diff --git a/nova/tests/unit/virt/libvirt/fake_libvirt_utils.py b/nova/tests/unit/virt/libvirt/fake_libvirt_utils.py index 3e1ea8083f7b..7dbc14c2d144 100644 --- a/nova/tests/unit/virt/libvirt/fake_libvirt_utils.py +++ b/nova/tests/unit/virt/libvirt/fake_libvirt_utils.py @@ -179,6 +179,10 @@ def cpu_features_to_traits(features): return libvirt_utils.cpu_features_to_traits(features) +def get_default_machine_type(arch): + return libvirt_utils.get_default_machine_type(arch) + + def mdev_name2uuid(mdev_name): return libvirt_utils.mdev_name2uuid(mdev_name) diff --git a/nova/tests/unit/virt/libvirt/test_utils.py b/nova/tests/unit/virt/libvirt/test_utils.py index 8aeb4af2e074..674b66f0cbc1 100644 --- a/nova/tests/unit/virt/libvirt/test_utils.py +++ b/nova/tests/unit/virt/libvirt/test_utils.py @@ -32,6 +32,7 @@ from nova import objects from nova.objects import fields as obj_fields import nova.privsep.fs from nova import test +from nova.tests import fixtures as nova_fixtures from nova.tests.unit import fake_instance from nova.tests.unit.virt.libvirt import fakelibvirt from nova.virt.disk import api as disk @@ -969,3 +970,29 @@ sunrpc /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0 disk_path, format = libvirt_utils.find_disk(guest) self.assertEqual('/test/disk', disk_path) self.assertEqual('ploop', format) + + def test_machine_type_mappings(self): + self.useFixture(nova_fixtures.ConfPatcher( + group="libvirt", hw_machine_type=['x86_64=q35', 'i686=legacy'])) + self.assertDictEqual({'x86_64': 'q35', 'i686': 'legacy'}, + libvirt_utils.machine_type_mappings()) + + def test_invalid_machine_type_mappings(self): + self.useFixture(nova_fixtures.ConfPatcher( + group="libvirt", hw_machine_type=['x86_64=q35', 'foo'])) + self.assertDictEqual({'x86_64': 'q35'}, + libvirt_utils.machine_type_mappings()) + + def test_get_default_machine_type(self): + self.useFixture(nova_fixtures.ConfPatcher( + group="libvirt", hw_machine_type=['x86_64=q35', 'i686=legacy'])) + self.assertEqual('q35', + libvirt_utils.get_default_machine_type('x86_64')) + + def test_get_default_machine_type_empty(self): + self.assertIsNone(libvirt_utils.get_default_machine_type('sparc')) + + def test_get_default_machine_type_missing(self): + self.useFixture(nova_fixtures.ConfPatcher( + group="libvirt", hw_machine_type=['x86_64=q35', 'i686=legacy'])) + self.assertIsNone(libvirt_utils.get_default_machine_type('sparc')) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index a23b56362427..608ac874296c 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -4227,13 +4227,6 @@ class LibvirtDriver(driver.ComputeDriver): return meta - def _machine_type_mappings(self): - mappings = {} - for mapping in CONF.libvirt.hw_machine_type: - host_arch, _, machine_type = mapping.partition('=') - mappings[host_arch] = machine_type - return mappings - def _get_machine_type(self, image_meta, caps): # The guest machine type can be set as an image metadata # property, or otherwise based on architecture-specific @@ -4257,9 +4250,10 @@ class LibvirtDriver(driver.ComputeDriver): mach_type = 's390-ccw-virtio' # If set in the config, use that as the default. - if CONF.libvirt.hw_machine_type: - mappings = self._machine_type_mappings() - mach_type = mappings.get(caps.host.cpu.arch) + mach_type = ( + libvirt_utils.get_default_machine_type(caps.host.cpu.arch) + or mach_type + ) return mach_type diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py index 59bb982caee6..10759f136a7f 100644 --- a/nova/virt/libvirt/utils.py +++ b/nova/virt/libvirt/utils.py @@ -541,6 +541,21 @@ def get_cpu_model_from_arch(arch): return mode +def machine_type_mappings(): + mappings = {} + for mapping in CONF.libvirt.hw_machine_type or {}: + host_arch, _, machine_type = mapping.partition('=') + if machine_type == '': + LOG.warning("Invalid hw_machine_type config value %s", mapping) + else: + mappings[host_arch] = machine_type + return mappings + + +def get_default_machine_type(arch): + return machine_type_mappings().get(arch) + + def mdev_name2uuid(mdev_name): """Convert an mdev name (of the form mdev_) to a uuid (of the form 8-4-4-4-12).