]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Catch ImageNotFound exception when deleting rbd volume
authorJordan Tardif <jordan@dreamhost.com>
Mon, 15 Sep 2014 21:59:06 +0000 (17:59 -0400)
committerJordan Tardif <jordan.tardif@gmail.com>
Wed, 17 Dec 2014 17:21:42 +0000 (17:21 +0000)
When deleting a rbd volume it is possible for remove() to
throw a ImageNotFound exception. In this case we should
catch the exception, so the volume delete can continue.

Closes-Bug: 1403172
Change-Id: I32cf9d3774c129cda4449996ceeb4b43b7e42904

cinder/tests/test_rbd.py
cinder/volume/drivers/rbd.py

index f40409b464f9cff20ad1891e8ca9c5446e63eadb..7b6496160b37b1d21244878819419c82e9f27caa 100644 (file)
@@ -348,6 +348,38 @@ class RBDTestCase(test.TestCase):
                     self.assertEqual(RAISED_EXCEPTIONS,
                                      [self.mock_rbd.ImageBusy])
 
+    @common_mocks
+    def test_delete_volume_not_found(self):
+        self.mock_rbd.Image.return_value.list_snaps.return_value = []
+
+        self.mock_rbd.RBD.return_value.remove.side_effect = (
+            self.mock_rbd.ImageNotFound)
+
+        with mock.patch.object(self.driver, '_get_clone_info') as \
+                mock_get_clone_info:
+            mock_get_clone_info.return_value = (None, None, None)
+            with mock.patch.object(self.driver, '_delete_backup_snaps') as \
+                    mock_delete_backup_snaps:
+                with mock.patch.object(driver, 'RADOSClient') as \
+                        mock_rados_client:
+                    self.assertIsNone(self.driver.delete_volume(self.volume))
+                    mock_get_clone_info.assert_called_once_with(
+                        self.mock_rbd.Image.return_value,
+                        self.volume_name,
+                        None)
+                    (self.mock_rbd.Image.return_value.list_snaps
+                     .assert_called_once_with())
+                    mock_rados_client.assert_called_once_with(self.driver)
+                    mock_delete_backup_snaps.assert_called_once_with(
+                        self.mock_rbd.Image.return_value)
+                    self.assertFalse(
+                        self.mock_rbd.Image.return_value.unprotect_snap.called)
+                    self.assertEqual(
+                        1, self.mock_rbd.RBD.return_value.remove.call_count)
+                    # Make sure the exception was raised
+                    self.assertEqual(RAISED_EXCEPTIONS,
+                                     [self.mock_rbd.ImageNotFound])
+
     @common_mocks
     def test_create_snapshot(self):
         proxy = self.mock_proxy.return_value
index 703d14ff3ffac40db94cd15a3b6033594812ff88..0c1a0749dd698ec29b8f574d0059e64eb6fb8ef1 100644 (file)
@@ -658,6 +658,11 @@ class RBDDriver(driver.VolumeDriver):
                     # Now raise this so that volume stays available so that we
                     # delete can be retried.
                     raise exception.VolumeIsBusy(msg, volume_name=volume_name)
+                except self.rbd.ImageNotFound:
+                    msg = (_LI("RBD volume %s not found, allowing delete "
+                               "operation to proceed.") % volume_name)
+                    LOG.info(msg)
+                    return
 
                 # If it is a clone, walk back up the parent chain deleting
                 # references.