From a9e4e2c9a5aaa4d675057790816aa395bc27e9bc Mon Sep 17 00:00:00 2001 From: George Shuklin Date: Fri, 1 May 2015 17:57:00 +0300 Subject: [PATCH] If rescue failed set instance to ERROR The compute API will allow attempting to rescue an instance that is in active/stopped/error state. The compute manager will power off the instance before calling driver.rescue. If the rescue call fails in the virt driver, we should set the instance to ERROR state since we (1) know the instance is definitely not active since the compute manager powered it off and (2) we don't know what failed in the virt driver, so punting and putting the instance into ERROR state is better than leaving it broken and not signaling that with the vm_state. Co-Authored-By: Matt Riedemann Closes-Bug: 1418590 Change-Id: Ia1054d3f9193f876803f8b5a26d00bd9d5d66c12 --- nova/compute/manager.py | 1 + nova/tests/unit/compute/test_compute.py | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 7e96f3480299..27f621ffe58d 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -3205,6 +3205,7 @@ class ComputeManager(manager.Manager): except Exception as e: LOG.exception(_LE("Error trying to Rescue Instance"), instance=instance) + self._set_instance_obj_error_state(context, instance) raise exception.InstanceNotRescuable( instance_id=instance.uuid, reason=_("Driver Error: %s") % e) diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py index 37b3f8f0d21e..b14dec79deb1 100644 --- a/nova/tests/unit/compute/test_compute.py +++ b/nova/tests/unit/compute/test_compute.py @@ -2208,7 +2208,7 @@ class ComputeTestCase(BaseTestCase): self.compute.terminate_instance(self.context, instance, [], []) def test_rescue_handle_err(self): - # If the driver fails to rescue, instance state should remain the same + # If the driver fails to rescue, instance state should got to ERROR # and the exception should be converted to InstanceNotRescuable inst_obj = self._create_fake_instance_obj() self.mox.StubOutWithMock(self.compute, '_get_rescue_image') @@ -2224,7 +2224,6 @@ class ComputeTestCase(BaseTestCase): expected_message = ('Instance %s cannot be rescued: ' 'Driver Error: Try again later' % inst_obj.uuid) - inst_obj.vm_state = 'some_random_state' with testtools.ExpectedException( exception.InstanceNotRescuable, expected_message): @@ -2233,7 +2232,7 @@ class ComputeTestCase(BaseTestCase): rescue_password='password', rescue_image_ref=None, clean_shutdown=True) - self.assertEqual('some_random_state', inst_obj.vm_state) + self.assertEqual(vm_states.ERROR, inst_obj.vm_state) @mock.patch.object(image_api.API, "get") @mock.patch.object(nova.virt.fake.FakeDriver, "rescue")