diff options
| author | Mathew Odden <mrodden@us.ibm.com> | 2012-08-31 23:51:12 -0500 |
|---|---|---|
| committer | Mathew Odden <mrodden@us.ibm.com> | 2012-09-01 14:25:30 -0500 |
| commit | a692e7750f9aa6394c1ab9df5e22ecb908e7eb29 (patch) | |
| tree | b96f8cf90ffca81d170dd6a948481ec6519a772e | |
| parent | 0318efe625682ee8703b91f363a966200503782f (diff) | |
Allow hard reboot of a soft rebooting instance
Allow hard reboot API calls to succeed if the task status is
soft reboot, but not hard reboot.
This was discussed in the previous change for this bug in
Iae95b121c5c623e1eaa6fba52b13170413722d2d
Fixes bug #944015
Change-Id: I0f78faad524774dbbcad0bf2adafed3802dfeb75
| -rw-r--r-- | nova/compute/api.py | 11 | ||||
| -rw-r--r-- | nova/tests/compute/test_compute.py | 36 |
2 files changed, 45 insertions, 2 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py index fa413fdb1..ffc034063 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -1238,14 +1238,21 @@ class API(base.Base): @check_instance_lock @check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.STOPPED, vm_states.RESCUED], - task_state=[None]) + task_state=[None, task_states.REBOOTING]) def reboot(self, context, instance, reboot_type): """Reboot the given instance.""" + if (reboot_type == 'SOFT' and + instance['task_state'] == task_states.REBOOTING): + raise exception.InstanceInvalidState( + attr='task_state', + instance_uuid=instance['uuid'], + state=instance['task_state']) state = {'SOFT': task_states.REBOOTING, 'HARD': task_states.REBOOTING_HARD}[reboot_type] instance = self.update(context, instance, vm_state=vm_states.ACTIVE, task_state=state, - expected_task_state=None) + expected_task_state=[None, + task_states.REBOOTING]) self.compute_rpcapi.reboot_instance(context, instance=instance, reboot_type=reboot_type) diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 13fa4b644..7142f92a9 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -3074,6 +3074,42 @@ class ComputeAPITestCase(BaseTestCase): db.instance_destroy(self.context, inst_ref['uuid']) + def test_hard_reboot_of_soft_rebooting_instance(self): + """Ensure instance can be hard rebooted while soft rebooting""" + instance = jsonutils.to_primitive(self._create_fake_instance()) + self.compute.run_instance(self.context, instance=instance) + + inst_ref = db.instance_get_by_uuid(self.context, instance['uuid']) + + db.instance_update(self.context, instance['uuid'], + {"task_state": task_states.REBOOTING}) + + reboot_type = "HARD" + self.compute_api.reboot(self.context, inst_ref, reboot_type) + + inst_ref = db.instance_get_by_uuid(self.context, inst_ref['uuid']) + self.assertEqual(inst_ref['task_state'], task_states.REBOOTING_HARD) + + db.instance_destroy(self.context, inst_ref['uuid']) + + def test_soft_reboot_of_rebooting_instance(self): + """Ensure instance can't be soft rebooted while rebooting""" + instance = jsonutils.to_primitive(self._create_fake_instance()) + self.compute.run_instance(self.context, instance=instance) + + inst_ref = db.instance_get_by_uuid(self.context, instance['uuid']) + + db.instance_update(self.context, instance['uuid'], + {"task_state": task_states.REBOOTING}) + + inst_ref = db.instance_get_by_uuid(self.context, inst_ref['uuid']) + reboot_type = "SOFT" + self.assertRaises(exception.InstanceInvalidState, + self.compute_api.reboot, + self.context, + inst_ref, + reboot_type) + def test_hostname_create(self): """Ensure instance hostname is set during creation.""" inst_type = instance_types.get_instance_type_by_name('m1.tiny') |
