From 662a793056d4544c9c9d73fc21b99d77404537cc Mon Sep 17 00:00:00 2001 From: Andrew Laski Date: Wed, 8 May 2013 15:59:55 -0400 Subject: Raise InstanceInvalidState for double hard reboot A hard reboot is not allowed if the instance task_state is REBOOTING_HARD so check for that state and raise InstanceInvalidState. This returns the correct status of 409 to the caller. Previously the hard reboot would fail the the expected_task_state check on db.instance_update_and_get_original which would log a traceback and return a 500 to the caller. Bug 1157237 Change-Id: Ifb6111790352da5c404289b218c50d8104384301 --- nova/compute/api.py | 6 +++-- .../api/openstack/compute/test_server_actions.py | 28 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 512b991d7..36c158114 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -1721,8 +1721,10 @@ class API(base.Base): task_states.SUSPENDING]) def reboot(self, context, instance, reboot_type): """Reboot the given instance.""" - if (reboot_type == 'SOFT' and - instance['task_state'] == task_states.REBOOTING): + if ((reboot_type == 'SOFT' and + instance['task_state'] == task_states.REBOOTING) or + (reboot_type == 'HARD' and + instance['task_state'] == task_states.REBOOTING_HARD)): raise exception.InstanceInvalidState( attr='task_state', instance_uuid=instance['uuid'], diff --git a/nova/tests/api/openstack/compute/test_server_actions.py b/nova/tests/api/openstack/compute/test_server_actions.py index fe65fe0d9..7347aa169 100644 --- a/nova/tests/api/openstack/compute/test_server_actions.py +++ b/nova/tests/api/openstack/compute/test_server_actions.py @@ -195,6 +195,34 @@ class ServerActionsControllerTest(test.TestCase): self.controller._action_reboot, req, FAKE_UUID, body) + def test_reboot_soft_with_soft_in_progress_raises_conflict(self): + body = dict(reboot=dict(type="SOFT")) + req = fakes.HTTPRequest.blank(self.url) + self.stubs.Set(db, 'instance_get_by_uuid', + fakes.fake_instance_get(vm_state=vm_states.ACTIVE, + task_state=task_states.REBOOTING)) + self.assertRaises(webob.exc.HTTPConflict, + self.controller._action_reboot, + req, FAKE_UUID, body) + + def test_reboot_hard_with_soft_in_progress_does_not_raise(self): + body = dict(reboot=dict(type="HARD")) + req = fakes.HTTPRequest.blank(self.url) + self.stubs.Set(db, 'instance_get_by_uuid', + fakes.fake_instance_get(vm_state=vm_states.ACTIVE, + task_state=task_states.REBOOTING)) + self.controller._action_reboot(req, FAKE_UUID, body) + + def test_reboot_hard_with_hard_in_progress_raises_conflict(self): + body = dict(reboot=dict(type="HARD")) + req = fakes.HTTPRequest.blank(self.url) + self.stubs.Set(db, 'instance_get_by_uuid', + fakes.fake_instance_get(vm_state=vm_states.ACTIVE, + task_state=task_states.REBOOTING_HARD)) + self.assertRaises(webob.exc.HTTPConflict, + self.controller._action_reboot, + req, FAKE_UUID, body) + def test_rebuild_accepted_minimum(self): return_server = fakes.fake_instance_get(image_ref='2', vm_state=vm_states.ACTIVE, host='fake_host') -- cgit