From a84be486c80da690b627d99644a5ed656757097c Mon Sep 17 00:00:00 2001 From: Takashi NATSUME Date: Fri, 13 Feb 2015 14:33:11 +0900 Subject: [PATCH] Handle MessagingException in unshelving instance Add Handling MessagingException in nova-conductor when unshelving instance Change-Id: I4dd95ee08e9618b8fd51f043c0f89f4ddcf1cb35 Closes-Bug: #1367186 --- nova/conductor/manager.py | 6 +++++ nova/tests/unit/conductor/test_conductor.py | 25 +++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index 213c269b8932..25bf082cbe83 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -766,6 +766,12 @@ class ComputeTaskManager(base.Base): LOG.warning(_LW("No valid host found for unshelve instance"), instance=instance) return + except Exception: + with excutils.save_and_reraise_exception(): + instance.task_state = None + instance.save() + LOG.error(_LE("Unshelve attempted but an error " + "has occurred"), instance=instance) else: LOG.error(_LE('Unshelve attempted but vm_state not SHELVED or ' 'SHELVED_OFFLOADED'), instance=instance) diff --git a/nova/tests/unit/conductor/test_conductor.py b/nova/tests/unit/conductor/test_conductor.py index 63fe9cf62821..f722817124e6 100644 --- a/nova/tests/unit/conductor/test_conductor.py +++ b/nova/tests/unit/conductor/test_conductor.py @@ -40,6 +40,7 @@ from nova import context from nova import db from nova.db.sqlalchemy import models from nova import exception as exc +from nova.image import api as image_api from nova import notifications from nova import objects from nova.objects import base as obj_base @@ -1545,6 +1546,30 @@ class _BaseTaskTestCase(object): show_deleted=False)]) self.assertEqual(vm_states.SHELVED_OFFLOADED, instance.vm_state) + @mock.patch.object(conductor_manager.ComputeTaskManager, + '_schedule_instances', + side_effect=messaging.MessagingTimeout()) + @mock.patch.object(image_api.API, 'get', return_value='fake_image') + def test_unshelve_instance_schedule_and_rebuild_messaging_exception( + self, mock_get_image, mock_schedule_instances): + instance = self._create_fake_instance_obj() + instance.vm_state = vm_states.SHELVED_OFFLOADED + instance.task_state = task_states.UNSHELVING + instance.save() + system_metadata = instance.system_metadata + + system_metadata['shelved_at'] = timeutils.utcnow() + system_metadata['shelved_image_id'] = 'fake_image_id' + system_metadata['shelved_host'] = 'fake-mini' + self.assertRaises(messaging.MessagingTimeout, + self.conductor_manager.unshelve_instance, + self.context, instance) + mock_get_image.assert_has_calls([mock.call(self.context, + system_metadata['shelved_image_id'], + show_deleted=False)]) + self.assertEqual(vm_states.SHELVED_OFFLOADED, instance.vm_state) + self.assertIsNone(instance.task_state) + def test_unshelve_instance_schedule_and_rebuild_volume_backed(self): instance = self._create_fake_instance_obj() instance.vm_state = vm_states.SHELVED_OFFLOADED