Skip to content

Commit 28d0059

Browse files
Dmitriy RabotyagovMrStupnikov
authored andcommitted
Ensure MAC addresses characters are in the same case
Currently neutron can report ports to have MAC addresses in upper case when they're created like that. In the meanwhile libvirt configuration file always stores MAC in lower case which leads to KeyError while trying to retrieve migrate_vif. Conflicts: nova/tests/unit/virt/libvirt/test_migration.py Note: conflict is caused by not having six.text_type removal patch I779bd1446dc1f070fa5100ccccda7881fa508d79 in stable/victoria. Original assertion method was preserved to resolve this conflict. Closes-Bug: #1945646 Change-Id: Ie3129ee395427337e9abcef2f938012608f643e1 (cherry picked from commit 6a15169) (cherry picked from commit 63a6388) (cherry picked from commit 6c3d5de)
1 parent 34e0c02 commit 28d0059

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

nova/tests/unit/virt/libvirt/test_migration.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,48 @@ def test_update_vif_xml_no_matching_vif(self):
991991
doc = etree.fromstring(original_xml)
992992
ex = self.assertRaises(KeyError, migration._update_vif_xml,
993993
doc, data, get_vif_config)
994-
self.assertIn("CA:FE:DE:AD:BE:EF", six.text_type(ex))
994+
self.assertIn("ca:fe:de:ad:be:ef", six.text_type(ex))
995+
996+
def test_update_vif_xml_lower_case_mac(self):
997+
"""Tests that the vif in the migrate data is not found in the existing
998+
guest interfaces.
999+
"""
1000+
conf = vconfig.LibvirtConfigGuestInterface()
1001+
conf.net_type = "bridge"
1002+
conf.source_dev = "qbra188171c-ea"
1003+
conf.target_dev = "tapa188171c-ea"
1004+
conf.mac_addr = "DE:AD:BE:EF:CA:FE"
1005+
conf.model = "virtio"
1006+
original_xml = """<domain>
1007+
<uuid>3de6550a-8596-4937-8046-9d862036bca5</uuid>
1008+
<devices>
1009+
<interface type="bridge">
1010+
<mac address="de:ad:be:ef:ca:fe"/>
1011+
<model type="virtio"/>
1012+
<source bridge="qbra188171c-ea"/>
1013+
<target dev="tapa188171c-ea"/>
1014+
<virtualport type="openvswitch">
1015+
<parameters interfaceid="%s"/>
1016+
</virtualport>
1017+
<address type='pci' domain='0x0000' bus='0x00' slot='0x04'
1018+
function='0x0'/>
1019+
</interface>
1020+
</devices>
1021+
</domain>""" % uuids.ovs
1022+
expected_xml = """<domain>
1023+
<uuid>3de6550a-8596-4937-8046-9d862036bca5</uuid>
1024+
<devices>
1025+
<interface type="bridge">
1026+
<mac address="DE:AD:BE:EF:CA:FE"/>
1027+
<model type="virtio"/>
1028+
<source bridge="qbra188171c-ea"/>
1029+
<target dev="tapa188171c-ea"/>
1030+
<address type='pci' domain='0x0000' bus='0x00' slot='0x04'
1031+
function='0x0'/>
1032+
</interface>
1033+
</devices>
1034+
</domain>"""
1035+
self._test_update_vif_xml(conf, original_xml, expected_xml)
9951036

9961037

9971038
class MigrationMonitorTestCase(test.NoDBTestCase):

nova/virt/libvirt/migration.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,14 +344,21 @@ def _update_vif_xml(xml_doc, migrate_data, get_vif_config):
344344
instance_uuid = xml_doc.findtext('uuid')
345345
parser = etree.XMLParser(remove_blank_text=True)
346346
interface_nodes = xml_doc.findall('./devices/interface')
347-
migrate_vif_by_mac = {vif.source_vif['address']: vif
347+
# MAC address stored for port in neutron DB and in domain XML
348+
# might be in different cases, so to harmonize that
349+
# we convert MAC to lower case for dict key.
350+
migrate_vif_by_mac = {vif.source_vif['address'].lower(): vif
348351
for vif in migrate_data.vifs}
349352
for interface_dev in interface_nodes:
350353
mac = interface_dev.find('mac')
351354
mac = mac if mac is not None else {}
352355
mac_addr = mac.get('address')
353356
if mac_addr:
354-
migrate_vif = migrate_vif_by_mac[mac_addr]
357+
# MAC address stored in libvirt should always be normalized
358+
# and stored in lower case. But just to be extra safe here
359+
# we still normalize MAC retrieved from XML to be absolutely
360+
# sure it will be the same with the Neutron provided one.
361+
migrate_vif = migrate_vif_by_mac[mac_addr.lower()]
355362
vif = migrate_vif.get_dest_vif()
356363
# get_vif_config is a partial function of
357364
# nova.virt.libvirt.vif.LibvirtGenericVIFDriver.get_config

0 commit comments

Comments
 (0)