]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
3PAR: Delete missing snapshot stuck in error_del
authorRamy Asselin <ramy.asselin@hp.com>
Mon, 24 Feb 2014 20:29:01 +0000 (12:29 -0800)
committerRamy Asselin <ramy.asselin@hp.com>
Mon, 24 Feb 2014 20:29:01 +0000 (12:29 -0800)
If the snapshot is deleted outside of cinder, attempting
to delete it again results in the snapshot state stuck in
error_deleting.

This is because the current code raises a NotFound exception,
but the base cinder code does not catch this and update its db.

Instead, log a warning, and simply tell the base cinder code that it was
successfully deleted.

Change-Id: I5c5d24bc113e320346ff4f1f4f62fffdf7cddfc4
Closes-Bug: #1283233

cinder/tests/test_hp3par.py
cinder/volume/drivers/san/hp/hp_3par_common.py

index 36d2ae6241a604a67d63089d0bca48e3547f39dc..bbe0fddbc1f590816b39e711dc0b9b5cac3898e4 100644 (file)
@@ -547,6 +547,21 @@ class HP3PARBaseDriver(object):
                           self.driver.delete_snapshot,
                           self.snapshot)
 
+    def test_delete_snapshot_not_found(self):
+        # setup_mock_client drive with default configuration
+        # and return the mock HTTP 3PAR client
+        mock_client = self.setup_driver()
+
+        self.driver.create_snapshot(self.snapshot)
+
+        try:
+            ex = hpexceptions.HTTPNotFound("not found")
+            mock_client.deleteVolume = mock.Mock(side_effect=ex)
+            self.driver.delete_snapshot(self.snapshot)
+        except Exception:
+            self.fail("Deleting a snapshot that is missing should act as if "
+                      "it worked.")
+
     def test_create_volume_from_snapshot(self):
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
index cad3a390c6d47fffb3398ab23fbefdfb3b0b5f98..848d3ce55cf836db02af8c4a8ad72cdb059794b5 100644 (file)
@@ -116,10 +116,11 @@ class HP3PARCommon(object):
         2.0.0 - Update hp3parclient API uses 3.0.x
         2.0.1 - Updated to use qos_specs, added new qos settings and personas
         2.0.2 - Add back-end assisted volume migrate
+        2.0.3 - Allow deleting missing snapshots bug #1283233
 
     """
 
-    VERSION = "2.0.2"
+    VERSION = "2.0.3"
 
     stats = {}
 
@@ -564,7 +565,7 @@ class HP3PARCommon(object):
                 # Cleanup the volume set if unable to create the qos rule
                 # or add the volume to the volume set
                 self.client.deleteVolumeSet(vvs_name)
-                raise exception.CinderException(ex.get_description())
+                raise exception.CinderException(ex)
 
     def get_cpg(self, volume, allowSnap=False):
         volume_name = self._get_3par_vol_name(volume['id'])
@@ -831,7 +832,9 @@ class HP3PARCommon(object):
         except hpexceptions.HTTPNotFound as ex:
             # We'll let this act as if it worked
             # it helps clean up the cinder entries.
-            LOG.error(str(ex))
+            msg = _("Delete volume id not found. Removing from cinder: "
+                    "%(id)s Ex: %(msg)s") % {'id': volume['id'], 'msg': ex}
+            LOG.warning(msg)
         except hpexceptions.HTTPForbidden as ex:
             LOG.error(str(ex))
             raise exception.NotAuthorized(ex.get_description())
@@ -898,7 +901,7 @@ class HP3PARCommon(object):
                     # Delete the volume if unable to add it to the volume set
                     self.client.deleteVolume(volume_name)
                     LOG.error(str(ex))
-                    raise exception.CinderException(ex.get_description())
+                    raise exception.CinderException(ex)
         except hpexceptions.HTTPForbidden as ex:
             LOG.error(str(ex))
             raise exception.NotAuthorized()
@@ -907,7 +910,7 @@ class HP3PARCommon(object):
             raise exception.NotFound()
         except Exception as ex:
             LOG.error(str(ex))
-            raise exception.CinderException(ex.get_description())
+            raise exception.CinderException(ex)
 
     def create_snapshot(self, snapshot):
         LOG.debug("Create Snapshot\n%s" % pprint.pformat(snapshot))
@@ -1129,8 +1132,11 @@ class HP3PARCommon(object):
             LOG.error(str(ex))
             raise exception.NotAuthorized()
         except hpexceptions.HTTPNotFound as ex:
-            LOG.error(str(ex))
-            raise exception.NotFound()
+            # We'll let this act as if it worked
+            # it helps clean up the cinder entries.
+            msg = _("Delete Snapshot id not found. Removing from cinder: "
+                    "%(id)s Ex: %(msg)s") % {'id': snapshot['id'], 'msg': ex}
+            LOG.warning(msg)
         except hpexceptions.HTTPConflict as ex:
             LOG.error(str(ex))
             raise exception.SnapshotIsBusy(snapshot_name=snapshot['id'])