1
0
Fork 0

Merging upstream version 2.3~rc1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-16 12:53:58 +01:00
parent 972d2d9aa2
commit ca2ec6771a
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
37 changed files with 1946 additions and 407 deletions

View file

@ -14,7 +14,8 @@ import sys
import logging
import functools
import configparser
from staslib import defs, singleton, timeparse
from urllib.parse import urlparse
from staslib import defs, iputil, nbft, singleton, timeparse
__TOKEN_RE = re.compile(r'\s*;\s*')
__OPTION_RE = re.compile(r'\s*=\s*')
@ -83,7 +84,8 @@ def _to_ip_family(text):
class OrderedMultisetDict(dict):
'''This class is used to change the behavior of configparser.ConfigParser
and allow multiple configuration parameters with the same key. The
result is a list of values.
result is a list of values, where values are sorted by the order they
appear in the file.
'''
def __setitem__(self, key, value):
@ -317,7 +319,7 @@ class SvcConf(metaclass=singleton.Singleton): # pylint: disable=too-many-public
option = 'persistent-connections'
value = self.get_option(section, option, ignore_default=True)
legacy = self.get_option('Global', 'persistent-connections', ignore_default=True)
legacy = self.get_option('Global', option, ignore_default=True)
if value is None and legacy is None:
return self._defaults.get((section, option), True)
@ -381,7 +383,7 @@ class SvcConf(metaclass=singleton.Singleton): # pylint: disable=too-many-public
controller_list = self.get_option('Controllers', 'exclude')
# 2022-09-20: Look for "blacklist". This is for backwards compatibility
# with releases 1.0 to 1.1.6. This is to be phased out (i.e. remove by 2024)
# with releases 1.0 to 1.1.x. This is to be phased out (i.e. remove by 2024)
controller_list += self.get_option('Controllers', 'blacklist')
excluded = [_parse_controller(controller) for controller in controller_list]
@ -572,7 +574,7 @@ class SysConf(metaclass=singleton.Singleton):
try:
value = self.__get_value('Host', 'key', defs.NVME_HOSTKEY)
except FileNotFoundError as ex:
logging.info('Host key undefined: %s', ex)
logging.debug('Host key undefined: %s', ex)
value = None
return value
@ -701,3 +703,97 @@ class NvmeOptions(metaclass=singleton.Singleton):
def dhchap_ctrlkey_supp(self):
'''This option allows specifying the controller DHCHAP key used for authentication.'''
return self._supported_options['dhchap_ctrl_secret']
# ******************************************************************************
class NbftConf(metaclass=singleton.Singleton):
'''Read and cache configuration file.'''
def __init__(self, root_dir=defs.NBFT_SYSFS_PATH):
self._disc_ctrls = []
self._subs_ctrls = []
nbft_files = nbft.get_nbft_files(root_dir)
if len(nbft_files):
logging.info('NBFT location(s): %s', list(nbft_files.keys()))
for data in nbft_files.values():
hfis = data.get('hfi', [])
discovery = data.get('discovery', [])
subsystem = data.get('subsystem', [])
self._disc_ctrls.extend(NbftConf.__nbft_disc_to_cids(discovery, hfis))
self._subs_ctrls.extend(NbftConf.__nbft_subs_to_cids(subsystem, hfis))
dcs = property(lambda self: self._disc_ctrls)
iocs = property(lambda self: self._subs_ctrls)
def get_controllers(self):
'''Retrieve the list of controllers. Stafd only cares about
discovery controllers. Stacd only cares about I/O controllers.'''
# For now, only return DCs. There are still unanswered questions
# regarding I/O controllers, e.g. what if multipathing has been
# configured.
return self.dcs if defs.PROG_NAME == 'stafd' else []
@staticmethod
def __nbft_disc_to_cids(discovery, hfis):
cids = []
for ctrl in discovery:
cid = NbftConf.__uri2cid(ctrl['uri'])
cid['subsysnqn'] = ctrl['nqn']
host_iface = NbftConf.__get_host_iface(ctrl.get('hfi_index'), hfis)
if host_iface:
cid['host-iface'] = host_iface
cids.append(cid)
return cids
@staticmethod
def __nbft_subs_to_cids(subsystem, hfis):
cids = []
for ctrl in subsystem:
cid = {
'transport': ctrl['trtype'],
'traddr': ctrl['traddr'],
'trsvcid': ctrl['trsvcid'],
'subsysnqn': ctrl['subsys_nqn'],
'hdr-digest': ctrl['pdu_header_digest_required'],
'data-digest': ctrl['data_digest_required'],
}
indexes = ctrl.get('hfi_indexes')
if isinstance(indexes, list) and len(indexes) > 0:
host_iface = NbftConf.__get_host_iface(indexes[0], hfis)
if host_iface:
cid['host-iface'] = host_iface
cids.append(cid)
return cids
@staticmethod
def __get_host_iface(indx, hfis):
if indx is None or indx >= len(hfis):
return None
mac = hfis[indx].get('mac_addr')
if mac is None:
return None
return iputil.mac2iface(mac)
@staticmethod
def __uri2cid(uri: str):
'''Convert a URI of the form "nvme+tcp://100.71.103.50:8009/" to a Controller ID'''
obj = urlparse(uri)
return {
'transport': obj.scheme.split('+')[1],
'traddr': obj.hostname,
'trsvcid': str(obj.port),
}