XtremIO: Add CG capability to generic groups.
Add consistency group capability to generic volume groups. DocImpact Change-Id: I0276769b5457961dafbfc4e7f570ac67aa41bbe3 implements: blueprint xtremio-cg-over-generic-groups
This commit is contained in:
parent
02389a1d2a
commit
ca77a489dc
@ -820,8 +820,6 @@ class XtremIODriverISCSITestCase(BaseXtremIODriverTestCase):
|
||||
add_volumes=[d.test_volume,
|
||||
d.test_volume2])
|
||||
self.driver.db = mock.Mock()
|
||||
(self.driver.db.
|
||||
volume_get_all_by_group.return_value) = [mock.MagicMock()]
|
||||
self.driver.create_cgsnapshot(d.context, d.cgsnapshot, [snapshot_obj])
|
||||
self.driver.delete_consistencygroup(d.context, d.group, [])
|
||||
|
||||
@ -938,6 +936,169 @@ class XtremIODriverISCSITestCase(BaseXtremIODriverTestCase):
|
||||
self.driver.create_consistencygroup_from_src,
|
||||
d.context, d.group, [], None, None, None, None)
|
||||
|
||||
# #### Groups ####
|
||||
def test_group_create(self, req):
|
||||
"""Test group create."""
|
||||
|
||||
req.side_effect = xms_request
|
||||
d = self.data
|
||||
|
||||
self.driver.create_group(d.context, d.group)
|
||||
self.assertEqual(1, len(xms_data['consistency-groups']))
|
||||
|
||||
def test_group_update(self, req):
|
||||
"""Test group update."""
|
||||
|
||||
req.side_effect = xms_request
|
||||
d = self.data
|
||||
|
||||
self.driver.create_consistencygroup(d.context, d.group)
|
||||
self.driver.update_consistencygroup(d.context, d.group,
|
||||
add_volumes=[d.test_volume,
|
||||
d.test_volume2])
|
||||
self.assertEqual(2, len(xms_data['consistency-group-volumes']))
|
||||
self.driver.update_group(d.context, d.group,
|
||||
remove_volumes=[d.test_volume2])
|
||||
self.assertEqual(1, len(xms_data['consistency-group-volumes']))
|
||||
|
||||
def test_create_group_snapshot(self, req):
|
||||
"""Test create group snapshot."""
|
||||
|
||||
req.side_effect = xms_request
|
||||
d = self.data
|
||||
snapshot_obj = fake_snapshot.fake_snapshot_obj(d.context)
|
||||
snapshot_obj.consistencygroup_id = d.group['id']
|
||||
|
||||
self.driver.create_group(d.context, d.group)
|
||||
self.driver.update_group(d.context, d.group,
|
||||
add_volumes=[d.test_volume,
|
||||
d.test_volume2])
|
||||
|
||||
res = self.driver.create_group_snapshot(d.context, d.cgsnapshot,
|
||||
[snapshot_obj])
|
||||
self.assertEqual((None, None), res)
|
||||
|
||||
def test_group_delete(self, req):
|
||||
""""Test delete group."""
|
||||
req.side_effect = xms_request
|
||||
d = self.data
|
||||
snapshot_obj = fake_snapshot.fake_snapshot_obj(d.context)
|
||||
snapshot_obj.consistencygroup_id = d.group['id']
|
||||
self.driver.create_group(d.context, d.group)
|
||||
self.driver.update_group(d.context, d.group,
|
||||
add_volumes=[d.test_volume,
|
||||
d.test_volume2])
|
||||
self.driver.db = mock.Mock()
|
||||
(self.driver.db.
|
||||
volume_get_all_by_group.return_value) = [mock.MagicMock()]
|
||||
self.driver.create_group_snapshot(d.context, d.cgsnapshot,
|
||||
[snapshot_obj])
|
||||
self.driver.delete_group(d.context, d.group, [])
|
||||
|
||||
def test_group_snapshot(self, req):
|
||||
"""test group snapshot."""
|
||||
req.side_effect = xms_request
|
||||
d = self.data
|
||||
snapshot_obj = fake_snapshot.fake_snapshot_obj(d.context)
|
||||
snapshot_obj.consistencygroup_id = d.group['id']
|
||||
self.driver.create_group(d.context, d.group)
|
||||
self.driver.update_group(d.context, d.group,
|
||||
add_volumes=[d.test_volume,
|
||||
d.test_volume2])
|
||||
|
||||
snapset_name = self.driver._get_cgsnap_name(d.cgsnapshot)
|
||||
self.assertEqual(snapset_name,
|
||||
'192eb39b6c2f420cbae33cfd117f0345192eb39b6c2f420cbae'
|
||||
'33cfd117f9876')
|
||||
snapset1 = {'ancestor-vol-id': ['', d.test_volume['id'], 2],
|
||||
'consistencygroup_id': d.group['id'],
|
||||
'name': snapset_name,
|
||||
'index': 1}
|
||||
xms_data['snapshot-sets'] = {snapset_name: snapset1, 1: snapset1}
|
||||
res = self.driver.delete_group_snapshot(d.context, d.cgsnapshot,
|
||||
[snapshot_obj])
|
||||
self.assertEqual((None, None), res)
|
||||
|
||||
def test_delete_group_snapshot(self, req):
|
||||
"""test delete group snapshot."""
|
||||
d = self.data
|
||||
snapshot_obj = fake_snapshot.fake_snapshot_obj(d.context)
|
||||
snapshot_obj.consistencygroup_id = d.group['id']
|
||||
self.driver.delete_group_snapshot(d.context, d.cgsnapshot,
|
||||
[snapshot_obj])
|
||||
req.assert_called_once_with('snapshot-sets', 'DELETE', None,
|
||||
'192eb39b6c2f420cbae33cfd117f0345192eb39'
|
||||
'b6c2f420cbae33cfd117f9876', None, 'v2')
|
||||
|
||||
def test_group_from_src_snapshot(self, req):
|
||||
"""test group from source snapshot."""
|
||||
req.side_effect = xms_request
|
||||
d = self.data
|
||||
|
||||
self.driver.create_group(d.context, d.group)
|
||||
self.driver.create_volume(d.test_volume)
|
||||
self.driver.create_group_snapshot(d.context, d.cgsnapshot, [])
|
||||
xms_data['volumes'][2]['ancestor-vol-id'] = (xms_data['volumes'][1]
|
||||
['vol-id'])
|
||||
snapset_name = self.driver._get_cgsnap_name(d.cgsnapshot)
|
||||
|
||||
snapset1 = {'vol-list': [xms_data['volumes'][2]['vol-id']],
|
||||
'name': snapset_name,
|
||||
'index': 1}
|
||||
xms_data['snapshot-sets'] = {snapset_name: snapset1, 1: snapset1}
|
||||
cg_obj = fake_cg.fake_consistencyobject_obj(d.context)
|
||||
new_vol1 = fake_volume_obj(d.context)
|
||||
snapshot1 = (fake_snapshot
|
||||
.fake_snapshot_obj
|
||||
(d.context, volume_id=d.test_volume['id']))
|
||||
res = self.driver.create_group_from_src(d.context, cg_obj,
|
||||
[new_vol1],
|
||||
d.cgsnapshot,
|
||||
[snapshot1])
|
||||
self.assertEqual((None, None), res)
|
||||
|
||||
def test_group_from_src_group(self, req):
|
||||
"""test group from source group."""
|
||||
req.side_effect = xms_request
|
||||
d = self.data
|
||||
|
||||
self.driver.create_group(d.context, d.group)
|
||||
self.driver.create_volume(d.test_volume)
|
||||
self.driver.create_group_snapshot(d.context, d.cgsnapshot, [])
|
||||
xms_data['volumes'][2]['ancestor-vol-id'] = (xms_data['volumes'][1]
|
||||
['vol-id'])
|
||||
snapset_name = self.driver._get_cgsnap_name(d.cgsnapshot)
|
||||
|
||||
snapset1 = {'vol-list': [xms_data['volumes'][2]['vol-id']],
|
||||
'name': snapset_name,
|
||||
'index': 1}
|
||||
xms_data['snapshot-sets'] = {snapset_name: snapset1, 1: snapset1}
|
||||
cg_obj = fake_cg.fake_consistencyobject_obj(d.context)
|
||||
new_vol1 = fake_volume_obj(d.context)
|
||||
new_cg_obj = fake_cg.fake_consistencyobject_obj(
|
||||
d.context, id=fake.CONSISTENCY_GROUP2_ID)
|
||||
snapset2_name = new_cg_obj.id
|
||||
new_vol1.id = '192eb39b-6c2f-420c-bae3-3cfd117f0001'
|
||||
new_vol2 = fake_volume_obj(d.context)
|
||||
snapset2 = {'vol-list': [xms_data['volumes'][2]['vol-id']],
|
||||
'name': snapset2_name,
|
||||
'index': 1}
|
||||
xms_data['snapshot-sets'].update({5: snapset2,
|
||||
snapset2_name: snapset2})
|
||||
self.driver.create_group_from_src(d.context, new_cg_obj,
|
||||
[new_vol2],
|
||||
None, None,
|
||||
cg_obj, [new_vol1])
|
||||
|
||||
def test_invalid_group_from_src_input(self, req):
|
||||
"""test invalid group from source."""
|
||||
req.side_effect = xms_request
|
||||
d = self.data
|
||||
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.driver.create_group_from_src,
|
||||
d.context, d.group, [], None, None, None, None)
|
||||
|
||||
|
||||
@mock.patch('requests.request')
|
||||
class XtremIODriverTestCase(BaseXtremIODriverTestCase):
|
||||
|
@ -408,15 +408,25 @@ class XtremIOVolumeDriver(san.SanDriver):
|
||||
self.client = XtremIOClient4(self.configuration, self.cluster_id)
|
||||
|
||||
def create_volume(self, volume):
|
||||
"Creates a volume"
|
||||
"""Creates a volume."""
|
||||
data = {'vol-name': volume['id'],
|
||||
'vol-size': str(volume['size']) + 'g'
|
||||
}
|
||||
self.client.req('volumes', 'POST', data)
|
||||
|
||||
if volume.get('consistencygroup_id'):
|
||||
# Add the volume to a cg in case volume requested a cgid or group_id.
|
||||
# If both cg_id and group_id exists in a volume. group_id will take
|
||||
# place.
|
||||
|
||||
consistency_group = volume.get('consistencygroup_id')
|
||||
|
||||
# if cg_id and group_id are both exists, we gives priority to group_id.
|
||||
if volume.get('group_id'):
|
||||
consistency_group = volume.get('group_id')
|
||||
|
||||
if consistency_group:
|
||||
self.client.add_vol_to_cg(volume['id'],
|
||||
volume['consistencygroup_id'])
|
||||
consistency_group)
|
||||
|
||||
def create_volume_from_snapshot(self, volume, snapshot):
|
||||
"""Creates a volume from a snapshot."""
|
||||
@ -679,8 +689,6 @@ class XtremIOVolumeDriver(san.SanDriver):
|
||||
self.client.req('consistency-groups', 'DELETE', name=group['id'],
|
||||
ver='v2')
|
||||
|
||||
volumes = self.db.volume_get_all_by_group(context, group['id'])
|
||||
|
||||
for volume in volumes:
|
||||
self.delete_volume(volume)
|
||||
volume.status = 'deleted'
|
||||
@ -787,6 +795,94 @@ class XtremIOVolumeDriver(san.SanDriver):
|
||||
|
||||
return None, None
|
||||
|
||||
def create_group(self, context, group):
|
||||
"""Creates a group.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param group: the group object.
|
||||
:returns: model_update
|
||||
"""
|
||||
|
||||
# the driver treats a group as a CG internally.
|
||||
# We proxy the calls to the CG api.
|
||||
return self.create_consistencygroup(context, group)
|
||||
|
||||
def delete_group(self, context, group, volumes):
|
||||
"""Deletes a group.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param group: the group object.
|
||||
:param volumes: a list of volume objects in the group.
|
||||
:returns: model_update, volumes_model_update
|
||||
"""
|
||||
|
||||
# the driver treats a group as a CG internally.
|
||||
# We proxy the calls to the CG api.
|
||||
return self.delete_consistencygroup(context, group, volumes)
|
||||
|
||||
def update_group(self, context, group,
|
||||
add_volumes=None, remove_volumes=None):
|
||||
"""Updates a group.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param group: the group object.
|
||||
:param add_volumes: a list of volume objects to be added.
|
||||
:param remove_volumes: a list of volume objects to be removed.
|
||||
:returns: model_update, add_volumes_update, remove_volumes_update
|
||||
"""
|
||||
|
||||
# the driver treats a group as a CG internally.
|
||||
# We proxy the calls to the CG api.
|
||||
return self.update_consistencygroup(context, group, add_volumes,
|
||||
remove_volumes)
|
||||
|
||||
def create_group_from_src(self, context, group, volumes,
|
||||
group_snapshot=None, snapshots=None,
|
||||
source_group=None, source_vols=None):
|
||||
"""Creates a group from source.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param group: the Group object to be created.
|
||||
:param volumes: a list of Volume objects in the group.
|
||||
:param group_snapshot: the GroupSnapshot object as source.
|
||||
:param snapshots: a list of snapshot objects in group_snapshot.
|
||||
:param source_group: the Group object as source.
|
||||
:param source_vols: a list of volume objects in the source_group.
|
||||
:returns: model_update, volumes_model_update
|
||||
"""
|
||||
|
||||
# the driver treats a group as a CG internally.
|
||||
# We proxy the calls to the CG api.
|
||||
return self.create_consistencygroup_from_src(context, group, volumes,
|
||||
group_snapshot, snapshots,
|
||||
source_group, source_vols)
|
||||
|
||||
def create_group_snapshot(self, context, group_snapshot, snapshots):
|
||||
"""Creates a group_snapshot.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param group_snapshot: the GroupSnapshot object to be created.
|
||||
:param snapshots: a list of Snapshot objects in the group_snapshot.
|
||||
:returns: model_update, snapshots_model_update
|
||||
"""
|
||||
|
||||
# the driver treats a group as a CG internally.
|
||||
# We proxy the calls to the CG api.
|
||||
return self.create_cgsnapshot(context, group_snapshot, snapshots)
|
||||
|
||||
def delete_group_snapshot(self, context, group_snapshot, snapshots):
|
||||
"""Deletes a group_snapshot.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param group_snapshot: the GroupSnapshot object to be deleted.
|
||||
:param snapshots: a list of snapshot objects in the group_snapshot.
|
||||
:returns: model_update, snapshots_model_update
|
||||
"""
|
||||
|
||||
# the driver treats a group as a CG internally.
|
||||
# We proxy the calls to the CG api.
|
||||
return self.delete_cgsnapshot(context, group_snapshot, snapshots)
|
||||
|
||||
def _get_ig(self, name):
|
||||
try:
|
||||
return self.client.req('initiator-groups', 'GET',
|
||||
|
@ -0,0 +1,3 @@
|
||||
---
|
||||
features:
|
||||
- Add consistent group capability to generic volume groups in the XtremIO driver.
|
Loading…
Reference in New Issue
Block a user