From 7b6f7ecfa6c7190d9136ed9287cfd86bdd5023d7 Mon Sep 17 00:00:00 2001 From: Vladik Romanovsky Date: Fri, 8 Apr 2016 15:19:29 -0400 Subject: [PATCH] libvirt: New configuration classes to parse device address element Adding new configuration classes to parse network and disk libvirt
elements. PCI type addresses can be formatted to proper PCI address string using a format_address helper method. Partially implements blueprint virt-device-role-tagging Change-Id: Icc5dbcab7815a48441de62b928d6d18cb2a73b73 --- nova/tests/unit/virt/libvirt/test_config.py | 55 +++++++++++++++++ nova/virt/libvirt/config.py | 67 +++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/nova/tests/unit/virt/libvirt/test_config.py b/nova/tests/unit/virt/libvirt/test_config.py index f330ca0ca6d..09c4512a2b7 100644 --- a/nova/tests/unit/virt/libvirt/test_config.py +++ b/nova/tests/unit/virt/libvirt/test_config.py @@ -927,6 +927,44 @@ def test_config_blockio(self): """, xml) + def test_config_disk_device_address(self): + xml = """ + + + + +
+ """ + + obj = config.LibvirtConfigGuestDisk() + obj.parse_str(xml) + + self.assertIsInstance(obj.device_addr, + config.LibvirtConfigGuestDeviceAddressPCI) + self.assertEqual('0000:00:09.0', obj.device_addr.format_address()) + + def test_config_disk_device_address_no_format(self): + xml = """ + + + + +
+ """ + + obj = config.LibvirtConfigGuestDisk() + obj.parse_str(xml) + + self.assertIsInstance(obj.device_addr, + config.LibvirtConfigGuestDeviceAddressDrive) + self.assertEqual(('0', '0', '0', '1'), (obj.device_addr.controller, + obj.device_addr.bus, + obj.device_addr.target, + obj.device_addr.unit)) + self.assertIsNone(obj.device_addr.format_address()) + class LibvirtConfigGuestSnapshotDiskTest(LibvirtConfigBaseTest): @@ -1541,6 +1579,23 @@ def test_config_vhostuser(self): obj2.parse_str(xml) self.assertXmlEqual(xml, obj2.to_xml()) + def test_config_interface_address(self): + xml = """ + + + + +
+ """ + + obj = config.LibvirtConfigGuestInterface() + obj.parse_str(xml) + + self.assertIsInstance(obj.device_addr, + config.LibvirtConfigGuestDeviceAddressPCI) + self.assertEqual('0000:00:03.0', obj.device_addr.format_address()) + class LibvirtConfigGuestFeatureTest(LibvirtConfigBaseTest): diff --git a/nova/virt/libvirt/config.py b/nova/virt/libvirt/config.py index d0bfe70fd65..e3d5209b368 100644 --- a/nova/virt/libvirt/config.py +++ b/nova/virt/libvirt/config.py @@ -738,6 +738,7 @@ def __init__(self, **kwargs): self.shareable = False self.snapshot = None self.backing_store = None + self.device_addr = None def format_dom(self): dev = super(LibvirtConfigGuestDisk, self).format_dom() @@ -889,6 +890,10 @@ def parse_dom(self, xmldoc): self.readonly = True elif c.tag == 'shareable': self.shareable = True + elif c.tag == 'address': + obj = LibvirtConfigGuestDeviceAddress.factory(c) + obj.parse_dom(c) + self.device_addr = obj class LibvirtConfigGuestDiskBackingStore(LibvirtConfigObject): @@ -1131,6 +1136,63 @@ def __init__(self, **kwargs): **kwargs) +class LibvirtConfigGuestDeviceAddress(LibvirtConfigObject): + def __init__(self, type=None, **kwargs): + super(LibvirtConfigGuestDeviceAddress, self).__init__( + root_name='address', **kwargs) + self.type = type + + @staticmethod + def factory(xmldoc): + addr_type = xmldoc.get('type') + if addr_type == 'pci': + return LibvirtConfigGuestDeviceAddressPCI() + elif addr_type == 'drive': + return LibvirtConfigGuestDeviceAddressDrive() + + +class LibvirtConfigGuestDeviceAddressDrive(LibvirtConfigGuestDeviceAddress): + def __init__(self, **kwargs): + super(LibvirtConfigGuestDeviceAddressDrive, self).\ + __init__(type='drive', **kwargs) + self.controller = None + self.bus = None + self.target = None + self.unit = None + + def parse_dom(self, xmldoc): + self.controller = xmldoc.get('controller') + self.bus = xmldoc.get('bus') + self.target = xmldoc.get('target') + self.unit = xmldoc.get('unit') + + def format_address(self): + return None + + +class LibvirtConfigGuestDeviceAddressPCI(LibvirtConfigGuestDeviceAddress): + def __init__(self, **kwargs): + super(LibvirtConfigGuestDeviceAddressPCI, self).\ + __init__(type='pci', **kwargs) + self.domain = None + self.bus = None + self.slot = None + self.function = None + + def parse_dom(self, xmldoc): + self.domain = xmldoc.get('domain') + self.bus = xmldoc.get('bus') + self.slot = xmldoc.get('slot') + self.function = xmldoc.get('function') + + def format_address(self): + if self.domain is not None: + return pci_utils.get_pci_address(self.domain[2:], + self.bus[2:], + self.slot[2:], + self.function[2:]) + + class LibvirtConfigGuestInterface(LibvirtConfigGuestDevice): def __init__(self, **kwargs): @@ -1161,6 +1223,7 @@ def __init__(self, **kwargs): self.vif_outbound_burst = None self.vif_outbound_average = None self.vlan = None + self.device_addr = None def format_dom(self): dev = super(LibvirtConfigGuestInterface, self).format_dom() @@ -1331,6 +1394,10 @@ def parse_dom(self, xmldoc): self.vif_outbound_burst = int(sub.get('burst')) if sub.get('peak'): self.vif_outbound_peak = int(sub.get('peak')) + elif c.tag == 'address': + obj = LibvirtConfigGuestDeviceAddress.factory(c) + obj.parse_dom(c) + self.device_addr = obj def add_filter_param(self, key, value): self.filterparams.append({'key': key, 'value': value})