Skip to content

Commit

Permalink
Merge pull request #40 from huangpeng5/cloud_cinder_715
Browse files Browse the repository at this point in the history
Huawei Cloud Cinder Driver 2.6.1 Pathch
  • Loading branch information
yunqifeng authored Jul 20, 2023
2 parents 17482ae + 72fa120 commit 1ee90e3
Show file tree
Hide file tree
Showing 40 changed files with 1,288 additions and 261 deletions.
2 changes: 1 addition & 1 deletion Cinder/Mitaka/dsware.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@

class DSWAREDriver(driver.VolumeDriver):
"""Huawei FusionStorage Driver."""
VERSION = "2.6.1"
VERSION = "2.6.2"

# ThirdPartySystems wiki page
CI_WIKI_NAME = "Huawei_FusionStorage_CI"
Expand Down
28 changes: 24 additions & 4 deletions Cinder/Newton/dsware.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@

@interface.volumedriver
class DSWAREBaseDriver(driver.VolumeDriver):
VERSION = "2.6.1"
VERSION = "2.6.2"
CI_WIKI_NAME = 'Huawei_FusionStorage_CI'

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -200,7 +200,7 @@ def _get_capacity(self, pool_info):
total = float(pool_info['totalCapacity']) / units.Ki
free = (float(pool_info['totalCapacity']) -
float(pool_info['usedCapacity'])) / units.Ki
provisioned = float(pool_info['usedCapacity']) / units.Ki
provisioned = float(pool_info['allocatedCapacity']) / units.Ki
pool_capacity['total_capacity_gb'] = total
pool_capacity['free_capacity_gb'] = free
pool_capacity['provisioned_capacity_gb'] = provisioned
Expand All @@ -221,6 +221,7 @@ def _update_single_pool_info_status(self, pool_info):
"thin_provisioning_support": True,
'max_over_subscription_ratio':
self.configuration.max_over_subscription_ratio,
"reserved_percentage": self.configuration.safe_get('reserved_percentage'),
})
return status

Expand Down Expand Up @@ -1261,6 +1262,18 @@ def terminate_connection(self, volume, connector, **kwargs):


class DSWAREISCSIDriver(DSWAREBaseDriver):
def __init__(self, *args, **kwargs):
super(DSWAREISCSIDriver, self).__init__(*args, **kwargs)
self.support_iscsi_links_balance_by_pool = False

def do_setup(self, context):
super(DSWAREISCSIDriver, self).do_setup(context)
if self.configuration.iscsi_manager_groups or self.configuration.target_ips:
self.support_iscsi_links_balance_by_pool = False
else:
self.support_iscsi_links_balance_by_pool = \
self.client.is_support_links_balance_by_pool()

def check_for_setup_error(self):
super(DSWAREISCSIDriver, self).check_for_setup_error()
fs_utils.check_iscsi_group_valid(
Expand All @@ -1282,9 +1295,16 @@ def initialize_connection(self, volume, connector):
raise exception.InvalidInput(reason=msg)

vol_name = self._get_vol_name(volume)
pool_name = volume_utils.extract_host(volume.host, level='pool')
iscsi_params = {
'configuration': self.configuration,
'manager_groups': self.manager_groups,
'thread_lock': self.lock,
'pool_name': pool_name,
'support_iscsi_links_balance_by_pool': self.support_iscsi_links_balance_by_pool
}
properties = fs_flow.initialize_iscsi_connection(
self.client, vol_name, connector, self.configuration,
self.manager_groups, self.lock)
self.client, vol_name, connector, iscsi_params)

