diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 33459900c5..5d2e5b56a9 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -5470,18 +5470,27 @@ class ComputeManager(manager.Manager): self._notify_about_instance_usage( context, instance, "live_migration.rollback.dest.start", network_info=network_info) + try: + # NOTE(tr3buchet): tear down networks on destination host + self.network_api.setup_networks_on_host(context, instance, + self.host, teardown=True) + except Exception: + with excutils.save_and_reraise_exception(): + # NOTE(tdurakov): even if teardown networks fails driver + # should try to rollback live migration on destination. + LOG.exception( + _LE('An error occurred while deallocating network.'), + instance=instance) + finally: + # always run this even if setup_networks_on_host fails + # NOTE(vish): The mapping is passed in so the driver can disconnect + # from remote volumes if necessary + block_device_info = self._get_instance_block_device_info(context, + instance) + self.driver.rollback_live_migration_at_destination( + context, instance, network_info, block_device_info, + destroy_disks=destroy_disks, migrate_data=migrate_data) - # NOTE(tr3buchet): tear down networks on destination host - self.network_api.setup_networks_on_host(context, instance, - self.host, teardown=True) - - # NOTE(vish): The mapping is passed in so the driver can disconnect - # from remote volumes if necessary - block_device_info = self._get_instance_block_device_info(context, - instance) - self.driver.rollback_live_migration_at_destination( - context, instance, network_info, block_device_info, - destroy_disks=destroy_disks, migrate_data=migrate_data) self._notify_about_instance_usage( context, instance, "live_migration.rollback.dest.end", network_info=network_info) diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py index 4eca3c76ca..9b293947e0 100644 --- a/nova/tests/unit/compute/test_compute.py +++ b/nova/tests/unit/compute/test_compute.py @@ -5968,6 +5968,21 @@ class ComputeTestCase(BaseTestCase): self.assertEqual(msg.event_type, 'compute.instance.live_migration.rollback.dest.end') + @mock.patch('nova.network.api.API.setup_networks_on_host', + side_effect=test.TestingException) + @mock.patch('nova.virt.driver.ComputeDriver.' + 'rollback_live_migration_at_destination') + def test_rollback_live_migration_at_destination_network_fails( + self, mock_rollback, net_mock): + c = context.get_admin_context() + instance = self._create_fake_instance_obj() + self.assertRaises(test.TestingException, + self.compute.rollback_live_migration_at_destination, + c, instance, destroy_disks=True, migrate_data={}) + mock_rollback.assert_called_once_with(c, instance, mock.ANY, mock.ANY, + destroy_disks=True, + migrate_data={}) + def test_run_kill_vm(self): # Detect when a vm is terminated behind the scenes. instance = self._create_fake_instance_obj()