]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add 'source-id' and 'source-name' support in VNX driver
authorpeter_wang <peter.wang13@emc.com>
Fri, 29 May 2015 00:38:56 +0000 (20:38 -0400)
committerpeter_wang <peter.wang13@emc.com>
Sun, 7 Jun 2015 21:47:04 +0000 (17:47 -0400)
Currently, VNX driver only supports 'id' as the id-type in manage/unmanage volume.
With release of new version python-cinderclient, 'source-id' and 'source-name' are
preferred id-type when using cinder manage.

This fix is to add 'source-id' and 'source-name' support
and obsolete the self-defined 'id' support.

Change-Id: Ia0619123ff56e44da98c4f12c554474c8fe6093c
closes-bug: 1450280

cinder/tests/unit/test_emc_vnxdirect.py
cinder/volume/drivers/emc/emc_cli_fc.py
cinder/volume/drivers/emc/emc_cli_iscsi.py
cinder/volume/drivers/emc/emc_vnx_cli.py

index 0ef8a53838002a7682744f529ddad047ff728674..2edfa4302bc1a4986de964b6f39277b5592083a7 100644 (file)
@@ -363,7 +363,8 @@ class EMCVNXCLIDriverTestData(object):
     }
 
     test_lun_id = 1
-    test_existing_ref = {'id': test_lun_id}
+    test_existing_ref = {'source-id': test_lun_id}
+    test_existing_ref_source_name = {'source-name': 'vol1'}
     test_pool_name = 'unit_test_pool'
     device_map = {
         '1122334455667788': {
@@ -2389,23 +2390,39 @@ Time Remaining:  0 second(s)
         commands = [lun_rename_cmd]
 
         results = [SUCCEED]
+        self.configuration.storage_vnx_pool_name = \
+            self.testData.test_pool_name
         fake_cli = self.driverSetup(commands, results)
-        self.driver.cli._client.command_execute = fake_cli
         self.driver.manage_existing(
             self.testData.test_volume_with_type,
             self.testData.test_existing_ref)
         expected = [mock.call(*lun_rename_cmd, poll=False)]
         fake_cli.assert_has_calls(expected)
 
+    def test_manage_existing_source_name(self):
+        lun_rename_cmd = ('lun', '-modify', '-l', self.testData.test_lun_id,
+                          '-newName', 'vol_with_type', '-o')
+        commands = [lun_rename_cmd]
+
+        results = [SUCCEED]
+        fake_cli = self.driverSetup(commands, results)
+        self.driver.manage_existing(
+            self.testData.test_volume_with_type,
+            self.testData.test_existing_ref_source_name)
+        expected = [mock.call(*lun_rename_cmd, poll=False)]
+        fake_cli.assert_has_calls(expected)
+
     def test_manage_existing_lun_in_another_pool(self):
         get_lun_cmd = ('lun', '-list', '-l', self.testData.test_lun_id,
                        '-state', '-userCap', '-owner',
                        '-attachedSnapshot', '-poolName')
-        commands = [get_lun_cmd]
         invalid_pool_name = "fake_pool"
+        commands = [get_lun_cmd]
         results = [self.testData.LUN_PROPERTY('lun_name',
                                               pool_name=invalid_pool_name)]
+        self.configuration.storage_vnx_pool_name = invalid_pool_name
         fake_cli = self.driverSetup(commands, results)
+        # mock the command executor
         ex = self.assertRaises(
             exception.ManageExistingInvalidReference,
             self.driver.manage_existing_get_size,
@@ -2424,7 +2441,11 @@ Time Remaining:  0 second(s)
         test_size = 2
         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
         fake_cli = self.driverSetup(commands, results)
+
         get_size = self.driver.manage_existing_get_size(
             self.testData.test_volume_with_type,
             self.testData.test_existing_ref)
index 88ebda3e166c4dbed76e1a191804aa88b69d8208..3a4e3975266d3fa59f95cb2a3f5698527ee30960 100644 (file)
@@ -57,6 +57,7 @@ class EMCCLIFCDriver(driver.FibreChannelDriver):
         6.0.0 - Over subscription support
                 Create consistency group from cgsnapshot support
                 Multiple pools support enhancement
+                Manage/unmanage volume revise
     """
 
     def __init__(self, *args, **kwargs):
@@ -210,11 +211,14 @@ class EMCCLIFCDriver(driver.FibreChannelDriver):
         volume['name'] which is how drivers traditionally map between a
         cinder volume and the associated backend storage object.
 
-        existing_ref:{
-            'id':lun_id
+        manage_existing_ref:{
+            'source-id':<lun id in VNX>
+        }
+        or
+        manage_existing_ref:{
+            'source-name':<lun name in VNX>
         }
         """
-        LOG.debug("Reference lun id %s.", existing_ref['id'])
         self.cli.manage_existing(volume, existing_ref)
 
     def manage_existing_get_size(self, volume, existing_ref):
index 909d495b8686e686c1fe24057572b9e1e614fad6..464c8db95926e7b4db7df61484c4084f13ba9bfb 100644 (file)
@@ -55,6 +55,7 @@ class EMCCLIISCSIDriver(driver.ISCSIDriver):
         6.0.0 - Over subscription support
                 Create consistency group from cgsnapshot support
                 Multiple pools support enhancement
+                Manage/unmanage volume revise
     """
 
     def __init__(self, *args, **kwargs):
@@ -189,11 +190,14 @@ class EMCCLIISCSIDriver(driver.ISCSIDriver):
         volume['name'] which is how drivers traditionally map between a
         cinder volume and the associated backend storage object.
 
-        existing_ref:{
-            'id':lun_id
+        manage_existing_ref:{
+            'source-id':<lun id in VNX>
+        }
+        or
+        manage_existing_ref:{
+            'source-name':<lun name in VNX>
         }
         """
-        LOG.debug("Reference lun id %s.", existing_ref['id'])
         self.cli.manage_existing(volume, existing_ref)
 
     def manage_existing_get_size(self, volume, existing_ref):
index 2f98454e9d7796acf40815b46c7d92224c657b2f..88dfa60e7b7b1184ed998f55628e2480dfc502c8 100644 (file)
@@ -565,15 +565,11 @@ class CommandLineHelper(object):
 
         self._wait_for_a_condition(lun_is_extented)
 
-    def lun_rename(self, lun_id, new_name, poll=False):
-        """This function used to rename a lun to match
-        the expected name for the volume.
-        """
+    def rename_lun(self, lun_id, new_name, poll=False):
         command_lun_rename = ('lun', '-modify',
                               '-l', lun_id,
                               '-newName', new_name,
                               '-o')
-
         out, rc = self.command_execute(*command_lun_rename,
                                        poll=poll)
         if rc != 0:
@@ -2974,52 +2970,54 @@ class EMCVnxCliBase(object):
             return conn_info
         return do_terminate_connection()
 
-    def manage_existing_get_size(self, volume, ref):
+    def manage_existing_get_size(self, volume, existing_ref):
         """Returns size of volume to be managed by manage_existing."""
-
-        # Check that the reference is valid
-        if 'id' not in ref:
-            reason = _('Reference must contain lun_id element.')
+        if 'source-id' in existing_ref:
+            data = self._client.get_lun_by_id(
+                existing_ref['source-id'],
+                properties=self._client.LUN_WITH_POOL)
+        elif 'source-name' in existing_ref:
+            data = self._client.get_lun_by_name(
+                existing_ref['source-name'],
+                properties=self._client.LUN_WITH_POOL)
+        else:
+            reason = _('Reference must contain source-id or source-name key.')
             raise exception.ManageExistingInvalidReference(
-                existing_ref=ref,
-                reason=reason)
-
-        # Check for existence of the lun
-        data = self._client.get_lun_by_id(
-            ref['id'],
-            properties=self._client.LUN_WITH_POOL)
-        if data is None:
-            reason = _('Find no lun with the specified id %s.') % ref['id']
-            raise exception.ManageExistingInvalidReference(existing_ref=ref,
-                                                           reason=reason)
-
-        pool = self.get_target_storagepool(volume, None)
-        if pool and data['pool'] != pool:
-            reason = (_('The input lun %(lun_id)s is in pool %(poolname)s '
+                existing_ref=existing_ref, reason=reason)
+        target_pool = self.get_target_storagepool(volume)
+        if target_pool and data['pool'] != target_pool:
+            reason = (_('The imported lun %(lun_id)s is in pool %(lun_pool)s '
                         'which is not managed by the host %(host)s.')
-                      % {'lun_id': ref['id'],
-                         'poolname': data['pool'],
+                      % {'lun_id': data['lun_id'],
+                         'lun_pool': data['pool'],
                          'host': volume['host']})
-            raise exception.ManageExistingInvalidReference(existing_ref=ref,
-                                                           reason=reason)
+            raise exception.ManageExistingInvalidReference(
+                existing_ref=existing_ref, reason=reason)
         return data['total_capacity_gb']
 
-    def manage_existing(self, volume, ref):
+    def manage_existing(self, volume, manage_existing_ref):
         """Imports the existing backend storage object as a volume.
 
-        Renames the backend storage object so that it matches the,
-        volume['name'] which is how drivers traditionally map between a
-        cinder volume and the associated backend storage object.
-
-        existing_ref:{
-            'id':lun_id
+        manage_existing_ref:{
+            'source-id':<lun id in VNX>
+        }
+        or
+        manage_existing_ref:{
+            'source-name':<lun name in VNX>
         }
         """
-
-        self._client.lun_rename(ref['id'], volume['name'])
+        if 'source-id' in manage_existing_ref:
+            lun_id = manage_existing_ref['source-id']
+        elif 'source-name' in manage_existing_ref:
+            lun_id = self._client.get_lun_by_name(
+                manage_existing_ref['source-name'], poll=False)['lun_id']
+        else:
+            reason = _('Reference must contain source-id or source-name key.')
+            raise exception.ManageExistingInvalidReference(
+                existing_ref=manage_existing_ref, reason=reason)
+        self._client.rename_lun(lun_id, volume['name'])
         model_update = {'provider_location':
-                        self._build_provider_location_for_lun(ref['id'])}
-
+                        self._build_provider_location_for_lun(lun_id)}
         return model_update
 
     def get_login_ports(self, connector):