3PAR: Create consistency group from source CG
Supports creating a consistency group from a source consistency group in the HPE 3PAR driver. This makes use of temporary snapshots, which are not managed by Cinder. Upon volume/CG deleteion, these temp snapshots will automatically be cleaned up. Change-Id: I033c2c4d45689d02dec96a0e58794629053efbc4 Implements: blueprint hpe-3par-create-cg-from-source DocImpact
This commit is contained in:
parent
839a32ee04
commit
c9e5562dfd
@ -91,11 +91,13 @@ class Comment(object):
|
|||||||
class HPE3PARBaseDriver(object):
|
class HPE3PARBaseDriver(object):
|
||||||
|
|
||||||
VOLUME_ID = 'd03338a9-9115-48a3-8dfc-35cdfcdc15a7'
|
VOLUME_ID = 'd03338a9-9115-48a3-8dfc-35cdfcdc15a7'
|
||||||
|
SRC_CG_VOLUME_ID = 'bd21d11b-c765-4c68-896c-6b07f63cfcb6'
|
||||||
CLONE_ID = 'd03338a9-9115-48a3-8dfc-000000000000'
|
CLONE_ID = 'd03338a9-9115-48a3-8dfc-000000000000'
|
||||||
VOLUME_TYPE_ID_REPLICATED = 'be9181f1-4040-46f2-8298-e7532f2bf9db'
|
VOLUME_TYPE_ID_REPLICATED = 'be9181f1-4040-46f2-8298-e7532f2bf9db'
|
||||||
VOLUME_TYPE_ID_DEDUP = 'd03338a9-9115-48a3-8dfc-11111111111'
|
VOLUME_TYPE_ID_DEDUP = 'd03338a9-9115-48a3-8dfc-11111111111'
|
||||||
VOLUME_TYPE_ID_FLASH_CACHE = 'd03338a9-9115-48a3-8dfc-22222222222'
|
VOLUME_TYPE_ID_FLASH_CACHE = 'd03338a9-9115-48a3-8dfc-22222222222'
|
||||||
VOLUME_NAME = 'volume-' + VOLUME_ID
|
VOLUME_NAME = 'volume-' + VOLUME_ID
|
||||||
|
SRC_CG_VOLUME_NAME = 'volume-' + SRC_CG_VOLUME_ID
|
||||||
VOLUME_NAME_3PAR = 'osv-0DM4qZEVSKON-DXN-NwVpw'
|
VOLUME_NAME_3PAR = 'osv-0DM4qZEVSKON-DXN-NwVpw'
|
||||||
SNAPSHOT_ID = '2f823bdc-e36e-4dc8-bd15-de1c7a28ff31'
|
SNAPSHOT_ID = '2f823bdc-e36e-4dc8-bd15-de1c7a28ff31'
|
||||||
SNAPSHOT_NAME = 'snapshot-2f823bdc-e36e-4dc8-bd15-de1c7a28ff31'
|
SNAPSHOT_NAME = 'snapshot-2f823bdc-e36e-4dc8-bd15-de1c7a28ff31'
|
||||||
@ -104,6 +106,8 @@ class HPE3PARBaseDriver(object):
|
|||||||
RCG_3PAR_NAME = 'rcg-0DM4qZEVSKON-DXN-N'
|
RCG_3PAR_NAME = 'rcg-0DM4qZEVSKON-DXN-N'
|
||||||
CONSIS_GROUP_ID = '6044fedf-c889-4752-900f-2039d247a5df'
|
CONSIS_GROUP_ID = '6044fedf-c889-4752-900f-2039d247a5df'
|
||||||
CONSIS_GROUP_NAME = 'vvs-YET.38iJR1KQDyA50kel3w'
|
CONSIS_GROUP_NAME = 'vvs-YET.38iJR1KQDyA50kel3w'
|
||||||
|
SRC_CONSIS_GROUP_ID = '7d7dfa02-ac6e-48cb-96af-8a0cd3008d47'
|
||||||
|
SRC_CONSIS_GROUP_NAME = 'vvs-fX36AqxuSMuWr4oM0wCNRw'
|
||||||
CGSNAPSHOT_ID = 'e91c5ed5-daee-4e84-8724-1c9e31e7a1f2'
|
CGSNAPSHOT_ID = 'e91c5ed5-daee-4e84-8724-1c9e31e7a1f2'
|
||||||
CGSNAPSHOT_BASE_NAME = 'oss-6Rxe1druToSHJByeMeeh8g'
|
CGSNAPSHOT_BASE_NAME = 'oss-6Rxe1druToSHJByeMeeh8g'
|
||||||
CLIENT_ID = "12345"
|
CLIENT_ID = "12345"
|
||||||
@ -148,6 +152,14 @@ class HPE3PARBaseDriver(object):
|
|||||||
'volume_type': None,
|
'volume_type': None,
|
||||||
'volume_type_id': None}
|
'volume_type_id': None}
|
||||||
|
|
||||||
|
volume_src_cg = {'name': SRC_CG_VOLUME_NAME,
|
||||||
|
'id': SRC_CG_VOLUME_ID,
|
||||||
|
'display_name': 'Foo Volume',
|
||||||
|
'size': 2,
|
||||||
|
'host': FAKE_CINDER_HOST,
|
||||||
|
'volume_type': None,
|
||||||
|
'volume_type_id': None}
|
||||||
|
|
||||||
volume_replicated = {'name': VOLUME_NAME,
|
volume_replicated = {'name': VOLUME_NAME,
|
||||||
'id': VOLUME_ID,
|
'id': VOLUME_ID,
|
||||||
'display_name': 'Foo Volume',
|
'display_name': 'Foo Volume',
|
||||||
@ -585,18 +597,20 @@ class HPE3PARBaseDriver(object):
|
|||||||
mock.call.logout()]
|
mock.call.logout()]
|
||||||
|
|
||||||
class fake_consistencygroup_object(object):
|
class fake_consistencygroup_object(object):
|
||||||
volume_type_id = '49fa96b5-828e-4653-b622-873a1b7e6f1c'
|
def __init__(self, cg_id='6044fedf-c889-4752-900f-2039d247a5df'):
|
||||||
name = 'cg_name'
|
self.id = cg_id
|
||||||
cgsnapshot_id = None
|
self.volume_type_id = '49fa96b5-828e-4653-b622-873a1b7e6f1c'
|
||||||
host = 'fakehost@foo#OpenStackCPG'
|
self.name = 'cg_name'
|
||||||
id = '6044fedf-c889-4752-900f-2039d247a5df'
|
self.cgsnapshot_id = None
|
||||||
description = 'consistency group'
|
self.host = 'fakehost@foo#OpenStackCPG'
|
||||||
|
self.description = 'consistency group'
|
||||||
|
|
||||||
class fake_cgsnapshot_object(object):
|
class fake_cgsnapshot_object(object):
|
||||||
consistencygroup_id = '6044fedf-c889-4752-900f-2039d247a5df'
|
def __init__(self, cgsnap_id='e91c5ed5-daee-4e84-8724-1c9e31e7a1f2'):
|
||||||
description = 'cgsnapshot'
|
self.id = cgsnap_id
|
||||||
id = 'e91c5ed5-daee-4e84-8724-1c9e31e7a1f2'
|
self.consistencygroup_id = '6044fedf-c889-4752-900f-2039d247a5df'
|
||||||
readOnly = False
|
self.description = 'cgsnapshot'
|
||||||
|
self.readOnly = False
|
||||||
|
|
||||||
def setup_configuration(self):
|
def setup_configuration(self):
|
||||||
configuration = mock.MagicMock()
|
configuration = mock.MagicMock()
|
||||||
@ -3926,6 +3940,60 @@ class HPE3PARBaseDriver(object):
|
|||||||
expected +
|
expected +
|
||||||
self.standard_logout)
|
self.standard_logout)
|
||||||
|
|
||||||
|
def test_create_consistency_group_from_src_cg(self):
|
||||||
|
mock_client = self.setup_driver()
|
||||||
|
mock_client.getStorageSystemInfo.return_value = {'id': self.CLIENT_ID}
|
||||||
|
volume = self.volume
|
||||||
|
source_volume = self.volume_src_cg
|
||||||
|
|
||||||
|
cgsnap_optional = (
|
||||||
|
{'expirationHours': 1})
|
||||||
|
|
||||||
|
cg_comment = Comment({
|
||||||
|
'display_name': 'cg_name',
|
||||||
|
'consistency_group_id': self.CONSIS_GROUP_ID,
|
||||||
|
'description': 'consistency group'})
|
||||||
|
|
||||||
|
with mock.patch.object(hpecommon.HPE3PARCommon,
|
||||||
|
'_create_client') as mock_create_client:
|
||||||
|
mock_create_client.return_value = mock_client
|
||||||
|
mock_client.getCPG.return_value = {'domain': None}
|
||||||
|
group = self.fake_consistencygroup_object()
|
||||||
|
source_group = self.fake_consistencygroup_object(
|
||||||
|
cg_id=self.SRC_CONSIS_GROUP_ID)
|
||||||
|
|
||||||
|
expected = [
|
||||||
|
mock.call.getCPG(HPE3PAR_CPG),
|
||||||
|
mock.call.createVolumeSet(
|
||||||
|
self.CONSIS_GROUP_NAME,
|
||||||
|
domain=None,
|
||||||
|
comment=cg_comment),
|
||||||
|
mock.call.createSnapshotOfVolumeSet(
|
||||||
|
mock.ANY,
|
||||||
|
self.SRC_CONSIS_GROUP_NAME,
|
||||||
|
optional=cgsnap_optional),
|
||||||
|
mock.call.copyVolume(
|
||||||
|
mock.ANY,
|
||||||
|
self.VOLUME_NAME_3PAR,
|
||||||
|
HPE3PAR_CPG,
|
||||||
|
{'snapCPG': HPE3PAR_CPG, 'online': True}),
|
||||||
|
mock.call.addVolumeToVolumeSet(
|
||||||
|
self.CONSIS_GROUP_NAME,
|
||||||
|
self.VOLUME_NAME_3PAR)]
|
||||||
|
|
||||||
|
# Create a consistency group from a source consistency group.
|
||||||
|
self.driver.create_consistencygroup_from_src(
|
||||||
|
context.get_admin_context(), group,
|
||||||
|
[volume], source_cg=source_group,
|
||||||
|
source_vols=[source_volume])
|
||||||
|
|
||||||
|
mock_client.assert_has_calls(
|
||||||
|
self.get_id_login +
|
||||||
|
self.standard_logout +
|
||||||
|
self.standard_login +
|
||||||
|
expected +
|
||||||
|
self.standard_logout)
|
||||||
|
|
||||||
def test_delete_consistency_group(self):
|
def test_delete_consistency_group(self):
|
||||||
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}
|
||||||
|
@ -225,10 +225,11 @@ class HPE3PARCommon(object):
|
|||||||
3.0.10 - Added additional volumes checks to the manage snapshot API
|
3.0.10 - Added additional volumes checks to the manage snapshot API
|
||||||
3.0.11 - Fix the image cache capability bug #1491088
|
3.0.11 - Fix the image cache capability bug #1491088
|
||||||
3.0.12 - Remove client version checks for replication
|
3.0.12 - Remove client version checks for replication
|
||||||
|
3.0.13 - Support creating a cg from a source cg
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VERSION = "3.0.12"
|
VERSION = "3.0.13"
|
||||||
|
|
||||||
stats = {}
|
stats = {}
|
||||||
|
|
||||||
@ -512,22 +513,35 @@ class HPE3PARCommon(object):
|
|||||||
cgsnapshot=None, snapshots=None,
|
cgsnapshot=None, snapshots=None,
|
||||||
source_cg=None, source_vols=None):
|
source_cg=None, source_vols=None):
|
||||||
|
|
||||||
if cgsnapshot and snapshots:
|
|
||||||
self.create_consistencygroup(context, group)
|
self.create_consistencygroup(context, group)
|
||||||
vvs_name = self._get_3par_vvs_name(group.id)
|
vvs_name = self._get_3par_vvs_name(group.id)
|
||||||
|
if cgsnapshot and snapshots:
|
||||||
cgsnap_name = self._get_3par_snap_name(cgsnapshot.id)
|
cgsnap_name = self._get_3par_snap_name(cgsnapshot.id)
|
||||||
for i, (volume, snapshot) in enumerate(zip(volumes, snapshots)):
|
snap_base = cgsnap_name
|
||||||
snap_name = cgsnap_name + "-" + six.text_type(i)
|
elif source_cg and source_vols:
|
||||||
|
cg_id = source_cg.id
|
||||||
|
# Create a brand new uuid for the temp snap.
|
||||||
|
snap_uuid = uuid.uuid4().hex
|
||||||
|
|
||||||
|
# Create a temporary snapshot of the volume set in order to
|
||||||
|
# perform an online copy. These temp snapshots will be deleted
|
||||||
|
# when the source consistency group is deleted.
|
||||||
|
temp_snap = self._get_3par_snap_name(snap_uuid, temp_snap=True)
|
||||||
|
snap_shot_name = temp_snap + "-@count@"
|
||||||
|
copy_of_name = self._get_3par_vvs_name(cg_id)
|
||||||
|
optional = {'expirationHours': 1}
|
||||||
|
self.client.createSnapshotOfVolumeSet(snap_shot_name, copy_of_name,
|
||||||
|
optional=optional)
|
||||||
|
snap_base = temp_snap
|
||||||
|
|
||||||
|
for i, volume in enumerate(volumes):
|
||||||
|
snap_name = snap_base + "-" + six.text_type(i)
|
||||||
volume_name = self._get_3par_vol_name(volume['id'])
|
volume_name = self._get_3par_vol_name(volume['id'])
|
||||||
type_info = self.get_volume_settings_from_type(volume)
|
type_info = self.get_volume_settings_from_type(volume)
|
||||||
cpg = type_info['cpg']
|
cpg = type_info['cpg']
|
||||||
optional = {'online': True, 'snapCPG': cpg}
|
optional = {'online': True, 'snapCPG': cpg}
|
||||||
self.client.copyVolume(snap_name, volume_name, cpg, optional)
|
self.client.copyVolume(snap_name, volume_name, cpg, optional)
|
||||||
self.client.addVolumeToVolumeSet(vvs_name, volume_name)
|
self.client.addVolumeToVolumeSet(vvs_name, volume_name)
|
||||||
else:
|
|
||||||
msg = _("create_consistencygroup_from_src only supports a"
|
|
||||||
" cgsnapshot source, other sources cannot be used.")
|
|
||||||
raise exception.InvalidInput(reason=msg)
|
|
||||||
|
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Added support for creating a consistency group from a source consistency group
|
||||||
|
in the HPE 3PAR driver.
|
Loading…
Reference in New Issue
Block a user