VMAX driver - Create a CG from a source CG
Currently, we can only create a consistency group from a cg snapshot. This updates the api to accommodate creating a cg from another cg Change-Id: I6fd01739b62fd399cf9a397431c10a2a7f7ec0f2 Implements: blueprint vmax-clone-cg
This commit is contained in:
parent
f2431b5d24
commit
24ec725bb2
@ -3937,6 +3937,34 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase):
|
||||
self.assertEqual([{'status': 'available', 'id': '2'}],
|
||||
volumes_model_update)
|
||||
|
||||
@mock.patch.object(
|
||||
emc_vmax_utils.EMCVMAXUtils,
|
||||
'find_group_sync_rg_by_target',
|
||||
return_value="")
|
||||
@mock.patch.object(
|
||||
emc_vmax_common.EMCVMAXCommon,
|
||||
'_find_consistency_group',
|
||||
return_value=(None, EMCVMAXCommonData.test_CG))
|
||||
@mock.patch.object(
|
||||
emc_vmax_common.EMCVMAXCommon,
|
||||
'_get_pool_and_storage_system',
|
||||
return_value=(None, EMCVMAXCommonData.storage_system))
|
||||
@mock.patch.object(
|
||||
volume_types,
|
||||
'get_volume_type_extra_specs',
|
||||
return_value={'volume_backend_name': 'ISCSINoFAST'})
|
||||
def test_create_consistencygroup_from_source_cg(
|
||||
self, _mock_volume_type, _mock_storage, _mock_cg, _mock_rg):
|
||||
volumes = [self.data.test_source_volume]
|
||||
model_update, volumes_model_update = (
|
||||
self.driver.create_consistencygroup_from_src(
|
||||
self.data.test_ctxt, self.data.test_CG, volumes,
|
||||
source_cg=self.data.test_CG, source_vols=volumes))
|
||||
self.assertEqual({'status': fields.ConsistencyGroupStatus.AVAILABLE},
|
||||
model_update)
|
||||
self.assertEqual([{'status': 'available', 'id': '2'}],
|
||||
volumes_model_update)
|
||||
|
||||
@mock.patch.object(
|
||||
emc_vmax_common.EMCVMAXCommon,
|
||||
'_update_pool_stats',
|
||||
|
@ -4377,26 +4377,31 @@ class EMCVMAXCommon(object):
|
||||
volumes_model_update is a list of dictionaries of volume
|
||||
update
|
||||
"""
|
||||
if source_cg or source_vols:
|
||||
LOG.debug("The VMAX driver does not support creating a "
|
||||
"consistency group from a consistency group in "
|
||||
"this version.")
|
||||
raise NotImplementedError()
|
||||
if cgsnapshot:
|
||||
sourceCgName = self.utils.truncate_string(cgsnapshot['id'],
|
||||
TRUNCATE_8)
|
||||
source_vols_or_snapshots = snapshots
|
||||
source_id = cgsnapshot['consistencygroup_id']
|
||||
elif source_cg:
|
||||
sourceCgName = self.utils.truncate_string(source_cg['id'],
|
||||
TRUNCATE_8)
|
||||
source_vols_or_snapshots = source_vols
|
||||
source_id = source_cg['id']
|
||||
else:
|
||||
exceptionMessage = (_("Must supply either CG snaphot or "
|
||||
"a source CG."))
|
||||
raise exception.VolumeBackendAPIException(
|
||||
data=exceptionMessage)
|
||||
|
||||
LOG.debug("Enter EMCVMAXCommon::create_consistencygroup_from_src. "
|
||||
"Group to be created: %(cgId)s, "
|
||||
"Source snapshot: %(cgSnapshot)s.",
|
||||
"Source : %(SourceCGId)s.",
|
||||
{'cgId': group['id'],
|
||||
'cgSnapshot': cgsnapshot['consistencygroup_id']})
|
||||
'SourceCGId': source_id})
|
||||
|
||||
self.create_consistencygroup(context, group)
|
||||
targetCgName = self.utils.truncate_string(group['id'], TRUNCATE_8)
|
||||
|
||||
if not snapshots:
|
||||
exceptionMessage = (_("No source snapshots provided to create "
|
||||
"consistency group %s.") % targetCgName)
|
||||
raise exception.VolumeBackendAPIException(
|
||||
data=exceptionMessage)
|
||||
|
||||
modelUpdate = {'status': fields.ConsistencyGroupStatus.AVAILABLE}
|
||||
|
||||
try:
|
||||
@ -4413,9 +4418,14 @@ class EMCVMAXCommon(object):
|
||||
LOG.debug("Create CG %(targetCg)s from snapshot.",
|
||||
{'targetCg': targetCgInstanceName})
|
||||
|
||||
for volume, snapshot in zip(volumes, snapshots):
|
||||
volumeSizeInbits = int(self.utils.convert_gb_to_bits(
|
||||
snapshot['volume_size']))
|
||||
for volume, source_vol_or_snapshot in zip(
|
||||
volumes, source_vols_or_snapshots):
|
||||
if 'size' in source_vol_or_snapshot:
|
||||
volumeSizeInbits = int(self.utils.convert_gb_to_bits(
|
||||
source_vol_or_snapshot['size']))
|
||||
else:
|
||||
volumeSizeInbits = int(self.utils.convert_gb_to_bits(
|
||||
source_vol_or_snapshot['volume_size']))
|
||||
targetVolumeName = 'targetVol'
|
||||
volume = {'size': int(self.utils.convert_bits_to_gbs(
|
||||
volumeSizeInbits))}
|
||||
@ -4432,9 +4442,9 @@ class EMCVMAXCommon(object):
|
||||
targetVolumeInstance = self.utils.find_volume_instance(
|
||||
self.conn, volumeDict, targetVolumeName)
|
||||
LOG.debug("Create target volume for member snapshot. "
|
||||
"Source snapshot: %(snapshot)s, "
|
||||
"Source : %(snapshot)s, "
|
||||
"Target volume: %(targetVol)s.",
|
||||
{'snapshot': snapshot['id'],
|
||||
{'snapshot': source_vol_or_snapshot['id'],
|
||||
'targetVol': targetVolumeInstance.path})
|
||||
|
||||
self.provision.add_volume_to_cg(self.conn,
|
||||
@ -4444,13 +4454,12 @@ class EMCVMAXCommon(object):
|
||||
targetCgName,
|
||||
targetVolumeName,
|
||||
extraSpecs)
|
||||
|
||||
sourceCgInstanceName = self._find_consistency_group(
|
||||
replicationService, str(cgsnapshot['id']))
|
||||
replicationService, sourceCgName)
|
||||
if sourceCgInstanceName is None:
|
||||
exceptionMessage = (_("Cannot find source CG instance. "
|
||||
"consistencygroup_id: %s.") %
|
||||
cgsnapshot['consistencygroup_id'])
|
||||
source_id)
|
||||
raise exception.VolumeBackendAPIException(
|
||||
data=exceptionMessage)
|
||||
relationName = self.utils.truncate_string(group['id'], TRUNCATE_5)
|
||||
@ -4479,11 +4488,10 @@ class EMCVMAXCommon(object):
|
||||
self.conn, replicationService,
|
||||
rgSyncInstanceName, extraSpecs)
|
||||
except Exception:
|
||||
cgSnapshotId = cgsnapshot['consistencygroup_id']
|
||||
exceptionMessage = (_("Failed to create CG %(cgName)s "
|
||||
"from snapshot %(cgSnapshot)s.")
|
||||
"from source %(cgSnapshot)s.")
|
||||
% {'cgName': targetCgName,
|
||||
'cgSnapshot': cgSnapshotId})
|
||||
'cgSnapshot': source_id})
|
||||
LOG.exception(exceptionMessage)
|
||||
raise exception.VolumeBackendAPIException(data=exceptionMessage)
|
||||
volumes_model_update = self.utils.get_volume_model_updates(
|
||||
|
3
releasenotes/notes/vmax-clone-cg-09fce492931c957f.yaml
Normal file
3
releasenotes/notes/vmax-clone-cg-09fce492931c957f.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
features:
|
||||
VMAX Driver - Create a CG from a source CG
|
Loading…
x
Reference in New Issue
Block a user