diff options
-rw-r--r-- | nova/tests/unit/virt/libvirt/test_migration.py | 43 | ||||
-rw-r--r-- | nova/virt/libvirt/migration.py | 11 |
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 |