From 8795b206247fe2ca57f32c437d72c51492637649 Mon Sep 17 00:00:00 2001 From: Lee Yarwood Date: Thu, 30 Jun 2016 10:22:28 +0100 Subject: [PATCH] libvirt: Use the recreated disk.config.rescue during a rescue I931421ea introduced a callback to _create_configdrive from _create_domain during a rescue that recreates the config disk of an instance with an additional .rescue suffix. However due to a latent bug neither the original or this recreated config disk are mapped to the instance during the resulting rescue. To correct this disk.config.rescue is now added to the disk_mapping for the instance if a config disk is required during a rescue. Closes-bug: #1597669 Change-Id: I46cebd0612f50ff7373f677c4a002d444a877972 --- .../tests/unit/virt/libvirt/test_blockinfo.py | 26 ++++++++++++++++++- nova/tests/unit/virt/libvirt/test_driver.py | 9 +++---- nova/virt/libvirt/blockinfo.py | 12 +++++++++ nova/virt/libvirt/driver.py | 5 ++-- 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/nova/tests/unit/virt/libvirt/test_blockinfo.py b/nova/tests/unit/virt/libvirt/test_blockinfo.py index 7a838b08af2c..58d3e591fc18 100644 --- a/nova/tests/unit/virt/libvirt/test_blockinfo.py +++ b/nova/tests/unit/virt/libvirt/test_blockinfo.py @@ -228,7 +228,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase): def test_get_disk_mapping_rescue(self): # A simple disk mapping setup, but in rescue mode - instance_ref = objects.Instance() + instance_ref = objects.Instance(**self.test_instance) image_meta = objects.ImageMeta.from_dict(self.test_image_meta) mapping = blockinfo.get_disk_mapping("kvm", instance_ref, @@ -245,6 +245,30 @@ class LibvirtBlockInfoTest(test.NoDBTestCase): } self.assertEqual(expect, mapping) + def test_get_disk_mapping_rescue_with_config(self): + # A simple disk mapping setup, but in rescue mode with a config drive + + test_instance_with_config = self.test_instance + test_instance_with_config['config_drive'] = True + instance_ref = objects.Instance(**test_instance_with_config) + image_meta = objects.ImageMeta.from_dict(self.test_image_meta) + + mapping = blockinfo.get_disk_mapping("kvm", instance_ref, + "virtio", "ide", + image_meta, + rescue=True) + + expect = { + 'disk.rescue': {'bus': 'virtio', 'dev': 'vda', + 'type': 'disk', 'boot_index': '1'}, + 'disk': {'bus': 'virtio', 'dev': 'vdb', 'type': 'disk'}, + 'disk.config.rescue': {'bus': 'ide', 'dev': 'hdd', + 'type': 'cdrom'}, + 'root': {'bus': 'virtio', 'dev': 'vda', + 'type': 'disk', 'boot_index': '1'}, + } + self.assertEqual(expect, mapping) + def test_get_disk_mapping_lxc(self): # A simple disk mapping setup, but for lxc diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 9f0b56c21247..59a33fe3d50b 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -16368,13 +16368,10 @@ class LibvirtDriverTestCase(test.NoDBTestCase): self.assertIsNone(disks['disk.rescue'].image_type) # We expect the generated domain to contain disk.rescue, disk, and - # config disk in that order - # NOTE(mdbooth): But it doesn't! Config disk is missing. - # See https://bugs.launchpad.net/nova/+bug/1597669 - # For now we assert the broken behaviour as a - # placeholder until the fix lands. + # disk.config.rescue in that order expected_domain_disk_paths = map( - lambda name: disks[name].path, ('disk.rescue', 'disk')) + lambda name: disks[name].path, ('disk.rescue', 'disk', + 'disk.config.rescue')) domain_disk_paths = doc.xpath('devices/disk/source/@file') self.assertEqual(expected_domain_disk_paths, domain_disk_paths) diff --git a/nova/virt/libvirt/blockinfo.py b/nova/virt/libvirt/blockinfo.py index 8fc7fc7e9f31..c386a4daa9be 100644 --- a/nova/virt/libvirt/blockinfo.py +++ b/nova/virt/libvirt/blockinfo.py @@ -522,6 +522,18 @@ def get_disk_mapping(virt_type, instance, disk_bus) mapping['disk'] = os_info + if configdrive.required_by(instance): + device_type = get_config_drive_type() + disk_bus = get_disk_bus_for_device_type(instance, + virt_type, + image_meta, + device_type) + config_info = get_next_disk_info(mapping, + disk_bus, + device_type, + last_device=True) + mapping['disk.config.rescue'] = config_info + return mapping pre_assigned_device_names = \ diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 5668f5740fb2..64f79d3b4614 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -3476,9 +3476,10 @@ class LibvirtDriver(driver.ComputeDriver): instance.default_swap_device = ( block_device.prepend_dev(diskswap.target_dev)) - if 'disk.config' in disk_mapping: + config_name = 'disk.config.rescue' if rescue else 'disk.config' + if config_name in disk_mapping: diskconfig = self._get_guest_disk_config( - instance, 'disk.config', disk_mapping, inst_type, + instance, config_name, disk_mapping, inst_type, self._get_disk_config_image_type()) devices.append(diskconfig)