From e31b9e78374bcaeae573cce2915897ceb870ffc3 Mon Sep 17 00:00:00 2001 From: Ramy Asselin Date: Mon, 24 Feb 2014 12:29:01 -0800 Subject: [PATCH] 3PAR: Delete missing snapshot stuck in error_del 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 | 15 ++++++++++++++ .../volume/drivers/san/hp/hp_3par_common.py | 20 ++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/cinder/tests/test_hp3par.py b/cinder/tests/test_hp3par.py index 36d2ae624..bbe0fddbc 100644 --- a/cinder/tests/test_hp3par.py +++ b/cinder/tests/test_hp3par.py @@ -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 diff --git a/cinder/volume/drivers/san/hp/hp_3par_common.py b/cinder/volume/drivers/san/hp/hp_3par_common.py index cad3a390c..848d3ce55 100644 --- a/cinder/volume/drivers/san/hp/hp_3par_common.py +++ b/cinder/volume/drivers/san/hp/hp_3par_common.py @@ -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']) -- 2.45.2