Merge "VMAX driver - copy state fix" into stable/newton
This commit is contained in:
commit
ca6e7b4974
|
@ -6200,7 +6200,14 @@ class EMCV3DriverTestCase(test.TestCase):
|
||||||
return_value=self.default_extraspec())
|
return_value=self.default_extraspec())
|
||||||
self.driver.delete_volume(self.data.test_volume_v3)
|
self.driver.delete_volume(self.data.test_volume_v3)
|
||||||
|
|
||||||
@unittest.skip("Skip until bug #1578986 is fixed")
|
@mock.patch.object(
|
||||||
|
emc_vmax_utils.EMCVMAXUtils,
|
||||||
|
'get_v3_default_sg_instance_name',
|
||||||
|
return_value=(None, None, EMCVMAXCommonData.default_sg_instance_name))
|
||||||
|
@mock.patch.object(
|
||||||
|
emc_vmax_utils.EMCVMAXUtils,
|
||||||
|
'is_clone_licensed',
|
||||||
|
return_value=True)
|
||||||
@mock.patch.object(
|
@mock.patch.object(
|
||||||
emc_vmax_common.EMCVMAXCommon,
|
emc_vmax_common.EMCVMAXCommon,
|
||||||
'_get_pool_and_storage_system',
|
'_get_pool_and_storage_system',
|
||||||
|
@ -6210,15 +6217,11 @@ class EMCV3DriverTestCase(test.TestCase):
|
||||||
'get_volume_type_extra_specs',
|
'get_volume_type_extra_specs',
|
||||||
return_value={'volume_backend_name': 'V3_BE'})
|
return_value={'volume_backend_name': 'V3_BE'})
|
||||||
def test_create_snapshot_v3_success(
|
def test_create_snapshot_v3_success(
|
||||||
self, mock_type, mock_pool):
|
self, mock_type, mock_pool, mock_licence, mock_sg):
|
||||||
common = self.driver.common
|
common = self.driver.common
|
||||||
common.provisionv3.utils.get_v3_default_sg_instance_name = mock.Mock(
|
with mock.patch.object(common, '_initial_setup',
|
||||||
return_value=(None, None, self.data.default_sg_instance_name))
|
return_value=self.default_extraspec()):
|
||||||
common.utils.is_clone_licensed = (
|
self.driver.create_snapshot(self.data.test_snapshot_v3)
|
||||||
mock.Mock(return_value=True))
|
|
||||||
common._initial_setup = mock.Mock(
|
|
||||||
return_value=self.default_extraspec())
|
|
||||||
self.driver.create_snapshot(self.data.test_snapshot_v3)
|
|
||||||
|
|
||||||
@mock.patch.object(
|
@mock.patch.object(
|
||||||
volume_types,
|
volume_types,
|
||||||
|
@ -6230,7 +6233,18 @@ class EMCV3DriverTestCase(test.TestCase):
|
||||||
return_value=self.default_extraspec())
|
return_value=self.default_extraspec())
|
||||||
self.driver.delete_snapshot(self.data.test_snapshot_v3)
|
self.driver.delete_snapshot(self.data.test_snapshot_v3)
|
||||||
|
|
||||||
@unittest.skip("Skip until bug #1578986 is fixed")
|
@mock.patch.object(
|
||||||
|
emc_vmax_utils.EMCVMAXUtils,
|
||||||
|
'get_v3_default_sg_instance_name',
|
||||||
|
return_value=(None, None, EMCVMAXCommonData.default_sg_instance_name))
|
||||||
|
@mock.patch.object(
|
||||||
|
emc_vmax_common.EMCVMAXCommon,
|
||||||
|
'_get_or_create_storage_group_v3',
|
||||||
|
return_value=EMCVMAXCommonData.default_sg_instance_name)
|
||||||
|
@mock.patch.object(
|
||||||
|
emc_vmax_utils.EMCVMAXUtils,
|
||||||
|
'is_clone_licensed',
|
||||||
|
return_value=True)
|
||||||
@mock.patch.object(
|
@mock.patch.object(
|
||||||
emc_vmax_utils.EMCVMAXUtils,
|
emc_vmax_utils.EMCVMAXUtils,
|
||||||
'compare_size',
|
'compare_size',
|
||||||
|
@ -6248,8 +6262,11 @@ class EMCV3DriverTestCase(test.TestCase):
|
||||||
'volume_get',
|
'volume_get',
|
||||||
return_value=EMCVMAXCommonData.test_source_volume)
|
return_value=EMCVMAXCommonData.test_source_volume)
|
||||||
def test_create_cloned_volume_v3_success(
|
def test_create_cloned_volume_v3_success(
|
||||||
self, mock_volume_db, mock_type, mock_pool, mock_compare):
|
self, mock_volume_db, mock_type, mock_pool, mock_compare,
|
||||||
self.data.test_volume_v3['volume_name'] = "vmax-1234567"
|
mock_licence, mock_sg, mock_sg_name):
|
||||||
|
sourceVol = self.data.test_volume_v3.copy()
|
||||||
|
sourceVol['volume_name'] = "vmax-1234567"
|
||||||
|
sourceVol['size'] = 100
|
||||||
cloneVol = {}
|
cloneVol = {}
|
||||||
cloneVol['name'] = 'vol1'
|
cloneVol['name'] = 'vol1'
|
||||||
cloneVol['id'] = '10'
|
cloneVol['id'] = '10'
|
||||||
|
@ -6262,17 +6279,16 @@ class EMCV3DriverTestCase(test.TestCase):
|
||||||
cloneVol['NumberOfBlocks'] = 100
|
cloneVol['NumberOfBlocks'] = 100
|
||||||
cloneVol['BlockSize'] = self.data.block_size
|
cloneVol['BlockSize'] = self.data.block_size
|
||||||
cloneVol['host'] = self.data.fake_host_v3
|
cloneVol['host'] = self.data.fake_host_v3
|
||||||
cloneVol['size'] = 1
|
cloneVol['size'] = 100
|
||||||
common = self.driver.common
|
common = self.driver.common
|
||||||
common.utils.is_clone_licensed = (
|
conn = FakeEcomConnection()
|
||||||
mock.Mock(return_value=True))
|
sourceInstance = (
|
||||||
common._initial_setup = mock.Mock(
|
conn.EnumerateInstanceNames("EMC_StorageVolume")[0])
|
||||||
return_value=self.default_extraspec())
|
with mock.patch.object(common, '_initial_setup',
|
||||||
common._get_or_create_storage_group_v3 = mock.Mock(
|
return_value=self.default_extraspec()):
|
||||||
return_value = self.data.default_sg_instance_name)
|
with mock.patch.object(common, '_find_lun',
|
||||||
common.provisionv3.utils.get_v3_default_sg_instance_name = mock.Mock(
|
return_value=sourceInstance):
|
||||||
return_value=(None, None, self.data.default_sg_instance_name))
|
self.driver.create_cloned_volume(cloneVol, sourceVol)
|
||||||
self.driver.create_cloned_volume(cloneVol, self.data.test_volume_v3)
|
|
||||||
|
|
||||||
@mock.patch.object(
|
@mock.patch.object(
|
||||||
emc_vmax_common.EMCVMAXCommon,
|
emc_vmax_common.EMCVMAXCommon,
|
||||||
|
@ -7703,7 +7719,11 @@ class EMCVMAXProvisionV3Test(test.TestCase):
|
||||||
extraSpecs)
|
extraSpecs)
|
||||||
self.assertEqual(self.data.default_sg_instance_name, newstoragegroup)
|
self.assertEqual(self.data.default_sg_instance_name, newstoragegroup)
|
||||||
|
|
||||||
def test_create_element_replica(self):
|
@mock.patch.object(
|
||||||
|
emc_vmax_utils.EMCVMAXUtils,
|
||||||
|
'get_v3_default_sg_instance_name',
|
||||||
|
return_value=(None, None, EMCVMAXCommonData.default_sg_instance_name))
|
||||||
|
def test_create_element_replica(self, mock_sg):
|
||||||
provisionv3 = self.driver.common.provisionv3
|
provisionv3 = self.driver.common.provisionv3
|
||||||
conn = FakeEcomConnection()
|
conn = FakeEcomConnection()
|
||||||
repServiceInstanceName = {
|
repServiceInstanceName = {
|
||||||
|
@ -7718,8 +7738,6 @@ class EMCVMAXProvisionV3Test(test.TestCase):
|
||||||
conn.EnumerateInstanceNames("EMC_StorageVolume")[0])
|
conn.EnumerateInstanceNames("EMC_StorageVolume")[0])
|
||||||
syncType = 7
|
syncType = 7
|
||||||
cloneName = 'new_ss'
|
cloneName = 'new_ss'
|
||||||
provisionv3.utils.get_v3_default_sg_instance_name = mock.Mock(
|
|
||||||
return_value=(None, None, self.data.default_sg_instance_name))
|
|
||||||
rc, job = provisionv3.create_element_replica(
|
rc, job = provisionv3.create_element_replica(
|
||||||
conn, repServiceInstanceName, cloneName, syncType, sourceInstance,
|
conn, repServiceInstanceName, cloneName, syncType, sourceInstance,
|
||||||
extraSpecs)
|
extraSpecs)
|
||||||
|
|
|
@ -3914,6 +3914,7 @@ class EMCVMAXCommon(object):
|
||||||
operation = self.utils.get_num(DISSOLVE_SNAPVX, '16')
|
operation = self.utils.get_num(DISSOLVE_SNAPVX, '16')
|
||||||
rsdInstance = None
|
rsdInstance = None
|
||||||
targetInstance = None
|
targetInstance = None
|
||||||
|
copyState = None
|
||||||
if isSnapshot:
|
if isSnapshot:
|
||||||
rsdInstance = self.utils.set_target_element_supplier_in_rsd(
|
rsdInstance = self.utils.set_target_element_supplier_in_rsd(
|
||||||
self.conn, repServiceInstanceName, SNAPVX_REPLICATION_TYPE,
|
self.conn, repServiceInstanceName, SNAPVX_REPLICATION_TYPE,
|
||||||
|
@ -3921,12 +3922,14 @@ class EMCVMAXCommon(object):
|
||||||
else:
|
else:
|
||||||
targetInstance = self._create_duplicate_volume(
|
targetInstance = self._create_duplicate_volume(
|
||||||
sourceInstance, cloneName, extraSpecs)
|
sourceInstance, cloneName, extraSpecs)
|
||||||
|
copyState = self.utils.get_num(4, '16')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_rc, job = (
|
_rc, job = (
|
||||||
self.provisionv3.create_element_replica(
|
self.provisionv3.create_element_replica(
|
||||||
self.conn, repServiceInstanceName, cloneName, syncType,
|
self.conn, repServiceInstanceName, cloneName, syncType,
|
||||||
sourceInstance, extraSpecs, targetInstance, rsdInstance))
|
sourceInstance, extraSpecs, targetInstance, rsdInstance,
|
||||||
|
copyState))
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.warning(_LW(
|
LOG.warning(_LW(
|
||||||
"Clone failed on V3. Cleaning up the target volume. "
|
"Clone failed on V3. Cleaning up the target volume. "
|
||||||
|
|
|
@ -234,7 +234,7 @@ class EMCVMAXProvisionV3(object):
|
||||||
def create_element_replica(
|
def create_element_replica(
|
||||||
self, conn, repServiceInstanceName,
|
self, conn, repServiceInstanceName,
|
||||||
cloneName, syncType, sourceInstance, extraSpecs,
|
cloneName, syncType, sourceInstance, extraSpecs,
|
||||||
targetInstance=None, rsdInstance=None):
|
targetInstance=None, rsdInstance=None, copyState=None):
|
||||||
"""Make SMI-S call to create replica for source element.
|
"""Make SMI-S call to create replica for source element.
|
||||||
|
|
||||||
:param conn: the connection to the ecom server
|
:param conn: the connection to the ecom server
|
||||||
|
@ -284,7 +284,7 @@ class EMCVMAXProvisionV3(object):
|
||||||
rc, job = self._create_element_replica_extra_params(
|
rc, job = self._create_element_replica_extra_params(
|
||||||
conn, repServiceInstanceName, cloneName, syncType,
|
conn, repServiceInstanceName, cloneName, syncType,
|
||||||
sourceInstance, targetInstance, rsdInstance,
|
sourceInstance, targetInstance, rsdInstance,
|
||||||
sgInstanceName)
|
sgInstanceName, copyState=copyState)
|
||||||
|
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
rc, errordesc = self.utils.wait_for_job_complete(conn, job,
|
rc, errordesc = self.utils.wait_for_job_complete(conn, job,
|
||||||
|
@ -309,7 +309,8 @@ class EMCVMAXProvisionV3(object):
|
||||||
|
|
||||||
def _create_element_replica_extra_params(
|
def _create_element_replica_extra_params(
|
||||||
self, conn, repServiceInstanceName, cloneName, syncType,
|
self, conn, repServiceInstanceName, cloneName, syncType,
|
||||||
sourceInstance, targetInstance, rsdInstance, sgInstanceName):
|
sourceInstance, targetInstance, rsdInstance, sgInstanceName,
|
||||||
|
copyState=None):
|
||||||
"""CreateElementReplica using extra parameters.
|
"""CreateElementReplica using extra parameters.
|
||||||
|
|
||||||
:param conn: the connection to the ecom server
|
:param conn: the connection to the ecom server
|
||||||
|
@ -332,13 +333,6 @@ class EMCVMAXProvisionV3(object):
|
||||||
SourceElement=sourceInstance.path,
|
SourceElement=sourceInstance.path,
|
||||||
TargetElement=targetInstance.path,
|
TargetElement=targetInstance.path,
|
||||||
ReplicationSettingData=rsdInstance)
|
ReplicationSettingData=rsdInstance)
|
||||||
elif targetInstance:
|
|
||||||
rc, job = conn.InvokeMethod(
|
|
||||||
'CreateElementReplica', repServiceInstanceName,
|
|
||||||
ElementName=cloneName,
|
|
||||||
SyncType=syncType,
|
|
||||||
SourceElement=sourceInstance.path,
|
|
||||||
TargetElement=targetInstance.path)
|
|
||||||
elif rsdInstance:
|
elif rsdInstance:
|
||||||
rc, job = conn.InvokeMethod(
|
rc, job = conn.InvokeMethod(
|
||||||
'CreateElementReplica', repServiceInstanceName,
|
'CreateElementReplica', repServiceInstanceName,
|
||||||
|
@ -347,7 +341,21 @@ class EMCVMAXProvisionV3(object):
|
||||||
SourceElement=sourceInstance.path,
|
SourceElement=sourceInstance.path,
|
||||||
ReplicationSettingData=rsdInstance,
|
ReplicationSettingData=rsdInstance,
|
||||||
Collections=[sgInstanceName])
|
Collections=[sgInstanceName])
|
||||||
|
elif targetInstance and copyState:
|
||||||
|
rc, job = conn.InvokeMethod(
|
||||||
|
'CreateElementReplica', repServiceInstanceName,
|
||||||
|
ElementName=cloneName,
|
||||||
|
SyncType=syncType,
|
||||||
|
SourceElement=sourceInstance.path,
|
||||||
|
TargetElement=targetInstance.path,
|
||||||
|
WaitForCopyState=copyState)
|
||||||
|
elif targetInstance:
|
||||||
|
rc, job = conn.InvokeMethod(
|
||||||
|
'CreateElementReplica', repServiceInstanceName,
|
||||||
|
ElementName=cloneName,
|
||||||
|
SyncType=syncType,
|
||||||
|
SourceElement=sourceInstance.path,
|
||||||
|
TargetElement=targetInstance.path)
|
||||||
return rc, job
|
return rc, job
|
||||||
|
|
||||||
def break_replication_relationship(
|
def break_replication_relationship(
|
||||||
|
|
Loading…
Reference in New Issue