]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
EMC VMAX - necessary updates for CG changes
authorHelen Walsh <helen.walsh@emc.com>
Fri, 15 Jan 2016 15:27:11 +0000 (15:27 +0000)
committerHelen Walsh <helen.walsh@emc.com>
Thu, 11 Feb 2016 20:46:02 +0000 (20:46 +0000)
Some of the stubs for the Consistency Group functionality
have changed to remove the db object.  As a consequence the
VMAX implementation for these operations needs to be
changed.

Change-Id: I6c1e56c31e02f25d30689a272f92fafd59e17f70
Closes-Bug: #1534616

cinder/tests/unit/test_emc_vmax.py
cinder/volume/drivers/emc/emc_vmax_common.py
cinder/volume/drivers/emc/emc_vmax_fc.py
cinder/volume/drivers/emc/emc_vmax_iscsi.py
cinder/volume/drivers/emc/emc_vmax_utils.py

index 6c2bd548864d82fafadee1c0daf08358f64218ca..0d059bf31c1ff07bd4f3f5da81b5647af0fac472 100644 (file)
@@ -471,7 +471,8 @@ class EMCVMAXCommonData(object):
                         'id': '12345abcde',
                         'consistencygroup_id': '123456789',
                         'status': 'available',
-                        'snapshots': []
+                        'snapshots': [],
+                        'consistencygroup': test_CG
                         }
     location_info = {'location_info': '000195900551#silver#None',
                      'storage_protocol': 'ISCSI'}
@@ -3627,7 +3628,8 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase):
         utils = self.driver.common.utils
         status = 'status-string'
         volumes = utils.get_volume_model_updates(
-            None, self.driver.db, self.data.test_CG['id'],
+            None, self.driver.db.volume_get_all_by_group("", 5),
+            self.data.test_CG['id'],
             status)
         self.assertEqual(status, volumes[0]['status'])
 
index d29406a781e4217fbfe37bc4025f995048052d83..0ba3cac19a48b08362fb4cd291757a772d1dac29 100644 (file)
@@ -2496,18 +2496,19 @@ class EMCVMAXCommon(object):
                 modelUpdate['status'] = 'error_deleting'
         return volumes, modelUpdate
 
-    def create_cgsnapshot(self, context, cgsnapshot, db):
+    def create_cgsnapshot(self, context, cgsnapshot, snapshots):
         """Creates a cgsnapshot.
 
         :param context: the context
         :param cgsnapshot: the consistency group snapshot to be created
-        :param db: cinder database
+        :param snapshots: snapshots
         :returns: dict -- modelUpdate
         :returns: list -- list of snapshots
         :raises: VolumeBackendAPIException
         """