LOG.info("Finish initialize iscsi connection, return: %s, the "
"remaining manager groups are %s",
Expand Down
46 changes: 38 additions & 8 deletions Cinder/Newton/fs_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,25 +711,29 @@ def add_iscsi_host_relation(self, host_name, ip_list):
else:
raise

def get_iscsi_host_relation(self, host_name):
iscsi_ips = []
def _get_iscsi_host_relation(self, key):
url = "/dsware/service/iscsi/queryIscsiHostRelation"
params = [{"key": host_name, "flag": 0}]
params = [{"key": key, "flag": 0}]
try:
result = self.call(url, "POST", params, get_system_time=True)
self._assert_rest_result(
result, _("Get iscsi host relation session error."))

for iscsi in result.get("hostList", []):
if int(iscsi.get("flag")) == constants.HOST_FLAG:
iscsi_ips = iscsi.get("content", "").split(";")
return iscsi_ips
return result
except Exception as err:
if constants.URL_NOT_FOUND in six.text_type(err):
return iscsi_ips
return {}
else:
raise

def get_iscsi_host_relation(self, host_name):
result = self._get_iscsi_host_relation(host_name)
iscsi_ips = []
for iscsi in result.get("hostList", []):
if int(iscsi.get("flag")) == constants.HOST_FLAG:
iscsi_ips = iscsi.get("content", "").split(";")
return iscsi_ips

def delete_iscsi_host_relation(self, host_name, ip_list):
if not ip_list:
return
Expand Down Expand Up @@ -818,3 +822,29 @@ def create_full_volume_from_snapshot(self, vol_name, snapshot_name):
result = self.call(url, "POST", params, get_system_time=True)
self._assert_rest_result(
result, _("create full volume from snap fails"))

def is_support_links_balance_by_pool(self):
result = self._get_iscsi_host_relation('get_newiscsi')
if result.get("newIscsi"):
LOG.info("Support new iscsi interface to get iscsi ip.")
return True
return False

def get_iscsi_links_by_pool(self, iscsi_link_count, pool_name, host_name):
url = "/dsware/service/iscsi/queryIscsiLinks"
params = {
"amount": iscsi_link_count,
"poolList": [pool_name],
"hostKey": host_name
}

try:
result = self.call(url, "POST", params, get_system_time=True)
self._assert_rest_result(
result, _("Get iscsi links by pool error."))
return result
except Exception as err:
if constants.URL_NOT_FOUND in six.text_type(err):
return {}
else:
raise
45 changes: 37 additions & 8 deletions Cinder/Newton/fs_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,15 @@ def execute(self, host_name, vol_name):
class GetISCSIProperties(task.Task):
default_provides = 'properties'

def __init__(self, client, configuration, manager_groups, thread_lock,
*args, **kwargs):
def __init__(self, client, iscsi_params, *args, **kwargs):
super(GetISCSIProperties, self).__init__(*args, **kwargs)
self.client = client
self.configuration = configuration
self.manager_groups = manager_groups
self.thread_lock = thread_lock
self.configuration = iscsi_params.get('configuration')
self.manager_groups = iscsi_params.get('manager_groups')
self.thread_lock = iscsi_params.get('thread_lock')
self.pool_name = iscsi_params.get("pool_name")
self.support_iscsi_links_balance_by_pool = iscsi_params.get(
"support_iscsi_links_balance_by_pool")

@staticmethod
def _construct_properties(multipath, target_lun, target_ips, target_iqns):
Expand All @@ -255,6 +257,22 @@ def _construct_properties(multipath, target_lun, target_ips, target_iqns):
})
return properties

@staticmethod
def _get_iscsi_info_from_iscsi_links(iscsi_links_info):
iscsi_ips = []
iscsi_iqns = []
for iscsi_info in iscsi_links_info:
if iscsi_info.get("iscsiPortal") and iscsi_info.get("targetName"):
iscsi_ips.append(iscsi_info.get("iscsiPortal"))
iscsi_iqns.append(iscsi_info.get("targetName"))

if not iscsi_ips:
msg = _("No available iscsi port can be found, Please Check Storage")
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)

return iscsi_ips, iscsi_iqns

def _find_target_ips(self):
config_target_ips = self.configuration.target_ips
target_ips, target_iqns = [], []
Expand Down Expand Up @@ -328,6 +346,15 @@ def _find_iscsi_ips_from_storage(self, host_name):
target_ips, target_iqns)
return target_ips, target_iqns

def _find_iscsi_ips_from_storage_pool(self, host_name, pool_name):
# The host obtains different iSCSI links for different storage pools.
# Obtain the same links for the same storage pool.
iscsi_links_result = self.client.get_iscsi_links_by_pool(
self.configuration.iscsi_link_count, pool_name, host_name)
target_ips_format, target_iqns = self._get_iscsi_info_from_iscsi_links(
iscsi_links_result.get("iscsiLinks", []))
return target_ips_format, target_iqns

def execute(self, host_name, vol_name, multipath):
LOG.info("Get ISCSI initialize connection properties.")
target_lun = fs_utils.get_target_lun(self.client, host_name, vol_name)
Expand All @@ -336,6 +363,9 @@ def execute(self, host_name, vol_name, multipath):
target_ips, target_iqns = self._find_iscsi_ips(host_name)
elif self.configuration.target_ips:
target_ips, target_iqns = self._find_target_ips()
elif self.pool_name and self.support_iscsi_links_balance_by_pool:
target_ips, target_iqns = self._find_iscsi_ips_from_storage_pool(
host_name, self.pool_name)
else:
target_ips, target_iqns = self._find_iscsi_ips_from_storage(
host_name)
Expand Down Expand Up @@ -377,8 +407,7 @@ def get_iscsi_required_params(vol_name, connector, client=None):
return vol_name, host_name, host_group_name, initiator_name, multipath


def initialize_iscsi_connection(client, vol_name, connector, configuration,
manager_groups, thread_lock):
def initialize_iscsi_connection(client, vol_name, connector, iscsi_params):
(vol_name, host_name, host_group_name, initiator_name,
multipath) = get_iscsi_required_params(vol_name, connector)

Expand All @@ -404,7 +433,7 @@ def initialize_iscsi_connection(client, vol_name, connector, configuration,
)

work_flow.add(
GetISCSIProperties(client, configuration, manager_groups, thread_lock)
GetISCSIProperties(client, iscsi_params)
)

engine = taskflow.engines.load(work_flow, store=store_spec)
Expand Down
28 changes: 24 additions & 4 deletions Cinder/Ocata/dsware.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@

