from cinder import exception
from cinder import test
+from cinder.tests.unit import fake_consistencygroup as fake_cg
from cinder.tests.unit import fake_snapshot
+from cinder.tests.unit import fake_volume
from cinder.volume.drivers.emc import xtremio
(self.driver.db.
volume_get_all_by_group.return_value) = [mock.MagicMock()]
self.driver.create_cgsnapshot(d.context, d.cgsnapshot)
- snaps_name = self.driver._get_cgsnap_name(d.cgsnapshot)
- snaps = xms_data['volumes'][1]
- snaps['index'] = 1
- xms_data['snapshot-sets'] = {snaps_name: snaps, 1: snaps}
+ 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}
+ self.driver.delete_cgsnapshot(d.context, d.cgsnapshot)
+ self.driver.delete_consistencygroup(d.context, d.group)
+ xms_data['snapshot-sets'] = {}
+
+ @mock.patch('cinder.objects.snapshot.SnapshotList.get_all_for_cgsnapshot')
+ def test_cg_from_src(self, get_all_for_cgsnapshot, req):
+ req.side_effect = xms_request
+ d = self.data
+
self.assertRaises(exception.InvalidInput,
self.driver.create_consistencygroup_from_src,
d.context, d.group, [], None, None, None, None)
- self.driver.delete_cgsnapshot(d.context, d.cgsnapshot)
- self.driver.delete_consistencygroup(d.context, d.group)
+
+ snapshot_obj = fake_snapshot.fake_snapshot_obj(d.context)
+ snapshot_obj.consistencygroup_id = d.group['id']
+ snapshot_obj.volume_id = d.test_volume['id']
+ get_all_for_cgsnapshot.return_value = [snapshot_obj]
+
+ self.driver.create_consistencygroup(d.context, d.group)
+ self.driver.create_volume(d.test_volume)
+ self.driver.create_cgsnapshot(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.fake_volume_obj(d.context)
+ snapshot1 = (fake_snapshot
+ .fake_snapshot_obj
+ (d.context, volume_id=d.test_volume['id']))
+ self.driver.create_consistencygroup_from_src(d.context, cg_obj,
+ [new_vol1],
+ d.cgsnapshot, [snapshot1])
@mock.patch('requests.request')
ALREADY_MAPPED_ERR = 'already_mapped'
SYSTEM_BUSY = 'system_is_busy'
+XTREMIO_OID_NAME = 1
+XTREMIO_OID_INDEX = 2
+
class XtremIOClient(object):
def __init__(self, configuration, cluster_id):
def get_initiator(self, port_address):
raise NotImplementedError()
+ def add_vol_to_cg(self, vol_id, cg_id):
+ pass
+
class XtremIOClient3(XtremIOClient):
def __init__(self, configuration, cluster_id):
}
self.client.req('volumes', 'POST', data)
- if volume.get('consistencygroup_id') and self.client is XtremIOClient4:
+ if volume.get('consistencygroup_id'):
self.client.add_vol_to_cg(volume['id'],
volume['consistencygroup_id'])
def create_volume_from_snapshot(self, volume, snapshot):
"""Creates a volume from a snapshot."""
- self.client.create_snapshot(snapshot.id, volume['id'])
+ if snapshot.get('cgsnapshot_id'):
+ # get array snapshot id from CG snapshot
+ snap_by_anc = self.get_snapset_ancestors(snapshot.cgsnapshot)
+ snapshot_id = snap_by_anc[snapshot['volume_id']]
+ else:
+ snapshot_id = snapshot['id']
- if (snapshot.get('consistencygroup_id') and
+ self.client.create_snapshot(snapshot_id, volume['id'])
+
+ # add new volume to consistency group
+ if (volume.get('consistencygroup_id') and
self.client is XtremIOClient4):
self.client.add_vol_to_cg(volume['id'],
snapshot['consistencygroup_id'])
return model_update, volumes
+ def get_snapset_ancestors(self, cgsnapshot):
+ snapset_name = self._get_cgsnap_name(cgsnapshot)
+ snapset = self.client.req('snapshot-sets',
+ name=snapset_name)['content']
+ volume_ids = [s[XTREMIO_OID_INDEX] for s in snapset['vol-list']]
+ return {v['ancestor-vol-id'][XTREMIO_OID_NAME]: v['name'] for v
+ in self.client.req('volumes',
+ data={'full': 1,
+ 'props':
+ 'ancestor-vol-id'})['volumes']
+ if v['index'] in volume_ids}
+
def create_consistencygroup_from_src(self, context, group, volumes,
cgsnapshot=None, snapshots=None,
source_cg=None, source_vols=None):
:return model_update, volumes_model_update
"""
if cgsnapshot and snapshots:
+ snap_by_anc = self.get_snapset_ancestors(cgsnapshot)
for volume, snapshot in zip(volumes, snapshots):
- self.create_volume_from_snapshot(volume, snapshot)
+ real_snap = snap_by_anc[snapshot['volume_id']]
+ self.create_volume_from_snapshot(volume, {'id': real_snap})
create_data = {'consistency-group-name': group['id'],
'vol-list': [v['id'] for v in volumes]}
self.client.req('consistency-groups', 'POST', data=create_data,
if initiator:
login_passwd = initiator['chap-authentication-initiator-password']
discovery_passwd = initiator['chap-discovery-initiator-password']
- ig = self._get_ig(initiator['ig-id'][1])
+ ig = self._get_ig(initiator['ig-id'][XTREMIO_OID_NAME])
else:
ig = self._get_ig(self._get_ig_name(connector))
if not ig:
self.client.req('initiators', 'PUT', data, idx=initiator['index'])
# lun mappping
- lunmap = self.create_lun_map(volume, ig['ig-id'][1])
+ lunmap = self.create_lun_map(volume, ig['ig-id'][XTREMIO_OID_NAME])
properties = self._get_iscsi_properties(lunmap)
(data=_("Failed to get targets")))
return self._targets
+ def _get_free_lun(self, igs):
+ luns = []
+ for ig in igs:
+ luns.extend(lm['lun'] for lm in
+ self.client.req('lun-maps',
+ data={'full': 1, 'prop': 'lun',
+ 'filter': 'ig-name:eq:%s' % ig})
+ ['lun-maps'])
+ uniq_luns = set(luns + [0])
+ seq = range(len(uniq_luns) + 1)
+ return min(set(seq) - uniq_luns)
+
@fczm_utils.AddFCZone
def initialize_connection(self, volume, connector):
wwpns = self._get_initiator_name(connector)
data = {'initiator-name': wwpn, 'ig-id': ig_name,
'port-address': wwpn}
self.client.req('initiators', 'POST', data)
- igs = list(set([i['ig-id'][1] for i in found] + [ig_name]))
+ igs = list(set([i['ig-id'][XTREMIO_OID_NAME]
+ for i in found] + [ig_name]))
- lun_num = None
+ if len(igs) > 1:
+ lun_num = self._get_free_lun(igs)
+ else:
+ lun_num = None
for ig in igs:
lunmap = self.create_lun_map(volume, ig, lun_num)
lun_num = lunmap['lun']