add --server flag for setup command

This commit is contained in:
Evgenii Alekseev 2023-08-18 18:05:27 +03:00
parent 479f0db572
commit c83936d4d9
6 changed files with 45 additions and 14 deletions

View File

@ -11,6 +11,7 @@ ENV AHRIMAN_PACKAGER="ahriman bot <ahriman@example.com>"
ENV AHRIMAN_PACMAN_MIRROR="" ENV AHRIMAN_PACMAN_MIRROR=""
ENV AHRIMAN_PORT="" ENV AHRIMAN_PORT=""
ENV AHRIMAN_REPOSITORY="aur-clone" ENV AHRIMAN_REPOSITORY="aur-clone"
ENV AHRIMAN_REPOSITORY_SERVER=""
ENV AHRIMAN_REPOSITORY_ROOT="/var/lib/ahriman/ahriman" ENV AHRIMAN_REPOSITORY_ROOT="/var/lib/ahriman/ahriman"
ENV AHRIMAN_UNIX_SOCKET="" ENV AHRIMAN_UNIX_SOCKET=""
ENV AHRIMAN_USER="ahriman" ENV AHRIMAN_USER="ahriman"

View File

@ -43,6 +43,9 @@ fi
if [ -n "$AHRIMAN_PORT" ]; then if [ -n "$AHRIMAN_PORT" ]; then
AHRIMAN_SETUP_ARGS+=("--web-port" "$AHRIMAN_PORT") AHRIMAN_SETUP_ARGS+=("--web-port" "$AHRIMAN_PORT")
fi fi
if [ -n "$AHRIMAN_REPOSITORY_SERVER" ]; then
AHRIMAN_SETUP_ARGS+=("--server" "$AHRIMAN_REPOSITORY_SERVER")
fi
if [ -n "$AHRIMAN_UNIX_SOCKET" ]; then if [ -n "$AHRIMAN_UNIX_SOCKET" ]; then
AHRIMAN_SETUP_ARGS+=("--web-unix-socket" "$AHRIMAN_UNIX_SOCKET") AHRIMAN_SETUP_ARGS+=("--web-unix-socket" "$AHRIMAN_UNIX_SOCKET")
fi fi

View File

