Move libvirt calculation of machine type to utils.py

The libvirt driver contains some code to calculate the
default machine type given an architecture, by looking it up
in CONF.libvirt.hw_machine_type.

This code will need to be reused when introducing calls to
libvirt's getDomainCapabilities() API, which requires the
machine type as one of the parameters.  However those calls
will need to be made from nova.virt.libvirt.host.Host which
has no access to the driver, so move the machine type
calculation code into nova.virt.libvirt.utils so that it can
be reused by both classes.

Also add some unit tests, and warn when an invalid config
value is used.

blueprint: amd-sev-libvirt-support
Change-Id: I055918ff16766c5b106d794a111ad8af8ff9ab23
This commit is contained in:
Adam Spiers 2019-03-19 00:53:02 +00:00
parent f58f73978e
commit d2f8995103
4 changed files with 50 additions and 10 deletions

View File

@ -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)

View File

@ -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'))

View File

@ -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

View File

@ -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_<uuid_with_underscores>) to a
uuid (of the form 8-4-4-4-12).