generalconfig: streamlined config discovery
determine generalconfig file location in order: - command line argument - environment variable - git location (../cfg) - local location (cwd) - global location (/etc/frappy) Change-Id: Ie34bcbd5188837075ee7bb7d5029d676ae72378e Reviewed-on: https://forge.frm2.tum.de/review/c/secop/frappy/+/34839 Reviewed-by: Bjoern Pedersen <bjoern.pedersen@frm2.tum.de> Reviewed-by: Alexander Zaft <a.zaft@fz-juelich.de> Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de>
This commit is contained in:
parent
261121297b
commit
632db924eb
@ -35,7 +35,15 @@ from frappy.server import Server
|
|||||||
|
|
||||||
|
|
||||||
def parseArgv(argv):
|
def parseArgv(argv):
|
||||||
parser = argparse.ArgumentParser(description="Manage a SECoP server")
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Manage a SECoP server",
|
||||||
|
epilog="""The server needs some configuration, by default from the
|
||||||
|
generalConfig.cfg file. the keys confdir, logdir and piddir have to
|
||||||
|
be set.
|
||||||
|
Alternatively, one can set the environment variables FRAPPY_CONFDIR
|
||||||
|
FRAPPY_LOGDIR and FRAPPY_PIDDIR to set the required values.
|
||||||
|
"""
|
||||||
|
)
|
||||||
loggroup = parser.add_mutually_exclusive_group()
|
loggroup = parser.add_mutually_exclusive_group()
|
||||||
loggroup.add_argument("-v", "--verbose",
|
loggroup.add_argument("-v", "--verbose",
|
||||||
help="Output lots of diagnostic information",
|
help="Output lots of diagnostic information",
|
||||||
|
@ -37,6 +37,10 @@ from pathlib import Path
|
|||||||
SECoP_DEFAULT_PORT = 10767
|
SECoP_DEFAULT_PORT = 10767
|
||||||
|
|
||||||
|
|
||||||
|
_gcfg_help = """
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class GeneralConfig:
|
class GeneralConfig:
|
||||||
"""generalConfig holds server configuration items
|
"""generalConfig holds server configuration items
|
||||||
|
|
||||||
@ -57,11 +61,12 @@ class GeneralConfig:
|
|||||||
|
|
||||||
:param configfile: if present, keys and values from the [FRAPPY] section are read
|
:param configfile: if present, keys and values from the [FRAPPY] section are read
|
||||||
|
|
||||||
default values for 'piddir', 'logdir' and 'confdir' are guessed from the
|
The following locations are searched for the generalConfig.cfg file.
|
||||||
location of this source file and from sys.executable.
|
- command line argument
|
||||||
|
- environment variable FRAPPY_CONFIG_FILE
|
||||||
if configfile is not given, the general config file is determined by
|
- git location (../cfg)
|
||||||
the env. variable FRAPPY_CONFIG_FILE or <confdir>/generalConfig.cfg is used
|
- local location (cwd)
|
||||||
|
- global location (/etc/frappy)
|
||||||
|
|
||||||
if a configfile is given, the values from the FRAPPY section are
|
if a configfile is given, the values from the FRAPPY section are
|
||||||
overriding above defaults
|
overriding above defaults
|
||||||
@ -69,37 +74,12 @@ class GeneralConfig:
|
|||||||
finally, the env. variables FRAPPY_PIDDIR, FRAPPY_LOGDIR and FRAPPY_CONFDIR
|
finally, the env. variables FRAPPY_PIDDIR, FRAPPY_LOGDIR and FRAPPY_CONFDIR
|
||||||
are overriding these values when given
|
are overriding these values when given
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
configfile = self._get_file_location(configfile)
|
||||||
|
|
||||||
cfg = {}
|
cfg = {}
|
||||||
mandatory = 'piddir', 'logdir', 'confdir'
|
mandatory = 'piddir', 'logdir', 'confdir'
|
||||||
repodir = Path(__file__).parents[2].expanduser().resolve()
|
repodir = Path(__file__).parents[2].expanduser().resolve()
|
||||||
# create default paths
|
|
||||||
if (Path(sys.executable).suffix == ".exe"
|
|
||||||
and not Path(sys.executable).name.startswith('python')):
|
|
||||||
# special MS windows environment
|
|
||||||
confdir = Path('./')
|
|
||||||
self.update_defaults(piddir=Path('./'), logdir=Path('./log'))
|
|
||||||
elif path.exists(path.join(repodir, 'cfg')):
|
|
||||||
# running from git repo
|
|
||||||
confdir = repodir / 'cfg'
|
|
||||||
# take logdir and piddir from <repodir>/cfg/generalConfig.cfg
|
|
||||||
else:
|
|
||||||
# running on installed system (typically with systemd)
|
|
||||||
self.update_defaults(
|
|
||||||
piddir=Path('/var/run/frappy'),
|
|
||||||
logdir=Path('/var/log'),
|
|
||||||
)
|
|
||||||
confdir = Path('/etc/frappy')
|
|
||||||
self.set_default('confdir', confdir)
|
|
||||||
if configfile is None:
|
|
||||||
configfile = environ.get('FRAPPY_CONFIG_FILE')
|
|
||||||
if configfile:
|
|
||||||
configfile = Path(configfile).expanduser()
|
|
||||||
if not configfile.exists():
|
|
||||||
raise FileNotFoundError(configfile)
|
|
||||||
else:
|
|
||||||
configfile = confdir / 'generalConfig.cfg'
|
|
||||||
if not configfile.exists():
|
|
||||||
configfile = None
|
|
||||||
if configfile:
|
if configfile:
|
||||||
parser = ConfigParser()
|
parser = ConfigParser()
|
||||||
parser.optionxform = str
|
parser.optionxform = str
|
||||||
@ -113,6 +93,7 @@ class GeneralConfig:
|
|||||||
cfg[key] = ':'.join(path.expanduser(v) for v in value.split(':'))
|
cfg[key] = ':'.join(path.expanduser(v) for v in value.split(':'))
|
||||||
if cfg.get('confdir') is None:
|
if cfg.get('confdir') is None:
|
||||||
cfg['confdir'] = configfile.parent
|
cfg['confdir'] = configfile.parent
|
||||||
|
# environment variables will overwrite the config file
|
||||||
for key in mandatory:
|
for key in mandatory:
|
||||||
env = environ.get(f'FRAPPY_{key.upper()}')
|
env = environ.get(f'FRAPPY_{key.upper()}')
|
||||||
if env is not None:
|
if env is not None:
|
||||||
@ -127,14 +108,46 @@ class GeneralConfig:
|
|||||||
if missing_keys:
|
if missing_keys:
|
||||||
if configfile:
|
if configfile:
|
||||||
raise KeyError(f"missing value for {' and '.join(missing_keys)} in {configfile}")
|
raise KeyError(f"missing value for {' and '.join(missing_keys)} in {configfile}")
|
||||||
raise KeyError('missing %s'
|
|
||||||
% ' and '.join('FRAPPY_%s' % k.upper() for k in missing_keys))
|
if len(missing_keys) < 3:
|
||||||
|
# user specified at least one env variable already
|
||||||
|
missing = ' (missing %s)' % ', '.join('FRAPPY_%s' % k.upper() for k in missing_keys)
|
||||||
|
else:
|
||||||
|
missing = ''
|
||||||
|
raise FileNotFoundError(
|
||||||
|
'Could not determine config file location for the general frappy config. '
|
||||||
|
f'Provide a config file or all required environment variables{missing}. '
|
||||||
|
'For more information, see frappy-server --help.'
|
||||||
|
)
|
||||||
if 'confdir' in cfg and isinstance(cfg['confdir'], Path):
|
if 'confdir' in cfg and isinstance(cfg['confdir'], Path):
|
||||||
cfg['confdir'] = [cfg['confdir']]
|
cfg['confdir'] = [cfg['confdir']]
|
||||||
# this is not customizable
|
# this is not customizable
|
||||||
cfg['basedir'] = repodir
|
cfg['basedir'] = repodir
|
||||||
self._config = cfg
|
self._config = cfg
|
||||||
|
|
||||||
|
def _get_file_location(self, configfile):
|
||||||
|
"""Determining the defaultConfig.cfg location as documented in init()"""
|
||||||
|
# given as command line arg
|
||||||
|
if configfile and Path(configfile).exists():
|
||||||
|
return configfile
|
||||||
|
# if not given as argument, check different sources
|
||||||
|
# env variable
|
||||||
|
fromenv = environ.get('FRAPPY_CONFIG_FILE')
|
||||||
|
if fromenv and Path(fromenv).exists():
|
||||||
|
return fromenv
|
||||||
|
# from ../cfg (there if running from checkout)
|
||||||
|
repodir = Path(__file__).parents[2].expanduser().resolve()
|
||||||
|
if (repodir / 'cfg' / 'generalConfig.cfg').exists():
|
||||||
|
return repodir / 'cfg' / 'generalConfig.cfg'
|
||||||
|
localfile = Path.cwd() / 'generalConfig.cfg'
|
||||||
|
if localfile.exists():
|
||||||
|
return localfile
|
||||||
|
# TODO: leave this hardcoded?
|
||||||
|
globalfile = Path('/etc/frappy/generalConfig.cfg')
|
||||||
|
if globalfile.exists():
|
||||||
|
return globalfile
|
||||||
|
return None
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
"""access for keys known to exist
|
"""access for keys known to exist
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user