From 5eed26fec4185dfcd8e9c1877a5a47068b0f3cc6 Mon Sep 17 00:00:00 2001 From: Wangpan Date: Wed, 27 Feb 2013 14:41:41 +0800 Subject: Catching InstanceNotFound exception during reboot instance If the instance is deleted during reboot(most of soft reboot), an InstanceNotFound exception may be raised when update instance info to DB, and the instance may become running deleted, so catching the exception and logging it. This commit is a supplement of bug #1111213, which may result in the instance becomes running deleted, when deleting an instance after soft reboot. Change-Id: I3e8df109d431040c64e87f16ca84ff5b62dde898 --- nova/compute/manager.py | 12 ++++++++---- nova/tests/compute/test_compute.py | 33 +++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index d9e8435cc..224ac01e0 100755 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1583,10 +1583,14 @@ class ComputeManager(manager.SchedulerDependentManager): # Fall through and reset task_state to None current_power_state = self._get_power_state(context, instance) - instance = self._instance_update(context, instance['uuid'], - power_state=current_power_state, - vm_state=vm_states.ACTIVE, - task_state=None) + try: + instance = self._instance_update(context, instance['uuid'], + power_state=current_power_state, + vm_state=vm_states.ACTIVE, + task_state=None) + except exception.InstanceNotFound: + LOG.warn(_("Instance disappeared during reboot"), + context=context, instance=instance) self._notify_about_instance_usage(context, instance, "reboot.end") diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 7869b76cc..7f85eee49 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -1085,7 +1085,7 @@ class ComputeTestCase(BaseTestCase): self.compute.terminate_instance(self.context, instance=jsonutils.to_primitive(instance)) - def _test_reboot(self, soft, legacy_nwinfo_driver): + def _test_reboot(self, soft, legacy_nwinfo_driver, test_delete=False): # This is a true unit test, so we don't need the network stubs. fake_network.unset_stub_network_methods(self.stubs) @@ -1164,13 +1164,24 @@ class ComputeTestCase(BaseTestCase): # Power state should be updated again self.compute._get_power_state(econtext, updated_instance1).AndReturn(fake_power_state2) - self.compute._instance_update(econtext, updated_instance1['uuid'], - power_state=fake_power_state2, - task_state=None, - vm_state=vm_states.ACTIVE).AndReturn(updated_instance2) - self.compute._notify_about_instance_usage(econtext, - updated_instance2, - 'reboot.end') + if test_delete: + self.compute._instance_update(econtext, updated_instance1['uuid'], + power_state=fake_power_state2, + task_state=None, + vm_state=vm_states.ACTIVE).AndRaise( + exception.InstanceNotFound( + instance_id=updated_instance1['uuid'])) + self.compute._notify_about_instance_usage(econtext, + updated_instance1, + 'reboot.end') + else: + self.compute._instance_update(econtext, updated_instance1['uuid'], + power_state=fake_power_state2, + task_state=None, + vm_state=vm_states.ACTIVE).AndReturn(updated_instance2) + self.compute._notify_about_instance_usage(econtext, + updated_instance2, + 'reboot.end') self.mox.ReplayAll() self.compute.reboot_instance(self.context, instance=instance, @@ -1181,9 +1192,15 @@ class ComputeTestCase(BaseTestCase): def test_reboot_soft(self): self._test_reboot(True, False) + def test_reboot_soft_and_delete(self): + self._test_reboot(True, False, True) + def test_reboot_hard(self): self._test_reboot(False, False) + def test_reboot_hard_and_delete(self): + self._test_reboot(False, False, True) + def test_reboot_soft_legacy_nwinfo_driver(self): self._test_reboot(True, True) -- cgit