Merge "More Manila cDOT qualified specs"
This commit is contained in:
commit
048bed870f
@ -760,7 +760,9 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
@na_utils.trace
|
||||
def create_volume(self, aggregate_name, volume_name, size_gb,
|
||||
thin_provisioned=False, snapshot_policy=None,
|
||||
language=None, max_files=None):
|
||||
language=None, dedup_enabled=False,
|
||||
compression_enabled=False, max_files=None):
|
||||
|
||||
"""Creates a volume."""
|
||||
api_args = {
|
||||
'containing-aggr-name': aggregate_name,
|
||||
@ -776,9 +778,29 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
api_args['language-code'] = language
|
||||
self.send_request('volume-create', api_args)
|
||||
|
||||
# cDOT compression requires that deduplication be enabled.
|
||||
if dedup_enabled or compression_enabled:
|
||||
self.enable_dedup(volume_name)
|
||||
if compression_enabled:
|
||||
self.enable_compression(volume_name)
|
||||
if max_files is not None:
|
||||
self.set_volume_max_files(volume_name, max_files)
|
||||
|
||||
@na_utils.trace
|
||||
def enable_dedup(self, volume_name):
|
||||
"""Enable deduplication on volume."""
|
||||
api_args = {'path': '/vol/%s' % volume_name}
|
||||
self.send_request('sis-enable', api_args)
|
||||
|
||||
@na_utils.trace
|
||||
def enable_compression(self, volume_name):
|
||||
"""Enable compression on volume."""
|
||||
api_args = {
|
||||
'path': '/vol/%s' % volume_name,
|
||||
'enable-compression': 'true'
|
||||
}
|
||||
self.send_request('sis-set-config', api_args)
|
||||
|
||||
@na_utils.trace
|
||||
def set_volume_max_files(self, volume_name, max_files):
|
||||
"""Set flexvol file limit."""
|
||||
|
@ -51,7 +51,9 @@ class NetAppCmodeFileStorageLibrary(object):
|
||||
# client library argument keywords. When we expose more backend
|
||||
# capabilities here, we will add them to this map.
|
||||
BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP = {
|
||||
'netapp:thin_provisioned': 'thin_provisioned'
|
||||
'netapp:thin_provisioned': 'thin_provisioned',
|
||||
'netapp:dedup': 'dedup_enabled',
|
||||
'netapp:compression': 'compression_enabled',
|
||||
}
|
||||
STRING_QUALIFIED_EXTRA_SPECS_MAP = {
|
||||
'netapp:snapshot_policy': 'snapshot_policy',
|
||||
@ -358,9 +360,6 @@ class NetAppCmodeFileStorageLibrary(object):
|
||||
'provisioning options %(options)s',
|
||||
{'share': share_name, 'pool': pool_name,
|
||||
'options': provisioning_options})
|
||||
|
||||
LOG.debug('Creating share %(share)s on pool %(pool)s',
|
||||
{'share': share_name, 'pool': pool_name})
|
||||
vserver_client.create_volume(pool_name, share_name,
|
||||
share['size'],
|
||||
**provisioning_options)
|
||||
@ -392,6 +391,21 @@ class NetAppCmodeFileStorageLibrary(object):
|
||||
@na_utils.trace
|
||||
def _check_boolean_extra_specs_validity(self, share, specs,
|
||||
keys_of_interest):
|
||||
# cDOT compression requires deduplication.
|
||||
dedup = specs.get('netapp:dedup', None)
|
||||
compression = specs.get('netapp:compression', None)
|
||||
if dedup is not None and compression is not None:
|
||||
if dedup.lower() == 'false' and compression.lower() == 'true':
|
||||
spec = {'netapp:dedup': dedup,
|
||||
'netapp:compression': compression}
|
||||
type_id = share['share_type_id']
|
||||
share_id = share['id']
|
||||
args = {'type_id': type_id, 'share_id': share_id, 'spec': spec}
|
||||
msg = _('Invalid combination of extra_specs in share_type '
|
||||
'%(type_id)s for share %(share_id)s: %(spec)s: '
|
||||
'deduplication must be enabled in order for '
|
||||
'compression to be enabled.')
|
||||
raise exception.Invalid(msg % args)
|
||||
"""Check if the boolean_extra_specs have valid values."""
|
||||
# Extra spec values must be (ignoring case) 'true' or 'false'.
|
||||
for key in keys_of_interest:
|
||||
|
@ -1383,12 +1383,15 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
def test_create_volume_with_extra_specs(self):
|
||||
|
||||
self.mock_object(self.client, 'set_volume_max_files')
|
||||
self.mock_object(self.client, 'enable_dedup')
|
||||
self.mock_object(self.client, 'enable_compression')
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
self.client.create_volume(
|
||||
fake.SHARE_AGGREGATE_NAME, fake.SHARE_NAME, 100,
|
||||
thin_provisioned=True, language='en-US',
|
||||
snapshot_policy='default', max_files=5000)
|
||||
snapshot_policy='default', dedup_enabled=True,
|
||||
compression_enabled=True, max_files=5000)
|
||||
|
||||
volume_create_args = {
|
||||
'containing-aggr-name': fake.SHARE_AGGREGATE_NAME,
|
||||
@ -1404,6 +1407,8 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
volume_create_args)
|
||||
self.client.set_volume_max_files.assert_called_once_with(
|
||||
fake.SHARE_NAME, fake.MAX_FILES)
|
||||
self.client.enable_dedup.assert_called_once_with(fake.SHARE_NAME)
|
||||
self.client.enable_compression.assert_called_once_with(fake.SHARE_NAME)
|
||||
|
||||
def test_set_volume_max_files(self):
|
||||
|
||||
@ -1431,6 +1436,31 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
self.client.send_request.assert_called_once_with(
|
||||
'volume-modify-iter', volume_modify_iter_api_args)
|
||||
|
||||
def test_enable_dedup(self):
|
||||
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
self.client.enable_dedup(fake.SHARE_NAME)
|
||||
|
||||
sis_enable_args = {'path': '/vol/%s' % fake.SHARE_NAME}
|
||||
|
||||
self.client.send_request.assert_called_once_with('sis-enable',
|
||||
sis_enable_args)
|
||||
|
||||
def test_enable_compression(self):
|
||||
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
||||
self.client.enable_compression(fake.SHARE_NAME)
|
||||
|
||||
sis_set_config_args = {
|
||||
'path': '/vol/%s' % fake.SHARE_NAME,
|
||||
'enable-compression': 'true'
|
||||
}
|
||||
|
||||
self.client.send_request.assert_called_once_with('sis-set-config',
|
||||
sis_set_config_args)
|
||||
|
||||
def test_volume_exists(self):
|
||||
|
||||
api_response = netapp_api.NaElement(fake.VOLUME_GET_NAME_RESPONSE)
|
||||
|
@ -538,6 +538,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
return_value=fake.POOL_NAME))
|
||||
self.mock_object(share_types, 'get_extra_specs_from_share',
|
||||
mock.Mock(return_value=fake.EXTRA_SPEC))
|
||||
|
||||
self.mock_object(self.library, '_check_boolean_extra_specs_validity')
|
||||
self.mock_object(self.library, '_get_boolean_provisioning_options',
|
||||
mock.Mock(return_value=fake.PROVISIONING_OPTIONS))
|
||||
@ -549,7 +550,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
vserver_client.create_volume.assert_called_once_with(
|
||||
fake.POOL_NAME, fake.SHARE_NAME, fake.SHARE['size'],
|
||||
thin_provisioned=True, snapshot_policy='default',
|
||||
language='en-US', max_files=5000)
|
||||
language='en-US', dedup_enabled=True,
|
||||
compression_enabled=False, max_files=5000)
|
||||
|
||||
def test_allocate_container_no_pool_name(self):
|
||||
self.mock_object(self.library, '_get_valid_share_name', mock.Mock(
|
||||
@ -573,42 +575,50 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
self.assertEqual(0, self.library._get_provisioning_options.call_count)
|
||||
|
||||
def test_check_extra_specs_validity(self):
|
||||
boolean_extra_spec_keys = list(
|
||||
self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP)
|
||||
mock_bool_check = self.mock_object(
|
||||
self.library, '_check_boolean_extra_specs_validity')
|
||||
mock_string_check = self.mock_object(
|
||||
self.library, '_check_string_extra_specs_validity')
|
||||
|
||||
self.library._check_extra_specs_validity(
|
||||
fake.EXTRA_SPEC_SHARE, fake.EXTRA_SPEC)
|
||||
|
||||
mock_bool_check.assert_called_once_with(
|
||||
fake.EXTRA_SPEC_SHARE, fake.EXTRA_SPEC, boolean_extra_spec_keys)
|
||||
mock_string_check.assert_called_once_with(
|
||||
fake.EXTRA_SPEC_SHARE, fake.EXTRA_SPEC)
|
||||
|
||||
def test_check_extra_specs_validity_empty_spec(self):
|
||||
self.library._check_extra_specs_validity(
|
||||
result = self.library._check_extra_specs_validity(
|
||||
fake.EXTRA_SPEC_SHARE, fake.EMPTY_EXTRA_SPEC)
|
||||
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_check_extra_specs_validity_invalid_value(self):
|
||||
self.assertRaises(
|
||||
exception.Invalid, self.library._check_extra_specs_validity,
|
||||
fake.EXTRA_SPEC_SHARE, fake.INVALID_EXTRA_SPEC)
|
||||
|
||||
def test_check_string_extra_specs_validity(self):
|
||||
self.library._check_string_extra_specs_validity(
|
||||
result = self.library._check_string_extra_specs_validity(
|
||||
fake.EXTRA_SPEC_SHARE, fake.EXTRA_SPEC)
|
||||
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_check_string_extra_specs_validity_empty_spec(self):
|
||||
self.library._check_string_extra_specs_validity(
|
||||
result = self.library._check_string_extra_specs_validity(
|
||||
fake.EXTRA_SPEC_SHARE, fake.EMPTY_EXTRA_SPEC)
|
||||
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_check_string_extra_specs_validity_invalid_value(self):
|
||||
self.assertRaises(
|
||||
exception.NetAppException,
|
||||
self.library._check_string_extra_specs_validity,
|
||||
fake.EXTRA_SPEC_SHARE, fake.INVALID_MAX_FILE_EXTRA_SPEC)
|
||||
|
||||
def test_check_boolean_extra_specs_validity(self):
|
||||
self.library._check_boolean_extra_specs_validity(
|
||||
fake.EXTRA_SPEC_SHARE, fake.EXTRA_SPEC,
|
||||
list(self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP))
|
||||
|
||||
def test_check_boolean_extra_specs_validity_empty_spec(self):
|
||||
self.library._check_boolean_extra_specs_validity(
|
||||
fake.EXTRA_SPEC_SHARE, fake.EMPTY_EXTRA_SPEC,
|
||||
list(self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP))
|
||||
|
||||
def test_check_boolean_extra_specs_validity_invalid_value(self):
|
||||
self.assertRaises(
|
||||
exception.Invalid,
|
||||
@ -616,6 +626,13 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
fake.EXTRA_SPEC_SHARE, fake.INVALID_EXTRA_SPEC,
|
||||
list(self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP))
|
||||
|
||||
def test_check_extra_specs_validity_invalid_combination(self):
|
||||
self.assertRaises(
|
||||
exception.Invalid,
|
||||
self.library._check_boolean_extra_specs_validity,
|
||||
fake.EXTRA_SPEC_SHARE, fake.INVALID_EXTRA_SPEC_COMBO,
|
||||
list(self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP))
|
||||
|
||||
def test_get_provisioning_options(self):
|
||||
result = self.library._get_provisioning_options(fake.EXTRA_SPEC)
|
||||
|
||||
@ -632,15 +649,20 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
result = self.library._get_provisioning_options(
|
||||
fake.EMPTY_EXTRA_SPEC)
|
||||
|
||||
expected = {'language': None, 'max_files': None,
|
||||
'snapshot_policy': None,
|
||||
'thin_provisioned': False}
|
||||
expected = {
|
||||
'language': None,
|
||||
'max_files': None,
|
||||
'snapshot_policy': None,
|
||||
'thin_provisioned': False,
|
||||
'compression_enabled': False,
|
||||
'dedup_enabled': False,
|
||||
}
|
||||
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_get_boolean_provisioning_options(self):
|
||||
result = self.library._get_boolean_provisioning_options(
|
||||
fake.BOOLEAN_EXTRA_SPEC,
|
||||
fake.SHORT_BOOLEAN_EXTRA_SPEC,
|
||||
self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP)
|
||||
|
||||
self.assertEqual(fake.PROVISIONING_OPTIONS_BOOLEAN, result)
|
||||
@ -653,11 +675,17 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
self.assertEqual(fake.PROVISIONING_OPTIONS_BOOLEAN, result)
|
||||
|
||||
def test_get_boolean_provisioning_options_implicit_false(self):
|
||||
expected = {
|
||||
'thin_provisioned': False,
|
||||
'dedup_enabled': False,
|
||||
'compression_enabled': False,
|
||||
}
|
||||
|
||||
result = self.library._get_boolean_provisioning_options(
|
||||
fake.EMPTY_EXTRA_SPEC,
|
||||
self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP)
|
||||
|
||||
self.assertEqual({'thin_provisioned': False}, result)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_get_string_provisioning_options(self):
|
||||
result = self.library._get_string_provisioning_options(
|
||||
|
@ -80,6 +80,8 @@ EXTRA_SPEC = {
|
||||
'netapp:thin_provisioned': 'true',
|
||||
'netapp:snapshot_policy': 'default',
|
||||
'netapp:language': 'en-US',
|
||||
'netapp:dedup': 'True',
|
||||
'netapp:compression': 'false',
|
||||
'netapp:max_files': 5000,
|
||||
}
|
||||
|
||||
@ -87,17 +89,23 @@ PROVISIONING_OPTIONS = {
|
||||
'thin_provisioned': True,
|
||||
'snapshot_policy': 'default',
|
||||
'language': 'en-US',
|
||||
'dedup_enabled': True,
|
||||
'compression_enabled': False,
|
||||
'max_files': 5000,
|
||||
}
|
||||
|
||||
PROVISIONING_OPTIONS_BOOLEAN = {
|
||||
'thin_provisioned': True,
|
||||
'dedup_enabled': False,
|
||||
'compression_enabled': False,
|
||||
}
|
||||
|
||||
PROVISIONING_OPTIONS_BOOLEAN_THIN_PROVISIONED_TRUE = {
|
||||
'thin_provisioned': True,
|
||||
'snapshot_policy': None,
|
||||
'language': None,
|
||||
'dedup_enabled': False,
|
||||
'compression_enabled': False,
|
||||
'max_files': None,
|
||||
}
|
||||
|
||||
@ -140,19 +148,15 @@ INVALID_EXTRA_SPEC = {
|
||||
'netapp:language': 'abc',
|
||||
}
|
||||
|
||||
INVALID_EXTRA_SPEC_COMBO = {
|
||||
'netapp:dedup': 'false',
|
||||
'netapp:compression': 'true'
|
||||
}
|
||||
|
||||
INVALID_MAX_FILE_EXTRA_SPEC = {
|
||||
'netapp:max_files': -1,
|
||||
}
|
||||
|
||||
BOOLEAN_EXTRA_SPEC = {
|
||||
'netapp:thin_provisioned': 'true',
|
||||
}
|
||||
|
||||
BOOLEAN_SHORT_EXTRA_SPEC = {
|
||||
'netapp:thin_provisioned': 'true',
|
||||
}
|
||||
|
||||
|
||||
EMPTY_EXTRA_SPEC = {}
|
||||
|
||||
SHARE_TYPE = {
|
||||
|
Loading…
Reference in New Issue
Block a user