From de5412356aa48a4af0b2ab0ba7b64e52240df299 Mon Sep 17 00:00:00 2001 From: Thomas Bechtold Date: Thu, 27 Aug 2015 21:08:52 +0200 Subject: [PATCH] Ignore unavailable volumes when deleting a share When deleting a share on a generic driver backend while the underlying cinder volume isn't available, ignore the VolumeNotFound exception and just continue to delete the share. This prevents the situation where a share can stay in error_deleting status forever. Closes-Bug: #1489573 Change-Id: I8cb4400573366587ac11ed28b82bb960e3bbd566 --- manila/share/drivers/generic.py | 7 ++++++- manila/tests/share/drivers/test_generic.py | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/manila/share/drivers/generic.py b/manila/share/drivers/generic.py index a821af7d11..dfa5570293 100644 --- a/manila/share/drivers/generic.py +++ b/manila/share/drivers/generic.py @@ -35,6 +35,7 @@ from manila import context from manila import exception from manila.i18n import _ from manila.i18n import _LE +from manila.i18n import _LI from manila.i18n import _LW from manila.share import driver from manila.share.drivers import service_instance @@ -524,7 +525,11 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver): def _deallocate_container(self, context, share): """Deletes cinder volume.""" - volume = self._get_volume(context, share['id']) + try: + volume = self._get_volume(context, share['id']) + except exception.VolumeNotFound: + LOG.info(_LI("Volume not found. Already deleted?")) + volume = None if volume: if volume['status'] == 'in-use': raise exception.ManilaException( diff --git a/manila/tests/share/drivers/test_generic.py b/manila/tests/share/drivers/test_generic.py index ab148157cb..4f52670747 100644 --- a/manila/tests/share/drivers/test_generic.py +++ b/manila/tests/share/drivers/test_generic.py @@ -777,6 +777,19 @@ class GenericShareDriverTestCase(test.TestCase): self._driver.volume_api.get.assert_called_once_with( self._context, fake_vol['id']) + def test_deallocate_container_with_volume_not_found(self): + fake_vol = fake_volume.FakeVolume() + self.mock_object(self._driver, '_get_volume', + mock.Mock(side_effect=exception.VolumeNotFound( + volume_id=fake_vol['id']))) + self.mock_object(self._driver.volume_api, 'delete') + + self._driver._deallocate_container(self._context, self.share) + + self._driver._get_volume.assert_called_once_with( + self._context, self.share['id']) + self.assertFalse(self._driver.volume_api.delete.called) + def test_create_share_from_snapshot(self): vol1 = 'fake_vol1' vol2 = 'fake_vol2'