]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Fix Pure create volume from cgsnapshot
authorPatrick East <patrick.east@purestorage.com>
Wed, 12 Aug 2015 00:55:22 +0000 (17:55 -0700)
committerPatrick East <patrick.east@purestorage.com>
Fri, 14 Aug 2015 23:12:49 +0000 (16:12 -0700)
We would previously lookup the consistency group id through the snapshot
db object, but with the new versioned snapshot object we can no longer
take that shortcut. We will now query the FlashArray for all Protection
Group snapshots and search for one with the cgsnapshot id in its name.

Closes-Bug: #1483916
Change-Id: Icb4991ec419c2cf46c760fa750e9f1be1528364c

cinder/tests/unit/test_pure.py
cinder/volume/drivers/pure.py

index 166e1e8015db3b3ab0b88405a554fb7dc123b7f9..57e532a6860dcb49b35ae6143550c73291342a43 100644 (file)
@@ -283,6 +283,20 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase):
             self.driver.create_volume_from_snapshot, VOLUME, SNAPSHOT)
         SNAPSHOT["volume_size"] = 2  # reset size
 
+    @mock.patch(BASE_DRIVER_OBJ + "._get_snap_name")
+    def test_create_volume_from_snapshot_cant_get_name(self, mock_get_name):
+        mock_get_name.return_value = None
+        self.assertRaises(exception.PureDriverException,
+                          self.driver.create_volume_from_snapshot,
+                          VOLUME, SNAPSHOT)
+
+    @mock.patch(BASE_DRIVER_OBJ + "._get_pgroup_snap_name_from_snapshot")
+    def test_create_volume_from_cgsnapshot_cant_get_name(self, mock_get_name):
+        mock_get_name.return_value = None
+        self.assertRaises(exception.PureDriverException,
+                          self.driver.create_volume_from_snapshot,
+                          VOLUME, SNAPSHOT_WITH_CGROUP)
+
     @mock.patch(BASE_DRIVER_OBJ + "._add_volume_to_consistency_group",
                 autospec=True)
     @mock.patch(BASE_DRIVER_OBJ + "._extend_if_needed", autospec=True)
@@ -615,28 +629,39 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase):
 
         self.assertEqual(expected_name, actual_name)
 
-    def test_get_pgroup_vol_snap_name(self):
-        cg_id = "4a2f7e3a-312a-40c5-96a8-536b8a0fe074"
-        cgsnap_id = "4a2f7e3a-312a-40c5-96a8-536b8a0fe075"
-        volume_name = "volume-4a2f7e3a-312a-40c5-96a8-536b8a0fe075"
+    def test_get_pgroup_snap_name_from_snapshot(self):
+        cgsnapshot_id = 'b919b266-23b4-4b83-9a92-e66031b9a921'
+        volume_id = 'a3b8b294-8494-4a72-bec7-9aadec561332'
+        pgsnap_name_base = ('consisgroup-0cfc0e4e-5029-4839-af20-184fbc42a9ed'
+                            '-cinder.cgsnapshot-%s-cinder.volume-%s-cinder')
+        pgsnap_name = pgsnap_name_base % (cgsnapshot_id, volume_id)
+
+        target_pgsnap_dict = {
+            'source': 'volume-a3b8b294-8494-4a72-bec7-9aadec561332-cinder',
+            'serial': '590474D16E6708FD00015075',
+            'size': 1073741824,
+            'name': pgsnap_name,
+            'created': '2015-08-11T22:25:43Z'
+        }
 
-        mock_snap = mock.Mock()
-        mock_snap.cgsnapshot = mock.Mock()
-        mock_snap.cgsnapshot.consistencygroup_id = cg_id
-        mock_snap.cgsnapshot.id = cgsnap_id
-        mock_snap.volume_name = volume_name
+        # Simulate another pgroup snapshot for another volume in the same group
+        other_volume_id = '73f6af5e-43cd-4c61-8f57-21f312e4523d'
+        other_pgsnap_dict = target_pgsnap_dict.copy()
+        other_pgsnap_dict['name'] = pgsnap_name_base % (cgsnapshot_id,
+                                                        other_volume_id)
 
-        expected_name = "consisgroup-%(cg)s-cinder.cgsnapshot-%(snap)s-cinder"\
-                        ".%(vol)s-cinder" % {
-                            "cg": cg_id,
-                            "snap": cgsnap_id,
-                            "vol": volume_name,
-                        }
+        snap_list = [other_pgsnap_dict, target_pgsnap_dict]
 
-        actual_name = self.driver._get_pgroup_snap_name_from_snapshot(
-            mock_snap)
+        self.array.list_volumes.return_value = snap_list
 
-        self.assertEqual(expected_name, actual_name)
+        mock_snap = mock.Mock()
+        mock_snap.cgsnapshot_id = cgsnapshot_id
+        mock_snap.volume_id = volume_id
+
+        actual_name = self.driver._get_pgroup_snap_name_from_snapshot(
+            mock_snap
+        )
+        self.assertEqual(pgsnap_name, actual_name)
 
     def test_create_consistencygroup(self):
         mock_cgroup = mock.Mock()
index 7be2c8f6693b3529ad476b6f120c677fb94ececb..d56d32ce7fac28f51033dad6735aa36276df1ca6 100644 (file)
@@ -134,6 +134,11 @@ class PureBaseVolumeDriver(san.SanDriver):
         else:
             snap_name = self._get_snap_name(snapshot)
 
+        if not snap_name:
+            msg = _('Unable to determine snapshot name in Purity for snapshot '
+                    '%(id)s.') % {'id': snapshot['id']}
+            raise exception.PureDriverException(reason=msg)
+
         self._array.copy_volume(snap_name, vol_name)
         self._extend_if_needed(vol_name, snapshot["volume_size"],
                                volume["size"])
@@ -614,11 +619,13 @@ class PureBaseVolumeDriver(san.SanDriver):
 
     def _get_pgroup_snap_name_from_snapshot(self, snapshot):
         """Return the name of the snapshot that Purity will use."""
-        cg_id = snapshot.cgsnapshot.consistencygroup_id
-        cg_name = self._get_pgroup_name_from_id(cg_id)
-        cgsnapshot_id = self._get_pgroup_snap_suffix(snapshot.cgsnapshot)
-        volume_name = snapshot.volume_name
-        return "%s.%s.%s-cinder" % (cg_name, cgsnapshot_id, volume_name)
+        pg_snaps = self._array.list_volumes(snap=True, pgroup=True)
+        for pg_snap in pg_snaps:
+            pg_snap_name = pg_snap['name']
+            if (snapshot.cgsnapshot_id in pg_snap_name and
+                    snapshot.volume_id in pg_snap_name):
+                return pg_snap_name
+        return None
 
     @staticmethod
     def _generate_purity_host_name(name):