@ -396,6 +396,7 @@ The following environment variables are supported:
* ``AHRIMAN_PACMAN_MIRROR`` - override pacman mirror server if set. * ``AHRIMAN_PACMAN_MIRROR`` - override pacman mirror server if set.
* ``AHRIMAN_PORT`` - HTTP server port if any, default is empty. * ``AHRIMAN_PORT`` - HTTP server port if any, default is empty.
* ``AHRIMAN_REPOSITORY`` - repository name, default is ``aur-clone``. * ``AHRIMAN_REPOSITORY`` - repository name, default is ``aur-clone``.
* ``AHRIMAN_REPOSITORY_SERVER`` - optional override for the repository url. Useful if you would like to download packages from remote instead of local filesystem.
* ``AHRIMAN_REPOSITORY_ROOT`` - repository root. Because of filesystem rights it is required to override default repository root. By default, it uses ``ahriman`` directory inside ahriman's home, which can be passed as mount volume. * ``AHRIMAN_REPOSITORY_ROOT`` - repository root. Because of filesystem rights it is required to override default repository root. By default, it uses ``ahriman`` directory inside ahriman's home, which can be passed as mount volume.
* ``AHRIMAN_UNIX_SOCKET`` - full path to unix socket which is used by web server, default is empty. Note that more likely you would like to put it inside ``AHRIMAN_REPOSITORY_ROOT`` directory (e.g. ``/var/lib/ahriman/ahriman/ahriman-web.sock``) or to ``/tmp``. * ``AHRIMAN_UNIX_SOCKET`` - full path to unix socket which is used by web server, default is empty. Note that more likely you would like to put it inside ``AHRIMAN_REPOSITORY_ROOT`` directory (e.g. ``/var/lib/ahriman/ahriman/ahriman-web.sock``) or to ``/tmp``.
* ``AHRIMAN_USER`` - ahriman user, usually must not be overwritten, default is ``ahriman``. * ``AHRIMAN_USER`` - ahriman user, usually must not be overwritten, default is ``ahriman``.
@ -855,6 +856,11 @@ In addition, the following settings are recommended for workers:
[remote-call] [remote-call]
wait_timeout = 0 wait_timeout = 0
Dependency management
"""""""""""""""""""""
By default worker nodes don't know anything about master nodes packages, thus it will try to build each dependency by its own. However, using ``AHRIMAN_REPOSITORY_SERVER`` docker variable (or ``--server`` flag for setup command), it is possible to specify address of the master node for devtools configuration.
Repository and packages signing Repository and packages signing
""""""""""""""""""""""""""""""" """""""""""""""""""""""""""""""

View File

@ -893,6 +893,7 @@ def _set_service_setup_parser(root: SubParserAction) -> argparse.ArgumentParser:
action=argparse.BooleanOptionalAction, default=True) action=argparse.BooleanOptionalAction, default=True)
parser.add_argument("--packager", help="packager name and email", required=True) parser.add_argument("--packager", help="packager name and email", required=True)
parser.add_argument("--repository", help="repository name", required=True) parser.add_argument("--repository", help="repository name", required=True)
parser.add_argument("--server", help="server to be used for devtools. If none set, local files will be used")
parser.add_argument("--sign-key", help="sign key id") parser.add_argument("--sign-key", help="sign key id")
parser.add_argument("--sign-target", help="sign options", action="append", parser.add_argument("--sign-target", help="sign options", action="append",
type=SignSettings.from_option, choices=enum_values(SignSettings)) type=SignSettings.from_option, choices=enum_values(SignSettings))

View File

@ -63,8 +63,9 @@ class Setup(Handler):
Setup.configuration_create_makepkg(args.packager, args.makeflags_jobs, application.repository.paths) Setup.configuration_create_makepkg(args.packager, args.makeflags_jobs, application.repository.paths)
Setup.executable_create(application.repository.paths, args.build_command, architecture) Setup.executable_create(application.repository.paths, args.build_command, architecture)
repository_server = f"file://{application.repository.paths.repository}" if args.server is None else args.server
Setup.configuration_create_devtools(args.build_command, architecture, args.from_configuration, args.mirror, Setup.configuration_create_devtools(args.build_command, architecture, args.from_configuration, args.mirror,
args.multilib, args.repository, application.repository.paths) args.multilib, args.repository, repository_server)
Setup.configuration_create_sudo(application.repository.paths, args.build_command, architecture) Setup.configuration_create_sudo(application.repository.paths, args.build_command, architecture)
application.repository.repo.init() application.repository.repo.init()
@ -134,7 +135,7 @@ class Setup(Handler):
@staticmethod @staticmethod
def configuration_create_devtools(prefix: str, architecture: str, source: Path, mirror: str | None, def configuration_create_devtools(prefix: str, architecture: str, source: Path, mirror: str | None,
multilib: bool, repository: str, paths: RepositoryPaths) -> None: multilib: bool, repository: str, repository_server: str) -> None:
""" """
create configuration for devtools based on ``source`` configuration create configuration for devtools based on ``source`` configuration
@ -148,7 +149,7 @@ class Setup(Handler):
mirror(str | None): link to package server mirror mirror(str | None): link to package server mirror
multilib(bool): add or do not multilib repository to the configuration multilib(bool): add or do not multilib repository to the configuration
repository(str): repository name repository(str): repository name
paths(RepositoryPaths): repository paths instance repository_server(str): url of the repository
""" """
# allow_no_value=True is required because pacman uses boolean configuration in which just keys present # allow_no_value=True is required because pacman uses boolean configuration in which just keys present
# (e.g. NoProgressBar) which will lead to exception # (e.g. NoProgressBar) which will lead to exception
@ -178,7 +179,7 @@ class Setup(Handler):
# add repository itself # add repository itself
configuration.set_option(repository, "SigLevel", "Never") # we don't care configuration.set_option(repository, "SigLevel", "Never") # we don't care
configuration.set_option(repository, "Server", f"file://{paths.repository}") configuration.set_option(repository, "Server", repository_server)
target = source.parent / f"{prefix}-{architecture}.conf" target = source.parent / f"{prefix}-{architecture}.conf"
with target.open("w") as devtools_configuration: with target.open("w") as devtools_configuration:

View File

@ -32,6 +32,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
args.multilib = True args.multilib = True
args.packager = "John Doe <john@doe.com>" args.packager = "John Doe <john@doe.com>"
args.repository = "aur-clone" args.repository = "aur-clone"
args.server = None
args.sign_key = "key" args.sign_key = "key"
args.sign_target = [SignSettings.Packages] args.sign_target = [SignSettings.Packages]
args.web_port = 8080 args.web_port = 8080
@ -57,13 +58,34 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
ahriman_configuration_mock.assert_called_once_with(args, "x86_64", args.repository, configuration) ahriman_configuration_mock.assert_called_once_with(args, "x86_64", args.repository, configuration)
devtools_configuration_mock.assert_called_once_with( devtools_configuration_mock.assert_called_once_with(
args.build_command, "x86_64", args.from_configuration, args.mirror, args.multilib, args.repository, args.build_command, "x86_64", args.from_configuration, args.mirror, args.multilib, args.repository,
repository_paths) f"file://{repository_paths.repository}")
makepkg_configuration_mock.assert_called_once_with(args.packager, args.makeflags_jobs, repository_paths) makepkg_configuration_mock.assert_called_once_with(args.packager, args.makeflags_jobs, repository_paths)
sudo_configuration_mock.assert_called_once_with(repository_paths, args.build_command, "x86_64") sudo_configuration_mock.assert_called_once_with(repository_paths, args.build_command, "x86_64")
executable_mock.assert_called_once_with(repository_paths, args.build_command, "x86_64") executable_mock.assert_called_once_with(repository_paths, args.build_command, "x86_64")
init_mock.assert_called_once_with() init_mock.assert_called_once_with()
def test_run_with_server(args: argparse.Namespace, configuration: Configuration, repository: Repository,
mocker: MockerFixture) -> None:
"""
must run command with server specified
"""
args = _default_args(args)
args.server = "server"
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
mocker.patch("ahriman.application.handlers.Setup.configuration_create_ahriman")
mocker.patch("ahriman.application.handlers.Setup.configuration_create_makepkg")
mocker.patch("ahriman.application.handlers.Setup.configuration_create_sudo")
mocker.patch("ahriman.application.handlers.Setup.executable_create")
mocker.patch("ahriman.core.alpm.repo.Repo.init")
devtools_configuration_mock = mocker.patch("ahriman.application.handlers.Setup.configuration_create_devtools")
Setup.run(args, "x86_64", configuration, report=False)
devtools_configuration_mock.assert_called_once_with(
args.build_command, "x86_64", args.from_configuration, args.mirror, args.multilib, args.repository,
"server")
def test_build_command(args: argparse.Namespace) -> None: def test_build_command(args: argparse.Namespace) -> None:
""" """
must generate correct build command name must generate correct build command name
@ -120,8 +142,7 @@ def test_configuration_create_ahriman_no_multilib(args: argparse.Namespace, conf
]) # non-strict check called intentionally ]) # non-strict check called intentionally
def test_configuration_create_devtools(args: argparse.Namespace, repository_paths: RepositoryPaths, def test_configuration_create_devtools(args: argparse.Namespace, mocker: MockerFixture) -> None:
mocker: MockerFixture) -> None:
""" """
must create configuration for the devtools must create configuration for the devtools
""" """
@ -132,13 +153,12 @@ def test_configuration_create_devtools(args: argparse.Namespace, repository_path
write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") write_mock = mocker.patch("ahriman.core.configuration.Configuration.write")
Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration, Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration,
None, args.multilib, args.repository, repository_paths) None, args.multilib, args.repository, "server")
add_section_mock.assert_has_calls([MockCall("multilib"), MockCall(args.repository)]) add_section_mock.assert_has_calls([MockCall("multilib"), MockCall(args.repository)])
write_mock.assert_called_once_with(pytest.helpers.anyvar(int)) write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
def test_configuration_create_devtools_mirror(args: argparse.Namespace, repository_paths: RepositoryPaths, def test_configuration_create_devtools_mirror(args: argparse.Namespace, mocker: MockerFixture) -> None:
mocker: MockerFixture) -> None:
""" """
must create configuration for the devtools with mirror set explicitly must create configuration for the devtools with mirror set explicitly
""" """
@ -157,14 +177,13 @@ def test_configuration_create_devtools_mirror(args: argparse.Namespace, reposito
set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option") set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option")
Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration, Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration,
args.mirror, False, args.repository, repository_paths) args.mirror, False, args.repository, "server")
get_mock.assert_has_calls([MockCall("core", "Include", fallback=None), MockCall("extra", "Include", fallback=None)]) get_mock.assert_has_calls([MockCall("core", "Include", fallback=None), MockCall("extra", "Include", fallback=None)])
remove_option_mock.assert_called_once_with("core", "Include") remove_option_mock.assert_called_once_with("core", "Include")
set_option_mock.assert_has_calls([MockCall("core", "Server", args.mirror)]) # non-strict check called intentionally set_option_mock.assert_has_calls([MockCall("core", "Server", args.mirror)]) # non-strict check called intentionally
def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, repository_paths: RepositoryPaths, def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, mocker: MockerFixture) -> None:
mocker: MockerFixture) -> None:
""" """
must create configuration for the devtools without multilib must create configuration for the devtools without multilib
""" """
@ -174,7 +193,7 @@ def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, rep
write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") write_mock = mocker.patch("ahriman.core.configuration.Configuration.write")
Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration, Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration,
None, False, args.repository, repository_paths) None, False, args.repository, "server")
write_mock.assert_called_once_with(pytest.helpers.anyvar(int)) write_mock.assert_called_once_with(pytest.helpers.anyvar(int))