Skip to content

Commit 63a6388

Browse files
Dmitriy Rabotyagovdavid-hill
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. Closes-Bug: #1945646 Change-Id: Ie3129ee395427337e9abcef2f938012608f643e1 (cherry picked from commit 6a15169)
1 parent d4edcd6 commit 63a6388

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
@@ -949,7 +949,48 @@ def test_update_vif_xml_no_matching_vif(self):
949949
doc = etree.fromstring(original_xml)
950950
ex = self.assertRaises(KeyError, migration._update_vif_xml,
951951
doc, data, get_vif_config)
952-
self.assertIn("CA:FE:DE:AD:BE:EF", str(ex))
952+
self.assertIn("ca:fe:de:ad:be:ef", str(ex))
953+
954+
def test_update_vif_xml_lower_case_mac(self):
955+
"""Tests that the vif in the migrate data is not found in the existing
956+
guest interfaces.
957+
"""
958+
conf = vconfig.LibvirtConfigGuestInterface()
959+
conf.net_type = "bridge"
960+
conf.source_dev = "qbra188171c-ea"
961+
conf.target_dev = "tapa188171c-ea"
962+
conf.mac_addr = "DE:AD:BE:EF:CA:FE"
963+
conf.model = "virtio"
964+
original_xml = """<domain>
965+
<uuid>3de6550a-8596-4937-8046-9d862036bca5</uuid>
966+
<devices>
967+
<interface type="bridge">
968+
<mac address="de:ad:be:ef:ca:fe"/>
969+
<model type="virtio"/>
970+
<source bridge="qbra188171c-ea"/>
971+
<target dev="tapa188171c-ea"/>
972+
<virtualport type="openvswitch">
973+
<parameters interfaceid="%s"/>
974+
</virtualport>
975+
<address type='pci' domain='0x0000' bus='0x00' slot='0x04'
976+
function='0x0'/>
977+
</interface>
978+
</devices>
979+
</domain>""" % uuids.ovs
980+
expected_xml = """<domain>
981+
<uuid>3de6550a-8596-4937-8046-9d862036bca5</uuid>
982+
<devices>
983+
<interface type="bridge">
984+
<mac address="DE:AD:BE:EF:CA:FE"/>
985+
<model type="virtio"/>
986+
<source bridge="qbra188171c-ea"/>
987+
<target dev="tapa188171c-ea"/>
988+
<address type='pci' domain='0x0000' bus='0x00' slot='0x04'
989+
function='0x0'/>
990+
</interface>
991+
</devices>
992+
</domain>"""
993+
self._test_update_vif_xml(conf, original_xml, expected_xml)
953994

954995

955996
class MigrationMonitorTestCase(test.NoDBTestCase):

nova/virt/libvirt/migration.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,14 +339,21 @@ def _update_vif_xml(xml_doc, migrate_data, get_vif_config):
339339
instance_uuid = xml_doc.findtext('uuid')
340340
parser = etree.XMLParser(remove_blank_text=True)
341341
interface_nodes = xml_doc.findall('./devices/interface')
342-
migrate_vif_by_mac = {vif.source_vif['address']: vif
342+
# MAC address stored for port in neutron DB and in domain XML
343+
# might be in different cases, so to harmonize that
344+
# we convert MAC to lower case for dict key.
345+
migrate_vif_by_mac = {vif.source_vif['address'].lower(): vif
343346
for vif in migrate_data.vifs}
344347
for interface_dev in interface_nodes:
345348
mac = interface_dev.find('mac')
346349
mac = mac if mac is not None else {}
347350
mac_addr = mac.get('address')
348351
if mac_addr:
349-
migrate_vif = migrate_vif_by_mac[mac_addr]
352+
# MAC address stored in libvirt should always be normalized
353+
# and stored in lower case. But just to be extra safe here
354+
# we still normalize MAC retrieved from XML to be absolutely
355+
# sure it will be the same with the Neutron provided one.
356+
migrate_vif = migrate_vif_by_mac[mac_addr.lower()]
350357
vif = migrate_vif.get_dest_vif()
351358
# get_vif_config is a partial function of
352359
# nova.virt.libvirt.vif.LibvirtGenericVIFDriver.get_config

0 commit comments

Comments
 (0)