diff --git a/nova/tests/unit/virt/xenapi/test_vmops.py b/nova/tests/unit/virt/xenapi/test_vmops.py index 241bc6850427..0261ee890036 100644 --- a/nova/tests/unit/virt/xenapi/test_vmops.py +++ b/nova/tests/unit/virt/xenapi/test_vmops.py @@ -1344,15 +1344,18 @@ class XenstoreCallsTestCase(VMOpsTestBase): class LiveMigrateTestCase(VMOpsTestBase): + @mock.patch.object(vmops.VMOps, '_get_network_ref') @mock.patch.object(vmops.VMOps, '_ensure_host_in_aggregate') def _test_check_can_live_migrate_destination_shared_storage( self, shared, - mock_ensure_host): + mock_ensure_host, + mock_net_ref): fake_instance = {"name": "fake_instance", "host": "fake_host"} block_migration = None disk_over_commit = False ctxt = 'ctxt' + mock_net_ref.return_value = 'fake_net_ref' with mock.patch.object(self._session, 'get_rec') as fake_sr_rec: fake_sr_rec.return_value = {'shared': shared} @@ -1363,6 +1366,8 @@ class LiveMigrateTestCase(VMOpsTestBase): self.assertFalse(migrate_data_ret.block_migration) else: self.assertTrue(migrate_data_ret.block_migration) + self.assertEqual({'': 'fake_net_ref'}, + migrate_data_ret.vif_uuid_map) def test_check_can_live_migrate_destination_shared_storage(self): self._test_check_can_live_migrate_destination_shared_storage(True) @@ -1370,15 +1375,18 @@ class LiveMigrateTestCase(VMOpsTestBase): def test_check_can_live_migrate_destination_shared_storage_false(self): self._test_check_can_live_migrate_destination_shared_storage(False) + @mock.patch.object(vmops.VMOps, '_get_network_ref') @mock.patch.object(vmops.VMOps, '_ensure_host_in_aggregate', side_effect=exception.MigrationPreCheckError(reason="")) def test_check_can_live_migrate_destination_block_migration( self, - mock_ensure_host): + mock_ensure_host, + mock_net_ref): fake_instance = {"name": "fake_instance", "host": "fake_host"} block_migration = None disk_over_commit = False ctxt = 'ctxt' + mock_net_ref.return_value = 'fake_net_ref' migrate_data_ret = self.vmops.check_can_live_migrate_destination( ctxt, fake_instance, block_migration, disk_over_commit) @@ -1388,6 +1396,8 @@ class LiveMigrateTestCase(VMOpsTestBase): migrate_data_ret.destination_sr_ref) self.assertEqual({'value': 'fake_migrate_data'}, migrate_data_ret.migrate_send_data) + self.assertEqual({'': 'fake_net_ref'}, + migrate_data_ret.vif_uuid_map) @mock.patch.object(vmops.objects.AggregateList, 'get_by_host') def test_get_host_uuid_from_aggregate_no_aggr(self, mock_get_by_host): @@ -1641,6 +1651,20 @@ class LiveMigrateHelperTestCase(VMOpsTestBase): 'vif_ref2': 'dest_net_ref2'} self.assertEqual(vif_map, expected) + def test_generate_vif_network_map_default_net(self): + with mock.patch.object(self._session.VIF, + 'get_other_config') as mock_other_config, \ + mock.patch.object(self._session.VM, + 'get_VIFs') as mock_get_vif: + mock_other_config.side_effect = [{'nicira-iface-id': 'vif_id_a'}, + {'nicira-iface-id': 'vif_id_b'}] + mock_get_vif.return_value = ['vif_ref1'] + vif_uuid_map = {'': 'default_net_ref'} + vif_map = self.vmops._generate_vif_network_map('vm_ref', + vif_uuid_map) + expected = {'vif_ref1': 'default_net_ref'} + self.assertEqual(vif_map, expected) + def test_generate_vif_network_map_exception(self): with mock.patch.object(self._session.VIF, 'get_other_config') as mock_other_config, \ diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index c10afe71d045..5418309f8d45 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -2129,8 +2129,7 @@ class VMOps(object): host_uuid = self._get_host_uuid_from_aggregate(context, hostname) return self._session.call_xenapi("host.get_by_uuid", host_uuid) - def _migrate_receive(self, ctxt): - destref = self._session.host_ref + def _get_network_ref(self): # Get the network to for migrate. # This is the one associated with the pif marked management. From cli: # uuid=`xe pif-list --minimal management=true` @@ -2150,6 +2149,12 @@ class VMOps(object): raise exception.MigrationPreCheckError(reason=msg) nwref = pifs[list(pifs.keys())[0]]['network'] + return nwref + + def _migrate_receive(self, ctxt): + destref = self._session.host_ref + # Get the network to for migrate. + nwref = self._get_network_ref() try: options = {} migrate_data = self._session.call_xenapi("host.migrate_receive", @@ -2219,6 +2224,10 @@ class VMOps(object): # TODO(johngarbutt) we currently assume # instance is on a SR shared with other destination # block migration work will be able to resolve this + + # Set the default net_ref for use in generate_vif_mapping + net_ref = self._get_network_ref() + dest_check_data.vif_uuid_map = {'': net_ref} return dest_check_data def check_can_live_migrate_source(self, ctxt, instance_ref, @@ -2371,14 +2380,15 @@ class VMOps(object): vif_map = {} # vif_uuid_map is dictionary of neutron_vif_uuid: dest_network_ref vifs = self._session.VM.get_VIFs(vm_ref) + default_net_ref = vif_uuid_map.get('') for vif in vifs: other_config = self._session.VIF.get_other_config(vif) neutron_id = other_config.get('nicira-iface-id') - if neutron_id is None or neutron_id not in vif_uuid_map.keys(): + network_ref = vif_uuid_map.get(neutron_id, default_net_ref) + if network_ref is None: raise exception.MigrationError( reason=_('No mapping for source network %s') % ( neutron_id)) - network_ref = vif_uuid_map[neutron_id] vif_map[vif] = network_ref return vif_map