Prevent force delete if the volume is attached
Force deletes were eventually failing on the volume manager layer due to being in an attached state. This will check that up front to inform the user that they need to detach first. Fixes: bug #1164929 Change-Id: I24ade24fd750dc647331ef25b835f45f29c10fd7
This commit is contained in:
parent
f30afa6e70
commit
8829bb1a1d
|
@ -175,6 +175,9 @@ class VolumeController(wsgi.Controller):
|
|||
self.volume_api.delete(context, volume)
|
||||
except exception.NotFound:
|
||||
raise exc.HTTPNotFound()
|
||||
except exception.VolumeAttached:
|
||||
explanation = 'Volume cannot be deleted while in attached state'
|
||||
raise exc.HTTPBadRequest(explanation=explanation)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.serializers(xml=VolumesTemplate)
|
||||
|
|
|
@ -658,6 +658,16 @@ class VolumeApiTest(test.TestCase):
|
|||
resp = self.controller.delete(req, 1)
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
|
||||
def test_volume_delete_attached(self):
|
||||
def stub_volume_attached(self, context, volume, force=False):
|
||||
raise exception.VolumeAttached(volume_id=volume['id'])
|
||||
self.stubs.Set(volume_api.API, "delete", stub_volume_attached)
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v2/volumes/1')
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.delete,
|
||||
req, 1)
|
||||
|
||||
def test_volume_delete_no_volume(self):
|
||||
self.stubs.Set(volume_api.API, "get", stubs.stub_volume_get_notfound)
|
||||
|
||||
|
|
|
@ -561,6 +561,24 @@ class VolumeTestCase(test.TestCase):
|
|||
# clean up
|
||||
self.volume.delete_volume(self.context, volume['id'])
|
||||
|
||||
def test_cant_force_delete_attached_volume(self):
|
||||
"""Test volume can't be force delete in attached state"""
|
||||
volume = self._create_volume()
|
||||
self.volume.create_volume(self.context, volume['id'])
|
||||
volume['status'] = 'in-use'
|
||||
volume['attach_status'] = 'attached'
|
||||
volume['host'] = 'fakehost'
|
||||
|
||||
volume_api = cinder.volume.api.API()
|
||||
|
||||
self.assertRaises(exception.VolumeAttached,
|
||||
volume_api.delete,
|
||||
self.context,
|
||||
volume,
|
||||
force=True)
|
||||
|
||||
self.volume.delete_volume(self.context, volume['id'])
|
||||
|
||||
def test_cant_delete_volume_with_snapshots(self):
|
||||
"""Test volume can't be deleted with dependent snapshots."""
|
||||
volume = self._create_volume()
|
||||
|
|
|
@ -320,6 +320,10 @@ class API(base.Base):
|
|||
msg = _("Volume status must be available or error")
|
||||
raise exception.InvalidVolume(reason=msg)
|
||||
|
||||
if volume['attach_status'] == "attached":
|
||||
# Volume is still attached, need to detach first
|
||||
raise exception.VolumeAttached(volume_id=volume_id)
|
||||
|
||||
snapshots = self.db.snapshot_get_all_for_volume(context, volume_id)
|
||||
if len(snapshots):
|
||||
msg = _("Volume still has %d dependent snapshots") % len(snapshots)
|
||||
|
|
Loading…
Reference in New Issue