3PAR: Fix delete volume when online clone

When an online clone volume is deleted, the clone needs to be stopped
first. On delete, a new exception is raised from the 3PAR. We need to
check for the error code when hpeexceptions.HTTPConflict is raised.

Change-Id: Iceb1b35e0312b109b2b19cd7d5c45b4a6242ccc5
Closes-Bug: #1349639
This commit is contained in:
Alex O'Rourke 2016-06-09 09:13:13 -07:00
parent 0f72ff555d
commit f0dda71610
2 changed files with 43 additions and 11 deletions

View File

@ -1673,6 +1673,29 @@ class HPE3PARBaseDriver(object):
expected +
self.standard_logout)
def test_delete_volume_online_clone_active(self):
# setup_mock_client drive with default configuration
# and return the mock HTTP 3PAR client
mock_client = self.setup_driver()
with mock.patch.object(hpecommon.HPE3PARCommon,
'_create_client') as mock_create_client:
mock_create_client.return_value = mock_client
ex = hpeexceptions.HTTPConflict("Online clone is active.")
ex._error_code = 151
mock_client.deleteVolume = mock.Mock(side_effect=ex)
mock_client.isOnlinePhysicalCopy.return_value = True
self.driver.delete_volume(self.volume)
expected = [
mock.call.deleteVolume(self.VOLUME_3PAR_NAME),
mock.call.isOnlinePhysicalCopy(self.VOLUME_3PAR_NAME),
mock.call.stopOnlinePhysicalCopy(self.VOLUME_3PAR_NAME)]
mock_client.assert_has_calls(
self.standard_login +
expected +
self.standard_logout)
@mock.patch.object(volume_types, 'get_volume_type')
def test_delete_volume_replicated(self, _mock_volume_types):
# setup_mock_client drive with default configuration

View File

@ -242,10 +242,11 @@ class HPE3PARCommon(object):
3.0.23 - Fix CG create failures with long display name or special
characters. bug #1573647
3.0.24 - Fix terminate connection on failover
3.0.25 - Fix delete volume when online clone is active. bug #1349639
"""
VERSION = "3.0.24"
VERSION = "3.0.25"
stats = {}
@ -2097,16 +2098,24 @@ class HPE3PARCommon(object):
self.client.removeVolumeFromVolumeSet(vvset_name,
volume_name)
self.client.deleteVolume(volume_name)
elif (ex.get_code() == 151):
# the volume is being operated on in a background
# task on the 3PAR.
# TODO(walter-boring) do a retry a few times.
# for now lets log a better message
msg = _("The volume is currently busy on the 3PAR"
" and cannot be deleted at this time. "
"You can try again later.")
LOG.error(msg)
raise exception.VolumeIsBusy(message=msg)
elif ex.get_code() == 151:
if self.client.isOnlinePhysicalCopy(volume_name):
LOG.debug("Found an online copy for %(volume)s",
{'volume': volume_name})
# the volume is in process of being cloned.
# stopOnlinePhysicalCopy will also delete
# the volume once it stops the copy.
self.client.stopOnlinePhysicalCopy(volume_name)
else:
# the volume is being operated on in a background
# task on the 3PAR.
# TODO(walter-boring) do a retry a few times.
# for now lets log a better message
msg = _("The volume is currently busy on the 3PAR"
" and cannot be deleted at this time. "
"You can try again later.")
LOG.error(msg)
raise exception.VolumeIsBusy(message=msg)
elif (ex.get_code() == 32):
# Error 32 means that the volume has children