@interface.volumedriver
class DSWAREBaseDriver(driver.VolumeDriver):
VERSION = "2.6.1"
VERSION = "2.6.2"
CI_WIKI_NAME = 'Huawei_FusionStorage_CI'

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -200,7 +200,7 @@ def _get_capacity(self, pool_info):
total = float(pool_info['totalCapacity']) / units.Ki
free = (float(pool_info['totalCapacity']) -
float(pool_info['usedCapacity'])) / units.Ki
provisioned = float(pool_info['usedCapacity']) / units.Ki
provisioned = float(pool_info['allocatedCapacity']) / units.Ki
pool_capacity['total_capacity_gb'] = total
pool_capacity['free_capacity_gb'] = free
pool_capacity['provisioned_capacity_gb'] = provisioned
Expand All @@ -221,6 +221,7 @@ def _update_single_pool_info_status(self, pool_info):
"thin_provisioning_support": True,
'max_over_subscription_ratio':
self.configuration.max_over_subscription_ratio,
"reserved_percentage": self.configuration.safe_get('reserved_percentage'),
})
return status

Expand Down Expand Up @@ -1261,6 +1262,18 @@ def terminate_connection(self, volume, connector, **kwargs):


class DSWAREISCSIDriver(DSWAREBaseDriver):
def __init__(self, *args, **kwargs):
super(DSWAREISCSIDriver, self).__init__(*args, **kwargs)
self.support_iscsi_links_balance_by_pool = False

def do_setup(self, context):
super(DSWAREISCSIDriver, self).do_setup(context)
if self.configuration.iscsi_manager_groups or self.configuration.target_ips:
self.support_iscsi_links_balance_by_pool = False
else:
self.support_iscsi_links_balance_by_pool = \
self.client.is_support_links_balance_by_pool()

def check_for_setup_error(self):
super(DSWAREISCSIDriver, self).check_for_setup_error()
fs_utils.check_iscsi_group_valid(
Expand All @@ -1282,9 +1295,16 @@ def initialize_connection(self, volume, connector):
raise exception.InvalidInput(reason=msg)

vol_name = self._get_vol_name(volume)
pool_name = volume_utils.extract_host(volume.host, level='pool')
iscsi_params = {
'configuration': self.configuration,
'manager_groups': self.manager_groups,
'thread_lock': self.lock,
'pool_name': pool_name,
'support_iscsi_links_balance_by_pool': self.support_iscsi_links_balance_by_pool
}
properties = fs_flow.initialize_iscsi_connection(
self.client, vol_name, connector, self.configuration,
self.manager_groups, self.lock)
self.client, vol_name, connector, iscsi_params)

LOG.info("Finish initialize iscsi connection, return: %s, the "
"remaining manager groups are %s",
Expand Down
46 changes: 38 additions & 8 deletions Cinder/Ocata/fs_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,25 +711,29 @@ def add_iscsi_host_relation(self, host_name, ip_list):
else:
raise

def get_iscsi_host_relation(self, host_name):
iscsi_ips = []
def _get_iscsi_host_relation(self, key):
url = "/dsware/service/iscsi/queryIscsiHostRelation"
params = [{"key": host_name, "flag": 0}]
params = [{"key": key, "flag": 0}]
try:
result = self.call(url, "POST", params, get_system_time=True)
self._assert_rest_result(
result, _("Get iscsi host relation session error."))

for iscsi in result.get("hostList", []):
if int(iscsi.get("flag")) == constants.HOST_FLAG:
iscsi_ips = iscsi.get("content", "").split(";")
return iscsi_ips
return result
except Exception as err:
if constants.URL_NOT_FOUND in six.text_type(err):
return iscsi_ips
return {}
else:
raise

def get_iscsi_host_relation(self, host_name):
result = self._get_iscsi_host_relation(host_name)
iscsi_ips = []
for iscsi in result.get("hostList", []):
if int(iscsi.get("flag")) == constants.HOST_FLAG:
iscsi_ips = iscsi.get("content", "").split(";")
return iscsi_ips

def delete_iscsi_host_relation(self, host_name, ip_list):
if not ip_list:
return
Expand Down Expand Up @@ -818,3 +822,29 @@ def create_full_volume_from_snapshot(self, vol_name, snapshot_name):
result = self.call(url, "POST", params, get_system_time=True)
self._assert_rest_result(
result, _("create full volume from snap fails"))

def is_support_links_balance_by_pool(self):
result = self._get_iscsi_host_relation('get_newiscsi')
if result.get("newIscsi"):
LOG.info("Support new iscsi interface to get iscsi ip.")
return True
return False

def get_iscsi_links_by_pool(self, iscsi_link_count, pool_name, host_name):
url = "/dsware/service/iscsi/queryIscsiLinks"
params = {
"amount": iscsi_link_count,
"poolList": [pool_name],
"hostKey": host_name
}

try:
result = self.call(url, "POST", params, get_system_time=True)
self._assert_rest_result(
result, _("Get iscsi links by pool error."))
return result
except Exception as err:
if constants.URL_NOT_FOUND in six.text_type(err):
return {}
else:
raise
Loading

0 comments on commit 1ee90e3

Please sign in to comment.