From a8de6737d22d19fea3d93024fb0cbbe40d67dde9 Mon Sep 17 00:00:00 2001 From: Pavlo Shchelokovskyy Date: Tue, 20 Feb 2024 19:47:44 +0000 Subject: [PATCH] Fix device type when booting from ISO image Closes-Bug: #2054446 Change-Id: Ib4cc34c30a8acf09a1ab6be89d0faa76fb6e705e (cherry picked from commit 96a5c21f24f6a89411d12677ae5fa75adf26ed61) --- .../tests/unit/virt/libvirt/test_blockinfo.py | 20 ++++++++---- nova/virt/libvirt/blockinfo.py | 32 +++++++++++-------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/nova/tests/unit/virt/libvirt/test_blockinfo.py b/nova/tests/unit/virt/libvirt/test_blockinfo.py index 62234f1fa636..5ee61abf9f31 100644 --- a/nova/tests/unit/virt/libvirt/test_blockinfo.py +++ b/nova/tests/unit/virt/libvirt/test_blockinfo.py @@ -578,7 +578,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase): 'disk_bus': u'virtio', 'device_type': u'disk'}]} instance_ref.flavor.swap = 5 - image_meta = {} + image_meta = objects.ImageMeta.from_dict(None) mapping = blockinfo.get_disk_mapping("kvm", instance_ref, "virtio", "ide", @@ -840,7 +840,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase): def test_get_disk_mapping_blockdev_root_on_spawn(self): # A disk mapping with a blockdev initializing the default root instance_ref = objects.Instance(**self.test_instance) - image_meta = {} + image_meta = objects.ImageMeta.from_dict(None) block_device_info = { 'image': [], @@ -1287,6 +1287,18 @@ class LibvirtBlockInfoTest(test.NoDBTestCase): self.assertEqual('virtio', info['bus']) + @mock.patch('nova.virt.libvirt.blockinfo.get_info_from_bdm') + def test_get_root_info_bdm_with_iso_image(self, mock_get_info): + self.test_image_meta['disk_format'] = 'iso' + instance = objects.Instance(**self.test_instance) + image_meta = objects.ImageMeta.from_dict(self.test_image_meta) + init_root_bdm = {'device_type': 'disk'} + iso_root_bdm = {'device_type': 'cdrom', 'disk_bus': 'ide'} + blockinfo.get_root_info(instance, 'kvm', image_meta, init_root_bdm, + 'virtio', 'ide') + mock_get_info.assert_called_once_with(instance, 'kvm', image_meta, + iso_root_bdm, {}, 'virtio') + @mock.patch('nova.virt.libvirt.blockinfo.get_info_from_bdm') def test_get_root_info_bdm(self, mock_get_info): # call get_root_info() with DriverBlockDevice @@ -1337,15 +1349,11 @@ class LibvirtBlockInfoTest(test.NoDBTestCase): # No root_device_name blockinfo.get_root_info( instance, 'kvm', image_meta, root_bdm, 'virtio', 'ide') - mock_get_info.assert_called_once_with( - instance, 'kvm', image_meta, root_bdm, {}, 'virtio') mock_get_info.reset_mock() # Both device names blockinfo.get_root_info( instance, 'kvm', image_meta, root_bdm, 'virtio', 'scsi', root_device_name='/dev/sda') - mock_get_info.assert_called_once_with( - instance, 'kvm', image_meta, root_bdm, {}, 'virtio') mock_get_info.reset_mock() # Missing device names original_bdm = copy.deepcopy(root_bdm) diff --git a/nova/virt/libvirt/blockinfo.py b/nova/virt/libvirt/blockinfo.py index c1563642d649..e73cc4d12156 100644 --- a/nova/virt/libvirt/blockinfo.py +++ b/nova/virt/libvirt/blockinfo.py @@ -427,28 +427,32 @@ def get_device_name(bdm): def get_root_info(instance, virt_type, image_meta, root_bdm, disk_bus, cdrom_bus, root_device_name=None): + # NOTE(mriedem): In case the image_meta object was constructed from + # an empty dict, like in the case of evacuate, we have to first check + # if disk_format is set on the ImageMeta object. + if is_iso := (image_meta.obj_attr_is_set('disk_format') and + image_meta.disk_format == 'iso'): + root_device_bus = cdrom_bus + root_device_type = 'cdrom' + else: + root_device_bus = disk_bus + root_device_type = 'disk' + if root_bdm is None: - # NOTE(mriedem): In case the image_meta object was constructed from - # an empty dict, like in the case of evacuate, we have to first check - # if disk_format is set on the ImageMeta object. - if (image_meta.obj_attr_is_set('disk_format') and - image_meta.disk_format == 'iso'): - root_device_bus = cdrom_bus - root_device_type = 'cdrom' - else: - root_device_bus = disk_bus - root_device_type = 'disk' if not root_device_name: root_device_name = find_disk_dev_for_disk_bus({}, root_device_bus) - return {'bus': root_device_bus, 'type': root_device_type, 'dev': block_device.strip_dev(root_device_name), 'boot_index': '1'} - root_bdm_copy = root_bdm - if not get_device_name(root_bdm) and root_device_name: - root_bdm_copy = copy.deepcopy(root_bdm) + root_bdm_copy = copy.deepcopy(root_bdm) + + if is_iso: + root_bdm_copy['disk_bus'] = root_device_bus + root_bdm_copy['device_type'] = root_device_type + + if not get_device_name(root_bdm_copy) and root_device_name: root_bdm_copy['device_name'] = root_device_name return get_info_from_bdm(