Merge "Stop failed live-migrates getting stuck migrating" into stable/newton

This commit is contained in:
Jenkins 2017-08-12 01:21:23 +00:00 committed by Gerrit Code Review
commit 508f1663ae
2 changed files with 52 additions and 3 deletions

View File

@ -5297,12 +5297,16 @@ class ComputeManager(manager.Manager):
self._rollback_live_migration,
block_migration, migrate_data)
except Exception:
# Executing live migration
# live_migration might raises exceptions, but
# nothing must be recovered in this version.
LOG.exception(_LE('Live migration failed.'), instance=instance)
with excutils.save_and_reraise_exception():
# Put instance and migration into error state,
# as its almost certainly too late to rollback
self._set_migration_status(migration, 'error')
# first refresh instance as it may have got updated by
# post_live_migration_at_destination
instance.refresh()
self._set_instance_obj_error_state(context, instance,
clean_task_state=True)
@wrap_exception()
@wrap_instance_event(prefix='compute')

View File

@ -5801,6 +5801,51 @@ class ComputeTestCase(BaseTestCase):
mock_post.assert_called_once_with(c, instance, False, dest)
mock_clear.assert_called_once_with(mock.ANY)
@mock.patch.object(compute_rpcapi.ComputeAPI, 'pre_live_migration')
@mock.patch.object(network_api.API, 'migrate_instance_start')
@mock.patch.object(compute_rpcapi.ComputeAPI,
'post_live_migration_at_destination')
@mock.patch.object(compute_manager.InstanceEvents,
'clear_events_for_instance')
@mock.patch.object(compute_utils, 'EventReporter')
@mock.patch('nova.objects.Migration.save')
def test_live_migration_handles_errors_correctly(self,
mock_save, mock_event, mock_clear,
mock_post, mock_migrate, mock_pre):
# Confirm live_migration() works as expected correctly.
# creating instance testdata
c = context.get_admin_context()
instance = self._create_fake_instance_obj(context=c)
instance.host = self.compute.host
dest = 'desthost'
migrate_data = migrate_data_obj.LibvirtLiveMigrateData(
is_shared_instance_path=False,
is_shared_block_storage=False)
mock_pre.return_value = migrate_data
# start test
migration = objects.Migration()
with mock.patch.object(self.compute.driver,
'cleanup') as mock_cleanup:
mock_cleanup.side_effect = test.TestingException
self.assertRaises(test.TestingException,
self.compute.live_migration,
c, dest, instance, False, migration, migrate_data)
# ensure we have updated the instance and migration objects
self.assertEqual(vm_states.ERROR, instance.vm_state)
self.assertIsNone(instance.task_state)
self.assertEqual("error", migration.status)
mock_pre.assert_called_once_with(c, instance, False, None,
dest, migrate_data)
self.assertEqual(0, mock_clear.call_count)
# cleanup
instance.destroy()
@mock.patch.object(fake.FakeDriver, 'unfilter_instance')
@mock.patch.object(network_api.API, 'migrate_instance_start')
@mock.patch.object(compute_rpcapi.ComputeAPI,