Follow up NetApp ONTAP FlexGroup feature
It is a follow up to the patch [1], providing the fixes: 1. Check the ONTAP storage version for the FlexGroup feature. The feature is only accepted whether the ONTAP is 9.8 or greater. 2. Remove multiattach support for flexgroup pools. 3. Start bumping the driver version with its documentation. 4. Update the flexgroup release notes. [1] https://review.opendev.org/c/openstack/cinder/+/776713 Change-Id: I0636b6530a79f8ca86db52f87273ec822c3cb406
This commit is contained in:
parent
a01b5bb39e
commit
bb444d4a47
@ -281,6 +281,8 @@ class NetAppNfsDriverTestCase(test.TestCase):
|
||||
self.mock_object(self.driver, '_ensure_flexgroup_not_in_cg')
|
||||
self.mock_object(self.driver, '_is_flexgroup',
|
||||
return_value=is_flexgroup)
|
||||
self.mock_object(self.driver, '_is_flexgroup_clone_file_supported',
|
||||
return_value=not is_flexgroup)
|
||||
mock_super_create = self.mock_object(
|
||||
nfs.NfsDriver, 'create_volume_from_snapshot',
|
||||
return_value=provider_location)
|
||||
@ -311,6 +313,8 @@ class NetAppNfsDriverTestCase(test.TestCase):
|
||||
self.mock_object(self.driver, '_ensure_flexgroup_not_in_cg')
|
||||
self.mock_object(self.driver, '_is_flexgroup',
|
||||
return_value=is_flexgroup)
|
||||
self.mock_object(self.driver, '_is_flexgroup_clone_file_supported',
|
||||
return_value=not is_flexgroup)
|
||||
mock_super_create = self.mock_object(
|
||||
nfs.NfsDriver, 'create_cloned_volume',
|
||||
return_value=provider_location)
|
||||
@ -368,6 +372,8 @@ class NetAppNfsDriverTestCase(test.TestCase):
|
||||
def test_create_snapshot(self, is_flexgroup):
|
||||
self.mock_object(self.driver, '_is_flexgroup',
|
||||
return_value=is_flexgroup)
|
||||
self.mock_object(self.driver, '_is_flexgroup_clone_file_supported',
|
||||
return_value=not is_flexgroup)
|
||||
mock_clone_backing_file_for_volume = self.mock_object(
|
||||
self.driver, '_clone_backing_file_for_volume')
|
||||
mock_snap_flexgroup = self.mock_object(
|
||||
@ -450,6 +456,8 @@ class NetAppNfsDriverTestCase(test.TestCase):
|
||||
self.mock_object(self.driver, '_delete_file')
|
||||
self.mock_object(self.driver, '_is_flexgroup',
|
||||
return_value=is_flexgroup)
|
||||
self.mock_object(self.driver, '_is_flexgroup_clone_file_supported',
|
||||
return_value=not is_flexgroup)
|
||||
mock_super_delete = self.mock_object(nfs.NfsDriver,
|
||||
'delete_snapshot')
|
||||
|
||||
@ -550,6 +558,8 @@ class NetAppNfsDriverTestCase(test.TestCase):
|
||||
mock_log = self.mock_object(nfs_base, 'LOG')
|
||||
self.mock_object(self.driver, '_is_flexgroup',
|
||||
return_value=False)
|
||||
self.mock_object(self.driver, '_is_flexgroup_clone_file_supported',
|
||||
return_value=True)
|
||||
self.mock_object(self.driver, '_ensure_flexgroup_not_in_cg')
|
||||
mock_copy_image = self.mock_object(
|
||||
remotefs.RemoteFSDriver, 'copy_image_to_volume')
|
||||
@ -1147,3 +1157,7 @@ class NetAppNfsDriverTestCase(test.TestCase):
|
||||
self.assertRaises(na_utils.NetAppDriverException,
|
||||
self.driver._ensure_flexgroup_not_in_cg,
|
||||
fake_v1)
|
||||
|
||||
def test__is_flexgroup_clone_file_supported(self):
|
||||
self.assertRaises(NotImplementedError,
|
||||
self.driver._is_flexgroup_clone_file_supported)
|
||||
|
@ -279,6 +279,7 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
'netapp_dedupe_used_percent': 0,
|
||||
'consistencygroup_support': False,
|
||||
'consistent_group_snapshot_enabled': False,
|
||||
'multiattach': False,
|
||||
})
|
||||
|
||||
self.assertEqual(expected, result)
|
||||
@ -435,16 +436,38 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
self.assertIsNone(vserver)
|
||||
|
||||
def test_check_for_setup_error(self):
|
||||
super_check_for_setup_error = self.mock_object(
|
||||
nfs_base.NetAppNfsDriver, 'check_for_setup_error')
|
||||
mock_add_looping_tasks = self.mock_object(
|
||||
self.driver, '_add_looping_tasks')
|
||||
mock_contains_fg = self.mock_object(
|
||||
self.driver.ssc_library, 'contains_flexgroup_pool',
|
||||
return_value=False)
|
||||
self.driver.zapi_client = mock.Mock(features=mock.Mock(
|
||||
FLEXGROUP=True))
|
||||
super_check_for_setup_error = self.mock_object(
|
||||
nfs_base.NetAppNfsDriver, 'check_for_setup_error')
|
||||
|
||||
self.driver.check_for_setup_error()
|
||||
|
||||
self.assertEqual(1, super_check_for_setup_error.call_count)
|
||||
self.assertEqual(1, mock_add_looping_tasks.call_count)
|
||||
mock_add_looping_tasks.assert_called_once_with()
|
||||
mock_contains_fg.assert_called_once_with()
|
||||
|
||||
def test_check_for_setup_error_fail(self):
|
||||
mock_add_looping_tasks = self.mock_object(
|
||||
self.driver, '_add_looping_tasks')
|
||||
mock_contains_fg = self.mock_object(
|
||||
self.driver.ssc_library, 'contains_flexgroup_pool',
|
||||
return_value=True)
|
||||
self.driver.zapi_client = mock.Mock(features=mock.Mock(
|
||||
FLEXGROUP=False))
|
||||
|
||||
self.assertRaises(
|
||||
na_utils.NetAppDriverException, self.driver.check_for_setup_error)
|
||||
|
||||
self.assertEqual(1, mock_add_looping_tasks.call_count)
|
||||
mock_add_looping_tasks.assert_called_once_with()
|
||||
mock_contains_fg.assert_called_once_with()
|
||||
|
||||
@ddt.data({'replication_enabled': True, 'failed_over': False,
|
||||
'cluster_credentials': True},
|
||||
@ -558,10 +581,14 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
'delete_volume')
|
||||
mock_flexgroup = self.mock_object(self.driver, '_is_flexgroup',
|
||||
return_value=False)
|
||||
mock_clone_file = self.mock_object(
|
||||
self.driver, '_is_flexgroup_clone_file_supported',
|
||||
return_value=True)
|
||||
|
||||
self.driver._delete_backing_file_for_volume(fake.NFS_VOLUME)
|
||||
|
||||
mock_flexgroup.assert_called_once_with(host=fake.NFS_VOLUME['host'])
|
||||
mock_clone_file.assert_not_called()
|
||||
mock_filer_delete.assert_called_once_with(
|
||||
fake.NFS_VOLUME['id'], fake.NFS_VOLUME['name'])
|
||||
self.assertEqual(0, mock_super_delete.call_count)
|
||||
@ -570,6 +597,9 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
def test_delete_backing_file_for_volume_exception_path(self, super_exc):
|
||||
mock_flexgroup = self.mock_object(self.driver, '_is_flexgroup',
|
||||
return_value=False)
|
||||
mock_clone_file = self.mock_object(
|
||||
self.driver, '_is_flexgroup_clone_file_supported',
|
||||
return_value=True)
|
||||
mock_exception_log = self.mock_object(nfs_cmode.LOG, 'exception')
|
||||
exception_call_count = 2 if super_exc else 1
|
||||
mock_filer_delete = self.mock_object(self.driver, '_delete_file')
|
||||
@ -582,6 +612,7 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
self.driver._delete_backing_file_for_volume(fake.NFS_VOLUME)
|
||||
|
||||
mock_flexgroup.assert_called_once_with(host=fake.NFS_VOLUME['host'])
|
||||
mock_clone_file.assert_not_called()
|
||||
mock_filer_delete.assert_called_once_with(
|
||||
fake.NFS_VOLUME['id'], fake.NFS_VOLUME['name'])
|
||||
mock_super_delete.assert_called_once_with(fake.NFS_VOLUME)
|
||||
@ -593,6 +624,8 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
self.driver, '_delete_backing_file_for_snapshot')
|
||||
self.mock_object(self.driver, '_is_flexgroup',
|
||||
return_value=is_flexgroup)
|
||||
self.mock_object(self.driver, '_is_flexgroup_clone_file_supported',
|
||||
return_value=not is_flexgroup)
|
||||
mock_super_delete = self.mock_object(nfs_base.NetAppNfsDriver,
|
||||
'delete_snapshot')
|
||||
self.driver.delete_snapshot(fake.test_snapshot)
|
||||
@ -1230,6 +1263,7 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
return_value=False)
|
||||
drv._copy_from_cache = mock.Mock(return_value=True)
|
||||
drv._is_flexgroup = mock.Mock(return_value=False)
|
||||
drv._is_flexgroup_clone_file_supported = mock.Mock(return_value=True)
|
||||
|
||||
drv.clone_image(context, volume, image_location, image_meta,
|
||||
image_service)
|
||||
@ -1242,6 +1276,9 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
|
||||
def test_clone_image_flexgroup(self):
|
||||
self.driver._is_flexgroup = mock.Mock(return_value=True)
|
||||
mock_clone_file = self.mock_object(
|
||||
self.driver, '_is_flexgroup_clone_file_supported',
|
||||
return_value=False)
|
||||
volume = {'host': 'openstack@nfscmode#192.128.1.1:/mnt_point'}
|
||||
context = object()
|
||||
model, cloned = self.driver.clone_image(
|
||||
@ -1250,6 +1287,7 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
self.assertFalse(cloned)
|
||||
self.assertIsNone(model)
|
||||
self.driver._is_flexgroup.assert_called_once_with(host=volume['host'])
|
||||
mock_clone_file.assert_called_once_with()
|
||||
|
||||
def test_clone_image_copyoffload_from_img_service(self):
|
||||
drv = self.driver
|
||||
@ -1271,6 +1309,7 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
return_value=True)
|
||||
drv._copy_from_img_service = mock.Mock(return_value=True)
|
||||
drv._is_flexgroup = mock.Mock(return_value=False)
|
||||
drv._is_flexgroup_clone_file_supported = mock.Mock(return_value=True)
|
||||
|
||||
retval = drv.clone_image(
|
||||
context, volume, image_location, image_meta, image_service)
|
||||
@ -1298,6 +1337,7 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
return_value=False)
|
||||
drv._copy_from_img_service = mock.Mock(side_effect=Exception())
|
||||
drv._is_flexgroup = mock.Mock(return_value=False)
|
||||
drv._is_flexgroup_clone_file_supported = mock.Mock(return_value=True)
|
||||
|
||||
retval = drv.clone_image(
|
||||
context, volume, image_location, image_meta, image_service)
|
||||
@ -1822,3 +1862,11 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
self.assertEqual('deleted', model_update['status'])
|
||||
self.assertEqual('deleted', volumes[0]['status'])
|
||||
mock_delete_file.assert_called_once_with(fake.VG_VOLUME)
|
||||
|
||||
def test__is_flexgroup_clone_file_supported(self):
|
||||
self.driver.zapi_client = mock.Mock(features=mock.Mock(
|
||||
FLEXGROUP_CLONE_FILE=True))
|
||||
|
||||
is_fg_clone = self.driver._is_flexgroup_clone_file_supported()
|
||||
|
||||
self.assertTrue(is_fg_clone)
|
||||
|
@ -583,3 +583,32 @@ class CapabilitiesLibraryTestCase(test.TestCase):
|
||||
self.assertEqual(expected, result)
|
||||
self.zapi_client.is_qos_min_supported.assert_called_once_with(False,
|
||||
'node')
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_is_flexgroup(self, is_fg):
|
||||
pool_name = 'fake_pool'
|
||||
self.ssc_library.ssc = {
|
||||
pool_name: {
|
||||
'pool_name': pool_name,
|
||||
'netapp_is_flexgroup': 'true' if is_fg else 'false',
|
||||
},
|
||||
}
|
||||
|
||||
if not is_fg:
|
||||
pool_name = 'no_pool'
|
||||
|
||||
is_fg_returned = self.ssc_library.is_flexgroup(pool_name)
|
||||
|
||||
self.assertEqual(is_fg_returned, is_fg)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_contains_flexgroup(self, contains_fg):
|
||||
self.ssc_library.ssc = {
|
||||
'fake_pool': {
|
||||
'netapp_is_flexgroup': 'true' if contains_fg else 'false',
|
||||
},
|
||||
}
|
||||
|
||||
contains_fg_returned = self.ssc_library.contains_flexgroup_pool()
|
||||
|
||||
self.assertEqual(contains_fg_returned, contains_fg)
|
||||
|
@ -48,7 +48,19 @@ LOG = logging.getLogger(__name__)
|
||||
@six.add_metaclass(volume_utils.TraceWrapperMetaclass)
|
||||
class NetAppBlockStorageCmodeLibrary(block_base.NetAppBlockStorageLibrary,
|
||||
data_motion.DataMotionMixin):
|
||||
"""NetApp block storage library for Data ONTAP (Cluster-mode)."""
|
||||
"""NetApp block storage library for Data ONTAP (Cluster-mode).
|
||||
|
||||
Version history:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
1.0.0 - Driver development before Wallaby
|
||||
2.0.0 - Add support for QoS minimums specs
|
||||
Add support for dynamic Adaptive QoS policy group creation
|
||||
|
||||
"""
|
||||
|
||||
VERSION = "2.0.0"
|
||||
|
||||
REQUIRED_CMODE_FLAGS = ['netapp_vserver']
|
||||
|
||||
|
@ -67,6 +67,8 @@ class Client(client_base.Client):
|
||||
ontapi_1_60 = ontapi_version >= (1, 160)
|
||||
ontapi_1_40 = ontapi_version >= (1, 140)
|
||||
ontapi_1_50 = ontapi_version >= (1, 150)
|
||||
ontapi_1_80 = ontapi_version >= (1, 180)
|
||||
ontapi_1_90 = ontapi_version >= (1, 190)
|
||||
|
||||
nodes_info = self._get_cluster_nodes_info()
|
||||
for node in nodes_info:
|
||||
@ -100,6 +102,9 @@ class Client(client_base.Client):
|
||||
self.features.add_feature('BACKUP_CLONE_PARAM', supported=ontapi_1_100)
|
||||
self.features.add_feature('CLUSTER_PEER_POLICY', supported=ontapi_1_30)
|
||||
self.features.add_feature('FLEXVOL_ENCRYPTION', supported=ontapi_1_1xx)
|
||||
self.features.add_feature('FLEXGROUP', supported=ontapi_1_80)
|
||||
self.features.add_feature('FLEXGROUP_CLONE_FILE',
|
||||
supported=ontapi_1_90)
|
||||
|
||||
self.features.add_feature('ADAPTIVE_QOS', supported=ontapi_1_40)
|
||||
self.features.add_feature('ADAPTIVE_QOS_BLOCK_SIZE',
|
||||
|
@ -179,7 +179,8 @@ class NetAppNfsDriver(driver.ManageableVD,
|
||||
because the ONTAP clone file is not supported by FlexGroup yet.
|
||||
"""
|
||||
self._ensure_flexgroup_not_in_cg(volume)
|
||||
if self._is_flexgroup(vol_id=snapshot['volume_id']):
|
||||
if (self._is_flexgroup(vol_id=snapshot['volume_id']) and
|
||||
not self._is_flexgroup_clone_file_supported()):
|
||||
model = super(NetAppNfsDriver, self).create_volume_from_snapshot(
|
||||
volume, snapshot)
|
||||
|
||||
@ -199,7 +200,8 @@ class NetAppNfsDriver(driver.ManageableVD,
|
||||
because the ONTAP clone file is not supported by FlexGroup yet.
|
||||
"""
|
||||
self._ensure_flexgroup_not_in_cg(volume)
|
||||
if self._is_flexgroup(vol_id=src_vref['id']):
|
||||
if (self._is_flexgroup(vol_id=src_vref['id']) and
|
||||
not self._is_flexgroup_clone_file_supported()):
|
||||
model = super(NetAppNfsDriver, self).create_cloned_volume(
|
||||
volume, src_vref)
|
||||
|
||||
@ -306,7 +308,8 @@ class NetAppNfsDriver(driver.ManageableVD,
|
||||
For a FlexGroup pool, the operation relies on the NFS generic driver
|
||||
because the ONTAP clone file is not supported by FlexGroup yet.
|
||||
"""
|
||||
if self._is_flexgroup(vol_id=snapshot['volume_id']):
|
||||
if (self._is_flexgroup(vol_id=snapshot['volume_id']) and
|
||||
not self._is_flexgroup_clone_file_supported()):
|
||||
self._create_snapshot_for_flexgroup(snapshot)
|
||||
else:
|
||||
self._clone_backing_file_for_volume(snapshot['volume_name'],
|
||||
@ -360,7 +363,8 @@ class NetAppNfsDriver(driver.ManageableVD,
|
||||
|
||||
def delete_snapshot(self, snapshot):
|
||||
"""Deletes a snapshot."""
|
||||
if self._is_flexgroup(vol_id=snapshot.volume_id):
|
||||
if (self._is_flexgroup(vol_id=snapshot.volume_id) and
|
||||
not self._is_flexgroup_clone_file_supported()):
|
||||
super(NetAppNfsDriver, self).delete_snapshot(snapshot)
|
||||
else:
|
||||
self._delete_file(snapshot.volume_id, snapshot.name)
|
||||
@ -477,9 +481,11 @@ class NetAppNfsDriver(driver.ManageableVD,
|
||||
LOG.info('Copied image to volume %s using regular download.',
|
||||
volume['id'])
|
||||
|
||||
if not self._is_flexgroup(host=volume['host']):
|
||||
# NOTE(felipe_rodrigues): FlexGroup does not support FlexClone
|
||||
# file, so the NetApp image cache cannot be used.
|
||||
if (not self._is_flexgroup(host=volume['host']) or
|
||||
self._is_flexgroup_clone_file_supported()):
|
||||
# NOTE(felipe_rodrigues): NetApp image cache relies on the
|
||||
# FlexClone file, which is only available for the earliest
|
||||
# versions of FlexGroup.
|
||||
self._register_image_in_cache(volume, image_id)
|
||||
|
||||
def _register_image_in_cache(self, volume, image_id):
|
||||
@ -641,10 +647,8 @@ class NetAppNfsDriver(driver.ManageableVD,
|
||||
Returns a dict of volume properties eg. provider_location,
|
||||
boolean indicating whether cloning occurred.
|
||||
"""
|
||||
if self._is_flexgroup(host=volume['host']):
|
||||
# NOTE(felipe_rodrigues): FlexGroup does not support FlexClone
|
||||
# file, so the clone_image cannot be used together with the Netapp
|
||||
# cache. Instead, it can use the core cache implementation.
|
||||
if (self._is_flexgroup(host=volume['host']) and
|
||||
not self._is_flexgroup_clone_file_supported()):
|
||||
return None, False
|
||||
|
||||
image_id = image_meta['id']
|
||||
@ -1215,3 +1219,7 @@ class NetAppNfsDriver(driver.ManageableVD,
|
||||
msg = _("Cannot create %s volume on FlexGroup pool with "
|
||||
"consistency group.")
|
||||
raise na_utils.NetAppDriverException(msg % volume['id'])
|
||||
|
||||
def _is_flexgroup_clone_file_supported(self):
|
||||
"""Check whether storage can perform clone file for FlexGroup"""
|
||||
raise NotImplementedError()
|
||||
|
@ -51,7 +51,20 @@ LOG = logging.getLogger(__name__)
|
||||
@six.add_metaclass(volume_utils.TraceWrapperWithABCMetaclass)
|
||||
class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
|
||||
data_motion.DataMotionMixin):
|
||||
"""NetApp NFS driver for Data ONTAP (Cluster-mode)."""
|
||||
"""NetApp NFS driver for Data ONTAP (Cluster-mode).
|
||||
|
||||
Version history:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
1.0.0 - Driver development before Wallaby
|
||||
2.0.0 - Add support for QoS minimums specs
|
||||
Add support for dynamic Adaptive QoS policy group creation
|
||||
Implement FlexGroup pool
|
||||
|
||||
"""
|
||||
|
||||
VERSION = "2.0.0"
|
||||
|
||||
REQUIRED_CMODE_FLAGS = ['netapp_vserver']
|
||||
|
||||
@ -101,6 +114,12 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
|
||||
def check_for_setup_error(self):
|
||||
"""Check that the driver is working and can communicate."""
|
||||
self._add_looping_tasks()
|
||||
|
||||
if (self.ssc_library.contains_flexgroup_pool() and
|
||||
not self.zapi_client.features.FLEXGROUP):
|
||||
msg = _('FlexGroup pool requires Data ONTAP 9.8 or later.')
|
||||
raise na_utils.NetAppDriverException(msg)
|
||||
|
||||
super(NetAppCmodeNfsDriver, self).check_for_setup_error()
|
||||
|
||||
def _add_looping_tasks(self):
|
||||
@ -288,6 +307,7 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
|
||||
if is_flexgroup:
|
||||
pool['consistencygroup_support'] = False
|
||||
pool['consistent_group_snapshot_enabled'] = False
|
||||
pool['multiattach'] = False
|
||||
|
||||
# Add up-to-date capacity info
|
||||
nfs_share = ssc_vol_info['pool_name']
|
||||
@ -452,12 +472,14 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
|
||||
is_flexgroup = self._is_flexgroup(host=volume['host'])
|
||||
try:
|
||||
LOG.debug('Deleting backing file for volume %s.', volume['id'])
|
||||
if is_flexgroup:
|
||||
if (is_flexgroup and
|
||||
not self._is_flexgroup_clone_file_supported()):
|
||||
super(NetAppCmodeNfsDriver, self).delete_volume(volume)
|
||||
else:
|
||||
self._delete_file(volume['id'], volume['name'])
|
||||
except Exception:
|
||||
if is_flexgroup:
|
||||
if (is_flexgroup and
|
||||
not self._is_flexgroup_clone_file_supported()):
|
||||
LOG.exception('Exec of "rm" command on backing file for '
|
||||
'%s was unsuccessful.', volume['id'])
|
||||
else:
|
||||
@ -482,7 +504,8 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
|
||||
|
||||
def delete_snapshot(self, snapshot):
|
||||
"""Deletes a snapshot."""
|
||||
if self._is_flexgroup(snapshot['volume_id']):
|
||||
if (self._is_flexgroup(snapshot['volume_id']) and
|
||||
not self._is_flexgroup_clone_file_supported()):
|
||||
super(NetAppCmodeNfsDriver, self).delete_snapshot(snapshot)
|
||||
else:
|
||||
self._delete_backing_file_for_snapshot(snapshot)
|
||||
@ -957,3 +980,7 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
|
||||
|
||||
pool_name = volume_utils.extract_host(host, level='pool')
|
||||
return self.ssc_library.is_flexgroup(pool_name)
|
||||
|
||||
def _is_flexgroup_clone_file_supported(self):
|
||||
"""Check whether storage can perform clone file for FlexGroup"""
|
||||
return self.zapi_client.features.FLEXGROUP_CLONE_FILE
|
||||
|
@ -378,3 +378,11 @@ class CapabilitiesLibrary(object):
|
||||
return flexvol_info['netapp_is_flexgroup'] == 'true'
|
||||
|
||||
return False
|
||||
|
||||
def contains_flexgroup_pool(self):
|
||||
for __, flexvol_info in self.ssc.items():
|
||||
if ('netapp_is_flexgroup' in flexvol_info and
|
||||
flexvol_info['netapp_is_flexgroup'] == 'true'):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
@ -4,29 +4,34 @@ features:
|
||||
NetApp ONTAP driver: added support for FlexGroup pool using the NFS
|
||||
mode. There are several considerations for using the driver with it:
|
||||
|
||||
1. The FlexGroup pool has a different view of aggregate capabilites,
|
||||
1. The FlexGroup pool is only supported using ONTAP storage 9.8 or greater.
|
||||
|
||||
2. The FlexGroup pool has a different view of aggregate capabilites,
|
||||
changing them by a list of elements, instead of a single element. They
|
||||
are ``netapp_aggregate``, ``netapp_raid_type``, ``netapp_disk_type`` and
|
||||
``netapp_hybrid_aggregate``. The ``netapp_aggregate_used_percent``
|
||||
capability is an average of used percent of all FlexGroup's aggregates.
|
||||
|
||||
2. The ``utilization`` capability is not calculated to FlexGroup pools, it is
|
||||
3. The ``utilization`` capability is not calculated to FlexGroup pools, it is
|
||||
always set to default of 50.
|
||||
|
||||
3. The driver cannot support consistency group with volumes that are over
|
||||
4. The driver cannot support consistency group with volumes that are over
|
||||
FlexGroup pools.
|
||||
|
||||
4. For volumes over the FlexGroup pool, the operations of clone volume,
|
||||
5. The driver cannot support multi-attach with volumes that are over
|
||||
FlexGroup pools.
|
||||
|
||||
6. For volumes over the FlexGroup pool, the operations of clone volume,
|
||||
create snapshot and create volume from an image are implemented as the NFS
|
||||
generic driver. Hence, it does not rely on the ONTAP storage to perform
|
||||
those operations.
|
||||
|
||||
5. A driver with FlexGroup pools has snapshot support disabled by default. To
|
||||
7. A driver with FlexGroup pools has snapshot support disabled by default. To
|
||||
enable, you must set ``nfs_snapshot_support`` to true in the backend's configuration
|
||||
section of the cinder configuration file.
|
||||
|
||||
6. The driver image cache is not applied for volumes over FlexGroup pools.
|
||||
8. The driver image cache is not applied for volumes over FlexGroup pools.
|
||||
It can use the core image cache for avoiding downloading twice, though.
|
||||
|
||||
7. Given that the FlexGroup pool may be on several cluster nodes, the QoS minimum
|
||||
9. Given that the FlexGroup pool may be on several cluster nodes, the QoS minimum
|
||||
support is only enabled if all nodes support it.
|
||||
|
Loading…
Reference in New Issue
Block a user