Disable volume attach/detach for suspended instances

As described in the bug - some hypervisors (libvirt) do not support
this. It is best to disable it in the API to provide a consistent user
experience.

Also adds a test to prevent an accidental regression.

Change-Id: I5b404cca22cffecbaf524e2511810e5341242052
Closes-bug: #1240922
This commit is contained in:
Nikola Dipanov 2014-03-27 18:01:22 +01:00
parent a323653a9f
commit d0948a1fb0
2 changed files with 26 additions and 4 deletions

View File

@ -2749,8 +2749,8 @@ class API(base.Base):
@wrap_check_policy
@check_instance_lock
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.PAUSED,
vm_states.SUSPENDED, vm_states.STOPPED,
vm_states.RESIZED, vm_states.SOFT_DELETED],
vm_states.STOPPED, vm_states.RESIZED,
vm_states.SOFT_DELETED],
task_state=[None])
def attach_volume(self, context, instance, volume_id, device=None,
disk_bus=None, device_type=None):
@ -2778,8 +2778,8 @@ class API(base.Base):
@wrap_check_policy
@check_instance_lock
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.PAUSED,
vm_states.SUSPENDED, vm_states.STOPPED,
vm_states.RESIZED, vm_states.SOFT_DELETED],
vm_states.STOPPED, vm_states.RESIZED,
vm_states.SOFT_DELETED],
task_state=[None])
def detach_volume(self, context, instance, volume):
"""Detach a volume from an instance."""

View File

@ -8319,6 +8319,15 @@ class ComputeAPITestCase(BaseTestCase):
None,
'/dev/vdb')
def test_no_attach_volume_in_suspended_state(self):
self.assertRaises(exception.InstanceInvalidState,
self.compute_api.attach_volume,
self.context,
{'uuid': 'fake_uuid', 'locked': False,
'vm_state': vm_states.SUSPENDED},
{'id': 'fake-volume-id'},
'/dev/vdb')
def test_no_detach_volume_in_rescue_state(self):
# Ensure volume can be detached from instance
@ -8675,6 +8684,19 @@ class ComputeAPITestCase(BaseTestCase):
self.compute_api.detach_volume, self.context,
instance, volume)
def test_detach_suspended_instance_fails(self):
instance = {'uuid': 'uuid1',
'locked': False,
'launched_at': timeutils.utcnow(),
'vm_state': vm_states.SUSPENDED,
'task_state': None}
volume = {'id': 1, 'attach_status': 'in-use',
'instance_uuid': 'uuid2'}
self.assertRaises(exception.InstanceInvalidState,
self.compute_api.detach_volume, self.context,
instance, volume)
def test_detach_volume_libvirt_is_down(self):
# Ensure rollback during detach if libvirt goes down