Reset instance to current vm_state if rolling back in resize_instance
You can resize a stopped instance and if the compute driver raises InstanceFaultRollback from migrate_disk_and_power_off, the _error_out_instance_on_exception decorator, used in the _resize_instance method, will by default reset the instance vm_state to ACTIVE even though the guest is stopped. The driver could raise InstanceFaultRollback if you try resizing the root disk down on a non-volume-backed instance. This builds on [1] and does the same thing as prep_resize [2] for making sure the original vm_state is reset on InstanceFaultRollback. [1] Ie4f9177f4d54cbc7dbcf58bd107fd5f24c60d8bb [2] I17543ecb572934ecc7d0bbc7a4ad2f537fa499bc Change-Id: Iff1f9f28a1e4ecf00368cbcac27b7687a5eb0dcf Closes-Bug: #1551703
This commit is contained in:
parent
9742a64403
commit
5a20996405
|
@ -5032,7 +5032,12 @@ class ComputeManager(manager.Manager):
|
|||
def _resize_instance(self, context, instance, image,
|
||||
migration, instance_type, clean_shutdown,
|
||||
request_spec):
|
||||
with self._error_out_instance_on_exception(context, instance), \
|
||||
# Pass instance_state=instance.vm_state because we can resize
|
||||
# a STOPPED server and we don't want to set it back to ACTIVE
|
||||
# in case migrate_disk_and_power_off raises InstanceFaultRollback.
|
||||
instance_state = instance.vm_state
|
||||
with self._error_out_instance_on_exception(
|
||||
context, instance, instance_state=instance_state), \
|
||||
errors_out_migration_ctxt(migration):
|
||||
network_info = self.network_api.get_instance_nw_info(context,
|
||||
instance)
|
||||
|
|
|
@ -7829,6 +7829,28 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase,
|
|||
# Assert that we set the migration to an error state
|
||||
self.assertEqual("error", self.migration.status)
|
||||
|
||||
def test_resize_instance_fail_rollback_stays_stopped(self):
|
||||
"""Tests that when the driver's migrate_disk_and_power_off method
|
||||
raises InstanceFaultRollback that the instance vm_state is preserved
|
||||
rather than reset to ACTIVE which would be wrong if resizing a STOPPED
|
||||
server.
|
||||
"""
|
||||
with self._mock_resize_instance() as (
|
||||
migrate_disk_and_power_off, notify):
|
||||
migrate_disk_and_power_off.side_effect = \
|
||||
exception.InstanceFaultRollback(
|
||||
exception.ResizeError(reason='unable to resize disk down'))
|
||||
self.instance.vm_state = vm_states.STOPPED
|
||||
self.assertRaises(
|
||||
exception.ResizeError, self.compute.resize_instance,
|
||||
context=self.context, instance=self.instance, image=self.image,
|
||||
migration=self.migration,
|
||||
instance_type='type', clean_shutdown=True,
|
||||
request_spec=objects.RequestSpec())
|
||||
|
||||
# Assert the instance vm_state was unchanged.
|
||||
self.assertEqual(vm_states.STOPPED, self.instance.vm_state)
|
||||
|
||||
def test_resize_instance_notify_failure(self):
|
||||
# Raise an exception sending the end notification, which is after we
|
||||
# cast the migration to the destination host
|
||||
|
|
Loading…
Reference in New Issue