Skip to content

Commit fae51fc

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Raise InstanceFaultRollback for UnableToMigrateToSelf from _prep_resize"
2 parents f502a33 + d1931ac commit fae51fc

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

nova/compute/manager.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4326,8 +4326,12 @@ def _prep_resize(self, context, image, instance, instance_type,
43264326
# check driver whether support migrate to same host
43274327
if not self.driver.capabilities.get(
43284328
'supports_migrate_to_same_host', False):
4329-
raise exception.UnableToMigrateToSelf(
4330-
instance_id=instance.uuid, host=self.host)
4329+
# Raise InstanceFaultRollback so that the
4330+
# _error_out_instance_on_exception context manager in
4331+
# prep_resize will set the instance.vm_state properly.
4332+
raise exception.InstanceFaultRollback(
4333+
inner_exception=exception.UnableToMigrateToSelf(
4334+
instance_id=instance.uuid, host=self.host))
43314335

43324336
# NOTE(danms): Stash the new instance_type to avoid having to
43334337
# look it up in the database later
@@ -4401,8 +4405,13 @@ def prep_resize(self, context, image, instance, instance_type,
44014405
if node is None:
44024406
node = self._get_nodename(instance, refresh=True)
44034407

4404-
with self._error_out_instance_on_exception(context, instance), \
4405-
errors_out_migration_ctxt(migration):
4408+
# Pass instance_state=instance.vm_state because we can resize
4409+
# a STOPPED server and we don't want to set it back to ACTIVE
4410+
# in case _prep_resize fails.
4411+
instance_state = instance.vm_state
4412+
with self._error_out_instance_on_exception(
4413+
context, instance, instance_state=instance_state),\
4414+
errors_out_migration_ctxt(migration):
44064415
self._send_prep_resize_notifications(
44074416
context, instance, fields.NotificationPhase.START,
44084417
instance_type)

nova/tests/unit/compute/test_compute_mgr.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8834,6 +8834,68 @@ def doit(mock_pr, mock_r):
88348834

88358835
doit()
88368836

8837+
def test_prep_resize_fails_unable_to_migrate_to_self(self):
8838+
"""Asserts that _prep_resize handles UnableToMigrateToSelf when
8839+
_prep_resize is called on the host on which the instance lives and
8840+
the flavor is not changing.
8841+
"""
8842+
instance = fake_instance.fake_instance_obj(
8843+
self.context, host=self.compute.host,
8844+
expected_attrs=['system_metadata', 'flavor'])
8845+
migration = mock.MagicMock(spec='nova.objects.Migration')
8846+
with mock.patch.dict(self.compute.driver.capabilities,
8847+
{'supports_migrate_to_same_host': False}):
8848+
ex = self.assertRaises(
8849+
exception.InstanceFaultRollback, self.compute._prep_resize,
8850+
self.context, instance.image_meta, instance, instance.flavor,
8851+
filter_properties={}, node=instance.node, migration=migration)
8852+
self.assertIsInstance(
8853+
ex.inner_exception, exception.UnableToMigrateToSelf)
8854+
8855+
@mock.patch('nova.compute.utils.notify_usage_exists')
8856+
@mock.patch('nova.compute.manager.ComputeManager.'
8857+
'_notify_about_instance_usage')
8858+
@mock.patch('nova.compute.utils.notify_about_resize_prep_instance')
8859+
@mock.patch('nova.objects.Instance.save')
8860+
@mock.patch('nova.compute.manager.ComputeManager._revert_allocation')
8861+
@mock.patch('nova.compute.manager.ComputeManager.'
8862+
'_reschedule_resize_or_reraise')
8863+
@mock.patch('nova.compute.utils.add_instance_fault_from_exc')
8864+
def test_prep_resize_fails_rollback(
8865+
self, add_instance_fault_from_exc, _reschedule_resize_or_reraise,
8866+
_revert_allocation, mock_instance_save,
8867+
notify_about_resize_prep_instance, _notify_about_instance_usage,
8868+
notify_usage_exists):
8869+
"""Tests that if _prep_resize raises InstanceFaultRollback, the
8870+
instance.vm_state is reset properly in _error_out_instance_on_exception
8871+
"""
8872+
instance = fake_instance.fake_instance_obj(
8873+
self.context, host=self.compute.host, vm_state=vm_states.STOPPED,
8874+
expected_attrs=['system_metadata', 'flavor'])
8875+
migration = mock.MagicMock(spec='nova.objects.Migration')
8876+
request_spec = mock.MagicMock(spec='nova.objects.RequestSpec')
8877+
ex = exception.InstanceFaultRollback(
8878+
inner_exception=exception.UnableToMigrateToSelf(
8879+
instance_id=instance.uuid, host=instance.host))
8880+
8881+
def fake_reschedule_resize_or_reraise(*args, **kwargs):
8882+
raise ex
8883+
8884+
_reschedule_resize_or_reraise.side_effect = (
8885+
fake_reschedule_resize_or_reraise)
8886+
8887+
with mock.patch.object(self.compute, '_prep_resize', side_effect=ex):
8888+
self.assertRaises(
8889+
# _error_out_instance_on_exception should reraise the
8890+
# UnableToMigrateToSelf inside InstanceFaultRollback.
8891+
exception.UnableToMigrateToSelf, self.compute.prep_resize,
8892+
self.context, instance.image_meta, instance, instance.flavor,
8893+
request_spec, filter_properties={}, node=instance.node,
8894+
clean_shutdown=True, migration=migration, host_list=[])
8895+
# The instance.vm_state should remain unchanged
8896+
# (_error_out_instance_on_exception will set to ACTIVE by default).
8897+
self.assertEqual(vm_states.STOPPED, instance.vm_state)
8898+
88378899
def test__claim_pci_for_instance_vifs(self):
88388900
@mock.patch.object(self.compute, 'rt')
88398901
@mock.patch.object(pci_request, 'get_instance_pci_request_from_vif')

nova/tests/unit/fake_instance.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ def fake_instance_obj(context, obj_instance_class=None, **updates):
132132
inst.vcpus = flavor.vcpus
133133
if 'memory_mb' in flavor and 'memory_mb' not in updates:
134134
inst.memory_mb = flavor.memory_mb
135+
if ('instance_type_id' not in inst or inst.instance_type_id is None
136+
and 'id' in flavor):
137+
inst.instance_type_id = flavor.id
135138
inst.old_flavor = None
136139
inst.new_flavor = None
137140
inst.obj_reset_changes()

0 commit comments

Comments
 (0)