From 9834639454103ee2ba980628f0bc67ad0baa94ff Mon Sep 17 00:00:00 2001 From: Ramy Asselin Date: Mon, 6 Jan 2014 15:26:07 -0800 Subject: [PATCH] 3PAR: Raise Ex when del snapshot with depend vol Deleting a 3PAR snapshot can result in an HTTP Conflict error message, such as when a volume is dependent on it. Previously, this exception was not caught, and the state was set to "Error_Deleting" with no recovery path. The code was updated to catch this exception and raise a SnapShotIsBusy exception with an appropriate error message. The state reverts back to 'Available' allowing the user to try again after removing the dependency. Change-Id: Ibe8c5d581af10c85397c37993c49f8fc3bce8620 Closes-Bug: #1250249 --- cinder/tests/test_hp3par.py | 19 ++++++++++++++++--- .../volume/drivers/san/hp/hp_3par_common.py | 9 +++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/cinder/tests/test_hp3par.py b/cinder/tests/test_hp3par.py index af2b95106..af9cfd6d0 100644 --- a/cinder/tests/test_hp3par.py +++ b/cinder/tests/test_hp3par.py @@ -13,9 +13,8 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -""" -Unit tests for OpenStack Cinder volume drivers -""" +"""Unit tests for OpenStack Cinder volume drivers.""" + import ast import mock import mox @@ -622,6 +621,20 @@ class HP3PARBaseDriver(): self.driver.common.client.getVolume, self.SNAPSHOT_3PAR_NAME) + def test_delete_snapshot_in_use(self): + self.flags(lock_path=self.tempdir) + + self.driver.create_snapshot(self.snapshot) + self.driver.create_volume_from_snapshot(self.volume, self.snapshot) + + ex = hpexceptions.HTTPConflict("In use") + self.driver.common.client.deleteVolume = mock.Mock(side_effect=ex) + + # Deleting the snapshot that a volume is dependent on should fail + self.assertRaises(exception.SnapshotIsBusy, + self.driver.delete_snapshot, + self.snapshot) + def test_create_volume_from_snapshot(self): self.flags(lock_path=self.tempdir) self.driver.create_volume_from_snapshot(self.volume, self.snapshot) diff --git a/cinder/volume/drivers/san/hp/hp_3par_common.py b/cinder/volume/drivers/san/hp/hp_3par_common.py index 654fb30ea..2dacfb01c 100644 --- a/cinder/volume/drivers/san/hp/hp_3par_common.py +++ b/cinder/volume/drivers/san/hp/hp_3par_common.py @@ -112,10 +112,11 @@ class HP3PARCommon(object): 1.2.2 - log prior to raising exceptions 1.2.3 - Methods to update key/value pair bug #1258033 1.2.4 - Remove deprecated config option hp3par_domain + 1.2.5 - Raise Ex when deleting snapshot with dependencies bug #1250249 """ - VERSION = "1.2.4" + VERSION = "1.2.5" stats = {} @@ -1019,7 +1020,8 @@ exit LOG.error(_("Error detaching volume %s") % volume) def delete_snapshot(self, snapshot): - LOG.debug("Delete Snapshot\n%s" % pprint.pformat(snapshot)) + LOG.debug("Delete Snapshot id %s %s" % (snapshot['id'], + pprint.pformat(snapshot))) try: snap_name = self._get_3par_snap_name(snapshot['id']) @@ -1030,6 +1032,9 @@ exit except hpexceptions.HTTPNotFound as ex: LOG.error(str(ex)) raise exception.NotFound() + except hpexceptions.HTTPConflict as ex: + LOG.error(str(ex)) + raise exception.SnapshotIsBusy(snapshot_name=snapshot['id']) def _get_3par_hostname_from_wwn_iqn(self, wwns, iqns): if wwns is not None and not isinstance(wwns, list): -- 2.45.2