Merge "Updates consistency group for ibm svc driver"
This commit is contained in:
commit
7df01a599a
cinder
@ -2646,6 +2646,15 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
||||
cg = testutils.create_consistencygroup(self.ctxt, **kwargs)
|
||||
return cg
|
||||
|
||||
def _create_consistencegroup(self, **kwargs):
|
||||
cg = self._create_consistencygroup_in_db(**kwargs)
|
||||
|
||||
model_update = self.driver.create_consistencygroup(self.ctxt, cg)
|
||||
self.assertEqual('available',
|
||||
model_update['status'],
|
||||
"CG created failed")
|
||||
return cg
|
||||
|
||||
def _create_cgsnapshot_in_db(self, cg_id, **kwargs):
|
||||
cg_snapshot = testutils.create_cgsnapshot(self.ctxt,
|
||||
consistencygroup_id= cg_id,
|
||||
@ -2669,6 +2678,22 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
||||
|
||||
return cg_snapshot
|
||||
|
||||
def _create_cgsnapshot(self, cg_id, **kwargs):
|
||||
cg_snapshot = self._create_cgsnapshot_in_db(cg_id, **kwargs)
|
||||
|
||||
model_update, snapshots = (
|
||||
self.driver.create_cgsnapshot(self.ctxt, cg_snapshot, []))
|
||||
self.assertEqual('available',
|
||||
model_update['status'],
|
||||
"CGSnapshot created failed")
|
||||
|
||||
for snapshot in snapshots:
|
||||
self.assertEqual('available', snapshot['status'])
|
||||
snapshots = (
|
||||
self.db.snapshot_get_all_for_cgsnapshot(self.ctxt.elevated(),
|
||||
cg_snapshot['id']))
|
||||
return cg_snapshot, snapshots
|
||||
|
||||
def _create_test_vol(self, opts):
|
||||
ctxt = testutils.get_test_admin_context()
|
||||
type_ref = volume_types.create(ctxt, 'testtype', opts)
|
||||
@ -3808,6 +3833,170 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
||||
for volume in model_update[1]:
|
||||
self.assertEqual('deleted', volume['status'])
|
||||
|
||||
def test_storwize_consistency_group_from_src_invalid(self):
|
||||
# Invalid input case for create cg from src
|
||||
cg_type = self._create_consistency_group_volume_type()
|
||||
self.ctxt.user_id = 'fake_user_id'
|
||||
self.ctxt.project_id = 'fake_project_id'
|
||||
# create cg in db
|
||||
cg = self._create_consistencygroup_in_db(volume_type_id=cg_type['id'])
|
||||
|
||||
# create volumes in db
|
||||
vol1 = testutils.create_volume(self.ctxt, volume_type_id=cg_type['id'],
|
||||
consistencygroup_id=cg['id'])
|
||||
vol2 = testutils.create_volume(self.ctxt, volume_type_id=cg_type['id'],
|
||||
consistencygroup_id=cg['id'])
|
||||
volumes = [vol1, vol2]
|
||||
|
||||
source_cg = self._create_consistencegroup(volume_type_id=cg_type['id'])
|
||||
|
||||
# Add volumes to source CG
|
||||
src_vol1 = self._create_volume(volume_type_id=cg_type['id'],
|
||||
consistencygroup_id=source_cg['id'])
|
||||
src_vol2 = self._create_volume(volume_type_id=cg_type['id'],
|
||||
consistencygroup_id=source_cg['id'])
|
||||
source_vols = [src_vol1, src_vol2]
|
||||
|
||||
cgsnapshot, snapshots = self._create_cgsnapshot(source_cg['id'])
|
||||
|
||||
# Create cg from src with null input
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.driver.create_consistencygroup_from_src,
|
||||
self.ctxt, cg, volumes, None, None,
|
||||
None, None)
|
||||
|
||||
# Create cg from src with source_cg and empty source_vols
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.driver.create_consistencygroup_from_src,
|
||||
self.ctxt, cg, volumes, None, None,
|
||||
source_cg, None)
|
||||
|
||||
# Create cg from src with source_vols and empty source_cg
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.driver.create_consistencygroup_from_src,
|
||||
self.ctxt, cg, volumes, None, None,
|
||||
None, source_vols)
|
||||
|
||||
# Create cg from src with cgsnapshot and empty snapshots
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.driver.create_consistencygroup_from_src,
|
||||
self.ctxt, cg, volumes, cgsnapshot, None,
|
||||
None, None)
|
||||
# Create cg from src with snapshots and empty cgsnapshot
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.driver.create_consistencygroup_from_src,
|
||||
self.ctxt, cg, volumes, None, snapshots,
|
||||
None, None)
|
||||
|
||||
model_update = self.driver.delete_consistencygroup(self.ctxt, cg, [])
|
||||
|
||||
self.assertEqual('deleted', model_update[0]['status'])
|
||||
for volume in model_update[1]:
|
||||
self.assertEqual('deleted', volume['status'])
|
||||
|
||||
model_update = (
|
||||
self.driver.delete_consistencygroup(self.ctxt, source_cg, []))
|
||||
|
||||
self.assertEqual('deleted', model_update[0]['status'])
|
||||
for volume in model_update[1]:
|
||||
self.assertEqual('deleted', volume['status'])
|
||||
|
||||
model_update = (
|
||||
self.driver.delete_consistencygroup(self.ctxt, cgsnapshot, []))
|
||||
|
||||
self.assertEqual('deleted', model_update[0]['status'])
|
||||
for volume in model_update[1]:
|
||||
self.assertEqual('deleted', volume['status'])
|
||||
|
||||
def test_storwize_consistency_group_from_src(self):
|
||||
# Valid case for create cg from src
|
||||
cg_type = self._create_consistency_group_volume_type()
|
||||
self.ctxt.user_id = 'fake_user_id'
|
||||
self.ctxt.project_id = 'fake_project_id'
|
||||
|
||||
# Create cg in db
|
||||
cg = self._create_consistencygroup_in_db(volume_type_id=cg_type['id'])
|
||||
# Create volumes in db
|
||||
testutils.create_volume(self.ctxt, volume_type_id=cg_type['id'],
|
||||
consistencygroup_id=cg['id'])
|
||||
testutils.create_volume(self.ctxt, volume_type_id=cg_type['id'],
|
||||
consistencygroup_id=cg['id'])
|
||||
volumes = (
|
||||
self.db.volume_get_all_by_group(self.ctxt.elevated(), cg['id']))
|
||||
|
||||
# Create source CG
|
||||
source_cg = self._create_consistencegroup(volume_type_id=cg_type['id'])
|
||||
# Add volumes to source CG
|
||||
self._create_volume(volume_type_id=cg_type['id'],
|
||||
consistencygroup_id=source_cg['id'])
|
||||
self._create_volume(volume_type_id=cg_type['id'],
|
||||
consistencygroup_id=source_cg['id'])
|
||||
source_vols = self.db.volume_get_all_by_group(
|
||||
self.ctxt.elevated(), source_cg['id'])
|
||||
|
||||
# Create cgsnapshot
|
||||
cgsnapshot, snapshots = self._create_cgsnapshot(source_cg['id'])
|
||||
|
||||
# Create cg from source cg
|
||||
model_update, volumes_model_update = (
|
||||
self.driver.create_consistencygroup_from_src(self.ctxt,
|
||||
cg,
|
||||
volumes,
|
||||
None, None,
|
||||
source_cg,
|
||||
source_vols))
|
||||
self.assertEqual('available',
|
||||
model_update['status'],
|
||||
"CG create from src created failed")
|
||||
|
||||
for each_vol in volumes_model_update:
|
||||
self.assertEqual('available', each_vol['status'])
|
||||
model_update = self.driver.delete_consistencygroup(self.ctxt,
|
||||
cg,
|
||||
[])
|
||||
|
||||
self.assertEqual('deleted', model_update[0]['status'])
|
||||
for each_vol in model_update[1]:
|
||||
self.assertEqual('deleted', each_vol['status'])
|
||||
|
||||
# Create cg from cg snapshot
|
||||
model_update, volumes_model_update = (
|
||||
self.driver.create_consistencygroup_from_src(self.ctxt,
|
||||
cg,
|
||||
volumes,
|
||||
cgsnapshot,
|
||||
snapshots,
|
||||
None, None))
|
||||
self.assertEqual('available',
|
||||
model_update['status'],
|
||||
"CG create from src created failed")
|
||||
|
||||
for each_vol in volumes:
|
||||
self.assertEqual('available', each_vol['status'])
|
||||
|
||||
model_update = self.driver.delete_consistencygroup(self.ctxt,
|
||||
cg, [])
|
||||
|
||||
self.assertEqual('deleted', model_update[0]['status'])
|
||||
for each_vol in model_update[1]:
|
||||
self.assertEqual('deleted', each_vol['status'])
|
||||
|
||||
model_update = self.driver.delete_consistencygroup(self.ctxt,
|
||||
cgsnapshot,
|
||||
[])
|
||||
|
||||
self.assertEqual('deleted', model_update[0]['status'])
|
||||
for volume in model_update[1]:
|
||||
self.assertEqual('deleted', volume['status'])
|
||||
|
||||
model_update = self.driver.delete_consistencygroup(self.ctxt,
|
||||
source_cg,
|
||||
[])
|
||||
|
||||
self.assertEqual('deleted', model_update[0]['status'])
|
||||
for each_vol in model_update[1]:
|
||||
self.assertEqual('deleted', each_vol['status'])
|
||||
|
||||
def _create_volume_type_qos(self, extra_specs, fake_qos):
|
||||
# Generate a QoS volume type for volume.
|
||||
if extra_specs:
|
||||
|
@ -1209,6 +1209,59 @@ class StorwizeHelpers(object):
|
||||
return mapping_ready
|
||||
self._wait_for_a_condition(prepare_fc_consistgrp_success, timeout)
|
||||
|
||||
def create_cg_from_source(self, group, fc_consistgrp,
|
||||
sources, targets, state,
|
||||
config, timeout):
|
||||
"""Create consistence group from source"""
|
||||
LOG.debug('Enter: create_cg_from_source: cg %(cg)s'
|
||||
' source %(source)s, target %(target)s',
|
||||
{'cg': fc_consistgrp, 'source': sources, 'target': targets})
|
||||
model_update = {'status': 'available'}
|
||||
ctxt = context.get_admin_context()
|
||||
try:
|
||||
for source, target in zip(sources, targets):
|
||||
opts = self.get_vdisk_params(config, state,
|
||||
source['volume_type_id'])
|
||||
self.create_flashcopy_to_consistgrp(source['name'],
|
||||
target['name'],
|
||||
fc_consistgrp,
|
||||
config, opts,
|
||||
True)
|
||||
self.prepare_fc_consistgrp(fc_consistgrp, timeout)
|
||||
self.start_fc_consistgrp(fc_consistgrp)
|
||||
self.delete_fc_consistgrp(fc_consistgrp)
|
||||
volumes_model_update = self._get_volume_model_updates(
|
||||
ctxt, targets, group['id'], model_update['status'])
|
||||
except exception.VolumeBackendAPIException as err:
|
||||
model_update['status'] = 'error'
|
||||
volumes_model_update = self._get_volume_model_updates(
|
||||
ctxt, targets, group['id'], model_update['status'])
|
||||
with excutils.save_and_reraise_exception():
|
||||
# Release cg
|
||||
self.delete_fc_consistgrp(fc_consistgrp)
|
||||
LOG.error(_LE("Failed to create CG from CGsnapshot. "
|
||||
"Exception: %s"), err)
|
||||
return model_update, volumes_model_update
|
||||
|
||||
LOG.debug('Leave: create_cg_from_source.')
|
||||
return model_update, volumes_model_update
|
||||
|
||||
def _get_volume_model_updates(self, ctxt, volumes, cgId,
|
||||
status='available'):
|
||||
"""Update the volume model's status and return it."""
|
||||
volume_model_updates = []
|
||||
LOG.info(_LI(
|
||||
"Updating status for CG: %(id)s."),
|
||||
{'id': cgId})
|
||||
if volumes:
|
||||
for volume in volumes:
|
||||
volume_model_updates.append({'id': volume['id'],
|
||||
'status': status})
|
||||
else:
|
||||
LOG.info(_LI("No volume found for CG: %(cg)s."),
|
||||
{'cg': cgId})
|
||||
return volume_model_updates
|
||||
|
||||
def run_flashcopy(self, source, target, timeout, copy_rate,
|
||||
full_copy=True):
|
||||
"""Create a FlashCopy mapping from the source to the target."""
|
||||
@ -2298,6 +2351,56 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
{'vol': volume['name'], 'exception': err})
|
||||
return model_update, volumes
|
||||
|
||||
def update_consistencygroup(self, ctxt, group, add_volumes,
|
||||
remove_volumes):
|
||||
"""Adds or removes volume(s) to/from an existing consistency group."""
|
||||
|
||||
LOG.debug("Updating consistency group.")
|
||||
return None, None, None
|
||||
|
||||
def create_consistencygroup_from_src(self, context, group, volumes,
|
||||
cgsnapshot=None, snapshots=None,
|
||||
source_cg=None, source_vols=None):
|
||||
"""Creates a consistencygroup from source.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param group: the dictionary of the consistency group to be created.
|
||||
:param volumes: a list of volume dictionaries in the group.
|
||||
:param cgsnapshot: the dictionary of the cgsnapshot as source.
|
||||
:param snapshots: a list of snapshot dictionaries in the cgsnapshot.
|
||||
:param source_cg: the dictionary of a consistency group as source.
|
||||
:param source_vols: a list of volume dictionaries in the source_cg.
|
||||
:return model_update, volumes_model_update
|
||||
"""
|
||||
LOG.debug('Enter: create_consistencygroup_from_src.')
|
||||
if cgsnapshot and snapshots:
|
||||
cg_name = 'cg-' + cgsnapshot.id
|
||||
sources = snapshots
|
||||
|
||||
elif source_cg and source_vols:
|
||||
cg_name = 'cg-' + source_cg.id
|
||||
sources = source_vols
|
||||
|
||||
else:
|
||||
error_msg = _("create_consistencygroup_from_src must be "
|
||||
"creating from a CG snapshot, or a source CG.")
|
||||
raise exception.InvalidInput(reason=error_msg)
|
||||
|
||||
LOG.debug('create_consistencygroup_from_src: cg_name %(cg_name)s'
|
||||
' %(sources)s', {'cg_name': cg_name, 'sources': sources})
|
||||
self._helpers.create_fc_consistgrp(cg_name)
|
||||
timeout = self.configuration.storwize_svc_flashcopy_timeout
|
||||
model_update, snapshots_model = (
|
||||
self._helpers.create_cg_from_source(group,
|
||||
cg_name,
|
||||
sources,
|
||||
volumes,
|
||||
self._state,
|
||||
self.configuration,
|
||||
timeout))
|
||||
LOG.debug("Leave: create_consistencygroup_from_src.")
|
||||
return model_update, snapshots_model
|
||||
|
||||
def create_cgsnapshot(self, ctxt, cgsnapshot, snapshots):
|
||||
"""Creates a cgsnapshot."""
|
||||
# Use cgsnapshot id as cg name
|
||||
|
Loading…
x
Reference in New Issue
Block a user