Merge "XtremIO fix create CG from src flow"

This commit is contained in:
Jenkins 2015-11-11 16:00:40 +00:00 committed by Gerrit Code Review
commit 2832a83bf7
2 changed files with 97 additions and 14 deletions

View File

@ -17,7 +17,9 @@ import mock
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
@ -465,15 +467,52 @@ class EMCXIODriverISCSITestCase(test.TestCase):
(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')

View File

@ -70,6 +70,9 @@ VOL_OBJ_NOT_FOUND_ERR = 'vol_obj_not_found'
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):
@ -184,6 +187,9 @@ class XtremIOClient(object):
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):
@ -367,15 +373,23 @@ class XtremIOVolumeDriver(san.SanDriver):
}
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'])
@ -566,6 +580,18 @@ class XtremIOVolumeDriver(san.SanDriver):
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):
@ -579,8 +605,10 @@ class XtremIOVolumeDriver(san.SanDriver):
: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,
@ -726,7 +754,7 @@ class XtremIOISCSIDriver(XtremIOVolumeDriver, driver.ISCSIDriver):
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:
@ -748,7 +776,7 @@ class XtremIOISCSIDriver(XtremIOVolumeDriver, driver.ISCSIDriver):
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)
@ -839,6 +867,18 @@ class XtremIOFibreChannelDriver(XtremIOVolumeDriver,
(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)
@ -862,9 +902,13 @@ class XtremIOFibreChannelDriver(XtremIOVolumeDriver,
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']