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:
Mike Perez 2013-05-31 00:11:24 -07:00
parent f30afa6e70
commit 8829bb1a1d
4 changed files with 35 additions and 0 deletions

View File

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

View File

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

View File

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

View File

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