summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Swartzlander <ben@swartzlander.org>2017-08-03 16:32:07 -0400
committerBen Swartzlander <ben@swartzlander.org>2017-08-11 19:41:44 +0000
commit80fe5f1fe4eb2f9d63c36fbfed3dcc388e4a931b (patch)
treecbcc88246c4b153f4c1c7ece5e7daa53d499c5b4
parentc6f073be24d19fa90120ad38c118baac2c0005e6 (diff)
Re-enable broken CG code in NetApp driver5.0.0.0rc15.0.0
Override the new create_share_group_snapshot() method in the driver class and call the old CG snapshot code if the share group specifies CG support, otherwise fall back on the new (existing) code. This patch also removes dead code from the old CG feature from Newton and earlier releases. Change-Id: Ief71b9900c2c84e0df1d12d303517fa20ff7908b Closes-bug: #1659023
Notes
Notes (review): Code-Review+2: Goutham Pacha Ravi <gouthampravi@gmail.com> Code-Review+2: Valeriy Ponomaryov <vponomaryov@mirantis.com> Workflow+1: Ben Swartzlander <ben@swartzlander.org> Verified+2: Jenkins Submitted-by: Jenkins Submitted-at: Fri, 11 Aug 2017 21:50:19 +0000 Reviewed-on: https://review.openstack.org/491877 Project: openstack/manila Branch: refs/heads/master
-rw-r--r--manila/share/drivers/netapp/dataontap/cluster_mode/drv_multi_svm.py47
-rw-r--r--manila/share/drivers/netapp/dataontap/cluster_mode/drv_single_svm.py47
-rw-r--r--manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py84
-rw-r--r--manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py179
-rw-r--r--manila/tests/share/drivers/netapp/dataontap/fakes.py13
-rw-r--r--releasenotes/notes/bug-1659023-netapp-cg-fix-56bb77b7bc61c3f5.yaml5
6 files changed, 224 insertions, 151 deletions
diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/drv_multi_svm.py b/manila/share/drivers/netapp/dataontap/cluster_mode/drv_multi_svm.py
index 9f7701c..293273b 100644
--- a/manila/share/drivers/netapp/dataontap/cluster_mode/drv_multi_svm.py
+++ b/manila/share/drivers/netapp/dataontap/cluster_mode/drv_multi_svm.py
@@ -71,25 +71,6 @@ class NetAppCmodeMultiSvmShareDriver(driver.ShareDriver):
71 def shrink_share(self, share, new_size, **kwargs): 71 def shrink_share(self, share, new_size, **kwargs):
72 self.library.shrink_share(share, new_size, **kwargs) 72 self.library.shrink_share(share, new_size, **kwargs)
73 73
74 def create_consistency_group(self, context, cg_dict, **kwargs):
75 return self.library.create_consistency_group(context, cg_dict,
76 **kwargs)
77
78 def create_consistency_group_from_cgsnapshot(self, context, cg_dict,
79 cgsnapshot_dict, **kwargs):
80 return self.library.create_consistency_group_from_cgsnapshot(
81 context, cg_dict, cgsnapshot_dict, **kwargs)
82
83 def delete_consistency_group(self, context, cg_dict, **kwargs):
84 return self.library.delete_consistency_group(context, cg_dict,
85 **kwargs)
86
87 def create_cgsnapshot(self, context, snap_dict, **kwargs):
88 return self.library.create_cgsnapshot(context, snap_dict, **kwargs)
89
90 def delete_cgsnapshot(self, context, snap_dict, **kwargs):
91 return self.library.delete_cgsnapshot(context, snap_dict, **kwargs)
92
93 def ensure_share(self, context, share, **kwargs): 74 def ensure_share(self, context, share, **kwargs):
94 pass 75 pass
95 76
@@ -225,3 +206,31 @@ class NetAppCmodeMultiSvmShareDriver(driver.ShareDriver):
225 context, source_share, destination_share, 206 context, source_share, destination_share,
226 source_snapshots, snapshot_mappings, share_server=share_server, 207 source_snapshots, snapshot_mappings, share_server=share_server,
227 destination_share_server=destination_share_server) 208 destination_share_server=destination_share_server)
209
210 def create_share_group_snapshot(self, context, snap_dict,
211 share_server=None):
212 fallback_create = super(NetAppCmodeMultiSvmShareDriver,
213 self).create_share_group_snapshot
214 return self.library.create_group_snapshot(context, snap_dict,
215 fallback_create,
216 share_server)
217
218 def delete_share_group_snapshot(self, context, snap_dict,
219 share_server=None):
220 fallback_delete = super(NetAppCmodeMultiSvmShareDriver,
221 self).delete_share_group_snapshot
222 return self.library.delete_group_snapshot(context, snap_dict,
223 fallback_delete,
224 share_server)
225
226 def create_share_group_from_share_group_snapshot(
227 self, context, share_group_dict, snapshot_dict,
228 share_server=None):
229 fallback_create = super(
230 NetAppCmodeMultiSvmShareDriver,
231 self).create_share_group_from_share_group_snapshot
232 return self.library.create_group_from_snapshot(context,
233 share_group_dict,
234 snapshot_dict,
235 fallback_create,
236 share_server)
diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/drv_single_svm.py b/manila/share/drivers/netapp/dataontap/cluster_mode/drv_single_svm.py
index 2433afd..3569621 100644
--- a/manila/share/drivers/netapp/dataontap/cluster_mode/drv_single_svm.py
+++ b/manila/share/drivers/netapp/dataontap/cluster_mode/drv_single_svm.py
@@ -71,25 +71,6 @@ class NetAppCmodeSingleSvmShareDriver(driver.ShareDriver):
71 def shrink_share(self, share, new_size, **kwargs): 71 def shrink_share(self, share, new_size, **kwargs):
72 self.library.shrink_share(share, new_size, **kwargs) 72 self.library.shrink_share(share, new_size, **kwargs)
73 73
74 def create_consistency_group(self, context, cg_dict, **kwargs):
75 return self.library.create_consistency_group(context, cg_dict,
76 **kwargs)
77
78 def create_consistency_group_from_cgsnapshot(self, context, cg_dict,
79 cgsnapshot_dict, **kwargs):
80 return self.library.create_consistency_group_from_cgsnapshot(
81 context, cg_dict, cgsnapshot_dict, **kwargs)
82
83 def delete_consistency_group(self, context, cg_dict, **kwargs):
84 return self.library.delete_consistency_group(context, cg_dict,
85 **kwargs)
86
87 def create_cgsnapshot(self, context, snap_dict, **kwargs):
88 return self.library.create_cgsnapshot(context, snap_dict, **kwargs)
89
90 def delete_cgsnapshot(self, context, snap_dict, **kwargs):
91 return self.library.delete_cgsnapshot(context, snap_dict, **kwargs)
92
93 def ensure_share(self, context, share, **kwargs): 74 def ensure_share(self, context, share, **kwargs):
94 pass 75 pass
95 76
@@ -241,3 +222,31 @@ class NetAppCmodeSingleSvmShareDriver(driver.ShareDriver):
241 context, source_share, destination_share, 222 context, source_share, destination_share,
242 source_snapshots, snapshot_mappings, share_server=share_server, 223 source_snapshots, snapshot_mappings, share_server=share_server,
243 destination_share_server=destination_share_server) 224 destination_share_server=destination_share_server)
225
226 def create_share_group_snapshot(self, context, snap_dict,
227 share_server=None):
228 fallback_create = super(NetAppCmodeSingleSvmShareDriver,
229 self).create_share_group_snapshot
230 return self.library.create_group_snapshot(context, snap_dict,
231 fallback_create,
232 share_server)
233
234 def delete_share_group_snapshot(self, context, snap_dict,
235 share_server=None):
236 fallback_delete = super(NetAppCmodeSingleSvmShareDriver,
237 self).delete_share_group_snapshot
238 return self.library.delete_group_snapshot(context, snap_dict,
239 fallback_delete,
240 share_server)
241
242 def create_share_group_from_share_group_snapshot(
243 self, context, share_group_dict, snapshot_dict,
244 share_server=None):
245 fallback_create = super(
246 NetAppCmodeSingleSvmShareDriver,
247 self).create_share_group_from_share_group_snapshot
248 return self.library.create_group_from_snapshot(context,
249 share_group_dict,
250 snapshot_dict,
251 fallback_create,
252 share_server)
diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py
index ebb1d07..e07c234 100644
--- a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py
+++ b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py
@@ -258,6 +258,9 @@ class NetAppCmodeFileStorageLibrary(object):
258 'storage_protocol': 'NFS_CIFS', 258 'storage_protocol': 'NFS_CIFS',
259 'pools': self._get_pools(filter_function=filter_function, 259 'pools': self._get_pools(filter_function=filter_function,
260 goodness_function=goodness_function), 260 goodness_function=goodness_function),
261 'share_group_stats': {
262 'consistent_snapshot_support': 'host',
263 },
261 } 264 }
262 265
263 if (self.configuration.replication_domain and 266 if (self.configuration.replication_domain and
@@ -1097,22 +1100,13 @@ class NetAppCmodeFileStorageLibrary(object):
1097 """Removes the specified snapshot from Manila management.""" 1100 """Removes the specified snapshot from Manila management."""
1098 1101
1099 @na_utils.trace 1102 @na_utils.trace
1100 def create_consistency_group(self, context, cg_dict, share_server=None):
1101 """Creates a consistency group.
1102
1103 cDOT has no persistent CG object, so apart from validating the
1104 share_server info is passed correctly, this method has nothing to do.
1105 """
1106 vserver, vserver_client = self._get_vserver(share_server=share_server)
1107
1108 @na_utils.trace
1109 def create_consistency_group_from_cgsnapshot( 1103 def create_consistency_group_from_cgsnapshot(
1110 self, context, cg_dict, cgsnapshot_dict, share_server=None): 1104 self, context, cg_dict, cgsnapshot_dict, share_server=None):
1111 """Creates a consistency group from an existing CG snapshot.""" 1105 """Creates a consistency group from an existing CG snapshot."""
1112 vserver, vserver_client = self._get_vserver(share_server=share_server) 1106 vserver, vserver_client = self._get_vserver(share_server=share_server)
1113 1107
1114 # Ensure there is something to do 1108 # Ensure there is something to do
1115 if not cgsnapshot_dict['cgsnapshot_members']: 1109 if not cgsnapshot_dict['share_group_snapshot_members']:
1116 return None, None 1110 return None, None
1117 1111
1118 clone_list = self._collate_cg_snapshot_info(cg_dict, cgsnapshot_dict) 1112 clone_list = self._collate_cg_snapshot_info(cg_dict, cgsnapshot_dict)
@@ -1153,12 +1147,13 @@ class NetAppCmodeFileStorageLibrary(object):
1153 1147
1154 clone_info = {'share': share} 1148 clone_info = {'share': share}
1155 1149
1156 for cgsnapshot_member in cgsnapshot_dict['cgsnapshot_members']: 1150 for cgsnapshot_member in (
1157 if (share['source_cgsnapshot_member_id'] == 1151 cgsnapshot_dict['share_group_snapshot_members']):
1152 if (share['source_share_group_snapshot_member_id'] ==
1158 cgsnapshot_member['id']): 1153 cgsnapshot_member['id']):
1159 clone_info['snapshot'] = { 1154 clone_info['snapshot'] = {
1160 'share_id': cgsnapshot_member['share_id'], 1155 'share_id': cgsnapshot_member['share_id'],
1161 'id': cgsnapshot_member['cgsnapshot_id'] 1156 'id': cgsnapshot_dict['id']
1162 } 1157 }
1163 break 1158 break
1164 1159
@@ -1172,30 +1167,13 @@ class NetAppCmodeFileStorageLibrary(object):
1172 return clone_list 1167 return clone_list
1173 1168
1174 @na_utils.trace 1169 @na_utils.trace
1175 def delete_consistency_group(self, context, cg_dict, share_server=None):
1176 """Deletes a consistency group.
1177
1178 cDOT has no persistent CG object, so apart from validating the
1179 share_server info is passed correctly, this method has nothing to do.
1180 """
1181 try:
1182 vserver, vserver_client = self._get_vserver(
1183 share_server=share_server)
1184 except (exception.InvalidInput,
1185 exception.VserverNotSpecified,
1186 exception.VserverNotFound) as error:
1187 LOG.warning("Could not determine share server for consistency "
1188 "group being deleted: %(cg)s. Deletion of CG "
1189 "record will proceed anyway. Error: %(error)s",
1190 {'cg': cg_dict['id'], 'error': error})
1191
1192 @na_utils.trace
1193 def create_cgsnapshot(self, context, snap_dict, share_server=None): 1170 def create_cgsnapshot(self, context, snap_dict, share_server=None):
1194 """Creates a consistency group snapshot.""" 1171 """Creates a consistency group snapshot."""
1195 vserver, vserver_client = self._get_vserver(share_server=share_server) 1172 vserver, vserver_client = self._get_vserver(share_server=share_server)
1196 1173
1197 share_names = [self._get_backend_share_name(member['share_id']) 1174 share_names = [self._get_backend_share_name(member['share_id'])
1198 for member in snap_dict.get('cgsnapshot_members', [])] 1175 for member in
1176 snap_dict.get('share_group_snapshot_members', [])]
1199 snapshot_name = self._get_backend_cg_snapshot_name(snap_dict['id']) 1177 snapshot_name = self._get_backend_cg_snapshot_name(snap_dict['id'])
1200 1178
1201 if share_names: 1179 if share_names:
@@ -1220,7 +1198,8 @@ class NetAppCmodeFileStorageLibrary(object):
1220 return None, None 1198 return None, None
1221 1199
1222 share_names = [self._get_backend_share_name(member['share_id']) 1200 share_names = [self._get_backend_share_name(member['share_id'])
1223 for member in snap_dict.get('cgsnapshot_members', [])] 1201 for member in (
1202 snap_dict.get('share_group_snapshot_members', []))]
1224 snapshot_name = self._get_backend_cg_snapshot_name(snap_dict['id']) 1203 snapshot_name = self._get_backend_cg_snapshot_name(snap_dict['id'])
1225 1204
1226 for share_name in share_names: 1205 for share_name in share_names:
@@ -1236,6 +1215,45 @@ class NetAppCmodeFileStorageLibrary(object):
1236 1215
1237 return None, None 1216 return None, None
1238 1217
1218 @staticmethod
1219 def _is_group_cg(context, share_group):
1220 return 'host' == share_group.consistent_snapshot_support
1221
1222 @na_utils.trace
1223 def create_group_snapshot(self, context, snap_dict, fallback_create,
1224 share_server=None):
1225 share_group = snap_dict['share_group']
1226 if self._is_group_cg(context, share_group):
1227 return self.create_cgsnapshot(context, snap_dict,
1228 share_server=share_server)
1229 else:
1230 return fallback_create(context, snap_dict,
1231 share_server=share_server)
1232
1233 @na_utils.trace
1234 def delete_group_snapshot(self, context, snap_dict, fallback_delete,
1235 share_server=None):
1236 share_group = snap_dict['share_group']
1237 if self._is_group_cg(context, share_group):
1238 return self.delete_cgsnapshot(context, snap_dict,
1239 share_server=share_server)
1240 else:
1241 return fallback_delete(context, snap_dict,
1242 share_server=share_server)
1243
1244 @na_utils.trace
1245 def create_group_from_snapshot(self, context, share_group,
1246 snapshot_dict, fallback_create,
1247 share_server=None):
1248 share_group2 = snapshot_dict['share_group']
1249 if self._is_group_cg(context, share_group2):
1250 return self.create_consistency_group_from_cgsnapshot(
1251 context, share_group, snapshot_dict,
1252 share_server=share_server)
1253 else:
1254 return fallback_create(context, share_group, snapshot_dict,
1255 share_server=share_server)
1256
1239 @na_utils.trace 1257 @na_utils.trace
1240 def _adjust_qos_policy_with_volume_resize(self, share, new_size, 1258 def _adjust_qos_policy_with_volume_resize(self, share, new_size,
1241 vserver_client): 1259 vserver_client):
diff --git a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py
index 7013196..d56e870 100644
--- a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py
+++ b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py
@@ -367,6 +367,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
367 'netapp_storage_family': 'ontap_cluster', 367 'netapp_storage_family': 'ontap_cluster',
368 'storage_protocol': 'NFS_CIFS', 368 'storage_protocol': 'NFS_CIFS',
369 'pools': fake.POOLS, 369 'pools': fake.POOLS,
370 'share_group_stats': {'consistent_snapshot_support': 'host'},
370 } 371 }
371 self.assertDictEqual(expected, result) 372 self.assertDictEqual(expected, result)
372 mock_get_pools.assert_called_once_with(filter_function='filter', 373 mock_get_pools.assert_called_once_with(filter_function='filter',
@@ -392,6 +393,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
392 'replication_type': 'dr', 393 'replication_type': 'dr',
393 'replication_domain': 'fake_domain', 394 'replication_domain': 'fake_domain',
394 'pools': fake.POOLS, 395 'pools': fake.POOLS,
396 'share_group_stats': {'consistent_snapshot_support': 'host'},
395 } 397 }
396 self.assertDictEqual(expected, result) 398 self.assertDictEqual(expected, result)
397 mock_get_pools.assert_called_once_with(filter_function='filter', 399 mock_get_pools.assert_called_once_with(filter_function='filter',
@@ -1839,40 +1841,6 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
1839 fake.FLEXVOL_TO_MANAGE, 1841 fake.FLEXVOL_TO_MANAGE,
1840 vserver_client) 1842 vserver_client)
1841 1843
1842 def test_create_consistency_group(self):
1843
1844 vserver_client = mock.Mock()
1845 mock_get_vserver = self.mock_object(
1846 self.library, '_get_vserver',
1847 mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
1848
1849 result = self.library.create_consistency_group(
1850 self.context, fake.EMPTY_CONSISTENCY_GROUP,
1851 share_server=fake.SHARE_SERVER)
1852
1853 self.assertIsNone(result)
1854 mock_get_vserver.assert_called_once_with(
1855 share_server=fake.SHARE_SERVER)
1856
1857 @ddt.data(exception.InvalidInput(reason='fake_reason'),
1858 exception.VserverNotSpecified(),
1859 exception.VserverNotFound(vserver='fake_vserver'))
1860 def test_create_consistency_group_no_share_server(self,
1861 get_vserver_exception):
1862
1863 mock_get_vserver = self.mock_object(
1864 self.library, '_get_vserver',
1865 mock.Mock(side_effect=get_vserver_exception))
1866
1867 self.assertRaises(type(get_vserver_exception),
1868 self.library.create_consistency_group,
1869 self.context,
1870 fake.EMPTY_CONSISTENCY_GROUP,
1871 share_server=fake.SHARE_SERVER)
1872
1873 mock_get_vserver.assert_called_once_with(
1874 share_server=fake.SHARE_SERVER)
1875
1876 def test_create_consistency_group_from_cgsnapshot(self): 1844 def test_create_consistency_group_from_cgsnapshot(self):
1877 1845
1878 vserver_client = mock.Mock() 1846 vserver_client = mock.Mock()
@@ -1936,7 +1904,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
1936 mock.Mock(side_effect=[['loc3'], ['loc4']])) 1904 mock.Mock(side_effect=[['loc3'], ['loc4']]))
1937 1905
1938 fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT) 1906 fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT)
1939 fake_cg_snapshot['cgsnapshot_members'] = [] 1907 fake_cg_snapshot['share_group_snapshot_members'] = []
1940 1908
1941 result = self.library.create_consistency_group_from_cgsnapshot( 1909 result = self.library.create_consistency_group_from_cgsnapshot(
1942 self.context, 1910 self.context,
@@ -1961,48 +1929,12 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
1961 def test_collate_cg_snapshot_info_invalid(self): 1929 def test_collate_cg_snapshot_info_invalid(self):
1962 1930
1963 fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT) 1931 fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT)
1964 fake_cg_snapshot['cgsnapshot_members'] = [] 1932 fake_cg_snapshot['share_group_snapshot_members'] = []
1965 1933
1966 self.assertRaises(exception.InvalidShareGroup, 1934 self.assertRaises(exception.InvalidShareGroup,
1967 self.library._collate_cg_snapshot_info, 1935 self.library._collate_cg_snapshot_info,
1968 fake.CONSISTENCY_GROUP_DEST, fake_cg_snapshot) 1936 fake.CONSISTENCY_GROUP_DEST, fake_cg_snapshot)
1969 1937
1970 def test_delete_consistency_group(self):
1971
1972 vserver_client = mock.Mock()
1973 mock_get_vserver = self.mock_object(
1974 self.library, '_get_vserver',
1975 mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
1976
1977 result = self.library.delete_consistency_group(
1978 self.context,
1979 fake.EMPTY_CONSISTENCY_GROUP,
1980 share_server=fake.SHARE_SERVER)
1981
1982 self.assertIsNone(result)
1983 mock_get_vserver.assert_called_once_with(
1984 share_server=fake.SHARE_SERVER)
1985
1986 @ddt.data(exception.InvalidInput(reason='fake_reason'),
1987 exception.VserverNotSpecified(),
1988 exception.VserverNotFound(vserver='fake_vserver'))
1989 def test_delete_consistency_group_no_share_server(self,
1990 get_vserver_exception):
1991
1992 mock_get_vserver = self.mock_object(
1993 self.library, '_get_vserver',
1994 mock.Mock(side_effect=get_vserver_exception))
1995
1996 result = self.library.delete_consistency_group(
1997 self.context,
1998 fake.EMPTY_CONSISTENCY_GROUP,
1999 share_server=fake.SHARE_SERVER)
2000
2001 self.assertIsNone(result)
2002 self.assertEqual(1, lib_base.LOG.warning.call_count)
2003 mock_get_vserver.assert_called_once_with(
2004 share_server=fake.SHARE_SERVER)
2005
2006 def test_create_cgsnapshot(self): 1938 def test_create_cgsnapshot(self):
2007 1939
2008 vserver_client = mock.Mock() 1940 vserver_client = mock.Mock()
@@ -2037,7 +1969,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
2037 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 1969 mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
2038 1970
2039 fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT) 1971 fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT)
2040 fake_cg_snapshot['cgsnapshot_members'] = [] 1972 fake_cg_snapshot['share_group_snapshot_members'] = []
2041 1973
2042 result = self.library.create_cgsnapshot( 1974 result = self.library.create_cgsnapshot(
2043 self.context, 1975 self.context,
@@ -2090,7 +2022,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
2090 '_delete_snapshot') 2022 '_delete_snapshot')
2091 2023
2092 fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT) 2024 fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT)
2093 fake_cg_snapshot['cgsnapshot_members'] = [] 2025 fake_cg_snapshot['share_group_snapshot_members'] = []
2094 2026
2095 result = self.library.delete_cgsnapshot( 2027 result = self.library.delete_cgsnapshot(
2096 self.context, 2028 self.context,
@@ -4779,3 +4711,102 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
4779 share_obj, fake.VSERVER1, {'maxiops': '3000'}) 4711 share_obj, fake.VSERVER1, {'maxiops': '3000'})
4780 self.library._client.qos_policy_group_modify.assert_not_called() 4712 self.library._client.qos_policy_group_modify.assert_not_called()
4781 self.library._client.qos_policy_group_rename.assert_not_called() 4713 self.library._client.qos_policy_group_rename.assert_not_called()
4714
4715 @ddt.data(('host', True), ('pool', False), (None, False), ('fake', False))
4716 @ddt.unpack
4717 def test__is_group_cg(self, css, is_cg):
4718 share_group = mock.Mock()
4719 share_group.consistent_snapshot_support = css
4720 self.assertEqual(is_cg,
4721 self.library._is_group_cg(self.context, share_group))
4722
4723 def test_create_group_snapshot_cg(self):
4724 share_group = mock.Mock()
4725 share_group.consistent_snapshot_support = 'host'
4726 snap_dict = {'share_group': share_group}
4727 fallback_create = mock.Mock()
4728 mock_create_cgsnapshot = self.mock_object(self.library,
4729 'create_cgsnapshot')
4730 self.library.create_group_snapshot(self.context, snap_dict,
4731 fallback_create,
4732 share_server=fake.SHARE_SERVER)
4733 mock_create_cgsnapshot.assert_called_once_with(
4734 self.context, snap_dict, share_server=fake.SHARE_SERVER)
4735 fallback_create.assert_not_called()
4736
4737 @ddt.data('pool', None, 'fake')
4738 def test_create_group_snapshot_fallback(self, css):
4739 share_group = mock.Mock()
4740 share_group.consistent_snapshot_support = css
4741 snap_dict = {'share_group': share_group}
4742 fallback_create = mock.Mock()
4743 mock_create_cgsnapshot = self.mock_object(self.library,
4744 'create_cgsnapshot')
4745 self.library.create_group_snapshot(self.context, snap_dict,
4746 fallback_create,
4747 share_server=fake.SHARE_SERVER)
4748 mock_create_cgsnapshot.assert_not_called()
4749 fallback_create.assert_called_once_with(self.context,
4750 snap_dict,
4751 share_server=fake.SHARE_SERVER)
4752
4753 def test_delete_group_snapshot_cg(self):
4754 share_group = mock.Mock()
4755 share_group.consistent_snapshot_support = 'host'
4756 snap_dict = {'share_group': share_group}
4757 fallback_delete = mock.Mock()
4758 mock_delete_cgsnapshot = self.mock_object(self.library,
4759 'delete_cgsnapshot')
4760 self.library.delete_group_snapshot(self.context, snap_dict,
4761 fallback_delete,
4762 share_server=fake.SHARE_SERVER)
4763 mock_delete_cgsnapshot.assert_called_once_with(
4764 self.context, snap_dict, share_server=fake.SHARE_SERVER)
4765 fallback_delete.assert_not_called()
4766
4767 @ddt.data('pool', None, 'fake')
4768 def test_delete_group_snapshot_fallback(self, css):
4769 share_group = mock.Mock()
4770 share_group.consistent_snapshot_support = css
4771 snap_dict = {'share_group': share_group}
4772 fallback_delete = mock.Mock()
4773 mock_delete_cgsnapshot = self.mock_object(self.library,
4774 'delete_cgsnapshot')
4775 self.library.delete_group_snapshot(self.context, snap_dict,
4776 fallback_delete,
4777 share_server=fake.SHARE_SERVER)
4778 mock_delete_cgsnapshot.assert_not_called()
4779 fallback_delete.assert_called_once_with(self.context,
4780 snap_dict,
4781 share_server=fake.SHARE_SERVER)
4782
4783 def test_create_group_from_snapshot_cg(self):
4784 share_group = mock.Mock()
4785 share_group.consistent_snapshot_support = 'host'
4786 snap_dict = {'share_group': share_group}
4787 fallback_create = mock.Mock()
4788 mock_create_cg_from_snapshot = self.mock_object(
4789 self.library, 'create_consistency_group_from_cgsnapshot')
4790 self.library.create_group_from_snapshot(self.context, share_group,
4791 snap_dict, fallback_create,
4792 share_server=fake.SHARE_SERVER)
4793 mock_create_cg_from_snapshot.assert_called_once_with(
4794 self.context, share_group, snap_dict,
4795 share_server=fake.SHARE_SERVER)
4796 fallback_create.assert_not_called()
4797
4798 @ddt.data('pool', None, 'fake')
4799 def test_create_group_from_snapshot_fallback(self, css):
4800 share_group = mock.Mock()
4801 share_group.consistent_snapshot_support = css
4802 snap_dict = {'share_group': share_group}
4803 fallback_create = mock.Mock()
4804 mock_create_cg_from_snapshot = self.mock_object(
4805 self.library, 'create_consistency_group_from_cgsnapshot')
4806 self.library.create_group_from_snapshot(self.context, share_group,
4807 snap_dict, fallback_create,
4808 share_server=fake.SHARE_SERVER)
4809 mock_create_cg_from_snapshot.assert_not_called()
4810 fallback_create.assert_called_once_with(self.context, share_group,
4811 snap_dict,
4812 share_server=fake.SHARE_SERVER)
diff --git a/manila/tests/share/drivers/netapp/dataontap/fakes.py b/manila/tests/share/drivers/netapp/dataontap/fakes.py
index 3df254a..6890be9 100644
--- a/manila/tests/share/drivers/netapp/dataontap/fakes.py
+++ b/manila/tests/share/drivers/netapp/dataontap/fakes.py
@@ -385,7 +385,7 @@ SHARE_FOR_CG1 = {
385 'host': HOST_NAME, 'backend': BACKEND_NAME, 'pool': POOL_NAME}, 385 'host': HOST_NAME, 'backend': BACKEND_NAME, 'pool': POOL_NAME},
386 'name': 'share_1', 386 'name': 'share_1',
387 'share_proto': 'NFS', 387 'share_proto': 'NFS',
388 'source_cgsnapshot_member_id': None, 388 'source_share_group_snapshot_member_id': None,
389} 389}
390 390
391SHARE_FOR_CG2 = { 391SHARE_FOR_CG2 = {
@@ -394,7 +394,7 @@ SHARE_FOR_CG2 = {
394 'host': HOST_NAME, 'backend': BACKEND_NAME, 'pool': POOL_NAME}, 394 'host': HOST_NAME, 'backend': BACKEND_NAME, 'pool': POOL_NAME},
395 'name': 'share_2', 395 'name': 'share_2',
396 'share_proto': 'NFS', 396 'share_proto': 'NFS',
397 'source_cgsnapshot_member_id': None, 397 'source_share_group_snapshot_member_id': None,
398} 398}
399 399
400# Clone dest of SHARE_FOR_CG1 400# Clone dest of SHARE_FOR_CG1
@@ -404,7 +404,7 @@ SHARE_FOR_CG3 = {
404 'host': HOST_NAME, 'backend': BACKEND_NAME, 'pool': POOL_NAME}, 404 'host': HOST_NAME, 'backend': BACKEND_NAME, 'pool': POOL_NAME},
405 'name': 'share3', 405 'name': 'share3',
406 'share_proto': 'NFS', 406 'share_proto': 'NFS',
407 'source_cgsnapshot_member_id': CG_SNAPSHOT_MEMBER_ID1, 407 'source_share_group_snapshot_member_id': CG_SNAPSHOT_MEMBER_ID1,
408} 408}
409 409
410# Clone dest of SHARE_FOR_CG2 410# Clone dest of SHARE_FOR_CG2
@@ -414,7 +414,7 @@ SHARE_FOR_CG4 = {
414 'host': HOST_NAME, 'backend': BACKEND_NAME, 'pool': POOL_NAME}, 414 'host': HOST_NAME, 'backend': BACKEND_NAME, 'pool': POOL_NAME},
415 'name': 'share4', 415 'name': 'share4',
416 'share_proto': 'NFS', 416 'share_proto': 'NFS',
417 'source_cgsnapshot_member_id': CG_SNAPSHOT_MEMBER_ID2, 417 'source_share_group_snapshot_member_id': CG_SNAPSHOT_MEMBER_ID2,
418} 418}
419 419
420EMPTY_CONSISTENCY_GROUP = { 420EMPTY_CONSISTENCY_GROUP = {
@@ -462,9 +462,10 @@ CG_SNAPSHOT_MEMBER_2 = {
462} 462}
463 463
464CG_SNAPSHOT = { 464CG_SNAPSHOT = {
465 'cgsnapshot_members': [CG_SNAPSHOT_MEMBER_1, CG_SNAPSHOT_MEMBER_2], 465 'share_group_snapshot_members': [CG_SNAPSHOT_MEMBER_1,
466 CG_SNAPSHOT_MEMBER_2],
466 'share_group': CONSISTENCY_GROUP, 467 'share_group': CONSISTENCY_GROUP,
467 'consistency_group_id': CONSISTENCY_GROUP_ID, 468 'share_group_id': CONSISTENCY_GROUP_ID,
468 'id': CG_SNAPSHOT_ID, 469 'id': CG_SNAPSHOT_ID,
469 'project_id': TENANT_ID, 470 'project_id': TENANT_ID,
470} 471}
diff --git a/releasenotes/notes/bug-1659023-netapp-cg-fix-56bb77b7bc61c3f5.yaml b/releasenotes/notes/bug-1659023-netapp-cg-fix-56bb77b7bc61c3f5.yaml
new file mode 100644
index 0000000..6ec1a02
--- /dev/null
+++ b/releasenotes/notes/bug-1659023-netapp-cg-fix-56bb77b7bc61c3f5.yaml
@@ -0,0 +1,5 @@
1---
2fixes:
3 - Re-enabled the consistent snapshot code in the NetApp driver, now
4 compatible with the Manila Share Groups API instead of the deprecated
5 and removed Manila Consistency Groups API.