libvirt: implement LibvirtConfigGuestInterface.parse_dom

This is needed by a follow on change that needs to find an
interface in the config by a given MAC address.

Change-Id: I6b9ab20570e1db832cc2eec94cbf69dddf4ef3d6
Partial-Bug: #1536671
This commit is contained in:
Matt Riedemann 2016-01-21 10:53:06 -08:00
parent 704de0a0a4
commit 6e6a881608
4 changed files with 161 additions and 2 deletions

View File

@ -69,6 +69,10 @@ def get_pci_address_fields(pci_addr):
return (domain, bus, slot, func)
def get_pci_address(domain, bus, slot, func):
return '%s:%s:%s.%s' % (domain, bus, slot, func)
def get_function_by_ifname(ifname):
"""Given the device name, returns the PCI address of a device
and returns True if the address in a physical function.

View File

@ -1302,6 +1302,12 @@ class LibvirtConfigGuestInterfaceTest(LibvirtConfigBaseTest):
</bandwidth>
</interface>""")
# parse the xml from the first object into a new object and make sure
# they are the same
obj2 = config.LibvirtConfigGuestInterface()
obj2.parse_str(xml)
self.assertXmlEqual(xml, obj2.to_xml())
def test_config_driver_options(self):
obj = config.LibvirtConfigGuestInterface()
obj.net_type = "ethernet"
@ -1320,6 +1326,12 @@ class LibvirtConfigGuestInterfaceTest(LibvirtConfigBaseTest):
<target dev="vnet0"/>
</interface>""")
# parse the xml from the first object into a new object and make sure
# they are the same
obj2 = config.LibvirtConfigGuestInterface()
obj2.parse_str(xml)
self.assertXmlEqual(xml, obj2.to_xml())
def test_config_bridge(self):
obj = config.LibvirtConfigGuestInterface()
obj.net_type = "bridge"
@ -1352,6 +1364,12 @@ class LibvirtConfigGuestInterfaceTest(LibvirtConfigBaseTest):
</bandwidth>
</interface>""")
# parse the xml from the first object into a new object and make sure
# they are the same
obj2 = config.LibvirtConfigGuestInterface()
obj2.parse_str(xml)
self.assertXmlEqual(xml, obj2.to_xml())
def test_config_bridge_ovs(self):
obj = config.LibvirtConfigGuestInterface()
obj.net_type = "bridge"
@ -1374,6 +1392,12 @@ class LibvirtConfigGuestInterfaceTest(LibvirtConfigBaseTest):
</virtualport>
</interface>""")
# parse the xml from the first object into a new object and make sure
# they are the same
obj2 = config.LibvirtConfigGuestInterface()
obj2.parse_str(xml)
self.assertXmlEqual(xml, obj2.to_xml())
def test_config_bridge_xen(self):
obj = config.LibvirtConfigGuestInterface()
obj.net_type = "bridge"
@ -1389,6 +1413,12 @@ class LibvirtConfigGuestInterfaceTest(LibvirtConfigBaseTest):
<script path="/path/to/test-vif-openstack"/>
</interface>""")
# parse the xml from the first object into a new object and make sure
# they are the same
obj2 = config.LibvirtConfigGuestInterface()
obj2.parse_str(xml)
self.assertXmlEqual(xml, obj2.to_xml())
def test_config_8021Qbh(self):
obj = config.LibvirtConfigGuestInterface()
obj.net_type = "direct"
@ -1408,6 +1438,12 @@ class LibvirtConfigGuestInterfaceTest(LibvirtConfigBaseTest):
<virtualport type="802.1Qbh"/>
</interface>""")
# parse the xml from the first object into a new object and make sure
# they are the same
obj2 = config.LibvirtConfigGuestInterface()
obj2.parse_str(xml)
self.assertXmlEqual(xml, obj2.to_xml())
def test_config_direct(self):
obj = config.LibvirtConfigGuestInterface()
obj.net_type = "direct"
@ -1424,6 +1460,12 @@ class LibvirtConfigGuestInterfaceTest(LibvirtConfigBaseTest):
<source dev="eth0" mode="passthrough"/>
</interface>""")
# parse the xml from the first object into a new object and make sure
# they are the same
obj2 = config.LibvirtConfigGuestInterface()
obj2.parse_str(xml)
self.assertXmlEqual(xml, obj2.to_xml())
def test_config_8021Qbh_hostdev(self):
obj = config.LibvirtConfigGuestInterface()
obj.net_type = "hostdev"
@ -1445,6 +1487,12 @@ class LibvirtConfigGuestInterfaceTest(LibvirtConfigBaseTest):
</virtualport>
</interface>""")
# parse the xml from the first object into a new object and make sure
# they are the same
obj2 = config.LibvirtConfigGuestInterface()
obj2.parse_str(xml)
self.assertXmlEqual(xml, obj2.to_xml())
def test_config_hw_veb_hostdev(self):
obj = config.LibvirtConfigGuestInterface()
obj.net_type = "hostdev"
@ -1465,6 +1513,12 @@ class LibvirtConfigGuestInterfaceTest(LibvirtConfigBaseTest):
</vlan>
</interface>""")
# parse the xml from the first object into a new object and make sure
# they are the same
obj2 = config.LibvirtConfigGuestInterface()
obj2.parse_str(xml)
self.assertXmlEqual(xml, obj2.to_xml())
def test_config_vhostuser(self):
obj = config.LibvirtConfigGuestInterface()
obj.net_type = "vhostuser"
@ -1481,6 +1535,12 @@ class LibvirtConfigGuestInterfaceTest(LibvirtConfigBaseTest):
<source type="unix" mode="server" path="/vhost-user/test.sock"/>
</interface>""")
# parse the xml from the first object into a new object and make sure
# they are the same
obj2 = config.LibvirtConfigGuestInterface()
obj2.parse_str(xml)
self.assertXmlEqual(xml, obj2.to_xml())
class LibvirtConfigGuestFeatureTest(LibvirtConfigBaseTest):

View File

@ -363,6 +363,13 @@ class GuestTestCase(test.NoDBTestCase):
<address domain='0x0000' bus='0x06' slot='0x12' function='0x6'/>
</source>
</hostdev>
<interface type="bridge">
<mac address="fa:16:3e:f9:af:ae"/>
<model type="virtio"/>
<driver name="qemu"/>
<source bridge="qbr84008d03-11"/>
<target dev="tap84008d03-11"/>
</interface>
<controller type='usb' index='0'/>
<controller type='pci' index='0' model='pci-root'/>
<memballoon model='none'/>
@ -373,14 +380,15 @@ class GuestTestCase(test.NoDBTestCase):
self.domain.XMLDesc.return_value = xml
devs = self.guest.get_all_devices()
# Only currently parse <disk> and <hostdev> elements
# Only currently parse <disk>, <hostdev> and <interface> elements
# hence we're not counting the controller/memballoon
self.assertEqual(5, len(devs))
self.assertEqual(6, len(devs))
self.assertIsInstance(devs[0], vconfig.LibvirtConfigGuestDisk)
self.assertIsInstance(devs[1], vconfig.LibvirtConfigGuestDisk)
self.assertIsInstance(devs[2], vconfig.LibvirtConfigGuestDisk)
self.assertIsInstance(devs[3], vconfig.LibvirtConfigGuestHostdev)
self.assertIsInstance(devs[4], vconfig.LibvirtConfigGuestHostdev)
self.assertIsInstance(devs[5], vconfig.LibvirtConfigGuestInterface)
devs = self.guest.get_all_devices(vconfig.LibvirtConfigGuestDisk)
self.assertEqual(3, len(devs))
@ -399,6 +407,10 @@ class GuestTestCase(test.NoDBTestCase):
self.assertIsInstance(devs[0], vconfig.LibvirtConfigGuestHostdev)
self.assertIsInstance(devs[1], vconfig.LibvirtConfigGuestHostdev)
devs = self.guest.get_all_devices(vconfig.LibvirtConfigGuestInterface)
self.assertEqual(1, len(devs))
self.assertIsInstance(devs[0], vconfig.LibvirtConfigGuestInterface)
def test_get_info(self):
self.domain.info.return_value = (1, 2, 3, 4, 5)
self.domain.ID.return_value = 6

View File

@ -1255,6 +1255,84 @@ class LibvirtConfigGuestInterface(LibvirtConfigGuestDevice):
return dev
def parse_dom(self, xmldoc):
super(LibvirtConfigGuestInterface, self).parse_dom(xmldoc)
self.net_type = xmldoc.get('type')
for c in xmldoc.getchildren():
if c.tag == 'mac':
self.mac_addr = c.get('address')
elif c.tag == 'model':
self.model = c.get('type')
elif c.tag == 'driver':
self.driver_name = c.get('name')
self.vhost_queues = c.get('queues')
elif c.tag == 'source':
if self.net_type == 'direct':
self.source_dev = c.get('dev')
self.source_mode = c.get('mode', 'private')
elif self.net_type == 'vhostuser':
self.vhostuser_type = c.get('type')
self.vhostuser_mode = c.get('mode')
self.vhostuser_path = c.get('path')
elif self.net_type == 'hostdev':
for sub in c.getchildren():
if sub.tag == 'address' and sub.get('type') == 'pci':
# strip the 0x prefix on each attribute since
# format_dom puts them back on - note that
# LibvirtConfigGuestHostdevPCI does not do this...
self.source_dev = (
pci_utils.get_pci_address(
sub.get('domain')[2:],
sub.get('bus')[2:],
sub.get('slot')[2:],
sub.get('function')[2:]
)
)
else:
self.source_dev = c.get('bridge')
elif c.tag == 'target':
self.target_dev = c.get('dev')
elif c.tag == 'script':
self.script = c.get('path')
elif c.tag == 'vlan':
# NOTE(mriedem): The vlan element can have multiple tag
# sub-elements but we're currently only storing a single tag
# id in the vlan attribute.
for sub in c.getchildren():
if sub.tag == 'tag' and sub.get('id'):
self.vlan = sub.get('id')
break
elif c.tag == 'virtualport':
self.vporttype = c.get('type')
for sub in c.getchildren():
if sub.tag == 'parameters':
for k, v in dict(sub.attrib).items():
self.add_vport_param(k, v)
elif c.tag == 'filterref':
self.filtername = c.get('filter')
for sub in c.getchildren():
if sub.tag == 'parameter':
self.add_filter_param(sub.get('name'),
sub.get('value'))
elif c.tag == 'bandwidth':
for sub in c.getchildren():
# Note that only average is mandatory, burst and peak are
# optional (and all are ints).
if sub.tag == 'inbound':
self.vif_inbound_average = int(sub.get('average'))
if sub.get('burst'):
self.vif_inbound_burst = int(sub.get('burst'))
if sub.get('peak'):
self.vif_inbound_peak = int(sub.get('peak'))
elif sub.tag == 'outbound':
self.vif_outbound_average = int(sub.get('average'))
if sub.get('burst'):
self.vif_outbound_burst = int(sub.get('burst'))
if sub.get('peak'):
self.vif_outbound_peak = int(sub.get('peak'))
def add_filter_param(self, key, value):
self.filterparams.append({'key': key, 'value': value})
@ -1992,6 +2070,7 @@ class LibvirtConfigGuest(LibvirtConfigObject):
def parse_dom(self, xmldoc):
# Note: This cover only for: LibvirtConfigGuestDisks
# LibvirtConfigGuestHostdevPCI
# LibvirtConfigGuestInterface
# LibvirtConfigGuestUidMap
# LibvirtConfigGuestGidMap
# LibvirtConfigGuestCPU
@ -2006,6 +2085,10 @@ class LibvirtConfigGuest(LibvirtConfigObject):
obj = LibvirtConfigGuestHostdevPCI()
obj.parse_dom(d)
self.devices.append(obj)
elif d.tag == 'interface':
obj = LibvirtConfigGuestInterface()
obj.parse_dom(d)
self.devices.append(obj)
if c.tag == 'idmap':
for map in c.getchildren():
obj = None