]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Fix SolidFire inaccurate model on migrated vols
authorJohn Griffith <john.griffith8@gmail.com>
Thu, 23 Oct 2014 16:37:11 +0000 (16:37 +0000)
committerJohn Griffith <john.griffith8@gmail.com>
Sun, 26 Oct 2014 14:34:49 +0000 (08:34 -0600)
The general migration impl in Cinder works
by creating a new volume, transfering the data
from the original volume to the new volume, and
then deleting the original and flipping the ID
of the new volume.

Turns out we missed the fact that this creates a
mismatch between the volume Cinder will later ask
for and what the volumes identity is on the backend
device.

This change adds a check on create_volume at the drivers
level to see if it's part of a migration and is infact
going to get renamed.  If so, just use the new name
and avoid all the headaches that come later with updating
provider auth and location.

The model info won't change in this case and is accessible
independent of the ID field in the Cinder base and the
crazy change that's going to take place on that value
in the Cinder DB.

Change-Id: If916df5fd986352ffb20f2dd74552e4d7dad4f60
Closes-Bug: #1381943

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

index a6ee0a5e16a6c8955720c0dd128ec287ec3e322f..36d85220928c957447b64d2c30ea01cdefdcb906 100644 (file)
@@ -634,3 +634,29 @@ class SolidFireVolumeTestCase(test.TestCase):
         model_update = sfv.manage_existing(testvol, external_ref)
         self.assertIsNotNone(model_update)
         self.assertIsNone(model_update.get('provider_geometry', None))
+
+    def test_create_volume_for_migration(self):
+        def _fake_do_v_create(self, project_id, params):
+            return project_id, params
+
+        self.stubs.Set(SolidFireDriver, '_issue_api_request',
+                       self.fake_issue_api_request)
+        self.stubs.Set(SolidFireDriver, '_do_volume_create', _fake_do_v_create)
+
+        testvol = {'project_id': 'testprjid',
+                   'name': 'testvol',
+                   'size': 1,
+                   'id': 'b830b3c0-d1f0-11e1-9b23-1900200c9a77',
+                   'volume_type_id': None,
+                   'created_at': timeutils.utcnow(),
+                   'migration_status': 'target:'
+                                       'a720b3c0-d1f0-11e1-9b23-0800200c9a66'}
+
+        sfv = SolidFireDriver(configuration=self.configuration)
+        proj_id, sf_vol_object = sfv.create_volume(testvol)
+        self.assertEqual('a720b3c0-d1f0-11e1-9b23-0800200c9a66',
+                         sf_vol_object['attributes']['uuid'])
+        self.assertEqual('b830b3c0-d1f0-11e1-9b23-1900200c9a77',
+                         sf_vol_object['attributes']['migration_uuid'])
+        self.assertEqual('UUID-a720b3c0-d1f0-11e1-9b23-0800200c9a66',
+                         sf_vol_object['name'])
index 8d3b15303ff9a60c2eaf9affcb39c30b5f46323d..be56afb7c0ff3d3ea3276d5621974466790a7578 100644 (file)
@@ -519,6 +519,15 @@ class SolidFireDriver(SanISCSIDriver):
                   'attributes': attributes,
                   'qos': qos}
 
+        # NOTE(jdg): Check if we're a migration tgt, if so
+        # use the old volume-id here for the SF Name
+        migration_status = volume.get('migration_status', None)
+        if migration_status and 'target' in migration_status:
+            k, v = migration_status.split(':')
+            params['name'] = 'UUID-%s' % v
+            params['attributes']['migration_uuid'] = volume['id']
+            params['attributes']['uuid'] = v
+
         return self._do_volume_create(volume['project_id'], params)
 
     def create_cloned_volume(self, volume, src_vref):
index 8859807bd8cb1a511f5b9fec73d8e01d263e7675..30d618b2d99351b660e71d846024f92d681077c9 100644 (file)
@@ -1001,6 +1001,11 @@ class VolumeManager(manager.SchedulerDependentManager):
             new_vol_values['volume_type_id'] = new_type_id
         new_vol_values['host'] = host['host']
         new_vol_values['status'] = 'creating'
+
+        # FIXME(jdg): using a : delimeter is confusing to
+        # me below here.  We're adding a string member to a dict
+        # using a :, which is kind of a poor choice in this case
+        # I think
         new_vol_values['migration_status'] = 'target:%s' % volume['id']
         new_vol_values['attach_status'] = 'detached'
         new_volume = self.db.volume_create(ctxt, new_vol_values)