diff --git a/webserver/config/basic.py b/webserver/config/basic.py index b9fab32..946f6ba 100644 --- a/webserver/config/basic.py +++ b/webserver/config/basic.py @@ -1,4 +1,7 @@ import logging +from functools import reduce +from os import getenv +from os.path import expandvars from pathlib import Path from pyhocon import ConfigTree, ConfigFactory @@ -9,6 +12,10 @@ from pyparsing import ( ParseSyntaxException, ) +DEFAULT_EXTRA_CONFIG_PATH = "/opt/trains/config" +EXTRA_CONFIG_PATH_ENV_KEY = "TRAINS_CONFIG_DIR" +EXTRA_CONFIG_PATH_SEP = ":" + class BasicConfig: NotSet = object() @@ -39,8 +46,32 @@ class BasicConfig: path = ".".join((self.prefix, Path(name).stem)) return logging.getLogger(path) + def _read_env_paths(self, key): + value = getenv(EXTRA_CONFIG_PATH_ENV_KEY, DEFAULT_EXTRA_CONFIG_PATH) + if value is None: + return + paths = [ + Path(expandvars(v)).expanduser() for v in value.split(EXTRA_CONFIG_PATH_SEP) + ] + invalid = [ + path + for path in paths + if not path.is_dir() and str(path) != DEFAULT_EXTRA_CONFIG_PATH + ] + if invalid: + print(f"WARNING: Invalid paths in {key} env var: {' '.join(invalid)}") + return [path for path in paths if path.is_dir()] + def _load(self, verbose=True): - self._config = self._read_recursive(self.folder, verbose=verbose) + extra_config_paths = self._read_env_paths(EXTRA_CONFIG_PATH_ENV_KEY) or [] + + self._config = reduce( + lambda config, path: ConfigTree.merge_configs( + config, self._read_recursive(path, verbose=verbose), copy_trees=True + ), + [self.folder] + extra_config_paths, + ConfigTree(), + ) def _read_recursive(self, conf_root, verbose=True): conf = ConfigTree() diff --git a/webserver/config/default/webserver.conf b/webserver/config/default/webserver.conf index 1c67c9f..3b6f8cf 100644 --- a/webserver/config/default/webserver.conf +++ b/webserver/config/default/webserver.conf @@ -38,7 +38,7 @@ auth { docs { # Default filename used when file not found error is reported when serving docs. - # This usually happans when the path is to a folder and not a file. + # This usually happens when the path is to a folder and not a file. default_filename: "index.html" }