summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Rabotyagov <noonedeadpunk@ya.ru>2021-09-30 14:08:38 +0300
committerAlexey Stupnikov <aleksey.stupnikov@gmail.com>2022-01-21 11:47:27 +0000
commita5da31ec1ea1d1c7b4df146857982699ebdc328e (patch)
treed8e83f62000d6a40492b870f1e52117109d53afa
parent8906552cfc2525a44251d4cf313ece61e57251eb (diff)
downloadnova-a5da31ec1ea1d1c7b4df146857982699ebdc328e.tar.gz
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 6a15169ed9f16672c2cde1d7f27178bb7868c41f) (cherry picked from commit 63a6388f6a0265f84232731aba8aec1bff3c6d18) (cherry picked from commit 6c3d5de659e558e8f6ee353475b54ff3ca7240ee) (cherry picked from commit 28d0059c1f52e51add31bff50f1f6e443c938792) (cherry picked from commit 184a3c976faed38907af148a533bc6e9faa410f5)
-rw-r--r--nova/tests/unit/virt/libvirt/test_migration.py43
-rw-r--r--nova/virt/libvirt/migration.py11
2 files changed, 51 insertions, 3 deletions
diff --git a/nova/tests/unit/virt/libvirt/test_migration.py b/nova/tests/unit/virt/libvirt/test_migration.py
index 7adfb0ef65..07d11f94e5 100644
--- a/nova/tests/unit/virt/libvirt/test_migration.py
+++ b/nova/tests/unit/virt/libvirt/test_migration.py
@@ -955,7 +955,48 @@ class UtilityMigrationTestCase(test.NoDBTestCase):
doc = etree.fromstring(original_xml)
ex = self.assertRaises(KeyError, migration._update_vif_xml,
doc, data, get_vif_config)
- self.assertIn("CA:FE:DE:AD:BE:EF", six.text_type(ex))
+ self.assertIn("ca:fe:de:ad:be:ef", six.text_type(ex))
+
+ def test_update_vif_xml_lower_case_mac(self):
+ """Tests that the vif in the migrate data is not found in the existing
+ guest interfaces.
+ """
+ conf = vconfig.LibvirtConfigGuestInterface()
+ conf.net_type = "bridge"
+ conf.source_dev = "qbra188171c-ea"
+ conf.target_dev = "tapa188171c-ea"
+ conf.mac_addr = "DE:AD:BE:EF:CA:FE"
+ conf.model = "virtio"
+ original_xml = """<domain>
+ <uuid>3de6550a-8596-4937-8046-9d862036bca5</uuid>
+ <devices>
+ <interface type="bridge">
+ <mac address="de:ad:be:ef:ca:fe"/>
+ <model type="virtio"/>
+ <source bridge="qbra188171c-ea"/>
+ <target dev="tapa188171c-ea"/>
+ <virtualport type="openvswitch">
+ <parameters interfaceid="%s"/>
+ </virtualport>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
+ function='0x0'/>
+ </interface>
+ </devices>
+ </domain>""" % uuids.ovs
+ expected_xml = """<domain>
+ <uuid>3de6550a-8596-4937-8046-9d862036bca5</uuid>
+ <devices>
+ <interface type="bridge">
+ <mac address="DE:AD:BE:EF:CA:FE"/>
+ <model type="virtio"/>
+ <source bridge="qbra188171c-ea"/>
+ <target dev="tapa188171c-ea"/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
+ function='0x0'/>
+ </interface>
+ </devices>
+ </domain>"""
+ self._test_update_vif_xml(conf, original_xml, expected_xml)
class MigrationMonitorTestCase(test.NoDBTestCase):
diff --git a/nova/virt/libvirt/migration.py b/nova/virt/libvirt/migration.py
index 7b7214712c..36a9d4bcd9 100644
--- a/nova/virt/libvirt/migration.py
+++ b/nova/virt/libvirt/migration.py
@@ -346,14 +346,21 @@ def _update_vif_xml(xml_doc, migrate_data, get_vif_config):
instance_uuid = xml_doc.findtext('uuid')
parser = etree.XMLParser(remove_blank_text=True)
interface_nodes = xml_doc.findall('./devices/interface')
- migrate_vif_by_mac = {vif.source_vif['address']: vif
+ # MAC address stored for port in neutron DB and in domain XML
+ # might be in different cases, so to harmonize that
+ # we convert MAC to lower case for dict key.
+ migrate_vif_by_mac = {vif.source_vif['address'].lower(): vif
for vif in migrate_data.vifs}
for interface_dev in interface_nodes:
mac = interface_dev.find('mac')
mac = mac if mac is not None else {}
mac_addr = mac.get('address')
if mac_addr:
- migrate_vif = migrate_vif_by_mac[mac_addr]
+ # MAC address stored in libvirt should always be normalized
+ # and stored in lower case. But just to be extra safe here
+ # we still normalize MAC retrieved from XML to be absolutely
+ # sure it will be the same with the Neutron provided one.
+ migrate_vif = migrate_vif_by_mac[mac_addr.lower()]
vif = migrate_vif.get_dest_vif()
# get_vif_config is a partial function of
# nova.virt.libvirt.vif.LibvirtGenericVIFDriver.get_config