Merge "HPE 3PAR: fix delete operation of replicated volume"
This commit is contained in:
commit
7aca716a0f
@ -2146,7 +2146,10 @@ class HPE3PARBaseDriver(object):
|
||||
# and return the mock HTTP 3PAR client
|
||||
mock_client = self.setup_driver()
|
||||
mock_client.getStorageSystemInfo.return_value = {'id': self.CLIENT_ID}
|
||||
|
||||
ex = hpeexceptions.HTTPConflict("In use")
|
||||
ex._error_code = 34
|
||||
mock_client.deleteVolume = mock.Mock(side_effect=[ex, 200])
|
||||
mock_client.findVolumeSet.return_value = self.VVS_NAME
|
||||
_mock_volume_types.return_value = {
|
||||
'name': 'replicated',
|
||||
'extra_specs': {
|
||||
@ -2170,6 +2173,10 @@ class HPE3PARBaseDriver(object):
|
||||
self.VOLUME_3PAR_NAME,
|
||||
removeFromTarget=True),
|
||||
mock.call.removeRemoteCopyGroup(self.RCG_3PAR_NAME),
|
||||
mock.call.deleteVolume(self.VOLUME_3PAR_NAME),
|
||||
mock.call.findVolumeSet(self.VOLUME_3PAR_NAME),
|
||||
mock.call.removeVolumeFromVolumeSet(self.VVS_NAME,
|
||||
self.VOLUME_3PAR_NAME),
|
||||
mock.call.deleteVolume(self.VOLUME_3PAR_NAME)]
|
||||
|
||||
mock_client.assert_has_calls(
|
||||
|
@ -262,11 +262,13 @@ class HPE3PARCommon(object):
|
||||
3.0.35 - Add volume to consistency group if flag enabled. bug #1702317
|
||||
3.0.36 - Swap volume name in migration. bug #1699733
|
||||
3.0.37 - Fixed image cache enabled capability. bug #1686985
|
||||
3.0.38 - Fixed delete operation of replicated volume which is part
|
||||
of QOS. bug #1717875
|
||||
|
||||
|
||||
"""
|
||||
|
||||
VERSION = "3.0.37"
|
||||
VERSION = "3.0.38"
|
||||
|
||||
stats = {}
|
||||
|
||||
@ -2266,19 +2268,7 @@ class HPE3PARCommon(object):
|
||||
if ex.get_code() == 34:
|
||||
# This is a special case which means the
|
||||
# volume is part of a volume set.
|
||||
vvset_name = self.client.findVolumeSet(volume_name)
|
||||
LOG.debug("Returned vvset_name = %s", vvset_name)
|
||||
if vvset_name is not None and \
|
||||
vvset_name.startswith('vvs-'):
|
||||
# We have a single volume per volume set, so
|
||||
# remove the volume set.
|
||||
self.client.deleteVolumeSet(
|
||||
self._get_3par_vvs_name(volume['id']))
|
||||
elif vvset_name is not None:
|
||||
# We have a pre-defined volume set just remove the
|
||||
# volume and leave the volume set.
|
||||
self.client.removeVolumeFromVolumeSet(vvset_name,
|
||||
volume_name)
|
||||
self._delete_vvset(volume)
|
||||
self.client.deleteVolume(volume_name)
|
||||
elif ex.get_code() == 151:
|
||||
if self.client.isOnlinePhysicalCopy(volume_name):
|
||||
@ -3680,6 +3670,12 @@ class HPE3PARCommon(object):
|
||||
try:
|
||||
if not retype:
|
||||
self.client.deleteVolume(vol_name)
|
||||
except hpeexceptions.HTTPConflict as ex:
|
||||
if ex.get_code() == 34:
|
||||
# This is a special case which means the
|
||||
# volume is part of a volume set.
|
||||
self._delete_vvset(volume)
|
||||
self.client.deleteVolume(vol_name)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@ -3709,6 +3705,24 @@ class HPE3PARCommon(object):
|
||||
self.client.toggleRemoteCopyConfigMirror(target_name,
|
||||
mirror_config=True)
|
||||
|
||||
def _delete_vvset(self, volume):
|
||||
|
||||
# volume is part of a volume set.
|
||||
volume_name = self._get_3par_vol_name(volume['id'])
|
||||
vvset_name = self.client.findVolumeSet(volume_name)
|
||||
LOG.debug("Returned vvset_name = %s", vvset_name)
|
||||
if vvset_name is not None:
|
||||
if vvset_name.startswith('vvs-'):
|
||||
# We have a single volume per volume set, so
|
||||
# remove the volume set.
|
||||
self.client.deleteVolumeSet(
|
||||
self._get_3par_vvs_name(volume['id']))
|
||||
else:
|
||||
# We have a pre-defined volume set just remove the
|
||||
# volume and leave the volume set.
|
||||
self.client.removeVolumeFromVolumeSet(vvset_name,
|
||||
volume_name)
|
||||
|
||||
class TaskWaiter(object):
|
||||
"""TaskWaiter waits for task to be not active and returns status."""
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user