mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 07:17:17 +00:00
add ability to read values from environment variables
It makes sense to read some values from environment. In particular this feature is useful in case of running application in containers in ci/cd See #108 for more details
This commit is contained in:
parent
573ade4ba5
commit
e3ed36fafd
@ -59,7 +59,7 @@ systemd-machine-id-setup &> /dev/null
|
||||
if [ -n "$AHRIMAN_FORCE_ROOT" ]; then
|
||||
AHRIMAN_EXECUTABLE=("ahriman")
|
||||
elif ahriman help-commands-unsafe -- "$@" &> /dev/null; then
|
||||
AHRIMAN_EXECUTABLE=("sudo" "-u" "$AHRIMAN_USER" "--" "ahriman")
|
||||
AHRIMAN_EXECUTABLE=("sudo" "-E" "-u" "$AHRIMAN_USER" "--" "ahriman")
|
||||
else
|
||||
AHRIMAN_EXECUTABLE=("ahriman")
|
||||
fi
|
||||
|
@ -12,6 +12,15 @@ There are two variable types which have been added to default ones, they are pat
|
||||
|
||||
Path values, except for casting to ``pathlib.Path`` type, will be also expanded to absolute paths relative to the configuration path. E.g. if path is set to ``ahriman.ini.d/logging.ini`` and root configuration path is ``/etc/ahriman.ini``, the value will be expanded to ``/etc/ahriman.ini.d/logging.ini``. In order to disable path expand, use the full path, e.g. ``/etc/ahriman.ini.d/logging.ini``.
|
||||
|
||||
Configuration allows string interpolation from environment variables, e.g.:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[section]
|
||||
key = $SECRET
|
||||
|
||||
will try to read value from ``SECRET`` environment variable. In case if the required environment variable wasn't found, it will keep original value (i.e. ``$SECRET`` in the example). Dollar sign can be set as ``$$``.
|
||||
|
||||
There is also additional subcommand which will allow to validate configuration and print found errors. In order to do so, run ``service-config-validate`` subcommand, e.g.:
|
||||
|
||||
.. code-block:: shell
|
||||
|
@ -25,6 +25,7 @@ from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
from typing import Any, Self
|
||||
|
||||
from ahriman.core.configuration.shell_interpolator import ShellInterpolator
|
||||
from ahriman.core.exceptions import InitializeError
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
||||
@ -73,10 +74,16 @@ class Configuration(configparser.RawConfigParser):
|
||||
allow_no_value(bool, optional): copies ``configparser.RawConfigParser`` behaviour. In case if it is set
|
||||
to ``True``, the keys without values will be allowed (Default value = False)
|
||||
"""
|
||||
configparser.RawConfigParser.__init__(self, allow_no_value=allow_no_value, converters={
|
||||
configparser.RawConfigParser.__init__(
|
||||
self,
|
||||
allow_no_value=allow_no_value,
|
||||
interpolation=ShellInterpolator(),
|
||||
converters={
|
||||
"list": shlex.split,
|
||||
"path": self._convert_path,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
self.architecture: str | None = None
|
||||
self.path: Path | None = None
|
||||
self.includes: list[Path] = []
|
||||
|
51
src/ahriman/core/configuration/shell_interpolator.py
Normal file
51
src/ahriman/core/configuration/shell_interpolator.py
Normal file
@ -0,0 +1,51 @@
|
||||
#
|
||||
# Copyright (c) 2021-2023 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import configparser
|
||||
import os
|
||||
|
||||
from collections.abc import Mapping, MutableMapping
|
||||
from string import Template
|
||||
|
||||
|
||||
class ShellInterpolator(configparser.Interpolation):
|
||||
"""
|
||||
custom string interpolator, because we cannot use defaults argument due to config validation
|
||||
"""
|
||||
|
||||
def before_get(self, parser: MutableMapping[str, Mapping[str, str]], section: str, option: str, value: str,
|
||||
defaults: Mapping[str, str]) -> str:
|
||||
"""
|
||||
interpolate option value
|
||||
|
||||
Args:
|
||||
parser(MutableMapping[str, Mapping[str, str]]): option parser
|
||||
section(str): section name
|
||||
option(str): option name
|
||||
value(str): source (not-converted) value
|
||||
defaults(Mapping[str, str]): default values
|
||||
|
||||
Returns:
|
||||
str: substituted value
|
||||
"""
|
||||
# At the moment it seems that it is the most legit way to handle environment variables
|
||||
# Template behaviour is literally the same as shell
|
||||
# In addition, we are using shell-like variables in some cases (see ``alpm.mirror`` option), thus we would like
|
||||
# to keep them alive
|
||||
return Template(value).safe_substitute(os.environ)
|
15
tests/ahriman/core/configuration/test_shell_interpolator.py
Normal file
15
tests/ahriman/core/configuration/test_shell_interpolator.py
Normal file
@ -0,0 +1,15 @@
|
||||
import os
|
||||
|
||||
from ahriman.core.configuration.shell_interpolator import ShellInterpolator
|
||||
|
||||
|
||||
def test_before_get() -> None:
|
||||
"""
|
||||
must correctly extract environment variables
|
||||
"""
|
||||
interpolator = ShellInterpolator()
|
||||
|
||||
assert interpolator.before_get({}, "", "", "value", {}) == "value"
|
||||
assert interpolator.before_get({}, "", "", "$value", {}) == "$value"
|
||||
assert interpolator.before_get({}, "", "", "$HOME", {}) == os.environ["HOME"]
|
||||
assert interpolator.before_get({}, "", "", "$$HOME", {}) == "$HOME"
|
Loading…
Reference in New Issue
Block a user