Skip to content

Commit

Permalink
libvirt: New configuration classes to parse device address element
Browse files Browse the repository at this point in the history
Adding new configuration classes to parse network and disk libvirt
<address> 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
  • Loading branch information
vladikr authored and notartom committed May 31, 2016
1 parent 028091d commit 7b6f7ec
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 0 deletions.
55 changes: 55 additions & 0 deletions nova/tests/unit/virt/libvirt/test_config.py
Expand Up @@ -927,6 +927,44 @@ def test_config_blockio(self):
<blockio logical_block_size="4096" physical_block_size="4096"/>
</disk>""", xml)

def test_config_disk_device_address(self):
xml = """
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/libvirt/images/centos.qcow2'/>
<target dev='vda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x09'
function='0x0'/>
</disk>"""

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 = """
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/libvirt/images/generic.qcow2'/>
<target dev='sda' bus='scsi'/>
<address type='drive' controller='0' bus='0'
target='0' unit='1'/>
</disk>"""

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

Expand Down Expand Up @@ -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 = """
<interface type='network'>
<mac address='52:54:00:f6:35:8f'/>
<source network='default'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x03' function='0x0'/>
</interface>"""

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

Expand Down
67 changes: 67 additions & 0 deletions nova/virt/libvirt/config.py
Expand Up @@ -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()
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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})
Expand Down

0 comments on commit 7b6f7ec

Please sign in to comment.