Merge "VM in rescue state must have a restricted set of actions" into stable/icehouse

This commit is contained in:
Jenkins 2014-09-27 14:30:30 +00:00 committed by Gerrit Code Review
commit 2eff1f91bc
3 changed files with 52 additions and 8 deletions

View File

@ -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

View File

@ -1759,8 +1759,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],
task_state=[None])
def stop(self, context, instance, do_cast=True):
"""Stop an instance."""
@ -2522,7 +2521,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
@ -2549,7 +2548,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

View File

@ -67,6 +67,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,
@ -204,6 +214,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(
@ -309,13 +332,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)
@ -1203,6 +1232,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)