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):
|
||||
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.add_argument("-v", "--verbose",
|
||||
help="Output lots of diagnostic information",
|
||||
|
@ -37,6 +37,10 @@ from pathlib import Path
|
||||
SECoP_DEFAULT_PORT = 10767
|
||||
|
||||
|
||||
_gcfg_help = """
|
||||
"""
|
||||
|
||||
|
||||
class GeneralConfig:
|
||||
"""generalConfig holds server configuration items
|
||||
|
||||
@ -57,11 +61,12 @@ class GeneralConfig:
|
||||
|
||||
:param configfile: if present, keys and values from the [FRAPPY] section are read
|
||||
|
||||
default values for 'piddir', 'logdir' and 'confdir' are guessed from the
|
||||
location of this source file and from sys.executable.
|
||||
|
||||
if configfile is not given, the general config file is determined by
|
||||
the env. variable FRAPPY_CONFIG_FILE or <confdir>/generalConfig.cfg is used
|
||||
The following locations are searched for the generalConfig.cfg file.
|
||||
- command line argument
|
||||
- environment variable FRAPPY_CONFIG_FILE
|
||||
- git location (../cfg)
|
||||
- local location (cwd)
|
||||
- global location (/etc/frappy)
|
||||
|
||||
if a configfile is given, the values from the FRAPPY section are
|
||||
overriding above defaults
|
||||
@ -69,37 +74,12 @@ class GeneralConfig:
|
||||
finally, the env. variables FRAPPY_PIDDIR, FRAPPY_LOGDIR and FRAPPY_CONFDIR
|
||||
are overriding these values when given
|
||||
"""
|
||||
|
||||
configfile = self._get_file_location(configfile)
|
||||
|
||||
cfg = {}
|
||||
mandatory = 'piddir', 'logdir', 'confdir'
|
||||
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:
|
||||
parser = ConfigParser()
|
||||
parser.optionxform = str
|
||||
@ -113,6 +93,7 @@ class GeneralConfig:
|
||||
cfg[key] = ':'.join(path.expanduser(v) for v in value.split(':'))
|
||||
if cfg.get('confdir') is None:
|
||||
cfg['confdir'] = configfile.parent
|
||||
# environment variables will overwrite the config file
|
||||
for key in mandatory:
|
||||
env = environ.get(f'FRAPPY_{key.upper()}')
|
||||
if env is not None:
|
||||
@ -127,14 +108,46 @@ class GeneralConfig:
|
||||
if missing_keys:
|
||||
if 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):
|
||||
cfg['confdir'] = [cfg['confdir']]
|
||||
# this is not customizable
|
||||
cfg['basedir'] = repodir
|
||||
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):
|
||||
"""access for keys known to exist
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user