diff --git a/manila/share/drivers/huawei/constants.py b/manila/share/drivers/huawei/constants.py index ac8236a59f..1cf77cc7fd 100644 --- a/manila/share/drivers/huawei/constants.py +++ b/manila/share/drivers/huawei/constants.py @@ -32,11 +32,14 @@ ERROR_CONNECT_TO_SERVER = -403 ERROR_UNAUTHORIZED_TO_SERVER = -401 ALLOC_TYPE_THIN_FLAG = "1" +ALLOC_TYPE_THICK_FLAG = "0" + ALLOC_TYPE_THIN = "Thin" ALLOC_TYPE_THICK = "Thick" THIN_PROVISIONING = "true" THICK_PROVISIONING = "false" + OPTS_CAPABILITIES = { 'dedupe': False, 'compression': False, diff --git a/manila/share/drivers/huawei/v3/connection.py b/manila/share/drivers/huawei/v3/connection.py index 5d3c97e912..0c75d62412 100644 --- a/manila/share/drivers/huawei/v3/connection.py +++ b/manila/share/drivers/huawei/v3/connection.py @@ -236,38 +236,36 @@ class V3StorageConnection(driver.HuaweiBase): all_pool_info = self.helper._find_all_pool_info() stats_dict["pools"] = [] - for pool_type in ('Thin', 'Thick'): - pool_name_list = root.findtext(('Filesystem/%s_StoragePool' - % pool_type)) - pool_name_list = pool_name_list.split(";") - for pool_name in pool_name_list: - pool_name = pool_name.strip().strip('\n') - capacity = self._get_capacity(pool_name, all_pool_info) - if capacity: - pool = dict( - pool_name=pool_name, - total_capacity_gb=capacity['TOTALCAPACITY'], - free_capacity_gb=capacity['CAPACITY'], - provisioned_capacity_gb=( - capacity['PROVISIONEDCAPACITYGB']), - max_over_subscription_ratio=( - self.configuration.safe_get( - 'max_over_subscription_ratio')), - allocated_capacity_gb=capacity['CONSUMEDCAPACITY'], - QoS_support=False, - reserved_percentage=0, - thin_provisioning=(pool_type == 'Thin'), - dedupe=(pool_type == 'Thin'), - compression=(pool_type == 'Thin'), - huawei_smartcache=True, - huawei_smartpartition=True, - ) - stats_dict["pools"].append(pool) + pool_name_list = root.findtext('Filesystem/StoragePool') + pool_name_list = pool_name_list.split(";") + for pool_name in pool_name_list: + pool_name = pool_name.strip().strip('\n') + capacity = self._get_capacity(pool_name, all_pool_info) + if capacity: + pool = dict( + pool_name=pool_name, + total_capacity_gb=capacity['TOTALCAPACITY'], + free_capacity_gb=capacity['CAPACITY'], + provisioned_capacity_gb=( + capacity['PROVISIONEDCAPACITYGB']), + max_over_subscription_ratio=( + self.configuration.safe_get( + 'max_over_subscription_ratio')), + allocated_capacity_gb=capacity['CONSUMEDCAPACITY'], + QoS_support=False, + reserved_percentage=0, + thin_provisioning=[True, False], + dedupe=[True, False], + compression=[True, False], + huawei_smartcache=[True, False], + huawei_smartpartition=[True, False], + ) + stats_dict["pools"].append(pool) if not stats_dict["pools"]: err_msg = _("The StoragePool is None.") LOG.error(err_msg) - raise exception.InvalidInput(err_msg) + raise exception.InvalidInput(reason=err_msg) def delete_share(self, share, share_server=None): """Delete share.""" @@ -323,8 +321,7 @@ class V3StorageConnection(driver.HuaweiBase): fileparam = { "NAME": name.replace("-", "_"), "DESCRIPTION": "", - "ALLOCTYPE": (1 if poolinfo['type'] == 'Thin' - else 0), + "ALLOCTYPE": constants.ALLOC_TYPE_THIN_FLAG, "CAPACITY": size, "PARENTID": poolinfo['ID'], "INITIALALLOCCAPACITY": units.Ki * 20, @@ -340,6 +337,25 @@ class V3StorageConnection(driver.HuaweiBase): "ENABLECOMPRESSION": extra_specs['compression'], } + if 'LUNType' in extra_specs: + fileparam['ALLOCTYPE'] = extra_specs['LUNType'] + else: + root = self.helper._read_xml() + fstype = root.findtext('Filesystem/AllocType') + if fstype: + fstype = fstype.strip().strip('\n') + if fstype == 'Thin': + fileparam['ALLOCTYPE'] = constants.ALLOC_TYPE_THIN_FLAG + elif fstype == 'Thick': + fileparam['ALLOCTYPE'] = constants.ALLOC_TYPE_THICK_FLAG + else: + err_msg = (_( + 'Config file is wrong. AllocType type must be set to' + ' "Thin" or "Thick". AllocType:%(fetchtype)s') % + {'fetchtype': fstype}) + LOG.error(err_msg) + raise exception.InvalidShare(reason=err_msg) + if fileparam['ALLOCTYPE'] == 0: if (extra_specs['dedupe'] or extra_specs['compression']): @@ -619,15 +635,12 @@ class V3StorageConnection(driver.HuaweiBase): else: opts['thin_provisioning'] = constants.ALLOC_TYPE_THICK - if (fs['ALLOCTYPE'] != poolinfo['type'] - or fs['ALLOCTYPE'] != opts['thin_provisioning']): - msg = (_("Manage existing share fs type and pool type " - "or fs type and new_share_type mismatch. " - "fs type is: %(fs_type)s, pool type is: " - "%(pool_type)s, new_share_type is: " - "%(new_share_type)s") + if fs['ALLOCTYPE'] != opts['thin_provisioning']: + msg = (_("Manage existing share " + "fs type and new_share_type mismatch. " + "fs type is: %(fs_type)s, " + "new_share_type is: %(new_share_type)s") % {"fs_type": fs['ALLOCTYPE'], - "pool_type": poolinfo['type'], "new_share_type": opts['thin_provisioning']}) raise exception.InvalidHost(reason=msg) else: @@ -761,8 +774,7 @@ class V3StorageConnection(driver.HuaweiBase): username = root.findtext('Storage/UserName') pwd = root.findtext('Storage/UserPassword') product = root.findtext('Storage/Product') - thin_pool_node = root.findtext('Filesystem/Thin_StoragePool') - thick_pool_node = root.findtext('Filesystem/Thick_StoragePool') + pool_node = root.findtext('Filesystem/StoragePool') if product != "V3": err_msg = (_( @@ -778,10 +790,10 @@ class V3StorageConnection(driver.HuaweiBase): LOG.error(err_msg) raise exception.InvalidInput(err_msg) - if (not thin_pool_node) and (not thick_pool_node): + if not pool_node: err_msg = (_( 'check_conf_file: Config file invalid. ' - 'Thin_StoragePool or Thick_StoragePool must be set.')) + 'StoragePool must be set.')) LOG.error(err_msg) raise exception.InvalidInput(err_msg) diff --git a/manila/share/drivers/huawei/v3/helper.py b/manila/share/drivers/huawei/v3/helper.py index 7be3ed91b8..815181f57c 100644 --- a/manila/share/drivers/huawei/v3/helper.py +++ b/manila/share/drivers/huawei/v3/helper.py @@ -331,17 +331,6 @@ class RestHelper(object): self._assert_rest_result(result, 'Start CIFS service error.') - def _find_pool_type(self, poolinfo): - root = self._read_xml() - for pool_type in ('Thin', 'Thick'): - pool_name_list = root.findtext(('Filesystem/%s_StoragePool' - % pool_type)) - pool_name_list = pool_name_list.split(";") - for pool_name in pool_name_list: - pool_name = pool_name.strip().strip('\n') - if poolinfo['name'] == pool_name: - poolinfo['type'] = pool_type - def _find_pool_info(self, pool_name, result): if pool_name is None: return @@ -355,7 +344,6 @@ class RestHelper(object): poolinfo['CAPACITY'] = item['USERFREECAPACITY'] poolinfo['TOTALCAPACITY'] = item['USERTOTALCAPACITY'] poolinfo['CONSUMEDCAPACITY'] = item['USERCONSUMEDCAPACITY'] - self._find_pool_type(poolinfo) break return poolinfo diff --git a/manila/tests/share/drivers/huawei/test_huawei_nas.py b/manila/tests/share/drivers/huawei/test_huawei_nas.py index 6a72eee85e..0d7a8da095 100644 --- a/manila/tests/share/drivers/huawei/test_huawei_nas.py +++ b/manila/tests/share/drivers/huawei/test_huawei_nas.py @@ -337,12 +337,6 @@ class FakeHuaweiNasHelper(helper.RestHelper): "NAME":"OpenStack_Pool", "USERTOTALCAPACITY":"4194304", "USAGETYPE":"2", - "USERCONSUMEDCAPACITY":"2097152"}, - {"USERFREECAPACITY":"2097152", - "ID":"2", - "NAME":"OpenStack_Pool_Thick", - "USERTOTALCAPACITY":"4194304", - "USAGETYPE":"2", "USERCONSUMEDCAPACITY":"2097152"}]}""" if url == "/filesystem": @@ -1028,6 +1022,17 @@ class HuaweiShareDriverTestCase(test.TestCase): self.assertRaises(exception.InvalidInput, self.driver.get_backend_driver) + def test_create_share_nfs_alloctype_fail(self): + self.recreate_fake_conf_file(alloctype_value='alloctype_fail') + self.driver.plugin.configuration.manila_huawei_conf_file = ( + self.fake_conf_file) + self.driver.plugin.helper.login() + self.assertRaises(exception.InvalidShare, + self.driver.create_share, + self._context, + self.share_nfs, + self.share_server) + def test_create_share_storagepool_not_exist(self): self.driver.plugin.helper.login() self.assertRaises(exception.InvalidHost, @@ -1095,6 +1100,7 @@ class HuaweiShareDriverTestCase(test.TestCase): 'share_type_get', mock.Mock(return_value=share_type)) self.driver.plugin.helper.login() + self.recreate_fake_conf_file(alloctype_value='Thin') self.driver.plugin.configuration.manila_huawei_conf_file = ( self.fake_conf_file) self.driver.plugin.helper.login() @@ -1195,6 +1201,7 @@ class HuaweiShareDriverTestCase(test.TestCase): self.mock_object(db, 'share_type_get', mock.Mock(return_value=share_type)) + self.recreate_fake_conf_file(alloctype_value='Thin') self.driver.plugin.configuration.manila_huawei_conf_file = ( self.fake_conf_file) self.driver.plugin.helper.login() @@ -1237,7 +1244,7 @@ class HuaweiShareDriverTestCase(test.TestCase): self.assertRaises(exception.InvalidShare, self.driver.create_share, self._context, - self.share_nfs_thick, + self.share_nfs, self.share_server) def test_create_share_cache_not_exist(self): @@ -1400,38 +1407,22 @@ class HuaweiShareDriverTestCase(test.TestCase): expected['QoS_support'] = False expected["snapshot_support"] = False expected["pools"] = [] - pool_thin = dict( + pool = dict( pool_name='OpenStack_Pool', total_capacity_gb=2.0, free_capacity_gb=1.0, allocated_capacity_gb=1.0, QoS_support=False, reserved_percentage=0, - compression=True, - dedupe=True, + compression=[True, False], + dedupe=[True, False], max_over_subscription_ratio=1, provisioned_capacity_gb=1.0, - thin_provisioning=True, - huawei_smartcache=True, - huawei_smartpartition=True, + thin_provisioning=[True, False], + huawei_smartcache=[True, False], + huawei_smartpartition=[True, False], ) - pool_thick = dict( - pool_name='OpenStack_Pool_Thick', - total_capacity_gb=2.0, - free_capacity_gb=1.0, - allocated_capacity_gb=1.0, - QoS_support=False, - reserved_percentage=0, - compression=False, - dedupe=False, - max_over_subscription_ratio=1, - provisioned_capacity_gb=1.0, - thin_provisioning=False, - huawei_smartcache=True, - huawei_smartpartition=True, - ) - expected["pools"].append(pool_thin) - expected["pools"].append(pool_thick) + expected["pools"].append(pool) self.assertEqual(expected, self.driver._stats) def test_allow_access_proto_fail(self): @@ -1991,6 +1982,7 @@ class HuaweiShareDriverTestCase(test.TestCase): product_flag=True, username_flag=True, pool_node_flag=True, timeout_flag=True, wait_interval_flag=True, + alloctype_value='Thick', multi_url=False, logical_port_ip='100.115.10.68'): doc = xml.dom.minidom.Document() @@ -2042,19 +2034,12 @@ class HuaweiShareDriverTestCase(test.TestCase): lun = doc.createElement('Filesystem') config.appendChild(lun) - thin_storagepool = doc.createElement('Thin_StoragePool') + storagepool = doc.createElement('StoragePool') if pool_node_flag: pool_text = doc.createTextNode('OpenStack_Pool;OpenStack_Pool2; ;') else: pool_text = doc.createTextNode('') - thin_storagepool.appendChild(pool_text) - - thick_storagepool = doc.createElement('Thick_StoragePool') - if pool_node_flag: - pool_text = doc.createTextNode('OpenStack_Pool_Thick') - else: - pool_text = doc.createTextNode('') - thick_storagepool.appendChild(pool_text) + storagepool.appendChild(pool_text) timeout = doc.createElement('Timeout') @@ -2071,10 +2056,14 @@ class HuaweiShareDriverTestCase(test.TestCase): waitinterval_text = doc.createTextNode('') waitinterval.appendChild(waitinterval_text) + alloctype = doc.createElement('AllocType') + alloctype_text = doc.createTextNode(alloctype_value) + alloctype.appendChild(alloctype_text) + lun.appendChild(timeout) + lun.appendChild(alloctype) lun.appendChild(waitinterval) - lun.appendChild(thin_storagepool) - lun.appendChild(thick_storagepool) + lun.appendChild(storagepool) prefetch = doc.createElement('Prefetch') prefetch.setAttribute('Type', '0') @@ -2088,6 +2077,7 @@ class HuaweiShareDriverTestCase(test.TestCase): def recreate_fake_conf_file(self, product_flag=True, username_flag=True, pool_node_flag=True, timeout_flag=True, wait_interval_flag=True, + alloctype_value='Thick', multi_url=False, logical_port_ip='100.115.10.68'): self.tmp_dir = tempfile.mkdtemp() @@ -2096,6 +2086,6 @@ class HuaweiShareDriverTestCase(test.TestCase): self.create_fake_conf_file(self.fake_conf_file, product_flag, username_flag, pool_node_flag, timeout_flag, wait_interval_flag, - multi_url, + alloctype_value, multi_url, logical_port_ip) self.addCleanup(os.remove, self.fake_conf_file)