Merge "Fix being able to hard reboot a pausing instance"
This commit is contained in:
commit
7f9cdb5d6d
@ -423,6 +423,29 @@ Reboots a server.
|
|||||||
|
|
||||||
Specify the ``reboot`` action in the request body.
|
Specify the ``reboot`` action in the request body.
|
||||||
|
|
||||||
|
**Preconditions**
|
||||||
|
|
||||||
|
The preconditions for rebooting a server depend on the type of reboot.
|
||||||
|
|
||||||
|
You can only *SOFT* reboot a server when its status is ``ACTIVE``.
|
||||||
|
|
||||||
|
You can only *HARD* reboot a server when its status is one of:
|
||||||
|
|
||||||
|
* ``ACTIVE``
|
||||||
|
* ``ERROR``
|
||||||
|
* ``HARD_REBOOT``
|
||||||
|
* ``PAUSED``
|
||||||
|
* ``REBOOT``
|
||||||
|
* ``SHUTOFF``
|
||||||
|
* ``SUSPENDED``
|
||||||
|
|
||||||
|
If the server is locked, you must have administrator privileges
|
||||||
|
to reboot the server.
|
||||||
|
|
||||||
|
**Asynchronous Postconditions**
|
||||||
|
|
||||||
|
After you successfully reboot a server, its status changes to ``ACTIVE``.
|
||||||
|
|
||||||
Normal response codes: 202
|
Normal response codes: 202
|
||||||
|
|
||||||
Error response codes: unauthorized(401), forbidden(403), itemNotFound(404),
|
Error response codes: unauthorized(401), forbidden(403), itemNotFound(404),
|
||||||
|
@ -3079,15 +3079,7 @@ class API(base.Base):
|
|||||||
task_state=task_states.ALLOW_REBOOT)
|
task_state=task_states.ALLOW_REBOOT)
|
||||||
def _hard_reboot(self, context, instance):
|
def _hard_reboot(self, context, instance):
|
||||||
instance.task_state = task_states.REBOOTING_HARD
|
instance.task_state = task_states.REBOOTING_HARD
|
||||||
expected_task_state = [None,
|
instance.save(expected_task_state=task_states.ALLOW_REBOOT)
|
||||||
task_states.REBOOTING,
|
|
||||||
task_states.REBOOT_PENDING,
|
|
||||||
task_states.REBOOT_STARTED,
|
|
||||||
task_states.REBOOTING_HARD,
|
|
||||||
task_states.RESUMING,
|
|
||||||
task_states.UNPAUSING,
|
|
||||||
task_states.SUSPENDING]
|
|
||||||
instance.save(expected_task_state = expected_task_state)
|
|
||||||
|
|
||||||
self._record_action_start(context, instance, instance_actions.REBOOT)
|
self._record_action_start(context, instance, instance_actions.REBOOT)
|
||||||
|
|
||||||
|
@ -3242,6 +3242,18 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
def test_reboot_fail_running(self):
|
def test_reboot_fail_running(self):
|
||||||
self._test_reboot(False, fail_reboot=True, fail_running=True)
|
self._test_reboot(False, fail_reboot=True, fail_running=True)
|
||||||
|
|
||||||
|
def test_reboot_hard_pausing(self):
|
||||||
|
# We need an actual instance in the database for this test to make
|
||||||
|
# sure that expected_task_state works OK with Instance.save().
|
||||||
|
instance = self._create_fake_instance_obj(
|
||||||
|
params={'task_state': task_states.PAUSING})
|
||||||
|
with mock.patch.object(self.compute_api.compute_rpcapi,
|
||||||
|
'reboot_instance') as rpc_reboot:
|
||||||
|
self.compute_api.reboot(self.context, instance, 'HARD')
|
||||||
|
rpc_reboot.assert_called_once_with(
|
||||||
|
self.context, instance=instance, block_device_info=None,
|
||||||
|
reboot_type='HARD')
|
||||||
|
|
||||||
def test_get_instance_block_device_info_source_image(self):
|
def test_get_instance_block_device_info_source_image(self):
|
||||||
bdms = block_device_obj.block_device_make_list(self.context,
|
bdms = block_device_obj.block_device_make_list(self.context,
|
||||||
[fake_block_device.FakeDbBlockDeviceDict({
|
[fake_block_device.FakeDbBlockDeviceDict({
|
||||||
|
@ -867,13 +867,7 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
|
|
||||||
expected_task_state = [None]
|
expected_task_state = [None]
|
||||||
if reboot_type == 'HARD':
|
if reboot_type == 'HARD':
|
||||||
expected_task_state.extend([task_states.REBOOTING,
|
expected_task_state = task_states.ALLOW_REBOOT
|
||||||
task_states.REBOOT_PENDING,
|
|
||||||
task_states.REBOOT_STARTED,
|
|
||||||
task_states.REBOOTING_HARD,
|
|
||||||
task_states.RESUMING,
|
|
||||||
task_states.UNPAUSING,
|
|
||||||
task_states.SUSPENDING])
|
|
||||||
|
|
||||||
if self.cell_type == 'api':
|
if self.cell_type == 'api':
|
||||||
rpcapi = self.compute_api.cells_rpcapi
|
rpcapi = self.compute_api.cells_rpcapi
|
||||||
@ -930,10 +924,6 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
self._test_reboot_type(vm_states.ACTIVE,
|
self._test_reboot_type(vm_states.ACTIVE,
|
||||||
'HARD', task_state=task_states.RESUMING)
|
'HARD', task_state=task_states.RESUMING)
|
||||||
|
|
||||||
def test_reboot_hard_pausing(self):
|
|
||||||
self._test_reboot_type(vm_states.ACTIVE,
|
|
||||||
'HARD', task_state=task_states.PAUSING)
|
|
||||||
|
|
||||||
def test_reboot_hard_unpausing(self):
|
def test_reboot_hard_unpausing(self):
|
||||||
self._test_reboot_type(vm_states.ACTIVE,
|
self._test_reboot_type(vm_states.ACTIVE,
|
||||||
'HARD', task_state=task_states.UNPAUSING)
|
'HARD', task_state=task_states.UNPAUSING)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user