Merge "XtremIO fix create CG from src flow"
This commit is contained in:
commit
2832a83bf7
@ -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')
|
||||
|
@ -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']
|
||||
|
Loading…
x
Reference in New Issue
Block a user