Update RequestSpec.flavor on resize_revert

Since I8abdf58a6537dd5e15a012ea37a7b48abd726579 in Newton
we update the RequestSpec.flavor to the new flavor during
a resize. However, if the resize is reverted, we didn't
revert the RequestSpec.flavor to the previous flavor
on the instance, which could cause issues later when
moving the instance since the scheduler will get a
RequestSpec with a flavor that doesn't match the actual
flavor on the instance.

This fixes the bug by updating the RequestSpec.flavor
with instance.old_flavor on resize_revert in the API.
Functional test wrinkles are added.

This fix was ported from the starlingx-staging/stx-nova
repo commit 71acfeae0.

Change-Id: Ic6e74702f2a5b57b437f4ffdfbc86c1e34cdac7d
Closes-Bug: #1785339
(cherry picked from commit ef3849e2da)
(cherry picked from commit 9125fc7caf)
This commit is contained in:
Matt Riedemann 2018-08-03 19:11:37 -04:00
parent 5a960e0fa2
commit f2d2a9a7c5
3 changed files with 31 additions and 2 deletions

View File

@ -3287,6 +3287,21 @@ class API(base.Base):
self._record_action_start(context, instance,
instance_actions.REVERT_RESIZE)
# Conductor updated the RequestSpec.flavor during the initial resize
# operation to point at the new flavor, so we need to update the
# RequestSpec to point back at the original flavor, otherwise
# subsequent move operations through the scheduler will be using the
# wrong flavor.
try:
reqspec = objects.RequestSpec.get_by_instance_uuid(
context, instance.uuid)
reqspec.flavor = instance.old_flavor
reqspec.save()
except exception.RequestSpecNotFound:
# TODO(mriedem): Make this a failure in Stein when we drop
# compatibility for missing request specs.
pass
# TODO(melwitt): We're not rechecking for strict quota here to guard
# against going over quota during a race at this time because the
# resource consumption for this operation is written to the database

View File

@ -1822,6 +1822,11 @@ class ServerMovingTests(ProviderUsageBaseTestCase):
self._run_periodics()
_check_allocation()
# Make sure the RequestSpec.flavor matches the new_flavor.
ctxt = context.get_admin_context()
reqspec = objects.RequestSpec.get_by_instance_uuid(ctxt, server['id'])
self.assertEqual(new_flavor['id'], reqspec.flavor.flavorid)
def test_resize_revert(self):
self._test_resize_revert(dest_hostname='host1')
@ -1863,6 +1868,11 @@ class ServerMovingTests(ProviderUsageBaseTestCase):
self.api.post_server_action(server['id'], post)
self._wait_for_state_change(self.api, server, 'ACTIVE')
# Make sure the RequestSpec.flavor matches the original flavor.
ctxt = context.get_admin_context()
reqspec = objects.RequestSpec.get_by_instance_uuid(ctxt, server['id'])
self.assertEqual(self.flavor1['id'], reqspec.flavor.flavorid)
self._run_periodics()
# the original host expected to have the old resource allocation

View File

@ -1821,8 +1821,9 @@ class _ComputeAPIUnitTestMixIn(object):
@mock.patch('nova.objects.Quotas.check_deltas')
@mock.patch('nova.objects.Migration.get_by_instance_and_status')
@mock.patch('nova.context.RequestContext.elevated')
def _test_revert_resize(self, mock_elevated, mock_get_migration,
mock_check):
@mock.patch('nova.objects.RequestSpec.get_by_instance_uuid')
def _test_revert_resize(self, mock_get_reqspec, mock_elevated,
mock_get_migration, mock_check):
params = dict(vm_state=vm_states.RESIZED)
fake_inst = self._create_instance_obj(params=params)
fake_inst.old_flavor = fake_inst.flavor
@ -1854,6 +1855,9 @@ class _ComputeAPIUnitTestMixIn(object):
self.context, fake_inst['uuid'], 'finished')
mock_inst_save.assert_called_once_with(expected_task_state=[None])
mock_mig_save.assert_called_once_with()
mock_get_reqspec.assert_called_once_with(
self.context, fake_inst.uuid)
mock_get_reqspec.return_value.save.assert_called_once_with()
mock_record_action.assert_called_once_with(self.context, fake_inst,
'revertResize')
mock_revert_resize.assert_called_once_with(