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
|
# and return the mock HTTP 3PAR client
|
||||||
mock_client = self.setup_driver()
|
mock_client = self.setup_driver()
|
||||||
mock_client.getStorageSystemInfo.return_value = {'id': self.CLIENT_ID}
|
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 = {
|
_mock_volume_types.return_value = {
|
||||||
'name': 'replicated',
|
'name': 'replicated',
|
||||||
'extra_specs': {
|
'extra_specs': {
|
||||||
|
@ -2170,6 +2173,10 @@ class HPE3PARBaseDriver(object):
|
||||||
self.VOLUME_3PAR_NAME,
|
self.VOLUME_3PAR_NAME,
|
||||||
removeFromTarget=True),
|
removeFromTarget=True),
|
||||||
mock.call.removeRemoteCopyGroup(self.RCG_3PAR_NAME),
|
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.call.deleteVolume(self.VOLUME_3PAR_NAME)]
|
||||||
|
|
||||||
mock_client.assert_has_calls(
|
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.35 - Add volume to consistency group if flag enabled. bug #1702317
|
||||||
3.0.36 - Swap volume name in migration. bug #1699733
|
3.0.36 - Swap volume name in migration. bug #1699733
|
||||||
3.0.37 - Fixed image cache enabled capability. bug #1686985
|
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 = {}
|
stats = {}
|
||||||
|
|
||||||
|
@ -2266,19 +2268,7 @@ class HPE3PARCommon(object):
|
||||||
if ex.get_code() == 34:
|
if ex.get_code() == 34:
|
||||||
# This is a special case which means the
|
# This is a special case which means the
|
||||||
# volume is part of a volume set.
|
# volume is part of a volume set.
|
||||||
vvset_name = self.client.findVolumeSet(volume_name)
|
self._delete_vvset(volume)
|
||||||
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.client.deleteVolume(volume_name)
|
self.client.deleteVolume(volume_name)
|
||||||
elif ex.get_code() == 151:
|
elif ex.get_code() == 151:
|
||||||
if self.client.isOnlinePhysicalCopy(volume_name):
|
if self.client.isOnlinePhysicalCopy(volume_name):
|
||||||
|
@ -3680,6 +3670,12 @@ class HPE3PARCommon(object):
|
||||||
try:
|
try:
|
||||||
if not retype:
|
if not retype:
|
||||||
self.client.deleteVolume(vol_name)
|
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:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -3709,6 +3705,24 @@ class HPE3PARCommon(object):
|
||||||
self.client.toggleRemoteCopyConfigMirror(target_name,
|
self.client.toggleRemoteCopyConfigMirror(target_name,
|
||||||
mirror_config=True)
|
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):
|
class TaskWaiter(object):
|
||||||
"""TaskWaiter waits for task to be not active and returns status."""
|
"""TaskWaiter waits for task to be not active and returns status."""
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue