add docker support (#52)

* add docker support

* make shellcheck happy
This commit is contained in:
Evgenii Alekseev 2022-03-13 23:43:25 +03:00 committed by GitHub
parent 9964a96296
commit 046febc440
59 changed files with 429 additions and 103 deletions

51
Dockerfile Normal file
View File

@ -0,0 +1,51 @@
FROM archlinux:base-devel
# image configuration
ENV AHRIMAN_ARCHITECTURE="x86_64"
ENV AHRIMAN_DEBUG=""
ENV AHRIMAN_FORCE_ROOT=""
ENV AHRIMAN_OUTPUT="syslog"
ENV AHRIMAN_PACKAGER="ahriman bot <ahriman@example.com>"
ENV AHRIMAN_PORT=""
ENV AHRIMAN_REPOSITORY="aur-clone"
ENV AHRIMAN_REPOSITORY_ROOT="/var/lib/ahriman/ahriman"
ENV AHRIMAN_USER="ahriman"
# install environment
## install git which is required for AUR interaction and go for yay
RUN pacman --noconfirm -Syu git go
## create build user
RUN useradd -m -d /home/build -s /usr/bin/nologin build && \
echo "build ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/build
## install AUR helper
RUN YAY_DIR="$(runuser -u build -- mktemp -d)" && \
git clone https://aur.archlinux.org/yay.git "$YAY_DIR" && \
cd "$YAY_DIR" && \
runuser -u build -- makepkg --noconfirm --install && \
cd - && rm -r "$YAY_DIR"
## install package dependencies
RUN runuser -u build -- yay --noconfirm -Sy devtools git pyalpm python-inflection python-passlib python-srcinfo && \
runuser -u build -- yay --noconfirm -Sy python-pip && \
runuser -u build -- yay --noconfirm -Sy breezy darcs mercurial python-aioauth-client python-aiohttp \
python-aiohttp-debugtoolbar python-aiohttp-jinja2 python-aiohttp-security \
python-aiohttp-session python-boto3 python-cryptography python-jinja \
rsync subversion
# install ahriman
## copy tree
COPY --chown=build . "/home/build/ahriman"
## create package archive and install it
RUN cd /home/build/ahriman && \
make VERSION="$(git describe --tags --abbrev=0)" archlinux && \
cp ./*-src.tar.xz package/archlinux && \
cd package/archlinux && \
runuser -u build -- makepkg --noconfirm --install --skipchecksums && \
cd - && rm -r /home/build/ahriman
VOLUME ["/var/lib/ahriman"]
# minimal runtime ahriman setup
COPY "docker/entrypoint.sh" "/usr/local/bin/entrypoint"
ENTRYPOINT ["entrypoint"]
# default command
CMD ["repo-update"]

50
docker/entrypoint.sh Executable file
View File

@ -0,0 +1,50 @@
#!/bin/bash
set -e
[ -n "$AHRIMAN_DEBUG" ] && set -x
# configuration tune
sed -i "s|root = /var/lib/ahriman|root = $AHRIMAN_REPOSITORY_ROOT|g" "/etc/ahriman.ini"
sed -i "s|host = 127.0.0.1|host = 0.0.0.0|g" "/etc/ahriman.ini"
sed -i "s|handlers = syslog_handler|handlers = ${AHRIMAN_OUTPUT}_handler|g" "/etc/ahriman.ini.d/logging.ini"
AHRIMAN_DEFAULT_ARGS=("-a" "$AHRIMAN_ARCHITECTURE")
if [[ "$AHRIMAN_OUTPUT" == "syslog" ]]; then
if [ ! -e "/dev/log" ]; then
# by default ahriman uses syslog which is not available inside container
# to make noise less we force quiet mode in case if /dev/log was not mounted
AHRIMAN_DEFAULT_ARGS+=("-q")
fi
fi
# create repository root inside the [[mounted]] directory and set correct ownership
[ -d "$AHRIMAN_REPOSITORY_ROOT" ] || mkdir "$AHRIMAN_REPOSITORY_ROOT"
chown "$AHRIMAN_USER":"$AHRIMAN_USER" "$AHRIMAN_REPOSITORY_ROOT"
# run initial setup
sudo -u "$AHRIMAN_USER" -- ahriman "${AHRIMAN_DEFAULT_ARGS[@]}" repo-init
# run built-in setup command
AHRIMAN_SETUP_ARGS=("--build-as-user" "$AHRIMAN_USER")
AHRIMAN_SETUP_ARGS+=("--packager" "$AHRIMAN_PACKAGER")
AHRIMAN_SETUP_ARGS+=("--repository" "$AHRIMAN_REPOSITORY")
if [ -n "$AHRIMAN_PORT" ]; then
# in addition it must be handled in docker run command
AHRIMAN_SETUP_ARGS+=("--web-port" "$AHRIMAN_PORT")
fi
ahriman "${AHRIMAN_DEFAULT_ARGS[@]}" repo-setup "${AHRIMAN_SETUP_ARGS[@]}"
# refresh database
runuser -u build -- yay --noconfirm -Syy &> /dev/null
# create machine-id which is required by build tools
systemd-machine-id-setup &> /dev/null
# if AHRIMAN_FORCE_ROOT is set or command is unsafe we can run without sudo
# otherwise we prepend executable by sudo command
if [ -n "$AHRIMAN_FORCE_ROOT" ]; then
AHRIMAN_EXECUTABLE=("ahriman")
elif ahriman help-commands-unsafe | grep -Fxq "$1"; then
AHRIMAN_EXECUTABLE=("ahriman")
else
AHRIMAN_EXECUTABLE=("sudo" "-u" "$AHRIMAN_USER" "--" "ahriman")
fi
exec "${AHRIMAN_EXECUTABLE[@]}" "${AHRIMAN_DEFAULT_ARGS[@]}" "$@"

View File

@ -198,6 +198,66 @@ server {
} }
``` ```
## Docker image
We provide official images which can be found under `arcan1s/ahriman` repository. Docker image is being updated on each master commit as well as on each version. If you would like to use last (probably unstable build) you can use `latest` tag; otherwise you can use any version tag available.
The default action (in case if no arguments provided) is `repo-update`. Basically the idea is to run container, e.g.:
```shell
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
```
`--privileged` flag is required to make mount possible inside container. In addition, you can pass own configuration overrides by using the same `-v` flag, e.g.:
```shell
docker run -v /path/to/local/repo:/var/lib/ahriman -v /etc/ahriman.ini:/etc/ahriman.ini.d/10-overrides.ini arcan1s/ahriman:latest
```
By default, it runs `repo-update`, but it can be overwritten to any other command you would like to, e.g.:
```shell
docker run arcan1s/ahriman:latest package-add ahriman --now
```
For more details please refer to docker FAQ.
### Environment variables
The following environment variables are supported:
* `AHRIMAN_ARCHITECTURE` - architecture of the repository, default is `x86_64`.
* `AHRIMAN_DEBUG` - if set all commands will be logged to console.
* `AHRIMAN_FORCE_ROOT` - force run ahriman as root instead of guessing by subcommand.
* `AHRIMAN_OUTPUT` - controls logging handler, e.g. `syslog`, `console`. The name must be found in logging configuration. Note that if `syslog` (the default) handler is used you will need to mount `/dev/log` inside container because it is not available there.
* `AHRIMAN_PACKAGER` - packager name from which packages will be built, default is `ahriman bot <ahriman@example.com>`.
* `AHRIMAN_PORT` - HTTP server port if any, default is empty.
* `AHRIMAN_REPOSITORY` - repository name, default is `aur-clone`.
* `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_USER` - ahriman user, usually must not be overwritten, default is `ahriman`.
You can pass any of these variables by using `-e` argument, e.g.:
```shell
docker run -e AHRIMAN_PORT=8080 arcan1s/ahriman:latest
```
### Working with web service
Well for that you would need to have web container instance running forever; it can be achieved by the following command:
```shell
docker run -p 8080:8080 -e AHRIMAN_PORT=8080 -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
```
Note about `AHRIMAN_PORT` environment variable which is required in order to enable web service. An additional port bind by `-p 8080:8080` is required to pass docker port outside of container.
For every next container run use arguments `-e AHRIMAN_PORT=8080 --net=host`, e.g.:
```shell
docker run --privileged -e AHRIMAN_PORT=8080 --net=host -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
```
## Remote synchronization ## Remote synchronization
### Wait I would like to use the repository from another server ### Wait I would like to use the repository from another server

View File

@ -72,6 +72,7 @@ def _parser() -> argparse.ArgumentParser:
subparsers = parser.add_subparsers(title="command", help="command to run", dest="command", required=True) subparsers = parser.add_subparsers(title="command", help="command to run", dest="command", required=True)
_set_aur_search_parser(subparsers) _set_aur_search_parser(subparsers)
_set_help_commands_unsafe(subparsers)
_set_key_import_parser(subparsers) _set_key_import_parser(subparsers)
_set_package_add_parser(subparsers) _set_package_add_parser(subparsers)
_set_package_remove_parser(subparsers) _set_package_remove_parser(subparsers)
@ -118,6 +119,19 @@ def _set_aur_search_parser(root: SubParserAction) -> argparse.ArgumentParser:
return parser return parser
def _set_help_commands_unsafe(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for listing unsafe commands
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("help-commands-unsafe", help="list unsafe commands",
description="list unsafe commands as defined in default args", formatter_class=_formatter)
parser.set_defaults(handler=handlers.UnsafeCommands, architecture=[""], lock=None, no_report=True, quiet=True,
unsafe=True, parser=_parser)
return parser
def _set_key_import_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_key_import_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for key import subcommand add parser for key import subcommand
@ -396,6 +410,7 @@ def _set_repo_setup_parser(root: SubParserAction) -> argparse.ArgumentParser:
description="create initial service configuration, requires root", description="create initial service configuration, requires root",
epilog="Create _minimal_ configuration for the service according to provided options.", epilog="Create _minimal_ configuration for the service according to provided options.",
formatter_class=_formatter) formatter_class=_formatter)
parser.add_argument("--build-as-user", help="force makepkg user to the specific one")
parser.add_argument("--build-command", help="build command prefix", default="ahriman") parser.add_argument("--build-command", help="build command prefix", default="ahriman")
parser.add_argument("--from-configuration", help="path to default devtools pacman configuration", parser.add_argument("--from-configuration", help="path to default devtools pacman configuration",
type=Path, default=Path("/usr/share/devtools/pacman-extra.conf")) type=Path, default=Path("/usr/share/devtools/pacman-extra.conf"))

View File

@ -32,14 +32,15 @@ class Properties:
:ivar repository: repository instance :ivar repository: repository instance
""" """
def __init__(self, architecture: str, configuration: Configuration, no_report: bool) -> None: def __init__(self, architecture: str, configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
default constructor default constructor
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
self.logger = logging.getLogger("root") self.logger = logging.getLogger("root")
self.configuration = configuration self.configuration = configuration
self.architecture = architecture self.architecture = architecture
self.repository = Repository(architecture, configuration, no_report) self.repository = Repository(architecture, configuration, no_report, unsafe)

View File

@ -35,6 +35,7 @@ from ahriman.application.handlers.sign import Sign
from ahriman.application.handlers.status import Status from ahriman.application.handlers.status import Status
from ahriman.application.handlers.status_update import StatusUpdate from ahriman.application.handlers.status_update import StatusUpdate
from ahriman.application.handlers.sync import Sync from ahriman.application.handlers.sync import Sync
from ahriman.application.handlers.unsafe_commands import UnsafeCommands
from ahriman.application.handlers.update import Update from ahriman.application.handlers.update import Update
from ahriman.application.handlers.user import User from ahriman.application.handlers.user import User
from ahriman.application.handlers.web import Web from ahriman.application.handlers.web import Web

View File

@ -33,15 +33,16 @@ class Add(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
application = Application(architecture, configuration, no_report) application = Application(architecture, configuration, no_report, unsafe)
application.add(args.package, args.source, args.without_dependencies) application.add(args.package, args.source, args.without_dependencies)
if not args.now: if not args.now:
return return

View File

@ -33,13 +33,14 @@ class Clean(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
Application(architecture, configuration, no_report).clean( Application(architecture, configuration, no_report, unsafe).clean(
args.build, args.cache, args.chroot, args.manual, args.packages, args.patches) args.build, args.cache, args.chroot, args.manual, args.packages, args.patches)

View File

@ -35,13 +35,14 @@ class Dump(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
dump = configuration.dump() dump = configuration.dump()
for section, values in sorted(dump.items()): for section, values in sorted(dump.items()):

View File

@ -76,7 +76,7 @@ class Handler:
try: try:
configuration = Configuration.from_path(args.configuration, architecture, args.quiet) configuration = Configuration.from_path(args.configuration, architecture, args.quiet)
with Lock(args, architecture, configuration): with Lock(args, architecture, configuration):
cls.run(args, architecture, configuration, args.no_report) cls.run(args, architecture, configuration, args.no_report, args.unsafe)
return True return True
except Exception: except Exception:
# we are basically always want to print error to stderr instead of default logger # we are basically always want to print error to stderr instead of default logger
@ -107,12 +107,13 @@ class Handler:
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
raise NotImplementedError raise NotImplementedError

View File

@ -35,12 +35,13 @@ class Init(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
Application(architecture, configuration, no_report).repository.repo.init() Application(architecture, configuration, no_report, unsafe).repository.repo.init()

View File

@ -35,12 +35,14 @@ class KeyImport(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
Application(architecture, configuration, no_report).repository.sign.key_import(args.key_server, args.key) Application(architecture, configuration, no_report, unsafe).repository.sign.key_import(
args.key_server, args.key)

View File

@ -41,15 +41,16 @@ class Patch(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
application = Application(architecture, configuration, no_report) application = Application(architecture, configuration, no_report, unsafe)
if args.action == Action.List: if args.action == Action.List:
Patch.patch_set_list(application, args.package) Patch.patch_set_list(application, args.package)

View File

@ -34,17 +34,18 @@ class Rebuild(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
depends_on = set(args.depends_on) if args.depends_on else None depends_on = set(args.depends_on) if args.depends_on else None
application = Application(architecture, configuration, no_report) application = Application(architecture, configuration, no_report, unsafe)
updates = application.repository.packages_depends_on(depends_on) updates = application.repository.packages_depends_on(depends_on)
if args.dry_run: if args.dry_run:
for package in updates: for package in updates:

View File

@ -33,12 +33,13 @@ class Remove(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
Application(architecture, configuration, no_report).remove(args.package) Application(architecture, configuration, no_report, unsafe).remove(args.package)

View File

@ -34,15 +34,16 @@ class RemoveUnknown(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
application = Application(architecture, configuration, no_report) application = Application(architecture, configuration, no_report, unsafe)
unknown_packages = application.unknown() unknown_packages = application.unknown()
if args.dry_run: if args.dry_run:
for package in sorted(unknown_packages): for package in sorted(unknown_packages):

View File

@ -33,12 +33,13 @@ class Report(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
Application(architecture, configuration, no_report).report(args.target, []) Application(architecture, configuration, no_report, unsafe).report(args.target, [])

View File

@ -42,13 +42,14 @@ class Search(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
packages_list = AUR.multisearch(*args.search) packages_list = AUR.multisearch(*args.search)
for package in Search.sort(packages_list, args.sort_by): for package in Search.sort(packages_list, args.sort_by):

View File

@ -46,15 +46,16 @@ class Setup(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
application = Application(architecture, configuration, no_report) application = Application(architecture, configuration, no_report, unsafe)
Setup.configuration_create_makepkg(args.packager, application.repository.paths) Setup.configuration_create_makepkg(args.packager, application.repository.paths)
Setup.executable_create(args.build_command, architecture) Setup.executable_create(args.build_command, architecture)
Setup.configuration_create_devtools(args.build_command, architecture, args.from_configuration, Setup.configuration_create_devtools(args.build_command, architecture, args.from_configuration,
@ -87,6 +88,8 @@ class Setup(Handler):
section = Configuration.section_name("build", architecture) section = Configuration.section_name("build", architecture)
configuration.set_option(section, "build_command", str(Setup.build_command(args.build_command, architecture))) configuration.set_option(section, "build_command", str(Setup.build_command(args.build_command, architecture)))
configuration.set_option("repository", "name", repository) configuration.set_option("repository", "name", repository)
if args.build_as_user is not None:
configuration.set_option(section, "makechrootpkg_flags", f"-U {args.build_as_user}")
if args.sign_key is not None: if args.sign_key is not None:
section = Configuration.section_name("sign", architecture) section = Configuration.section_name("sign", architecture)

View File

@ -33,12 +33,13 @@ class Sign(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
Application(architecture, configuration, no_report).sign(args.package) Application(architecture, configuration, no_report, unsafe).sign(args.package)

View File

@ -39,16 +39,17 @@ class Status(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
# we are using reporter here # we are using reporter here
client = Application(architecture, configuration, no_report=False).repository.reporter client = Application(architecture, configuration, no_report=False, unsafe=unsafe).repository.reporter
if args.ahriman: if args.ahriman:
ahriman = client.get_self() ahriman = client.get_self()
StatusPrinter(ahriman).print(args.info) StatusPrinter(ahriman).print(args.info)

View File

@ -36,16 +36,17 @@ class StatusUpdate(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
# we are using reporter here # we are using reporter here
client = Application(architecture, configuration, no_report=False).repository.reporter client = Application(architecture, configuration, no_report=False, unsafe=unsafe).repository.reporter
if args.action == Action.Update and args.package: if args.action == Action.Update and args.package:
# update packages statuses # update packages statuses

View File

@ -33,12 +33,13 @@ class Sync(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
Application(architecture, configuration, no_report).sync(args.target, []) Application(architecture, configuration, no_report, unsafe).sync(args.target, [])

View File

@ -0,0 +1,58 @@
#
# Copyright (c) 2021 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 argparse
from typing import List, Type
from ahriman.application.formatters.string_printer import StringPrinter
from ahriman.application.handlers.handler import Handler
from ahriman.core.configuration import Configuration
class UnsafeCommands(Handler):
"""
unsafe command help parser
"""
@classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
"""
callback for command line
:param args: command line args
:param architecture: repository architecture
:param configuration: configuration instance
:param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
"""
unsafe_commands = UnsafeCommands.get_unsafe_commands(args.parser())
for command in unsafe_commands:
StringPrinter(command).print(verbose=True)
@staticmethod
def get_unsafe_commands(parser: argparse.ArgumentParser) -> List[str]:
"""
extract unsafe commands from argument parser
:param parser: generated argument parser
:return: list of commands with default unsafe flag
"""
# pylint: disable=protected-access
subparser = next(action for action in parser._actions if isinstance(action, argparse._SubParsersAction))
return [action_name for action_name, action in subparser.choices.items() if action.get_default("unsafe")]

View File

@ -33,15 +33,16 @@ class Update(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
application = Application(architecture, configuration, no_report) application = Application(architecture, configuration, no_report, unsafe)
packages = application.updates(args.package, args.no_aur, args.no_local, args.no_manual, args.no_vcs, packages = application.updates(args.package, args.no_aur, args.no_local, args.no_manual, args.no_vcs,
Update.log_fn(application, args.dry_run)) Update.log_fn(application, args.dry_run))
if args.dry_run: if args.dry_run:

View File

@ -40,13 +40,14 @@ class User(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
salt = User.get_salt(configuration) salt = User.get_salt(configuration)
user = User.user_create(args) user = User.user_create(args)
@ -58,7 +59,7 @@ class User(Handler):
User.configuration_write(auth_configuration, args.secure) User.configuration_write(auth_configuration, args.secure)
if not args.no_reload: if not args.no_reload:
client = Application(architecture, configuration, no_report=False).repository.reporter client = Application(architecture, configuration, no_report=False, unsafe=unsafe).repository.reporter
client.reload_auth() client.reload_auth()
@staticmethod @staticmethod

View File

@ -36,13 +36,14 @@ class Web(Handler):
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None: configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
# we are using local import for optional dependencies # we are using local import for optional dependencies
from ahriman.web.web import run_server, setup_service from ahriman.web.web import run_server, setup_service

View File

@ -103,9 +103,7 @@ class Lock:
""" """
check if current user is actually owner of ahriman root check if current user is actually owner of ahriman root
""" """
if self.unsafe: check_user(self.root, self.unsafe)
return
check_user(self.root)
def clear(self) -> None: def clear(self) -> None:
""" """

View File

@ -45,12 +45,13 @@ class Properties:
:ivar sign: GPG wrapper instance :ivar sign: GPG wrapper instance
""" """
def __init__(self, architecture: str, configuration: Configuration, no_report: bool) -> None: def __init__(self, architecture: str, configuration: Configuration, no_report: bool, unsafe: bool) -> None:
""" """
default constructor default constructor
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting :param no_report: force disable reporting
:param unsafe: if set no user check will be performed before path creation
""" """
self.logger = logging.getLogger("root") self.logger = logging.getLogger("root")
self.architecture = architecture self.architecture = architecture
@ -61,7 +62,7 @@ class Properties:
self.paths = RepositoryPaths(configuration.getpath("repository", "root"), architecture) self.paths = RepositoryPaths(configuration.getpath("repository", "root"), architecture)
try: try:
check_user(self.paths.root) check_user(self.paths.root, unsafe)
self.paths.tree_create() self.paths.tree_create()
except UnsafeRun: except UnsafeRun:
self.logger.warning("root owner differs from the current user, skipping tree creation") self.logger.warning("root owner differs from the current user, skipping tree creation")

View File

@ -49,7 +49,7 @@ class Watcher:
self.logger = logging.getLogger("http") self.logger = logging.getLogger("http")
self.architecture = architecture self.architecture = architecture
self.repository = Repository(architecture, configuration, no_report=True) self.repository = Repository(architecture, configuration, no_report=True, unsafe=False)
self.known: Dict[str, Tuple[Package, BuildStatus]] = {} self.known: Dict[str, Tuple[Package, BuildStatus]] = {}
self.status = BuildStatus() self.status = BuildStatus()

View File

@ -55,13 +55,16 @@ def check_output(*args: str, exception: Optional[Exception], cwd: Optional[Path]
raise exception or e raise exception or e
def check_user(root: Path) -> None: def check_user(root: Path, unsafe: bool) -> None:
""" """
check if current user is the owner of the root check if current user is the owner of the root
:param root: root directory (i.e. ahriman home) :param root: root directory (i.e. ahriman home)
:param unsafe: if set no user check will be performed before path creation
""" """
if not root.exists(): if not root.exists():
return # no directory found, skip check return # no directory found, skip check
if unsafe:
return # unsafe flag is enabled, no check performed
current_uid = os.getuid() current_uid = os.getuid()
root_uid = root.stat().st_uid root_uid = root.stat().st_uid
if current_uid != root_uid: if current_uid != root_uid:

View File

@ -17,7 +17,7 @@ def application_packages(configuration: Configuration, mocker: MockerFixture) ->
:return: application test instance :return: application test instance
""" """
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
return Packages("x86_64", configuration, no_report=True) return Packages("x86_64", configuration, no_report=True, unsafe=False)
@pytest.fixture @pytest.fixture
@ -29,7 +29,7 @@ def application_properties(configuration: Configuration, mocker: MockerFixture)
:return: application test instance :return: application test instance
""" """
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
return Properties("x86_64", configuration, no_report=True) return Properties("x86_64", configuration, no_report=True, unsafe=False)
@pytest.fixture @pytest.fixture
@ -41,4 +41,4 @@ def application_repository(configuration: Configuration, mocker: MockerFixture)
:return: application test instance :return: application test instance
""" """
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
return Repository("x86_64", configuration, no_report=True) return Repository("x86_64", configuration, no_report=True, unsafe=False)

View File

@ -18,7 +18,7 @@ def application(configuration: Configuration, mocker: MockerFixture) -> Applicat
:return: application test instance :return: application test instance
""" """
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
return Application("x86_64", configuration, no_report=True) return Application("x86_64", configuration, no_report=True, unsafe=False)
@pytest.fixture @pytest.fixture

View File

@ -114,4 +114,4 @@ def test_run(args: argparse.Namespace, configuration: Configuration) -> None:
must raise NotImplemented for missing method must raise NotImplemented for missing method
""" """
with pytest.raises(NotImplementedError): with pytest.raises(NotImplementedError):
Handler.run(args, "x86_64", configuration, True) Handler.run(args, "x86_64", configuration, True, True)

View File

@ -30,7 +30,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.application.application.Application.add") application_mock = mocker.patch("ahriman.application.application.Application.add")
Add.run(args, "x86_64", configuration, True) Add.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with(args.package, args.source, args.without_dependencies) application_mock.assert_called_once_with(args.package, args.source, args.without_dependencies)
@ -46,6 +46,6 @@ def test_run_with_updates(args: argparse.Namespace, configuration: Configuration
application_mock = mocker.patch("ahriman.application.application.Application.update") application_mock = mocker.patch("ahriman.application.application.Application.update")
updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman]) updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman])
Add.run(args, "x86_64", configuration, True) Add.run(args, "x86_64", configuration, True, False)
updates_mock.assert_called_once_with(args.package, True, True, False, True, pytest.helpers.anyvar(int)) updates_mock.assert_called_once_with(args.package, True, True, False, True, pytest.helpers.anyvar(int))
application_mock.assert_called_once_with([package_ahriman]) application_mock.assert_called_once_with([package_ahriman])

View File

@ -29,5 +29,5 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.application.application.Application.clean") application_mock = mocker.patch("ahriman.application.application.Application.clean")
Clean.run(args, "x86_64", configuration, True) Clean.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with(False, False, False, False, False, False) application_mock.assert_called_once_with(False, False, False, False, False, False)

View File

@ -15,7 +15,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
application_mock = mocker.patch("ahriman.core.configuration.Configuration.dump", application_mock = mocker.patch("ahriman.core.configuration.Configuration.dump",
return_value=configuration.dump()) return_value=configuration.dump())
Dump.run(args, "x86_64", configuration, True) Dump.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with() application_mock.assert_called_once_with()
print_mock.assert_called() print_mock.assert_called()

View File

@ -14,7 +14,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init") init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init")
Init.run(args, "x86_64", configuration, True) Init.run(args, "x86_64", configuration, True, False)
tree_create_mock.assert_called_once_with() tree_create_mock.assert_called_once_with()
init_mock.assert_called_once_with() init_mock.assert_called_once_with()

View File

@ -25,7 +25,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_import") application_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_import")
KeyImport.run(args, "x86_64", configuration, True) KeyImport.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with(args.key_server, args.key) application_mock.assert_called_once_with(args.key_server, args.key)

View File

@ -32,7 +32,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_create") application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_create")
Patch.run(args, "x86_64", configuration, True) Patch.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, args.track) application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, args.track)
@ -45,7 +45,7 @@ def test_run_list(args: argparse.Namespace, configuration: Configuration, mocker
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_list") application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_list")
Patch.run(args, "x86_64", configuration, True) Patch.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package) application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package)
@ -58,7 +58,7 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, mock
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_remove") application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_remove")
Patch.run(args, "x86_64", configuration, True) Patch.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package) application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package)

View File

@ -29,7 +29,7 @@ def test_run(args: argparse.Namespace, package_ahriman: Package,
return_value=[package_ahriman]) return_value=[package_ahriman])
application_mock = mocker.patch("ahriman.application.application.Application.update") application_mock = mocker.patch("ahriman.application.application.Application.update")
Rebuild.run(args, "x86_64", configuration, True) Rebuild.run(args, "x86_64", configuration, True, False)
application_packages_mock.assert_called_once_with(None) application_packages_mock.assert_called_once_with(None)
application_mock.assert_called_once_with([package_ahriman]) application_mock.assert_called_once_with([package_ahriman])
@ -45,7 +45,7 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration,
mocker.patch("ahriman.core.repository.repository.Repository.packages_depends_on", return_value=[package_ahriman]) mocker.patch("ahriman.core.repository.repository.Repository.packages_depends_on", return_value=[package_ahriman])
application_mock = mocker.patch("ahriman.application.application.Application.update") application_mock = mocker.patch("ahriman.application.application.Application.update")
Rebuild.run(args, "x86_64", configuration, True) Rebuild.run(args, "x86_64", configuration, True, False)
application_mock.assert_not_called() application_mock.assert_not_called()
@ -59,7 +59,7 @@ def test_run_filter(args: argparse.Namespace, configuration: Configuration, mock
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depends_on") application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depends_on")
Rebuild.run(args, "x86_64", configuration, True) Rebuild.run(args, "x86_64", configuration, True, False)
application_packages_mock.assert_called_once_with({"python-aur"}) application_packages_mock.assert_called_once_with({"python-aur"})
@ -72,5 +72,5 @@ def test_run_without_filter(args: argparse.Namespace, configuration: Configurati
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depends_on") application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depends_on")
Rebuild.run(args, "x86_64", configuration, True) Rebuild.run(args, "x86_64", configuration, True, False)
application_packages_mock.assert_called_once_with(None) application_packages_mock.assert_called_once_with(None)

View File

@ -24,5 +24,5 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.application.application.Application.remove") application_mock = mocker.patch("ahriman.application.application.Application.remove")
Remove.run(args, "x86_64", configuration, True) Remove.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with([]) application_mock.assert_called_once_with([])

View File

@ -29,7 +29,7 @@ def test_run(args: argparse.Namespace, package_ahriman: Package,
return_value=[package_ahriman]) return_value=[package_ahriman])
remove_mock = mocker.patch("ahriman.application.application.Application.remove") remove_mock = mocker.patch("ahriman.application.application.Application.remove")
RemoveUnknown.run(args, "x86_64", configuration, True) RemoveUnknown.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with() application_mock.assert_called_once_with()
remove_mock.assert_called_once_with([package_ahriman]) remove_mock.assert_called_once_with([package_ahriman])
@ -47,7 +47,7 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, pac
remove_mock = mocker.patch("ahriman.application.application.Application.remove") remove_mock = mocker.patch("ahriman.application.application.Application.remove")
print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print") print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print")
RemoveUnknown.run(args, "x86_64", configuration, True) RemoveUnknown.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with() application_mock.assert_called_once_with()
remove_mock.assert_not_called() remove_mock.assert_not_called()
print_mock.assert_called_once_with(False) print_mock.assert_called_once_with(False)
@ -67,7 +67,7 @@ def test_run_dry_run_verbose(args: argparse.Namespace, configuration: Configurat
remove_mock = mocker.patch("ahriman.application.application.Application.remove") remove_mock = mocker.patch("ahriman.application.application.Application.remove")
print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print") print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print")
RemoveUnknown.run(args, "x86_64", configuration, True) RemoveUnknown.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with() application_mock.assert_called_once_with()
remove_mock.assert_not_called() remove_mock.assert_not_called()
print_mock.assert_called_once_with(True) print_mock.assert_called_once_with(True)

View File

@ -24,5 +24,5 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.application.application.Application.report") application_mock = mocker.patch("ahriman.application.application.Application.report")
Report.run(args, "x86_64", configuration, True) Report.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with(args.target, []) application_mock.assert_called_once_with(args.target, [])

View File

@ -31,7 +31,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, aur_package
search_mock = mocker.patch("ahriman.core.alpm.aur.AUR.multisearch", return_value=[aur_package_ahriman]) search_mock = mocker.patch("ahriman.core.alpm.aur.AUR.multisearch", return_value=[aur_package_ahriman])
print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print") print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print")
Search.run(args, "x86_64", configuration, True) Search.run(args, "x86_64", configuration, True, False)
search_mock.assert_called_once_with("ahriman") search_mock.assert_called_once_with("ahriman")
print_mock.assert_called_once_with(False) print_mock.assert_called_once_with(False)
@ -45,7 +45,7 @@ def test_run_sort(args: argparse.Namespace, configuration: Configuration, aur_pa
mocker.patch("ahriman.core.alpm.aur.AUR.multisearch", return_value=[aur_package_ahriman]) mocker.patch("ahriman.core.alpm.aur.AUR.multisearch", return_value=[aur_package_ahriman])
sort_mock = mocker.patch("ahriman.application.handlers.search.Search.sort") sort_mock = mocker.patch("ahriman.application.handlers.search.Search.sort")
Search.run(args, "x86_64", configuration, True) Search.run(args, "x86_64", configuration, True, False)
sort_mock.assert_called_once_with([aur_package_ahriman], "name") sort_mock.assert_called_once_with([aur_package_ahriman], "name")
@ -59,7 +59,7 @@ def test_run_sort_by(args: argparse.Namespace, configuration: Configuration, aur
mocker.patch("ahriman.core.alpm.aur.AUR.multisearch", return_value=[aur_package_ahriman]) mocker.patch("ahriman.core.alpm.aur.AUR.multisearch", return_value=[aur_package_ahriman])
sort_mock = mocker.patch("ahriman.application.handlers.search.Search.sort") sort_mock = mocker.patch("ahriman.application.handlers.search.Search.sort")
Search.run(args, "x86_64", configuration, True) Search.run(args, "x86_64", configuration, True, False)
sort_mock.assert_called_once_with([aur_package_ahriman], "field") sort_mock.assert_called_once_with([aur_package_ahriman], "field")

View File

@ -17,6 +17,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
:param args: command line arguments fixture :param args: command line arguments fixture
:return: generated arguments for these test cases :return: generated arguments for these test cases
""" """
args.build_as_user = "ahriman"
args.build_command = "ahriman" args.build_command = "ahriman"
args.from_configuration = Path("/usr/share/devtools/pacman-extra.conf") args.from_configuration = Path("/usr/share/devtools/pacman-extra.conf")
args.no_multilib = False args.no_multilib = False
@ -41,7 +42,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
executable_mock = mocker.patch("ahriman.application.handlers.setup.Setup.executable_create") executable_mock = mocker.patch("ahriman.application.handlers.setup.Setup.executable_create")
paths = RepositoryPaths(configuration.getpath("repository", "root"), "x86_64") paths = RepositoryPaths(configuration.getpath("repository", "root"), "x86_64")
Setup.run(args, "x86_64", configuration, True) Setup.run(args, "x86_64", configuration, True, False)
ahriman_configuration_mock.assert_called_once_with(args, "x86_64", args.repository, configuration.include) ahriman_configuration_mock.assert_called_once_with(args, "x86_64", args.repository, configuration.include)
devtools_configuration_mock.assert_called_once_with(args.build_command, "x86_64", args.from_configuration, devtools_configuration_mock.assert_called_once_with(args.build_command, "x86_64", args.from_configuration,
args.no_multilib, args.repository, paths) args.no_multilib, args.repository, paths)
@ -73,6 +74,7 @@ def test_configuration_create_ahriman(args: argparse.Namespace, configuration: C
set_option_mock.assert_has_calls([ set_option_mock.assert_has_calls([
mock.call(Configuration.section_name("build", "x86_64"), "build_command", str(command)), mock.call(Configuration.section_name("build", "x86_64"), "build_command", str(command)),
mock.call("repository", "name", args.repository), mock.call("repository", "name", args.repository),
mock.call(Configuration.section_name("build", "x86_64"), "makechrootpkg_flags", f"-U {args.build_as_user}"),
mock.call(Configuration.section_name("sign", "x86_64"), "target", mock.call(Configuration.section_name("sign", "x86_64"), "target",
" ".join([target.name.lower() for target in args.sign_target])), " ".join([target.name.lower() for target in args.sign_target])),
mock.call(Configuration.section_name("sign", "x86_64"), "key", args.sign_key), mock.call(Configuration.section_name("sign", "x86_64"), "key", args.sign_key),

View File

@ -24,5 +24,5 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.application.application.Application.sign") application_mock = mocker.patch("ahriman.application.application.Application.sign")
Sign.run(args, "x86_64", configuration, True) Sign.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with([]) application_mock.assert_called_once_with([])

View File

@ -35,7 +35,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, package_ahr
(package_python_schedule, BuildStatus(BuildStatusEnum.Failed))]) (package_python_schedule, BuildStatus(BuildStatusEnum.Failed))])
print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print") print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print")
Status.run(args, "x86_64", configuration, True) Status.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with() application_mock.assert_called_once_with()
packages_mock.assert_called_once_with(None) packages_mock.assert_called_once_with(None)
print_mock.assert_has_calls([mock.call(False) for _ in range(3)]) print_mock.assert_has_calls([mock.call(False) for _ in range(3)])
@ -53,7 +53,7 @@ def test_run_verbose(args: argparse.Namespace, configuration: Configuration, pac
return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))]) return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))])
print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print") print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print")
Status.run(args, "x86_64", configuration, True) Status.run(args, "x86_64", configuration, True, False)
print_mock.assert_has_calls([mock.call(True) for _ in range(2)]) print_mock.assert_has_calls([mock.call(True) for _ in range(2)])
@ -68,7 +68,7 @@ def test_run_with_package_filter(args: argparse.Namespace, configuration: Config
packages_mock = mocker.patch("ahriman.core.status.client.Client.get", packages_mock = mocker.patch("ahriman.core.status.client.Client.get",
return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))]) return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))])
Status.run(args, "x86_64", configuration, True) Status.run(args, "x86_64", configuration, True, False)
packages_mock.assert_called_once_with(package_ahriman.base) packages_mock.assert_called_once_with(package_ahriman.base)
@ -85,7 +85,7 @@ def test_run_by_status(args: argparse.Namespace, configuration: Configuration, p
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print") print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print")
Status.run(args, "x86_64", configuration, True) Status.run(args, "x86_64", configuration, True, False)
print_mock.assert_has_calls([mock.call(False) for _ in range(2)]) print_mock.assert_has_calls([mock.call(False) for _ in range(2)])
@ -97,7 +97,7 @@ def test_imply_with_report(args: argparse.Namespace, configuration: Configuratio
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
load_mock = mocker.patch("ahriman.core.status.client.Client.load") load_mock = mocker.patch("ahriman.core.status.client.Client.load")
Status.run(args, "x86_64", configuration, True) Status.run(args, "x86_64", configuration, True, False)
load_mock.assert_called_once_with(configuration) load_mock.assert_called_once_with(configuration)

View File

@ -29,7 +29,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
update_self_mock = mocker.patch("ahriman.core.status.client.Client.update_self") update_self_mock = mocker.patch("ahriman.core.status.client.Client.update_self")
StatusUpdate.run(args, "x86_64", configuration, True) StatusUpdate.run(args, "x86_64", configuration, True, False)
update_self_mock.assert_called_once_with(args.status) update_self_mock.assert_called_once_with(args.status)
@ -43,7 +43,7 @@ def test_run_packages(args: argparse.Namespace, configuration: Configuration, pa
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
update_mock = mocker.patch("ahriman.core.status.client.Client.update") update_mock = mocker.patch("ahriman.core.status.client.Client.update")
StatusUpdate.run(args, "x86_64", configuration, True) StatusUpdate.run(args, "x86_64", configuration, True, False)
update_mock.assert_called_once_with(package_ahriman.base, args.status) update_mock.assert_called_once_with(package_ahriman.base, args.status)
@ -58,7 +58,7 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, pack
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
update_mock = mocker.patch("ahriman.core.status.client.Client.remove") update_mock = mocker.patch("ahriman.core.status.client.Client.remove")
StatusUpdate.run(args, "x86_64", configuration, True) StatusUpdate.run(args, "x86_64", configuration, True, False)
update_mock.assert_called_once_with(package_ahriman.base) update_mock.assert_called_once_with(package_ahriman.base)
@ -70,7 +70,7 @@ def test_imply_with_report(args: argparse.Namespace, configuration: Configuratio
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
load_mock = mocker.patch("ahriman.core.status.client.Client.load") load_mock = mocker.patch("ahriman.core.status.client.Client.load")
StatusUpdate.run(args, "x86_64", configuration, True) StatusUpdate.run(args, "x86_64", configuration, True, False)
load_mock.assert_called_once_with(configuration) load_mock.assert_called_once_with(configuration)

View File

@ -24,5 +24,5 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.application.application.Application.sync") application_mock = mocker.patch("ahriman.application.application.Application.sync")
Sync.run(args, "x86_64", configuration, True) Sync.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with(args.target, []) application_mock.assert_called_once_with(args.target, [])

View File

@ -34,7 +34,7 @@ def test_run(args: argparse.Namespace, package_ahriman: Package,
application_mock = mocker.patch("ahriman.application.application.Application.update") application_mock = mocker.patch("ahriman.application.application.Application.update")
updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman]) updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman])
Update.run(args, "x86_64", configuration, True) Update.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with([package_ahriman]) application_mock.assert_called_once_with([package_ahriman])
updates_mock.assert_called_once_with(args.package, args.no_aur, args.no_local, args.no_manual, args.no_vcs, updates_mock.assert_called_once_with(args.package, args.no_aur, args.no_local, args.no_manual, args.no_vcs,
pytest.helpers.anyvar(int)) pytest.helpers.anyvar(int))
@ -49,7 +49,7 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, moc
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
updates_mock = mocker.patch("ahriman.application.application.Application.updates") updates_mock = mocker.patch("ahriman.application.application.Application.updates")
Update.run(args, "x86_64", configuration, True) Update.run(args, "x86_64", configuration, True, False)
updates_mock.assert_called_once_with(args.package, args.no_aur, args.no_local, args.no_manual, args.no_vcs, updates_mock.assert_called_once_with(args.package, args.no_aur, args.no_local, args.no_manual, args.no_vcs,
pytest.helpers.anyvar(int)) pytest.helpers.anyvar(int))

View File

@ -41,7 +41,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
get_salt_mock = mocker.patch("ahriman.application.handlers.User.get_salt") get_salt_mock = mocker.patch("ahriman.application.handlers.User.get_salt")
reload_mock = mocker.patch("ahriman.core.status.client.Client.reload_auth") reload_mock = mocker.patch("ahriman.core.status.client.Client.reload_auth")
User.run(args, "x86_64", configuration, True) User.run(args, "x86_64", configuration, True, False)
get_auth_configuration_mock.assert_called_once_with(configuration.include) get_auth_configuration_mock.assert_called_once_with(configuration.include)
create_configuration_mock.assert_called_once_with( create_configuration_mock.assert_called_once_with(
pytest.helpers.anyvar(int), pytest.helpers.anyvar(int), pytest.helpers.anyvar(int), args.as_service) pytest.helpers.anyvar(int), pytest.helpers.anyvar(int), pytest.helpers.anyvar(int), args.as_service)
@ -63,7 +63,7 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, mock
write_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_write") write_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_write")
reload_mock = mocker.patch("ahriman.core.status.client.Client.reload_auth") reload_mock = mocker.patch("ahriman.core.status.client.Client.reload_auth")
User.run(args, "x86_64", configuration, True) User.run(args, "x86_64", configuration, True, False)
get_auth_configuration_mock.assert_called_once_with(configuration.include) get_auth_configuration_mock.assert_called_once_with(configuration.include)
create_configuration_mock.assert_not_called() create_configuration_mock.assert_not_called()
write_configuration_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.secure) write_configuration_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.secure)
@ -81,7 +81,7 @@ def test_run_no_reload(args: argparse.Namespace, configuration: Configuration, m
mocker.patch("ahriman.application.handlers.User.configuration_write") mocker.patch("ahriman.application.handlers.User.configuration_write")
reload_mock = mocker.patch("ahriman.core.status.client.Client.reload_auth") reload_mock = mocker.patch("ahriman.core.status.client.Client.reload_auth")
User.run(args, "x86_64", configuration, True) User.run(args, "x86_64", configuration, True, False)
reload_mock.assert_not_called() reload_mock.assert_not_called()

View File

@ -27,7 +27,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
setup_mock = mocker.patch("ahriman.web.web.setup_service") setup_mock = mocker.patch("ahriman.web.web.setup_service")
run_mock = mocker.patch("ahriman.web.web.run_server") run_mock = mocker.patch("ahriman.web.web.run_server")
Web.run(args, "x86_64", configuration, True) Web.run(args, "x86_64", configuration, True, False)
setup_mock.assert_called_once_with("x86_64", configuration, pytest.helpers.anyvar(int)) setup_mock.assert_called_once_with("x86_64", configuration, pytest.helpers.anyvar(int))
run_mock.assert_called_once_with(pytest.helpers.anyvar(int)) run_mock.assert_called_once_with(pytest.helpers.anyvar(int))

View File

@ -0,0 +1,33 @@
import argparse
import pytest
from pytest_mock import MockerFixture
from ahriman.application.ahriman import _parser
from ahriman.application.handlers import UnsafeCommands
from ahriman.core.configuration import Configuration
def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must run command
"""
args.parser = _parser
commands_mock = mocker.patch("ahriman.application.handlers.UnsafeCommands.get_unsafe_commands",
return_value=["command"])
print_mock = mocker.patch("ahriman.application.formatters.printer.Printer.print")
UnsafeCommands.run(args, "x86_64", configuration, True, False)
commands_mock.assert_called_once_with(pytest.helpers.anyvar(int))
print_mock.assert_called_once_with(verbose=True)
def test_get_unsafe_commands() -> None:
"""
must return unsafe commands
"""
parser = _parser()
subparser = next(action for action in parser._actions if isinstance(action, argparse._SubParsersAction))
commands = UnsafeCommands.get_unsafe_commands(parser)
for command in commands:
assert subparser.choices[command].get_default("unsafe")

View File

@ -65,6 +65,27 @@ def test_subparsers_aur_search_architecture(parser: argparse.ArgumentParser) ->
assert args.architecture == [""] assert args.architecture == [""]
def test_subparsers_help_commands_unsafe(parser: argparse.ArgumentParser) -> None:
"""
help-commands-unsafe command must imply architecture list, lock, no-report, quiet, unsafe and parser
"""
args = parser.parse_args(["help-commands-unsafe"])
assert args.architecture == [""]
assert args.lock is None
assert args.no_report
assert args.quiet
assert args.unsafe
assert args.parser is not None and args.parser()
def test_subparsers_help_commands_unsafe_architecture(parser: argparse.ArgumentParser) -> None:
"""
help-ommands-unsafe command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "help-commands-unsafe"])
assert args.architecture == [""]
def test_subparsers_key_import(parser: argparse.ArgumentParser) -> None: def test_subparsers_key_import(parser: argparse.ArgumentParser) -> None:
""" """
key-import command must imply architecture list, lock and no-report key-import command must imply architecture list, lock and no-report

View File

@ -82,7 +82,7 @@ def test_check_user(lock: Lock, mocker: MockerFixture) -> None:
""" """
check_user_patch = mocker.patch("ahriman.application.lock.check_user") check_user_patch = mocker.patch("ahriman.application.lock.check_user")
lock.check_user() lock.check_user()
check_user_patch.assert_called_once_with(lock.root) check_user_patch.assert_called_once_with(lock.root, False)
def test_check_user_exception(lock: Lock, mocker: MockerFixture) -> None: def test_check_user_exception(lock: Lock, mocker: MockerFixture) -> None:

View File

@ -19,7 +19,7 @@ def cleaner(configuration: Configuration, mocker: MockerFixture) -> Cleaner:
:return: cleaner test instance :return: cleaner test instance
""" """
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
return Cleaner("x86_64", configuration, no_report=True) return Cleaner("x86_64", configuration, no_report=True, unsafe=False)
@pytest.fixture @pytest.fixture
@ -36,7 +36,7 @@ def executor(configuration: Configuration, mocker: MockerFixture) -> Executor:
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_manual") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_manual")
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_packages") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_packages")
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
return Executor("x86_64", configuration, no_report=True) return Executor("x86_64", configuration, no_report=True, unsafe=False)
@pytest.fixture @pytest.fixture
@ -48,7 +48,7 @@ def repository(configuration: Configuration, mocker: MockerFixture) -> Repositor
:return: repository test instance :return: repository test instance
""" """
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
return Repository("x86_64", configuration, no_report=True) return Repository("x86_64", configuration, no_report=True, unsafe=False)
@pytest.fixture @pytest.fixture
@ -58,7 +58,7 @@ def properties(configuration: Configuration) -> Properties:
:param configuration: configuration fixture :param configuration: configuration fixture
:return: properties test instance :return: properties test instance
""" """
return Properties("x86_64", configuration, no_report=True) return Properties("x86_64", configuration, no_report=True, unsafe=False)
@pytest.fixture @pytest.fixture
@ -75,4 +75,4 @@ def update_handler(configuration: Configuration, mocker: MockerFixture) -> Updat
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_manual") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_manual")
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_packages") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_packages")
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
return UpdateHandler("x86_64", configuration, no_report=True) return UpdateHandler("x86_64", configuration, no_report=True, unsafe=False)

View File

@ -12,7 +12,7 @@ def test_create_tree_on_load(configuration: Configuration, mocker: MockerFixture
""" """
mocker.patch("ahriman.core.repository.properties.check_user") mocker.patch("ahriman.core.repository.properties.check_user")
tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
Properties("x86_64", configuration, True) Properties("x86_64", configuration, True, False)
tree_create_mock.assert_called_once_with() tree_create_mock.assert_called_once_with()
@ -23,7 +23,7 @@ def test_create_tree_on_load_unsafe(configuration: Configuration, mocker: Mocker
""" """
mocker.patch("ahriman.core.repository.properties.check_user", side_effect=UnsafeRun(0, 1)) mocker.patch("ahriman.core.repository.properties.check_user", side_effect=UnsafeRun(0, 1))
tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
Properties("x86_64", configuration, True) Properties("x86_64", configuration, True, False)
tree_create_mock.assert_not_called() tree_create_mock.assert_not_called()
@ -34,7 +34,7 @@ def test_create_dummy_report_client(configuration: Configuration, mocker: Mocker
""" """
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
load_mock = mocker.patch("ahriman.core.status.client.Client.load") load_mock = mocker.patch("ahriman.core.status.client.Client.load")
properties = Properties("x86_64", configuration, True) properties = Properties("x86_64", configuration, True, False)
load_mock.assert_not_called() load_mock.assert_not_called()
assert not isinstance(properties.reporter, WebClient) assert not isinstance(properties.reporter, WebClient)
@ -46,6 +46,6 @@ def test_create_full_report_client(configuration: Configuration, mocker: MockerF
""" """
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
load_mock = mocker.patch("ahriman.core.status.client.Client.load") load_mock = mocker.patch("ahriman.core.status.client.Client.load")
Properties("x86_64", configuration, False) Properties("x86_64", configuration, False, False)
load_mock.assert_called_once_with(configuration) load_mock.assert_called_once_with(configuration)

View File

@ -58,7 +58,7 @@ def test_check_user(mocker: MockerFixture) -> None:
""" """
cwd = Path.cwd() cwd = Path.cwd()
mocker.patch("os.getuid", return_value=cwd.stat().st_uid) mocker.patch("os.getuid", return_value=cwd.stat().st_uid)
check_user(cwd) check_user(cwd, False)
def test_check_user_no_directory(mocker: MockerFixture) -> None: def test_check_user_no_directory(mocker: MockerFixture) -> None:
@ -66,7 +66,7 @@ def test_check_user_no_directory(mocker: MockerFixture) -> None:
must not fail in case if no directory found must not fail in case if no directory found
""" """
mocker.patch("pathlib.Path.exists", return_value=False) mocker.patch("pathlib.Path.exists", return_value=False)
check_user(Path.cwd()) check_user(Path.cwd(), False)
def test_check_user_exception(mocker: MockerFixture) -> None: def test_check_user_exception(mocker: MockerFixture) -> None:
@ -77,7 +77,16 @@ def test_check_user_exception(mocker: MockerFixture) -> None:
mocker.patch("os.getuid", return_value=cwd.stat().st_uid + 1) mocker.patch("os.getuid", return_value=cwd.stat().st_uid + 1)
with pytest.raises(UnsafeRun): with pytest.raises(UnsafeRun):
check_user(cwd) check_user(cwd, False)
def test_check_unsafe(mocker: MockerFixture) -> None:
"""
must skip check if unsafe flag is set
"""
cwd = Path.cwd()
mocker.patch("os.getuid", return_value=cwd.stat().st_uid + 1)
check_user(cwd, True)
def test_filter_json(package_ahriman: Package) -> None: def test_filter_json(package_ahriman: Package) -> None: