Fix drop_move_claim() on revert resize

On revert_resize(), the migration context was dropped hence setting it
to None.  The problem is that the migration context is needed when
executing finish_revert_resize() so that the neutron port can be updated
with the right binding profile.

This patch moves the instance.drop_migration_context() call out from the
resource tracker so that the migration context can be dropped at the
appropriate times: after RT.drop_move_claim() is called in the compute
manager's confirm_resize() call and after the virt driver's
finish_revert_resize() in the compute manager's finish_revert_resize()
call.

NOTE(lyarwood): Conflict caused by the DB warning clean up in I4529b4bdc.

Conflicts:
        nova/tests/unit/compute/test_compute_mgr.py

Change-Id: I1b7b2573de4380576dd8b801ed59d8955b0ab72a
Partial-bug: #1512880
(cherry picked from commit 2f073fd8df)
This commit is contained in:
Ludovic Beliveau 2016-07-29 11:51:47 -04:00 committed by Lee Yarwood
parent 9d7ab8274c
commit 8a2d7d4d4f
5 changed files with 75 additions and 3 deletions

View File

@ -298,3 +298,4 @@ class MoveClaim(Claim):
self.tracker.drop_move_claim(
self.context,
self.instance, instance_type=self.instance_type)
self.instance.drop_migration_context()

View File

@ -3437,6 +3437,7 @@ class ComputeManager(manager.Manager):
rt = self._get_resource_tracker(migration.source_node)
rt.drop_move_claim(context, instance, old_instance_type,
prefix='old_')
instance.drop_migration_context()
# NOTE(mriedem): The old_vm_state could be STOPPED but the user
# might have manually powered up the instance to confirm the
@ -3588,6 +3589,7 @@ class ComputeManager(manager.Manager):
network_info,
block_device_info, power_on)
instance.drop_migration_context()
instance.launched_at = timeutils.utcnow()
instance.save(expected_task_state=task_states.RESIZE_REVERTING)

View File

@ -377,8 +377,6 @@ class ResourceTracker(object):
ctxt = context.elevated()
self._update(ctxt)
instance.drop_migration_context()
@utils.synchronized(COMPUTE_RESOURCE_SEMAPHORE)
def update_usage(self, context, instance):
"""Update the resource usage and stats after a change in an

View File

@ -415,9 +415,11 @@ class MoveClaimTestCase(ClaimTestCase):
limits=limits)
return get_claim()
def test_abort(self):
@mock.patch('nova.objects.Instance.drop_migration_context')
def test_abort(self, mock_drop):
claim = self._abort()
self.assertTrue(claim.tracker.rcalled)
mock_drop.assert_called_once_with()
def test_image_meta(self):
claim = self._claim()

View File

@ -31,6 +31,7 @@ import nova
from nova.compute import build_results
from nova.compute import manager
from nova.compute import power_state
from nova.compute import resource_tracker
from nova.compute import task_states
from nova.compute import utils as compute_utils
from nova.compute import vm_states
@ -4620,6 +4621,7 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase):
finish_revert_migration,
get_resource_tracker):
self.instance.migration_context = objects.MigrationContext()
self.migration.source_compute = self.instance['host']
self.migration.source_node = self.instance['host']
self.compute.finish_revert_resize(context=self.context,
@ -4631,6 +4633,73 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase):
do_test()
def test_finish_revert_resize_migration_context(self):
fake_rt = resource_tracker.ResourceTracker(None, None, None)
fake_rt.tracked_migrations[self.instance['uuid']] = (
self.migration, None)
@mock.patch('nova.compute.rpcapi.ComputeAPI.finish_revert_resize')
@mock.patch.object(fake_rt, '_get_instance_type', return_value=None)
@mock.patch.object(self.instance, 'revert_migration_context')
@mock.patch.object(self.compute.network_api, 'get_instance_nw_info')
@mock.patch.object(self.compute, '_is_instance_storage_shared')
@mock.patch.object(self.compute, '_instance_update')
@mock.patch.object(self.compute, '_get_resource_tracker',
return_value=fake_rt)
@mock.patch.object(self.compute.driver, 'destroy')
@mock.patch.object(self.compute.network_api, 'setup_networks_on_host')
@mock.patch.object(self.compute.network_api, 'migrate_instance_start')
@mock.patch.object(compute_utils, 'notify_usage_exists')
@mock.patch.object(self.migration, 'save')
@mock.patch.object(objects.BlockDeviceMappingList,
'get_by_instance_uuid')
def do_revert_resize(mock_get_by_instance_uuid,
mock_migration_save,
mock_notify_usage_exists,
mock_migrate_instance_start,
mock_setup_networks_on_host,
mock_destroy,
mock_get_resource_tracker,
mock_instance_update,
mock_is_instance_storage_shared,
mock_get_instance_nw_info,
mock_revert_migration_context,
mock_get_itype,
mock_finish_revert):
self.instance.migration_context = objects.MigrationContext()
self.migration.source_compute = self.instance['host']
self.migration.source_node = self.instance['node']
self.compute.revert_resize(context=self.context,
migration=self.migration,
instance=self.instance,
reservations=None)
self.assertIsNotNone(self.instance.migration_context)
@mock.patch.object(self.compute, "_notify_about_instance_usage")
@mock.patch.object(self.compute, "_set_instance_info")
@mock.patch.object(self.instance, 'save')
@mock.patch.object(self.migration, 'save')
@mock.patch.object(self.compute.network_api, 'setup_networks_on_host')
@mock.patch.object(self.compute.network_api, 'migrate_instance_finish')
@mock.patch.object(self.compute.network_api, 'get_instance_nw_info')
def do_finish_revert_resize(mock_get_instance_nw_info,
mock_instance_finish,
mock_setup_network,
mock_mig_save,
mock_inst_save,
mock_set,
mock_notify):
self.compute.finish_revert_resize(context=self.context,
instance=self.instance,
reservations=None,
migration=self.migration)
self.assertIsNone(self.instance.migration_context)
do_revert_resize()
do_finish_revert_resize()
def test_consoles_enabled(self):
self.flags(enabled=False, group='vnc')
self.flags(enabled=False, group='spice')