Merge "VM in rescue state must have a restricted set of actions"
This commit is contained in:
commit
bf1b6df322
@ -88,6 +88,7 @@ task states for various commands issued by the user:
|
||||
rescue -> error
|
||||
active -> rescue
|
||||
stopped -> rescue
|
||||
error -> rescue
|
||||
|
||||
unrescue [shape="rectangle"]
|
||||
unrescue -> active
|
||||
@ -139,7 +140,9 @@ task states for various commands issued by the user:
|
||||
reboot -> error
|
||||
active -> reboot
|
||||
stopped -> reboot
|
||||
rescued -> reboot
|
||||
paused -> reboot
|
||||
suspended -> reboot
|
||||
error -> reboot
|
||||
|
||||
live_migrate [shape="rectangle"]
|
||||
live_migrate -> active
|
||||
@ -159,4 +162,4 @@ The following diagram shows the sequence of VM states, task states, and
|
||||
power states when a new VM instance is created.
|
||||
|
||||
|
||||
.. image:: /images/run_instance_walkthrough.png
|
||||
.. image:: /images/run_instance_walkthrough.png
|
||||
|
@ -1769,8 +1769,7 @@ class API(base.Base):
|
||||
@check_instance_lock
|
||||
@check_instance_host
|
||||
@check_instance_cell
|
||||
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.RESCUED,
|
||||
vm_states.ERROR])
|
||||
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.ERROR])
|
||||
def stop(self, context, instance, do_cast=True):
|
||||
"""Stop an instance."""
|
||||
self.force_stop(context, instance, do_cast)
|
||||
@ -2543,7 +2542,7 @@ class API(base.Base):
|
||||
@wrap_check_policy
|
||||
@check_instance_lock
|
||||
@check_instance_cell
|
||||
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.RESCUED])
|
||||
@check_instance_state(vm_state=[vm_states.ACTIVE])
|
||||
def pause(self, context, instance):
|
||||
"""Pause the given instance."""
|
||||
instance.task_state = task_states.PAUSING
|
||||
@ -2576,7 +2575,7 @@ class API(base.Base):
|
||||
@wrap_check_policy
|
||||
@check_instance_lock
|
||||
@check_instance_cell
|
||||
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.RESCUED])
|
||||
@check_instance_state(vm_state=[vm_states.ACTIVE])
|
||||
def suspend(self, context, instance):
|
||||
"""Suspend the given instance."""
|
||||
instance.task_state = task_states.SUSPENDING
|
||||
|
@ -65,6 +65,16 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
self.context = context.RequestContext(self.user_id,
|
||||
self.project_id)
|
||||
|
||||
def _get_vm_states(self, exclude_states=None):
|
||||
vm_state = set([vm_states.ACTIVE, vm_states.BUILDING, vm_states.PAUSED,
|
||||
vm_states.SUSPENDED, vm_states.RESCUED, vm_states.STOPPED,
|
||||
vm_states.RESIZED, vm_states.SOFT_DELETED,
|
||||
vm_states.DELETED, vm_states.ERROR, vm_states.SHELVED,
|
||||
vm_states.SHELVED_OFFLOADED])
|
||||
if not exclude_states:
|
||||
exclude_states = set()
|
||||
return vm_state - exclude_states
|
||||
|
||||
def _create_flavor(self, params=None):
|
||||
flavor = {'id': 1,
|
||||
'flavorid': 1,
|
||||
@ -244,6 +254,19 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
self.assertEqual(task_states.SUSPENDING,
|
||||
instance.task_state)
|
||||
|
||||
def _test_suspend_fails(self, vm_state):
|
||||
params = dict(vm_state=vm_state)
|
||||
instance = self._create_instance_obj(params=params)
|
||||
self.assertIsNone(instance.task_state)
|
||||
self.assertRaises(exception.InstanceInvalidState,
|
||||
self.compute_api.suspend,
|
||||
self.context, instance)
|
||||
|
||||
def test_suspend_fails_invalid_states(self):
|
||||
invalid_vm_states = self._get_vm_states(set([vm_states.ACTIVE]))
|
||||
for state in invalid_vm_states:
|
||||
self._test_suspend_fails(state)
|
||||
|
||||
def test_resume(self):
|
||||
# Ensure instance can be resumed (if suspended).
|
||||
instance = self._create_instance_obj(
|
||||
@ -349,13 +372,19 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
def test_stop_stopped_instance_with_bypass(self):
|
||||
self._test_stop(vm_states.STOPPED, force=True)
|
||||
|
||||
def test_stop_invalid_state(self):
|
||||
params = dict(vm_state=vm_states.PAUSED)
|
||||
def _test_stop_invalid_state(self, vm_state):
|
||||
params = dict(vm_state=vm_state)
|
||||
instance = self._create_instance_obj(params=params)
|
||||
self.assertRaises(exception.InstanceInvalidState,
|
||||
self.compute_api.stop,
|
||||
self.context, instance)
|
||||
|
||||
def test_stop_fails_invalid_states(self):
|
||||
invalid_vm_states = self._get_vm_states(set([vm_states.ACTIVE,
|
||||
vm_states.ERROR]))
|
||||
for state in invalid_vm_states:
|
||||
self._test_stop_invalid_state(state)
|
||||
|
||||
def test_stop_a_stopped_inst(self):
|
||||
params = {'vm_state': vm_states.STOPPED}
|
||||
instance = self._create_instance_obj(params=params)
|
||||
@ -1283,6 +1312,19 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
self.assertEqual(task_states.PAUSING,
|
||||
instance.task_state)
|
||||
|
||||
def _test_pause_fails(self, vm_state):
|
||||
params = dict(vm_state=vm_state)
|
||||
instance = self._create_instance_obj(params=params)
|
||||
self.assertIsNone(instance.task_state)
|
||||
self.assertRaises(exception.InstanceInvalidState,
|
||||
self.compute_api.pause,
|
||||
self.context, instance)
|
||||
|
||||
def test_pause_fails_invalid_states(self):
|
||||
invalid_vm_states = self._get_vm_states(set([vm_states.ACTIVE]))
|
||||
for state in invalid_vm_states:
|
||||
self._test_pause_fails(state)
|
||||
|
||||
def test_unpause(self):
|
||||
# Ensure instance can be unpaused.
|
||||
params = dict(vm_state=vm_states.PAUSED)
|
||||
|
Loading…
Reference in New Issue
Block a user