properties = {'ConsumableBlocks': '12345',
'BlockSize': '512'}
+ block_size = 512
test_volume = {'name': 'vol1',
'size': 1,
'volume_name': 'vol1',
'status': 'available',
'host': 'fake-host',
'NumberOfBlocks': 100,
- 'BlockSize': 512
+ 'BlockSize': block_size
}
test_volume_v2 = {'name': 'vol1',
'status': 'available',
'host': 'fake-host',
'NumberOfBlocks': 100,
- 'BlockSize': 512
+ 'BlockSize': block_size
}
test_volume_v3 = {'name': 'vol1',
'status': 'available',
'host': 'fake-host',
'NumberOfBlocks': 100,
- 'BlockSize': 512
+ 'BlockSize': block_size
}
-
+ metaHead_volume = {'DeviceID': 10,
+ 'ConsumableBlocks': 1000
+ }
+ meta_volume1 = {'DeviceID': 11,
+ 'ConsumableBlocks': 200
+ }
+ meta_volume2 = {'DeviceID': 12,
+ 'ConsumableBlocks': 300
+ }
test_volume_CG = {'name': 'volInCG',
'consistencygroup_id': 'abc',
'size': 1,
'storagetype:slo': u'Bronze',
'storagetype:array': u'0123456789',
'isV3': True}
+ majorVersion = 1
+ minorVersion = 2
+ revNumber = 3
class FakeLookupService(object):
Type=None, EMCSRP=None, EMCSLO=None, EMCWorkload=None,
EMCCollections=None, InitiatorMaskingGroup=None,
DeviceMaskingGroup=None, TargetMaskingGroup=None,
- ProtocolController=None, StorageID=None, IDType=None):
+ ProtocolController=None, StorageID=None, IDType=None,
+ WaitForCopyState=None):
rc = 0
myjob = SE_ConcreteJob()
elif TheElements and \
TheElements[0]['DeviceID'] == '99999' and \
- MethodName == 'EMCReturnToStoragePool':
+ MethodName == 'ReturnElementsToStoragePool':
rc = 10
myjob['status'] = 'failure'
elif HardwareId:
rc = 0
ret['HardwareID'] = self.data.iscsi_initiator
return rc, ret
+ elif MethodName == 'GetCompositeElements':
+ ret = {}
+ rc = 0
+ ret['OutElements'] = [self.data.metaHead_volume,
+ self.data.meta_volume1,
+ self.data.meta_volume2]
+ return rc, ret
job = {'Job': myjob}
return rc, job
result = self._enum_repservcpbls()
elif name == 'SE_StorageSynchronized_SV_SV':
result = self._enum_storageSyncSvSv()
+ elif name == 'Symm_SRPStoragePool':
+ result = self._enum_srpstoragepool()
else:
result = self._default_enum()
return result
result = self._enum_pool_details()
elif name == 'SE_StorageHardwareID':
result = self._enum_storhdwids()
+ elif name == 'SE_ManagementServerSoftwareIdentity':
+ result = self._enum_sw_identity()
else:
result = self._default_enum()
return result
def _getinstance_pool(self, objectpath):
pool = {}
pool['CreationClassName'] = 'Symm_VirtualProvisioningPool'
- pool['ElementName'] = 'gold'
+ pool['ElementName'] = self.data.poolname
pool['SystemName'] = self.data.storage_system
pool['TotalManagedSpace'] = self.data.totalmanagedspace_bits
pool['EMCSubscribedCapacity'] = self.data.subscribedcapacity_bits
srpstoragepool = SYMM_SrpStoragePool()
srpstoragepool['CreationClassName'] = (
self.data.srpstoragepool_creationclass)
+ srpstoragepool['ElementName'] = 'SRP_1'
classcimproperty = Fake_CIMProperty()
totalManagedSpace = (
vols.append(failed_vol)
+ volumeHead = EMC_StorageVolume()
+ volumeHead.classname = 'Symm_StorageVolume'
+ blockSize = self.data.block_size
+ volumeHead['ConsumableBlocks'] = (
+ self.data.metaHead_volume['ConsumableBlocks'])
+ volumeHead['BlockSize'] = blockSize
+ volumeHead['DeviceID'] = self.data.metaHead_volume['DeviceID']
+ vols.append(volumeHead)
+
+ metaMember1 = EMC_StorageVolume()
+ metaMember1.classname = 'Symm_StorageVolume'
+ metaMember1['ConsumableBlocks'] = (
+ self.data.meta_volume1['ConsumableBlocks'])
+ metaMember1['BlockSize'] = blockSize
+ metaMember1['DeviceID'] = self.data.meta_volume1['DeviceID']
+ vols.append(metaMember1)
+
+ metaMember2 = EMC_StorageVolume()
+ metaMember2.classname = 'Symm_StorageVolume'
+ metaMember2['ConsumableBlocks'] = (
+ self.data.meta_volume2['ConsumableBlocks'])
+ metaMember2['BlockSize'] = blockSize
+ metaMember2['DeviceID'] = self.data.meta_volume2['DeviceID']
+ vols.append(metaMember2)
+
return vols
def _enum_initiatorMaskingGroup(self):
svInstances.append(svInstance)
return svInstances
+ def _enum_sw_identity(self):
+ swIdentities = []
+ swIdentity = {}
+ swIdentity['MajorVersion'] = self.data.majorVersion
+ swIdentity['MinorVersion'] = self.data.minorVersion
+ swIdentity['RevisionNumber'] = self.data.revNumber
+ swIdentities.append(swIdentity)
+ return swIdentities
+
def _default_enum(self):
names = []
name = {}
self.assertEqual(storageHardwareIDInstanceNames[0],
self.data.iscsi_initiator)
- def test_format_system_name(self):
- v2array = ['SYMMETRIX', '000195900551', 'U', 'gold']
- systemnameV2 = self.driver.utils._format_system_name(v2array[0],
- v2array[1],
- '+')
- self.assertEqual('SYMMETRIX+000195900551', systemnameV2)
-
- v3array = ['SYMMETRIX', '000197200056', 'SRP_1']
- systemnameV3 = self.driver.utils._format_system_name(v3array[0],
- v3array[1],
- '-+-')
- self.assertEqual('SYMMETRIX-+-000197200056', systemnameV3)
+ def test_get_pool_instance_and_system_name(self):
+ conn = self.fake_ecom_connection()
+ # V2 - old '+' separator
+ storagesystem = {}
+ storagesystem['SystemName'] = self.data.storage_system
+ storagesystem['Name'] = self.data.storage_system
+ pools = conn.EnumerateInstanceNames("EMC_VirtualProvisioningPool")
+ poolname = 'gold'
+ poolinstancename, systemname = (
+ self.driver.common.utils._get_pool_instance_and_system_name(
+ conn, pools, storagesystem, poolname))
+ self.assertEqual(self.data.storage_system, systemname)
+ self.assertEqual(self.data.storagepoolid,
+ poolinstancename['InstanceID'])
+ # V3 - note: V2 can also have the '-+-' separator
+ storagesystem = {}
+ storagesystem['SystemName'] = self.data.storage_system_v3
+ storagesystem['Name'] = self.data.storage_system_v3
+ pools = conn.EnumerateInstanceNames('Symm_SRPStoragePool')
+ poolname = 'SRP_1'
+ poolinstancename, systemname = (
+ self.driver.common.utils._get_pool_instance_and_system_name(
+ conn, pools, storagesystem, poolname))
+ self.assertEqual(self.data.storage_system_v3, systemname)
+ self.assertEqual('SYMMETRIX-+-000197200056-+-SRP_1',
+ poolinstancename['InstanceID'])
+ # Invalid poolname
+ poolname = 'bogus'
+ poolinstancename, systemname = (
+ self.driver.common.utils._get_pool_instance_and_system_name(
+ conn, pools, storagesystem, poolname))
+ self.assertIsNone(poolinstancename)
+ self.assertEqual(self.data.storage_system_v3, systemname)
def test_get_hardware_type(self):
iqn_initiator = 'iqn.1992-04.com.emc: 50000973f006dd80'
volume2 = EMC_StorageVolume()
volume2['name'] = 'myVol'
volume2['provider_location'] = six.text_type(provider_location2)
- verify_orig = self.driver.common.utils.get_existing_instance
- self.driver.common.utils.get_existing_instance = mock.Mock(
+ verify_orig = self.driver.common.conn.GetInstance
+ self.driver.common.conn.GetInstance = mock.Mock(
return_value=None)
findlun2 = self.driver.common._find_lun(volume2)
# Not found.
self.assertIsNone(findlun2)
- instancename2 = self.driver.utils.get_instance_name(
+ self.driver.utils.get_instance_name(
provider_location2['classname'],
keybindings2)
- self.driver.common.utils.get_existing_instance.assert_called_once_with(
- self.driver.common.conn, instancename2)
- self.driver.common.utils.get_existing_instance.reset_mock()
- self.driver.common.utils.get_existing_instance = verify_orig
+ self.driver.common.conn.GetInstance.assert_called_once_with(
+ keybindings2)
+ self.driver.common.conn.GetInstance.reset_mock()
+ self.driver.common.conn.GetInstance = verify_orig
keybindings3 = {'CreationClassName': u'Symm_StorageVolume',
'SystemName': u'SYMMETRIX+000195900551',
return_value=(None, EMCVMAXCommonData.storage_system))
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
- 'get_meta_members_capacity_in_bit',
+ 'get_meta_members_capacity_in_byte',
return_value=[1234567, 7654321])
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
- 'get_meta_members_capacity_in_bit',
+ 'get_meta_members_capacity_in_byte',
return_value=[1234567])
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
return_value=(None, EMCVMAXCommonData.storage_system))
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
- 'get_meta_members_capacity_in_bit',
+ 'get_meta_members_capacity_in_byte',
return_value=[1234567, 7654321])
@mock.patch.object(
FakeDB,
return_value=(None, EMCVMAXCommonData.storage_system))
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
- 'get_meta_members_capacity_in_bit',
+ 'get_meta_members_capacity_in_byte',
return_value=[1234567, 7654321])
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
conn, volumeInstance, originalName)
self.assertEqual(originalName, volumeInstance['ElementName'])
+ def test_get_smi_version(self):
+ conn = self.fake_ecom_connection()
+ utils = self.driver.common.utils
+ version = utils.get_smi_version(conn)
+ expected = int(str(self.data.majorVersion)
+ + str(self.data.minorVersion)
+ + str(self.data.revNumber))
+ self.assertEqual(version, expected)
+
+ def test_get_pool_name(self):
+ conn = self.fake_ecom_connection()
+ utils = self.driver.common.utils
+ poolInstanceName = {}
+ poolInstanceName['InstanceID'] = "SATA_GOLD1"
+ poolInstanceName['CreationClassName'] = 'Symm_VirtualProvisioningPool'
+ poolName = utils._get_pool_name(conn, poolInstanceName)
+ self.assertEqual(poolName, self.data.poolname)
+
+ def test_get_meta_members_capacity_in_byte(self):
+ conn = self.fake_ecom_connection()
+ utils = self.driver.common.utils
+ memberVolumeInstanceNames = []
+ volumeHead = EMC_StorageVolume()
+ volumeHead.classname = 'Symm_StorageVolume'
+ blockSize = self.data.block_size
+ volumeHead['ConsumableBlocks'] = (
+ self.data.metaHead_volume['ConsumableBlocks'])
+ volumeHead['BlockSize'] = blockSize
+ volumeHead['DeviceID'] = self.data.metaHead_volume['DeviceID']
+ memberVolumeInstanceNames.append(volumeHead)
+ metaMember1 = EMC_StorageVolume()
+ metaMember1.classname = 'Symm_StorageVolume'
+ metaMember1['ConsumableBlocks'] = (
+ self.data.meta_volume1['ConsumableBlocks'])
+ metaMember1['BlockSize'] = blockSize
+ metaMember1['DeviceID'] = self.data.meta_volume1['DeviceID']
+ memberVolumeInstanceNames.append(metaMember1)
+ metaMember2 = EMC_StorageVolume()
+ metaMember2.classname = 'Symm_StorageVolume'
+ metaMember2['ConsumableBlocks'] = (
+ self.data.meta_volume2['ConsumableBlocks'])
+ metaMember2['BlockSize'] = blockSize
+ metaMember2['DeviceID'] = self.data.meta_volume2['DeviceID']
+ memberVolumeInstanceNames.append(metaMember2)
+ capacities = utils.get_meta_members_capacity_in_byte(
+ conn, memberVolumeInstanceNames)
+ headSize = (
+ volumeHead['ConsumableBlocks'] -
+ metaMember1['ConsumableBlocks'] -
+ metaMember2['ConsumableBlocks'])
+ expected = [headSize * blockSize,
+ metaMember1['ConsumableBlocks'] * blockSize,
+ metaMember2['ConsumableBlocks'] * blockSize]
+ self.assertEqual(capacities, expected)
+
+ def test_get_composite_elements(self):
+ conn = self.fake_ecom_connection()
+ utils = self.driver.common.utils
+ volumeInstanceName = (
+ conn.EnumerateInstanceNames("EMC_StorageVolume")[0])
+ volumeInstance = conn.GetInstance(volumeInstanceName)
+ memberVolumeInstanceNames = utils.get_composite_elements(
+ conn, volumeInstance)
+ expected = [self.data.metaHead_volume,
+ self.data.meta_volume1,
+ self.data.meta_volume2]
+ self.assertEqual(memberVolumeInstanceNames, expected)
+
def _cleanup(self):
if self.config_file_path:
bExists = os.path.exists(self.config_file_path)
return_value=(None, EMCVMAXCommonData.storage_system))
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
- 'get_meta_members_capacity_in_bit',
+ 'get_meta_members_capacity_in_byte',
return_value=[1234567, 7654321])
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
- 'get_meta_members_capacity_in_bit',
+ 'get_meta_members_capacity_in_byte',
return_value=[1234567])
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
return_value=(None, EMCVMAXCommonData.storage_system))
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
- 'get_meta_members_capacity_in_bit',
+ 'get_meta_members_capacity_in_byte',
return_value=[1234567, 7654321])
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
'status': 'available',
'host': self.data.fake_host,
'NumberOfBlocks': 100,
- 'BlockSize': 512
+ 'BlockSize': self.data.block_size
}
common = self.driver.common
common._initial_setup = mock.Mock(
'status': 'available',
'host': self.data.fake_host,
'NumberOfBlocks': 100,
- 'BlockSize': 512
+ 'BlockSize': self.data.block_size
}
common = self.driver.common
common._initial_setup = mock.Mock(
return_value=(None, EMCVMAXCommonData.storage_system))
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
- 'get_meta_members_capacity_in_bit',
+ 'get_meta_members_capacity_in_byte',
return_value=[1234567, 7654321])
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
- 'get_meta_members_capacity_in_bit',
+ 'get_meta_members_capacity_in_byte',
return_value=[1234567])
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
return_value=(None, EMCVMAXCommonData.storage_system))
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
- 'get_meta_members_capacity_in_bit',
+ 'get_meta_members_capacity_in_byte',
return_value=[1234567, 7654321])
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
cloneVol['volume_type_id'] = 'abc'
cloneVol['provider_location'] = None
cloneVol['NumberOfBlocks'] = 100
- cloneVol['BlockSize'] = 512
+ cloneVol['BlockSize'] = self.data.block_size
self.driver.create_cloned_volume(cloneVol, self.data.test_volume)
@mock.patch.object(
MEMBERCOUNT = 'storagetype:membercount'
STRIPED = 'striped'
CONCATENATED = 'concatenated'
+SMI_VERSION_8 = 800
# V3
SLO = 'storagetype:slo'
WORKLOAD = 'storagetype:workload'
if isinstance(loc, six.string_types):
name = eval(loc)
+ keys = name['keybindings']
+ systemName = keys['SystemName']
+
+ prefix1 = 'SYMMETRIX+'
+ prefix2 = 'SYMMETRIX-+-'
+ smiversion = self.utils.get_smi_version(self.conn)
+ if smiversion > SMI_VERSION_8 and prefix1 in systemName:
+ keys['SystemName'] = systemName.replace(prefix1, prefix2)
+ name['keybindings'] = keys
instancename = self.utils.get_instance_name(
name['classname'], name['keybindings'])
-
# Handle the case where volume cannot be found.
- foundVolumeinstance = self.utils.get_existing_instance(
- self.conn, instancename)
+ try:
+ foundVolumeinstance = self.conn.GetInstance(instancename)
+ except Exception:
+ foundVolumeinstance = None
if foundVolumeinstance is None:
LOG.debug("Volume %(volumename)s not found on the array.",
if 'True' in isVolumeBound:
appendVolumeInstance = (
self._unbind_and_get_volume_from_storage_pool(
- conn, storageConfigService, assocPoolInstanceName,
- appendVolumeInstance.path, 'appendVolume', extraSpecs))
+ conn, storageConfigService, appendVolumeInstance.path,
+ 'appendVolume', extraSpecs))
return appendVolumeInstance
return volumeInstance
def _unbind_and_get_volume_from_storage_pool(
- self, conn, storageConfigService, poolInstanceName,
- volumeInstanceName, volumeName, extraSpecs):
+ self, conn, storageConfigService, volumeInstanceName,
+ volumeName, extraSpecs):
"""Unbind a volume from a pool and return the unbound volume.
:param conn: the connection information to the ecom server
:param storageConfigService: the storage config service instance name
- :param poolInstanceName: the pool instance name
:param volumeInstanceName: the volume instance name
:param volumeName: string the volumeName
:param extraSpecs: extra specifications
:returns: unboundVolumeInstance -- the unbound volume instance
"""
- _rc, job = (
+ rc, job = (
self.provision.unbind_volume_from_storage_pool(
- conn, storageConfigService, poolInstanceName,
- volumeInstanceName,
+ conn, storageConfigService, volumeInstanceName,
volumeName, extraSpecs))
- volumeDict = self.provision.get_volume_dict_from_job(conn, job['Job'])
- volumeInstance = self.utils.find_volume_instance(
- self.conn, volumeDict, volumeName)
+ # Check that the volume is unbound
+ volumeInstance = conn.GetInstance(volumeInstanceName)
+ isVolumeBound = self.utils.is_volume_bound_to_pool(
+ conn, volumeInstance)
+ if 'False' not in isVolumeBound:
+ exceptionMessage = (_(
+ "Failed to unbind volume: %(volume)s")
+ % {'volume': volumeInstanceName})
+ LOG.error(exceptionMessage)
+ raise exception.VolumeBackendAPIException(data=exceptionMessage)
+
return volumeInstance
def _modify_and_get_composite_volume_instance(
controllerConfigurationService,
volumeInstance.path, volumeName, extraSpecs)
- LOG.debug("Delete Volume: %(name)s Method: EMCReturnToStoragePool "
- "ConfigService: %(service)s TheElement: %(vol_instance)s "
- "DeviceId: %(deviceId)s.",
- {'service': storageConfigService,
- 'name': volumeName,
- 'vol_instance': volumeInstance.path,
+ LOG.debug("Deleting Volume: %(name)s with deviceId: %(deviceId)s.",
+ {'name': volumeName,
'deviceId': deviceId})
try:
rc = self.provision.delete_volume_from_pool(
else: # Composite volume with meta device members.
# Check if the meta members capacity.
metaMemberInstanceNames = (
- self.utils.get_meta_members_of_composite_volume(
- self.conn, metaHeadInstanceName))
- volumeCapacities = self.utils.get_meta_members_capacity_in_bit(
+ self.utils.get_composite_elements(
+ self.conn, sourceInstance))
+ volumeCapacities = self.utils.get_meta_members_capacity_in_byte(
self.conn, metaMemberInstanceNames)
LOG.debug("Volume capacities: %(metasizes)s.",
{'metasizes': volumeCapacities})
2.1.2 - Clean up failed clones (bug #1440154)
2.1.3 - Fixed a problem with FAST support (bug #1435069)
2.2.0 - Add manage/unmanage
+ 2.2.1 - Support for SE 8.0.3
"""
- VERSION = "2.2.0"
+ VERSION = "2.2.1"
def __init__(self, *args, **kwargs):
# under the License.
import base64
+import httplib
import os
import socket
import ssl
import string
import struct
+import urllib
from eventlet import patcher
import OpenSSL
from oslo_log import log as logging
import six
-from six.moves import http_client
-from six.moves import urllib
from cinder.i18n import _, _LI
class OpenSSLConnectionDelegator(object):
"""An OpenSSL.SSL.Connection delegator.
- Supplies an additional 'makefile' method which http_client requires
+ Supplies an additional 'makefile' method which httplib requires
and is not present in OpenSSL.SSL.Connection.
Note: Since it is not possible to inherit from OpenSSL.SSL.Connection
a delegator must be used.
return socket._fileobject(self.connection, *args, **kwargs)
-class HTTPSConnection(http_client.HTTPSConnection):
+class HTTPSConnection(httplib.HTTPSConnection):
def __init__(self, host, port=None, key_file=None, cert_file=None,
strict=None, ca_certs=None, no_verification=False):
if not pywbemAvailable:
else:
excp_lst = ()
try:
- http_client.HTTPSConnection.__init__(self, host, port,
- key_file=key_file,
- cert_file=cert_file)
+ httplib.HTTPSConnection.__init__(self, host, port,
+ key_file=key_file,
+ cert_file=cert_file)
self.key_file = None if key_file is None else key_file
self.cert_file = None if cert_file is None else cert_file
"""Send request over HTTP.
Send XML data over HTTP to the specified url. Return the
- response in XML. Uses Python's build-in http_client. x509 may be a
+ response in XML. Uses Python's build-in httplib. x509 may be a
dictionary containing the location of the SSL certificate and key
files.
"""
localAuthHeader = None
tryLimit = 5
- if isinstance(data, six.text_type):
+ if isinstance(data, unicode):
data = data.encode('utf-8')
data = '<?xml version="1.0" encoding="utf-8" ?>\n' + data
h.putheader('PegasusAuthorization', 'Local "%s"' % locallogin)
for hdr in headers:
- if isinstance(hdr, six.text_type):
+ if isinstance(hdr, unicode):
hdr = hdr.encode('utf-8')
s = map(lambda x: string.strip(x), string.split(hdr, ":", 1))
- h.putheader(urllib.parse.quote(s[0]), urllib.parse.quote(s[1]))
+ h.putheader(urllib.quote(s[0]), urllib.quote(s[1]))
try:
h.endheaders()
if response.status != 200:
raise pywbem.cim_http.Error('HTTP error')
- except http_client.BadStatusLine as arg:
+ except httplib.BadStatusLine as arg:
msg = (_("Bad Status line returned: %(arg)s.")
% {'arg': arg})
raise pywbem.cim_http.Error(msg)
2.1.2 - Clean up failed clones (bug #1440154)
2.1.3 - Fixed a problem with FAST support (bug #1435069)
2.2.0 - Add manage/unmanage
+ 2.2.1 - Support for SE 8.0.3
"""
- VERSION = "2.2.0"
+ VERSION = "2.2.1"
def __init__(self, *args, **kwargs):
theElements = [volumeInstanceName]
rc, job = conn.InvokeMethod(
- 'EMCReturnToStoragePool', storageConfigservice,
+ 'ReturnElementsToStoragePool', storageConfigservice,
TheElements=theElements)
if rc != 0:
time.time())})
def unbind_volume_from_storage_pool(
- self, conn, storageConfigService, poolInstanceName,
- volumeInstanceName, volumeName, extraSpecs):
+ self, conn, storageConfigService, volumeInstanceName,
+ volumeName, extraSpecs):
"""Unbind a volume from a pool and return the unbound volume.
:param conn: the connection information to the ecom server
:param storageConfigService: the storage configuration service
instance name
- :param poolInstanceName: the pool instance name
:param volumeInstanceName: the volume instance name
:param volumeName: the volume name
:param extraSpecs: additional info
rc, job = conn.InvokeMethod(
'EMCUnBindElement',
storageConfigService,
- InPool=poolInstanceName,
TheElement=volumeInstanceName)
if rc != 0:
'relationName': relationName,
'srcGroup': srcGroupInstanceName,
'tgtGroup': tgtGroupInstanceName})
- # 8 for clone.
+ # SyncType 8 - clone.
+ # CopyState 4 - Synchronized.
rc, job = conn.InvokeMethod(
'CreateGroupReplica',
replicationService,
RelationshipName=relationName,
SourceGroup=srcGroupInstanceName,
TargetGroup=tgtGroupInstanceName,
- SyncType=self.utils.get_num(8, '16'))
+ SyncType=self.utils.get_num(8, '16'),
+ WaitForCopyState=self.utils.get_num(4, '16'))
if rc != 0:
rc, errordesc = self.utils.wait_for_job_complete(conn, job,
LOG.debug(
"storagePoolName: %(poolName)s, storageSystemName: %(array)s.",
{'poolName': storagePoolName, 'array': storageSystemName})
- poolInstanceNames = conn.EnumerateInstanceNames(
- 'EMC_VirtualProvisioningPool')
+ storageSystemInstanceName = self.find_storageSystem(conn,
+ storageSystemName)
+ poolInstanceNames = conn.AssociatorNames(
+ storageSystemInstanceName,
+ ResultClass='EMC_VirtualProvisioningPool')
for poolInstanceName in poolInstanceNames:
- poolName, systemName = (
- self.parse_pool_instance_id(poolInstanceName['InstanceID']))
- if (poolName == storagePoolName and
- storageSystemName in systemName):
+ poolName = self._get_pool_name(conn, poolInstanceName)
+ if (poolName == storagePoolName):
# Check that the pool hasn't been recently deleted.
instance = self.get_existing_instance(conn, poolInstanceName)
if instance is None:
:returns: foundPoolInstanceName
:returns: string -- systemNameStr
"""
- foundPoolInstanceName = None
vpoolInstanceNames = conn.AssociatorNames(
storageSystemInstanceName,
ResultClass='EMC_VirtualProvisioningPool')
- for vpoolInstanceName in vpoolInstanceNames:
- poolInstanceId = vpoolInstanceName['InstanceID']
- # Example: SYMMETRIX+000195900551+TP+Sol_Innov
- poolnameStr, systemNameStr = self.parse_pool_instance_id(
- poolInstanceId)
- if poolnameStr is not None and systemNameStr is not None:
- if six.text_type(poolNameInStr) == six.text_type(poolnameStr):
- # check that the pool hasn't recently been deleted.
- try:
- conn.GetInstance(vpoolInstanceName)
- foundPoolInstanceName = vpoolInstanceName
- except Exception:
- foundPoolInstanceName = None
- break
-
- return foundPoolInstanceName, systemNameStr
+ return self._get_pool_instance_and_system_name(
+ conn, vpoolInstanceNames, storageSystemInstanceName,
+ poolNameInStr)
def get_pool_and_system_name_v3(
self, conn, storageSystemInstanceName, poolNameInStr):
:returns: foundPoolInstanceName
:returns: string -- systemNameStr
"""
- foundPoolInstanceName = None
srpPoolInstanceNames = conn.AssociatorNames(
storageSystemInstanceName,
ResultClass='Symm_SRPStoragePool')
- for srpPoolInstanceName in srpPoolInstanceNames:
- poolInstanceID = srpPoolInstanceName['InstanceID']
+ return self._get_pool_instance_and_system_name(
+ conn, srpPoolInstanceNames, storageSystemInstanceName,
+ poolNameInStr)
+
+ def _get_pool_instance_and_system_name(
+ self, conn, poolInstanceNames, storageSystemInstanceName,
+ poolname):
+ """Get the pool instance and the system name
+
+ :param conn: the ecom connection
+ :param poolInstanceNames: list of pool instances
+ :param storageSystemInstanceName: storage system instance name
+ :param poolname: pool name (string)
+ :returns: foundPoolInstanceName, systemNameStr
+ """
+ foundPoolInstanceName = None
+ poolnameStr = None
+ systemNameStr = storageSystemInstanceName['Name']
+ for poolInstanceName in poolInstanceNames:
# Example: SYMMETRIX-+-000196700535-+-SR-+-SRP_1
- poolnameStr, systemNameStr = self.parse_pool_instance_id_v3(
- poolInstanceID)
- if poolnameStr is not None and systemNameStr is not None:
- if six.text_type(poolNameInStr) == six.text_type(poolnameStr):
- try:
- conn.GetInstance(srpPoolInstanceName)
- foundPoolInstanceName = srpPoolInstanceName
- except Exception:
- foundPoolInstanceName = None
+ # Example: SYMMETRIX+000195900551+TP+Sol_Innov
+ poolnameStr = self._get_pool_name(conn, poolInstanceName)
+ if poolnameStr is not None:
+ if six.text_type(poolname) == six.text_type(poolnameStr):
+ foundPoolInstanceName = poolInstanceName
break
return foundPoolInstanceName, systemNameStr
+ def _get_pool_name(self, conn, poolInstanceName):
+ """The pool name from the instance
+
+ :param conn: the ecom connection
+ :param poolInstanceName: the pool instance
+ :returns: poolnameStr
+ """
+ poolnameStr = None
+ try:
+ poolInstance = conn.GetInstance(poolInstanceName)
+ poolnameStr = poolInstance['ElementName']
+ except Exception:
+ pass
+ return poolnameStr
+
def find_storageSystem(self, conn, arrayStr):
"""Find an array instance name given the array name.
LOG.debug("metaMembers: %(members)s.", {'members': metaMembers})
return metaMembers
- def get_meta_members_capacity_in_bit(self, conn, volumeInstanceNames):
- """Get the capacity in bits of all meta device member volumes.
+ def get_meta_members_capacity_in_byte(self, conn, volumeInstanceNames):
+ """Get the capacity in byte of all meta device member volumes.
:param conn: the ecom connection
:param volumeInstanceNames: array contains meta device member volumes
:returns: array contains capacities of each member device in bits
"""
- capacitiesInBit = []
+ capacitiesInByte = []
+ headVolume = conn.GetInstance(volumeInstanceNames[0])
+ totalSizeInByte = (
+ headVolume['ConsumableBlocks'] * headVolume['BlockSize'])
+ volumeInstanceNames.pop(0)
for volumeInstanceName in volumeInstanceNames:
volumeInstance = conn.GetInstance(volumeInstanceName)
numOfBlocks = volumeInstance['ConsumableBlocks']
blockSize = volumeInstance['BlockSize']
- volumeSizeInbits = numOfBlocks * blockSize
- capacitiesInBit.append(volumeSizeInbits)
- return capacitiesInBit
+ volumeSizeInByte = numOfBlocks * blockSize
+ capacitiesInByte.append(volumeSizeInByte)
+ totalSizeInByte = totalSizeInByte - volumeSizeInByte
+
+ capacitiesInByte.insert(0, totalSizeInByte)
+ return capacitiesInByte
def get_existing_instance(self, conn, instanceName):
"""Check that the instance name still exists and return the instance.
{'source': sourceDeviceId, 'storageSystem': storageSystem})
return foundSyncInstanceName
+
+ def get_smi_version(self, conn):
+ intVersion = 0
+ swIndentityInstances = conn.EnumerateInstances(
+ 'SE_ManagementServerSoftwareIdentity')
+ if swIndentityInstances:
+ swIndentityInstance = swIndentityInstances[0]
+ majorVersion = swIndentityInstance['MajorVersion']
+ minorVersion = swIndentityInstance['MinorVersion']
+ revisionNumber = swIndentityInstance['RevisionNumber']
+
+ intVersion = int(str(majorVersion) + str(minorVersion)
+ + str(revisionNumber))
+
+ LOG.debug("Major version: %(majV)lu, Minor version: %(minV)lu, "
+ "Revision number: %(revNum)lu, Version: %(intV)lu.",
+ {'majV': majorVersion,
+ 'minV': minorVersion,
+ 'revNum': revisionNumber,
+ 'intV': intVersion})
+ return intVersion
+
+ def get_composite_elements(
+ self, conn, volumeInstance):
+ """Get the meta members of a composite volume.
+
+ :param conn: ECOM connection
+ :param volumeInstance: the volume instance
+ :returns memberVolumes: a list of meta members
+ """
+ memberVolumes = None
+ storageSystemName = volumeInstance['SystemName']
+ elementCompositionService = self.find_element_composition_service(
+ conn, storageSystemName)
+ rc, ret = conn.InvokeMethod(
+ 'GetCompositeElements',
+ elementCompositionService,
+ TheElement=volumeInstance.path)
+
+ if 'OutElements' in ret:
+ LOG.debug("Get composite elements of volume "
+ "%(volume)s rc=%(rc)d, ret=%(ret)s",
+ {'volume': volumeInstance.path, 'rc': rc, 'ret': ret})
+ memberVolumes = ret['OutElements']
+ return memberVolumes