libvirt: Report storage bus traits

Add dynamic trait reporting based on the currently enabled virt type.

Change-Id: I1c31cfd317d089026fa30d401157f661b6049cd3
Partially-Implements: blueprint image-metadata-prefiltering
Co-Authored-By: Stephen Finucane <sfinucan@redhat.com>
This commit is contained in:
Sean Mooney 2019-06-21 19:53:15 +01:00 committed by Stephen Finucane
parent 07cb3eec4b
commit 6336162585
4 changed files with 64 additions and 22 deletions

View File

@ -78,7 +78,8 @@ class LibvirtReportTraitsTests(LibvirtReportTraitsTestBase):
# The periodic restored the COMPUTE_NODE trait.
u'COMPUTE_NODE']
)
self.assertItemsEqual(expected_traits, traits)
for trait in expected_traits:
self.assertIn(trait, traits)
class LibvirtReportNoSevTraitsTests(LibvirtReportTraitsTestBase):

View File

@ -19616,8 +19616,8 @@ class TestUpdateProviderTree(test.NoDBTestCase):
self._test_update_provider_tree()
self.assertEqual(self._get_inventory(),
(self.pt.data(self.cn_rp['uuid'])).inventory)
self.assertEqual(set(['HW_CPU_X86_AVX512F', 'HW_CPU_X86_BMI']),
self.pt.data(self.cn_rp['uuid']).traits)
for trait in ['HW_CPU_X86_AVX512F', 'HW_CPU_X86_BMI']:
self.assertIn(trait, self.pt.data(self.cn_rp['uuid']).traits)
def test_update_provider_tree_with_vgpus(self):
pci_devices = ['pci_0000_06_00_0', 'pci_0000_07_00_0']
@ -19780,8 +19780,8 @@ class TestUpdateProviderTree(test.NoDBTestCase):
self.pt.add_traits(self.cn_rp['uuid'],
'HW_CPU_X86_VMX', 'HW_CPU_X86_XOP')
self._test_update_provider_tree()
self.assertEqual(set(['HW_CPU_X86_AVX512F', 'HW_CPU_X86_BMI']),
self.pt.data(self.cn_rp['uuid']).traits)
for trait in ['HW_CPU_X86_AVX512F', 'HW_CPU_X86_BMI']:
self.assertIn(trait, self.pt.data(self.cn_rp['uuid']).traits)
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver.'
'_get_mediated_device_information')
@ -23073,6 +23073,25 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
self.assertRaises(test.TestingException,
self._test_detach_mediated_devices, exc)
def test_storage_bus_traits(self):
"""Test getting storage bus traits per virt type."""
all_traits = set()
# ensure each virt type reports the correct bus types
for virt_type, buses in blockinfo.SUPPORTED_STORAGE_BUSES.items():
self.flags(virt_type=virt_type, group='libvirt')
bus_traits = self.drvr._get_storage_bus_traits()
for bus in buses:
trait = f'COMPUTE_STORAGE_BUS_{bus.upper()}'
self.assertIn(trait, bus_traits)
self.assertTrue(bus_traits[trait])
all_traits.add(trait)
# ..and all the traits reported are valid os-trait traits
valid_traits = ot.check_traits(all_traits)
self.assertEqual(len(all_traits), len(valid_traits[0]))
self.assertEqual(0, len(valid_traits[1]))
@mock.patch.object(libvirt_driver.LibvirtDriver, '_get_cpu_feature_traits',
new=mock.Mock(return_value={}))
def test_cpu_traits__sev_support(self):

View File

@ -200,22 +200,24 @@ def find_disk_dev_for_disk_bus(mapping, bus,
raise exception.TooManyDiskDevices(maximum=max_dev)
# NOTE(aspiers): If you change this, don't forget to update the docs and
# metadata for hw_*_bus in glance. In addition, these bus names map directly to
# standard os-traits as 'foo' => 'COMPUTE_STORAGE_BUS_FOO'. If adding a new bus
# name, make sure the standard trait conforms to this rule.
SUPPORTED_STORAGE_BUSES = {
'qemu': ['virtio', 'scsi', 'ide', 'usb', 'fdc', 'sata'],
'kvm': ['virtio', 'scsi', 'ide', 'usb', 'fdc', 'sata'],
'xen': ['xen', 'ide'],
'uml': ['uml'],
'lxc': ['lxc'],
'parallels': ['ide', 'scsi']
}
def is_disk_bus_valid_for_virt(virt_type, disk_bus):
# NOTE(aspiers): If you change this, don't forget to update the
# docs and metadata for hw_*_bus in glance.
valid_bus = {
'qemu': ['virtio', 'scsi', 'ide', 'usb', 'fdc', 'sata'],
'kvm': ['virtio', 'scsi', 'ide', 'usb', 'fdc', 'sata'],
'xen': ['xen', 'ide'],
'uml': ['uml'],
'lxc': ['lxc'],
'parallels': ['ide', 'scsi']
}
if virt_type not in valid_bus:
if virt_type not in SUPPORTED_STORAGE_BUSES:
raise exception.UnsupportedVirtType(virt=virt_type)
return disk_bus in valid_bus[virt_type]
return disk_bus in SUPPORTED_STORAGE_BUSES[virt_type]
def get_disk_bus_for_device_type(instance,

View File

@ -7243,10 +7243,13 @@ class LibvirtDriver(driver.ComputeDriver):
provider_tree.update_inventory(nodename, result)
provider_tree.update_resources(nodename, resources)
# _get_cpu_traits and _get_storage_bus_traits return a dict of trait
# names mapped to boolean values...
traits = self._get_cpu_traits()
# _get_cpu_traits returns a dict of trait names mapped to boolean
# values. Add traits equal to True to provider tree, remove
# those False traits from provider tree.
traits.update(self._get_storage_bus_traits())
# ..and we add traits equal to True to provider tree while removing
# those equal to False
traits_to_add = [t for t in traits if traits[t]]
traits_to_remove = set(traits) - set(traits_to_add)
provider_tree.add_traits(nodename, *traits_to_add)
@ -10355,6 +10358,23 @@ class LibvirtDriver(driver.ComputeDriver):
nova.privsep.fs.FS_FORMAT_EXT4,
nova.privsep.fs.FS_FORMAT_XFS]
def _get_storage_bus_traits(self):
"""Get storage bus traits based on the currently enabled virt_type.
:return: A dict of trait names mapped to boolean values.
"""
all_buses = set(itertools.chain(
*blockinfo.SUPPORTED_STORAGE_BUSES.values()
))
supported_buses = blockinfo.SUPPORTED_STORAGE_BUSES.get(
CONF.libvirt.virt_type, []
)
# construct the corresponding standard trait from the storage bus name
return {
f'COMPUTE_STORAGE_BUS_{bus.upper()}': bus in supported_buses
for bus in all_buses
}
def _get_cpu_traits(self):
"""Get CPU-related traits to be set and unset on the host's resource
provider.