-        consistencyGroup = db.consistencygroup_get(
-            context, cgsnapshot['consistencygroup_id'])
+        consistencyGroup = cgsnapshot.get('consistencygroup')
+
+        snapshots_model_update = []
 
         LOG.info(_LI(
             "Create snapshot for Consistency Group %(cgId)s "
@@ -2518,8 +2519,6 @@ class EMCVMAXCommon(object):
         cgName = self.utils.truncate_string(
             cgsnapshot['consistencygroup_id'], 8)
 
-        modelUpdate = {'status': 'available'}
-
         volumeTypeId = consistencyGroup['volume_type_id'].replace(",", "")
         extraSpecs = self._initial_setup(None, volumeTypeId)
         self.conn = self._get_ecom_connection()
@@ -2621,41 +2620,39 @@ class EMCVMAXCommon(object):
                                                          extraSpecs)
 
         except Exception:
-            modelUpdate['status'] = 'error'
-            self.utils.populate_cgsnapshot_status(
-                context, db, cgsnapshot['id'], modelUpdate['status'])
             exceptionMessage = (_("Failed to create snapshot for cg:"
                                   " %(cgName)s.")
                                 % {'cgName': cgName})
             LOG.exception(exceptionMessage)
             raise exception.VolumeBackendAPIException(data=exceptionMessage)
 
-        snapshots = self.utils.populate_cgsnapshot_status(
-            context, db, cgsnapshot['id'], modelUpdate['status'])
-        return modelUpdate, snapshots
+        for snapshot in snapshots:
+            snapshots_model_update.append(
+                {'id': snapshot['id'], 'status': 'available'})
+        modelUpdate = {'status': fields.ConsistencyGroupStatus.AVAILABLE}
+
+        return modelUpdate, snapshots_model_update
 
-    def delete_cgsnapshot(self, context, cgsnapshot, db):
+    def delete_cgsnapshot(self, context, cgsnapshot, snapshots):
         """Delete a cgsnapshot.
 
         :param context: the context
         :param cgsnapshot: the consistency group snapshot to be created
-        :param db: cinder database
+        :param snapshots: snapshots
         :returns: dict -- modelUpdate
         :returns: list -- list of snapshots
         :raises: VolumeBackendAPIException
         """
-        consistencyGroup = db.consistencygroup_get(
-            context, cgsnapshot['consistencygroup_id'])
-        snapshots = db.snapshot_get_all_for_cgsnapshot(
-            context, cgsnapshot['id'])
-
+        consistencyGroup = cgsnapshot.get('consistencygroup')
+        model_update = {}
+        snapshots_model_update = []
         LOG.info(_LI(
             "Delete snapshot for source CG %(cgId)s "
             "cgsnapshotID: %(cgsnapshot)s."),
             {'cgsnapshot': cgsnapshot['id'],
              'cgId': cgsnapshot['consistencygroup_id']})
 
-        modelUpdate = {'status': 'deleted'}
+        model_update['status'] = cgsnapshot['status']
         volumeTypeId = consistencyGroup['volume_type_id'].replace(",", "")
         extraSpecs = self._initial_setup(None, volumeTypeId)
         self.conn = self._get_ecom_connection()
@@ -2665,22 +2662,20 @@ class EMCVMAXCommon(object):
 
         try:
             targetCgName = self.utils.truncate_string(cgsnapshot['id'], 8)
-            modelUpdate, snapshots = self._delete_cg_and_members(
-                storageSystem, targetCgName, modelUpdate,
+            model_update, snapshots = self._delete_cg_and_members(
+                storageSystem, targetCgName, model_update,
                 snapshots, extraSpecs)
+            for snapshot in snapshots:
+                snapshots_model_update.append(
+                    {'id': snapshot['id'], 'status': 'deleted'})
         except Exception:
-            modelUpdate['status'] = 'error_deleting'
-            self.utils.populate_cgsnapshot_status(
-                context, db, cgsnapshot['id'], modelUpdate['status'])
             exceptionMessage = (_("Failed to delete snapshot for cg: "
                                   "%(cgId)s.")
                                 % {'cgId': cgsnapshot['consistencygroup_id']})
             LOG.exception(exceptionMessage)
             raise exception.VolumeBackendAPIException(data=exceptionMessage)
 
-        snapshots = self.utils.populate_cgsnapshot_status(
-            context, db, cgsnapshot['id'], modelUpdate['status'])
-        return modelUpdate, snapshots
+        return model_update, snapshots_model_update
 
     def _find_consistency_group(self, replicationService, cgName):
         """Finds a CG given its name.
@@ -4219,7 +4214,8 @@ class EMCVMAXCommon(object):
         return volumeInstanceNames
 
     def create_consistencygroup_from_src(self, context, group, volumes,
-                                         cgsnapshot, snapshots, db):
+                                         cgsnapshot, snapshots, source_cg,
+                                         source_vols):
         """Creates the consistency group from source.
 
         Currently the source can only be a cgsnapshot.
@@ -4229,7 +4225,8 @@ class EMCVMAXCommon(object):
         :param volumes: volumes in the consistency group
         :param cgsnapshot: the source consistency group snapshot
         :param snapshots: snapshots of the source volumes
-        :param db: database
+        :param source_cg: the source consistency group
+        :param source_vols: the source vols
         :returns: model_update, volumes_model_update
                   model_update is a dictionary of cg status
                   volumes_model_update is a list of dictionaries of volume
@@ -4338,21 +4335,16 @@ class EMCVMAXCommon(object):
                     self.provision.delete_clone_relationship(
                         self.conn, replicationService,
                         rgSyncInstanceName, extraSpecs)
-        except Exception as ex:
-            modelUpdate['status'] = 'error'
+        except Exception:
             cgSnapshotId = cgsnapshot['consistencygroup_id']
-            volumes_model_update = self.utils.get_volume_model_updates(
-                context, db, group['id'], modelUpdate['status'])
-            LOG.error(_LE("Exception: %(ex)s."), {'ex': ex})
             exceptionMessage = (_("Failed to create CG %(cgName)s "
                                   "from snapshot %(cgSnapshot)s.")
                                 % {'cgName': targetCgName,
                                    'cgSnapshot': cgSnapshotId})
-            LOG.error(exceptionMessage)
-            return modelUpdate, volumes_model_update
-
+            LOG.exception(exceptionMessage)
+            raise exception.VolumeBackendAPIException(data=exceptionMessage)
         volumes_model_update = self.utils.get_volume_model_updates(
-            context, db, group['id'], modelUpdate['status'])
+            context, volumes, group['id'], modelUpdate['status'])
 
         return modelUpdate, volumes_model_update
 
index 66e6244d42b70ea40ee57f78302bfd91829d4d9d..c6c612593d5600217fc284fff6c62462032e6432 100644 (file)
@@ -56,6 +56,7 @@ class EMCVMAXFCDriver(driver.FibreChannelDriver):
               - Last volume in SG fix
               - _remove_last_vol_and_delete_sg is not being called
                 for VMAX3 (bug #1520549)
+              - necessary updates for CG changes (#1534616)
     """
 
     VERSION = "2.3.0"
@@ -353,11 +354,11 @@ class EMCVMAXFCDriver(driver.FibreChannelDriver):
 
     def create_cgsnapshot(self, context, cgsnapshot, snapshots):
         """Creates a cgsnapshot."""
-        return self.common.create_cgsnapshot(context, cgsnapshot, self.db)
+        return self.common.create_cgsnapshot(context, cgsnapshot, snapshots)
 
     def delete_cgsnapshot(self, context, cgsnapshot, snapshots):
         """Deletes a cgsnapshot."""
-        return self.common.delete_cgsnapshot(context, cgsnapshot, self.db)
+        return self.common.delete_cgsnapshot(context, cgsnapshot, snapshots)
 
     def manage_existing(self, volume, external_ref):
         """Manages an existing VMAX Volume (import to Cinder).
@@ -406,4 +407,5 @@ class EMCVMAXFCDriver(driver.FibreChannelDriver):
         :param source_vols: a list of volume dictionaries in the source_cg.
         """
         return self.common.create_consistencygroup_from_src(
-            context, group, volumes, cgsnapshot, snapshots, self.db)
+            context, group, volumes, cgsnapshot, snapshots, source_cg,
+            source_vols)
index 83c8b8553a4d1c9b3a2867e7451d8ff310ff7dc1..e8edf4737d5218c677bebb9ad7ee610540526703 100644 (file)
@@ -62,6 +62,7 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
               - Last volume in SG fix
               - _remove_last_vol_and_delete_sg is not being called
                 for VMAX3 (bug #1520549)
+              - necessary updates for CG changes (#1534616)
     """
 
     VERSION = "2.3.0"
@@ -350,11 +351,11 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
 
     def create_cgsnapshot(self, context, cgsnapshot, snapshots):
         """Creates a cgsnapshot."""
-        return self.common.create_cgsnapshot(context, cgsnapshot, self.db)
+        return self.common.create_cgsnapshot(context, cgsnapshot, snapshots)
 
     def delete_cgsnapshot(self, context, cgsnapshot, snapshots):
         """Deletes a cgsnapshot."""
-        return self.common.delete_cgsnapshot(context, cgsnapshot, self.db)
+        return self.common.delete_cgsnapshot(context, cgsnapshot, snapshots)
 
     def _check_for_iscsi_ip_address(self):
         """Check to see if iscsi_ip_address is set in cinder.conf
@@ -411,4 +412,5 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
         :param source_vols: a list of volume dictionaries in the source_cg.
         """
         return self.common.create_consistencygroup_from_src(
-            context, group, volumes, cgsnapshot, snapshots, self.db)
+            context, group, volumes, cgsnapshot, snapshots, source_cg,
+            source_vols)
index 217a1d44865438fb7d9cbafa7605bb66ea1a6d85..7144d1d1bf01caf5c78956738bc92d4fc95ae23b 100644 (file)
@@ -1272,28 +1272,6 @@ class EMCVMAXUtils(object):
 
         return foundSyncInstanceName
 
-    def populate_cgsnapshot_status(
-            self, context, db, cgsnapshot_id, status='available'):
-        """Update cgsnapshot status in the cinder database.
-
-        :param context: the context
-        :param db: cinder database
-        :param cgsnapshot_id: cgsnapshot id
-        :param status: string value reflects the status of the member snapshot
-        :returns: snapshots - updated snapshots
-        """
-        snapshots = db.snapshot_get_all_for_cgsnapshot(context, cgsnapshot_id)
-        LOG.info(_LI(
-            "Populating status for cgsnapshot: %(id)s."),
-            {'id': cgsnapshot_id})
-        if snapshots:
-            for snapshot in snapshots:
-                snapshot['status'] = status
-        else:
-            LOG.info(_LI("No snapshot found for %(cgsnapshot)s."),
-                     {'cgsnapshot': cgsnapshot_id})
-        return snapshots
-
     def get_firmware_version(self, conn, arrayName):
         """Get the firmware version of array.
 
@@ -2291,17 +2269,16 @@ class EMCVMAXUtils(object):
         return foundSyncInstanceName
 
     def get_volume_model_updates(
-            self, context, db, cgId, status='available'):
+            self, context, volumes, cgId, status='available'):
         """Update the volume model's status and return it.
 
         :param context: the context
-        :param db: cinder database
+        :param volumes: volumes object api
         :param cgId: cg id
         :param status: string value reflects the status of the member volume
         :returns: volume_model_updates - updated volumes
         """
         volume_model_updates = []
-        volumes = db.volume_get_all_by_group(context, cgId)
         LOG.info(_LI(
             "Updating status for CG: %(id)s."),
             {'id': cgId})