From 460489baa5804daf9553caa7433bee08609ba478 Mon Sep 17 00:00:00 2001 From: peter_wang Date: Mon, 19 Oct 2015 04:06:49 -0400 Subject: [PATCH] VNX: Fix failure in SnapCopy feature Previously, user needs to enable this feature via Volume Type. See: https://review.openstack.org/#/c/184733/ This introduces some failures for volume operations, for example: 1. Creating cloned volume or snapshot from snapcopy volume will fail. 2. Creating volume from snapshot whose source volume's volume type is snapcopy type will fail. 3. Creating non-snapcopy volume from source volume with snapcopy type will fail. In order to fix above issues, Driver needs to store the base LUN info for all volumes. When creating cloned volume or volume from snapshot , driver extracts the base LUN info and creates snapshot mount point according to the base LUN and then exposes as a snapcopy volume. Example cinder command to enable snapcopy on volume: cinder create --source-volid --metadata snapcopy=True or cinder create --snapshot-id --metadata snapcopy=True liberty-backport-potential DocImpact Change-Id: I91c83ddac9bcad9c7c788d7bf82bcc4dced71751 Closes-Bug: 1514319 --- ...{test_emc_vnxdirect.py => test_emc_vnx.py} | 978 ++++++++++-------- cinder/volume/drivers/emc/emc_vnx_cli.py | 282 ++--- 2 files changed, 680 insertions(+), 580 deletions(-) rename cinder/tests/unit/{test_emc_vnxdirect.py => test_emc_vnx.py} (90%) diff --git a/cinder/tests/unit/test_emc_vnxdirect.py b/cinder/tests/unit/test_emc_vnx.py similarity index 90% rename from cinder/tests/unit/test_emc_vnxdirect.py rename to cinder/tests/unit/test_emc_vnx.py index 76b340726..8a1b80b42 100644 --- a/cinder/tests/unit/test_emc_vnxdirect.py +++ b/cinder/tests/unit/test_emc_vnx.py @@ -40,130 +40,144 @@ FAKE_ERROR_RETURN = ("FAKE ERROR", 255) VERSION = emc_vnx_cli.EMCVnxCliBase.VERSION +def build_provider_location(lun_id, lun_type, base_lun_name=None, system=None): + pl_dict = {'system': 'FNM11111' if system is None else system, + 'type': six.text_type(lun_type), + 'id': six.text_type(lun_id), + 'base_lun_name': six.text_type(base_lun_name), + 'version': VERSION} + return '|'.join([k + '^' + pl_dict[k] for k in pl_dict]) + + +def build_migration_dest_name(src_name): + return src_name + '_dest' + + class EMCVNXCLIDriverTestData(object): + base_lun_name = 'volume-1' test_volume = { 'status': 'creating', - 'name': 'vol1', + 'name': 'volume-1', 'size': 1, - 'volume_name': 'vol1', + 'volume_name': 'volume-1', 'id': '1', 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", 'project_id': 'project', - 'provider_location': 'system^FNM11111|type^lun|id^1|version^05.03.00', - 'display_name': 'vol1', + 'provider_location': build_provider_location(1, 'lun', base_lun_name), + 'display_name': 'volume-1', 'display_description': 'test volume', 'volume_type_id': None, 'consistencygroup_id': None } test_legacy_volume = { - 'name': 'vol1', + 'name': 'volume-1', 'size': 1, - 'volume_name': 'vol1', + 'volume_name': 'volume-1', 'id': '1', 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", 'project_id': 'project', 'provider_location': 'system^FNM11111|type^lun|id^1', - 'display_name': 'vol1', + 'display_name': 'volume-1', 'display_description': 'test volume', 'volume_type_id': None, 'consistencygroup_id': None } test_volume_clone_cg = { - 'name': 'vol1', + 'name': 'volume-1', 'size': 1, - 'volume_name': 'vol1', + 'volume_name': 'volume-1', 'id': '1', 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", 'project_id': 'project', - 'display_name': 'vol1', + 'display_name': 'volume-1', 'display_description': 'test volume', 'volume_type_id': None, 'consistencygroup_id': None, - 'provider_location': 'system^FNM11111|type^lun|id^1', + 'provider_location': build_provider_location(1, 'lun', base_lun_name), } test_volume_cg = { - 'name': 'vol1', + 'name': 'volume-1', 'size': 1, - 'volume_name': 'vol1', + 'volume_name': 'volume-1', 'id': '1', 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", 'project_id': 'project', - 'display_name': 'vol1', + 'display_name': 'volume-1', 'display_description': 'test volume', 'volume_type_id': None, - 'consistencygroup_id': 'cg_id' + 'consistencygroup_id': 'cg_id', + 'provider_location': build_provider_location(1, 'lun', base_lun_name), } test_volume_rw = { - 'name': 'vol1', + 'name': 'volume-1', 'size': 1, - 'volume_name': 'vol1', + 'volume_name': 'volume-1', 'id': '1', 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", 'project_id': 'project', - 'display_name': 'vol1', + 'display_name': 'volume-1', 'display_description': 'test volume', 'volume_type_id': None, 'consistencygroup_id': None, - 'provider_location': 'system^FNM11111|type^lun|id^1|version^05.03.00', + 'provider_location': build_provider_location(1, 'lun', base_lun_name), } test_volume2 = { - 'name': 'vol2', + 'name': 'volume-2', 'size': 1, - 'volume_name': 'vol2', - 'id': '1', + 'volume_name': 'volume-2', + 'id': '2', 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", 'project_id': 'project', - 'display_name': 'vol2', + 'display_name': 'volume-2', 'consistencygroup_id': None, 'display_description': 'test volume', 'volume_type_id': None, - 'provider_location': 'system^FNM11111|type^lun|id^1|version^05.03.00', - 'metadata': {'key': 'lun_type', 'value': 'lun'}} + 'provider_location': build_provider_location(1, 'lun', 'volume-2')} volume_in_cg = { - 'name': 'vol2', + 'name': 'volume-2', 'size': 1, - 'volume_name': 'vol2', - 'id': '1', + 'volume_name': 'volume-2', + 'id': '2', 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", 'project_id': 'project', - 'display_name': 'vol1_in_cg', - 'provider_location': 'system^FNM11111|type^lun|id^1', + 'display_name': 'volume-1_in_cg', 'consistencygroup_id': 'consistencygroup_id', 'display_description': 'test volume', + 'provider_location': build_provider_location(1, 'lun', 'volume-2'), 'volume_type_id': None} volume2_in_cg = { - 'name': 'vol2', + 'name': 'volume-3', 'size': 1, - 'volume_name': 'vol2', + 'volume_name': 'volume-3', 'id': '3', 'provider_auth': None, 'project_id': 'project', - 'display_name': 'vol2_in_cg', - 'provider_location': 'system^FNM11111|type^lun|id^3', + 'display_name': 'volume-3_in_cg', + 'provider_location': build_provider_location(3, 'lun', 'volume-3'), 'consistencygroup_id': 'consistencygroup_id', 'display_description': 'test volume', 'volume_type_id': None} test_volume_with_type = { - 'name': 'vol_with_type', + 'name': 'volume-1', 'size': 1, - 'volume_name': 'vol_with_type', - 'id': '1', + 'volume_name': 'volume-1', + 'id': 1, 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", 'project_id': 'project', @@ -171,12 +185,13 @@ class EMCVNXCLIDriverTestData(object): 'consistencygroup_id': None, 'display_description': 'vol with type', 'volume_type_id': 'abc1-2320-9013-8813-8941-1374-8112-1231', - 'provider_location': 'system^FNM11111|type^lun|id^1'} + 'provider_location': build_provider_location(1, 'smp', 'volume-1'), + 'volume_metadata': [{'key': 'snapcopy', 'value': 'True'}]} test_failed_volume = { - 'name': 'failed_vol1', + 'name': 'volume-4', 'size': 1, - 'volume_name': 'failed_vol1', + 'volume_name': 'volume-4', 'id': '4', 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", @@ -187,9 +202,9 @@ class EMCVNXCLIDriverTestData(object): 'volume_type_id': None} test_volume1_in_sg = { - 'name': 'vol1_in_sg', + 'name': 'volume-4', 'size': 1, - 'volume_name': 'vol1_in_sg', + 'volume_name': 'volume-4', 'id': '4', 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", @@ -197,12 +212,13 @@ class EMCVNXCLIDriverTestData(object): 'display_name': 'failed_vol', 'display_description': 'Volume 1 in SG', 'volume_type_id': None, - 'provider_location': 'system^fakesn|type^lun|id^4|version^05.03.00'} + 'provider_location': + build_provider_location(4, 'lun', 'volume-4', 'fakesn')} test_volume2_in_sg = { - 'name': 'vol2_in_sg', + 'name': 'volume-5', 'size': 1, - 'volume_name': 'vol2_in_sg', + 'volume_name': 'volume-5', 'id': '5', 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", @@ -210,62 +226,63 @@ class EMCVNXCLIDriverTestData(object): 'display_name': 'failed_vol', 'display_description': 'Volume 2 in SG', 'volume_type_id': None, - 'provider_location': 'system^fakesn|type^lun|id^3|version^05.03.00'} + 'provider_location': + build_provider_location(3, 'lun', 'volume-5', 'fakesn')} test_snapshot = { - 'name': 'snapshot1', + 'name': 'snapshot-4444', 'size': 1, 'id': '4444', - 'volume_name': 'vol1', + 'volume_name': test_volume['name'], 'volume': test_volume, 'volume_size': 1, 'consistencygroup_id': None, 'cgsnapshot_id': None, 'project_id': 'project'} - test_failed_snapshot = { - 'name': 'failed_snapshot', + + test_snapshot1 = { + 'name': 'snapshot-5555', 'size': 1, 'id': '5555', - 'volume_name': 'vol-vol1', + 'volume_name': test_volume['name'], 'volume': test_volume, 'volume_size': 1, 'project_id': 'project'} + test_clone = { - 'name': 'clone1', + 'name': 'volume-2', 'size': 1, 'id': '2', - 'volume_name': 'vol1', + 'volume_name': 'volume-2', 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", 'project_id': 'project', - 'display_name': 'clone1', + 'display_name': 'volume-2', 'consistencygroup_id': None, 'display_description': 'volume created from snapshot', 'volume_type_id': '19fdd0dd-03b3-4d7c-b541-f4df46f308c8', - 'provider_location': 'system^fakesn|type^lun|id^2|version^05.03.00'} + 'provider_location': None, + 'volume_metadata': [{'key': 'snapcopy', 'value': 'True'}]} + test_clone_cg = { - 'name': 'clone1', + 'name': 'volume-2', 'size': 1, 'id': '2', - 'volume_name': 'vol1', + 'volume_name': 'volume-2', 'provider_auth': None, 'host': "host@backendsec#unit_test_pool", 'project_id': 'project', - 'display_name': 'clone1', + 'display_name': 'volume-2', 'consistencygroup_id': 'consistencygroup_id', 'display_description': 'volume created from snapshot', 'volume_type_id': None, - 'provider_location': 'system^fakesn|type^lun|id^2|version^05.03.00'} - connector = { - 'ip': '10.0.0.2', - 'initiator': 'iqn.1993-08.org.debian:01:222', - 'wwpns': ["1234567890123456", "1234567890543216"], - 'wwnns': ["2234567890123456", "2234567890543216"], - 'host': 'fakehost'} + 'provider_location': + build_provider_location(2, 'lun', 'volume-2', 'fakesn')} + test_volume3 = { 'migration_status': None, 'availability_zone': 'nova', - 'id': '1181d1b2-cea3-4f55-8fa8-3360d026ce24', - 'name': 'vol3', + 'id': '3', + 'name': 'volume-3', 'size': 2, 'status': 'available', 'volume_type_id': @@ -278,34 +295,18 @@ class EMCVNXCLIDriverTestData(object): 'volume_type': [], 'volume_attachment': [], 'provider_location': - 'system^FNM11111|type^lun|id^1|version^05.03.00', + build_provider_location(1, 'lun', 'volume-3'), '_name_id': None, 'metadata': {}} - test_new_type = {'name': 'voltype0', 'qos_specs_id': None, - 'deleted': False, - 'extra_specs': {'storagetype:provisioning': 'thin'}, - 'id': 'f82f28c8-148b-416e-b1ae-32d3c02556c0'} - - test_diff = {'encryption': {}, 'qos_specs': {}, - 'extra_specs': - {'storagetype:provisioning': ('thick', 'thin')}} - - test_host = {'host': 'ubuntu-server12@pool_backend_1#POOL_SAS1', - 'capabilities': - {'pool_name': 'POOL_SAS1', - 'location_info': 'POOL_SAS1|FNM00124500890', - 'volume_backend_name': 'pool_backend_1', - 'storage_protocol': 'iSCSI'}} - test_volume4 = {'migration_status': None, 'availability_zone': 'nova', - 'id': '1181d1b2-cea3-4f55-8fa8-3360d026ce24', - 'name': 'vol4', + 'id': '4', + 'name': 'volume-4', 'size': 2, 'status': 'available', 'volume_type_id': '19fdd0dd-03b3-4d7c-b541-f4df46f308c8', 'deleted': False, 'provider_location': - 'system^FNM11111|type^lun|id^4', + build_provider_location(4, 'lun', 'volume-4'), 'host': 'ubuntu-server12@array_backend_1', 'source_volid': None, 'provider_auth': None, 'display_name': 'vol-test02', @@ -315,15 +316,15 @@ class EMCVNXCLIDriverTestData(object): '_name_id': None, 'metadata': {}} test_volume5 = {'migration_status': None, 'availability_zone': 'nova', - 'id': '1181d1b2-cea3-4f55-8fa8-3360d026ce25', + 'id': '5', 'name_id': '1181d1b2-cea3-4f55-8fa8-3360d026ce25', - 'name': 'vol5', + 'name': 'volume-5', 'size': 1, 'status': 'available', 'volume_type_id': '19fdd0dd-03b3-4d7c-b541-f4df46f308c8', 'deleted': False, 'provider_location': - 'system^FNM11111|type^lun|id^5|version^05.02.00', + build_provider_location(5, 'lun', 'volume-5'), 'host': 'ubuntu-server12@array_backend_1#unit_test_pool', 'source_volid': None, 'provider_auth': None, 'display_name': 'vol-test05', @@ -332,6 +333,29 @@ class EMCVNXCLIDriverTestData(object): 'volume_type': [], '_name_id': None, 'metadata': {}} + test_new_type = {'name': 'voltype0', 'qos_specs_id': None, + 'deleted': False, + 'extra_specs': {'storagetype:provisioning': 'thin'}, + 'id': 'f82f28c8-148b-416e-b1ae-32d3c02556c0'} + + test_diff = {'encryption': {}, 'qos_specs': {}, + 'extra_specs': + {'storagetype:provisioning': ('thick', 'thin')}} + + test_host = {'host': 'ubuntu-server12@pool_backend_1#POOL_SAS1', + 'capabilities': + {'pool_name': 'POOL_SAS1', + 'location_info': 'POOL_SAS1|FNM00124500890', + 'volume_backend_name': 'pool_backend_1', + 'storage_protocol': 'iSCSI'}} + + connector = { + 'ip': '10.0.0.2', + 'initiator': 'iqn.1993-08.org.debian:01:222', + 'wwpns': ["1234567890123456", "1234567890543216"], + 'wwnns': ["2234567890123456", "2234567890543216"], + 'host': 'fakehost'} + test_new_type2 = {'name': 'voltype0', 'qos_specs_id': None, 'deleted': False, 'extra_specs': {'storagetype:pool': 'POOL_SAS2'}, @@ -364,11 +388,23 @@ class EMCVNXCLIDriverTestData(object): 'status': 'available'} test_member_cgsnapshot = { - 'name': 'snapshot1', + 'name': 'snapshot-1111', 'size': 1, - 'id': 'cgsnapshot_id', + 'id': '1111', 'volume': test_volume, - 'volume_name': 'vol1', + 'volume_name': 'volume-1', + 'volume_size': 1, + 'consistencygroup_id': 'consistencygroup_id', + 'cgsnapshot_id': 'cgsnapshot_id', + 'project_id': 'project' + } + + test_member_cgsnapshot2 = { + 'name': 'snapshot-2222', + 'size': 1, + 'id': '2222', + 'volume': test_volume2, + 'volume_name': 'volume-2', 'volume_size': 1, 'consistencygroup_id': 'consistencygroup_id', 'cgsnapshot_id': 'cgsnapshot_id', @@ -377,7 +413,7 @@ class EMCVNXCLIDriverTestData(object): test_lun_id = 1 test_existing_ref = {'source-id': test_lun_id} - test_existing_ref_source_name = {'source-name': 'vol1'} + test_existing_ref_source_name = {'source-name': 'volume-1'} test_pool_name = 'unit_test_pool' device_map = { '1122334455667788': { @@ -548,11 +584,11 @@ class EMCVNXCLIDriverTestData(object): Attached Snapshot: N/A """ - def SNAP_MP_CREATE_CMD(self, name='vol1', source='vol1'): + def SNAP_MP_CREATE_CMD(self, name='volume-1', source='volume-1'): return ('lun', '-create', '-type', 'snap', '-primaryLunName', source, '-name', name) - def SNAP_ATTACH_CMD(self, name='vol1', snapName='snapshot1'): + def SNAP_ATTACH_CMD(self, name='volume-1', snapName='snapshot-4444'): return ('lun', '-attach', '-name', name, '-snapName', snapName) def SNAP_DELETE_CMD(self, name): @@ -568,7 +604,7 @@ class EMCVNXCLIDriverTestData(object): '-allowAutoDelete', 'yes') def SNAP_LIST_CMD(self, res_id=1): - cmd = ('snap', '-list', '-res', res_id) + cmd = ('snap', '-list', '-res', int(res_id)) return cmd def LUN_DELETE_CMD(self, name): @@ -587,13 +623,13 @@ class EMCVNXCLIDriverTestData(object): '-attachedSnapshot') @staticmethod - def LUN_RENAME_CMD(lun_id): - return ('lun', '-modify', '-l', lun_id, - '-newName', 'vol_with_type', '-o') + def LUN_RENAME_CMD(lun_id, lun_name): + return ('lun', '-modify', '-l', int(lun_id), + '-newName', lun_name, '-o') @staticmethod def LUN_LIST_ALL_CMD(lun_id): - return ('lun', '-list', '-l', lun_id, + return ('lun', '-list', '-l', int(lun_id), '-attachedSnapshot', '-userCap', '-dedupState', '-initialTier', '-isCompressed', '-isThinLUN', @@ -602,7 +638,7 @@ class EMCVNXCLIDriverTestData(object): @staticmethod def LUN_LIST_SPECS_CMD(lun_id): - return ('lun', '-list', '-l', lun_id, + return ('lun', '-list', '-l', int(lun_id), '-poolName', '-isThinLUN', '-isCompressed', '-dedupState', '-initialTier', '-tieringPolicy') @@ -1310,6 +1346,22 @@ IP Address: 192.168.4.53 '-sp', sp, '-spport', spport, '-spvport', vport, '-ip', ip, '-host', gname, '-o') + @staticmethod + def convert_snapshot(snapshot, expected_attrs=['volume']): + if expected_attrs: + snapshot = snapshot.copy() + snapshot['volume'] = fake_volume.fake_volume_obj( + None, **snapshot['volume']) + snap = fake_snapshot.fake_snapshot_obj( + None, expected_attrs=expected_attrs, **snapshot) + return snap + + @staticmethod + def convert_volume(volume): + vol = fake_volume.fake_volume_obj( + None, **volume) + return vol + class DriverTestCaseBase(test.TestCase): def setUp(self): @@ -1340,6 +1392,7 @@ class DriverTestCaseBase(test.TestCase): 'volume_backend_name': 'namedbackend'})) self.testData = EMCVNXCLIDriverTestData() + self.navisecclicmd = '/opt/Navisphere/bin/naviseccli ' + \ '-address 10.0.0.1 -user sysadmin -password sysadmin -scope 0 ' self.configuration.iscsi_initiators = '{"fakehost": ["10.0.0.2"]}' @@ -1375,19 +1428,20 @@ class DriverTestCaseBase(test.TestCase): def standard_fake_command_execute(self, *args, **kwargv): standard_commands = [ - self.testData.LUN_PROPERTY_ALL_CMD('vol1'), - self.testData.LUN_PROPERTY_ALL_CMD('vol2'), - self.testData.LUN_PROPERTY_ALL_CMD('vol2_dest'), + self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), + self.testData.LUN_PROPERTY_ALL_CMD('volume-2'), + self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-2')), self.testData.LUN_PROPERTY_ALL_CMD('vol-vol1'), - self.testData.LUN_PROPERTY_ALL_CMD('snapshot1'), + self.testData.LUN_PROPERTY_ALL_CMD('snapshot-4444'), self.testData.POOL_PROPERTY_CMD] standard_results = [ - self.testData.LUN_PROPERTY('vol1'), - self.testData.LUN_PROPERTY('vol2'), - self.testData.LUN_PROPERTY('vol2_dest'), + self.testData.LUN_PROPERTY('volume-1'), + self.testData.LUN_PROPERTY('volume-2'), + self.testData.LUN_PROPERTY(build_migration_dest_name('volume-2')), self.testData.LUN_PROPERTY('vol-vol1'), - self.testData.LUN_PROPERTY('snapshot1'), + self.testData.LUN_PROPERTY('snapshot-4444'), self.testData.POOL_PROPERTY] standard_default = SUCCEED @@ -1429,12 +1483,12 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): self.driver.delete_volume(self.testData.test_volume) expect_cmd = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol1', 1, + 'volume-1', 1, 'unit_test_pool', 'thick', None, poll=False)), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), poll=False), - mock.call(*self.testData.LUN_DELETE_CMD('vol1'))] + mock.call(*self.testData.LUN_DELETE_CMD('volume-1'))] fake_cli.assert_has_calls(expect_cmd) @@ -1447,11 +1501,11 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): self.driver.create_volume(self.testData.test_volume) expect_cmd = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol1', 1, + 'volume-1', 1, 'unit_test_pool', 'thick', None, ignore_thresholds=True, poll=False)), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), poll=False)] fake_cli.assert_has_calls(expect_cmd) @@ -1464,11 +1518,11 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): "get_volume_type_extra_specs", mock.Mock(return_value={'storagetype:provisioning': 'compressed'})) def test_create_volume_compressed(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), - self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), + self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), self.testData.NDU_LIST_CMD] - results = [self.testData.LUN_PROPERTY('vol_with_type', True), - self.testData.LUN_PROPERTY('vol_with_type', True), + results = [self.testData.LUN_PROPERTY('volume-1', True), + self.testData.LUN_PROPERTY('volume-1', True), self.testData.NDU_LIST_RESULT] fake_cli = self.driverSetup(commands, results) self.driver.cli.enablers = ['-Compression', @@ -1480,13 +1534,13 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): # verification expect_cmd = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol_with_type', 1, + 'volume-1', 1, 'unit_test_pool', 'compressed', None, poll=False)), mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( - 'vol_with_type'), poll=False), + 'volume-1'), poll=False), mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( - 'vol_with_type'), poll=True), + 'volume-1'), poll=True), mock.call(*self.testData.ENABLE_COMPRESSION_CMD( 1))] fake_cli.assert_has_calls(expect_cmd) @@ -1500,9 +1554,9 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): mock.Mock(return_value={'provisioning:type': 'thin', 'storagetype:provisioning': 'thick'})) def test_create_volume_thin(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), self.testData.NDU_LIST_CMD] - results = [self.testData.LUN_PROPERTY('vol_with_type', True), + results = [self.testData.LUN_PROPERTY('volume-1', True), self.testData.NDU_LIST_RESULT] fake_cli = self.driverSetup(commands, results) self.driver.cli.enablers = ['-Compression', @@ -1514,11 +1568,11 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): # verification expect_cmd = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol_with_type', 1, + 'volume-1', 1, 'unit_test_pool', 'thin', None, poll=False)), mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( - 'vol_with_type'), poll=False)] + 'volume-1'), poll=False)] fake_cli.assert_has_calls(expect_cmd) @mock.patch( @@ -1529,9 +1583,9 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): "get_volume_type_extra_specs", mock.Mock(return_value={'provisioning:type': 'thick'})) def test_create_volume_thick(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), self.testData.NDU_LIST_CMD] - results = [self.testData.LUN_PROPERTY('vol_with_type', False), + results = [self.testData.LUN_PROPERTY('volume-1', False), self.testData.NDU_LIST_RESULT] fake_cli = self.driverSetup(commands, results) self.driver.cli.enablers = ['-Compression', @@ -1543,11 +1597,11 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): # verification expect_cmd = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol_with_type', 1, + 'volume-1', 1, 'unit_test_pool', 'thick', None, poll=False)), mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( - 'vol_with_type'), poll=False)] + 'volume-1'), poll=False)] fake_cli.assert_has_calls(expect_cmd) @mock.patch( @@ -1559,11 +1613,11 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): mock.Mock(return_value={'storagetype:provisioning': 'compressed', 'storagetype:tiering': 'HighestAvailable'})) def test_create_volume_compressed_tiering_highestavailable(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), - self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), + self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), self.testData.NDU_LIST_CMD] - results = [self.testData.LUN_PROPERTY('vol_with_type', True), - self.testData.LUN_PROPERTY('vol_with_type', True), + results = [self.testData.LUN_PROPERTY('volume-1', True), + self.testData.LUN_PROPERTY('volume-1', True), self.testData.NDU_LIST_RESULT] fake_cli = self.driverSetup(commands, results) self.driver.cli.enablers = ['-Compression', @@ -1576,13 +1630,13 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): # verification expect_cmd = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol_with_type', 1, + 'volume-1', 1, 'unit_test_pool', 'compressed', 'highestavailable', poll=False)), mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( - 'vol_with_type'), poll=False), + 'volume-1'), poll=False), mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( - 'vol_with_type'), poll=True), + 'volume-1'), poll=True), mock.call(*self.testData.ENABLE_COMPRESSION_CMD( 1))] fake_cli.assert_has_calls(expect_cmd) @@ -1595,11 +1649,11 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): "get_volume_type_extra_specs", mock.Mock(return_value={'storagetype:provisioning': 'deduplicated'})) def test_create_volume_deduplicated(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), - self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), + self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), self.testData.NDU_LIST_CMD] - results = [self.testData.LUN_PROPERTY('vol_with_type', True), - self.testData.LUN_PROPERTY('vol_with_type', True), + results = [self.testData.LUN_PROPERTY('volume-1', True), + self.testData.LUN_PROPERTY('volume-1', True), self.testData.NDU_LIST_RESULT] fake_cli = self.driverSetup(commands, results) self.driver.cli.enablers = ['-Compression', @@ -1612,7 +1666,7 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): # verification expect_cmd = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol_with_type', 1, + 'volume-1', 1, 'unit_test_pool', 'deduplicated', None, poll=False))] fake_cli.assert_has_calls(expect_cmd) @@ -1625,11 +1679,11 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): "get_volume_type_extra_specs", mock.Mock(return_value={'storagetype:tiering': 'Auto'})) def test_create_volume_tiering_auto(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), - self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), + self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), self.testData.NDU_LIST_CMD] - results = [self.testData.LUN_PROPERTY('vol_with_type', True), - self.testData.LUN_PROPERTY('vol_with_type', True), + results = [self.testData.LUN_PROPERTY('volume-1', True), + self.testData.LUN_PROPERTY('volume-1', True), self.testData.NDU_LIST_RESULT] fake_cli = self.driverSetup(commands, results) self.driver.cli.enablers = ['-Compression', @@ -1642,7 +1696,7 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): # verification expect_cmd = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol_with_type', 1, + 'volume-1', 1, 'unit_test_pool', None, 'auto', poll=False))] fake_cli.assert_has_calls(expect_cmd) @@ -1653,9 +1707,9 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): mock.Mock(return_value={'storagetype:tiering': 'Auto', 'storagetype:provisioning': 'Deduplicated'})) def test_create_volume_deduplicated_tiering_auto(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), self.testData.NDU_LIST_CMD] - results = [self.testData.LUN_PROPERTY('vol_with_type', True), + results = [self.testData.LUN_PROPERTY('volume-1', True), self.testData.NDU_LIST_RESULT] self.driverSetup(commands, results) ex = self.assertRaises( @@ -1671,9 +1725,9 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): "get_volume_type_extra_specs", mock.Mock(return_value={'storagetype:provisioning': 'Compressed'})) def test_create_volume_compressed_no_enabler(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), self.testData.NDU_LIST_CMD] - results = [self.testData.LUN_PROPERTY('vol_with_type', True), + results = [self.testData.LUN_PROPERTY('volume-1', True), ('No package', 0)] self.driverSetup(commands, results) ex = self.assertRaises( @@ -1684,19 +1738,6 @@ class EMCVNXCLIDriverISCSITestCase(DriverTestCaseBase): re.match(r".*Compression Enabler is not installed", ex.msg)) - @mock.patch( - "cinder.volume.volume_types." - "get_volume_type_extra_specs", - mock.Mock(return_value={'copytype:snap': 'true'})) - def test_create_volume_snapcopy_in_cg(self): - self.driverSetup() - vol = self.testData.test_volume_with_type.copy() - vol['consistencygroup_id'] = '7450764f-9d24-4c70-ad46-7cd90acd4292' - self.assertRaises( - exception.VolumeBackendAPIException, - self.driver.create_volume, - vol) - def test_get_volume_stats(self): commands = [self.testData.NDU_LIST_CMD, self.testData.POOL_GET_ALL_CMD(True)] @@ -2004,8 +2045,7 @@ Time Remaining: 0 second(s) @mock.patch( "cinder.volume.volume_types." "get_volume_type_extra_specs", - mock.Mock(return_value={'storagetype:tiering': 'Auto', - 'copytype:snap': 'true'})) + mock.Mock(return_value={'storagetype:tiering': 'Auto'})) def test_volume_migration_smp(self): commands = [self.testData.MIGRATION_CMD(), @@ -2029,9 +2069,11 @@ Time Remaining: 0 second(s) "unit_test_pool2|fakeSerial", 'storage_protocol': 'iSCSI'}} - vol = self.testData.test_volume.copy() + vol = EMCVNXCLIDriverTestData.convert_volume( + self.testData.test_volume) vol['provider_location'] = 'system^FNM11111|type^smp|id^1' - tmp_snap = "snap-as-vol-%s" % vol['id'] + vol['volume_metadata'] = [{'key': 'snapcopy', 'value': 'True'}] + tmp_snap = "tmp-snap-%s" % vol['id'] ret = self.driver.migrate_volume(None, vol, fake_host) @@ -2057,9 +2099,11 @@ Time Remaining: 0 second(s) self.driver.delete_snapshot(self.testData.test_snapshot) # verification - expect_cmd = [mock.call(*self.testData.SNAP_CREATE_CMD('snapshot1'), + expect_cmd = [mock.call(*self.testData.SNAP_CREATE_CMD( + 'snapshot-4444'), poll=False), - mock.call(*self.testData.SNAP_DELETE_CMD('snapshot1'), + mock.call(*self.testData.SNAP_DELETE_CMD( + 'snapshot-4444'), poll=True)] fake_cli.assert_has_calls(expect_cmd) @@ -2067,28 +2111,28 @@ Time Remaining: 0 second(s) @mock.patch('oslo_service.loopingcall.FixedIntervalLoopingCall', new=utils.ZeroIntervalLoopingCall) def test_snapshot_preparing_volume(self): - commands = [self.testData.SNAP_CREATE_CMD('snapshot1'), - self.testData.LUN_PROPERTY_ALL_CMD('vol1')] + commands = [self.testData.SNAP_CREATE_CMD('snapshot-4444'), + self.testData.LUN_PROPERTY_ALL_CMD('volume-1')] results = [[self.testData.LUN_PREP_ERROR(), SUCCEED], - [self.testData.LUN_PROPERTY('vol1', size=1, + [self.testData.LUN_PROPERTY('volume-1', size=1, operation='Preparing'), - self.testData.LUN_PROPERTY('vol1', size=1, + self.testData.LUN_PROPERTY('volume-1', size=1, operation='Optimizing'), - self.testData.LUN_PROPERTY('vol1', size=1, + self.testData.LUN_PROPERTY('volume-1', size=1, operation='None')]] fake_cli = self.driverSetup(commands, results) self.driver.create_snapshot(self.testData.test_snapshot) - expected = [mock.call(*self.testData.SNAP_CREATE_CMD('snapshot1'), + expected = [mock.call(*self.testData.SNAP_CREATE_CMD('snapshot-4444'), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), poll=True), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), poll=False), - mock.call(*self.testData.SNAP_CREATE_CMD('snapshot1'), + mock.call(*self.testData.SNAP_CREATE_CMD('snapshot-4444'), poll=False)] fake_cli.assert_has_calls(expected) @@ -2467,7 +2511,7 @@ Time Remaining: 0 second(s) def test_create_volume_cli_failed(self): commands = [self.testData.LUN_CREATION_CMD( - 'failed_vol1', 1, 'unit_test_pool', None, None, poll=False)] + 'volume-4', 1, 'unit_test_pool', None, None, poll=False)] results = [FAKE_ERROR_RETURN] fake_cli = self.driverSetup(commands, results) @@ -2475,7 +2519,7 @@ Time Remaining: 0 second(s) self.driver.create_volume, self.testData.test_failed_volume) expect_cmd = [mock.call(*self.testData.LUN_CREATION_CMD( - 'failed_vol1', 1, 'unit_test_pool', None, None, poll=False))] + 'volume-4', 1, 'unit_test_pool', None, None, poll=False))] fake_cli.assert_has_calls(expect_cmd) @mock.patch('oslo_service.loopingcall.FixedIntervalLoopingCall', @@ -2530,27 +2574,34 @@ Time Remaining: 0 second(s) offline_volume) def test_create_volume_snapshot_failed(self): - commands = [self.testData.SNAP_CREATE_CMD('failed_snapshot')] + test_snapshot = EMCVNXCLIDriverTestData.convert_snapshot( + self.testData.test_snapshot1) + commands = [self.testData.SNAP_CREATE_CMD(test_snapshot.name)] results = [FAKE_ERROR_RETURN] fake_cli = self.driverSetup(commands, results) - # case self.assertRaises(exception.EMCVnxCLICmdError, self.driver.create_snapshot, - self.testData.test_failed_snapshot) + test_snapshot) # verification expect_cmd = [ mock.call( - *self.testData.SNAP_CREATE_CMD('failed_snapshot'), + *self.testData.SNAP_CREATE_CMD(test_snapshot.name), poll=False)] fake_cli.assert_has_calls(expect_cmd) def test_create_volume_from_snapshot(self): - # set up - cmd_dest = self.testData.LUN_PROPERTY_ALL_CMD("vol2_dest") - cmd_dest_np = self.testData.LUN_PROPERTY_ALL_CMD("vol2_dest") - output_dest = self.testData.LUN_PROPERTY("vol2_dest") + test_snapshot = EMCVNXCLIDriverTestData.convert_snapshot( + self.testData.test_snapshot) + test_volume = EMCVNXCLIDriverTestData.convert_volume( + self.testData.test_volume2) + cmd_dest = self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name(test_volume.name)) + cmd_dest_np = self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name(test_volume.name)) + output_dest = self.testData.LUN_PROPERTY( + build_migration_dest_name(test_volume.name)) cmd_migrate = self.testData.MIGRATION_CMD(1, 1) output_migrate = ("", 0) cmd_migrate_verify = self.testData.MIGRATION_VERIFY_CMD(1) @@ -2561,24 +2612,25 @@ Time Remaining: 0 second(s) results = [output_dest, output_dest, output_migrate, output_migrate_verify] fake_cli1 = self.driverSetup(commands, results) - - self.driver.create_volume_from_snapshot(self.testData.test_volume2, - self.testData.test_snapshot) + self.driver.create_volume_from_snapshot(test_volume, + test_snapshot) expect_cmd1 = [ - mock.call( - *self.testData.SNAP_MP_CREATE_CMD( - name='vol2', source='vol1'), - poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol2'), + mock.call(*self.testData.SNAP_MP_CREATE_CMD( + name=test_volume.name, source=test_snapshot.volume_name), + poll=False), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD(test_volume.name), poll=True), mock.call( *self.testData.SNAP_ATTACH_CMD( - name='vol2', snapName='snapshot1')), + name=test_volume.name, snapName=test_snapshot.name)), mock.call(*self.testData.LUN_CREATION_CMD( - 'vol2_dest', 1, 'unit_test_pool', None, None)), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol2_dest'), + build_migration_dest_name(test_volume.name), + 1, 'unit_test_pool', None, None)), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name(test_volume.name)), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol2_dest'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name(test_volume.name)), poll=False), mock.call(*self.testData.MIGRATION_CMD(1, 1), retry_disable=True, @@ -2589,53 +2641,62 @@ Time Remaining: 0 second(s) self.configuration.ignore_pool_full_threshold = True fake_cli2 = self.driverSetup(commands, results) - self.driver.create_volume_from_snapshot(self.testData.test_volume2, - self.testData.test_snapshot) + self.driver.create_volume_from_snapshot(test_volume, + test_snapshot) expect_cmd2 = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol2_dest', 1, 'unit_test_pool', None, None, + build_migration_dest_name(test_volume.name), 1, + 'unit_test_pool', None, None, ignore_thresholds=True))] fake_cli2.assert_has_calls(expect_cmd2) @mock.patch( "cinder.volume.volume_types." "get_volume_type_extra_specs", - mock.Mock(return_value={'copytype:snap': 'true'})) + mock.Mock(return_value={'provisioning:type': 'thick'})) def test_create_volume_from_snapshot_smp(self): fake_cli = self.driverSetup() - vol = self.driver.create_volume_from_snapshot( - self.testData.test_volume_with_type, + test_snap = EMCVNXCLIDriverTestData.convert_snapshot( self.testData.test_snapshot) - self.assertIn('type^smp', vol['provider_location']) + new_volume = self.testData.test_volume_with_type.copy() + new_volume['name_id'] = new_volume['id'] + vol = self.driver.create_volume_from_snapshot( + new_volume, test_snap) + self.assertTrue( + vol['provider_location'].find('type^smp') > 0) expect_cmd = [ mock.call( *self.testData.SNAP_COPY_CMD( - src_snap='snapshot1', - snap_name='snap-as-vol-%s' % '1')), + src_snap=test_snap.name, + snap_name='snap-as-vol-%s' % test_snap.volume.id)), mock.call( *self.testData.SNAP_MODIFY_CMD( - name='snap-as-vol-%s' % '1', + name='snap-as-vol-%s' % test_snap.volume.id, rw='yes')), mock.call( *self.testData.SNAP_MP_CREATE_CMD( - name='vol_with_type', source='vol1'), + name=new_volume['name'], source=test_snap.volume_name), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD(new_volume['name']), poll=True), mock.call( *self.testData.SNAP_ATTACH_CMD( - name='vol_with_type', snapName='snap-as-vol-%s' % '1'))] + name=new_volume['name'], + snapName='snap-as-vol-%s' % test_snap.volume.id))] fake_cli.assert_has_calls(expect_cmd) @mock.patch('oslo_service.loopingcall.FixedIntervalLoopingCall', new=utils.ZeroIntervalLoopingCall) def test_create_volume_from_snapshot_sync_failed(self): - cmd_dest = self.testData.LUN_PROPERTY_ALL_CMD("vol2_dest") - cmd_dest_np = self.testData.LUN_PROPERTY_ALL_CMD("vol2_dest") - output_dest = self.testData.LUN_PROPERTY("vol2_dest") + cmd_dest = self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('vol2')) + cmd_dest_np = self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('vol2')) + output_dest = self.testData.LUN_PROPERTY( + build_migration_dest_name('vol2')) cmd_migrate = self.testData.MIGRATION_CMD(1, 1) - cmd_detach_lun = ('lun', '-detach', '-name', 'vol2', '-o') + cmd_detach_lun = ('lun', '-detach', '-name', 'volume-2', '-o') output_migrate = ("", 0) cmd_migrate_verify = self.testData.MIGRATION_VERIFY_CMD(1) output_migrate_verify = (r'The specified source LUN ' @@ -2650,26 +2711,31 @@ Time Remaining: 0 second(s) output_migrate_cancel] fake_cli = self.driverSetup(commands, results) - + new_volume = EMCVNXCLIDriverTestData.convert_volume( + self.testData.test_volume2) + src_snapshot = EMCVNXCLIDriverTestData.convert_snapshot( + self.testData.test_snapshot) self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_volume_from_snapshot, - self.testData.test_volume2, - self.testData.test_snapshot) + new_volume, src_snapshot) + expect_cmd = [ mock.call( *self.testData.SNAP_MP_CREATE_CMD( - name='vol2', source='vol1'), + name='volume-2', source='volume-1'), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol2'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-2'), poll=True), mock.call( *self.testData.SNAP_ATTACH_CMD( - name='vol2', snapName='snapshot1')), + name='volume-2', snapName=src_snapshot.name)), mock.call(*self.testData.LUN_CREATION_CMD( - 'vol2_dest', 1, 'unit_test_pool', None, None)), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol2_dest'), - poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol2_dest'), + build_migration_dest_name('volume-2'), 1, + 'unit_test_pool', None, None)), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-2')), poll=False), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-2')), poll=False), mock.call(*self.testData.MIGRATION_CMD(1, 1), retry_disable=True, @@ -2679,52 +2745,63 @@ Time Remaining: 0 second(s) mock.call(*self.testData.MIGRATION_CANCEL_CMD(1)), mock.call(*self.testData.MIGRATION_VERIFY_CMD(1), poll=False), - mock.call(*self.testData.LUN_DELETE_CMD('vol2_dest')), + mock.call(*self.testData.LUN_DELETE_CMD( + build_migration_dest_name('volume-2'))), mock.call(*cmd_detach_lun), - mock.call(*self.testData.LUN_DELETE_CMD('vol2'))] + mock.call(*self.testData.LUN_DELETE_CMD('volume-2'))] fake_cli.assert_has_calls(expect_cmd) def test_create_vol_from_snap_failed_in_migrate_lun(self): - cmd_dest = self.testData.LUN_PROPERTY_ALL_CMD("vol2_dest") - output_dest = self.testData.LUN_PROPERTY("vol2_dest") + cmd_dest = self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('vol2')) + output_dest = self.testData.LUN_PROPERTY( + build_migration_dest_name('vol2')) cmd_migrate = self.testData.MIGRATION_CMD(1, 1) - cmd_detach_lun = ('lun', '-detach', '-name', 'vol2', '-o') + cmd_detach_lun = ('lun', '-detach', '-name', 'volume-2', '-o') commands = [cmd_dest, cmd_migrate] results = [output_dest, FAKE_ERROR_RETURN] fake_cli = self.driverSetup(commands, results) + test_snapshot = EMCVNXCLIDriverTestData.convert_snapshot( + self.testData.test_snapshot) self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_volume_from_snapshot, self.testData.test_volume2, - self.testData.test_snapshot) + test_snapshot) expect_cmd = [ - mock.call( - *self.testData.SNAP_MP_CREATE_CMD( - name='vol2', source='vol1'), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol2'), poll=True), - mock.call( - *self.testData.SNAP_ATTACH_CMD( - name='vol2', snapName='snapshot1')), + mock.call(*self.testData.SNAP_MP_CREATE_CMD( + name='volume-2', source='volume-1'), poll=False), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-2'), + poll=True), + mock.call(*self.testData.SNAP_ATTACH_CMD( + name='volume-2', snapName=test_snapshot.name)), mock.call(*self.testData.LUN_CREATION_CMD( - 'vol2_dest', 1, 'unit_test_pool', None, None)), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol2_dest'), + build_migration_dest_name('volume-2'), 1, + 'unit_test_pool', None, None)), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-2')), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol2_dest'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-2')), poll=False), mock.call(*self.testData.MIGRATION_CMD(1, 1), poll=True, retry_disable=True), - mock.call(*self.testData.LUN_DELETE_CMD('vol2_dest')), + mock.call(*self.testData.LUN_DELETE_CMD( + build_migration_dest_name('volume-2'))), mock.call(*cmd_detach_lun), - mock.call(*self.testData.LUN_DELETE_CMD('vol2'))] + mock.call(*self.testData.LUN_DELETE_CMD('volume-2'))] fake_cli.assert_has_calls(expect_cmd) def test_create_cloned_volume(self): - cmd_dest = self.testData.LUN_PROPERTY_ALL_CMD("clone1_dest") - cmd_dest_p = self.testData.LUN_PROPERTY_ALL_CMD("clone1_dest") - output_dest = self.testData.LUN_PROPERTY("clone1_dest") - cmd_clone = self.testData.LUN_PROPERTY_ALL_CMD("clone1") - output_clone = self.testData.LUN_PROPERTY("clone1") + cmd_dest = self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-2')) + cmd_dest_p = self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-2')) + output_dest = self.testData.LUN_PROPERTY( + build_migration_dest_name('volume-2')) + cmd_clone = self.testData.LUN_PROPERTY_ALL_CMD("volume-2") + output_clone = self.testData.LUN_PROPERTY("volume-2") cmd_migrate = self.testData.MIGRATION_CMD(1, 1) output_migrate = ("", 0) cmd_migrate_verify = self.testData.MIGRATION_VERIFY_CMD(1) @@ -2737,27 +2814,28 @@ Time Remaining: 0 second(s) fake_cli = self.driverSetup(commands, results) volume = self.testData.test_volume.copy() - volume['name'] = 'clone1' - + volume['id'] = '2' + volume = EMCVNXCLIDriverTestData.convert_volume(volume) self.driver.create_cloned_volume(volume, self.testData.test_volume) - tmp_snap = 'tmp-snap-' + self.testData.test_volume['id'] + tmp_snap = 'tmp-snap-' + volume.id expect_cmd = [ mock.call( *self.testData.SNAP_CREATE_CMD(tmp_snap), poll=False), mock.call(*self.testData.SNAP_MP_CREATE_CMD( - name='clone1', - source='vol1'), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('clone1'), + name='volume-2', + source='volume-1'), poll=False), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-2'), poll=True), mock.call( *self.testData.SNAP_ATTACH_CMD( - name='clone1', snapName=tmp_snap)), + name='volume-2', snapName=tmp_snap)), mock.call(*self.testData.LUN_CREATION_CMD( - 'clone1_dest', 1, 'unit_test_pool', None, None)), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('clone1_dest'), - poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('clone1_dest'), - poll=False), + build_migration_dest_name('volume-2'), 1, + 'unit_test_pool', None, None)), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-2')), poll=False), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-2')), poll=False), mock.call(*self.testData.MIGRATION_CMD(1, 1), poll=True, retry_disable=True), @@ -2770,11 +2848,13 @@ Time Remaining: 0 second(s) @mock.patch( "cinder.volume.volume_types." "get_volume_type_extra_specs", - mock.Mock(return_value={'copytype:snap': 'true'})) + mock.Mock(return_value={'provisioning:type': 'thick'})) def test_create_cloned_volume_smp(self): fake_cli = self.driverSetup() + test_clone = self.testData.test_clone.copy() + test_clone['name_id'] = test_clone['id'] vol = self.driver.create_cloned_volume( - self.testData.test_clone, + test_clone, self.testData.test_volume_with_type) self.assertIn('type^smp', vol['provider_location']) expect_cmd = [ @@ -2784,29 +2864,29 @@ Time Remaining: 0 second(s) poll=False), mock.call( *self.testData.SNAP_MP_CREATE_CMD( - name='clone1', source='vol_with_type'), + name='volume-2', source='volume-1'), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('clone1'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-2'), poll=True), mock.call( *self.testData.SNAP_ATTACH_CMD( - name='clone1', snapName='snap-as-vol-%s' % '2'))] + name='volume-2', snapName='snap-as-vol-%s' % '2'))] fake_cli.assert_has_calls(expect_cmd) def test_delete_volume_failed(self): - commands = [self.testData.LUN_DELETE_CMD('failed_vol1')] + commands = [self.testData.LUN_DELETE_CMD('volume-4')] results = [FAKE_ERROR_RETURN] fake_cli = self.driverSetup(commands, results) self.assertRaises(exception.EMCVnxCLICmdError, self.driver.delete_volume, self.testData.test_failed_volume) - expected = [mock.call(*self.testData.LUN_DELETE_CMD('failed_vol1'))] + expected = [mock.call(*self.testData.LUN_DELETE_CMD('volume-4'))] fake_cli.assert_has_calls(expected) def test_delete_volume_in_sg_failed(self): - commands = [self.testData.LUN_DELETE_CMD('vol1_in_sg'), - self.testData.LUN_DELETE_CMD('vol2_in_sg')] + commands = [self.testData.LUN_DELETE_CMD('volume-4'), + self.testData.LUN_DELETE_CMD('volume-5')] results = [self.testData.LUN_DELETE_IN_SG_ERROR(), self.testData.LUN_DELETE_IN_SG_ERROR(False)] self.driverSetup(commands, results) @@ -2818,13 +2898,13 @@ Time Remaining: 0 second(s) self.testData.test_volume2_in_sg) def test_delete_volume_in_sg_force(self): - commands = [self.testData.LUN_DELETE_CMD('vol1_in_sg'), + commands = [self.testData.LUN_DELETE_CMD('volume-4'), self.testData.STORAGEGROUP_LIST_CMD(), self.testData.STORAGEGROUP_REMOVEHLU_CMD('fakehost1', '41'), self.testData.STORAGEGROUP_REMOVEHLU_CMD('fakehost1', '42'), - self.testData.LUN_DELETE_CMD('vol2_in_sg'), + self.testData.LUN_DELETE_CMD('volume-5'), self.testData.STORAGEGROUP_REMOVEHLU_CMD('fakehost2', '31'), self.testData.STORAGEGROUP_REMOVEHLU_CMD('fakehost2', @@ -2843,28 +2923,30 @@ Time Remaining: 0 second(s) self.driver.cli.force_delete_lun_in_sg = True self.driver.delete_volume(self.testData.test_volume1_in_sg) self.driver.delete_volume(self.testData.test_volume2_in_sg) - expected = [mock.call(*self.testData.LUN_DELETE_CMD('vol1_in_sg')), + expected = [mock.call(*self.testData.LUN_DELETE_CMD('volume-4')), mock.call(*self.testData.STORAGEGROUP_LIST_CMD(), poll=True), mock.call(*self.testData.STORAGEGROUP_REMOVEHLU_CMD( 'fakehost1', '41'), poll=False), mock.call(*self.testData.STORAGEGROUP_REMOVEHLU_CMD( 'fakehost2', '42'), poll=False), - mock.call(*self.testData.LUN_DELETE_CMD('vol1_in_sg')), - mock.call(*self.testData.LUN_DELETE_CMD('vol2_in_sg')), + mock.call(*self.testData.LUN_DELETE_CMD('volume-4')), + mock.call(*self.testData.LUN_DELETE_CMD('volume-5')), mock.call(*self.testData.STORAGEGROUP_LIST_CMD(), poll=True), mock.call(*self.testData.STORAGEGROUP_REMOVEHLU_CMD( 'fakehost1', '31'), poll=False), mock.call(*self.testData.STORAGEGROUP_REMOVEHLU_CMD( 'fakehost2', '32'), poll=False), - mock.call(*self.testData.LUN_DELETE_CMD('vol2_in_sg'))] + mock.call(*self.testData.LUN_DELETE_CMD('volume-5'))] fake_cli.assert_has_calls(expected) def test_delete_volume_smp(self): fake_cli = self.driverSetup() vol = self.testData.test_volume_with_type.copy() + vol['metadata'] = [{'key': 'snapcopy', 'value': 'True'}] vol['provider_location'] = 'system^FNM11111|type^smp|id^1' + vol['name_id'] = vol['id'] tmp_snap = 'snap-as-vol-%s' % vol['id'] self.driver.delete_volume(vol) expected = [mock.call(*self.testData.LUN_DELETE_CMD(vol['name'])), @@ -2873,20 +2955,20 @@ Time Remaining: 0 second(s) fake_cli.assert_has_calls(expected) def test_extend_volume(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol1')] - results = [self.testData.LUN_PROPERTY('vol1', size=2)] + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-1')] + results = [self.testData.LUN_PROPERTY('volume-1', size=2)] fake_cli = self.driverSetup(commands, results) # case self.driver.extend_volume(self.testData.test_volume, 2) - expected = [mock.call(*self.testData.LUN_EXTEND_CMD('vol1', 2), + expected = [mock.call(*self.testData.LUN_EXTEND_CMD('volume-1', 2), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), poll=False)] fake_cli.assert_has_calls(expected) def test_extend_volume_has_snapshot(self): - commands = [self.testData.LUN_EXTEND_CMD('failed_vol1', 2)] + commands = [self.testData.LUN_EXTEND_CMD('volume-4', 2)] results = [FAKE_ERROR_RETURN] fake_cli = self.driverSetup(commands, results) @@ -2894,15 +2976,15 @@ Time Remaining: 0 second(s) self.driver.extend_volume, self.testData.test_failed_volume, 2) - expected = [mock.call(*self.testData.LUN_EXTEND_CMD('failed_vol1', 2), + expected = [mock.call(*self.testData.LUN_EXTEND_CMD('volume-4', 2), poll=False)] fake_cli.assert_has_calls(expected) @mock.patch('oslo_service.loopingcall.FixedIntervalLoopingCall', new=utils.ZeroIntervalLoopingCall) def test_extend_volume_failed(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('failed_vol1')] - results = [self.testData.LUN_PROPERTY('failed_vol1', size=2)] + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-4')] + results = [self.testData.LUN_PROPERTY('volume-4', size=2)] fake_cli = self.driverSetup(commands, results) self.driver.cli._client.timeout = 0 @@ -2912,40 +2994,40 @@ Time Remaining: 0 second(s) 3) expected = [ mock.call( - *self.testData.LUN_EXTEND_CMD('failed_vol1', 3), + *self.testData.LUN_EXTEND_CMD('volume-4', 3), poll=False), mock.call( - *self.testData.LUN_PROPERTY_ALL_CMD('failed_vol1'), + *self.testData.LUN_PROPERTY_ALL_CMD('volume-4'), poll=False)] fake_cli.assert_has_calls(expected) @mock.patch('oslo_service.loopingcall.FixedIntervalLoopingCall', new=utils.ZeroIntervalLoopingCall) def test_extend_preparing_volume(self): - commands = [self.testData.LUN_EXTEND_CMD('vol1', 2), - self.testData.LUN_PROPERTY_ALL_CMD('vol1')] + commands = [self.testData.LUN_EXTEND_CMD('volume-1', 2), + self.testData.LUN_PROPERTY_ALL_CMD('volume-1')] results = [[self.testData.LUN_PREP_ERROR(), SUCCEED], - [self.testData.LUN_PROPERTY('vol1', size=1, + [self.testData.LUN_PROPERTY('volume-1', size=1, operation='Preparing'), - self.testData.LUN_PROPERTY('vol1', size=1, + self.testData.LUN_PROPERTY('volume-1', size=1, operation='Optimizing'), - self.testData.LUN_PROPERTY('vol1', size=1, + self.testData.LUN_PROPERTY('volume-1', size=1, operation='None'), - self.testData.LUN_PROPERTY('vol1', size=2)]] + self.testData.LUN_PROPERTY('volume-1', size=2)]] fake_cli = self.driverSetup(commands, results) self.driver.extend_volume(self.testData.test_volume, 2) - expected = [mock.call(*self.testData.LUN_EXTEND_CMD('vol1', 2), + expected = [mock.call(*self.testData.LUN_EXTEND_CMD('volume-1', 2), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), poll=True), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), poll=False), - mock.call(*self.testData.LUN_EXTEND_CMD('vol1', 2), + mock.call(*self.testData.LUN_EXTEND_CMD('volume-1', 2), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), poll=False)] fake_cli.assert_has_calls(expected) @@ -2955,14 +3037,16 @@ Time Remaining: 0 second(s) mock.Mock(return_value={})) def test_manage_existing(self): data = self.testData - lun_rename_cmd = data.LUN_RENAME_CMD(data.test_lun_id) - lun_list_cmd = data.LUN_LIST_ALL_CMD(data.test_lun_id) + test_volume = data.test_volume_with_type + lun_rename_cmd = data.LUN_RENAME_CMD( + test_volume['id'], test_volume['name']) + lun_list_cmd = data.LUN_LIST_ALL_CMD(test_volume['id']) commands = (lun_rename_cmd, lun_list_cmd) results = (SUCCEED, (data.LIST_LUN_1_ALL, 0)) - self.configuration.storage_vnx_pool_name = \ - self.testData.test_pool_name + self.configuration.storage_vnx_pool_name = ( + self.testData.test_pool_name) fake_cli = self.driverSetup(commands, results) self.driver.manage_existing( self.testData.test_volume_with_type, @@ -2976,8 +3060,10 @@ Time Remaining: 0 second(s) mock.Mock(return_value={})) def test_manage_existing_source_name(self): data = self.testData - lun_rename_cmd = data.LUN_RENAME_CMD(data.test_lun_id) - lun_list_cmd = data.LUN_LIST_ALL_CMD(data.test_lun_id) + test_volume = data.test_volume_with_type + lun_rename_cmd = data.LUN_RENAME_CMD( + test_volume['id'], test_volume['name']) + lun_list_cmd = data.LUN_LIST_ALL_CMD(test_volume['id']) commands = (lun_rename_cmd, lun_list_cmd) results = (SUCCEED, (data.LIST_LUN_1_ALL, 0)) @@ -2995,22 +3081,31 @@ Time Remaining: 0 second(s) mock.Mock(return_value={ 'storagetype:provisioning': 'compressed', 'compression_support': 'True'})) - @mock.patch("time.time", mock.Mock(return_value=1)) + @mock.patch("time.time", mock.Mock(return_value=123)) def test_manage_existing_success_retype_with_migration(self): data = self.testData - lun_rename_cmd = data.LUN_RENAME_CMD(data.test_lun_id) - lun_list_cmd = data.LUN_LIST_ALL_CMD(data.test_lun_id) - snap_existing_cmd = data.SNAP_LIST_CMD(data.test_lun_id) + test_volume = EMCVNXCLIDriverTestData.convert_volume( + data.test_volume_with_type) + test_volume.metadata = {} + test_volume.provider_location = build_provider_location( + 1, 'lun', test_volume.name) + + lun_rename_cmd = data.LUN_RENAME_CMD( + test_volume['id'], test_volume['name']) + lun_list_cmd = data.LUN_LIST_ALL_CMD(test_volume['id']) + snap_existing_cmd = data.SNAP_LIST_CMD(test_volume['id']) + new_lun_name = test_volume['name'] + '-123' lun_create_cmd = data.LUN_CREATION_CMD( - 'vol_with_type-1', + new_lun_name, 1, 'unit_test_pool', 'compressed') - lun3_status_cmd = data.LUN_PROPERTY_ALL_CMD('vol_with_type-1') + lun3_status_cmd = data.LUN_PROPERTY_ALL_CMD(new_lun_name) compression_cmd = data.ENABLE_COMPRESSION_CMD(3) - lun1_status_cmd = data.LUN_PROPERTY_ALL_CMD('vol_with_type') + lun1_status_cmd = data.LUN_PROPERTY_ALL_CMD(test_volume['name']) migration_cmd = data.MIGRATION_CMD(1, 3) migration_verify_cmd = data.MIGRATION_VERIFY_CMD(1) + commands = (lun_list_cmd, snap_existing_cmd, lun_create_cmd, @@ -3024,8 +3119,8 @@ Time Remaining: 0 second(s) cmd_success = ('', 0) migrate_verify = ('The specified source LUN ' 'is not currently migrating', 23) - lun3_status = data.LUN_PROPERTY('vol_with_type-1', lunid=3) - lun1_status = data.LUN_PROPERTY('vol_with_type', lunid=1) + lun3_status = data.LUN_PROPERTY(new_lun_name, lunid=3) + lun1_status = data.LUN_PROPERTY(test_volume['name'], lunid=1) results = ((data.LIST_LUN_1_ALL, 0), ('no snap', 1023), cmd_success, @@ -3035,9 +3130,10 @@ Time Remaining: 0 second(s) cmd_success, migrate_verify, cmd_success) + fake_cli = self.driverSetup(commands, results) self.driver.manage_existing( - data.test_volume_with_type, + test_volume, {'source-id': 1}) expected = [mock.call(*lun_list_cmd, poll=False), @@ -3061,8 +3157,10 @@ Time Remaining: 0 second(s) @mock.patch("time.time", mock.Mock(return_value=1)) def test_manage_existing_success_retype_change_tier(self): data = self.testData - lun_rename_cmd = data.LUN_RENAME_CMD(data.test_lun_id) - lun_list_cmd = data.LUN_LIST_ALL_CMD(data.test_lun_id) + test_volume = data.test_volume_with_type + lun_rename_cmd = data.LUN_RENAME_CMD( + test_volume['id'], test_volume['name']) + lun_list_cmd = data.LUN_LIST_ALL_CMD(test_volume['id']) lun_tier_cmd = data.LUN_MODIFY_TIER(data.test_lun_id, 'optimizePool', 'noMovement') @@ -3124,8 +3222,8 @@ Time Remaining: 0 second(s) commands = [get_lun_cmd] results = [self.testData.LUN_PROPERTY('lun_name', size=test_size)] - self.configuration.storage_vnx_pool_name = \ - self.testData.test_pool_name + self.configuration.storage_vnx_pool_name = ( + self.testData.test_pool_name) fake_cli = self.driverSetup(commands, results) get_size = self.driver.manage_existing_get_size( @@ -3196,8 +3294,8 @@ Time Remaining: 0 second(s) expect_cmd1 = [ mock.call(*self.testData.SNAP_LIST_CMD(), poll=False), mock.call(*self.testData.LUN_CREATION_CMD( - 'vol3-123456', 2, 'unit_test_pool', 'deduplicated', None)), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol3-123456'), + 'volume-3-123456', 2, 'unit_test_pool', 'deduplicated', None)), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-3-123456'), poll=False), mock.call(*self.testData.MIGRATION_CMD(1, None), retry_disable=True, @@ -3219,7 +3317,7 @@ Time Remaining: 0 second(s) host_test_data) expect_cmd2 = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol3-123456', 2, 'unit_test_pool', 'deduplicated', None, + 'volume-3-123456', 2, 'unit_test_pool', 'deduplicated', None, ignore_thresholds=True))] fake_cli2.assert_has_calls(expect_cmd2) @@ -3272,7 +3370,7 @@ Time Remaining: 0 second(s) expect_cmd = [ mock.call(*self.testData.SNAP_LIST_CMD(), poll=False), mock.call(*self.testData.ENABLE_COMPRESSION_CMD(1)), - mock.call(*self.testData.MODIFY_TIERING_CMD('vol3', 'auto')) + mock.call(*self.testData.MODIFY_TIERING_CMD('volume-3', 'auto')) ] fake_cli.assert_has_calls(expect_cmd) @@ -3398,7 +3496,8 @@ Time Remaining: 0 second(s) expect_cmd = [ mock.call(*self.testData.SNAP_LIST_CMD(), poll=False), mock.call(*self.testData.LUN_CREATION_CMD( - 'vol3-123456', 2, 'unit_test_pool2', 'compressed', 'auto')), + 'volume-3-123456', 2, 'unit_test_pool2', + 'compressed', 'auto')), mock.call(*self.testData.ENABLE_COMPRESSION_CMD(1)), mock.call(*self.testData.MIGRATION_CMD(), retry_disable=True, @@ -3459,8 +3558,9 @@ Time Remaining: 0 second(s) diff_data, host_test_data) expect_cmd = [ - mock.call('lun', '-modify', '-name', 'vol3', '-o', '-initialTier', - 'optimizePool', '-tieringPolicy', 'noMovement')] + mock.call( + 'lun', '-modify', '-name', 'volume-3', '-o', '-initialTier', + 'optimizePool', '-tieringPolicy', 'noMovement')] fake_cli.assert_has_calls(expect_cmd) @mock.patch( @@ -3576,7 +3676,7 @@ Time Remaining: 0 second(s) expect_cmd = [ mock.call(*self.testData.SNAP_LIST_CMD(), poll=False), mock.call(*self.testData.LUN_CREATION_CMD( - 'vol3-123456', 2, 'unit_test_pool', 'deduplicated', None)), + 'volume-3-123456', 2, 'unit_test_pool', 'deduplicated', None)), mock.call(*self.testData.MIGRATION_CMD(), retry_disable=True, poll=True), @@ -3735,9 +3835,11 @@ Time Remaining: 0 second(s) emc_vnx_cli.CommandLineHelper.get_array_serial = mock.Mock( return_value={'array_serial': "FNM00124500890"}) - vol = self.testData.test_volume3.copy() + vol = EMCVNXCLIDriverTestData.convert_volume( + self.testData.test_volume3) vol['provider_location'] = 'system^FNM11111|type^smp|id^1' - tmp_snap = 'snap-as-vol-%s' % vol['id'] + vol['volume_metadata'] = [{'key': 'snapcopy', 'value': 'True'}] + tmp_snap = 'tmp-snap-%s' % vol['id'] ret = self.driver.retype(None, vol, new_type_data, diff_data, @@ -3759,15 +3861,15 @@ Time Remaining: 0 second(s) """Test creating volume with fastcache enabled.""" commands = [self.testData.NDU_LIST_CMD, self.testData.POOL_PROPERTY_W_FASTCACHE_CMD, - self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), + self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), ] results = [self.testData.NDU_LIST_RESULT, self.testData.POOL_PROPERTY_W_FASTCACHE, - self.testData.LUN_PROPERTY('vol_with_type', True), + self.testData.LUN_PROPERTY('volume-1', True), ] fake_cli = self.driverSetup(commands, results) - lun_info = {'lun_name': "vol_with_type", + lun_info = {'lun_name': "volume-1", 'lun_id': 1, 'pool': "unit_test_pool", 'attached_snapshot': "N/A", @@ -3802,8 +3904,7 @@ Time Remaining: 0 second(s) mock.call('-np', 'lun', '-create', '-capacity', 1, '-sq', 'gb', '-poolName', self.testData.test_pool_name, - '-name', 'vol_with_type', '-type', 'NonThin') - ] + '-name', 'volume-1', '-type', 'NonThin')] fake_cli.assert_has_calls(expect_cmd) @@ -3899,7 +4000,7 @@ Time Remaining: 0 second(s) def test_delete_consistency_group(self): cg_name = self.testData.test_cg['id'] commands = [self.testData.DELETE_CONSISTENCYGROUP_CMD(cg_name), - self.testData.LUN_DELETE_CMD('vol1')] + self.testData.LUN_DELETE_CMD('volume-1')] results = [SUCCEED, SUCCEED] fake_cli = self.driverSetup(commands, results) self.driver.delete_consistencygroup( @@ -3909,8 +4010,8 @@ Time Remaining: 0 second(s) mock.call( *self.testData.DELETE_CONSISTENCYGROUP_CMD( cg_name)), - mock.call(*self.testData.LUN_DELETE_CMD('vol1')), - mock.call(*self.testData.LUN_DELETE_CMD('vol1'))] + mock.call(*self.testData.LUN_DELETE_CMD('volume-1')), + mock.call(*self.testData.LUN_DELETE_CMD('volume-1'))] fake_cli.assert_has_calls(expect_cmd) def test_create_cgsnapshot(self): @@ -3979,10 +4080,10 @@ Time Remaining: 0 second(s) "eventlet.event.Event.wait", mock.Mock(return_value=None)) def test_add_volume_to_cg(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol1'), + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), self.testData.ADD_LUN_TO_CG_CMD('cg_id', 1), ] - results = [self.testData.LUN_PROPERTY('vol1', True), + results = [self.testData.LUN_PROPERTY('volume-1', True), SUCCEED] fake_cli = self.driverSetup(commands, results) @@ -3990,19 +4091,22 @@ Time Remaining: 0 second(s) expect_cmd = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol1', 1, + 'volume-1', 1, 'unit_test_pool', None, None, poll=False)), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), poll=False), mock.call(*self.testData.ADD_LUN_TO_CG_CMD( 'cg_id', 1), poll=False)] fake_cli.assert_has_calls(expect_cmd) - def test_create_cloned_volume_from_consistnecy_group(self): - cmd_dest = self.testData.LUN_PROPERTY_ALL_CMD("vol1_dest") - cmd_dest_p = self.testData.LUN_PROPERTY_ALL_CMD("vol1_dest") - output_dest = self.testData.LUN_PROPERTY("vol1_dest") + def test_create_cloned_volume_from_consistency_group(self): + cmd_dest = self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-1')) + cmd_dest_p = self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-1')) + output_dest = self.testData.LUN_PROPERTY( + build_migration_dest_name('volume-1')) cmd_migrate = self.testData.MIGRATION_CMD(1, 1) output_migrate = ("", 0) cmd_migrate_verify = self.testData.MIGRATION_VERIFY_CMD(1) @@ -4015,28 +4119,31 @@ Time Remaining: 0 second(s) results = [output_dest, output_dest, output_migrate, output_migrate_verify] fake_cli = self.driverSetup(commands, results) - - self.driver.create_cloned_volume(self.testData.test_volume_clone_cg, + test_volume_clone_cg = EMCVNXCLIDriverTestData.convert_volume( + self.testData.test_volume_clone_cg) + self.driver.create_cloned_volume(test_volume_clone_cg, self.testData.test_clone_cg) - tmp_cgsnapshot = 'tmp-cgsnapshot-' + self.testData.test_volume['id'] + tmp_cgsnapshot = 'tmp-snap-' + self.testData.test_volume['id'] expect_cmd = [ mock.call( *self.testData.CREATE_CG_SNAPSHOT(cg_name, tmp_cgsnapshot)), mock.call( *self.testData.GET_SNAP(tmp_cgsnapshot)), - mock.call(*self.testData.SNAP_MP_CREATE_CMD(name='vol1', - source='clone1'), + mock.call(*self.testData.SNAP_MP_CREATE_CMD(name='volume-1', + source='volume-2'), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1'), poll=True), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), + poll=True), mock.call( *self.testData.SNAP_ATTACH_CMD( - name='vol1', snapName=tmp_cgsnapshot)), + name='volume-1', snapName=tmp_cgsnapshot)), mock.call(*self.testData.LUN_CREATION_CMD( - 'vol1_dest', 1, 'unit_test_pool', None, None)), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1_dest'), - poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol1_dest'), - poll=False), + build_migration_dest_name('volume-1'), 1, + 'unit_test_pool', None, None)), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-1')), poll=False), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-1')), poll=False), mock.call(*self.testData.MIGRATION_CMD(1, 1), retry_disable=True, poll=True), @@ -4046,9 +4153,12 @@ Time Remaining: 0 second(s) fake_cli.assert_has_calls(expect_cmd) def test_create_volume_from_cgsnapshot(self): - cmd_dest = self.testData.LUN_PROPERTY_ALL_CMD("vol2_dest") - cmd_dest_np = self.testData.LUN_PROPERTY_ALL_CMD("vol2_dest") - output_dest = self.testData.LUN_PROPERTY("vol2_dest") + cmd_dest = self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('vol2')) + cmd_dest_np = self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('vol2')) + output_dest = self.testData.LUN_PROPERTY( + build_migration_dest_name('vol2')) cmd_migrate = self.testData.MIGRATION_CMD(1, 1) output_migrate = ("", 0) cmd_migrate_verify = self.testData.MIGRATION_VERIFY_CMD(1) @@ -4059,25 +4169,27 @@ Time Remaining: 0 second(s) results = [output_dest, output_dest, output_migrate, output_migrate_verify] fake_cli = self.driverSetup(commands, results) - + test_snapshot = EMCVNXCLIDriverTestData.convert_snapshot( + self.testData.test_member_cgsnapshot) self.driver.create_volume_from_snapshot( - self.testData.volume_in_cg, self.testData.test_member_cgsnapshot) + self.testData.volume_in_cg, test_snapshot) expect_cmd = [ mock.call( *self.testData.SNAP_MP_CREATE_CMD( - name='vol2', source='vol1'), + name='volume-2', source='volume-1'), poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol2'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-2'), poll=True), mock.call( *self.testData.SNAP_ATTACH_CMD( - name='vol2', snapName='cgsnapshot_id')), + name='volume-2', snapName='cgsnapshot_id')), mock.call(*self.testData.LUN_CREATION_CMD( - 'vol2_dest', 1, 'unit_test_pool', None, None)), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol2_dest'), - poll=False), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol2_dest'), - poll=False), + build_migration_dest_name('volume-2'), 1, + 'unit_test_pool', None, None)), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-2')), poll=False), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( + build_migration_dest_name('volume-2')), poll=False), mock.call(*self.testData.MIGRATION_CMD(1, 1), retry_disable=True, poll=True), @@ -4090,7 +4202,6 @@ Time Remaining: 0 second(s) commands = [self.testData.GET_CG_BY_NAME_CMD(cg_name)] results = [self.testData.CG_PROPERTY(cg_name)] fake_cli = self.driverSetup(commands, results) - (model_update, add_vols, remove_vols) = ( self.driver.update_consistencygroup(None, self.testData.test_cg, self.testData. @@ -4162,37 +4273,28 @@ Time Remaining: 0 second(s) new_cg.id = 'new_cg_id' vol1_in_new_cg = self.testData.test_volume_cg.copy() vol1_in_new_cg.update( - {'name': 'vol1_in_cg', + {'name': 'volume-1_in_cg', 'id': '111111', 'consistencygroup_id': 'new_cg_id', 'provider_location': None}) vol2_in_new_cg = self.testData.test_volume_cg.copy() vol2_in_new_cg.update( - {'name': 'vol2_in_cg', + {'name': 'volume-2_in_cg', 'id': '222222', 'consistencygroup_id': 'new_cg_id', 'provider_location': None}) src_cgsnap = self.testData.test_cgsnapshot - snap1_in_src_cgsnap = self.testData.test_member_cgsnapshot.copy() - snap1_in_src_cgsnap.update( - {'volume': fake_volume.fake_volume_obj( - None, **self.testData.test_volume), - 'expected_attrs': ['volume']}) - snap1_in_src_cgsnap = fake_snapshot.fake_snapshot_obj( - None, **snap1_in_src_cgsnap) - snap2_in_src_cgsnap = self.testData.test_member_cgsnapshot.copy() - snap2_in_src_cgsnap.update( - {'volume': fake_volume.fake_volume_obj( - None, **self.testData.test_volume2), - 'expected_attrs': ['volume']}) - snap2_in_src_cgsnap = fake_snapshot.fake_snapshot_obj( - None, **snap2_in_src_cgsnap) + + snap1_in_src_cgsnap = EMCVNXCLIDriverTestData.convert_snapshot( + self.testData.test_member_cgsnapshot) + snap2_in_src_cgsnap = EMCVNXCLIDriverTestData.convert_snapshot( + self.testData.test_member_cgsnapshot2) copied_snap_name = 'temp_snapshot_for_%s' % new_cg['id'] td = self.testData commands = [td.SNAP_COPY_CMD(src_cgsnap['id'], copied_snap_name), td.ALLOW_READWRITE_ON_SNAP_CMD(copied_snap_name), td.SNAP_MP_CREATE_CMD(vol1_in_new_cg['name'], - snap1_in_src_cgsnap.volume_name), + self.testData.test_volume['name']), td.SNAP_ATTACH_CMD(vol1_in_new_cg['name'], copied_snap_name), td.LUN_CREATION_CMD(vol1_in_new_cg['name'] + '_dest', @@ -4203,7 +4305,7 @@ Time Remaining: 0 second(s) td.MIGRATION_CMD(6231, 1), td.SNAP_MP_CREATE_CMD(vol2_in_new_cg['name'], - snap2_in_src_cgsnap.volume_name), + self.testData.test_volume2['name']), td.SNAP_ATTACH_CMD(vol2_in_new_cg['name'], copied_snap_name), td.LUN_CREATION_CMD(vol2_in_new_cg['name'] + '_dest', @@ -4230,7 +4332,6 @@ Time Remaining: 0 second(s) SUCCEED, SUCCEED] fake_cli = self.driverSetup(commands, results) - cg_model_update, volumes_model_update = ( self.driver.create_consistencygroup_from_src( None, new_cg, [vol1_in_new_cg, vol2_in_new_cg], @@ -4247,7 +4348,7 @@ Time Remaining: 0 second(s) mock.call(*td.SNAP_COPY_CMD(src_cgsnap['id'], copied_snap_name)), mock.call(*td.ALLOW_READWRITE_ON_SNAP_CMD(copied_snap_name)), mock.call(*td.SNAP_MP_CREATE_CMD(vol1_in_new_cg['name'], - snap1_in_src_cgsnap.volume_name), + self.testData.test_volume['name']), poll=False), mock.call(*td.LUN_PROPERTY_ALL_CMD(vol1_in_new_cg['name']), poll=True), @@ -4263,7 +4364,7 @@ Time Remaining: 0 second(s) mock.call(*td.MIGRATION_CMD(6231, 1), poll=True, retry_disable=True), mock.call(*td.SNAP_MP_CREATE_CMD(vol2_in_new_cg['name'], - snap2_in_src_cgsnap.volume_name), + self.testData.test_volume2['name']), poll=False), mock.call(*td.LUN_PROPERTY_ALL_CMD(vol2_in_new_cg['name']), poll=True), @@ -4338,31 +4439,21 @@ Time Remaining: 0 second(s) new_cg.id = 'new_cg_id' vol1_in_new_cg = self.testData.test_volume_cg.copy() vol1_in_new_cg.update( - {'name': 'vol1_in_cg', + {'name': 'volume-1_in_cg', 'id': '111111', 'consistencygroup_id': 'new_cg_id', 'provider_location': None}) vol2_in_new_cg = self.testData.test_volume_cg.copy() vol2_in_new_cg.update( - {'name': 'vol2_in_cg', + {'name': 'volume-2_in_cg', 'id': '222222', 'consistencygroup_id': 'new_cg_id', 'provider_location': None}) src_cgsnap = self.testData.test_cgsnapshot - snap1_in_src_cgsnap = self.testData.test_member_cgsnapshot.copy() - snap1_in_src_cgsnap.update( - {'volume': fake_volume.fake_volume_obj( - None, **self.testData.test_volume), - 'expected_attrs': ['volume']}) - snap1_in_src_cgsnap = fake_snapshot.fake_snapshot_obj( - None, **snap1_in_src_cgsnap) - snap2_in_src_cgsnap = self.testData.test_member_cgsnapshot.copy() - snap2_in_src_cgsnap.update( - {'volume': fake_volume.fake_volume_obj( - None, **self.testData.test_volume2), - 'expected_attrs': ['volume']}) - snap2_in_src_cgsnap = fake_snapshot.fake_snapshot_obj( - None, **snap2_in_src_cgsnap) + snap1_in_src_cgsnap = EMCVNXCLIDriverTestData.convert_snapshot( + self.testData.test_member_cgsnapshot) + snap2_in_src_cgsnap = EMCVNXCLIDriverTestData.convert_snapshot( + self.testData.test_member_cgsnapshot2) copied_snap_name = 'temp_snapshot_for_%s' % new_cg['id'] td = self.testData commands = [td.LUN_PROPERTY_ALL_CMD(vol1_in_new_cg['name'] + '_dest'), @@ -4408,13 +4499,13 @@ Time Remaining: 0 second(s) new_cg.id = 'new_cg_id' vol1_in_new_cg = self.testData.test_volume_cg.copy() vol1_in_new_cg.update( - {'name': 'vol1_in_cg', + {'name': 'volume-1_in_cg', 'id': '111111', 'consistencygroup_id': 'new_cg_id', 'provider_location': None}) vol2_in_new_cg = self.testData.test_volume_cg.copy() vol2_in_new_cg.update( - {'name': 'vol2_in_cg', + {'name': 'volume-2_in_cg', 'id': '222222', 'consistencygroup_id': 'new_cg_id', 'provider_location': None}) @@ -4423,16 +4514,18 @@ Time Remaining: 0 second(s) src_cg.id = 'src_cg_id' vol1_in_src_cg = self.testData.test_volume_cg.copy() vol1_in_src_cg.update( - {'name': 'vol1_in_src_cg', + {'name': 'volume-1_in_src_cg', 'id': '111110000', 'consistencygroup_id': 'src_cg_id', - 'provider_location': None}) + 'provider_location': build_provider_location( + 1, 'lun', 'volume-1_in_src_cg')}) vol2_in_src_cg = self.testData.test_volume_cg.copy() vol2_in_src_cg.update( - {'name': 'vol2_in_src_cg', + {'name': 'volume-2_in_src_cg', 'id': '222220000', 'consistencygroup_id': 'src_cg_id', - 'provider_location': None}) + 'provider_location': build_provider_location( + 2, 'lun', 'volume-2_in_src_cg')}) temp_snap_name = 'temp_snapshot_for_%s' % new_cg['id'] td = self.testData commands = [td.CREATE_CG_SNAPSHOT(src_cg['id'], temp_snap_name), @@ -4475,7 +4568,6 @@ Time Remaining: 0 second(s) SUCCEED, SUCCEED] fake_cli = self.driverSetup(commands, results) - cg_model_update, volumes_model_update = ( self.driver.create_consistencygroup_from_src( None, new_cg, [vol1_in_new_cg, vol2_in_new_cg], @@ -4516,7 +4608,7 @@ Time Remaining: 0 second(s) new_cg.id = 'new_cg_id' vol1_in_new_cg = self.testData.test_volume_cg.copy() vol1_in_new_cg.update( - {'name': 'vol1_in_cg', + {'name': 'volume-1_in_cg', 'id': '111111', 'consistencygroup_id': 'new_cg_id', 'provider_location': None}) @@ -4525,10 +4617,11 @@ Time Remaining: 0 second(s) src_cg.id = 'src_cg_id' vol1_in_src_cg = self.testData.test_volume_cg.copy() vol1_in_src_cg.update( - {'name': 'vol1_in_src_cg', + {'name': 'volume-1_in_src_cg', 'id': '111110000', 'consistencygroup_id': 'src_cg_id', - 'provider_location': None}) + 'provider_location': build_provider_location( + 1, 'lun', 'volume-1_in_src_cg')}) temp_snap_name = 'temp_snapshot_for_%s' % new_cg['id'] td = self.testData commands = [td.CREATE_CG_SNAPSHOT(src_cg['id'], temp_snap_name), @@ -4685,7 +4778,9 @@ Time Remaining: 0 second(s) def test_update_migrated_volume(self): self.driverSetup() - expected_update = {'metadata': {'lun_type': 'lun'}} + expected_update = {'provider_location': + self.testData.test_volume2['provider_location'], + 'metadata': {'snapcopy': 'False'}} model_update = self.driver.update_migrated_volume( None, self.testData.test_volume, self.testData.test_volume2, 'available') @@ -4838,8 +4933,8 @@ class EMCVNXCLIDArrayBasedDriverTestCase(DriverTestCaseBase): "get_volume_type_extra_specs", mock.Mock(return_value={'storagetype:provisioning': 'deduplicated'})) def test_create_volume_deduplicated(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type')] - results = [self.testData.LUN_PROPERTY('vol_with_type', True)] + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-1')] + results = [self.testData.LUN_PROPERTY('volume-1', True)] fake_cli = self.driverSetup(commands, results) self.driver.cli.enablers = ['-Compression', @@ -4852,10 +4947,10 @@ class EMCVNXCLIDArrayBasedDriverTestCase(DriverTestCaseBase): # Verification expect_cmd = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol_with_type', 1, + 'volume-1', 1, 'unit_test_pool', 'deduplicated', None, poll=False)), - mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), + mock.call(*self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), poll=False)] fake_cli.assert_has_calls(expect_cmd) @@ -4937,8 +5032,11 @@ class EMCVNXCLIDArrayBasedDriverTestCase(DriverTestCaseBase): mock.Mock(return_value={})) def test_manage_existing(self): data = self.testData - lun_rename_cmd = data.LUN_RENAME_CMD(data.test_lun_id) - lun_list_cmd = data.LUN_LIST_ALL_CMD(data.test_lun_id) + test_volume = data.test_volume_with_type + lun_rename_cmd = data.LUN_RENAME_CMD( + test_volume['id'], test_volume['name']) + lun_list_cmd = data.LUN_LIST_ALL_CMD(test_volume['id']) + commands = lun_rename_cmd, lun_list_cmd results = SUCCEED, (data.LIST_LUN_1_SPECS, 0) fake_cli = self.driverSetup(commands, results) @@ -4957,11 +5055,11 @@ class EMCVNXCLIDArrayBasedDriverTestCase(DriverTestCaseBase): mock.Mock(return_value={'storagetype:provisioning': 'Compressed', 'storagetype:pool': 'unit_test_pool'})) def test_create_compression_volume(self): - commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), - self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'), + commands = [self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), + self.testData.LUN_PROPERTY_ALL_CMD('volume-1'), self.testData.NDU_LIST_CMD] - results = [self.testData.LUN_PROPERTY('vol_with_type', True), - self.testData.LUN_PROPERTY('vol_with_type', True), + results = [self.testData.LUN_PROPERTY('volume-1', True), + self.testData.LUN_PROPERTY('volume-1', True), self.testData.NDU_LIST_RESULT] fake_cli = self.driverSetup(commands, results) @@ -4976,13 +5074,13 @@ class EMCVNXCLIDArrayBasedDriverTestCase(DriverTestCaseBase): # Verification expect_cmd = [ mock.call(*self.testData.LUN_CREATION_CMD( - 'vol_with_type', 1, + 'volume-1', 1, 'unit_test_pool', 'compressed', None, poll=False)), mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( - 'vol_with_type'), poll=False), + 'volume-1'), poll=False), mock.call(*self.testData.LUN_PROPERTY_ALL_CMD( - 'vol_with_type'), poll=True), + 'volume-1'), poll=True), mock.call(*self.testData.ENABLE_COMPRESSION_CMD( 1))] fake_cli.assert_has_calls(expect_cmd) @@ -5133,8 +5231,8 @@ class EMCVNXCLIDriverFCTestCase(DriverTestCaseBase): ('', 0), self.testData.FC_PORTS] fake_cli = self.driverSetup(commands, results) - self.driver.cli.zonemanager_lookup_service =\ - fc_service.FCSanLookupService(configuration=self.configuration) + self.driver.cli.zonemanager_lookup_service = ( + fc_service.FCSanLookupService(configuration=self.configuration)) conn_info = self.driver.initialize_connection( self.testData.test_volume, @@ -5256,8 +5354,8 @@ class EMCVNXCLIDriverFCTestCase(DriverTestCaseBase): cli_helper.get_storage_group = mock.Mock( return_value=data) cli_helper.remove_hlu_from_storagegroup = mock.Mock() - self.driver.cli.zonemanager_lookup_service =\ - fc_service.FCSanLookupService(configuration=self.configuration) + self.driver.cli.zonemanager_lookup_service = ( + fc_service.FCSanLookupService(configuration=self.configuration)) connection_info = self.driver.terminate_connection( self.testData.test_volume, self.testData.connector) @@ -5282,8 +5380,8 @@ class EMCVNXCLIDriverFCTestCase(DriverTestCaseBase): cli_helper.get_storage_group = mock.Mock( return_value=data) cli_helper.remove_hlu_from_storagegroup = mock.Mock() - self.driver.cli.zonemanager_lookup_service =\ - fc_service.FCSanLookupService(configuration=self.configuration) + self.driver.cli.zonemanager_lookup_service = ( + fc_service.FCSanLookupService(configuration=self.configuration)) connection_info = self.driver.terminate_connection( self.testData.test_volume, self.testData.connector) diff --git a/cinder/volume/drivers/emc/emc_vnx_cli.py b/cinder/volume/drivers/emc/emc_vnx_cli.py index e49cea9fa..2a247bf50 100644 --- a/cinder/volume/drivers/emc/emc_vnx_cli.py +++ b/cinder/volume/drivers/emc/emc_vnx_cli.py @@ -2113,9 +2113,8 @@ class EMCVnxCliBase(object): 'thick_provisioning_support': True} enablers = [] tmp_snap_prefix = 'tmp-snap-' - snap_as_vol_prefix = 'snap-as-vol-' - tmp_cgsnap_prefix = 'tmp-cgsnapshot-' tmp_smp_for_backup_prefix = 'tmp-smp-' + snap_as_vol_prefix = 'snap-as-vol-' def __init__(self, prtcl, configuration=None): self.protocol = prtcl @@ -2260,40 +2259,39 @@ class EMCVnxCliBase(object): def _construct_store_spec(self, volume, snapshot): if snapshot['cgsnapshot_id']: + # Snapshot is part of cg snapshot snapshot_name = snapshot['cgsnapshot_id'] else: snapshot_name = snapshot['name'] - source_volume_name = snapshot['volume_name'] + new_snap_name = snapshot_name + if self._is_snapcopy_enabled(volume): + new_snap_name = self._construct_snap_name(volume) + pool_name = self.get_target_storagepool(volume, snapshot['volume']) volume_name = volume['name'] volume_size = snapshot['volume_size'] dest_volume_name = volume_name + '_dest' - snap_name = snapshot_name - pool_name = self.get_target_storagepool(volume, snapshot['volume']) specs = self.get_volumetype_extraspecs(volume) - provisioning, tiering, snapcopy = self._get_extra_spec_value(specs) - if snapcopy == 'true': - snap_name = self._construct_snap_as_vol_name(volume) + provisioning, tiering = self._get_extra_spec_value(specs) store_spec = { - 'source_vol_name': source_volume_name, 'volume': volume, 'src_snap_name': snapshot_name, - 'snap_name': snap_name, + 'new_snap_name': new_snap_name, 'dest_vol_name': dest_volume_name, 'pool_name': pool_name, 'provisioning': provisioning, 'tiering': tiering, - 'snapcopy': snapcopy, 'volume_size': volume_size, 'client': self._client, 'ignore_pool_full_threshold': self.ignore_pool_full_threshold } return store_spec - def _construct_snap_as_vol_name(self, volume): - return self.snap_as_vol_prefix + volume['id'] - - def _construct_tmp_snap_name(self, volume): - return self.tmp_snap_prefix + volume['id'] + def _construct_snap_name(self, volume): + """Returns snapshot or cgsnapshot name.""" + if self._is_snapcopy_enabled(volume): + return self.snap_as_vol_prefix + six.text_type(volume['name_id']) + else: + return self.tmp_snap_prefix + six.text_type(volume['name_id']) def _construct_tmp_smp_name(self, snapshot): return self.tmp_smp_for_backup_prefix + snapshot.id @@ -2308,33 +2306,30 @@ class EMCVnxCliBase(object): # defining CLI command specs = self.get_volumetype_extraspecs(volume) pool = self.get_target_storagepool(volume) - provisioning, tiering, snapcopy = self._get_extra_spec_value(specs) - - if snapcopy == 'true' and volume['consistencygroup_id']: - msg = _("Volume with copytype:snap=True can not be put in " - "consistency group.") - LOG.error(msg) - raise exception.VolumeBackendAPIException(data=msg) + provisioning, tiering = self._get_extra_spec_value(specs) + if 'snapcopy' in volume_metadata: + # We ignore snapcopy metadata when creating volume + LOG.warning(_LW('snapcopy metadata is ignored when' + ' creating volume.')) + volume_metadata['snapcopy'] = 'False' LOG.info(_LI('Create Volume: %(volume)s Size: %(size)s ' 'pool: %(pool)s ' 'provisioning: %(provisioning)s ' - 'tiering: %(tiering)s ' - 'snapcopy: %(snapcopy)s.'), + 'tiering: %(tiering)s '), {'volume': volume_name, 'size': volume_size, 'pool': pool, 'provisioning': provisioning, - 'tiering': tiering, - 'snapcopy': snapcopy}) + 'tiering': tiering}) data = self._client.create_lun_with_advance_feature( pool, volume_name, volume_size, provisioning, tiering, volume['consistencygroup_id'], ignore_thresholds=self.ignore_pool_full_threshold, poll=False) - pl = self._build_provider_location(data['lun_id']) - volume_metadata['lun_type'] = 'lun' + pl = self._build_provider_location(lun_id=data['lun_id'], + base_lun_name=volume['name']) model_update = {'provider_location': pl, 'metadata': volume_metadata} @@ -2352,7 +2347,7 @@ class EMCVnxCliBase(object): "since driver version 5.1.0. This key will be " "ignored.")) - provisioning, tiering, snap_copy = self._get_extra_spec_value(specs) + provisioning, tiering = self._get_extra_spec_value(specs) # step 1: check extra spec value if provisioning: self._check_extra_spec_value( @@ -2362,13 +2357,10 @@ class EMCVnxCliBase(object): self._check_extra_spec_value( tiering, VNXTieringEnum.get_all()) - if snap_copy: - self._check_extra_spec_value( - snap_copy, ['true', 'false']) # step 2: check extra spec combination - self._check_extra_spec_combination([provisioning, tiering, snap_copy]) - return provisioning, tiering, snap_copy + self._check_extra_spec_combination([provisioning, tiering]) + return provisioning, tiering def _check_extra_spec_value(self, extra_spec, valid_values): """Checks whether an extra spec's value is valid.""" @@ -2403,17 +2395,15 @@ class EMCVnxCliBase(object): "'provisioning:type' instead.")) tiering = extra_specs.get( self._client.tiering_spec, 'None').lower() - snapcopy = extra_specs.get( - self._client.copytype_spec, 'False').lower() - return provisioning, tiering, snapcopy + return provisioning, tiering def _check_extra_spec_combination(self, spec_values): """Checks whether extra spec combination is valid.""" enablers = self.enablers - # check provisioning, tiering, snapcopy + # check provisioning, tiering # deduplicated and tiering can not be both enabled - provisioning, tiering, snapcopy = spec_values + provisioning, tiering = spec_values if provisioning == 'deduplicated' and tiering != 'none': msg = _("deduplicated and auto tiering can't be both enabled.") LOG.error(msg) @@ -2464,11 +2454,11 @@ class EMCVnxCliBase(object): # Reraise the original exception pass if volume['provider_location']: - lun_type = self._extract_provider_location_for_lun( + lun_type = self._extract_provider_location( volume['provider_location'], 'type') if lun_type == 'smp': self._client.delete_snapshot( - self._construct_snap_as_vol_name(volume)) + self._construct_snap_name(volume)) def extend_volume(self, volume, new_size): """Extends an EMC volume.""" @@ -2581,10 +2571,10 @@ class EMCVnxCliBase(object): src_id = self.get_lun_id(volume) if type_specs is not None: - provisioning, tiering, snapcopy = self._get_extra_spec_value( + provisioning, tiering = self._get_extra_spec_value( type_specs) else: - provisioning, tiering, snapcopy = self._get_extra_spec_value( + provisioning, tiering = self._get_extra_spec_value( self.get_volumetype_extraspecs(volume)) data = self._client.create_lun_with_advance_feature( @@ -2596,33 +2586,39 @@ class EMCVnxCliBase(object): moved = self._client.migrate_lun_with_verification( src_id, dst_id, new_volume_name) - lun_type = self._extract_provider_location_for_lun( + lun_type = self._extract_provider_location( volume['provider_location'], 'type') + # A smp will become a LUN after migration if lun_type == 'smp': self._client.delete_snapshot( - self._construct_snap_as_vol_name(volume)) + self._construct_snap_name(volume)) - pl = self._build_provider_location(src_id, 'lun') + pl = self._build_provider_location(src_id, 'lun', + base_lun_name=volume['name']) volume_metadata = self._get_volume_metadata(volume) - volume_metadata['lun_type'] = 'lun' + volume_metadata['snapcopy'] = 'False' model_update = {'provider_location': pl, 'metadata': volume_metadata} return moved, model_update def update_migrated_volume(self, context, volume, new_volume, original_volume_status): - lun_type = self._extract_provider_location_for_lun( + """Updates metadata after host-assisted migration.""" + lun_type = self._extract_provider_location( new_volume['provider_location'], 'type') volume_metadata = self._get_volume_metadata(volume) + model_update = {'provider_location': + new_volume['provider_location']} if lun_type: - volume_metadata['lun_type'] = lun_type - model_update = {'metadata': volume_metadata} - return model_update + volume_metadata['snapcopy'] = ( + 'True' if lun_type == 'smp' else 'False') + model_update['metadata'] = volume_metadata + return model_update def retype(self, ctxt, volume, new_type, diff, host): new_specs = new_type['extra_specs'] - new_provisioning, new_tiering, snapcopy = ( + new_provisioning, new_tiering = ( self._get_and_validate_extra_specs(new_specs)) # Check what changes are needed @@ -2684,14 +2680,14 @@ class EMCVnxCliBase(object): } old_specs = self.get_volumetype_extraspecs(volume) - old_provisioning, old_tiering, old_snapcopy = ( + old_provisioning, old_tiering = ( self._get_extra_spec_value(old_specs)) new_specs = new_type['extra_specs'] - new_provisioning, new_tiering, new_snapcopy = ( + new_provisioning, new_tiering = ( self._get_extra_spec_value(new_specs)) - lun_type = self._extract_provider_location_for_lun( + lun_type = self._extract_provider_location( volume['provider_location'], 'type') if volume['host'] != host['host']: @@ -2821,14 +2817,6 @@ class EMCVnxCliBase(object): snapshot_name = snapshot['name'] volume_name = snapshot['volume_name'] volume = snapshot['volume'] - lun_type = self._extract_provider_location_for_lun( - volume['provider_location'], 'type') - if lun_type == 'smp': - msg = (_('Failed to create snapshot of %s because it is a ' - 'snapshot mount point.') - % volume_name) - LOG.error(msg) - raise exception.VolumeBackendAPIException(data=msg) LOG.info(_LI('Create snapshot: %(snapshot)s: volume: %(volume)s'), {'snapshot': snapshot_name, 'volume': volume_name}) @@ -2871,27 +2859,18 @@ class EMCVnxCliBase(object): 1. Create a snap mount point (SMP) for the snapshot. 2. Attach the snapshot to the SMP created in the first step. 3. Create a temporary lun prepare for migration. - (Skipped if copytype:snap='true') + (Skipped if snapcopy='true') 4. Start a migration between the SMP and the temp lun. - (Skipped if copytype:snap='true') + (Skipped if snapcopy='true') """ self._volume_creation_check(volume) flow_name = 'create_volume_from_snapshot' + base_lun_name = self._get_base_lun_name(snapshot.volume) work_flow = linear_flow.Flow(flow_name) store_spec = self._construct_store_spec(volume, snapshot) + store_spec.update({'base_lun_name': base_lun_name}) volume_metadata = self._get_volume_metadata(volume) - if store_spec['snapcopy'] == 'false': - work_flow.add(CreateSMPTask(), - AttachSnapTask(), - CreateDestLunTask(), - MigrateLunTask()) - flow_engine = taskflow.engines.load(work_flow, - store=store_spec) - flow_engine.run() - new_lun_id = flow_engine.storage.fetch('new_lun_id') - pl = self._build_provider_location(new_lun_id, 'lun') - volume_metadata['lun_type'] = 'lun' - else: + if self._is_snapcopy_enabled(volume): work_flow.add(CopySnapshotTask(), AllowReadWriteOnSnapshotTask(), CreateSMPTask(), @@ -2900,8 +2879,21 @@ class EMCVnxCliBase(object): store=store_spec) flow_engine.run() new_lun_id = flow_engine.storage.fetch('new_smp_id') - pl = self._build_provider_location(new_lun_id, 'smp') - volume_metadata['lun_type'] = 'smp' + pl = self._build_provider_location( + new_lun_id, 'smp', base_lun_name) + volume_metadata['snapcopy'] = 'True' + else: + work_flow.add(CreateSMPTask(), + AttachSnapTask(), + CreateDestLunTask(), + MigrateLunTask()) + flow_engine = taskflow.engines.load(work_flow, + store=store_spec) + flow_engine.run() + new_lun_id = flow_engine.storage.fetch('new_lun_id') + pl = self._build_provider_location( + new_lun_id, 'lun', volume['name']) + volume_metadata['snapcopy'] = 'False' model_update = {'provider_location': pl, 'metadata': volume_metadata} volume_host = volume['host'] @@ -2914,42 +2906,46 @@ class EMCVnxCliBase(object): def create_cloned_volume(self, volume, src_vref): """Creates a clone of the specified volume.""" - lun_type = self._extract_provider_location_for_lun( - src_vref['provider_location'], 'type') - if lun_type == 'smp': - msg = (_('Failed to clone %s because it is a ' - 'snapshot mount point.') - % src_vref['name']) - LOG.error(msg) - raise exception.VolumeBackendAPIException(data=msg) self._volume_creation_check(volume) - source_volume_name = src_vref['name'] + base_lun_name = self._get_base_lun_name(src_vref) source_lun_id = self.get_lun_id(src_vref) volume_size = src_vref['size'] + source_volume_name = src_vref['name'] consistencygroup_id = src_vref['consistencygroup_id'] - snapshot_name = self._construct_tmp_snap_name(volume) - tmp_cgsnapshot_name = None + cgsnapshot_name = None if consistencygroup_id: - tmp_cgsnapshot_name = self.tmp_cgsnap_prefix + volume['id'] + cgsnapshot_name = self._construct_snap_name(volume) + snapshot_name = self._construct_snap_name(volume) snapshot = { 'name': snapshot_name, 'volume_name': source_volume_name, 'volume_size': volume_size, 'volume': src_vref, - 'cgsnapshot_id': tmp_cgsnapshot_name, + 'cgsnapshot_id': cgsnapshot_name, 'consistencygroup_id': consistencygroup_id, - 'id': tmp_cgsnapshot_name + 'id': cgsnapshot_name } flow_name = 'create_cloned_volume' store_spec = self._construct_store_spec(volume, snapshot) - volume_metadata = self._get_volume_metadata(volume) work_flow = linear_flow.Flow(flow_name) - if store_spec['snapcopy'] == 'true': - snapshot['name'] = self._construct_snap_as_vol_name(volume) store_spec.update({'snapshot': snapshot}) store_spec.update({'source_lun_id': source_lun_id}) - if store_spec['snapcopy'] == 'false': + store_spec.update({'base_lun_name': base_lun_name}) + volume_metadata = self._get_volume_metadata(volume) + if self._is_snapcopy_enabled(volume): + # snapcopy feature enabled + work_flow.add(CreateSnapshotTask(), + CreateSMPTask(), + AttachSnapTask()) + flow_engine = taskflow.engines.load(work_flow, + store=store_spec) + flow_engine.run() + new_lun_id = flow_engine.storage.fetch('new_smp_id') + pl = self._build_provider_location( + new_lun_id, 'smp', base_lun_name) + else: + # snapcopy feature disabled, need to migrate work_flow.add(CreateSnapshotTask(), CreateSMPTask(), AttachSnapTask(), @@ -2964,18 +2960,10 @@ class EMCVnxCliBase(object): self._client.delete_cgsnapshot(snapshot['id']) else: self.delete_snapshot(snapshot) - pl = self._build_provider_location(new_lun_id, 'lun') - volume_metadata['lun_type'] = 'lun' - else: - work_flow.add(CreateSnapshotTask(), - CreateSMPTask(), - AttachSnapTask()) - flow_engine = taskflow.engines.load(work_flow, - store=store_spec) - flow_engine.run() - new_lun_id = flow_engine.storage.fetch('new_smp_id') - pl = self._build_provider_location(new_lun_id, 'smp') - volume_metadata['lun_type'] = 'smp' + # After migration, volume's base lun is itself + pl = self._build_provider_location( + new_lun_id, 'lun', volume['name']) + volume_metadata['snapcopy'] = 'False' model_update = {'provider_location': pl, 'metadata': volume_metadata} @@ -2998,18 +2986,37 @@ class EMCVnxCliBase(object): return volume_metadata return volume['metadata'] if 'metadata' in volume else {} + def _is_snapcopy_enabled(self, volume): + meta = self._get_volume_metadata(volume) + return 'snapcopy' in meta and meta['snapcopy'].lower() == 'true' + + def _get_base_lun_name(self, volume): + """Returns base LUN name for SMP or LUN.""" + base_name = self._extract_provider_location( + volume['provider_location'], 'base_lun_name') + if base_name is None or base_name == 'None': + return volume['name'] + return base_name + def dumps_provider_location(self, pl_dict): return '|'.join([k + '^' + pl_dict[k] for k in pl_dict]) - def _build_provider_location(self, lun_id, type='lun'): - """Builds provider_location for volume or snapshot.""" + def _build_provider_location(self, lun_id, type='lun', base_lun_name=None): + """Builds provider_location for volume or snapshot. + + :param lun_id: LUN ID in VNX + :param type: 'lun' or 'smp' + "param base_lun_name: primary LUN name, + it will be used when creating snap lun + """ pl_dict = {'system': self.get_array_serial(), 'type': type, 'id': six.text_type(lun_id), + 'base_lun_name': six.text_type(base_lun_name), 'version': self.VERSION} return self.dumps_provider_location(pl_dict) - def _extract_provider_location_for_lun(self, provider_location, key='id'): + def _extract_provider_location(self, provider_location, key='id'): """Extracts value of the specified field from provider_location string. :param provider_location: provider_location string @@ -3030,7 +3037,7 @@ class EMCVnxCliBase(object): if group.get('volume_type_id') is not None: for id in group['volume_type_id'].split(","): if id: - provisioning, tiering, snapcopy = ( + provisioning, tiering = ( self._get_extra_spec_value( volume_types.get_volume_type_extra_specs(id))) if provisioning == 'compressed': @@ -3039,12 +3046,6 @@ class EMCVnxCliBase(object): "accept compressed LUNs as members." ) % group['id'] raise exception.VolumeBackendAPIException(data=msg) - if snapcopy == 'true': - msg = _("Failed to create consistency group %s " - "because VNX consistency group cannot " - "enable copytype:snap=True on its members." - ) % group['id'] - raise exception.VolumeBackendAPIException(data=msg) def create_consistencygroup(self, context, group): """Creates a consistency group.""" @@ -3178,7 +3179,7 @@ class EMCVnxCliBase(object): try: provider_location = volume.get('provider_location') if provider_location: - lun_id = self._extract_provider_location_for_lun( + lun_id = self._extract_provider_location( provider_location, 'id') if lun_id: @@ -3778,7 +3779,7 @@ class EMCVnxCliBase(object): tar_pool = vol_utils.extract_host(volume['host'], 'pool') LOG.debug("Target pool of LUN to manage is: %s.", tar_pool) - tar_type, tar_tier, snap_copy = self._get_extra_spec_value(specs) + tar_type, tar_tier = self._get_extra_spec_value(specs) vnx_lun = self._get_lun_pool_and_type(lun_id) LOG.debug("LUN to manage: %s.", vnx_lun) LOG.debug("Target info: pool: %(pool)s, type: %(type)s, " @@ -3819,7 +3820,7 @@ class EMCVnxCliBase(object): else: client.rename_lun(lun_id, volume['name']) - location = self._build_provider_location(lun_id) + location = self._build_provider_location(lun_id, 'lun', volume['name']) return {'provider_location': location} def _get_lun_pool_and_type(self, lun_id): @@ -3910,7 +3911,7 @@ class EMCVnxCliBase(object): 'group': group, 'snapshot': {'id': temp_cgsnapshot_name, 'consistencygroup_id': source_cg.id}, - 'snap_name': temp_cgsnapshot_name, + 'new_snap_name': temp_cgsnapshot_name, 'source_lun_id': None, 'client': self._client } @@ -3935,7 +3936,7 @@ class EMCVnxCliBase(object): store_spec = { 'group': group, 'src_snap_name': cgsnapshot['id'], - 'snap_name': copied_snapshot_name, + 'new_snap_name': copied_snapshot_name, 'client': self._client } @@ -3976,12 +3977,13 @@ class EMCVnxCliBase(object): for i, (volume, src_volume) in enumerate(zip(volumes, source_vols)): specs = self.get_volumetype_extraspecs(volume) - provisioning, tiering, snap_copy = ( + provisioning, tiering = ( self._get_and_validate_extra_specs(specs)) pool_name = self.get_target_storagepool(volume, src_volume) + base_lun_name = self._get_base_lun_name(src_volume) sub_store_spec = { 'volume': volume, - 'source_vol_name': src_volume['name'], + 'base_lun_name': base_lun_name, 'pool_name': pool_name, 'dest_vol_name': volume['name'] + '_dest', 'volume_size': volume['size'], @@ -4041,8 +4043,8 @@ class EMCVnxCliBase(object): provider_location = source_volume.get('provider_location') if (not provider_location or - not self._extract_provider_location_for_lun(provider_location, - 'version')): + not self._extract_provider_location(provider_location, + 'version')): LOG.warning(_LW("The source volume is a legacy volume. " "Create volume in the pool where the source " "volume %s is created."), @@ -4108,9 +4110,9 @@ class CreateSMPTask(task.Task): provides='new_smp_id', inject=inject) - def execute(self, client, volume, source_vol_name, *args, **kwargs): + def execute(self, client, volume, base_lun_name, *args, **kwargs): LOG.debug('CreateSMPTask.execute') - client.create_mount_point(source_vol_name, volume['name']) + client.create_mount_point(base_lun_name, volume['name']) return client.get_lun_by_name(volume['name'])['lun_id'] def revert(self, result, client, volume, *args, **kwargs): @@ -4128,10 +4130,10 @@ class AttachSnapTask(task.Task): Reversion strategy: Detach the SMP. """ - def execute(self, client, volume, snap_name, + def execute(self, client, volume, new_snap_name, *args, **kwargs): LOG.debug('AttachSnapTask.execute') - client.attach_mount_point(volume['name'], snap_name) + client.attach_mount_point(volume['name'], new_snap_name) def revert(self, result, client, volume, *args, **kwargs): LOG.debug('AttachSnapTask.revert') @@ -4260,12 +4262,12 @@ class CopySnapshotTask(task.Task): Reversion Strategy: Delete the copied snapshot/cgsnapshot """ - def execute(self, client, src_snap_name, snap_name, *args, **kwargs): + def execute(self, client, src_snap_name, new_snap_name, *args, **kwargs): LOG.debug('CopySnapshotTask.execute') client.copy_snapshot(src_snap_name, - snap_name) + new_snap_name) - def revert(self, result, client, src_snap_name, snap_name, + def revert(self, result, client, src_snap_name, new_snap_name, *args, **kwargs): LOG.debug('CopySnapshotTask.revert') if isinstance(result, failure.Failure): @@ -4274,16 +4276,16 @@ class CopySnapshotTask(task.Task): LOG.warning(_LW('CopySnapshotTask.revert: delete the ' 'copied snapshot %(new_name)s of ' '%(source_name)s.'), - {'new_name': snap_name, + {'new_name': new_snap_name, 'source_name': src_snap_name}) - client.delete_snapshot(snap_name) + client.delete_snapshot(new_snap_name) class AllowReadWriteOnSnapshotTask(task.Task): """Task to modify a Snapshot to allow ReadWrite on it.""" - def execute(self, client, snap_name, *args, **kwargs): + def execute(self, client, new_snap_name, *args, **kwargs): LOG.debug('AllowReadWriteOnSnapshotTask.execute') - client.allow_snapshot_readwrite_and_autodelete(snap_name) + client.allow_snapshot_readwrite_and_autodelete(new_snap_name) class CreateConsistencyGroupTask(task.Task): -- 2.45.2