]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Get updated model info on volume transfer
authorJohn Griffith <john.griffith8@gmail.com>
Mon, 28 Jul 2014 17:35:54 +0000 (11:35 -0600)
committerJay S. Bryant <jsbryant@us.ibm.com>
Mon, 28 Jul 2014 23:04:09 +0000 (18:04 -0500)
On some drivers CHAP credentials are tied to accounts
which may be unique for each OS and/or backend Tenant.

For example:
  Volume is created with project_id xyz
  Backend creates an account for xyz with specific CHAP

  Volume is transferred to project_id abc

Currently we don't update the model_info, so even though
on the backend we updated the owner and CHAP settings we
never propogated that back up to the DB object so the volume
can't be used by the new owner.

This patch just adds an option to return model_update
on the accept_transfer call to the driver and updates
the db accordingly.

Also adds a call in the SF driver to actually get the
new model info to be fed back to the manager.

Change-Id: Ie0447cdad69c4fbee99b4b6b1d3cacdfdd14137d
Closes-Bug: #1349475

cinder/volume/drivers/solidfire.py
cinder/volume/manager.py

index ecec15ab8ed244a2d1b3d977a67a2568cbf54f75..64c16e29ec62065299b7dcb8203cd6c707d8fa50 100644 (file)
@@ -416,7 +416,7 @@ class SolidFireDriver(SanISCSIDriver):
         qos = {}
         valid_presets = self.sf_qos_dict.keys()
 
-        #First look to see if they included a preset
+        # First look to see if they included a preset
         presets = [i.value for i in volume.get('volume_metadata')
                    if i.key == 'sf-qos' and i.value in valid_presets]
         if len(presets) > 0:
@@ -425,7 +425,7 @@ class SolidFireDriver(SanISCSIDriver):
                               'detected, using %s') % presets[0])
             qos = self.sf_qos_dict[presets[0]]
         else:
-            #look for explicit settings
+            # look for explicit settings
             for i in volume.get('volume_metadata'):
                 if i.key in self.sf_qos_keys:
                     qos[i.key] = int(i.value)
@@ -770,7 +770,11 @@ class SolidFireDriver(SanISCSIDriver):
         if 'result' not in data:
             raise exception.SolidFireAPIDataException(data=data)
 
+        volume['project_id': new_project]
+        volume['user_id': new_user]
+        model_update = self._do_export(volume)
         LOG.debug("Leaving SolidFire transfer volume")
+        return model_update
 
     def retype(self, ctxt, volume, new_type, diff, host):
         """Convert the volume to be of the new type.
index 3719c7262549dbb345d1e5a93ad866724d7c6a06..1f4433dcfb4c5361a8f250090b45ee116db0e5fb 100644 (file)
@@ -880,7 +880,30 @@ class VolumeManager(manager.SchedulerDependentManager):
         # NOTE(jdg): need elevated context as we haven't "given" the vol
         # yet
         volume_ref = self.db.volume_get(context.elevated(), volume_id)
-        self.driver.accept_transfer(context, volume_ref, new_user, new_project)
+
+        # NOTE(jdg): Some drivers tie provider info (CHAP) to tenant
+        # for those that do allow them to return updated model info
+        model_update = self.driver.accept_transfer(context,
+                                                   volume_ref,
+                                                   new_user,
+                                                   new_project)
+
+        if model_update:
+            try:
+                self.db.volume_update(context,
+                                      volume_id,
+                                      model_update)
+            except exception.CinderException:
+                with excutils.save_and_reraise_exception():
+                    LOG.exception(_("Failed updating model of "
+                                    "volume %(volume_id)s "
+                                    "with drivers update %(model)s "
+                                    "during xfr.") %
+                                  {'volume_id': volume_id,
+                                   'model': model_update})
+                    self.db.volume_update(context.elevated(),
+                                          volume_id,
+                                          {'status': 'error'})
 
     def _migrate_volume_generic(self, ctxt, volume, host, new_type_id):
         rpcapi = volume_rpcapi.VolumeAPI()