mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-06-27 14:22:10 +00:00
Compare commits
82 Commits
Author | SHA1 | Date | |
---|---|---|---|
84d4523e85 | |||
2c2eae2334 | |||
214d6d7fdd | |||
e9512e9a6a | |||
f984ea75d0 | |||
b44e5c3a3d | |||
1891d6c944 | |||
08d68258ca | |||
cd3d12a754 | |||
81d9526054 | |||
c7447f19f0 | |||
7de94a8daa | |||
aa1a59d0a3 | |||
8864855c14 | |||
b0b37e8169 | |||
7df4adfc9d | |||
2d5b73c6dc | |||
1c8aed4a97 | |||
2e059023f3 | |||
da5d97788a | |||
0e839fbbf2 | |||
262462d3c3 | |||
7aa91f9e2e | |||
01eda513cf | |||
0161617e36 | |||
4811dec759 | |||
09623c20d5 | |||
eba247b759 | |||
5073c80af1 | |||
766081d212 | |||
896cd0bd71 | |||
ce1bd2f2db | |||
6ba96d838d | |||
df9e03f495 | |||
89944eb2b6 | |||
336784519b | |||
f3341ec7cd | |||
d36e851a29 | |||
28bd5f2095 | |||
011b4e2e31 | |||
15609ba044 | |||
6d4f9981f7 | |||
bbb97d1cdd | |||
3bca780bdd | |||
78e6b48c24 | |||
137d62e2f8 | |||
8a6854c867 | |||
299732181c | |||
84c1b4d82d | |||
cdd66ee780 | |||
b2ed383de0 | |||
551ee670bf | |||
5d4bd9e459 | |||
4f21eb6fe6 | |||
9a008ddafa | |||
0cd07afa0f | |||
f590136197 | |||
1855e513a8 | |||
233dda8420 | |||
9556779ee2 | |||
8b32bd43db | |||
0eadef597a | |||
e58ccdc8ad | |||
2a07356d24 | |||
43c553a3db | |||
0d1a890bd0 | |||
3aeaa8ce2c | |||
7cee859f19 | |||
fb6b22cdd7 | |||
4f35ec6542 | |||
d98211e5e5 | |||
b97c8928e1 | |||
649df81aa5 | |||
ad7cdb7d95 | |||
4bb598d2eb | |||
f47be6cab0 | |||
342b3cb652 | |||
fc0d8387df | |||
e0b0c3caeb | |||
61969dd682 | |||
e441d93a56 | |||
664b6369bb |
14
.dockerignore
Normal file
14
.dockerignore
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
.eggs/
|
||||||
|
.git/
|
||||||
|
.github/
|
||||||
|
.idea/
|
||||||
|
.mypy_cache/
|
||||||
|
.pytest_cache/
|
||||||
|
.tox/
|
||||||
|
.venv/
|
||||||
|
|
||||||
|
*.egg-info/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
*.pyd
|
||||||
|
*.pyo
|
20
.github/ISSUE_TEMPLATE/02-security-report.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/02-security-report.md
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Security report
|
||||||
|
about: Create a report related to security issues
|
||||||
|
title: ''
|
||||||
|
labels: security
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
A clear and concise description of what the issue is.
|
||||||
|
|
||||||
|
### Steps to reproduce
|
||||||
|
|
||||||
|
Steps to reproduce the behavior (commands, environment etc).
|
||||||
|
|
||||||
|
### Intended impact
|
||||||
|
|
||||||
|
Brief optional description of how this vulnerability can be used and which effects can be achieved.
|
16
.github/workflows/run-setup.yml
vendored
16
.github/workflows/run-setup.yml
vendored
@ -7,6 +7,22 @@ on:
|
|||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
run-setup-minimal:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
container:
|
||||||
|
image: archlinux:latest
|
||||||
|
volumes:
|
||||||
|
- ${{ github.workspace }}:/build
|
||||||
|
options: --privileged -w /build
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: setup the minimal service in arch linux container
|
||||||
|
run: .github/workflows/setup.sh minimal
|
||||||
|
|
||||||
run-setup:
|
run-setup:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
33
.github/workflows/setup.sh
vendored
33
.github/workflows/setup.sh
vendored
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
|
|
||||||
|
[[ $1 = "minimal" ]] && MINIMAL_INSTALL=1
|
||||||
|
|
||||||
# install dependencies
|
# install dependencies
|
||||||
echo -e '[arcanisrepo]\nServer = http://repo.arcanis.me/$arch\nSigLevel = Never' | tee -a /etc/pacman.conf
|
echo -e '[arcanisrepo]\nServer = http://repo.arcanis.me/$arch\nSigLevel = Never' | tee -a /etc/pacman.conf
|
||||||
# refresh the image
|
# refresh the image
|
||||||
@ -12,12 +14,14 @@ pacman --noconfirm -Sy base-devel devtools git pyalpm python-aur python-passlib
|
|||||||
# make dependencies
|
# make dependencies
|
||||||
pacman --noconfirm -Sy python-build python-installer python-wheel
|
pacman --noconfirm -Sy python-build python-installer python-wheel
|
||||||
# optional dependencies
|
# optional dependencies
|
||||||
# VCS support
|
if [[ -z $MINIMAL_INSTALL ]]; then
|
||||||
pacman --noconfirm -Sy breezy darcs mercurial subversion
|
# VCS support
|
||||||
# web server
|
pacman --noconfirm -Sy breezy darcs mercurial subversion
|
||||||
pacman --noconfirm -Sy python-aioauth-client python-aiohttp python-aiohttp-debugtoolbar python-aiohttp-jinja2 python-aiohttp-security python-aiohttp-session python-cryptography python-jinja
|
# web server
|
||||||
# additional features
|
pacman --noconfirm -Sy python-aioauth-client python-aiohttp python-aiohttp-debugtoolbar python-aiohttp-jinja2 python-aiohttp-security python-aiohttp-session python-cryptography python-jinja
|
||||||
pacman --noconfirm -Sy gnupg python-boto3 rsync
|
# additional features
|
||||||
|
pacman --noconfirm -Sy gnupg python-boto3 rsync
|
||||||
|
fi
|
||||||
|
|
||||||
# create fresh tarball
|
# create fresh tarball
|
||||||
make VERSION=1.0.0 archlinux # well, it does not really matter which version we will put here
|
make VERSION=1.0.0 archlinux # well, it does not really matter which version we will put here
|
||||||
@ -33,20 +37,23 @@ systemd-machine-id-setup
|
|||||||
# special thing for the container, because /dev/log interface is not available there
|
# special thing for the container, because /dev/log interface is not available there
|
||||||
sed -i "s/handlers = syslog_handler/handlers = console_handler/g" /etc/ahriman.ini.d/logging.ini
|
sed -i "s/handlers = syslog_handler/handlers = console_handler/g" /etc/ahriman.ini.d/logging.ini
|
||||||
# initial setup command as root
|
# initial setup command as root
|
||||||
ahriman -a x86_64 repo-setup --packager "ahriman bot <ahriman@example.com>" --repository "github" --web-port 8080
|
[[ -z $MINIMAL_INSTALL ]] && WEB_ARGS=("--web-port" "8080")
|
||||||
|
ahriman -a x86_64 repo-setup --packager "ahriman bot <ahriman@example.com>" --repository "github" "${WEB_ARGS[@]}"
|
||||||
# enable services
|
# enable services
|
||||||
systemctl enable ahriman-web@x86_64
|
systemctl enable ahriman-web@x86_64
|
||||||
systemctl enable ahriman@x86_64.timer
|
systemctl enable ahriman@x86_64.timer
|
||||||
# run web service (detached)
|
if [[ -z $MINIMAL_INSTALL ]]; then
|
||||||
sudo -u ahriman -- ahriman -a x86_64 web &
|
# run web service (detached)
|
||||||
WEBPID=$!
|
sudo -u ahriman -- ahriman -a x86_64 web &
|
||||||
sleep 15s # wait for the web service activation
|
WEB_PID=$!
|
||||||
|
sleep 15s # wait for the web service activation
|
||||||
|
fi
|
||||||
# add the first package
|
# add the first package
|
||||||
# the build itself does not really work in the container
|
# the build itself does not really work in the container
|
||||||
sudo -u ahriman -- ahriman package-add --now yay
|
sudo -u ahriman -- ahriman package-add --now yay
|
||||||
# check if package was actually installed
|
# check if package was actually installed
|
||||||
#test -n "$(find "/var/lib/ahriman/repository/x86_64" -name "yay*pkg*")"
|
test -n "$(find "/var/lib/ahriman/repository/x86_64" -name "yay*pkg*")"
|
||||||
# run package check
|
# run package check
|
||||||
sudo -u ahriman -- ahriman repo-update
|
sudo -u ahriman -- ahriman repo-update
|
||||||
# stop web service lol
|
# stop web service lol
|
||||||
kill $WEBPID
|
[[ -z $WEB_PID ]] || kill $WEB_PID
|
||||||
|
@ -82,7 +82,8 @@ disable=raw-checker-failed,
|
|||||||
fixme,
|
fixme,
|
||||||
too-many-arguments,
|
too-many-arguments,
|
||||||
duplicate-code,
|
duplicate-code,
|
||||||
cyclic-import
|
cyclic-import,
|
||||||
|
confusing-with-statement,
|
||||||
|
|
||||||
|
|
||||||
# Enable the message, report, category or checker with the given id(s). You can
|
# Enable the message, report, category or checker with the given id(s). You can
|
||||||
@ -148,7 +149,7 @@ indent-string=' '
|
|||||||
max-line-length=100
|
max-line-length=100
|
||||||
|
|
||||||
# Maximum number of lines in a module.
|
# Maximum number of lines in a module.
|
||||||
max-module-lines=1000
|
max-module-lines=400
|
||||||
|
|
||||||
# Allow the body of a class to be on the same line as the declaration if body
|
# Allow the body of a class to be on the same line as the declaration if body
|
||||||
# contains single statement.
|
# contains single statement.
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
version: 2
|
version: 2
|
||||||
|
|
||||||
formats: all
|
formats:
|
||||||
|
- pdf
|
||||||
|
|
||||||
build:
|
build:
|
||||||
os: ubuntu-20.04
|
os: ubuntu-20.04
|
||||||
tools:
|
tools:
|
||||||
python: "3.9"
|
python: "3.10"
|
||||||
|
|
||||||
sphinx:
|
sphinx:
|
||||||
builder: html
|
builder: html
|
||||||
configuration: docs/conf.py
|
configuration: docs/conf.py
|
||||||
|
fail_on_warning: true
|
||||||
|
|
||||||
python:
|
python:
|
||||||
install:
|
install:
|
||||||
@ -17,4 +19,6 @@ python:
|
|||||||
path: .
|
path: .
|
||||||
extra_requirements:
|
extra_requirements:
|
||||||
- docs
|
- docs
|
||||||
|
- s3
|
||||||
|
- web
|
||||||
system_packages: true
|
system_packages: true
|
||||||
|
4
AUTHORS
4
AUTHORS
@ -1,2 +1,2 @@
|
|||||||
Current developers:
|
Current maintainer:
|
||||||
Evgenii Alekseev aka arcanis <esalexeev (at) gmail (dot) com>
|
Evgenii Alekseev <esalexeev (at) gmail (dot) com>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Contributing to ahriman
|
# Contributing to ahriman
|
||||||
|
|
||||||
Welcome to ahriman! The goal of the project is to provide the best user experience to manage Archlinux repositories. In order to follow this we set some limitations for the issue creations and heavily restricted code contribution.
|
Welcome to ahriman! The goal of the project is to provide the best user experience to manage Arch linux repositories. In order to follow this we set some limitations for the issue creations and heavily restricted code contribution.
|
||||||
|
|
||||||
## Create an issue
|
## Create an issue
|
||||||
|
|
||||||
@ -26,12 +26,13 @@ In order to resolve all difficult cases the `autopep8` is used. You can perform
|
|||||||
Again, the most checks can be performed by `make check` command, though some additional guidelines must be applied:
|
Again, the most checks can be performed by `make check` command, though some additional guidelines must be applied:
|
||||||
|
|
||||||
* Every class, every function (including private and protected), every attribute must be documented. The project follows [Google style documentation](https://google.github.io/styleguide/pyguide.html). The only exception is local functions.
|
* Every class, every function (including private and protected), every attribute must be documented. The project follows [Google style documentation](https://google.github.io/styleguide/pyguide.html). The only exception is local functions.
|
||||||
|
* Type annotations are the must, even for local functions.
|
||||||
* For any path interactions `pathlib.Path` must be used.
|
* For any path interactions `pathlib.Path` must be used.
|
||||||
* Configuration interactions must go through `ahriman.core.configuration.Configuration` class instance.
|
* Configuration interactions must go through `ahriman.core.configuration.Configuration` class instance.
|
||||||
* In case if class load requires some actions, it is recommended to create class method which can be used for class instantiating.
|
* In case if class load requires some actions, it is recommended to create class method which can be used for class instantiating.
|
||||||
* The code must follow the exception safety, unless it is explicitly asked by end user. It means that most exceptions must be handled and printed to log, no other actions must be done (e.g. raising another exception).
|
* The code must follow the exception safety, unless it is explicitly asked by end user. It means that most exceptions must be handled and printed to log, no other actions must be done (e.g. raising another exception).
|
||||||
* For the external command `ahriman.core.util.check_output` function must be used.
|
* For the external command `ahriman.core.util.check_output` function must be used.
|
||||||
* Every temporary file/directory must be removed at the end of processing, no matter what. The ``tempfile`` module provides good ways to do it.
|
* Every temporary file/directory must be removed at the end of processing, no matter what. The `tempfile` module provides good ways to do it.
|
||||||
* Import order must be the following:
|
* Import order must be the following:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@ -55,12 +56,12 @@ Again, the most checks can be performed by `make check` command, though some add
|
|||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
```
|
```
|
||||||
|
|
||||||
* One file should define only one class, exception is class satellites in case if file length remain less than 200 lines.
|
* One file should define only one class, exception is class satellites in case if file length remains less than 400 lines.
|
||||||
* It is possible to create file which contains some functions (e.g. `ahriman.core.util`), but in this case you would need to define `__all__` attribute.
|
* It is possible to create file which contains some functions (e.g. `ahriman.core.util`), but in this case you would need to define `__all__` attribute.
|
||||||
* The file size mentioned above must be applicable in general. In case of big classes consider splitting them into traits.
|
* The file size mentioned above must be applicable in general. In case of big classes consider splitting them into traits. Note, however, that `pylint` includes comments and docstrings into counter, thus you need to check file size by other tools.
|
||||||
* No global variable allowed outside of `ahriman.version` module.
|
* No global variable is allowed outside of `ahriman.version` module.
|
||||||
* Single quotes are not allowed. The reason behind this restriction is the fact that docstrings must be written by using double quotes only, and we would like to make style consistent.
|
* Single quotes are not allowed. The reason behind this restriction is the fact that docstrings must be written by using double quotes only, and we would like to make style consistent.
|
||||||
* If your class writes anything to log, the `ahriman.core.lazy_logging.LazyLogging` trait must be used.
|
* If your class writes anything to log, the `ahriman.core.log.LazyLogging` trait must be used.
|
||||||
|
|
||||||
### Other checks
|
### Other checks
|
||||||
|
|
||||||
|
12
Dockerfile
12
Dockerfile
@ -10,20 +10,24 @@ ENV AHRIMAN_PACKAGER="ahriman bot <ahriman@example.com>"
|
|||||||
ENV AHRIMAN_PORT=""
|
ENV AHRIMAN_PORT=""
|
||||||
ENV AHRIMAN_REPOSITORY="aur-clone"
|
ENV AHRIMAN_REPOSITORY="aur-clone"
|
||||||
ENV AHRIMAN_REPOSITORY_ROOT="/var/lib/ahriman/ahriman"
|
ENV AHRIMAN_REPOSITORY_ROOT="/var/lib/ahriman/ahriman"
|
||||||
|
ENV AHRIMAN_UNIX_SOCKET=""
|
||||||
ENV AHRIMAN_USER="ahriman"
|
ENV AHRIMAN_USER="ahriman"
|
||||||
|
|
||||||
# install environment
|
# install environment
|
||||||
|
## update pacman.conf with multilib
|
||||||
|
RUN echo "[multilib]" >> "/etc/pacman.conf" && \
|
||||||
|
echo "Include = /etc/pacman.d/mirrorlist" >> "/etc/pacman.conf"
|
||||||
## install minimal required packages
|
## install minimal required packages
|
||||||
RUN pacman --noconfirm -Syu binutils fakeroot git make sudo
|
RUN pacman --noconfirm -Syu binutils fakeroot git make sudo
|
||||||
## create build user
|
## create build user
|
||||||
RUN useradd -m -d /home/build -s /usr/bin/nologin build && \
|
RUN useradd -m -d "/home/build" -s "/usr/bin/nologin" build && \
|
||||||
echo "build ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/build
|
echo "build ALL=(ALL) NOPASSWD: ALL" > "/etc/sudoers.d/build"
|
||||||
COPY "docker/install-aur-package.sh" "/usr/local/bin/install-aur-package"
|
COPY "docker/install-aur-package.sh" "/usr/local/bin/install-aur-package"
|
||||||
## install package dependencies
|
## install package dependencies
|
||||||
## darcs is not installed by reasons, because it requires a lot haskell packages which dramatically increase image size
|
## darcs is not installed by reasons, because it requires a lot haskell packages which dramatically increase image size
|
||||||
RUN pacman --noconfirm -Sy devtools git pyalpm python-inflection python-passlib python-requests python-setuptools python-srcinfo && \
|
RUN pacman --noconfirm -Sy devtools git pyalpm python-inflection python-passlib python-requests python-setuptools python-srcinfo && \
|
||||||
pacman --noconfirm -Sy python-build python-installer python-wheel && \
|
pacman --noconfirm -Sy python-build python-installer python-wheel && \
|
||||||
pacman --noconfirm -Sy breezy mercurial python-aiohttp python-boto3 python-cryptography python-jinja rsync subversion && \
|
pacman --noconfirm -Sy breezy mercurial python-aiohttp python-boto3 python-cryptography python-jinja python-requests-unixsocket rsync subversion && \
|
||||||
runuser -u build -- install-aur-package python-aioauth-client python-aiohttp-jinja2 python-aiohttp-debugtoolbar \
|
runuser -u build -- install-aur-package python-aioauth-client python-aiohttp-jinja2 python-aiohttp-debugtoolbar \
|
||||||
python-aiohttp-session python-aiohttp-security
|
python-aiohttp-session python-aiohttp-security
|
||||||
|
|
||||||
@ -47,4 +51,4 @@ VOLUME ["/var/lib/ahriman"]
|
|||||||
COPY "docker/entrypoint.sh" "/usr/local/bin/entrypoint"
|
COPY "docker/entrypoint.sh" "/usr/local/bin/entrypoint"
|
||||||
ENTRYPOINT ["entrypoint"]
|
ENTRYPOINT ["entrypoint"]
|
||||||
# default command
|
# default command
|
||||||
CMD ["repo-update"]
|
CMD ["repo-update", "--refresh"]
|
||||||
|
6
Makefile
6
Makefile
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
PROJECT := ahriman
|
PROJECT := ahriman
|
||||||
|
|
||||||
FILES := AUTHORS CONTRIBUTING.md COPYING README.md docs package src setup.py tox.ini web.png
|
FILES := AUTHORS CONTRIBUTING.md COPYING Makefile README.md SECURITY.md docs package src setup.py tox.ini web.png
|
||||||
TARGET_FILES := $(addprefix $(PROJECT)/, $(FILES))
|
TARGET_FILES := $(addprefix $(PROJECT)/, $(FILES))
|
||||||
IGNORE_FILES := package/archlinux src/.mypy_cache
|
IGNORE_FILES := package/archlinux src/.mypy_cache
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ html: specification
|
|||||||
tox -e docs-html
|
tox -e docs-html
|
||||||
|
|
||||||
push: specification archlinux
|
push: specification archlinux
|
||||||
git add package/archlinux/PKGBUILD src/ahriman/version.py docs/ahriman-architecture.svg docs/ahriman.1
|
git add package/archlinux/PKGBUILD src/ahriman/version.py docs/ahriman-architecture.svg docs/ahriman.1 docs/completions/
|
||||||
git commit -m "Release $(VERSION)"
|
git commit -m "Release $(VERSION)"
|
||||||
git tag "$(VERSION)"
|
git tag "$(VERSION)"
|
||||||
git push
|
git push
|
||||||
@ -56,4 +56,4 @@ version:
|
|||||||
ifndef VERSION
|
ifndef VERSION
|
||||||
$(error VERSION is required, but not set)
|
$(error VERSION is required, but not set)
|
||||||
endif
|
endif
|
||||||
sed -i '/__version__ = .*/s/[^"][^)]*/__version__ = "$(VERSION)"/' src/ahriman/version.py
|
sed -i 's/^__version__ = .*/__version__ = "$(VERSION)"/' src/ahriman/version.py
|
||||||
|
@ -33,3 +33,9 @@ Every available option is described in the [documentation](https://ahriman.readt
|
|||||||
The application provides reasonable defaults which allow to use it out-of-box; however additional steps (like configuring build toolchain and sudoers) are recommended and can be easily achieved by following install instructions.
|
The application provides reasonable defaults which allow to use it out-of-box; however additional steps (like configuring build toolchain and sudoers) are recommended and can be easily achieved by following install instructions.
|
||||||
|
|
||||||
## [FAQ](https://ahriman.readthedocs.io/en/latest/faq.html)
|
## [FAQ](https://ahriman.readthedocs.io/en/latest/faq.html)
|
||||||
|
|
||||||
|
## Live demos
|
||||||
|
|
||||||
|
* [Build status page](https://ahriman-demo.arcanis.me). You can log in as `demo` user by using `demo` password. However, you will not be able to run tasks.
|
||||||
|
* [Repository index](http://repo.arcanis.me/x86_64/index.html).
|
||||||
|
* [Telegram feed](https://t.me/arcanisrepo).
|
||||||
|
9
SECURITY.md
Normal file
9
SECURITY.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
The project follows bleeding edge philosophy, thus only the latest version is supported with the exception for release candidates (i.e. tags which are marked with `rc` suffix).
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
In the most cases you can report (suspected) security vulnerabilities directly on github by using ["Security report" template](https://github.com/arcan1s/ahriman/issues/new?assignees=&labels=security&template=02-security-report.md&title=). However, if your report could lead to data leak or break the system we kindly ask you to contact [current maintainer](AUTHORS) directly by email.
|
@ -4,9 +4,17 @@ set -e
|
|||||||
[ -n "$AHRIMAN_DEBUG" ] && set -x
|
[ -n "$AHRIMAN_DEBUG" ] && set -x
|
||||||
|
|
||||||
# configuration tune
|
# configuration tune
|
||||||
sed -i "s|root = /var/lib/ahriman|root = $AHRIMAN_REPOSITORY_ROOT|g" "/etc/ahriman.ini"
|
cat <<EOF > "/etc/ahriman.ini.d/00-docker.ini"
|
||||||
sed -i "s|database = /var/lib/ahriman/ahriman.db|database = $AHRIMAN_REPOSITORY_ROOT/ahriman.db|g" "/etc/ahriman.ini"
|
[repository]
|
||||||
sed -i "s|host = 127.0.0.1|host = $AHRIMAN_HOST|g" "/etc/ahriman.ini"
|
root = $AHRIMAN_REPOSITORY_ROOT
|
||||||
|
|
||||||
|
[settings]
|
||||||
|
database = $AHRIMAN_REPOSITORY_ROOT/ahriman.db
|
||||||
|
|
||||||
|
[web]
|
||||||
|
host = $AHRIMAN_HOST
|
||||||
|
|
||||||
|
EOF
|
||||||
sed -i "s|handlers = syslog_handler|handlers = ${AHRIMAN_OUTPUT}_handler|g" "/etc/ahriman.ini.d/logging.ini"
|
sed -i "s|handlers = syslog_handler|handlers = ${AHRIMAN_OUTPUT}_handler|g" "/etc/ahriman.ini.d/logging.ini"
|
||||||
|
|
||||||
AHRIMAN_DEFAULT_ARGS=("--architecture" "$AHRIMAN_ARCHITECTURE")
|
AHRIMAN_DEFAULT_ARGS=("--architecture" "$AHRIMAN_ARCHITECTURE")
|
||||||
@ -22,18 +30,23 @@ fi
|
|||||||
[ -d "$AHRIMAN_REPOSITORY_ROOT" ] || mkdir "$AHRIMAN_REPOSITORY_ROOT"
|
[ -d "$AHRIMAN_REPOSITORY_ROOT" ] || mkdir "$AHRIMAN_REPOSITORY_ROOT"
|
||||||
chown "$AHRIMAN_USER":"$AHRIMAN_USER" "$AHRIMAN_REPOSITORY_ROOT"
|
chown "$AHRIMAN_USER":"$AHRIMAN_USER" "$AHRIMAN_REPOSITORY_ROOT"
|
||||||
|
|
||||||
|
# create .gnupg directory which is required for keys
|
||||||
|
AHRIMAN_GNUPG_HOME="$(getent passwd "$AHRIMAN_USER" | cut -d : -f 6)/.gnupg"
|
||||||
|
[ -d "$AHRIMAN_GNUPG_HOME" ] || mkdir -m700 "$AHRIMAN_GNUPG_HOME"
|
||||||
|
chown "$AHRIMAN_USER":"$AHRIMAN_USER" "$AHRIMAN_GNUPG_HOME"
|
||||||
|
|
||||||
# run built-in setup command
|
# run built-in setup command
|
||||||
AHRIMAN_SETUP_ARGS=("--build-as-user" "$AHRIMAN_USER")
|
AHRIMAN_SETUP_ARGS=("--build-as-user" "$AHRIMAN_USER")
|
||||||
AHRIMAN_SETUP_ARGS+=("--packager" "$AHRIMAN_PACKAGER")
|
AHRIMAN_SETUP_ARGS+=("--packager" "$AHRIMAN_PACKAGER")
|
||||||
AHRIMAN_SETUP_ARGS+=("--repository" "$AHRIMAN_REPOSITORY")
|
AHRIMAN_SETUP_ARGS+=("--repository" "$AHRIMAN_REPOSITORY")
|
||||||
if [ -n "$AHRIMAN_PORT" ]; then
|
if [ -n "$AHRIMAN_PORT" ]; then
|
||||||
# in addition it must be handled in docker run command
|
|
||||||
AHRIMAN_SETUP_ARGS+=("--web-port" "$AHRIMAN_PORT")
|
AHRIMAN_SETUP_ARGS+=("--web-port" "$AHRIMAN_PORT")
|
||||||
fi
|
fi
|
||||||
|
if [ -n "$AHRIMAN_UNIX_SOCKET" ]; then
|
||||||
|
AHRIMAN_SETUP_ARGS+=("--web-unix-socket" "$AHRIMAN_UNIX_SOCKET")
|
||||||
|
fi
|
||||||
ahriman "${AHRIMAN_DEFAULT_ARGS[@]}" repo-setup "${AHRIMAN_SETUP_ARGS[@]}"
|
ahriman "${AHRIMAN_DEFAULT_ARGS[@]}" repo-setup "${AHRIMAN_SETUP_ARGS[@]}"
|
||||||
|
|
||||||
# refresh database
|
|
||||||
pacman -Syy &> /dev/null
|
|
||||||
# create machine-id which is required by build tools
|
# create machine-id which is required by build tools
|
||||||
systemd-machine-id-setup &> /dev/null
|
systemd-machine-id-setup &> /dev/null
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ Depending on the goal the package can be used in different ways. Nevertheless, i
|
|||||||
from ahriman.core.database import SQLite
|
from ahriman.core.database import SQLite
|
||||||
|
|
||||||
architecture = "x86_64"
|
architecture = "x86_64"
|
||||||
configuration = Configuration.from_path(Path("/etc/ahriman.ini"), architecture, quiet=False)
|
configuration = Configuration.from_path(Path("/etc/ahriman.ini"), architecture)
|
||||||
sqlite = SQLite.load(configuration)
|
database = SQLite.load(configuration)
|
||||||
|
|
||||||
At this point there are ``configuration`` and ``database`` instances which can be used later at any time anywhere, e.g.
|
At this point there are ``configuration`` and ``database`` instances which can be used later at any time anywhere, e.g.
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ Almost all actions are wrapped by ``ahriman.core.repository.Repository`` class
|
|||||||
|
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
|
|
||||||
repository = Repository(architecture, configuration, database, no_report=False, unsafe=False)
|
repository = Repository(architecture, configuration, database, report=True, unsafe=False)
|
||||||
|
|
||||||
And the ``repository`` instance can be used to perform repository maintenance
|
And the ``repository`` instance can be used to perform repository maintenance
|
||||||
|
|
||||||
@ -37,6 +37,6 @@ And the ``repository`` instance can be used to perform repository maintenance
|
|||||||
built_packages = repository.packages_built()
|
built_packages = repository.packages_built()
|
||||||
update_result = repository.process_update(built_packages)
|
update_result = repository.process_update(built_packages)
|
||||||
|
|
||||||
repository.process_triggers(update_result)
|
repository.triggers.on_result(update_result, repository.packages())
|
||||||
|
|
||||||
For the more info please refer to the classes documentation.
|
For the more info please refer to the classes documentation.
|
||||||
|
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 537 KiB After Width: | Height: | Size: 641 KiB |
432
docs/ahriman.1
432
docs/ahriman.1
@ -1,16 +1,16 @@
|
|||||||
.TH AHRIMAN "1" Manual
|
.TH AHRIMAN "1" "2023\-01\-02" "ahriman" "Generated Python Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
ahriman
|
ahriman
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B ahriman
|
.B ahriman
|
||||||
[-h] [-a ARCHITECTURE] [-c CONFIGURATION] [--force] [-l LOCK] [--no-report] [-q] [--unsafe] [-V] {aur-search,search,help,help-commands-unsafe,key-import,package-add,add,package-update,package-remove,remove,package-status,status,package-status-remove,package-status-update,status-update,patch-add,patch-list,patch-remove,repo-backup,repo-check,check,repo-clean,clean,repo-config,config,repo-rebuild,rebuild,repo-remove-unknown,remove-unknown,repo-report,report,repo-restore,repo-setup,init,repo-init,setup,repo-sign,sign,repo-status-update,repo-sync,sync,repo-triggers,repo-update,update,shell,user-add,user-list,user-remove,version,web} ...
|
[-h] [-a ARCHITECTURE] [-c CONFIGURATION] [--force] [-l LOCK] [--report | --no-report] [-q] [--unsafe] [-V] {aur-search,search,daemon,help,help-commands-unsafe,key-import,package-add,add,package-update,package-remove,remove,package-status,status,package-status-remove,package-status-update,status-update,patch-add,patch-list,patch-remove,patch-set-add,repo-backup,repo-check,check,repo-clean,clean,repo-config,config,repo-rebuild,rebuild,repo-remove-unknown,remove-unknown,repo-report,report,repo-restore,repo-setup,init,repo-init,setup,repo-sign,sign,repo-status-update,repo-sync,sync,repo-tree,repo-triggers,repo-update,update,shell,user-add,user-list,user-remove,version,web} ...
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
ArcH linux ReposItory MANager
|
ArcH linux ReposItory MANager
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
\fB\-a\fR \fI\,ARCHITECTURE\/\fR, \fB\-\-architecture\fR \fI\,ARCHITECTURE\/\fR
|
\fB\-a\fR \fI\,ARCHITECTURE\/\fR, \fB\-\-architecture\fR \fI\,ARCHITECTURE\/\fR
|
||||||
target architectures (can be used multiple times)
|
target architectures. For several subcommands it can be used multiple times
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-c\fR \fI\,CONFIGURATION\/\fR, \fB\-\-configuration\fR \fI\,CONFIGURATION\/\fR
|
\fB\-c\fR \fI\,CONFIGURATION\/\fR, \fB\-\-configuration\fR \fI\,CONFIGURATION\/\fR
|
||||||
@ -25,8 +25,8 @@ force run, remove file lock
|
|||||||
lock file
|
lock file
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-no\-report\fR
|
\fB\-\-report\fR, \fB\-\-no\-report\fR
|
||||||
force disable reporting to web service
|
force enable or disable reporting to web service (default: True)
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-q\fR, \fB\-\-quiet\fR
|
\fB\-q\fR, \fB\-\-quiet\fR
|
||||||
@ -43,94 +43,103 @@ show program's version number and exit
|
|||||||
.SH
|
.SH
|
||||||
COMMAND
|
COMMAND
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,aur-search\/\fR
|
\fBahriman\fR \fI\,aur\-search\/\fR
|
||||||
search for package
|
search for package
|
||||||
.TP
|
.TP
|
||||||
|
\fBahriman\fR \fI\,daemon\/\fR
|
||||||
|
run application as daemon
|
||||||
|
.TP
|
||||||
\fBahriman\fR \fI\,help\/\fR
|
\fBahriman\fR \fI\,help\/\fR
|
||||||
show help message
|
show help message
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,help-commands-unsafe\/\fR
|
\fBahriman\fR \fI\,help\-commands\-unsafe\/\fR
|
||||||
list unsafe commands
|
list unsafe commands
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,key-import\/\fR
|
\fBahriman\fR \fI\,key\-import\/\fR
|
||||||
import PGP key
|
import PGP key
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,package-add\/\fR
|
\fBahriman\fR \fI\,package\-add\/\fR
|
||||||
add package
|
add package
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,package-remove\/\fR
|
\fBahriman\fR \fI\,package\-remove\/\fR
|
||||||
remove package
|
remove package
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,package-status\/\fR
|
\fBahriman\fR \fI\,package\-status\/\fR
|
||||||
get package status
|
get package status
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,package-status-remove\/\fR
|
\fBahriman\fR \fI\,package\-status\-remove\/\fR
|
||||||
remove package status
|
remove package status
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,package-status-update\/\fR
|
\fBahriman\fR \fI\,package\-status\-update\/\fR
|
||||||
update package status
|
update package status
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,patch-add\/\fR
|
\fBahriman\fR \fI\,patch\-add\/\fR
|
||||||
add patch set
|
add patch for PKGBUILD function
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,patch-list\/\fR
|
\fBahriman\fR \fI\,patch\-list\/\fR
|
||||||
list patch sets
|
list patch sets
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,patch-remove\/\fR
|
\fBahriman\fR \fI\,patch\-remove\/\fR
|
||||||
remove patch set
|
remove patch set
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-backup\/\fR
|
\fBahriman\fR \fI\,patch\-set\-add\/\fR
|
||||||
|
add patch set
|
||||||
|
.TP
|
||||||
|
\fBahriman\fR \fI\,repo\-backup\/\fR
|
||||||
backup repository data
|
backup repository data
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-check\/\fR
|
\fBahriman\fR \fI\,repo\-check\/\fR
|
||||||
check for updates
|
check for updates
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-clean\/\fR
|
\fBahriman\fR \fI\,repo\-clean\/\fR
|
||||||
clean local caches
|
clean local caches
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-config\/\fR
|
\fBahriman\fR \fI\,repo\-config\/\fR
|
||||||
dump configuration
|
dump configuration
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-rebuild\/\fR
|
\fBahriman\fR \fI\,repo\-rebuild\/\fR
|
||||||
rebuild repository
|
rebuild repository
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-remove-unknown\/\fR
|
\fBahriman\fR \fI\,repo\-remove\-unknown\/\fR
|
||||||
remove unknown packages
|
remove unknown packages
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-report\/\fR
|
\fBahriman\fR \fI\,repo\-report\/\fR
|
||||||
generate report
|
generate report
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-restore\/\fR
|
\fBahriman\fR \fI\,repo\-restore\/\fR
|
||||||
restore repository data
|
restore repository data
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-setup\/\fR
|
\fBahriman\fR \fI\,repo\-setup\/\fR
|
||||||
initial service configuration
|
initial service configuration
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-sign\/\fR
|
\fBahriman\fR \fI\,repo\-sign\/\fR
|
||||||
sign packages
|
sign packages
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-status-update\/\fR
|
\fBahriman\fR \fI\,repo\-status\-update\/\fR
|
||||||
update repository status
|
update repository status
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-sync\/\fR
|
\fBahriman\fR \fI\,repo\-sync\/\fR
|
||||||
sync repository
|
sync repository
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-triggers\/\fR
|
\fBahriman\fR \fI\,repo\-tree\/\fR
|
||||||
|
dump repository tree
|
||||||
|
.TP
|
||||||
|
\fBahriman\fR \fI\,repo\-triggers\/\fR
|
||||||
run triggers
|
run triggers
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,repo-update\/\fR
|
\fBahriman\fR \fI\,repo\-update\/\fR
|
||||||
update packages
|
update packages
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,shell\/\fR
|
\fBahriman\fR \fI\,shell\/\fR
|
||||||
envoke python shell
|
invoke python shell
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,user-add\/\fR
|
\fBahriman\fR \fI\,user\-add\/\fR
|
||||||
create or update user
|
create or update user
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,user-list\/\fR
|
\fBahriman\fR \fI\,user\-list\/\fR
|
||||||
user known users and their access
|
user known users and their access
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,user-remove\/\fR
|
\fBahriman\fR \fI\,user\-remove\/\fR
|
||||||
remove user
|
remove user
|
||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,version\/\fR
|
\fBahriman\fR \fI\,version\/\fR
|
||||||
@ -138,33 +147,65 @@ application version
|
|||||||
.TP
|
.TP
|
||||||
\fBahriman\fR \fI\,web\/\fR
|
\fBahriman\fR \fI\,web\/\fR
|
||||||
web server
|
web server
|
||||||
.SH COMMAND \fI\,'ahriman aur-search'\/\fR
|
|
||||||
usage: ahriman aur-search [-h] [-e] [-i]
|
.SH COMMAND \fI\,'ahriman aur\-search'\/\fR
|
||||||
[--sort-by {description,first_submitted,id,last_modified,maintainer,name,num_votes,out_of_date,package_base,package_base_id,popularity,repository,url,url_path,version}]
|
usage: ahriman aur\-search [\-h] [\-e] [\-\-info | \-\-no\-info]
|
||||||
|
[\-\-sort\-by {description,first_submitted,id,last_modified,maintainer,name,num_votes,out_of_date,package_base,package_base_id,popularity,repository,url,url_path,version}]
|
||||||
search [search ...]
|
search [search ...]
|
||||||
|
|
||||||
search for package in AUR using API
|
search for package in AUR using API
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fBsearch\fR
|
\fBsearch\fR
|
||||||
search terms, can be specified multiple times, result will match all terms
|
search terms, can be specified multiple times, the result will match all terms
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman aur-search'\/\fR
|
.SH OPTIONS \fI\,'ahriman aur\-search'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-e\fR, \fB\-\-exit\-code\fR
|
\fB\-e\fR, \fB\-\-exit\-code\fR
|
||||||
return non\-zero exit status if result is empty
|
return non\-zero exit status if result is empty
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-i\fR, \fB\-\-info\fR
|
\fB\-\-info\fR, \fB\-\-no\-info\fR
|
||||||
show additional package information
|
show additional package information (default: False)
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-sort\-by\fR \fI\,{description,first_submitted,id,last_modified,maintainer,name,num_votes,out_of_date,package_base,package_base_id,popularity,repository,url,url_path,version}\/\fR
|
\fB\-\-sort\-by\fR \fI\,{description,first_submitted,id,last_modified,maintainer,name,num_votes,out_of_date,package_base,package_base_id,popularity,repository,url,url_path,version}\/\fR
|
||||||
sort field by this field. In case if two packages have the same value of the specified field, they will be always sorted
|
sort field by this field. In case if two packages have the same value of the specified field, they will be always sorted
|
||||||
by name
|
by name
|
||||||
|
|
||||||
|
.SH COMMAND \fI\,'ahriman daemon'\/\fR
|
||||||
|
usage: ahriman daemon [\-h] [\-i INTERVAL] [\-\-aur | \-\-no\-aur] [\-\-local | \-\-no\-local] [\-\-manual | \-\-no\-manual]
|
||||||
|
[\-\-vcs | \-\-no\-vcs] [\-y]
|
||||||
|
|
||||||
|
start process which periodically will run update process
|
||||||
|
|
||||||
|
.SH OPTIONS \fI\,'ahriman daemon'\/\fR
|
||||||
|
.TP
|
||||||
|
\fB\-i\fR \fI\,INTERVAL\/\fR, \fB\-\-interval\fR \fI\,INTERVAL\/\fR
|
||||||
|
interval between runs in seconds
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-\-aur\fR, \fB\-\-no\-aur\fR
|
||||||
|
enable or disable checking for AUR updates. Implies \-\-no\-vcs (default: True)
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-\-local\fR, \fB\-\-no\-local\fR
|
||||||
|
enable or disable checking of local packages for updates (default: True)
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-\-manual\fR, \fB\-\-no\-manual\fR
|
||||||
|
include or exclude manual updates (default: True)
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-\-vcs\fR, \fB\-\-no\-vcs\fR
|
||||||
|
enable or disable checking of VCS packages (default: True)
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-y\fR, \fB\-\-refresh\fR
|
||||||
|
download fresh package databases from the mirror before actions, \-yy to force refresh even if up to date
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman help'\/\fR
|
.SH COMMAND \fI\,'ahriman help'\/\fR
|
||||||
usage: ahriman help [-h] [command]
|
usage: ahriman help [\-h] [command]
|
||||||
|
|
||||||
show help message for application or command and exit
|
show help message for application or command and exit
|
||||||
|
|
||||||
@ -172,19 +213,19 @@ show help message for application or command and exit
|
|||||||
\fBcommand\fR
|
\fBcommand\fR
|
||||||
show help message for specific command
|
show help message for specific command
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman help-commands-unsafe'\/\fR
|
.SH COMMAND \fI\,'ahriman help\-commands\-unsafe'\/\fR
|
||||||
usage: ahriman help-commands-unsafe [-h] [--command COMMAND]
|
usage: ahriman help\-commands\-unsafe [\-h] [\-\-command COMMAND]
|
||||||
|
|
||||||
list unsafe commands as defined in default args
|
list unsafe commands as defined in default args
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman help-commands-unsafe'\/\fR
|
.SH OPTIONS \fI\,'ahriman help\-commands\-unsafe'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-command\fR \fI\,COMMAND\/\fR
|
\fB\-\-command\fR \fI\,COMMAND\/\fR
|
||||||
instead of showing commands, just test command line for unsafe subcommand and return 0 in case if command is safe and 1
|
instead of showing commands, just test command line for unsafe subcommand and return 0 in case if command is safe and 1
|
||||||
otherwise
|
otherwise
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman key-import'\/\fR
|
.SH COMMAND \fI\,'ahriman key\-import'\/\fR
|
||||||
usage: ahriman key-import [-h] [--key-server KEY_SERVER] key
|
usage: ahriman key\-import [\-h] [\-\-key\-server KEY_SERVER] key
|
||||||
|
|
||||||
import PGP key from public sources to the repository user
|
import PGP key from public sources to the repository user
|
||||||
|
|
||||||
@ -192,14 +233,14 @@ import PGP key from public sources to the repository user
|
|||||||
\fBkey\fR
|
\fBkey\fR
|
||||||
PGP key to import from public server
|
PGP key to import from public server
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman key-import'\/\fR
|
.SH OPTIONS \fI\,'ahriman key\-import'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-key\-server\fR \fI\,KEY_SERVER\/\fR
|
\fB\-\-key\-server\fR \fI\,KEY_SERVER\/\fR
|
||||||
key server for key import
|
key server for key import
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman package-add'\/\fR
|
.SH COMMAND \fI\,'ahriman package\-add'\/\fR
|
||||||
usage: ahriman package-add [-h] [-e] [-n] [-s {auto,archive,aur,directory,local,remote,repository}]
|
usage: ahriman package\-add [\-h] [\-e] [\-n] [\-y] [\-s {auto,archive,aur,directory,local,remote,repository}]
|
||||||
[--without-dependencies]
|
[\-\-without\-dependencies]
|
||||||
package [package ...]
|
package [package ...]
|
||||||
|
|
||||||
add existing or new package to the build queue
|
add existing or new package to the build queue
|
||||||
@ -208,7 +249,7 @@ add existing or new package to the build queue
|
|||||||
\fBpackage\fR
|
\fBpackage\fR
|
||||||
package source (base name, path to local files, remote URL)
|
package source (base name, path to local files, remote URL)
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman package-add'\/\fR
|
.SH OPTIONS \fI\,'ahriman package\-add'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-e\fR, \fB\-\-exit\-code\fR
|
\fB\-e\fR, \fB\-\-exit\-code\fR
|
||||||
return non\-zero exit status if result is empty
|
return non\-zero exit status if result is empty
|
||||||
@ -217,6 +258,10 @@ return non\-zero exit status if result is empty
|
|||||||
\fB\-n\fR, \fB\-\-now\fR
|
\fB\-n\fR, \fB\-\-now\fR
|
||||||
run update function after
|
run update function after
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-y\fR, \fB\-\-refresh\fR
|
||||||
|
download fresh package databases from the mirror before actions, \-yy to force refresh even if up to date
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-s\fR \fI\,{auto,archive,aur,directory,local,remote,repository}\/\fR, \fB\-\-source\fR \fI\,{auto,archive,aur,directory,local,remote,repository}\/\fR
|
\fB\-s\fR \fI\,{auto,archive,aur,directory,local,remote,repository}\/\fR, \fB\-\-source\fR \fI\,{auto,archive,aur,directory,local,remote,repository}\/\fR
|
||||||
explicitly specify the package source for this command
|
explicitly specify the package source for this command
|
||||||
@ -225,8 +270,8 @@ explicitly specify the package source for this command
|
|||||||
\fB\-\-without\-dependencies\fR
|
\fB\-\-without\-dependencies\fR
|
||||||
do not add dependencies
|
do not add dependencies
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman package-remove'\/\fR
|
.SH COMMAND \fI\,'ahriman package\-remove'\/\fR
|
||||||
usage: ahriman package-remove [-h] package [package ...]
|
usage: ahriman package\-remove [\-h] package [package ...]
|
||||||
|
|
||||||
remove package from the repository
|
remove package from the repository
|
||||||
|
|
||||||
@ -234,8 +279,9 @@ remove package from the repository
|
|||||||
\fBpackage\fR
|
\fBpackage\fR
|
||||||
package name or base
|
package name or base
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman package-status'\/\fR
|
.SH COMMAND \fI\,'ahriman package\-status'\/\fR
|
||||||
usage: ahriman package-status [-h] [--ahriman] [-e] [-i] [-s {unknown,pending,building,failed,success}] [package ...]
|
usage: ahriman package\-status [\-h] [\-\-ahriman] [\-e] [\-\-info | \-\-no\-info] [\-s {unknown,pending,building,failed,success}]
|
||||||
|
[package ...]
|
||||||
|
|
||||||
request status of the package
|
request status of the package
|
||||||
|
|
||||||
@ -243,7 +289,7 @@ request status of the package
|
|||||||
\fBpackage\fR
|
\fBpackage\fR
|
||||||
filter status by package base
|
filter status by package base
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman package-status'\/\fR
|
.SH OPTIONS \fI\,'ahriman package\-status'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-ahriman\fR
|
\fB\-\-ahriman\fR
|
||||||
get service status itself
|
get service status itself
|
||||||
@ -253,24 +299,24 @@ get service status itself
|
|||||||
return non\-zero exit status if result is empty
|
return non\-zero exit status if result is empty
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-i\fR, \fB\-\-info\fR
|
\fB\-\-info\fR, \fB\-\-no\-info\fR
|
||||||
show additional package information
|
show additional package information (default: False)
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-s\fR \fI\,{unknown,pending,building,failed,success}\/\fR, \fB\-\-status\fR \fI\,{unknown,pending,building,failed,success}\/\fR
|
\fB\-s\fR \fI\,{unknown,pending,building,failed,success}\/\fR, \fB\-\-status\fR \fI\,{unknown,pending,building,failed,success}\/\fR
|
||||||
filter packages by status
|
filter packages by status
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman package-status-remove'\/\fR
|
.SH COMMAND \fI\,'ahriman package\-status\-remove'\/\fR
|
||||||
usage: ahriman package-status-remove [-h] package [package ...]
|
usage: ahriman package\-status\-remove [\-h] package [package ...]
|
||||||
|
|
||||||
remove the package from the status page
|
remove the package from the status page
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fBpackage\fR
|
\fBpackage\fR
|
||||||
remove specified packages
|
remove specified packages from status page
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman package-status-update'\/\fR
|
.SH COMMAND \fI\,'ahriman package\-status\-update'\/\fR
|
||||||
usage: ahriman package-status-update [-h] [-s {unknown,pending,building,failed,success}] [package ...]
|
usage: ahriman package\-status\-update [\-h] [\-s {unknown,pending,building,failed,success}] [package ...]
|
||||||
|
|
||||||
update package status on the status page
|
update package status on the status page
|
||||||
|
|
||||||
@ -278,27 +324,30 @@ update package status on the status page
|
|||||||
\fBpackage\fR
|
\fBpackage\fR
|
||||||
set status for specified packages. If no packages supplied, service status will be updated
|
set status for specified packages. If no packages supplied, service status will be updated
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman package-status-update'\/\fR
|
.SH OPTIONS \fI\,'ahriman package\-status\-update'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-s\fR \fI\,{unknown,pending,building,failed,success}\/\fR, \fB\-\-status\fR \fI\,{unknown,pending,building,failed,success}\/\fR
|
\fB\-s\fR \fI\,{unknown,pending,building,failed,success}\/\fR, \fB\-\-status\fR \fI\,{unknown,pending,building,failed,success}\/\fR
|
||||||
new status
|
new package build status
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman patch-add'\/\fR
|
.SH COMMAND \fI\,'ahriman patch\-add'\/\fR
|
||||||
usage: ahriman patch-add [-h] [-t TRACK] package
|
usage: ahriman patch\-add [\-h] package variable [patch]
|
||||||
|
|
||||||
create or update source patches
|
create or update patched PKGBUILD function or variable
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fBpackage\fR
|
\fBpackage\fR
|
||||||
path to directory with changed files for patch addition/update
|
package base
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman patch-add'\/\fR
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-t\fR \fI\,TRACK\/\fR, \fB\-\-track\fR \fI\,TRACK\/\fR
|
\fBvariable\fR
|
||||||
files which has to be tracked
|
PKGBUILD variable or function name. If variable is a function, it must end with ()
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman patch-list'\/\fR
|
.TP
|
||||||
usage: ahriman patch-list [-h] [-e] [package]
|
\fBpatch\fR
|
||||||
|
path to file which contains function or variable value. If not set, the value will be read from stdin
|
||||||
|
|
||||||
|
.SH COMMAND \fI\,'ahriman patch\-list'\/\fR
|
||||||
|
usage: ahriman patch\-list [\-h] [\-e] [\-v VARIABLE] [package]
|
||||||
|
|
||||||
list available patches for the package
|
list available patches for the package
|
||||||
|
|
||||||
@ -306,13 +355,17 @@ list available patches for the package
|
|||||||
\fBpackage\fR
|
\fBpackage\fR
|
||||||
package base
|
package base
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman patch-list'\/\fR
|
.SH OPTIONS \fI\,'ahriman patch\-list'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-e\fR, \fB\-\-exit\-code\fR
|
\fB\-e\fR, \fB\-\-exit\-code\fR
|
||||||
return non\-zero exit status if result is empty
|
return non\-zero exit status if result is empty
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman patch-remove'\/\fR
|
.TP
|
||||||
usage: ahriman patch-remove [-h] package
|
\fB\-v\fR \fI\,VARIABLE\/\fR, \fB\-\-variable\fR \fI\,VARIABLE\/\fR
|
||||||
|
if set, show only patches for specified PKGBUILD variables
|
||||||
|
|
||||||
|
.SH COMMAND \fI\,'ahriman patch\-remove'\/\fR
|
||||||
|
usage: ahriman patch\-remove [\-h] [\-v VARIABLE] package
|
||||||
|
|
||||||
remove patches for the package
|
remove patches for the package
|
||||||
|
|
||||||
@ -320,69 +373,98 @@ remove patches for the package
|
|||||||
\fBpackage\fR
|
\fBpackage\fR
|
||||||
package base
|
package base
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-backup'\/\fR
|
.SH OPTIONS \fI\,'ahriman patch\-remove'\/\fR
|
||||||
usage: ahriman repo-backup [-h] path
|
.TP
|
||||||
|
\fB\-v\fR \fI\,VARIABLE\/\fR, \fB\-\-variable\fR \fI\,VARIABLE\/\fR
|
||||||
|
should be used for single\-function patches in case if you wold like to remove only specified PKGBUILD variables. In case
|
||||||
|
if not set, it will remove all patches related to the package
|
||||||
|
|
||||||
backup settings and database
|
.SH COMMAND \fI\,'ahriman patch\-set\-add'\/\fR
|
||||||
|
usage: ahriman patch\-set\-add [\-h] [\-t TRACK] package
|
||||||
|
|
||||||
|
create or update source patches
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fBpackage\fR
|
||||||
|
path to directory with changed files for patch addition/update
|
||||||
|
|
||||||
|
.SH OPTIONS \fI\,'ahriman patch\-set\-add'\/\fR
|
||||||
|
.TP
|
||||||
|
\fB\-t\fR \fI\,TRACK\/\fR, \fB\-\-track\fR \fI\,TRACK\/\fR
|
||||||
|
files which has to be tracked
|
||||||
|
|
||||||
|
.SH COMMAND \fI\,'ahriman repo\-backup'\/\fR
|
||||||
|
usage: ahriman repo\-backup [\-h] path
|
||||||
|
|
||||||
|
backup repository settings and database
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fBpath\fR
|
\fBpath\fR
|
||||||
path of the output archive
|
path of the output archive
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-check'\/\fR
|
.SH COMMAND \fI\,'ahriman repo\-check'\/\fR
|
||||||
usage: ahriman repo-check [-h] [-e] [--no-vcs] [package ...]
|
usage: ahriman repo\-check [\-h] [\-e] [\-\-vcs | \-\-no\-vcs] [\-y] [package ...]
|
||||||
|
|
||||||
check for packages updates. Same as update \-\-dry\-run \-\-no\-manual
|
check for packages updates. Same as repo\-update \-\-dry\-run \-\-no\-manual
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fBpackage\fR
|
\fBpackage\fR
|
||||||
filter check by package base
|
filter check by package base
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman repo-check'\/\fR
|
.SH OPTIONS \fI\,'ahriman repo\-check'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-e\fR, \fB\-\-exit\-code\fR
|
\fB\-e\fR, \fB\-\-exit\-code\fR
|
||||||
return non\-zero exit status if result is empty
|
return non\-zero exit status if result is empty
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-no\-vcs\fR
|
\fB\-\-vcs\fR, \fB\-\-no\-vcs\fR
|
||||||
do not check VCS packages
|
enable or disable checking of VCS packages (default: True)
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-clean'\/\fR
|
.TP
|
||||||
usage: ahriman repo-clean [-h] [--cache] [--chroot] [--manual] [--packages]
|
\fB\-y\fR, \fB\-\-refresh\fR
|
||||||
|
download fresh package databases from the mirror before actions, \-yy to force refresh even if up to date
|
||||||
|
|
||||||
|
.SH COMMAND \fI\,'ahriman repo\-clean'\/\fR
|
||||||
|
usage: ahriman repo\-clean [\-h] [\-\-cache | \-\-no\-cache] [\-\-chroot | \-\-no\-chroot] [\-\-manual | \-\-no\-manual]
|
||||||
|
[\-\-packages | \-\-no\-packages] [\-\-pacman | \-\-no\-pacman]
|
||||||
|
|
||||||
remove local caches
|
remove local caches
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman repo-clean'\/\fR
|
.SH OPTIONS \fI\,'ahriman repo\-clean'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-cache\fR
|
\fB\-\-cache\fR, \fB\-\-no\-cache\fR
|
||||||
clear directory with package caches
|
clear directory with package caches (default: False)
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-chroot\fR
|
\fB\-\-chroot\fR, \fB\-\-no\-chroot\fR
|
||||||
clear build chroot
|
clear build chroot (default: False)
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-manual\fR
|
\fB\-\-manual\fR, \fB\-\-no\-manual\fR
|
||||||
clear manually added packages queue
|
clear manually added packages queue (default: False)
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-packages\fR
|
\fB\-\-packages\fR, \fB\-\-no\-packages\fR
|
||||||
clear directory with built packages
|
clear directory with built packages (default: False)
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-config'\/\fR
|
.TP
|
||||||
usage: ahriman repo-config [-h]
|
\fB\-\-pacman\fR, \fB\-\-no\-pacman\fR
|
||||||
|
clear directory with pacman local database cache (default: False)
|
||||||
|
|
||||||
|
.SH COMMAND \fI\,'ahriman repo\-config'\/\fR
|
||||||
|
usage: ahriman repo\-config [\-h]
|
||||||
|
|
||||||
dump configuration for the specified architecture
|
dump configuration for the specified architecture
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-rebuild'\/\fR
|
.SH COMMAND \fI\,'ahriman repo\-rebuild'\/\fR
|
||||||
usage: ahriman repo-rebuild [-h] [--depends-on DEPENDS_ON] [--dry-run] [--from-database] [-e]
|
usage: ahriman repo\-rebuild [\-h] [\-\-depends\-on DEPENDS_ON] [\-\-dry\-run] [\-\-from\-database] [\-e]
|
||||||
|
|
||||||
force rebuild whole repository
|
force rebuild whole repository
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman repo-rebuild'\/\fR
|
.SH OPTIONS \fI\,'ahriman repo\-rebuild'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-depends\-on\fR \fI\,DEPENDS_ON\/\fR
|
\fB\-\-depends\-on\fR \fI\,DEPENDS_ON\/\fR
|
||||||
only rebuild packages that depend on specified package
|
only rebuild packages that depend on specified packages
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-dry\-run\fR
|
\fB\-\-dry\-run\fR
|
||||||
@ -391,34 +473,30 @@ just perform check for packages without rebuild process itself
|
|||||||
.TP
|
.TP
|
||||||
\fB\-\-from\-database\fR
|
\fB\-\-from\-database\fR
|
||||||
read packages from database instead of filesystem. This feature in particular is required in case if you would like to
|
read packages from database instead of filesystem. This feature in particular is required in case if you would like to
|
||||||
restore repository from another repository instance. Note however that in order to restore packages you need to have
|
restore repository from another repository instance. Note, however, that in order to restore packages you need to have
|
||||||
original ahriman instance run with web service and have run repo\-update at least once.
|
original ahriman instance run with web service and have run repo\-update at least once.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-e\fR, \fB\-\-exit\-code\fR
|
\fB\-e\fR, \fB\-\-exit\-code\fR
|
||||||
return non\-zero exit status if result is empty
|
return non\-zero exit status if result is empty
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-remove-unknown'\/\fR
|
.SH COMMAND \fI\,'ahriman repo\-remove\-unknown'\/\fR
|
||||||
usage: ahriman repo-remove-unknown [-h] [--dry-run] [-i]
|
usage: ahriman repo\-remove\-unknown [\-h] [\-\-dry\-run]
|
||||||
|
|
||||||
remove packages which are missing in AUR and do not have local PKGBUILDs
|
remove packages which are missing in AUR and do not have local PKGBUILDs
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman repo-remove-unknown'\/\fR
|
.SH OPTIONS \fI\,'ahriman repo\-remove\-unknown'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-dry\-run\fR
|
\fB\-\-dry\-run\fR
|
||||||
just perform check for packages without removal
|
just perform check for packages without removal
|
||||||
|
|
||||||
.TP
|
.SH COMMAND \fI\,'ahriman repo\-report'\/\fR
|
||||||
\fB\-i\fR, \fB\-\-info\fR
|
usage: ahriman repo\-report [\-h]
|
||||||
show additional package information
|
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-report'\/\fR
|
|
||||||
usage: ahriman repo-report [-h]
|
|
||||||
|
|
||||||
generate repository report according to current settings
|
generate repository report according to current settings
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-restore'\/\fR
|
.SH COMMAND \fI\,'ahriman repo\-restore'\/\fR
|
||||||
usage: ahriman repo-restore [-h] [-o OUTPUT] path
|
usage: ahriman repo\-restore [\-h] [\-o OUTPUT] path
|
||||||
|
|
||||||
restore settings and database
|
restore settings and database
|
||||||
|
|
||||||
@ -426,20 +504,21 @@ restore settings and database
|
|||||||
\fBpath\fR
|
\fBpath\fR
|
||||||
path of the input archive
|
path of the input archive
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman repo-restore'\/\fR
|
.SH OPTIONS \fI\,'ahriman repo\-restore'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-o\fR \fI\,OUTPUT\/\fR, \fB\-\-output\fR \fI\,OUTPUT\/\fR
|
\fB\-o\fR \fI\,OUTPUT\/\fR, \fB\-\-output\fR \fI\,OUTPUT\/\fR
|
||||||
root path of the extracted files
|
root path of the extracted files
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-setup'\/\fR
|
.SH COMMAND \fI\,'ahriman repo\-setup'\/\fR
|
||||||
usage: ahriman repo-setup [-h] [--build-as-user BUILD_AS_USER] [--build-command BUILD_COMMAND]
|
usage: ahriman repo\-setup [\-h] [\-\-build\-as\-user BUILD_AS_USER] [\-\-build\-command BUILD_COMMAND]
|
||||||
[--from-configuration FROM_CONFIGURATION] [--no-multilib] --packager PACKAGER --repository
|
[\-\-from\-configuration FROM_CONFIGURATION] [\-\-makeflags\-jobs | \-\-no\-makeflags\-jobs]
|
||||||
REPOSITORY [--sign-key SIGN_KEY] [--sign-target {disabled,pacakges,repository}]
|
[\-\-multilib | \-\-no\-multilib] \-\-packager PACKAGER \-\-repository REPOSITORY [\-\-sign\-key SIGN_KEY]
|
||||||
[--web-port WEB_PORT]
|
[\-\-sign\-target {disabled,packages,repository}] [\-\-web\-port WEB_PORT]
|
||||||
|
[\-\-web\-unix\-socket WEB_UNIX_SOCKET]
|
||||||
|
|
||||||
create initial service configuration, requires root
|
create initial service configuration, requires root
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman repo-setup'\/\fR
|
.SH OPTIONS \fI\,'ahriman repo\-setup'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-build\-as\-user\fR \fI\,BUILD_AS_USER\/\fR
|
\fB\-\-build\-as\-user\fR \fI\,BUILD_AS_USER\/\fR
|
||||||
force makepkg user to the specific one
|
force makepkg user to the specific one
|
||||||
@ -453,8 +532,12 @@ build command prefix
|
|||||||
path to default devtools pacman configuration
|
path to default devtools pacman configuration
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-no\-multilib\fR
|
\fB\-\-makeflags\-jobs\fR, \fB\-\-no\-makeflags\-jobs\fR
|
||||||
do not add multilib repository
|
append MAKEFLAGS variable with parallelism set to number of cores (default: True)
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-\-multilib\fR, \fB\-\-no\-multilib\fR
|
||||||
|
add or do not multilib repository (default: True)
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-packager\fR \fI\,PACKAGER\/\fR
|
\fB\-\-packager\fR \fI\,PACKAGER\/\fR
|
||||||
@ -469,15 +552,19 @@ repository name
|
|||||||
sign key id
|
sign key id
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-sign\-target\fR \fI\,{disabled,pacakges,repository}\/\fR
|
\fB\-\-sign\-target\fR \fI\,{disabled,packages,repository}\/\fR
|
||||||
sign options
|
sign options
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-web\-port\fR \fI\,WEB_PORT\/\fR
|
\fB\-\-web\-port\fR \fI\,WEB_PORT\/\fR
|
||||||
port of the web service
|
port of the web service
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-sign'\/\fR
|
.TP
|
||||||
usage: ahriman repo-sign [-h] [package ...]
|
\fB\-\-web\-unix\-socket\fR \fI\,WEB_UNIX_SOCKET\/\fR
|
||||||
|
path to unix socket used for interprocess communications
|
||||||
|
|
||||||
|
.SH COMMAND \fI\,'ahriman repo\-sign'\/\fR
|
||||||
|
usage: ahriman repo\-sign [\-h] [package ...]
|
||||||
|
|
||||||
(re\-)sign packages and repository database according to current settings
|
(re\-)sign packages and repository database according to current settings
|
||||||
|
|
||||||
@ -485,32 +572,39 @@ usage: ahriman repo-sign [-h] [package ...]
|
|||||||
\fBpackage\fR
|
\fBpackage\fR
|
||||||
sign only specified packages
|
sign only specified packages
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-status-update'\/\fR
|
.SH COMMAND \fI\,'ahriman repo\-status\-update'\/\fR
|
||||||
usage: ahriman repo-status-update [-h] [-s {unknown,pending,building,failed,success}]
|
usage: ahriman repo\-status\-update [\-h] [\-s {unknown,pending,building,failed,success}]
|
||||||
|
|
||||||
update repository status on the status page
|
update repository status on the status page
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman repo-status-update'\/\fR
|
.SH OPTIONS \fI\,'ahriman repo\-status\-update'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-s\fR \fI\,{unknown,pending,building,failed,success}\/\fR, \fB\-\-status\fR \fI\,{unknown,pending,building,failed,success}\/\fR
|
\fB\-s\fR \fI\,{unknown,pending,building,failed,success}\/\fR, \fB\-\-status\fR \fI\,{unknown,pending,building,failed,success}\/\fR
|
||||||
new status
|
new status
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-sync'\/\fR
|
.SH COMMAND \fI\,'ahriman repo\-sync'\/\fR
|
||||||
usage: ahriman repo-sync [-h]
|
usage: ahriman repo\-sync [\-h]
|
||||||
|
|
||||||
sync repository files to remote server according to current settings
|
sync repository files to remote server according to current settings
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-triggers'\/\fR
|
.SH COMMAND \fI\,'ahriman repo\-tree'\/\fR
|
||||||
usage: ahriman repo-triggers [-h] [trigger ...]
|
usage: ahriman repo\-tree [\-h]
|
||||||
|
|
||||||
|
dump repository tree based on packages dependencies
|
||||||
|
|
||||||
|
.SH COMMAND \fI\,'ahriman repo\-triggers'\/\fR
|
||||||
|
usage: ahriman repo\-triggers [\-h] [trigger ...]
|
||||||
|
|
||||||
run triggers on empty build result as configured by settings
|
run triggers on empty build result as configured by settings
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fBtrigger\fR
|
\fBtrigger\fR
|
||||||
instead of running all triggers as set by configuration, just process specified ones oin order of metion
|
instead of running all triggers as set by configuration, just process specified ones in order of mention
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman repo-update'\/\fR
|
.SH COMMAND \fI\,'ahriman repo\-update'\/\fR
|
||||||
usage: ahriman repo-update [-h] [--dry-run] [-e] [--no-aur] [--no-local] [--no-manual] [--no-vcs] [package ...]
|
usage: ahriman repo\-update [\-h] [\-\-dry\-run] [\-e] [\-\-aur | \-\-no\-aur] [\-\-local | \-\-no\-local] [\-\-manual | \-\-no\-manual]
|
||||||
|
[\-\-vcs | \-\-no\-vcs] [\-y]
|
||||||
|
[package ...]
|
||||||
|
|
||||||
check for packages updates and run build process if requested
|
check for packages updates and run build process if requested
|
||||||
|
|
||||||
@ -518,7 +612,7 @@ check for packages updates and run build process if requested
|
|||||||
\fBpackage\fR
|
\fBpackage\fR
|
||||||
filter check by package base
|
filter check by package base
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman repo-update'\/\fR
|
.SH OPTIONS \fI\,'ahriman repo\-update'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-dry\-run\fR
|
\fB\-\-dry\-run\fR
|
||||||
just perform check for updates, same as check command
|
just perform check for updates, same as check command
|
||||||
@ -528,28 +622,36 @@ just perform check for updates, same as check command
|
|||||||
return non\-zero exit status if result is empty
|
return non\-zero exit status if result is empty
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-no\-aur\fR
|
\fB\-\-aur\fR, \fB\-\-no\-aur\fR
|
||||||
do not check for AUR updates. Implies \-\-no\-vcs
|
enable or disable checking for AUR updates. Implies \-\-no\-vcs (default: True)
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-no\-local\fR
|
\fB\-\-local\fR, \fB\-\-no\-local\fR
|
||||||
do not check local packages for updates
|
enable or disable checking of local packages for updates (default: True)
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-no\-manual\fR
|
\fB\-\-manual\fR, \fB\-\-no\-manual\fR
|
||||||
do not include manual updates
|
include or exclude manual updates (default: True)
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-no\-vcs\fR
|
\fB\-\-vcs\fR, \fB\-\-no\-vcs\fR
|
||||||
do not check VCS packages
|
enable or disable checking of VCS packages (default: True)
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-y\fR, \fB\-\-refresh\fR
|
||||||
|
download fresh package databases from the mirror before actions, \-yy to force refresh even if up to date
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman shell'\/\fR
|
.SH COMMAND \fI\,'ahriman shell'\/\fR
|
||||||
usage: ahriman shell [-h]
|
usage: ahriman shell [\-h] [code]
|
||||||
|
|
||||||
drop into python shell while having created application
|
drop into python shell while having created application
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman user-add'\/\fR
|
.TP
|
||||||
usage: ahriman user-add [-h] [--as-service] [-p PASSWORD] [-r {unauthorized,read,reporter,full}] [-s] username
|
\fBcode\fR
|
||||||
|
instead of dropping into shell, just execute the specified code
|
||||||
|
|
||||||
|
.SH COMMAND \fI\,'ahriman user\-add'\/\fR
|
||||||
|
usage: ahriman user\-add [\-h] [\-p PASSWORD] [\-r {unauthorized,read,reporter,full}] [\-s] username
|
||||||
|
|
||||||
update user for web services with the given password and role. In case if password was not entered it will be asked interactively
|
update user for web services with the given password and role. In case if password was not entered it will be asked interactively
|
||||||
|
|
||||||
@ -557,11 +659,7 @@ update user for web services with the given password and role. In case if passwo
|
|||||||
\fBusername\fR
|
\fBusername\fR
|
||||||
username for web service
|
username for web service
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman user-add'\/\fR
|
.SH OPTIONS \fI\,'ahriman user\-add'\/\fR
|
||||||
.TP
|
|
||||||
\fB\-\-as\-service\fR
|
|
||||||
add user as service user
|
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-p\fR \fI\,PASSWORD\/\fR, \fB\-\-password\fR \fI\,PASSWORD\/\fR
|
\fB\-p\fR \fI\,PASSWORD\/\fR, \fB\-\-password\fR \fI\,PASSWORD\/\fR
|
||||||
user password. Blank password will be treated as empty password, which is in particular must be used for OAuth2
|
user password. Blank password will be treated as empty password, which is in particular must be used for OAuth2
|
||||||
@ -575,8 +673,8 @@ user access level
|
|||||||
\fB\-s\fR, \fB\-\-secure\fR
|
\fB\-s\fR, \fB\-\-secure\fR
|
||||||
set file permissions to user\-only
|
set file permissions to user\-only
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman user-list'\/\fR
|
.SH COMMAND \fI\,'ahriman user\-list'\/\fR
|
||||||
usage: ahriman user-list [-h] [-e] [-r {unauthorized,read,reporter,full}] [username]
|
usage: ahriman user\-list [\-h] [\-e] [\-r {unauthorized,read,reporter,full}] [username]
|
||||||
|
|
||||||
list users from the user mapping and their roles
|
list users from the user mapping and their roles
|
||||||
|
|
||||||
@ -584,7 +682,7 @@ list users from the user mapping and their roles
|
|||||||
\fBusername\fR
|
\fBusername\fR
|
||||||
filter users by username
|
filter users by username
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman user-list'\/\fR
|
.SH OPTIONS \fI\,'ahriman user\-list'\/\fR
|
||||||
.TP
|
.TP
|
||||||
\fB\-e\fR, \fB\-\-exit\-code\fR
|
\fB\-e\fR, \fB\-\-exit\-code\fR
|
||||||
return non\-zero exit status if result is empty
|
return non\-zero exit status if result is empty
|
||||||
@ -593,8 +691,8 @@ return non\-zero exit status if result is empty
|
|||||||
\fB\-r\fR \fI\,{unauthorized,read,reporter,full}\/\fR, \fB\-\-role\fR \fI\,{unauthorized,read,reporter,full}\/\fR
|
\fB\-r\fR \fI\,{unauthorized,read,reporter,full}\/\fR, \fB\-\-role\fR \fI\,{unauthorized,read,reporter,full}\/\fR
|
||||||
filter users by role
|
filter users by role
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman user-remove'\/\fR
|
.SH COMMAND \fI\,'ahriman user\-remove'\/\fR
|
||||||
usage: ahriman user-remove [-h] [-s] username
|
usage: ahriman user\-remove [\-h] username
|
||||||
|
|
||||||
remove user from the user mapping and update the configuration
|
remove user from the user mapping and update the configuration
|
||||||
|
|
||||||
@ -602,18 +700,13 @@ remove user from the user mapping and update the configuration
|
|||||||
\fBusername\fR
|
\fBusername\fR
|
||||||
username for web service
|
username for web service
|
||||||
|
|
||||||
.SH OPTIONS \fI\,'ahriman user-remove'\/\fR
|
|
||||||
.TP
|
|
||||||
\fB\-s\fR, \fB\-\-secure\fR
|
|
||||||
set file permissions to user\-only
|
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman version'\/\fR
|
.SH COMMAND \fI\,'ahriman version'\/\fR
|
||||||
usage: ahriman version [-h]
|
usage: ahriman version [\-h]
|
||||||
|
|
||||||
print application and its dependencies versions
|
print application and its dependencies versions
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman web'\/\fR
|
.SH COMMAND \fI\,'ahriman web'\/\fR
|
||||||
usage: ahriman web [-h]
|
usage: ahriman web [\-h]
|
||||||
|
|
||||||
start web server
|
start web server
|
||||||
|
|
||||||
@ -623,7 +716,8 @@ Argument list can also be read from file by using @ prefix.
|
|||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
.nf
|
.nf
|
||||||
ahriman team
|
ahriman team
|
||||||
.fi.nf
|
.fi
|
||||||
|
.nf
|
||||||
|
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
|
@ -28,6 +28,14 @@ ahriman.application.handlers.clean module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.application.handlers.daemon module
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.application.handlers.daemon
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.application.handlers.dump module
|
ahriman.application.handlers.dump module
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
@ -148,6 +156,14 @@ ahriman.application.handlers.status\_update module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.application.handlers.structure module
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.application.handlers.structure
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.application.handlers.triggers module
|
ahriman.application.handlers.triggers module
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
|
@ -28,6 +28,22 @@ ahriman.core.database.migrations.m002\_user\_access module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.database.migrations.m003\_patch\_variables module
|
||||||
|
--------------------------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.database.migrations.m003_patch_variables
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.database.migrations.m004\_logs module
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.database.migrations.m004_logs
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
Module contents
|
Module contents
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
@ -20,6 +20,14 @@ ahriman.core.database.operations.build\_operations module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.database.operations.logs\_operations module
|
||||||
|
--------------------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.database.operations.logs_operations
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.core.database.operations.operations module
|
ahriman.core.database.operations.operations module
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|
||||||
|
@ -36,6 +36,14 @@ ahriman.core.formatters.package\_printer module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.formatters.patch\_printer module
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.formatters.patch_printer
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.core.formatters.printer module
|
ahriman.core.formatters.printer module
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
@ -60,6 +68,14 @@ ahriman.core.formatters.string\_printer module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.formatters.tree\_printer module
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.formatters.tree_printer
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.core.formatters.update\_printer module
|
ahriman.core.formatters.update\_printer module
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
|
||||||
|
45
docs/ahriman.core.gitremote.rst
Normal file
45
docs/ahriman.core.gitremote.rst
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
ahriman.core.gitremote package
|
||||||
|
==============================
|
||||||
|
|
||||||
|
Submodules
|
||||||
|
----------
|
||||||
|
|
||||||
|
ahriman.core.gitremote.remote\_pull module
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.gitremote.remote_pull
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.gitremote.remote\_pull\_trigger module
|
||||||
|
---------------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.gitremote.remote_pull_trigger
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.gitremote.remote\_push module
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.gitremote.remote_push
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.gitremote.remote\_push\_trigger module
|
||||||
|
---------------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.gitremote.remote_push_trigger
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
Module contents
|
||||||
|
---------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.gitremote
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
45
docs/ahriman.core.log.rst
Normal file
45
docs/ahriman.core.log.rst
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
ahriman.core.log package
|
||||||
|
========================
|
||||||
|
|
||||||
|
Submodules
|
||||||
|
----------
|
||||||
|
|
||||||
|
ahriman.core.log.filtered\_access\_logger module
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.log.filtered_access_logger
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.log.http\_log\_handler module
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.log.http_log_handler
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.log.lazy\_logging module
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.log.lazy_logging
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.log.log module
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.log.log
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
Module contents
|
||||||
|
---------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.log
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
@ -12,6 +12,8 @@ Subpackages
|
|||||||
ahriman.core.build_tools
|
ahriman.core.build_tools
|
||||||
ahriman.core.database
|
ahriman.core.database
|
||||||
ahriman.core.formatters
|
ahriman.core.formatters
|
||||||
|
ahriman.core.gitremote
|
||||||
|
ahriman.core.log
|
||||||
ahriman.core.report
|
ahriman.core.report
|
||||||
ahriman.core.repository
|
ahriman.core.repository
|
||||||
ahriman.core.sign
|
ahriman.core.sign
|
||||||
@ -38,14 +40,6 @@ ahriman.core.exceptions module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.core.lazy\_logging module
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.core.lazy_logging
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
ahriman.core.spawn module
|
ahriman.core.spawn module
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
@ -36,6 +36,14 @@ ahriman.models.build\_status module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.models.context\_key module
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.models.context_key
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.models.counters module
|
ahriman.models.counters module
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
@ -52,6 +60,14 @@ ahriman.models.internal\_status module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.models.log\_record\_id module
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.models.log_record_id
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.models.migration module
|
ahriman.models.migration module
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
@ -12,6 +12,22 @@ ahriman.web.views.service.add module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.web.views.service.pgp module
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.service.pgp
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.web.views.service.rebuild module
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.service.rebuild
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.web.views.service.remove module
|
ahriman.web.views.service.remove module
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
@ -36,6 +52,14 @@ ahriman.web.views.service.search module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.web.views.service.update module
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.service.update
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
Module contents
|
Module contents
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
@ -4,6 +4,14 @@ ahriman.web.views.status package
|
|||||||
Submodules
|
Submodules
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
ahriman.web.views.status.logs module
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.status.logs
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.web.views.status.package module
|
ahriman.web.views.status.package module
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
@ -28,19 +28,21 @@ This package contains application (aka executable) related classes and everythin
|
|||||||
``ahriman.core`` package
|
``ahriman.core`` package
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
This package contains everything which is required for any time of application run and separated into several packages:
|
This package contains everything required for the most of application actions and it is separated into several packages:
|
||||||
|
|
||||||
* ``ahriman.core.alpm`` package controls pacman related functions. It provides wrappers for ``pyalpm`` library and safe calls for repository tools (``repo-add`` and ``repo-remove``). Also this package contains ``ahriman.core.alpm.remote`` package which provides wrapper for remote sources (e.g. AUR RPC and official repositories RPC).
|
* ``ahriman.core.alpm`` package controls pacman related functions. It provides wrappers for ``pyalpm`` library and safe calls for repository tools (``repo-add`` and ``repo-remove``). Also this package contains ``ahriman.core.alpm.remote`` package which provides wrapper for remote sources (e.g. AUR RPC and official repositories RPC).
|
||||||
* ``ahriman.core.auth`` package provides classes for authorization methods used by web mostly. Base class is ``ahriman.core.auth.Auth`` which must be called by ``load`` method.
|
* ``ahriman.core.auth`` package provides classes for authorization methods used by web mostly. Base class is ``ahriman.core.auth.Auth`` which must be called by ``load`` method.
|
||||||
* ``ahriman.core.build_tools`` is a package which provides wrapper for ``devtools`` commands.
|
* ``ahriman.core.build_tools`` is a package which provides wrapper for ``devtools`` commands.
|
||||||
* ``ahriman.core.database`` is everything including data and schema migrations for database.
|
* ``ahriman.core.database`` is everything including data and schema migrations for database.
|
||||||
* ``ahriman.core.formatters`` package provides ``Printer`` sub-classes for printing data (e.g. package properties) to stdout which are used by some handlers.
|
* ``ahriman.core.formatters`` package provides ``Printer`` sub-classes for printing data (e.g. package properties) to stdout which are used by some handlers.
|
||||||
* ``ahriman.core.report`` is a package with reporting classes. Usually it must be called by ``ahriman.core.report.Report.load`` method.
|
* ``ahriman.core.gitremote`` is a package with remote PKGBUILD triggers. Should not be called directly.
|
||||||
|
* ``ahriman.core.log`` is a log utils package. It includes logger loader class, custom HTTP based logger and access logger for HTTP services with additional filters.
|
||||||
|
* ``ahriman.core.report`` is a package with reporting triggers. Should not be called directly.
|
||||||
* ``ahriman.core.repository`` contains several traits and base repository (``ahriman.core.repository.Repository`` class) implementation.
|
* ``ahriman.core.repository`` contains several traits and base repository (``ahriman.core.repository.Repository`` class) implementation.
|
||||||
* ``ahriman.core.sign`` package provides sign feature (only gpg calls are available).
|
* ``ahriman.core.sign`` package provides sign feature (only gpg calls are available).
|
||||||
* ``ahriman.core.status`` contains helpers and watcher class which are required for web application. Reporter must be initialized by using ``ahriman.core.status.client.Client.load`` method.
|
* ``ahriman.core.status`` contains helpers and watcher class which are required for web application. Reporter must be initialized by using ``ahriman.core.status.client.Client.load`` method.
|
||||||
* ``ahriman.core.triggers`` package contains base trigger classes. Classes from this package must be imported in order to implement user extensions. In fact, ``ahriman.core.report`` and ``ahriman.core.upload`` use this package.
|
* ``ahriman.core.triggers`` package contains base trigger classes. Classes from this package must be imported in order to implement user extensions. In fact, ``ahriman.core.report`` and ``ahriman.core.upload`` use this package.
|
||||||
* ``ahriman.core.upload`` package provides sync feature, must be called by ``ahriman.core.upload.Upload.load`` method.
|
* ``ahriman.core.upload`` package provides sync feature, should not be called directly.
|
||||||
|
|
||||||
This package also provides some generic functions and classes which may be used by other packages:
|
This package also provides some generic functions and classes which may be used by other packages:
|
||||||
|
|
||||||
@ -52,7 +54,7 @@ This package also provides some generic functions and classes which may be used
|
|||||||
``ahriman.models`` package
|
``ahriman.models`` package
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
It provides models for any other part of application. Unlike ``ahriman.core`` package classes from here provides only conversion methods (e.g. create class from another or convert to). Mostly case classes and enumerations.
|
It provides models for any other part of application. Unlike ``ahriman.core`` package classes from here provide only conversion methods (e.g. create class from another or convert to). Mostly case classes and enumerations.
|
||||||
|
|
||||||
``ahriman.web`` package
|
``ahriman.web`` package
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -75,7 +77,7 @@ Application run
|
|||||||
* Return result (success or failure) of each subprocess and exit from application.
|
* Return result (success or failure) of each subprocess and exit from application.
|
||||||
* Some handlers may override their status and throw ``ExitCode`` exception. This exception is just silently suppressed and changes application exit code to ``1``.
|
* Some handlers may override their status and throw ``ExitCode`` exception. This exception is just silently suppressed and changes application exit code to ``1``.
|
||||||
|
|
||||||
In most cases handlers spawn god class ``ahriman.application.application.Application`` class and call required methods.
|
In the most cases handlers spawn god class ``ahriman.application.application.Application`` class and call required methods.
|
||||||
|
|
||||||
Application is designed to run from ``systemd`` services and provides parametrized by architecture timer and service file for that.
|
Application is designed to run from ``systemd`` services and provides parametrized by architecture timer and service file for that.
|
||||||
|
|
||||||
@ -103,7 +105,7 @@ Type conversions
|
|||||||
|
|
||||||
By default, it parses rows into python dictionary. In addition, the following pseudo-types are supported:
|
By default, it parses rows into python dictionary. In addition, the following pseudo-types are supported:
|
||||||
|
|
||||||
* ``Dict[str, Any]``, ``List[Any]`` - for storing JSON data structures in database (technically there is no restriction on types for dictionary keys and values, but it is recommended to use only string keys). The type is stored as ``json`` datatype and ``json.loads`` and ``json.dumps`` methods are used in order to read and write from/to database respectively.
|
* ``Dict[str, Any]``, ``List[Any]`` - for storing JSON data structures in database (technically there is no restriction on types for dictionary keys and values, but it is recommended to use only string keys). The type is stored as ``json`` data type and ``json.loads`` and ``json.dumps`` methods are used in order to read and write from/to database respectively.
|
||||||
|
|
||||||
Basic flows
|
Basic flows
|
||||||
-----------
|
-----------
|
||||||
@ -167,6 +169,15 @@ Utils
|
|||||||
|
|
||||||
For every external command run (which is actually not recommended if possible) custom wrapper for ``subprocess`` is used. Additional functions ``ahriman.core.auth.helpers`` provide safe calls for ``aiohttp_security`` methods and are required to make this dependency optional.
|
For every external command run (which is actually not recommended if possible) custom wrapper for ``subprocess`` is used. Additional functions ``ahriman.core.auth.helpers`` provide safe calls for ``aiohttp_security`` methods and are required to make this dependency optional.
|
||||||
|
|
||||||
|
Context variables
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Package provides implicit global variables which can be accessed from ``ahriman.core`` package as ``context`` variable, wrapped by ``contextvars.ContextVar`` class. The value of the variable is defaulting to private ``_Context`` class which is defined in the same module. The default values - such as ``database`` and ``sign`` - are being set on the service initialization.
|
||||||
|
|
||||||
|
The ``_Context`` class itself mimics default collection interface (as is Mapping) and can be modified by ``_Context.set`` method. The stored variables can be achieved by ``_Context.get`` method, which is unlike default ``Mapping`` interface also performs type and presence checks.
|
||||||
|
|
||||||
|
In order to provide statically typed interface, the ``ahriman.models.context_key.ContextKey`` class is used for both ``_Content.get`` and ``_Content.set`` methods; the context instance itself, however, does not store information about types.
|
||||||
|
|
||||||
Submodules
|
Submodules
|
||||||
^^^^^^^^^^
|
^^^^^^^^^^
|
||||||
|
|
||||||
@ -195,19 +206,23 @@ means that there is user ``username`` with ``read`` access and password ``passwo
|
|||||||
|
|
||||||
OAuth provider uses library definitions (``aioauth-client``) in order *authenticate* users. It still requires user permission to be set in database, thus it inherits mapping provider without any changes. Whereas we could override ``check_credentials`` (authentication method) by something custom, OAuth flow is a bit more complex than just forward request, thus we have to implement the flow in login form.
|
OAuth provider uses library definitions (``aioauth-client``) in order *authenticate* users. It still requires user permission to be set in database, thus it inherits mapping provider without any changes. Whereas we could override ``check_credentials`` (authentication method) by something custom, OAuth flow is a bit more complex than just forward request, thus we have to implement the flow in login form.
|
||||||
|
|
||||||
OAuth's implementation also allows authenticating users via username + password (in the same way as mapping does) though it is not recommended for end-users and password must be left blank. In particular this feature is used by service reporting (aka robots).
|
OAuth's implementation also allows authenticating users via username + password (in the same way as mapping does) though it is not recommended for end-users and password must be left blank. In particular this feature can be used by service reporting (aka robots).
|
||||||
|
|
||||||
|
In addition, web service checks the source socket used. In case if it belongs to ``socket.AF_UNIX`` family, it will skip any furher checks considering the request to be performed in safe environment (e.g. on the same physical machine). This feature, in particular is being used by the reporter instances in case if socket address is set in configuration.
|
||||||
|
|
||||||
In order to configure users there are special commands.
|
In order to configure users there are special commands.
|
||||||
|
|
||||||
Triggers
|
Triggers
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
Triggers are extensions which can be used in order to perform any actions after the update process. The package provides two default extensions - one is report generation and another one is remote upload feature.
|
Triggers are extensions which can be used in order to perform any actions on application start, after the update process and, finally, before the application exit.
|
||||||
|
|
||||||
The main idea is to load classes by their full path (e.g. ``ahriman.core.upload.UploadTrigger``) by using ``importlib``: get the last part of the import and treat it as class name, join remain part by ``.`` and interpret as module path, import module and extract attribute from it.
|
The main idea is to load classes by their full path (e.g. ``ahriman.core.upload.UploadTrigger``) by using ``importlib``: get the last part of the import and treat it as class name, join remain part by ``.`` and interpret as module path, import module and extract attribute from it.
|
||||||
|
|
||||||
The loaded triggers will be called with ``ahriman.models.result.Result`` and ``List[Packages]`` arguments, which describes the process result and current repository packages respectively. Any exception raised will be suppressed and will generate an exception message in logs.
|
The loaded triggers will be called with ``ahriman.models.result.Result`` and ``List[Packages]`` arguments, which describes the process result and current repository packages respectively. Any exception raised will be suppressed and will generate an exception message in logs.
|
||||||
|
|
||||||
|
In addition triggers can implement ``on_start`` and ``on_stop`` actions which will be called on the application start and right before the application exit. The ``on_start`` action is usually being called from handlers directly in order to make sure that no trigger will be run when it is not required (e.g. on user management). As soon as ``on_start`` action is called, the additional flag will be set; ``ahriman.core.triggers.TriggerLoader`` class implements ``__del__`` method in which, if the flag is set, the ``on_stop`` actions will be called.
|
||||||
|
|
||||||
For more details how to deal with the triggers, refer to :doc:`documentation <triggers>` and modules descriptions.
|
For more details how to deal with the triggers, refer to :doc:`documentation <triggers>` and modules descriptions.
|
||||||
|
|
||||||
Remote synchronization
|
Remote synchronization
|
||||||
@ -241,6 +256,7 @@ Web application requires the following python packages to be installed:
|
|||||||
* In addition, ``aiohttp_debugtoolbar`` is required for debug panel. Please note that this option does not work together with authorization and basically must not be used in production.
|
* In addition, ``aiohttp_debugtoolbar`` is required for debug panel. Please note that this option does not work together with authorization and basically must not be used in production.
|
||||||
* In addition, authorization feature requires ``aiohttp_security``, ``aiohttp_session`` and ``cryptography``.
|
* In addition, authorization feature requires ``aiohttp_security``, ``aiohttp_session`` and ``cryptography``.
|
||||||
* In addition to base authorization dependencies, OAuth2 also requires ``aioauth-client`` library.
|
* In addition to base authorization dependencies, OAuth2 also requires ``aioauth-client`` library.
|
||||||
|
* In addition if you would like to disable authorization for local access (recommended way in order to run the application itself with reporting support), the ``requests-unixsocket`` library is required.
|
||||||
|
|
||||||
Middlewares
|
Middlewares
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
|
484
docs/completions/bash/_ahriman
Normal file
484
docs/completions/bash/_ahriman
Normal file
@ -0,0 +1,484 @@
|
|||||||
|
# AUTOMATICALLY GENERATED by `shtab`
|
||||||
|
|
||||||
|
_shtab_ahriman_subparsers=('aur-search' 'search' 'daemon' 'help' 'help-commands-unsafe' 'key-import' 'package-add' 'add' 'package-update' 'package-remove' 'remove' 'package-status' 'status' 'package-status-remove' 'package-status-update' 'status-update' 'patch-add' 'patch-list' 'patch-remove' 'patch-set-add' 'repo-backup' 'repo-check' 'check' 'repo-clean' 'clean' 'repo-config' 'config' 'repo-rebuild' 'rebuild' 'repo-remove-unknown' 'remove-unknown' 'repo-report' 'report' 'repo-restore' 'repo-setup' 'init' 'repo-init' 'setup' 'repo-sign' 'sign' 'repo-status-update' 'repo-sync' 'sync' 'repo-tree' 'repo-triggers' 'repo-update' 'update' 'shell' 'user-add' 'user-list' 'user-remove' 'version' 'web')
|
||||||
|
|
||||||
|
_shtab_ahriman_option_strings=('-h' '--help' '-a' '--architecture' '-c' '--configuration' '--force' '-l' '--lock' '--report' '--no-report' '-q' '--quiet' '--unsafe' '-V' '--version')
|
||||||
|
_shtab_ahriman_aur_search_option_strings=('-h' '--help' '-e' '--exit-code' '--info' '--no-info' '--sort-by')
|
||||||
|
_shtab_ahriman_search_option_strings=('-h' '--help' '-e' '--exit-code' '--info' '--no-info' '--sort-by')
|
||||||
|
_shtab_ahriman_daemon_option_strings=('-h' '--help' '-i' '--interval' '--aur' '--no-aur' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||||
|
_shtab_ahriman_help_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_help_commands_unsafe_option_strings=('-h' '--help' '--command')
|
||||||
|
_shtab_ahriman_key_import_option_strings=('-h' '--help' '--key-server')
|
||||||
|
_shtab_ahriman_package_add_option_strings=('-h' '--help' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source' '--without-dependencies')
|
||||||
|
_shtab_ahriman_add_option_strings=('-h' '--help' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source' '--without-dependencies')
|
||||||
|
_shtab_ahriman_package_update_option_strings=('-h' '--help' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source' '--without-dependencies')
|
||||||
|
_shtab_ahriman_package_remove_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_remove_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_package_status_option_strings=('-h' '--help' '--ahriman' '-e' '--exit-code' '--info' '--no-info' '-s' '--status')
|
||||||
|
_shtab_ahriman_status_option_strings=('-h' '--help' '--ahriman' '-e' '--exit-code' '--info' '--no-info' '-s' '--status')
|
||||||
|
_shtab_ahriman_package_status_remove_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_package_status_update_option_strings=('-h' '--help' '-s' '--status')
|
||||||
|
_shtab_ahriman_status_update_option_strings=('-h' '--help' '-s' '--status')
|
||||||
|
_shtab_ahriman_patch_add_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_patch_list_option_strings=('-h' '--help' '-e' '--exit-code' '-v' '--variable')
|
||||||
|
_shtab_ahriman_patch_remove_option_strings=('-h' '--help' '-v' '--variable')
|
||||||
|
_shtab_ahriman_patch_set_add_option_strings=('-h' '--help' '-t' '--track')
|
||||||
|
_shtab_ahriman_repo_backup_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_repo_check_option_strings=('-h' '--help' '-e' '--exit-code' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||||
|
_shtab_ahriman_check_option_strings=('-h' '--help' '-e' '--exit-code' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||||
|
_shtab_ahriman_repo_clean_option_strings=('-h' '--help' '--cache' '--no-cache' '--chroot' '--no-chroot' '--manual' '--no-manual' '--packages' '--no-packages' '--pacman' '--no-pacman')
|
||||||
|
_shtab_ahriman_clean_option_strings=('-h' '--help' '--cache' '--no-cache' '--chroot' '--no-chroot' '--manual' '--no-manual' '--packages' '--no-packages' '--pacman' '--no-pacman')
|
||||||
|
_shtab_ahriman_repo_config_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_config_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_repo_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '-e' '--exit-code')
|
||||||
|
_shtab_ahriman_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '-e' '--exit-code')
|
||||||
|
_shtab_ahriman_repo_remove_unknown_option_strings=('-h' '--help' '--dry-run')
|
||||||
|
_shtab_ahriman_remove_unknown_option_strings=('-h' '--help' '--dry-run')
|
||||||
|
_shtab_ahriman_repo_report_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_report_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_repo_restore_option_strings=('-h' '--help' '-o' '--output')
|
||||||
|
_shtab_ahriman_repo_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--makeflags-jobs' '--no-makeflags-jobs' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||||
|
_shtab_ahriman_init_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--makeflags-jobs' '--no-makeflags-jobs' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||||
|
_shtab_ahriman_repo_init_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--makeflags-jobs' '--no-makeflags-jobs' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||||
|
_shtab_ahriman_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--makeflags-jobs' '--no-makeflags-jobs' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||||
|
_shtab_ahriman_repo_sign_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_sign_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_repo_status_update_option_strings=('-h' '--help' '-s' '--status')
|
||||||
|
_shtab_ahriman_repo_sync_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_sync_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_repo_tree_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_repo_triggers_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_repo_update_option_strings=('-h' '--help' '--dry-run' '-e' '--exit-code' '--aur' '--no-aur' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||||
|
_shtab_ahriman_update_option_strings=('-h' '--help' '--dry-run' '-e' '--exit-code' '--aur' '--no-aur' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||||
|
_shtab_ahriman_shell_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_user_add_option_strings=('-h' '--help' '-p' '--password' '-r' '--role' '-s' '--secure')
|
||||||
|
_shtab_ahriman_user_list_option_strings=('-h' '--help' '-e' '--exit-code' '-r' '--role')
|
||||||
|
_shtab_ahriman_user_remove_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_version_option_strings=('-h' '--help')
|
||||||
|
_shtab_ahriman_web_option_strings=('-h' '--help')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_shtab_ahriman_pos_0_choices=('aur-search' 'search' 'daemon' 'help' 'help-commands-unsafe' 'key-import' 'package-add' 'add' 'package-update' 'package-remove' 'remove' 'package-status' 'status' 'package-status-remove' 'package-status-update' 'status-update' 'patch-add' 'patch-list' 'patch-remove' 'patch-set-add' 'repo-backup' 'repo-check' 'check' 'repo-clean' 'clean' 'repo-config' 'config' 'repo-rebuild' 'rebuild' 'repo-remove-unknown' 'remove-unknown' 'repo-report' 'report' 'repo-restore' 'repo-setup' 'init' 'repo-init' 'setup' 'repo-sign' 'sign' 'repo-status-update' 'repo-sync' 'sync' 'repo-tree' 'repo-triggers' 'repo-update' 'update' 'shell' 'user-add' 'user-list' 'user-remove' 'version' 'web')
|
||||||
|
_shtab_ahriman_aur_search___sort_by_choices=('description' 'first_submitted' 'id' 'last_modified' 'maintainer' 'name' 'num_votes' 'out_of_date' 'package_base' 'package_base_id' 'popularity' 'repository' 'url' 'url_path' 'version')
|
||||||
|
_shtab_ahriman_search___sort_by_choices=('description' 'first_submitted' 'id' 'last_modified' 'maintainer' 'name' 'num_votes' 'out_of_date' 'package_base' 'package_base_id' 'popularity' 'repository' 'url' 'url_path' 'version')
|
||||||
|
_shtab_ahriman_package_add__s_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
|
||||||
|
_shtab_ahriman_package_add___source_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
|
||||||
|
_shtab_ahriman_add__s_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
|
||||||
|
_shtab_ahriman_add___source_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
|
||||||
|
_shtab_ahriman_package_update__s_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
|
||||||
|
_shtab_ahriman_package_update___source_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
|
||||||
|
_shtab_ahriman_package_status__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||||
|
_shtab_ahriman_package_status___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||||
|
_shtab_ahriman_status__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||||
|
_shtab_ahriman_status___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||||
|
_shtab_ahriman_package_status_update__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||||
|
_shtab_ahriman_package_status_update___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||||
|
_shtab_ahriman_status_update__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||||
|
_shtab_ahriman_status_update___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||||
|
_shtab_ahriman_repo_setup___sign_target_choices=('disabled' 'packages' 'repository')
|
||||||
|
_shtab_ahriman_init___sign_target_choices=('disabled' 'packages' 'repository')
|
||||||
|
_shtab_ahriman_repo_init___sign_target_choices=('disabled' 'packages' 'repository')
|
||||||
|
_shtab_ahriman_setup___sign_target_choices=('disabled' 'packages' 'repository')
|
||||||
|
_shtab_ahriman_repo_status_update__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||||
|
_shtab_ahriman_repo_status_update___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||||
|
_shtab_ahriman_user_add__r_choices=('unauthorized' 'read' 'reporter' 'full')
|
||||||
|
_shtab_ahriman_user_add___role_choices=('unauthorized' 'read' 'reporter' 'full')
|
||||||
|
_shtab_ahriman_user_list__r_choices=('unauthorized' 'read' 'reporter' 'full')
|
||||||
|
_shtab_ahriman_user_list___role_choices=('unauthorized' 'read' 'reporter' 'full')
|
||||||
|
|
||||||
|
_shtab_ahriman_pos_0_nargs=A...
|
||||||
|
_shtab_ahriman__h_nargs=0
|
||||||
|
_shtab_ahriman___help_nargs=0
|
||||||
|
_shtab_ahriman___force_nargs=0
|
||||||
|
_shtab_ahriman___report_nargs=0
|
||||||
|
_shtab_ahriman___no_report_nargs=0
|
||||||
|
_shtab_ahriman__q_nargs=0
|
||||||
|
_shtab_ahriman___quiet_nargs=0
|
||||||
|
_shtab_ahriman___unsafe_nargs=0
|
||||||
|
_shtab_ahriman__V_nargs=0
|
||||||
|
_shtab_ahriman___version_nargs=0
|
||||||
|
_shtab_ahriman_aur_search_pos_0_nargs=+
|
||||||
|
_shtab_ahriman_aur_search__h_nargs=0
|
||||||
|
_shtab_ahriman_aur_search___help_nargs=0
|
||||||
|
_shtab_ahriman_aur_search__e_nargs=0
|
||||||
|
_shtab_ahriman_aur_search___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_aur_search___info_nargs=0
|
||||||
|
_shtab_ahriman_aur_search___no_info_nargs=0
|
||||||
|
_shtab_ahriman_search_pos_0_nargs=+
|
||||||
|
_shtab_ahriman_search__h_nargs=0
|
||||||
|
_shtab_ahriman_search___help_nargs=0
|
||||||
|
_shtab_ahriman_search__e_nargs=0
|
||||||
|
_shtab_ahriman_search___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_search___info_nargs=0
|
||||||
|
_shtab_ahriman_search___no_info_nargs=0
|
||||||
|
_shtab_ahriman_daemon__h_nargs=0
|
||||||
|
_shtab_ahriman_daemon___help_nargs=0
|
||||||
|
_shtab_ahriman_daemon___aur_nargs=0
|
||||||
|
_shtab_ahriman_daemon___no_aur_nargs=0
|
||||||
|
_shtab_ahriman_daemon___local_nargs=0
|
||||||
|
_shtab_ahriman_daemon___no_local_nargs=0
|
||||||
|
_shtab_ahriman_daemon___manual_nargs=0
|
||||||
|
_shtab_ahriman_daemon___no_manual_nargs=0
|
||||||
|
_shtab_ahriman_daemon___vcs_nargs=0
|
||||||
|
_shtab_ahriman_daemon___no_vcs_nargs=0
|
||||||
|
_shtab_ahriman_daemon__y_nargs=0
|
||||||
|
_shtab_ahriman_daemon___refresh_nargs=0
|
||||||
|
_shtab_ahriman_help__h_nargs=0
|
||||||
|
_shtab_ahriman_help___help_nargs=0
|
||||||
|
_shtab_ahriman_help_commands_unsafe__h_nargs=0
|
||||||
|
_shtab_ahriman_help_commands_unsafe___help_nargs=0
|
||||||
|
_shtab_ahriman_key_import__h_nargs=0
|
||||||
|
_shtab_ahriman_key_import___help_nargs=0
|
||||||
|
_shtab_ahriman_package_add_pos_0_nargs=+
|
||||||
|
_shtab_ahriman_package_add__h_nargs=0
|
||||||
|
_shtab_ahriman_package_add___help_nargs=0
|
||||||
|
_shtab_ahriman_package_add__e_nargs=0
|
||||||
|
_shtab_ahriman_package_add___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_package_add__n_nargs=0
|
||||||
|
_shtab_ahriman_package_add___now_nargs=0
|
||||||
|
_shtab_ahriman_package_add__y_nargs=0
|
||||||
|
_shtab_ahriman_package_add___refresh_nargs=0
|
||||||
|
_shtab_ahriman_package_add___without_dependencies_nargs=0
|
||||||
|
_shtab_ahriman_add_pos_0_nargs=+
|
||||||
|
_shtab_ahriman_add__h_nargs=0
|
||||||
|
_shtab_ahriman_add___help_nargs=0
|
||||||
|
_shtab_ahriman_add__e_nargs=0
|
||||||
|
_shtab_ahriman_add___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_add__n_nargs=0
|
||||||
|
_shtab_ahriman_add___now_nargs=0
|
||||||
|
_shtab_ahriman_add__y_nargs=0
|
||||||
|
_shtab_ahriman_add___refresh_nargs=0
|
||||||
|
_shtab_ahriman_add___without_dependencies_nargs=0
|
||||||
|
_shtab_ahriman_package_update_pos_0_nargs=+
|
||||||
|
_shtab_ahriman_package_update__h_nargs=0
|
||||||
|
_shtab_ahriman_package_update___help_nargs=0
|
||||||
|
_shtab_ahriman_package_update__e_nargs=0
|
||||||
|
_shtab_ahriman_package_update___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_package_update__n_nargs=0
|
||||||
|
_shtab_ahriman_package_update___now_nargs=0
|
||||||
|
_shtab_ahriman_package_update__y_nargs=0
|
||||||
|
_shtab_ahriman_package_update___refresh_nargs=0
|
||||||
|
_shtab_ahriman_package_update___without_dependencies_nargs=0
|
||||||
|
_shtab_ahriman_package_remove_pos_0_nargs=+
|
||||||
|
_shtab_ahriman_package_remove__h_nargs=0
|
||||||
|
_shtab_ahriman_package_remove___help_nargs=0
|
||||||
|
_shtab_ahriman_remove_pos_0_nargs=+
|
||||||
|
_shtab_ahriman_remove__h_nargs=0
|
||||||
|
_shtab_ahriman_remove___help_nargs=0
|
||||||
|
_shtab_ahriman_package_status_pos_0_nargs=*
|
||||||
|
_shtab_ahriman_package_status__h_nargs=0
|
||||||
|
_shtab_ahriman_package_status___help_nargs=0
|
||||||
|
_shtab_ahriman_package_status___ahriman_nargs=0
|
||||||
|
_shtab_ahriman_package_status__e_nargs=0
|
||||||
|
_shtab_ahriman_package_status___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_package_status___info_nargs=0
|
||||||
|
_shtab_ahriman_package_status___no_info_nargs=0
|
||||||
|
_shtab_ahriman_status_pos_0_nargs=*
|
||||||
|
_shtab_ahriman_status__h_nargs=0
|
||||||
|
_shtab_ahriman_status___help_nargs=0
|
||||||
|
_shtab_ahriman_status___ahriman_nargs=0
|
||||||
|
_shtab_ahriman_status__e_nargs=0
|
||||||
|
_shtab_ahriman_status___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_status___info_nargs=0
|
||||||
|
_shtab_ahriman_status___no_info_nargs=0
|
||||||
|
_shtab_ahriman_package_status_remove_pos_0_nargs=+
|
||||||
|
_shtab_ahriman_package_status_remove__h_nargs=0
|
||||||
|
_shtab_ahriman_package_status_remove___help_nargs=0
|
||||||
|
_shtab_ahriman_package_status_update_pos_0_nargs=*
|
||||||
|
_shtab_ahriman_package_status_update__h_nargs=0
|
||||||
|
_shtab_ahriman_package_status_update___help_nargs=0
|
||||||
|
_shtab_ahriman_status_update_pos_0_nargs=*
|
||||||
|
_shtab_ahriman_status_update__h_nargs=0
|
||||||
|
_shtab_ahriman_status_update___help_nargs=0
|
||||||
|
_shtab_ahriman_patch_add__h_nargs=0
|
||||||
|
_shtab_ahriman_patch_add___help_nargs=0
|
||||||
|
_shtab_ahriman_patch_list__h_nargs=0
|
||||||
|
_shtab_ahriman_patch_list___help_nargs=0
|
||||||
|
_shtab_ahriman_patch_list__e_nargs=0
|
||||||
|
_shtab_ahriman_patch_list___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_patch_remove__h_nargs=0
|
||||||
|
_shtab_ahriman_patch_remove___help_nargs=0
|
||||||
|
_shtab_ahriman_patch_set_add__h_nargs=0
|
||||||
|
_shtab_ahriman_patch_set_add___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_backup__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_backup___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_check_pos_0_nargs=*
|
||||||
|
_shtab_ahriman_repo_check__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_check___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_check__e_nargs=0
|
||||||
|
_shtab_ahriman_repo_check___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_repo_check___vcs_nargs=0
|
||||||
|
_shtab_ahriman_repo_check___no_vcs_nargs=0
|
||||||
|
_shtab_ahriman_repo_check__y_nargs=0
|
||||||
|
_shtab_ahriman_repo_check___refresh_nargs=0
|
||||||
|
_shtab_ahriman_check_pos_0_nargs=*
|
||||||
|
_shtab_ahriman_check__h_nargs=0
|
||||||
|
_shtab_ahriman_check___help_nargs=0
|
||||||
|
_shtab_ahriman_check__e_nargs=0
|
||||||
|
_shtab_ahriman_check___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_check___vcs_nargs=0
|
||||||
|
_shtab_ahriman_check___no_vcs_nargs=0
|
||||||
|
_shtab_ahriman_check__y_nargs=0
|
||||||
|
_shtab_ahriman_check___refresh_nargs=0
|
||||||
|
_shtab_ahriman_repo_clean__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_clean___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_clean___cache_nargs=0
|
||||||
|
_shtab_ahriman_repo_clean___no_cache_nargs=0
|
||||||
|
_shtab_ahriman_repo_clean___chroot_nargs=0
|
||||||
|
_shtab_ahriman_repo_clean___no_chroot_nargs=0
|
||||||
|
_shtab_ahriman_repo_clean___manual_nargs=0
|
||||||
|
_shtab_ahriman_repo_clean___no_manual_nargs=0
|
||||||
|
_shtab_ahriman_repo_clean___packages_nargs=0
|
||||||
|
_shtab_ahriman_repo_clean___no_packages_nargs=0
|
||||||
|
_shtab_ahriman_repo_clean___pacman_nargs=0
|
||||||
|
_shtab_ahriman_repo_clean___no_pacman_nargs=0
|
||||||
|
_shtab_ahriman_clean__h_nargs=0
|
||||||
|
_shtab_ahriman_clean___help_nargs=0
|
||||||
|
_shtab_ahriman_clean___cache_nargs=0
|
||||||
|
_shtab_ahriman_clean___no_cache_nargs=0
|
||||||
|
_shtab_ahriman_clean___chroot_nargs=0
|
||||||
|
_shtab_ahriman_clean___no_chroot_nargs=0
|
||||||
|
_shtab_ahriman_clean___manual_nargs=0
|
||||||
|
_shtab_ahriman_clean___no_manual_nargs=0
|
||||||
|
_shtab_ahriman_clean___packages_nargs=0
|
||||||
|
_shtab_ahriman_clean___no_packages_nargs=0
|
||||||
|
_shtab_ahriman_clean___pacman_nargs=0
|
||||||
|
_shtab_ahriman_clean___no_pacman_nargs=0
|
||||||
|
_shtab_ahriman_repo_config__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_config___help_nargs=0
|
||||||
|
_shtab_ahriman_config__h_nargs=0
|
||||||
|
_shtab_ahriman_config___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_rebuild__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_rebuild___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_rebuild___dry_run_nargs=0
|
||||||
|
_shtab_ahriman_repo_rebuild___from_database_nargs=0
|
||||||
|
_shtab_ahriman_repo_rebuild__e_nargs=0
|
||||||
|
_shtab_ahriman_repo_rebuild___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_rebuild__h_nargs=0
|
||||||
|
_shtab_ahriman_rebuild___help_nargs=0
|
||||||
|
_shtab_ahriman_rebuild___dry_run_nargs=0
|
||||||
|
_shtab_ahriman_rebuild___from_database_nargs=0
|
||||||
|
_shtab_ahriman_rebuild__e_nargs=0
|
||||||
|
_shtab_ahriman_rebuild___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_repo_remove_unknown__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_remove_unknown___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_remove_unknown___dry_run_nargs=0
|
||||||
|
_shtab_ahriman_remove_unknown__h_nargs=0
|
||||||
|
_shtab_ahriman_remove_unknown___help_nargs=0
|
||||||
|
_shtab_ahriman_remove_unknown___dry_run_nargs=0
|
||||||
|
_shtab_ahriman_repo_report__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_report___help_nargs=0
|
||||||
|
_shtab_ahriman_report__h_nargs=0
|
||||||
|
_shtab_ahriman_report___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_restore__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_restore___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_setup__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_setup___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_setup___makeflags_jobs_nargs=0
|
||||||
|
_shtab_ahriman_repo_setup___no_makeflags_jobs_nargs=0
|
||||||
|
_shtab_ahriman_repo_setup___multilib_nargs=0
|
||||||
|
_shtab_ahriman_repo_setup___no_multilib_nargs=0
|
||||||
|
_shtab_ahriman_init__h_nargs=0
|
||||||
|
_shtab_ahriman_init___help_nargs=0
|
||||||
|
_shtab_ahriman_init___makeflags_jobs_nargs=0
|
||||||
|
_shtab_ahriman_init___no_makeflags_jobs_nargs=0
|
||||||
|
_shtab_ahriman_init___multilib_nargs=0
|
||||||
|
_shtab_ahriman_init___no_multilib_nargs=0
|
||||||
|
_shtab_ahriman_repo_init__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_init___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_init___makeflags_jobs_nargs=0
|
||||||
|
_shtab_ahriman_repo_init___no_makeflags_jobs_nargs=0
|
||||||
|
_shtab_ahriman_repo_init___multilib_nargs=0
|
||||||
|
_shtab_ahriman_repo_init___no_multilib_nargs=0
|
||||||
|
_shtab_ahriman_setup__h_nargs=0
|
||||||
|
_shtab_ahriman_setup___help_nargs=0
|
||||||
|
_shtab_ahriman_setup___makeflags_jobs_nargs=0
|
||||||
|
_shtab_ahriman_setup___no_makeflags_jobs_nargs=0
|
||||||
|
_shtab_ahriman_setup___multilib_nargs=0
|
||||||
|
_shtab_ahriman_setup___no_multilib_nargs=0
|
||||||
|
_shtab_ahriman_repo_sign_pos_0_nargs=*
|
||||||
|
_shtab_ahriman_repo_sign__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_sign___help_nargs=0
|
||||||
|
_shtab_ahriman_sign_pos_0_nargs=*
|
||||||
|
_shtab_ahriman_sign__h_nargs=0
|
||||||
|
_shtab_ahriman_sign___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_status_update__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_status_update___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_sync__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_sync___help_nargs=0
|
||||||
|
_shtab_ahriman_sync__h_nargs=0
|
||||||
|
_shtab_ahriman_sync___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_tree__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_tree___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_triggers_pos_0_nargs=*
|
||||||
|
_shtab_ahriman_repo_triggers__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_triggers___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_update_pos_0_nargs=*
|
||||||
|
_shtab_ahriman_repo_update__h_nargs=0
|
||||||
|
_shtab_ahriman_repo_update___help_nargs=0
|
||||||
|
_shtab_ahriman_repo_update___dry_run_nargs=0
|
||||||
|
_shtab_ahriman_repo_update__e_nargs=0
|
||||||
|
_shtab_ahriman_repo_update___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_repo_update___aur_nargs=0
|
||||||
|
_shtab_ahriman_repo_update___no_aur_nargs=0
|
||||||
|
_shtab_ahriman_repo_update___local_nargs=0
|
||||||
|
_shtab_ahriman_repo_update___no_local_nargs=0
|
||||||
|
_shtab_ahriman_repo_update___manual_nargs=0
|
||||||
|
_shtab_ahriman_repo_update___no_manual_nargs=0
|
||||||
|
_shtab_ahriman_repo_update___vcs_nargs=0
|
||||||
|
_shtab_ahriman_repo_update___no_vcs_nargs=0
|
||||||
|
_shtab_ahriman_repo_update__y_nargs=0
|
||||||
|
_shtab_ahriman_repo_update___refresh_nargs=0
|
||||||
|
_shtab_ahriman_update_pos_0_nargs=*
|
||||||
|
_shtab_ahriman_update__h_nargs=0
|
||||||
|
_shtab_ahriman_update___help_nargs=0
|
||||||
|
_shtab_ahriman_update___dry_run_nargs=0
|
||||||
|
_shtab_ahriman_update__e_nargs=0
|
||||||
|
_shtab_ahriman_update___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_update___aur_nargs=0
|
||||||
|
_shtab_ahriman_update___no_aur_nargs=0
|
||||||
|
_shtab_ahriman_update___local_nargs=0
|
||||||
|
_shtab_ahriman_update___no_local_nargs=0
|
||||||
|
_shtab_ahriman_update___manual_nargs=0
|
||||||
|
_shtab_ahriman_update___no_manual_nargs=0
|
||||||
|
_shtab_ahriman_update___vcs_nargs=0
|
||||||
|
_shtab_ahriman_update___no_vcs_nargs=0
|
||||||
|
_shtab_ahriman_update__y_nargs=0
|
||||||
|
_shtab_ahriman_update___refresh_nargs=0
|
||||||
|
_shtab_ahriman_shell__h_nargs=0
|
||||||
|
_shtab_ahriman_shell___help_nargs=0
|
||||||
|
_shtab_ahriman_shell__v_nargs=0
|
||||||
|
_shtab_ahriman_shell___verbose_nargs=0
|
||||||
|
_shtab_ahriman_user_add__h_nargs=0
|
||||||
|
_shtab_ahriman_user_add___help_nargs=0
|
||||||
|
_shtab_ahriman_user_add__s_nargs=0
|
||||||
|
_shtab_ahriman_user_add___secure_nargs=0
|
||||||
|
_shtab_ahriman_user_list__h_nargs=0
|
||||||
|
_shtab_ahriman_user_list___help_nargs=0
|
||||||
|
_shtab_ahriman_user_list__e_nargs=0
|
||||||
|
_shtab_ahriman_user_list___exit_code_nargs=0
|
||||||
|
_shtab_ahriman_user_remove__h_nargs=0
|
||||||
|
_shtab_ahriman_user_remove___help_nargs=0
|
||||||
|
_shtab_ahriman_version__h_nargs=0
|
||||||
|
_shtab_ahriman_version___help_nargs=0
|
||||||
|
_shtab_ahriman_web__h_nargs=0
|
||||||
|
_shtab_ahriman_web___help_nargs=0
|
||||||
|
|
||||||
|
|
||||||
|
# $1=COMP_WORDS[1]
|
||||||
|
_shtab_compgen_files() {
|
||||||
|
compgen -f -- $1 # files
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1=COMP_WORDS[1]
|
||||||
|
_shtab_compgen_dirs() {
|
||||||
|
compgen -d -- $1 # recurse into subdirs
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1=COMP_WORDS[1]
|
||||||
|
_shtab_replace_nonword() {
|
||||||
|
echo "${1//[^[:word:]]/_}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# set default values (called for the initial parser & any subparsers)
|
||||||
|
_set_parser_defaults() {
|
||||||
|
local subparsers_var="${prefix}_subparsers[@]"
|
||||||
|
sub_parsers=${!subparsers_var}
|
||||||
|
|
||||||
|
local current_option_strings_var="${prefix}_option_strings[@]"
|
||||||
|
current_option_strings=${!current_option_strings_var}
|
||||||
|
|
||||||
|
completed_positional_actions=0
|
||||||
|
|
||||||
|
_set_new_action "pos_${completed_positional_actions}" true
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1=action identifier
|
||||||
|
# $2=positional action (bool)
|
||||||
|
# set all identifiers for an action's parameters
|
||||||
|
_set_new_action() {
|
||||||
|
current_action="${prefix}_$(_shtab_replace_nonword $1)"
|
||||||
|
|
||||||
|
local current_action_compgen_var=${current_action}_COMPGEN
|
||||||
|
current_action_compgen="${!current_action_compgen_var}"
|
||||||
|
|
||||||
|
local current_action_choices_var="${current_action}_choices[@]"
|
||||||
|
current_action_choices="${!current_action_choices_var}"
|
||||||
|
|
||||||
|
local current_action_nargs_var="${current_action}_nargs"
|
||||||
|
if [ -n "${!current_action_nargs_var}" ]; then
|
||||||
|
current_action_nargs="${!current_action_nargs_var}"
|
||||||
|
else
|
||||||
|
current_action_nargs=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
current_action_args_start_index=$(( $word_index + 1 ))
|
||||||
|
|
||||||
|
current_action_is_positional=$2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Notes:
|
||||||
|
# `COMPREPLY`: what will be rendered after completion is triggered
|
||||||
|
# `completing_word`: currently typed word to generate completions for
|
||||||
|
# `${!var}`: evaluates the content of `var` and expand its content as a variable
|
||||||
|
# hello="world"
|
||||||
|
# x="hello"
|
||||||
|
# ${!x} -> ${hello} -> "world"
|
||||||
|
_shtab_ahriman() {
|
||||||
|
local completing_word="${COMP_WORDS[COMP_CWORD]}"
|
||||||
|
COMPREPLY=()
|
||||||
|
|
||||||
|
prefix=_shtab_ahriman
|
||||||
|
word_index=0
|
||||||
|
_set_parser_defaults
|
||||||
|
word_index=1
|
||||||
|
|
||||||
|
# determine what arguments are appropriate for the current state
|
||||||
|
# of the arg parser
|
||||||
|
while [ $word_index -ne $COMP_CWORD ]; do
|
||||||
|
local this_word="${COMP_WORDS[$word_index]}"
|
||||||
|
|
||||||
|
if [[ -n $sub_parsers && " ${sub_parsers[@]} " =~ " ${this_word} " ]]; then
|
||||||
|
# valid subcommand: add it to the prefix & reset the current action
|
||||||
|
prefix="${prefix}_$(_shtab_replace_nonword $this_word)"
|
||||||
|
_set_parser_defaults
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ " ${current_option_strings[@]} " =~ " ${this_word} " ]]; then
|
||||||
|
# a new action should be acquired (due to recognised option string or
|
||||||
|
# no more input expected from current action);
|
||||||
|
# the next positional action can fill in here
|
||||||
|
_set_new_action $this_word false
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$current_action_nargs" != "*" ]] && \
|
||||||
|
[[ "$current_action_nargs" != "+" ]] && \
|
||||||
|
[[ "$current_action_nargs" != *"..." ]] && \
|
||||||
|
(( $word_index + 1 - $current_action_args_start_index >= \
|
||||||
|
$current_action_nargs )); then
|
||||||
|
$current_action_is_positional && let "completed_positional_actions += 1"
|
||||||
|
_set_new_action "pos_${completed_positional_actions}" true
|
||||||
|
fi
|
||||||
|
|
||||||
|
let "word_index+=1"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Generate the completions
|
||||||
|
|
||||||
|
if [[ "${completing_word}" == -* ]]; then
|
||||||
|
# optional argument started: use option strings
|
||||||
|
COMPREPLY=( $(compgen -W "${current_option_strings[*]}" -- "${completing_word}") )
|
||||||
|
else
|
||||||
|
# use choices & compgen
|
||||||
|
local IFS=$'\n' # items may contain spaces, so delimit using newline
|
||||||
|
COMPREPLY=( $([ -n "${current_action_compgen}" ] \
|
||||||
|
&& "${current_action_compgen}" "${completing_word}") )
|
||||||
|
unset IFS
|
||||||
|
COMPREPLY+=( $(compgen -W "${current_action_choices[*]}" -- "${completing_word}") )
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -o filenames -F _shtab_ahriman ahriman
|
531
docs/completions/zsh/_ahriman
Normal file
531
docs/completions/zsh/_ahriman
Normal file
@ -0,0 +1,531 @@
|
|||||||
|
#compdef ahriman
|
||||||
|
|
||||||
|
# AUTOMATICALLY GENERATED by `shtab`
|
||||||
|
|
||||||
|
|
||||||
|
_shtab_ahriman_commands() {
|
||||||
|
local _commands=(
|
||||||
|
"add:add existing or new package to the build queue"
|
||||||
|
"aur-search:search for package in AUR using API"
|
||||||
|
"check:check for packages updates. Same as repo-update --dry-run --no-manual"
|
||||||
|
"clean:remove local caches"
|
||||||
|
"config:dump configuration for the specified architecture"
|
||||||
|
"daemon:start process which periodically will run update process"
|
||||||
|
"help:show help message for application or command and exit"
|
||||||
|
"help-commands-unsafe:list unsafe commands as defined in default args"
|
||||||
|
"init:create initial service configuration, requires root"
|
||||||
|
"key-import:import PGP key from public sources to the repository user"
|
||||||
|
"package-add:add existing or new package to the build queue"
|
||||||
|
"package-remove:remove package from the repository"
|
||||||
|
"package-status:request status of the package"
|
||||||
|
"package-status-remove:remove the package from the status page"
|
||||||
|
"package-status-update:update package status on the status page"
|
||||||
|
"package-update:add existing or new package to the build queue"
|
||||||
|
"patch-add:create or update patched PKGBUILD function or variable"
|
||||||
|
"patch-list:list available patches for the package"
|
||||||
|
"patch-remove:remove patches for the package"
|
||||||
|
"patch-set-add:create or update source patches"
|
||||||
|
"rebuild:force rebuild whole repository"
|
||||||
|
"remove:remove package from the repository"
|
||||||
|
"remove-unknown:remove packages which are missing in AUR and do not have local PKGBUILDs"
|
||||||
|
"repo-backup:backup repository settings and database"
|
||||||
|
"repo-check:check for packages updates. Same as repo-update --dry-run --no-manual"
|
||||||
|
"repo-clean:remove local caches"
|
||||||
|
"repo-config:dump configuration for the specified architecture"
|
||||||
|
"repo-init:create initial service configuration, requires root"
|
||||||
|
"repo-rebuild:force rebuild whole repository"
|
||||||
|
"repo-remove-unknown:remove packages which are missing in AUR and do not have local PKGBUILDs"
|
||||||
|
"repo-report:generate repository report according to current settings"
|
||||||
|
"repo-restore:restore settings and database"
|
||||||
|
"repo-setup:create initial service configuration, requires root"
|
||||||
|
"repo-sign:(re-)sign packages and repository database according to current settings"
|
||||||
|
"repo-status-update:update repository status on the status page"
|
||||||
|
"repo-sync:sync repository files to remote server according to current settings"
|
||||||
|
"repo-tree:dump repository tree based on packages dependencies"
|
||||||
|
"repo-triggers:run triggers on empty build result as configured by settings"
|
||||||
|
"repo-update:check for packages updates and run build process if requested"
|
||||||
|
"report:generate repository report according to current settings"
|
||||||
|
"search:search for package in AUR using API"
|
||||||
|
"setup:create initial service configuration, requires root"
|
||||||
|
"shell:drop into python shell while having created application"
|
||||||
|
"sign:(re-)sign packages and repository database according to current settings"
|
||||||
|
"status:request status of the package"
|
||||||
|
"status-update:update package status on the status page"
|
||||||
|
"sync:sync repository files to remote server according to current settings"
|
||||||
|
"update:check for packages updates and run build process if requested"
|
||||||
|
"user-add:update user for web services with the given password and role. In case if password was not entered it will be asked interactively"
|
||||||
|
"user-list:list users from the user mapping and their roles"
|
||||||
|
"user-remove:remove user from the user mapping and update the configuration"
|
||||||
|
"version:print application and its dependencies versions"
|
||||||
|
"web:start web server"
|
||||||
|
)
|
||||||
|
_describe 'ahriman commands' _commands
|
||||||
|
}
|
||||||
|
|
||||||
|
_shtab_ahriman_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"*"{-a,--architecture}"[target architectures. For several subcommands it can be used multiple times]:architecture:"
|
||||||
|
{-c,--configuration}"[configuration path]:configuration:"
|
||||||
|
"--force[force run, remove file lock]"
|
||||||
|
{-l,--lock}"[lock file]:lock:"
|
||||||
|
{--report,--no-report}"[force enable or disable reporting to web service (default\: \%(default)s)]:report:"
|
||||||
|
{-q,--quiet}"[force disable any logging]"
|
||||||
|
"--unsafe[allow to run ahriman as non-ahriman user. Some actions might be unavailable]"
|
||||||
|
"(- : *)"{-V,--version}"[show program\'s version number and exit]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_add_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
{-n,--now}"[run update function after]"
|
||||||
|
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||||
|
{-s,--source}"[explicitly specify the package source for this command]:source:(auto archive aur directory local remote repository)"
|
||||||
|
"--without-dependencies[do not add dependencies]"
|
||||||
|
"(*):package source (base name, path to local files, remote URL):"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_aur_search_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
{--info,--no-info}"[show additional package information (default\: \%(default)s)]:info:"
|
||||||
|
"--sort-by[sort field by this field. In case if two packages have the same value of the specified field, they will be always sorted by name]:sort_by:(description first_submitted id last_modified maintainer name num_votes out_of_date package_base package_base_id popularity repository url url_path version)"
|
||||||
|
"(*):search terms, can be specified multiple times, the result will match all terms:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_check_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
{--vcs,--no-vcs}"[enable or disable checking of VCS packages (default\: \%(default)s)]:vcs:"
|
||||||
|
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||||
|
"(*)::filter check by package base:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_clean_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{--cache,--no-cache}"[clear directory with package caches (default\: \%(default)s)]:cache:"
|
||||||
|
{--chroot,--no-chroot}"[clear build chroot (default\: \%(default)s)]:chroot:"
|
||||||
|
{--manual,--no-manual}"[clear manually added packages queue (default\: \%(default)s)]:manual:"
|
||||||
|
{--packages,--no-packages}"[clear directory with built packages (default\: \%(default)s)]:packages:"
|
||||||
|
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: \%(default)s)]:pacman:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_config_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_daemon_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-i,--interval}"[interval between runs in seconds]:interval:"
|
||||||
|
{--aur,--no-aur}"[enable or disable checking for AUR updates. Implies --no-vcs (default\: \%(default)s)]:aur:"
|
||||||
|
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: \%(default)s)]:local:"
|
||||||
|
{--manual,--no-manual}"[include or exclude manual updates (default\: \%(default)s)]:manual:"
|
||||||
|
{--vcs,--no-vcs}"[enable or disable checking of VCS packages (default\: \%(default)s)]:vcs:"
|
||||||
|
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_help_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
":show help message for specific command:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_help_commands_unsafe_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"--command[instead of showing commands, just test command line for unsafe subcommand and return 0 in case if command is safe and 1 otherwise]:command:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_init_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"--build-as-user[force makepkg user to the specific one]:build_as_user:"
|
||||||
|
"--build-command[build command prefix]:build_command:"
|
||||||
|
"--from-configuration[path to default devtools pacman configuration]:from_configuration:"
|
||||||
|
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: \%(default)s)]:makeflags_jobs:"
|
||||||
|
{--multilib,--no-multilib}"[add or do not multilib repository (default\: \%(default)s)]:multilib:"
|
||||||
|
"--packager[packager name and email]:packager:"
|
||||||
|
"--repository[repository name]:repository:"
|
||||||
|
"--sign-key[sign key id]:sign_key:"
|
||||||
|
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
|
||||||
|
"--web-port[port of the web service]:web_port:"
|
||||||
|
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_key_import_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"--key-server[key server for key import]:key_server:"
|
||||||
|
":PGP key to import from public server:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_package_add_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
{-n,--now}"[run update function after]"
|
||||||
|
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||||
|
{-s,--source}"[explicitly specify the package source for this command]:source:(auto archive aur directory local remote repository)"
|
||||||
|
"--without-dependencies[do not add dependencies]"
|
||||||
|
"(*):package source (base name, path to local files, remote URL):"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_package_remove_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"(*):package name or base:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_package_status_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"--ahriman[get service status itself]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
{--info,--no-info}"[show additional package information (default\: \%(default)s)]:info:"
|
||||||
|
{-s,--status}"[filter packages by status]:status:(unknown pending building failed success)"
|
||||||
|
"(*)::filter status by package base:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_package_status_remove_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"(*):remove specified packages from status page:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_package_status_update_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-s,--status}"[new package build status]:status:(unknown pending building failed success)"
|
||||||
|
"(*)::set status for specified packages. If no packages supplied, service status will be updated:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_package_update_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
{-n,--now}"[run update function after]"
|
||||||
|
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||||
|
{-s,--source}"[explicitly specify the package source for this command]:source:(auto archive aur directory local remote repository)"
|
||||||
|
"--without-dependencies[do not add dependencies]"
|
||||||
|
"(*):package source (base name, path to local files, remote URL):"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_patch_add_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
":package base:"
|
||||||
|
":PKGBUILD variable or function name. If variable is a function, it must end with ():"
|
||||||
|
":path to file which contains function or variable value. If not set, the value will be read from stdin:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_patch_list_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
"*"{-v,--variable}"[if set, show only patches for specified PKGBUILD variables]:variable:"
|
||||||
|
":package base:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_patch_remove_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"*"{-v,--variable}"[should be used for single-function patches in case if you wold like to remove only specified PKGBUILD variables. In case if not set, it will remove all patches related to the package]:variable:"
|
||||||
|
":package base:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_patch_set_add_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"*"{-t,--track}"[files which has to be tracked]:track:"
|
||||||
|
":path to directory with changed files for patch addition\/update:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_rebuild_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"*--depends-on[only rebuild packages that depend on specified packages]:depends_on:"
|
||||||
|
"--dry-run[just perform check for packages without rebuild process itself]"
|
||||||
|
"--from-database[read packages from database instead of filesystem. This feature in particular is required in case if you would like to restore repository from another repository instance. Note, however, that in order to restore packages you need to have original ahriman instance run with web service and have run repo-update at least once.]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_remove_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"(*):package name or base:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_remove_unknown_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"--dry-run[just perform check for packages without removal]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_backup_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
":path of the output archive:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_check_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
{--vcs,--no-vcs}"[enable or disable checking of VCS packages (default\: \%(default)s)]:vcs:"
|
||||||
|
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||||
|
"(*)::filter check by package base:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_clean_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{--cache,--no-cache}"[clear directory with package caches (default\: \%(default)s)]:cache:"
|
||||||
|
{--chroot,--no-chroot}"[clear build chroot (default\: \%(default)s)]:chroot:"
|
||||||
|
{--manual,--no-manual}"[clear manually added packages queue (default\: \%(default)s)]:manual:"
|
||||||
|
{--packages,--no-packages}"[clear directory with built packages (default\: \%(default)s)]:packages:"
|
||||||
|
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: \%(default)s)]:pacman:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_config_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_init_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"--build-as-user[force makepkg user to the specific one]:build_as_user:"
|
||||||
|
"--build-command[build command prefix]:build_command:"
|
||||||
|
"--from-configuration[path to default devtools pacman configuration]:from_configuration:"
|
||||||
|
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: \%(default)s)]:makeflags_jobs:"
|
||||||
|
{--multilib,--no-multilib}"[add or do not multilib repository (default\: \%(default)s)]:multilib:"
|
||||||
|
"--packager[packager name and email]:packager:"
|
||||||
|
"--repository[repository name]:repository:"
|
||||||
|
"--sign-key[sign key id]:sign_key:"
|
||||||
|
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
|
||||||
|
"--web-port[port of the web service]:web_port:"
|
||||||
|
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_rebuild_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"*--depends-on[only rebuild packages that depend on specified packages]:depends_on:"
|
||||||
|
"--dry-run[just perform check for packages without rebuild process itself]"
|
||||||
|
"--from-database[read packages from database instead of filesystem. This feature in particular is required in case if you would like to restore repository from another repository instance. Note, however, that in order to restore packages you need to have original ahriman instance run with web service and have run repo-update at least once.]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_remove_unknown_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"--dry-run[just perform check for packages without removal]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_report_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_restore_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-o,--output}"[root path of the extracted files]:output:"
|
||||||
|
":path of the input archive:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_setup_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"--build-as-user[force makepkg user to the specific one]:build_as_user:"
|
||||||
|
"--build-command[build command prefix]:build_command:"
|
||||||
|
"--from-configuration[path to default devtools pacman configuration]:from_configuration:"
|
||||||
|
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: \%(default)s)]:makeflags_jobs:"
|
||||||
|
{--multilib,--no-multilib}"[add or do not multilib repository (default\: \%(default)s)]:multilib:"
|
||||||
|
"--packager[packager name and email]:packager:"
|
||||||
|
"--repository[repository name]:repository:"
|
||||||
|
"--sign-key[sign key id]:sign_key:"
|
||||||
|
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
|
||||||
|
"--web-port[port of the web service]:web_port:"
|
||||||
|
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_sign_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"(*)::sign only specified packages:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_status_update_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-s,--status}"[new status]:status:(unknown pending building failed success)"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_sync_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_tree_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_triggers_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"(*)::instead of running all triggers as set by configuration, just process specified ones in order of mention:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_repo_update_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"--dry-run[just perform check for updates, same as check command]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
{--aur,--no-aur}"[enable or disable checking for AUR updates. Implies --no-vcs (default\: \%(default)s)]:aur:"
|
||||||
|
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: \%(default)s)]:local:"
|
||||||
|
{--manual,--no-manual}"[include or exclude manual updates (default\: \%(default)s)]:manual:"
|
||||||
|
{--vcs,--no-vcs}"[enable or disable checking of VCS packages (default\: \%(default)s)]:vcs:"
|
||||||
|
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||||
|
"(*)::filter check by package base:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_report_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_search_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
{--info,--no-info}"[show additional package information (default\: \%(default)s)]:info:"
|
||||||
|
"--sort-by[sort field by this field. In case if two packages have the same value of the specified field, they will be always sorted by name]:sort_by:(description first_submitted id last_modified maintainer name num_votes out_of_date package_base package_base_id popularity repository url url_path version)"
|
||||||
|
"(*):search terms, can be specified multiple times, the result will match all terms:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_setup_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"--build-as-user[force makepkg user to the specific one]:build_as_user:"
|
||||||
|
"--build-command[build command prefix]:build_command:"
|
||||||
|
"--from-configuration[path to default devtools pacman configuration]:from_configuration:"
|
||||||
|
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: \%(default)s)]:makeflags_jobs:"
|
||||||
|
{--multilib,--no-multilib}"[add or do not multilib repository (default\: \%(default)s)]:multilib:"
|
||||||
|
"--packager[packager name and email]:packager:"
|
||||||
|
"--repository[repository name]:repository:"
|
||||||
|
"--sign-key[sign key id]:sign_key:"
|
||||||
|
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
|
||||||
|
"--web-port[port of the web service]:web_port:"
|
||||||
|
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_shell_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
":instead of dropping into shell, just execute the specified code:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_sign_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"(*)::sign only specified packages:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_status_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"--ahriman[get service status itself]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
{--info,--no-info}"[show additional package information (default\: \%(default)s)]:info:"
|
||||||
|
{-s,--status}"[filter packages by status]:status:(unknown pending building failed success)"
|
||||||
|
"(*)::filter status by package base:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_status_update_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-s,--status}"[new package build status]:status:(unknown pending building failed success)"
|
||||||
|
"(*)::set status for specified packages. If no packages supplied, service status will be updated:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_sync_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_update_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
"--dry-run[just perform check for updates, same as check command]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
{--aur,--no-aur}"[enable or disable checking for AUR updates. Implies --no-vcs (default\: \%(default)s)]:aur:"
|
||||||
|
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: \%(default)s)]:local:"
|
||||||
|
{--manual,--no-manual}"[include or exclude manual updates (default\: \%(default)s)]:manual:"
|
||||||
|
{--vcs,--no-vcs}"[enable or disable checking of VCS packages (default\: \%(default)s)]:vcs:"
|
||||||
|
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||||
|
"(*)::filter check by package base:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_user_add_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-p,--password}"[user password. Blank password will be treated as empty password, which is in particular must be used for OAuth2 authorization type.]:password:"
|
||||||
|
{-r,--role}"[user access level]:role:(unauthorized read reporter full)"
|
||||||
|
{-s,--secure}"[set file permissions to user-only]"
|
||||||
|
":username for web service:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_user_list_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||||
|
{-r,--role}"[filter users by role]:role:(unauthorized read reporter full)"
|
||||||
|
":filter users by username:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_user_remove_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
":username for web service:"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_version_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
)
|
||||||
|
|
||||||
|
_shtab_ahriman_web_options=(
|
||||||
|
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_shtab_ahriman() {
|
||||||
|
local context state line curcontext="$curcontext" one_or_more='(-)*' remainder='(*)'
|
||||||
|
|
||||||
|
if ((${_shtab_ahriman_options[(I)${(q)one_or_more}*]} + ${_shtab_ahriman_options[(I)${(q)remainder}*]} == 0)); then # noqa: E501
|
||||||
|
_shtab_ahriman_options+=(': :_shtab_ahriman_commands' '*::: :->ahriman')
|
||||||
|
fi
|
||||||
|
_arguments -C $_shtab_ahriman_options
|
||||||
|
|
||||||
|
case $state in
|
||||||
|
ahriman)
|
||||||
|
words=($line[1] "${words[@]}")
|
||||||
|
(( CURRENT += 1 ))
|
||||||
|
curcontext="${curcontext%:*:*}:_shtab_ahriman-$line[1]:"
|
||||||
|
case $line[1] in
|
||||||
|
add) _arguments -C $_shtab_ahriman_add_options ;;
|
||||||
|
aur-search) _arguments -C $_shtab_ahriman_aur_search_options ;;
|
||||||
|
check) _arguments -C $_shtab_ahriman_check_options ;;
|
||||||
|
clean) _arguments -C $_shtab_ahriman_clean_options ;;
|
||||||
|
config) _arguments -C $_shtab_ahriman_config_options ;;
|
||||||
|
daemon) _arguments -C $_shtab_ahriman_daemon_options ;;
|
||||||
|
help) _arguments -C $_shtab_ahriman_help_options ;;
|
||||||
|
help-commands-unsafe) _arguments -C $_shtab_ahriman_help_commands_unsafe_options ;;
|
||||||
|
init) _arguments -C $_shtab_ahriman_init_options ;;
|
||||||
|
key-import) _arguments -C $_shtab_ahriman_key_import_options ;;
|
||||||
|
package-add) _arguments -C $_shtab_ahriman_package_add_options ;;
|
||||||
|
package-remove) _arguments -C $_shtab_ahriman_package_remove_options ;;
|
||||||
|
package-status) _arguments -C $_shtab_ahriman_package_status_options ;;
|
||||||
|
package-status-remove) _arguments -C $_shtab_ahriman_package_status_remove_options ;;
|
||||||
|
package-status-update) _arguments -C $_shtab_ahriman_package_status_update_options ;;
|
||||||
|
package-update) _arguments -C $_shtab_ahriman_package_update_options ;;
|
||||||
|
patch-add) _arguments -C $_shtab_ahriman_patch_add_options ;;
|
||||||
|
patch-list) _arguments -C $_shtab_ahriman_patch_list_options ;;
|
||||||
|
patch-remove) _arguments -C $_shtab_ahriman_patch_remove_options ;;
|
||||||
|
patch-set-add) _arguments -C $_shtab_ahriman_patch_set_add_options ;;
|
||||||
|
rebuild) _arguments -C $_shtab_ahriman_rebuild_options ;;
|
||||||
|
remove) _arguments -C $_shtab_ahriman_remove_options ;;
|
||||||
|
remove-unknown) _arguments -C $_shtab_ahriman_remove_unknown_options ;;
|
||||||
|
repo-backup) _arguments -C $_shtab_ahriman_repo_backup_options ;;
|
||||||
|
repo-check) _arguments -C $_shtab_ahriman_repo_check_options ;;
|
||||||
|
repo-clean) _arguments -C $_shtab_ahriman_repo_clean_options ;;
|
||||||
|
repo-config) _arguments -C $_shtab_ahriman_repo_config_options ;;
|
||||||
|
repo-init) _arguments -C $_shtab_ahriman_repo_init_options ;;
|
||||||
|
repo-rebuild) _arguments -C $_shtab_ahriman_repo_rebuild_options ;;
|
||||||
|
repo-remove-unknown) _arguments -C $_shtab_ahriman_repo_remove_unknown_options ;;
|
||||||
|
repo-report) _arguments -C $_shtab_ahriman_repo_report_options ;;
|
||||||
|
repo-restore) _arguments -C $_shtab_ahriman_repo_restore_options ;;
|
||||||
|
repo-setup) _arguments -C $_shtab_ahriman_repo_setup_options ;;
|
||||||
|
repo-sign) _arguments -C $_shtab_ahriman_repo_sign_options ;;
|
||||||
|
repo-status-update) _arguments -C $_shtab_ahriman_repo_status_update_options ;;
|
||||||
|
repo-sync) _arguments -C $_shtab_ahriman_repo_sync_options ;;
|
||||||
|
repo-tree) _arguments -C $_shtab_ahriman_repo_tree_options ;;
|
||||||
|
repo-triggers) _arguments -C $_shtab_ahriman_repo_triggers_options ;;
|
||||||
|
repo-update) _arguments -C $_shtab_ahriman_repo_update_options ;;
|
||||||
|
report) _arguments -C $_shtab_ahriman_report_options ;;
|
||||||
|
search) _arguments -C $_shtab_ahriman_search_options ;;
|
||||||
|
setup) _arguments -C $_shtab_ahriman_setup_options ;;
|
||||||
|
shell) _arguments -C $_shtab_ahriman_shell_options ;;
|
||||||
|
sign) _arguments -C $_shtab_ahriman_sign_options ;;
|
||||||
|
status) _arguments -C $_shtab_ahriman_status_options ;;
|
||||||
|
status-update) _arguments -C $_shtab_ahriman_status_update_options ;;
|
||||||
|
sync) _arguments -C $_shtab_ahriman_sync_options ;;
|
||||||
|
update) _arguments -C $_shtab_ahriman_update_options ;;
|
||||||
|
user-add) _arguments -C $_shtab_ahriman_user_add_options ;;
|
||||||
|
user-list) _arguments -C $_shtab_ahriman_user_list_options ;;
|
||||||
|
user-remove) _arguments -C $_shtab_ahriman_user_remove_options ;;
|
||||||
|
version) _arguments -C $_shtab_ahriman_version_options ;;
|
||||||
|
web) _arguments -C $_shtab_ahriman_web_options ;;
|
||||||
|
esac
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typeset -A opt_args
|
||||||
|
_shtab_ahriman "$@"
|
16
docs/conf.py
16
docs/conf.py
@ -25,20 +25,10 @@ sys.path.insert(0, str(basedir))
|
|||||||
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
|
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
|
||||||
|
|
||||||
for module in (
|
for module in (
|
||||||
"aioauth_client",
|
|
||||||
"aiohttp",
|
|
||||||
"aiohttp.web",
|
|
||||||
"aiohttp.web_exceptions",
|
|
||||||
"aiohttp.web_response",
|
|
||||||
"aiohttp.web_urldispatcher",
|
|
||||||
"aiohttp_jinja2",
|
|
||||||
"aiohttp_security",
|
|
||||||
"aiohttp_session",
|
|
||||||
"aiohttp_session.cookie_storage",
|
|
||||||
"boto3",
|
|
||||||
"cryptography",
|
|
||||||
"pyalpm",
|
"pyalpm",
|
||||||
):
|
):
|
||||||
|
if module in sys.modules:
|
||||||
|
continue
|
||||||
sys.modules[module] = mock.Mock()
|
sys.modules[module] = mock.Mock()
|
||||||
|
|
||||||
|
|
||||||
@ -89,7 +79,7 @@ html_theme = "default" if on_rtd else "alabaster"
|
|||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
html_static_path = ["_static"]
|
html_static_path = []
|
||||||
|
|
||||||
add_module_names = False
|
add_module_names = False
|
||||||
|
|
||||||
|
@ -26,9 +26,11 @@ Base configuration settings.
|
|||||||
|
|
||||||
libalpm and AUR related configuration.
|
libalpm and AUR related configuration.
|
||||||
|
|
||||||
* ``database`` - path to pacman local database cache, string, required.
|
* ``database`` - path to pacman system database cache, string, required.
|
||||||
|
* ``mirror`` - package database mirror used by pacman for syncronization, string, required. This option supports standard pacman substitutions with ``$arch`` and ``$repo``. Note that the mentioned mirror should contain all repositories which are set by ``alpm.repositories`` option.
|
||||||
* ``repositories`` - list of pacman repositories, space separated list of strings, required.
|
* ``repositories`` - list of pacman repositories, space separated list of strings, required.
|
||||||
* ``root`` - root for alpm library, string, required.
|
* ``root`` - root for alpm library, string, required.
|
||||||
|
* ``use_ahriman_cache`` - use local pacman package cache instead of system one, boolean, required. With this option enabled you might want to refresh database periodically (available as additional flag for some subcommands).
|
||||||
|
|
||||||
``auth`` group
|
``auth`` group
|
||||||
--------------
|
--------------
|
||||||
@ -42,7 +44,7 @@ Base authorization settings. ``OAuth`` provider requires ``aioauth-client`` libr
|
|||||||
* ``max_age`` - parameter which controls both cookie expiration and token expiration inside the service, integer, optional, default is 7 days.
|
* ``max_age`` - parameter which controls both cookie expiration and token expiration inside the service, integer, optional, default is 7 days.
|
||||||
* ``oauth_provider`` - OAuth2 provider class name as is in ``aioauth-client`` (e.g. ``GoogleClient``, ``GithubClient`` etc), string, required in case if ``oauth`` is used.
|
* ``oauth_provider`` - OAuth2 provider class name as is in ``aioauth-client`` (e.g. ``GoogleClient``, ``GithubClient`` etc), string, required in case if ``oauth`` is used.
|
||||||
* ``oauth_scopes`` - scopes list for OAuth2 provider, which will allow retrieving user email (which is used for checking user permissions), e.g. ``https://www.googleapis.com/auth/userinfo.email`` for ``GoogleClient`` or ``user:email`` for ``GithubClient``, space separated list of strings, required in case if ``oauth`` is used.
|
* ``oauth_scopes`` - scopes list for OAuth2 provider, which will allow retrieving user email (which is used for checking user permissions), e.g. ``https://www.googleapis.com/auth/userinfo.email`` for ``GoogleClient`` or ``user:email`` for ``GithubClient``, space separated list of strings, required in case if ``oauth`` is used.
|
||||||
* ``salt`` - password hash salt, string, required in case if authorization enabled (automatically generated by ``create-user`` subcommand).
|
* ``salt`` - password hash salt, string, required in case if authorization enabled (automatically generated by ``user-add`` subcommand).
|
||||||
|
|
||||||
Authorized users are stored inside internal database, if any of external provides are used the password field for non-service users must be empty.
|
Authorized users are stored inside internal database, if any of external provides are used the password field for non-service users must be empty.
|
||||||
|
|
||||||
@ -57,6 +59,7 @@ Build related configuration. Group name can refer to architecture, e.g. ``build:
|
|||||||
* ``makepkg_flags`` - additional flags passed to ``makepkg`` command, space separated list of strings, optional.
|
* ``makepkg_flags`` - additional flags passed to ``makepkg`` command, space separated list of strings, optional.
|
||||||
* ``makechrootpkg_flags`` - additional flags passed to ``makechrootpkg`` command, space separated list of strings, optional.
|
* ``makechrootpkg_flags`` - additional flags passed to ``makechrootpkg`` command, space separated list of strings, optional.
|
||||||
* ``triggers`` - list of ``ahriman.core.triggers.Trigger`` class implementation (e.g. ``ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger``) which will be loaded and run at the end of processing, space separated list of strings, optional. You can also specify triggers by their paths, e.g. ``/usr/lib/python3.10/site-packages/ahriman/core/report/report.py.ReportTrigger``. Triggers are run in the order of mention.
|
* ``triggers`` - list of ``ahriman.core.triggers.Trigger`` class implementation (e.g. ``ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger``) which will be loaded and run at the end of processing, space separated list of strings, optional. You can also specify triggers by their paths, e.g. ``/usr/lib/python3.10/site-packages/ahriman/core/report/report.py.ReportTrigger``. Triggers are run in the order of mention.
|
||||||
|
* ``vcs_allowed_age`` - maximal age in seconds of the VCS packages before their version will be updated with its remote source, int, optional, default ``0``.
|
||||||
|
|
||||||
``repository`` group
|
``repository`` group
|
||||||
--------------------
|
--------------------
|
||||||
@ -75,6 +78,37 @@ Settings for signing packages or repository. Group name can refer to architectur
|
|||||||
* ``key`` - default PGP key, string, required. This key will also be used for database signing if enabled.
|
* ``key`` - default PGP key, string, required. This key will also be used for database signing if enabled.
|
||||||
* ``key_*`` settings - PGP key which will be used for specific packages, string, optional. For example, if there is ``key_yay`` option the specified key will be used for yay package and default key for others.
|
* ``key_*`` settings - PGP key which will be used for specific packages, string, optional. For example, if there is ``key_yay`` option the specified key will be used for yay package and default key for others.
|
||||||
|
|
||||||
|
``remote-pull`` group
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Remote git source synchronization settings. Unlike ``Upload`` triggers those triggers are used for PKGBUILD synchronization - fetch from remote repository PKGBUILDs before updating process.
|
||||||
|
|
||||||
|
It supports authorization; to do so you'd need to prefix the url with authorization part, e.g. ``https://key:token@github.com/arcan1s/ahriman.git``. It is highly recommended to use application tokens instead of your user authorization details.
|
||||||
|
|
||||||
|
* ``target`` - list of remote pull triggers to be used, space separated list of strings, optional, defaults to ``gitremote``. It must point to valid section (or to section with architecture), e.g. ``gitremote`` must point to either ``gitremote`` or ``gitremote:x86_64`` (the one with architecture has higher priority).
|
||||||
|
|
||||||
|
Remote pull trigger
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
* ``pull_url`` - url of the remote repository from which PKGBUILDs can be pulled before build process, string, required.
|
||||||
|
* ``pull_branch`` - branch of the remote repository from which PKGBUILDs can be pulled before build process, string, optional, default is ``master``.
|
||||||
|
|
||||||
|
``remote-push`` group
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Remote git source synchronization settings. Same as remote pull triggers those triggers are used for PKGBUILD synchronization - push updated PKGBUILDs to the remote repository after build process.
|
||||||
|
|
||||||
|
It supports authorization; to do so you'd need to prefix the url with authorization part, e.g. ``https://key:token@github.com/arcan1s/ahriman.git``. It is highly recommended to use application tokens instead of your user authorization details.
|
||||||
|
|
||||||
|
* ``target`` - list of remote push triggers to be used, space separated list of strings, optional, defaults to ``gitremote``. It must point to valid section (or to section with architecture), e.g. ``gitremote`` must point to either ``gitremote`` or ``gitremote:x86_64`` (the one with architecture has higher priority).
|
||||||
|
|
||||||
|
Remote push trigger
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
* ``commit_author`` - git commit author, string, optional. In case if not set, the git will generate author for you. Note, however, that in this case it will disclosure your hostname.
|
||||||
|
* ``push_url`` - url of the remote repository to which PKGBUILDs should be pushed after build process, string, required.
|
||||||
|
* ``push_branch`` - branch of the remote repository to which PKGBUILDs should be pushed after build process, string, optional, default is ``master``.
|
||||||
|
|
||||||
``report`` group
|
``report`` group
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
@ -82,7 +116,7 @@ Report generation settings.
|
|||||||
|
|
||||||
* ``target`` - list of reports to be generated, space separated list of strings, required. It must point to valid section (or to section with architecture), e.g. ``somerandomname`` must point to existing section, ``email`` must point to either ``email`` or ``email:x86_64`` (the one with architecture has higher priority).
|
* ``target`` - list of reports to be generated, space separated list of strings, required. It must point to valid section (or to section with architecture), e.g. ``somerandomname`` must point to existing section, ``email`` must point to either ``email`` or ``email:x86_64`` (the one with architecture has higher priority).
|
||||||
|
|
||||||
Type will be read from several ways:
|
Type will be read from several sources:
|
||||||
|
|
||||||
* In case if ``type`` option set inside the section, it will be used.
|
* In case if ``type`` option set inside the section, it will be used.
|
||||||
* Otherwise, it will look for type from section name removing architecture name.
|
* Otherwise, it will look for type from section name removing architecture name.
|
||||||
@ -147,7 +181,7 @@ Remote synchronization settings.
|
|||||||
|
|
||||||
* ``target`` - list of synchronizations to be used, space separated list of strings, required. It must point to valid section (or to section with architecture), e.g. ``somerandomname`` must point to existing section, ``github`` must point to one of ``github`` of ``github:x86_64`` (with architecture it has higher priority).
|
* ``target`` - list of synchronizations to be used, space separated list of strings, required. It must point to valid section (or to section with architecture), e.g. ``somerandomname`` must point to existing section, ``github`` must point to one of ``github`` of ``github:x86_64`` (with architecture it has higher priority).
|
||||||
|
|
||||||
Type will be read from several ways:
|
Type will be read from several sources:
|
||||||
|
|
||||||
* In case if ``type`` option set inside the section, it will be used.
|
* In case if ``type`` option set inside the section, it will be used.
|
||||||
* Otherwise, it will look for type from section name removing architecture name.
|
* Otherwise, it will look for type from section name removing architecture name.
|
||||||
@ -207,4 +241,5 @@ Web server settings. If any of ``host``/``port`` is not set, web integration wil
|
|||||||
* ``port`` - port to bind, int, optional.
|
* ``port`` - port to bind, int, optional.
|
||||||
* ``static_path`` - path to directory with static files, string, required.
|
* ``static_path`` - path to directory with static files, string, required.
|
||||||
* ``templates`` - path to templates directory, string, required.
|
* ``templates`` - path to templates directory, string, required.
|
||||||
|
* ``unix_socket`` - path to the listening unix socket, string, optional. If set, server will create the socket on the specified address which can (and will) be used by application. Note, that unlike usual host/port configuration, unix socket allows to perform requests without authorization.
|
||||||
* ``username`` - username to authorize in web service in order to update service status, string, required in case if authorization enabled.
|
* ``username`` - username to authorize in web service in order to update service status, string, required in case if authorization enabled.
|
||||||
|
354
docs/faq.rst
354
docs/faq.rst
@ -1,16 +1,17 @@
|
|||||||
|
|
||||||
FAQ
|
FAQ
|
||||||
===
|
===
|
||||||
|
|
||||||
General topics
|
General topics
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
What is the purpose of the project?
|
What is the purpose of the project
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
This project has been created in order to maintain self-hosted Arch Linux user repository without manual intervention - checking for updates and building packages.
|
This project has been created in order to maintain self-hosted Arch Linux user repository without manual intervention - checking for updates and building packages.
|
||||||
|
|
||||||
How do I install it?
|
How to install ahriman
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
TL;DR
|
TL;DR
|
||||||
|
|
||||||
@ -25,8 +26,8 @@ Long answer
|
|||||||
|
|
||||||
The idea is to install the package as usual, create working directory tree, create configuration for ``sudo`` and ``devtools``. Detailed description of the setup instruction can be found :doc:`here <setup>`.
|
The idea is to install the package as usual, create working directory tree, create configuration for ``sudo`` and ``devtools``. Detailed description of the setup instruction can be found :doc:`here <setup>`.
|
||||||
|
|
||||||
What does "architecture specific" mean? / How to configure for different architectures?
|
What does "architecture specific" mean / How to configure for different architectures
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Some sections can be configured per architecture. The service will merge architecture specific values into common settings. In order to specify settings for specific architecture you must point it in section name.
|
Some sections can be configured per architecture. The service will merge architecture specific values into common settings. In order to specify settings for specific architecture you must point it in section name.
|
||||||
|
|
||||||
@ -46,8 +47,8 @@ states that default build command is ``extra-x86_64-build``. But if there is sec
|
|||||||
|
|
||||||
the ``extra-i686-build`` command will be used for ``i686`` architecture.
|
the ``extra-i686-build`` command will be used for ``i686`` architecture.
|
||||||
|
|
||||||
How to use reporter/upload settings?
|
How to generate build reports
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Normally you probably like to generate only one report for the specific type, e.g. only one email report. In order to do it you will need to have the following configuration:
|
Normally you probably like to generate only one report for the specific type, e.g. only one email report. In order to do it you will need to have the following configuration:
|
||||||
|
|
||||||
@ -87,8 +88,8 @@ But for some cases you would like to have multiple different reports with the sa
|
|||||||
type = email
|
type = email
|
||||||
...
|
...
|
||||||
|
|
||||||
Okay, I've installed ahriman, how do I add new package?
|
How do I add new package
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
@ -101,8 +102,8 @@ Okay, I've installed ahriman, how do I add new package?
|
|||||||
sudo -u ahriman ahriman package-add ahriman
|
sudo -u ahriman ahriman package-add ahriman
|
||||||
sudo -u ahriman ahriman repo-update
|
sudo -u ahriman ahriman repo-update
|
||||||
|
|
||||||
AUR is fine, but I would like to create package from local PKGBUILD
|
How to build package from local PKGBUILD
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
TL;DR
|
TL;DR
|
||||||
|
|
||||||
@ -112,19 +113,91 @@ TL;DR
|
|||||||
|
|
||||||
Before using this command you will need to create local directory, put ``PKGBUILD`` there and generate ``.SRCINFO`` by using ``makepkg --printsrcinfo > .SRCINFO`` command. These packages will be stored locally and *will be ignored* during automatic update; in order to update the package you will need to run ``package-add`` command again.
|
Before using this command you will need to create local directory, put ``PKGBUILD`` there and generate ``.SRCINFO`` by using ``makepkg --printsrcinfo > .SRCINFO`` command. These packages will be stored locally and *will be ignored* during automatic update; in order to update the package you will need to run ``package-add`` command again.
|
||||||
|
|
||||||
But I just wanted to change PKGBUILD from AUR a bit!
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Well it is supported also.
|
How to fetch PKGBUILDs from remote repository
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
#. Clone sources from AUR.
|
For that purpose you could use ``RemotePullTrigger`` trigger. To do so you will need:
|
||||||
#. Make changes you would like to (e.g. edit ``PKGBUILD``, add external patches).
|
|
||||||
#. Run ``sudo -u ahriman ahriman patch-add /path/to/local/directory/with/PKGBUILD``.
|
#.
|
||||||
|
Append ``triggers`` option in ``build`` section with the following line:
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[build]
|
||||||
|
triggers = ahriman.core.gitremote.RemotePullTrigger
|
||||||
|
|
||||||
|
#.
|
||||||
|
Configure trigger as following:
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[remote-pull]
|
||||||
|
target = gitremote
|
||||||
|
|
||||||
|
[gitremote]
|
||||||
|
pull_url = https://github.com/username/repository
|
||||||
|
|
||||||
|
During the next application run it will fetch repository from the specified url and will try to find packages there which can be used as local sources.
|
||||||
|
|
||||||
|
How to push updated PKGBUILDs to remote repository
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
For that purpose you'd need to use another trigger called ``RemotePushTrigger``. Configure it as following:
|
||||||
|
|
||||||
|
#.
|
||||||
|
Append ``triggers`` option in ``build`` section with the trigger name:
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[build]
|
||||||
|
triggers = ahriman.core.gitremote.RemotePushTrigger
|
||||||
|
|
||||||
|
#.
|
||||||
|
Configure trigger as following:
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[remote-push]
|
||||||
|
target = gitremote
|
||||||
|
|
||||||
|
[gitremote]
|
||||||
|
push_url = https://github.com/username/repository
|
||||||
|
|
||||||
|
Unlike ``RemotePullTrigger`` trigger, the ``RemotePushTrigger`` more likely will require authorization. It is highly recommended to use application tokens for that instead of using your password (e.g. for Github you can generate tokens `here <https://github.com/settings/tokens>`_ with scope ``public_repo``). Authorization can be supplied by using authorization part of the url, e.g. ``https://key:token@github.com/username/repository``.
|
||||||
|
|
||||||
|
How to change PKGBUILDs before build
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Well it is supported also. The recommended way is to patch specific function, e.g. by running
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
sudo -u ahriman ahriman patch-add ahriman version
|
||||||
|
|
||||||
|
This command will prompt for new value of the PKGBUILD variable ``version``. You can also write it to file and read from it:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
sudo -u ahriman ahriman patch-add ahriman version version.patch
|
||||||
|
|
||||||
|
Alternatively you can create full-diff patches, which are calculated by using ``git diff`` from current PKGBUILD master branch:
|
||||||
|
|
||||||
|
#.
|
||||||
|
Clone sources from AUR.
|
||||||
|
#.
|
||||||
|
Make changes you would like to (e.g. edit ``PKGBUILD``, add external patches).
|
||||||
|
#.
|
||||||
|
Run command
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
sudo -u ahriman ahriman patch-set-add /path/to/local/directory/with/PKGBUILD
|
||||||
|
|
||||||
The last command will calculate diff from current tree to the ``HEAD`` and will store it locally. Patches will be applied on any package actions (e.g. it can be used for dependency management).
|
The last command will calculate diff from current tree to the ``HEAD`` and will store it locally. Patches will be applied on any package actions (e.g. it can be used for dependency management).
|
||||||
|
|
||||||
Hey, I would like to rebuild the official repository package
|
How to build package from official repository
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
So it is the same as adding any other package, but due to restrictions you must specify source explicitly, e.g.:
|
So it is the same as adding any other package, but due to restrictions you must specify source explicitly, e.g.:
|
||||||
|
|
||||||
@ -143,17 +216,17 @@ TL;DR
|
|||||||
|
|
||||||
sudo -u ahriman ahriman key-import ...
|
sudo -u ahriman ahriman key-import ...
|
||||||
|
|
||||||
How do I check if there are new commits for VCS packages?
|
How to update VCS packages
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Normally the service handles VCS packages correctly, but it requires additional dependencies:
|
Normally the service handles VCS packages correctly, however it requires additional dependencies:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
pacman -S breezy darcs mercurial subversion
|
pacman -S breezy darcs mercurial subversion
|
||||||
|
|
||||||
I would like to remove package because it is no longer needed/moved to official repositories
|
How to remove package
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
@ -163,8 +236,64 @@ Also, there is command ``repo-remove-unknown`` which checks packages in AUR and
|
|||||||
|
|
||||||
Remove commands also remove any package files (patches, caches etc).
|
Remove commands also remove any package files (patches, caches etc).
|
||||||
|
|
||||||
There is new major release of %library-name%, how do I rebuild packages?
|
How to sign repository
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Repository sign feature is available in several configurations. The recommended way is just to sign repository database file by single key instead of trying to sign each package. However, the steps are pretty same, just configuration is a bit differ. For more details about options kindly refer to :doc:`configuration reference <configuration>`.
|
||||||
|
|
||||||
|
#.
|
||||||
|
First you would need to create the key on your local machine:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
gpg --full-generate-key
|
||||||
|
|
||||||
|
This command will prompt you for several questions. Most of them may be left default, but you will need to fill real name and email address with some data. Because at the moment the service doesn't support passphrases, it must be left blank.
|
||||||
|
|
||||||
|
#.
|
||||||
|
The command above will generate key and print its hash, something like ``8BE91E5A773FB48AC05CC1EDBED105AED6246B39``. Copy it.
|
||||||
|
|
||||||
|
#.
|
||||||
|
Export your private key by using the hash above:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
gpg --export-secret-keys -a 8BE91E5A773FB48AC05CC1EDBED105AED6246B39 > repository-key.gpg
|
||||||
|
|
||||||
|
#.
|
||||||
|
|
||||||
|
Copy the specified key to the build machine (i.e. where the service is running).
|
||||||
|
|
||||||
|
#.
|
||||||
|
Import the specified key to the service user:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
sudo -u ahriman gpg --import repository-key.gpg
|
||||||
|
|
||||||
|
Don't forget to remove the key from filesystem after import.
|
||||||
|
|
||||||
|
#.
|
||||||
|
Change trust level to ``ultimate``:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
sudo -u ahriman gpg --edit-key 8BE91E5A773FB48AC05CC1EDBED105AED6246B39
|
||||||
|
|
||||||
|
The command above will drop you into gpg shell, in which you will need to type ``trust``, choose ``5 = I trust ultimately``, confirm and exit ``quit``.
|
||||||
|
|
||||||
|
#.
|
||||||
|
Proceed with service configuration according to the :doc:`configuration <configuration>`:
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[sign]
|
||||||
|
target = repository
|
||||||
|
key = 8BE91E5A773FB48AC05CC1EDBED105AED6246B39
|
||||||
|
|
||||||
|
|
||||||
|
How to rebuild packages after library update
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
TL;DR
|
TL;DR
|
||||||
|
|
||||||
@ -176,8 +305,8 @@ You can even rebuild the whole repository (which is particular useful in case if
|
|||||||
|
|
||||||
However, note that you do not need to rebuild repository in case if you just changed signing option, just use ``repo-sign`` command instead.
|
However, note that you do not need to rebuild repository in case if you just changed signing option, just use ``repo-sign`` command instead.
|
||||||
|
|
||||||
Hmm, I have packages built, but how can I use it?
|
How to install built packages
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Add the following lines to your ``pacman.conf``:
|
Add the following lines to your ``pacman.conf``:
|
||||||
|
|
||||||
@ -188,8 +317,8 @@ Add the following lines to your ``pacman.conf``:
|
|||||||
|
|
||||||
(You might need to add ``SigLevel`` option according to the pacman documentation.)
|
(You might need to add ``SigLevel`` option according to the pacman documentation.)
|
||||||
|
|
||||||
I would like to serve the repository
|
How to serve repository
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Easy. For example, nginx configuration (without SSL) will look like:
|
Easy. For example, nginx configuration (without SSL) will look like:
|
||||||
|
|
||||||
@ -226,7 +355,7 @@ Example of the status page configuration is the following (status service is usi
|
|||||||
Docker image
|
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 ``edge`` tag or ``latest`` for any tagged versions; otherwise you can use any version tag available.
|
We provide official images which can be found under ``arcan1s/ahriman`` repository. Docker image is being updated on each commit to master as well as on each version. If you would like to use last (probably unstable) build you can use ``edge`` tag or ``latest`` for any tagged versions; 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.:
|
The default action (in case if no arguments provided) is ``repo-update``. Basically the idea is to run container, e.g.:
|
||||||
|
|
||||||
@ -234,17 +363,17 @@ The default action (in case if no arguments provided) is ``repo-update``. Basica
|
|||||||
|
|
||||||
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
|
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.:
|
``--privileged`` flag is required to make mount possible inside container. In order to make data available outside of container, you would need to mount local (parent) directory inside container by using ``-v /path/to/local/repo:/var/lib/ahriman`` argument, where ``/path/to/local/repo`` is a path to repository on local machine. In addition, you can pass own configuration overrides by using the same ``-v`` flag, e.g.:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: 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
|
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman -v /path/to/overrides/overrides.ini:/etc/ahriman.ini.d/10-overrides.ini arcan1s/ahriman:latest
|
||||||
|
|
||||||
The action can be specified during run, e.g.:
|
The action can be specified during run, e.g.:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
docker run arcan1s/ahriman:latest package-add ahriman --now
|
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest package-add ahriman --now
|
||||||
|
|
||||||
For more details please refer to docker FAQ.
|
For more details please refer to docker FAQ.
|
||||||
|
|
||||||
@ -262,13 +391,25 @@ The following environment variables are supported:
|
|||||||
* ``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_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_USER`` - ahriman user, usually must not be overwritten, default is ``ahriman``.
|
* ``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.:
|
You can pass any of these variables by using ``-e`` argument, e.g.:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
docker run -e AHRIMAN_PORT=8080 arcan1s/ahriman:latest
|
docker run --privileged -e AHRIMAN_PORT=8080 -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
|
||||||
|
|
||||||
|
Daemon service
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
There is special ``daemon`` subcommand which emulates systemd timer and will perform repository update periodically:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest daemon
|
||||||
|
|
||||||
|
This command uses same rules as ``repo-update``, thus, e.g. requires ``--privileged`` flag.
|
||||||
|
|
||||||
Web service setup
|
Web service setup
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
@ -277,21 +418,29 @@ Well for that you would need to have web container instance running forever; it
|
|||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
docker run -p 8080:8080 -e AHRIMAN_PORT=8080 -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
|
docker run --privileged -p 8080:8080 -e AHRIMAN_PORT=8080 -e AHRIMAN_UNIX_SOCKET=/var/lib/ahriman/ahriman/ahriman-web.sock -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.
|
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.:
|
The ``AHRIMAN_UNIX_SOCKET`` variable is not required, however, highly recommended as it can be used for interprocess communications. If you set this variable you would like to be sure that this path is available outside of container if you are going to use multiple docker instances.
|
||||||
|
|
||||||
|
If you are using ``AHRIMAN_UNIX_SOCKET`` variable, for every next container run it has to be passed also, e.g.:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
docker run --privileged -e AHRIMAN_PORT=8080 --net=host -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
|
docker run --privileged -e AHRIMAN_UNIX_SOCKET=/var/lib/ahriman/ahriman/ahriman-web.sock -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
|
||||||
|
|
||||||
|
Otherwise, you would need to pass ``AHRIMAN_PORT`` and mount container network to the host system (``--net=host``), e.g.:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
docker run --privileged --net=host -e AHRIMAN_PORT=8080 -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
|
How to sync repository to another server
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
There are several choices:
|
There are several choices:
|
||||||
|
|
||||||
@ -320,8 +469,8 @@ There are several choices:
|
|||||||
|
|
||||||
After that just add ``/srv/repo`` to the ``pacman.conf`` as usual. You can also upload to S3 (e.g. ``Server = https://s3.eu-central-1.amazonaws.com/repository/x86_64``) or to Github (e.g. ``Server = https://github.com/ahriman/repository/releases/download/x86_64``).
|
After that just add ``/srv/repo`` to the ``pacman.conf`` as usual. You can also upload to S3 (e.g. ``Server = https://s3.eu-central-1.amazonaws.com/repository/x86_64``) or to Github (e.g. ``Server = https://github.com/ahriman/repository/releases/download/x86_64``).
|
||||||
|
|
||||||
How do I configure S3?
|
How to sync to S3
|
||||||
^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Install dependencies:
|
Install dependencies:
|
||||||
@ -379,8 +528,8 @@ How do I configure S3?
|
|||||||
region = eu-central-1
|
region = eu-central-1
|
||||||
secret_key = ...
|
secret_key = ...
|
||||||
|
|
||||||
How do I configure Github?
|
How to sync to Github releases
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Create a repository.
|
Create a repository.
|
||||||
@ -403,8 +552,8 @@ How do I configure Github?
|
|||||||
Reporting
|
Reporting
|
||||||
---------
|
---------
|
||||||
|
|
||||||
I would like to get report to email
|
How to report by email
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Install dependencies:
|
Install dependencies:
|
||||||
@ -430,8 +579,8 @@ I would like to get report to email
|
|||||||
sender = me@example.com
|
sender = me@example.com
|
||||||
user = me@example.com
|
user = me@example.com
|
||||||
|
|
||||||
I'm using synchronization to S3 and would like to generate index page
|
How to generate index page for S3
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Install dependencies:
|
Install dependencies:
|
||||||
@ -454,8 +603,8 @@ I'm using synchronization to S3 and would like to generate index page
|
|||||||
|
|
||||||
After these steps ``index.html`` file will be automatically synced to S3
|
After these steps ``index.html`` file will be automatically synced to S3
|
||||||
|
|
||||||
I would like to get messages to my telegram account/channel
|
How to post build report to telegram
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
#.
|
#.
|
||||||
It still requires additional dependencies:
|
It still requires additional dependencies:
|
||||||
@ -504,8 +653,8 @@ If you did everything fine you should receive the message with the next update.
|
|||||||
Web service
|
Web service
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Readme mentions web interface, how do I use it?
|
How to setup web service
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Install dependencies:
|
Install dependencies:
|
||||||
@ -525,8 +674,8 @@ Readme mentions web interface, how do I use it?
|
|||||||
#.
|
#.
|
||||||
Start the web service ``systemctl enable --now ahriman-web@x86_64``.
|
Start the web service ``systemctl enable --now ahriman-web@x86_64``.
|
||||||
|
|
||||||
I would like to limit user access to the status page
|
How to enable basic authorization
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Install dependencies 😊:
|
Install dependencies 😊:
|
||||||
@ -543,22 +692,44 @@ I would like to limit user access to the status page
|
|||||||
[auth]
|
[auth]
|
||||||
target = configuration
|
target = configuration
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Create user for the service:
|
In order to provide access for reporting from application instances you can (recommended way) use unix sockets by configuring the following (note, that it requires ``python-requests-unixsocket`` package to be installed):
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[web]
|
||||||
|
unix_socket = /var/lib/ahriman/ahriman-web.sock
|
||||||
|
|
||||||
|
This socket path must be available for web service instance and must be available for application instances (e.g. in case if you are using docker container, see above, you need to be sure that the socket is passed to the root filesystem).
|
||||||
|
|
||||||
|
By the way, unix socket variable will be automatically set in case if ``--web-unix-socket`` argument is supplied to the ``setup`` subcommand.
|
||||||
|
|
||||||
|
Alternatively, you need to create user for the service:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
sudo -u ahriman ahriman user-add --as-service -r write api
|
sudo -u ahriman ahriman user-add -r full api
|
||||||
|
|
||||||
This command will ask for the password, just type it in stdin; *do not* leave the field blank, user will not be able to authorize.
|
This command will ask for the password, just type it in stdin; *do not* leave the field blank, user will not be able to authorize, and finally configure the application:
|
||||||
|
|
||||||
#.
|
.. code-block:: ini
|
||||||
Create end-user ``sudo -u ahriman ahriman user-add -r write my-first-user`` with password.
|
|
||||||
|
|
||||||
#. Restart web service ``systemctl restart ahriman-web@x86_64``.
|
[web]
|
||||||
|
username = api
|
||||||
|
password = pa55w0rd
|
||||||
|
|
||||||
I would like to use OAuth
|
#.
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
Create end-user with password:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
sudo -u ahriman ahriman user-add -r full my-first-user
|
||||||
|
|
||||||
|
#.
|
||||||
|
Restart web service ``systemctl restart ahriman-web@x86_64``.
|
||||||
|
|
||||||
|
How to enable OAuth authorization
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Create OAuth web application, download its ``client_id`` and ``client_secret``.
|
Create OAuth web application, download its ``client_id`` and ``client_secret``.
|
||||||
@ -589,12 +760,19 @@ I would like to use OAuth
|
|||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
sudo -u ahriman ahriman user-add --as-service -r write api
|
sudo -u ahriman ahriman user-add --as-service -r full api
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Create end-user ``sudo -u ahriman ahriman user-add -r write my-first-user``. When it will ask for the password leave it blank.
|
Create end-user:
|
||||||
|
|
||||||
#. Restart web service ``systemctl restart ahriman-web@x86_64``.
|
.. code-block:: shell
|
||||||
|
|
||||||
|
sudo -u ahriman ahriman user-add -r full my-first-user
|
||||||
|
|
||||||
|
When it will ask for the password leave it blank.
|
||||||
|
|
||||||
|
#.
|
||||||
|
Restart web service ``systemctl restart ahriman-web@x86_64``.
|
||||||
|
|
||||||
Backup and restore
|
Backup and restore
|
||||||
------------------
|
------------------
|
||||||
@ -614,7 +792,7 @@ The service provides several commands aim to do easy repository backup and resto
|
|||||||
Copy created archive from source server ``server1.example.com`` to target ``server2.example.com``.
|
Copy created archive from source server ``server1.example.com`` to target ``server2.example.com``.
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Install ahriman as usual on the target server ``server2.example.com`` if you didn't yet.
|
Install package as usual on the target server ``server2.example.com`` if you didn't yet.
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Extract archive e.g. by using subcommand:
|
Extract archive e.g. by using subcommand:
|
||||||
@ -638,51 +816,55 @@ Other topics
|
|||||||
How does it differ from %another-manager%?
|
How does it differ from %another-manager%?
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Short answer - I do not know.
|
Short answer - I do not know. Also for some references credits to `Alad <https://github.com/AladW>`_, he `did <https://wiki.archlinux.org/title/User:Alad/Local_repo_tools>`_ really good investigation of existing alternatives.
|
||||||
|
|
||||||
|
`arch-repo-manager <https://github.com/Martchus/arch-repo-manager>`_
|
||||||
|
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
|
Looks actually pretty good, in case if I would find it, I would probably didn't start this project, most of features (like web interface or additional helpers) are already implemented or planned to be. However, this project seems to be at early alpha stage (as for Nov 2022), written in C++ (not pro or con) and misses code documentation.
|
||||||
|
|
||||||
`archrepo2 <https://github.com/lilydjwg/archrepo2>`_
|
`archrepo2 <https://github.com/lilydjwg/archrepo2>`_
|
||||||
""""""""""""""""""""""""""""""""""""""""""""""""""""
|
""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
Don't know, haven't tried it. But it lacks of documentation at least.
|
Don't know, haven't tried it. But it lacks of documentation at least.
|
||||||
|
|
||||||
* Web interface.
|
* ``ahriman`` has web interface.
|
||||||
* No synchronization and reporting.
|
* ``archrepo2`` doesn't have synchronization and reporting.
|
||||||
* ``archrepo2`` actively uses direct shell calls and ``yaourt`` components.
|
* ``archrepo2`` actively uses direct shell calls and ``yaourt`` components.
|
||||||
* It has constantly running process instead of timer process (it is not pro or con).
|
* ``archrepo2`` has constantly running process instead of timer process (it is not pro or con).
|
||||||
|
|
||||||
`repoctl <https://github.com/cassava/repoctl>`_
|
`repoctl <https://github.com/cassava/repoctl>`_
|
||||||
"""""""""""""""""""""""""""""""""""""""""""""""
|
"""""""""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
* Web interface.
|
* ``ahriman`` has web interface.
|
||||||
* No reporting.
|
* ``repoctl`` does not have reporting feature.
|
||||||
* Local packages and patches support.
|
* ``repoctl`` does not support local packages and patches.
|
||||||
* Some actions are not fully automated (e.g. package update still requires manual intervention for the build itself).
|
* Some actions are not fully automated in ``repoctl`` (e.g. package update still requires manual intervention for the build itself).
|
||||||
* ``repoctl`` has better AUR interaction features. With colors!
|
* ``repoctl`` has better AUR interaction features. With colors!
|
||||||
* ``repoctl`` has much easier configuration and even completion.
|
* ``repoctl`` has much easier configuration and even completion.
|
||||||
* ``repoctl`` is able to store old packages.
|
* ``repoctl`` is able to store old packages.
|
||||||
* Ability to host repository from same command vs external services (e.g. nginx) in ``ahriman``.
|
* Ability to host repository from same command in ``repoctl`` vs external services (e.g. nginx) in ``ahriman``.
|
||||||
|
|
||||||
`repo-scripts <https://github.com/arcan1s/repo-scripts>`_
|
`repo-scripts <https://github.com/arcan1s/repo-scripts>`_
|
||||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
Though originally I've created ahriman by trying to improve the project, it still lacks a lot of features:
|
Though originally I've created ahriman by trying to improve the project, it still lacks a lot of features:
|
||||||
|
|
||||||
* Web interface.
|
* ``ahriman`` has web interface.
|
||||||
* Better reporting with template support.
|
* ``ahriman`` has better reporting with template support.
|
||||||
* Synchronization features (there was only ``rsync`` based).
|
* ``ahriman`` has more synchronization features (there was only ``rsync`` based).
|
||||||
* Local packages and patches support.
|
* ``ahriman`` supports local packages and patches.
|
||||||
* No dependency management.
|
* ``repo-scripts`` doesn't have dependency management.
|
||||||
* And so on.
|
|
||||||
|
|
||||||
``repo-scripts`` also have bad architecture and bad quality code and uses out-of-dated ``yaourt`` and ``package-query``.
|
...and so on. ``repo-scripts`` also has bad architecture and bad quality code and uses out-of-dated ``yaourt`` and ``package-query``.
|
||||||
|
|
||||||
`toolbox <https://github.com/chaotic-aur/toolbox>`_
|
`toolbox <https://github.com/chaotic-aur/toolbox>`_
|
||||||
"""""""""""""""""""""""""""""""""""""""""""""""""""
|
"""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
It is automation tools for ``repoctl`` mentioned above. Except for using shell it looks pretty cool and also offers some additional features like patches, remote synchronization (isn't it?) and reporting.
|
It is automation tools for ``repoctl`` mentioned above. Except for using shell it looks pretty cool and also offers some additional features like patches, remote synchronization (isn't it?) and reporting.
|
||||||
|
|
||||||
I would like to check service logs
|
How to check service logs
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
By default, the service writes logs to ``/dev/log`` which can be accessed by using ``journalctl`` command (logs are written to the journal of the user under which command is run).
|
By default, the service writes logs to ``/dev/log`` which can be accessed by using ``journalctl`` command (logs are written to the journal of the user under which command is run).
|
||||||
|
|
||||||
|
@ -16,6 +16,13 @@ Features
|
|||||||
* Triggers for repository updates, e.g. synchronization to remote services (rsync, s3 and github) and report generation (email, html, telegram).
|
* Triggers for repository updates, e.g. synchronization to remote services (rsync, s3 and github) and report generation (email, html, telegram).
|
||||||
* Repository status interface with optional authorization and control options.
|
* Repository status interface with optional authorization and control options.
|
||||||
|
|
||||||
|
Live demos
|
||||||
|
----------
|
||||||
|
|
||||||
|
* `Build status page <https://ahriman-demo.arcanis.me>`_. You can login as ``demo`` user by using ``demo`` password. Note, however, you will not be able to run tasks.
|
||||||
|
* `Repository index <http://repo.arcanis.me/x86_64/index.html>`_.
|
||||||
|
* `Telegram feed <https://t.me/arcanisrepo>`_.
|
||||||
|
|
||||||
Contents
|
Contents
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ Initial setup
|
|||||||
#.
|
#.
|
||||||
Change settings if required, see :doc:`configuration reference <configuration>` for more details.
|
Change settings if required, see :doc:`configuration reference <configuration>` for more details.
|
||||||
#.
|
#.
|
||||||
TL;DR:
|
Perform initial setup:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
@ -67,6 +67,8 @@ Initial setup
|
|||||||
echo 'ahriman ALL=(ALL) NOPASSWD: CARCHBUILD_CMD' | tee -a /etc/sudoers.d/ahriman
|
echo 'ahriman ALL=(ALL) NOPASSWD: CARCHBUILD_CMD' | tee -a /etc/sudoers.d/ahriman
|
||||||
chmod 400 /etc/sudoers.d/ahriman
|
chmod 400 /etc/sudoers.d/ahriman
|
||||||
|
|
||||||
|
This command supports several arguments, kindly refer to its help message.
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Start and enable ``ahriman@.timer`` via ``systemctl``:
|
Start and enable ``ahriman@.timer`` via ``systemctl``:
|
||||||
|
|
||||||
|
@ -1,12 +1,79 @@
|
|||||||
Triggers
|
Triggers
|
||||||
========
|
========
|
||||||
|
|
||||||
The package provides ability to write custom extensions which will be run on (the most) actions, e.g. after updates. By default ahriman provides two types of extensions - reporting and files uploading. Each extension must derive from the ``ahriman.core.triggers.Trigger`` class and implement ``run`` method
|
The package provides ability to write custom extensions which will be run on (the most) actions, e.g. after updates. By default ahriman provides three types of extensions - reporting, files uploading and PKGBUILD syncronization. Each extension must derive from the ``ahriman.core.triggers.Trigger`` class and should implement at least one of the abstract methods:
|
||||||
|
|
||||||
|
* ``on_result`` - trigger action which will be called after build process, the build result and the list of repository packages will be supplied as arguments.
|
||||||
|
* ``on_start`` - trigger action which will be called right before the start of the application process.
|
||||||
|
* ``on_stop`` - action which will be called right before the exit.
|
||||||
|
|
||||||
|
Note, it isn't required to implement all of those methods (or even one of them), however, it is highly recommended to avoid trigger actions in ``__init__`` method as it will be run on any application start (e.g. even if you are just searching in AUR).
|
||||||
|
|
||||||
|
Built-in triggers
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
For the configuration details and settings explanation kindly refer to the :doc:`documentation <configuration>`.
|
||||||
|
|
||||||
|
``ahriman.core.gitremote.RemotePullTrigger``
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This trigger will be called before any action (``on_start``) and pulls remote PKGBUILD repository locally; after that it copies found PKGBUILDs from the cloned repository to the local cache. It is useful in case if you have patched PGKBUILDs (or even missing in AUR) which you would like to use for package building and, technically, just simplifies the local package building.
|
||||||
|
|
||||||
|
In order to update those packages you would need to clone your repository separately, make changes in PKGBUILD (e.g. bump version and update checksums), commit them and push back. On the next ahriman's repository update, it will pull changes you committed and will perform package update.
|
||||||
|
|
||||||
|
``ahriman.core.gitremote.RemotePushTrigger``
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This trigger will be called right after build process (``on_result``). It will pick PKGBUILDs for the updated packages, pull them (together with any other files) and commit and push changes to remote repository. No real use cases, but the most of user repositories do it.
|
||||||
|
|
||||||
|
``ahriman.core.report.ReportTrigger``
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Trigger which can be used for reporting. It implements ``on_result`` method and thus being called on each build update and generates report (e.g. html, telegram etc) according to the current settings.
|
||||||
|
|
||||||
|
``ahriman.core.upload.UploadTrigger``
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This trigger takes build result (``on_result``) and performs syncing of the local packages to the remote mirror (e.g. S3 or just by rsync).
|
||||||
|
|
||||||
|
Context variables
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
By default, only configuration and architecture are passed to triggers. However, some triggers might want to have access to other high-level wrappers. In order to provide such ability and avoid (double) initialization, the service provides a global context variables, which can be accessed from ``ahriman.core`` package:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from ahriman.core import context
|
||||||
|
|
||||||
|
ctx = context.get()
|
||||||
|
|
||||||
|
Just because context is wrapped inside ``contexvars.ContextVar``, you need to explicitly extract variable by ``get()`` method. Later you can extract any variable if it is set, e.g.:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from ahriman.core.database import SQLite
|
||||||
|
from ahriman.models.context_key import ContextKey
|
||||||
|
|
||||||
|
database = ctx.get(ContextKey("database", SQLite))
|
||||||
|
|
||||||
|
In order to provide typed API, all variables are stored together with their type. The ``get(ContextKey)`` method will throw ``KeyError`` in case if key is missing. Alternatively you can set your own variable inside context:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
ctx.set(ContextKey("answer", int), 42)
|
||||||
|
context.set(ctx)
|
||||||
|
|
||||||
|
Note, however, that there are several limitations:
|
||||||
|
|
||||||
|
* Context variables are immutable, thus you cannot override value if the key already presented.
|
||||||
|
* The ``return_type`` of ``ContextKey`` should match the value type, otherwise exception will be thrown.
|
||||||
|
|
||||||
|
The ``context`` also implements collection methods such as ``__iter__`` and ``__len__``.
|
||||||
|
|
||||||
Trigger example
|
Trigger example
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Lets consider example of reporting trigger (e.g. `slack <https://slack.com/>`_, which provides easy HTTP API for integration triggers).
|
Lets consider example of reporting trigger (e.g. `slack <https://slack.com/>`_, which provides easy HTTP API for integration triggers).gre
|
||||||
|
|
||||||
In order to post message to slack we will need a specific trigger url (something like ``https://hooks.slack.com/services/company_id/trigger_id``), channel (e.g. ``#archrepo``) and username (``repo-bot``).
|
In order to post message to slack we will need a specific trigger url (something like ``https://hooks.slack.com/services/company_id/trigger_id``), channel (e.g. ``#archrepo``) and username (``repo-bot``).
|
||||||
|
|
||||||
@ -49,12 +116,12 @@ Obviously you can implement the specified method in class, but for guide purpose
|
|||||||
self.channel = configuration.get("slack", "channel")
|
self.channel = configuration.get("slack", "channel")
|
||||||
self.username = configuration.get("slack", "username")
|
self.username = configuration.get("slack", "username")
|
||||||
|
|
||||||
def run(self, result, packages):
|
def on_result(self, result, packages):
|
||||||
notify(result, self.slack_url, self.channel, self.username)
|
notify(result, self.slack_url, self.channel, self.username)
|
||||||
|
|
||||||
Setup the trigger
|
Setup the trigger
|
||||||
-----------------
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
First, put the trigger in any path it can be exported, e.g. by packing the resource into python package (which will lead to import path as ``package.slack_reporter.SlackReporter``) or just put file somewhere it can be accessed by application (e.g. ``/usr/local/lib/slack_reporter.py.SlackReporter``.
|
First, put the trigger in any path it can be exported, e.g. by packing the resource into python package (which will lead to import path as ``package.slack_reporter.SlackReporter``) or just put file somewhere it can be accessed by application (e.g. ``/usr/local/lib/slack_reporter.py.SlackReporter``).
|
||||||
|
|
||||||
After that run application as usual and receive notification in your slack channel.
|
After that run application as usual and receive notification in your slack channel.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Maintainer: Evgeniy Alekseev
|
# Maintainer: Evgeniy Alekseev
|
||||||
|
|
||||||
pkgname='ahriman'
|
pkgname='ahriman'
|
||||||
pkgver=2.2.1
|
pkgver=2.5.2
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="ArcH linux ReposItory MANager"
|
pkgdesc="ArcH linux ReposItory MANager"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
@ -20,6 +20,7 @@ optdepends=('breezy: -bzr packages support'
|
|||||||
'python-aiohttp-session: web server with authorization'
|
'python-aiohttp-session: web server with authorization'
|
||||||
'python-boto3: sync to s3'
|
'python-boto3: sync to s3'
|
||||||
'python-cryptography: web server with authorization'
|
'python-cryptography: web server with authorization'
|
||||||
|
'python-requests-unixsocket: client report to web server by unix socket'
|
||||||
'python-jinja: html report generation'
|
'python-jinja: html report generation'
|
||||||
'rsync: sync by using rsync'
|
'rsync: sync by using rsync'
|
||||||
'subversion: -svn packages support')
|
'subversion: -svn packages support')
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
Description=ArcH linux ReposItory MANager (%I architecture)
|
Description=ArcH linux ReposItory MANager (%I architecture)
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=/usr/bin/ahriman --architecture %i update
|
ExecStart=/usr/bin/ahriman --architecture %i repo-update --refresh
|
||||||
User=ahriman
|
User=ahriman
|
||||||
Group=ahriman
|
Group=ahriman
|
@ -5,8 +5,10 @@ database = /var/lib/ahriman/ahriman.db
|
|||||||
|
|
||||||
[alpm]
|
[alpm]
|
||||||
database = /var/lib/pacman
|
database = /var/lib/pacman
|
||||||
|
mirror = https://geo.mirror.pkgbuild.com/$repo/os/$arch
|
||||||
repositories = core extra community multilib
|
repositories = core extra community multilib
|
||||||
root = /
|
root = /
|
||||||
|
use_ahriman_cache = yes
|
||||||
|
|
||||||
[auth]
|
[auth]
|
||||||
target = disabled
|
target = disabled
|
||||||
@ -22,6 +24,7 @@ ignore_packages =
|
|||||||
makechrootpkg_flags =
|
makechrootpkg_flags =
|
||||||
makepkg_flags = --nocolor --ignorearch
|
makepkg_flags = --nocolor --ignorearch
|
||||||
triggers = ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger
|
triggers = ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger
|
||||||
|
vcs_allowed_age = 604800
|
||||||
|
|
||||||
[repository]
|
[repository]
|
||||||
name = aur-clone
|
name = aur-clone
|
||||||
|
@ -20,11 +20,11 @@ formatter = syslog_format
|
|||||||
args = ("/dev/log",)
|
args = ("/dev/log",)
|
||||||
|
|
||||||
[formatter_generic_format]
|
[formatter_generic_format]
|
||||||
format = [%(levelname)s %(asctime)s] [%(threadName)s] [%(name)s]: %(message)s
|
format = [%(levelname)s %(asctime)s] [%(name)s]: %(message)s
|
||||||
datefmt =
|
datefmt =
|
||||||
|
|
||||||
[formatter_syslog_format]
|
[formatter_syslog_format]
|
||||||
format = [%(levelname)s] [%(threadName)s] [%(name)s]: %(message)s
|
format = [%(levelname)s] [%(name)s]: %(message)s
|
||||||
datefmt =
|
datefmt =
|
||||||
|
|
||||||
[logger_root]
|
[logger_root]
|
||||||
|
@ -12,35 +12,56 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="container">
|
{% include "utils/bootstrap-scripts.jinja2" %}
|
||||||
<h1>ahriman
|
|
||||||
<img id="badge-version" src="https://img.shields.io/badge/version-unknown-informational" alt="unknown">
|
|
||||||
<img id="badge-repository" src="https://img.shields.io/badge/repository-unknown-informational" alt="unknown">
|
|
||||||
<img id="badge-architecture" src="https://img.shields.io/badge/architecture-unknown-informational" alt="unknown">
|
|
||||||
<img id="badge-status" src="https://img.shields.io/badge/service%20status-unknown-inactive" alt="unknown">
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div id="toolbar">
|
<h1 id="badge-repository">ahriman</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="alert-placeholder" class="toast-container p3 top-0 start-50 translate-middle-x"></div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div id="toolbar" class="dropdown">
|
||||||
|
<a id="badge-status" tabindex="0" role="button" class="btn btn-outline-secondary" data-bs-toggle="popover" data-bs-trigger="focus" data-bs-content="no run data"><i class="bi bi-info-circle"></i></a>
|
||||||
|
|
||||||
{% if not auth.enabled or auth.username is not none %}
|
{% if not auth.enabled or auth.username is not none %}
|
||||||
<button id="add-btn" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#add-form" hidden>
|
<button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
<i class="bi bi-plus"></i> add
|
<i class="bi bi-box"></i> packages
|
||||||
</button>
|
</button>
|
||||||
<button id="update-btn" class="btn btn-secondary" onclick="updatePackages()" disabled hidden>
|
<ul class="dropdown-menu">
|
||||||
<i class="bi bi-play"></i> update
|
<li>
|
||||||
</button>
|
<button id="package-add-btn" class="btn dropdown-item" data-bs-toggle="modal" data-bs-target="#package-add-modal" hidden>
|
||||||
<button id="remove-btn" class="btn btn-danger" onclick="removePackages()" disabled hidden>
|
<i class="bi bi-plus"></i> add
|
||||||
<i class="bi bi-trash"></i> remove
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button id="package-update-btn" class="btn dropdown-item" onclick="updatePackages()" hidden>
|
||||||
|
<i class="bi bi-play"></i> update
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button id="package-rebuild-btn" class="btn dropdown-item" data-bs-toggle="modal" data-bs-target="#package-rebuild-modal" hidden>
|
||||||
|
<i class="bi bi-arrow-clockwise"></i> rebuild
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button id="package-remove-btn" class="btn dropdown-item" onclick="removePackages()" disabled hidden>
|
||||||
|
<i class="bi bi-trash"></i> remove
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<button id="key-import-btn" type="button" class="btn btn-info" data-bs-toggle="modal" data-bs-target="#key-import-modal" hidden>
|
||||||
|
<i class="bi bi-key"></i> import key
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button class="btn btn-secondary" onclick="reload()">
|
|
||||||
|
<button type="button" class="btn btn-secondary" onclick="reload()">
|
||||||
<i class="bi bi-arrow-clockwise"></i> reload
|
<i class="bi bi-arrow-clockwise"></i> reload
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table id="packages" class="table table-striped table-hover"
|
<table id="packages" class="table table-striped table-hover"
|
||||||
data-click-to-select="true"
|
|
||||||
data-export-options='{"fileName": "packages"}'
|
data-export-options='{"fileName": "packages"}'
|
||||||
data-page-list="[10, 25, 50, 100, all]"
|
data-page-list="[10, 25, 50, 100, all]"
|
||||||
data-page-size="10"
|
data-page-size="10"
|
||||||
@ -76,25 +97,29 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<footer class="d-flex flex-wrap justify-content-between align-items-center border-top">
|
<footer class="d-flex flex-wrap justify-content-between align-items-center border-top">
|
||||||
<ul class="nav">
|
<ul class="nav">
|
||||||
<li><a class="nav-link" href="https://github.com/arcan1s/ahriman" title="sources">ahriman</a></li>
|
<li><a id="badge-version" class="nav-link" href="https://github.com/arcan1s/ahriman" title="sources"><i class="bi bi-github"></i> ahriman</a></li>
|
||||||
<li><a class="nav-link" href="https://github.com/arcan1s/ahriman/releases" title="releases list">releases</a></li>
|
<li><a class="nav-link" href="https://github.com/arcan1s/ahriman/releases" title="releases list">releases</a></li>
|
||||||
<li><a class="nav-link" href="https://github.com/arcan1s/ahriman/issues" title="issues tracker">report a bug</a></li>
|
<li><a class="nav-link" href="https://github.com/arcan1s/ahriman/issues" title="issues tracker">report a bug</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{% if index_url is not none %}
|
{% if index_url is not none %}
|
||||||
<ul class="nav">
|
<ul class="nav">
|
||||||
<li><a class="nav-link" href="{{ index_url }}" title="repo index">repo index</a></li>
|
<li><a class="nav-link" href="{{ index_url }}" title="repo index"><i class="bi bi-house"></i> repo index</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if auth.enabled %}
|
{% if auth.enabled %}
|
||||||
{% if auth.username is none %}
|
<ul class="nav">
|
||||||
{{ auth.control|safe }}
|
{% if auth.username is none %}
|
||||||
{% else %}
|
<li>{{ auth.control|safe }}</li>
|
||||||
<form action="/api/v1/logout" method="post">
|
{% else %}
|
||||||
<button class="btn btn-link" style="text-decoration: none">logout ({{ auth.username }})</button>
|
<li>
|
||||||
</form>
|
<form action="/api/v1/logout" method="post">
|
||||||
{% endif %}
|
<button class="btn btn-link" style="text-decoration: none"><i class="bi bi-box-arrow-right"></i> logout ({{ auth.username }})</button>
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
@ -103,12 +128,13 @@
|
|||||||
{% include "build-status/login-modal.jinja2" %}
|
{% include "build-status/login-modal.jinja2" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% include "utils/bootstrap-scripts.jinja2" %}
|
{% include "build-status/alerts.jinja2" %}
|
||||||
|
|
||||||
{% include "build-status/failed-modal.jinja2" %}
|
|
||||||
{% include "build-status/success-modal.jinja2" %}
|
|
||||||
|
|
||||||
{% include "build-status/package-add-modal.jinja2" %}
|
{% include "build-status/package-add-modal.jinja2" %}
|
||||||
|
{% include "build-status/package-rebuild-modal.jinja2" %}
|
||||||
|
{% include "build-status/key-import-modal.jinja2" %}
|
||||||
|
|
||||||
|
{% include "build-status/package-info-modal.jinja2" %}
|
||||||
|
|
||||||
{% include "build-status/table.jinja2" %}
|
{% include "build-status/table.jinja2" %}
|
||||||
|
|
||||||
|
45
package/share/ahriman/templates/build-status/alerts.jinja2
Normal file
45
package/share/ahriman/templates/build-status/alerts.jinja2
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<script>
|
||||||
|
const alertPlaceholder = $("#alert-placeholder");
|
||||||
|
|
||||||
|
function createAlert(title, message, clz) {
|
||||||
|
const wrapper = document.createElement("div");
|
||||||
|
wrapper.classList.add("toast", clz);
|
||||||
|
wrapper.role = "alert";
|
||||||
|
wrapper.ariaLive = "assertive";
|
||||||
|
wrapper.ariaAtomic = "true";
|
||||||
|
wrapper.style.width = "500px"; // 500px is default modal size
|
||||||
|
|
||||||
|
const header = document.createElement("div");
|
||||||
|
header.classList.add("toast-header");
|
||||||
|
header.innerHTML = `<strong class="me-auto">${safe(title)}</strong> <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="close"></button>`;
|
||||||
|
wrapper.appendChild(header);
|
||||||
|
|
||||||
|
const body = document.createElement("div");
|
||||||
|
body.classList.add("toast-body", "text-bg-light");
|
||||||
|
body.innerText = message;
|
||||||
|
wrapper.appendChild(body);
|
||||||
|
|
||||||
|
alertPlaceholder.append(wrapper);
|
||||||
|
const toast = new bootstrap.Toast(wrapper);
|
||||||
|
wrapper.addEventListener("hidden.bs.toast", () => {
|
||||||
|
wrapper.remove(); // bootstrap doesn't remove elements
|
||||||
|
reload();
|
||||||
|
});
|
||||||
|
toast.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function showFailure(title, description, jqXHR, errorThrown) {
|
||||||
|
let details;
|
||||||
|
try {
|
||||||
|
details = $.parseJSON(jqXHR.responseText).error; // execution handler json error response
|
||||||
|
} catch (_) {
|
||||||
|
details = errorThrown;
|
||||||
|
}
|
||||||
|
createAlert(title, description(details), "text-bg-danger");
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSuccess(title, description) {
|
||||||
|
createAlert(title, description, "text-bg-success");
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
@ -1,28 +0,0 @@
|
|||||||
<div id="failed-form" tabindex="-1" role="dialog" class="modal fade">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header bg-danger">
|
|
||||||
<h4 class="modal-title">failed</h4>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<p>Packages update has failed.</p>
|
|
||||||
<p id="error-details"></p>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const failedForm = $("#failed-form");
|
|
||||||
const errorDetails = $("#error-details");
|
|
||||||
failedForm.on("hidden.bs.modal", () => { reload(); });
|
|
||||||
|
|
||||||
function showFailure(details) {
|
|
||||||
errorDetails.text(details);
|
|
||||||
failedForm.modal("show");
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -0,0 +1,93 @@
|
|||||||
|
<div id="key-import-modal" tabindex="-1" role="dialog" class="modal fade">
|
||||||
|
<div class="modal-dialog modal-xl" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form id="key-import-form" onsubmit="return false">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Import key from PGP server</h4>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="key-fingerprint-input" class="col-sm-2 col-form-label">fingerprint</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input id="key-fingerprint-input" type="text" class="form-control" placeholder="PGP key fingerprint" name="key" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="key-server-input" class="col-sm-2 col-form-label">key server</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input id="key-server-input" type="text" class="form-control" placeholder="PGP key server" name="server" value="keyserver.ubuntu.com" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-sm-2"></div>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<pre class="language-less"><samp id="key-body-input" class="pre-scrollable language-less"></samp><button id="key-copy-btn" type="button" class="btn language-less" onclick="copyPgpKey()"><i class="bi bi-clipboard"></i> copy</button></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="submit" class="btn btn-primary" onclick="importPgpKey()"><i class="bi bi-play"></i> import</button>
|
||||||
|
<button type="submit" class="btn btn-success" onclick="fetchPgpKey()"><i class="bi bi-arrow-clockwise"></i> fetch</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const keyImportModal = $("#key-import-modal");
|
||||||
|
const keyImportForm = $("#key-import-form");
|
||||||
|
keyImportModal.on("hidden.bs.modal", () => {
|
||||||
|
keyBodyInput.text("");
|
||||||
|
keyImportForm.trigger("reset");
|
||||||
|
});
|
||||||
|
|
||||||
|
const keyBodyInput = $("#key-body-input");
|
||||||
|
const keyCopyButton = $("#key-copy-btn");
|
||||||
|
|
||||||
|
const keyFingerprintInput = $("#key-fingerprint-input");
|
||||||
|
const keyServerInput = $("#key-server-input");
|
||||||
|
|
||||||
|
async function copyPgpKey() {
|
||||||
|
const logs = keyBodyInput.text();
|
||||||
|
await copyToClipboard(logs, keyCopyButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchPgpKey() {
|
||||||
|
const key = keyFingerprintInput.val();
|
||||||
|
const server = keyServerInput.val();
|
||||||
|
|
||||||
|
if (key && server) {
|
||||||
|
$.ajax({
|
||||||
|
url: "/api/v1/service/pgp",
|
||||||
|
data: {"key": key, "server": server},
|
||||||
|
type: "GET",
|
||||||
|
dataType: "json",
|
||||||
|
success: response => { keyBodyInput.text(response.key); },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function importPgpKey() {
|
||||||
|
const key = keyFingerprintInput.val();
|
||||||
|
const server = keyServerInput.val();
|
||||||
|
|
||||||
|
if (key && server) {
|
||||||
|
$.ajax({
|
||||||
|
url: "/api/v1/service/pgp",
|
||||||
|
data: JSON.stringify({key: key, server: server}),
|
||||||
|
type: "POST",
|
||||||
|
contentType: "application/json",
|
||||||
|
success: _ => {
|
||||||
|
keyImportModal.modal("hide");
|
||||||
|
showSuccess("Success", `Key ${key} has been imported`);
|
||||||
|
},
|
||||||
|
error: (jqXHR, _, errorThrown) => {
|
||||||
|
const message = _ => { return `Could not import key ${key} from ${server}`; };
|
||||||
|
showFailure("Action failed", message, jqXHR, errorThrown);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,9 +1,9 @@
|
|||||||
<div id="loginForm" tabindex="-1" role="dialog" class="modal fade">
|
<div id="login-modal" tabindex="-1" role="dialog" class="modal fade">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<form action="/api/v1/login" method="post">
|
<form action="/api/v1/login" method="post">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h4 class="modal-title">login</h4>
|
<h4 class="modal-title">Login</h4>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
@ -16,14 +16,36 @@
|
|||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label for="password" class="col-sm-2 col-form-label">password</label>
|
<label for="password" class="col-sm-2 col-form-label">password</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input id="password" type="password" class="form-control" placeholder="enter password" name="password" required>
|
<div class="input-group">
|
||||||
|
<input id="password" type="password" class="form-control" placeholder="enter password" name="password" required>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-outline-secondary" type="button" onclick="showPassword()"><i id="show-hide-password-btn" class="bi bi-eye"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class="btn btn-primary">login</button>
|
<button class="btn btn-primary"><i class="bi bi-person"></i> login</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const passwordInput = $("#password");
|
||||||
|
const showHidePasswordButton = $("#show-hide-password-btn");
|
||||||
|
|
||||||
|
function showPassword() {
|
||||||
|
if (passwordInput.attr("type") === "password") {
|
||||||
|
passwordInput.attr("type", "text");
|
||||||
|
showHidePasswordButton.removeClass("bi-eye");
|
||||||
|
showHidePasswordButton.addClass("bi-eye-slash");
|
||||||
|
} else {
|
||||||
|
passwordInput.attr("type", "password");
|
||||||
|
showHidePasswordButton.removeClass("bi-eye-slash");
|
||||||
|
showHidePasswordButton.addClass("bi-eye");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
@ -1,61 +1,78 @@
|
|||||||
<div id="add-form" tabindex="-1" role="dialog" class="modal fade">
|
<div id="package-add-modal" tabindex="-1" role="dialog" class="modal fade">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<form id="package-add-form" onsubmit="return false">
|
||||||
<h4 class="modal-title">add new packages</h4>
|
<div class="modal-header">
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
|
<h4 class="modal-title">Add new packages</h4>
|
||||||
</div>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
|
||||||
<div class="modal-body">
|
</div>
|
||||||
<div class="form-group row">
|
<div class="modal-body">
|
||||||
<label for="package" class="col-sm-2 col-form-label">package</label>
|
<div class="form-group row">
|
||||||
<div class="col-sm-10">
|
<label for="package-input" class="col-sm-2 col-form-label">package</label>
|
||||||
<input id="package-form" type="text" list="known-packages-dlist" autocomplete="off" class="form-control" placeholder="AUR package" name="package" required>
|
<div class="col-sm-10">
|
||||||
<datalist id="known-packages-dlist"></datalist>
|
<input id="package-input" type="text" list="known-packages-dlist" autocomplete="off" class="form-control" placeholder="AUR package" name="package" required>
|
||||||
|
<datalist id="known-packages-dlist"></datalist>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="modal-footer">
|
||||||
<div class="modal-footer">
|
<button type="submit" class="btn btn-primary" onclick="packagesAdd()"><i class="bi bi-play"></i> add</button>
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">close</button>
|
<button type="submit" class="btn btn-success" onclick="packagesRequest()"><i class="bi bi-plus"></i> request</button>
|
||||||
<button type="button" class="btn btn-success" data-bs-dismiss="modal" onclick="requestPackages()">request</button>
|
</div>
|
||||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" onclick="addPackages()">add</button>
|
</form>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const packageInput = $("#package-form");
|
const packageAddModal = $("#package-add-modal");
|
||||||
const knownPackages = $("#known-packages-dlist");
|
const packageAddForm = $("#package-add-form");
|
||||||
|
packageAddModal.on("hidden.bs.modal", () => { packageAddForm.trigger("reset"); });
|
||||||
|
|
||||||
|
const packageInput = $("#package-input");
|
||||||
|
const knownPackagesList = $("#known-packages-dlist");
|
||||||
packageInput.keyup(() => {
|
packageInput.keyup(() => {
|
||||||
clearTimeout(packageInput.data("timeout"));
|
clearTimeout(packageInput.data("timeout"));
|
||||||
packageInput.data("timeout", setTimeout($.proxy(() => {
|
packageInput.data("timeout", setTimeout($.proxy(() => {
|
||||||
const value = packageInput.val();
|
const value = packageInput.val();
|
||||||
|
|
||||||
$.ajax({
|
if (value.length >= 3) {
|
||||||
url: "/api/v1/service/search",
|
$.ajax({
|
||||||
data: {"for": value},
|
url: "/api/v1/service/search",
|
||||||
type: "GET",
|
data: {"for": value},
|
||||||
dataType: "json",
|
type: "GET",
|
||||||
success: response => {
|
dataType: "json",
|
||||||
const options = response.map(pkg => {
|
success: response => {
|
||||||
const option = document.createElement("option");
|
const options = response.map(pkg => {
|
||||||
option.value = pkg.package;
|
const option = document.createElement("option");
|
||||||
option.innerText = `${pkg.package} (${pkg.description})`;
|
option.value = pkg.package;
|
||||||
return option;
|
option.innerText = `${pkg.package} (${pkg.description})`;
|
||||||
});
|
return option;
|
||||||
knownPackages.empty().append(options);
|
});
|
||||||
},
|
knownPackagesList.empty().append(options);
|
||||||
})
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}, this), 500));
|
}, this), 500));
|
||||||
});
|
});
|
||||||
|
|
||||||
function addPackages() {
|
function packagesAdd() {
|
||||||
const packages = [packageInput.val()];
|
const packages = packageInput.val();
|
||||||
doPackageAction("/api/v1/service/add", packages);
|
if (packages) {
|
||||||
|
packageAddModal.modal("hide");
|
||||||
|
const onSuccess = update => { return `Packages ${update} have been added`; };
|
||||||
|
const onFailure = error => { return `Package addition failed: ${error}`; };
|
||||||
|
doPackageAction("/api/v1/service/add", [packages], onSuccess, onFailure);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function requestPackages() {
|
function packagesRequest() {
|
||||||
const packages = [packageInput.val()];
|
const packages = packageInput.val();
|
||||||
doPackageAction("/api/v1/service/request", packages);
|
if (packages) {
|
||||||
|
packageAddModal.modal("hide");
|
||||||
|
const onSuccess = update => { return `Packages ${update} have been requested`; };
|
||||||
|
const onFailure = error => { return `Package request failed: ${error}`; };
|
||||||
|
doPackageAction("/api/v1/service/request", [packages], onSuccess, onFailure);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
<div id="package-info-modal" tabindex="-1" role="dialog" class="modal fade">
|
||||||
|
<div class="modal-dialog modal-xl" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div id="package-info-modal-header" class="modal-header">
|
||||||
|
<h4 id="package-info" class="modal-title"></h4>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<pre class="language-logs"><samp id="package-info-logs-input" class="pre-scrollable language-logs"></samp><button id="logs-copy-btn" type="button" class="btn language-logs" onclick="copyLogs()"><i class="bi bi-clipboard"></i> copy</button></pre>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" onclick="showLogs()"><i class="bi bi-arrow-clockwise"></i> reload</button>
|
||||||
|
<button type="button" class="btn btn-primary" data-bs-dismiss="modal"><i class="bi bi-x"></i> close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const packageInfoModal = $("#package-info-modal");
|
||||||
|
const packageInfoModalHeader = $("#package-info-modal-header");
|
||||||
|
const packageInfo = $("#package-info");
|
||||||
|
|
||||||
|
const packageInfoLogsInput = $("#package-info-logs-input");
|
||||||
|
const packageInfoLogsCopyButton = $("#logs-copy-btn");
|
||||||
|
|
||||||
|
async function copyLogs() {
|
||||||
|
const logs = packageInfoLogsInput.text();
|
||||||
|
await copyToClipboard(logs, packageInfoLogsCopyButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showLogs(packageBase) {
|
||||||
|
const isPackageBaseSet = packageBase !== undefined;
|
||||||
|
if (isPackageBaseSet)
|
||||||
|
packageInfoModal.data("package", packageBase); // set package base as currently used
|
||||||
|
else
|
||||||
|
packageBase = packageInfoModal.data("package"); // read package base from the current window attribute
|
||||||
|
|
||||||
|
const headerClass = status => {
|
||||||
|
if (status === "pending") return ["bg-warning"];
|
||||||
|
if (status === "building") return ["bg-warning"];
|
||||||
|
if (status === "failed") return ["bg-danger", "text-white"];
|
||||||
|
if (status === "success") return ["bg-success", "text-white"];
|
||||||
|
return ["bg-secondary", "text-white"];
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: `/api/v1/packages/${packageBase}/logs`,
|
||||||
|
type: "GET",
|
||||||
|
dataType: "json",
|
||||||
|
success: response => {
|
||||||
|
packageInfo.text(`${response.package_base} ${response.status.status} at ${new Date(1000 * response.status.timestamp).toISOString()}`);
|
||||||
|
packageInfoLogsInput.text(response.logs);
|
||||||
|
|
||||||
|
packageInfoModalHeader.removeClass();
|
||||||
|
packageInfoModalHeader.addClass("modal-header");
|
||||||
|
headerClass(response.status.status).forEach((clz) => packageInfoModalHeader.addClass(clz));
|
||||||
|
|
||||||
|
if (isPackageBaseSet) packageInfoModal.modal("show"); // we don't need to show window again
|
||||||
|
},
|
||||||
|
error: (jqXHR, _, errorThrown) => {
|
||||||
|
// show failed modal in case if first time loading
|
||||||
|
if (isPackageBaseSet) {
|
||||||
|
const message = error => { return `Could not load package ${packageBase} logs: ${error}`; };
|
||||||
|
showFailure("Load failure", message, jqXHR, errorThrown);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,41 @@
|
|||||||
|
<div id="package-rebuild-modal" tabindex="-1" role="dialog" class="modal fade">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form id="package-rebuild-form" onsubmit="return false">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Rebuild depending packages</h4>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="dependency-input" class="col-sm-4 col-form-label">dependency</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input id="dependency-input" type="text" class="form-control" placeholder="packages dependency" name="package" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="submit" class="btn btn-primary" onclick="packagesRebuild()"><i class="bi bi-play"></i> rebuild</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const packageRebuildModal = $("#package-rebuild-modal");
|
||||||
|
const packageRebuildForm = $("#package-rebuild-form");
|
||||||
|
packageRebuildModal.on("hidden.bs.modal", () => { packageRebuildForm.trigger("reset"); });
|
||||||
|
|
||||||
|
const dependencyInput = $("#dependency-input");
|
||||||
|
|
||||||
|
function packagesRebuild() {
|
||||||
|
const packages = dependencyInput.val();
|
||||||
|
if (packages) {
|
||||||
|
packageRebuildModal.modal("hide");
|
||||||
|
const onSuccess = update => { return `Repository rebuild has been run for packages which depend on ${update}`; };
|
||||||
|
const onFailure = error => { return `Repository rebuild failed: ${error}`; };
|
||||||
|
doPackageAction("/api/v1/service/rebuild", [packages], onSuccess, onFailure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,28 +0,0 @@
|
|||||||
<div id="success-form" tabindex="-1" role="dialog" class="modal fade">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header bg-success">
|
|
||||||
<h4 class="modal-title">success</h4>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<p>Packages update has been run.</p>
|
|
||||||
<ul id="success-details"></ul>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const successForm = $("#success-form");
|
|
||||||
const successDetails = $("#success-details");
|
|
||||||
successForm.on("hidden.bs.modal", () => { reload(); });
|
|
||||||
|
|
||||||
function showSuccess(details) {
|
|
||||||
successDetails.empty().append(details);
|
|
||||||
successForm.modal("show");
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -1,37 +1,38 @@
|
|||||||
<script>
|
<script>
|
||||||
const addButton = $("#add-btn");
|
const keyImportButton = $("#key-import-btn");
|
||||||
const removeButton = $("#remove-btn");
|
const packageAddButton = $("#package-add-btn");
|
||||||
const updateButton = $("#update-btn");
|
const packageRebuildButton = $("#package-rebuild-btn");
|
||||||
|
const packageRemoveButton = $("#package-remove-btn");
|
||||||
|
const packageUpdateButton = $("#package-update-btn");
|
||||||
|
|
||||||
const table = $("#packages");
|
const table = $("#packages");
|
||||||
table.on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table",
|
table.on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table", () => {
|
||||||
() => {
|
packageRemoveButton.prop("disabled", !table.bootstrapTable("getSelections").length);
|
||||||
removeButton.prop("disabled", !table.bootstrapTable("getSelections").length);
|
});
|
||||||
updateButton.prop("disabled", !table.bootstrapTable("getSelections").length);
|
table.on("click-row.bs.table", (self, data, row, cell) => {
|
||||||
});
|
if (0 === cell || "base" === cell) {
|
||||||
|
const method = data[0] === true ? "uncheckBy" : "checkBy"; // fck javascript
|
||||||
|
table.bootstrapTable(method, {field: "id", values: [data.id]});
|
||||||
|
} else showLogs(data.id);
|
||||||
|
});
|
||||||
|
|
||||||
const architectureBadge = $("#badge-architecture");
|
|
||||||
const repositoryBadge = $("#badge-repository");
|
const repositoryBadge = $("#badge-repository");
|
||||||
const statusBadge = $("#badge-status");
|
const statusBadge = $("#badge-status");
|
||||||
const versionBadge = $("#badge-version");
|
const versionBadge = $("#badge-version");
|
||||||
|
|
||||||
function doPackageAction(uri, packages) {
|
function doPackageAction(uri, packages, successText, failureText) {
|
||||||
if (packages.length === 0)
|
|
||||||
return;
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: uri,
|
url: uri,
|
||||||
data: JSON.stringify({packages: packages}),
|
data: JSON.stringify({packages: packages}),
|
||||||
type: "POST",
|
type: "POST",
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
||||||
success: _ => {
|
success: _ => {
|
||||||
const details = packages.map(pkg => {
|
const message = successText(packages.join(", "));
|
||||||
const li = document.createElement("li");
|
showSuccess("Success", message);
|
||||||
li.innerText = pkg;
|
},
|
||||||
return li;
|
error: (jqXHR, _, errorThrown) => {
|
||||||
});
|
showFailure("Action failed", failureText, jqXHR, errorThrown);
|
||||||
showSuccess(details);
|
|
||||||
},
|
},
|
||||||
error: (jqXHR, _, errorThrown) => { showFailure(errorThrown); },
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,19 +40,40 @@
|
|||||||
return table.bootstrapTable("getSelections").map(row => { return row.id; });
|
return table.bootstrapTable("getSelections").map(row => { return row.id; });
|
||||||
}
|
}
|
||||||
|
|
||||||
function removePackages() { doPackageAction("/api/v1/service/remove", getSelection()); }
|
function removePackages() {
|
||||||
|
const onSuccess = update => { return `Packages ${update} have been removed`; };
|
||||||
|
const onFailure = error => { return `Could not remove packages: ${error}`; };
|
||||||
|
doPackageAction("/api/v1/service/remove", getSelection(), onSuccess, onFailure);
|
||||||
|
}
|
||||||
|
|
||||||
function updatePackages() { doPackageAction("/api/v1/service/add", getSelection()); }
|
function updatePackages() {
|
||||||
|
const currentSelection = getSelection();
|
||||||
|
const [url, onSuccess] = currentSelection.length === 0
|
||||||
|
? ["/api/v1/service/update", _ => { return "Repository update has been run"; }]
|
||||||
|
: ["/api/v1/service/add", update => { return `Run update for packages ${update}`; }];
|
||||||
|
const onFailure = error => { return `Packages update failed: ${error}`; };
|
||||||
|
doPackageAction(url, currentSelection, onSuccess, onFailure);
|
||||||
|
}
|
||||||
|
|
||||||
function hideControls(hidden) {
|
function hideControls(hidden) {
|
||||||
addButton.attr("hidden", hidden);
|
keyImportButton.attr("hidden", hidden);
|
||||||
removeButton.attr("hidden", hidden);
|
packageAddButton.attr("hidden", hidden);
|
||||||
updateButton.attr("hidden", hidden);
|
packageRebuildButton.attr("hidden", hidden);
|
||||||
|
packageRemoveButton.attr("hidden", hidden);
|
||||||
|
packageUpdateButton.attr("hidden", hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
function reload() {
|
function reload() {
|
||||||
table.bootstrapTable("showLoading");
|
table.bootstrapTable("showLoading");
|
||||||
|
|
||||||
|
const badgeClass = status => {
|
||||||
|
if (status === "pending") return "btn-outline-warning";
|
||||||
|
if (status === "building") return "btn-outline-warning";
|
||||||
|
if (status === "failed") return "btn-outline-danger";
|
||||||
|
if (status === "success") return "btn-outline-success";
|
||||||
|
return "btn-outline-secondary";
|
||||||
|
};
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/api/v1/packages",
|
url: "/api/v1/packages",
|
||||||
type: "GET",
|
type: "GET",
|
||||||
@ -98,7 +120,8 @@
|
|||||||
table.bootstrapTable("hideLoading");
|
table.bootstrapTable("hideLoading");
|
||||||
} else {
|
} else {
|
||||||
// other errors
|
// other errors
|
||||||
showFailure(errorThrown);
|
const messaga = error => { return `Could not load list of packages: ${error}`; };
|
||||||
|
showFailure("Load failure", messaga, jqXHR, errorThrown);
|
||||||
}
|
}
|
||||||
hideControls(true);
|
hideControls(true);
|
||||||
},
|
},
|
||||||
@ -109,39 +132,20 @@
|
|||||||
type: "GET",
|
type: "GET",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: response => {
|
success: response => {
|
||||||
const badgeColor = status => {
|
repositoryBadge.text(`${response.repository} ${response.architecture}`);
|
||||||
if (status === "pending") return "yellow";
|
versionBadge.html(`<i class="bi bi-github"></i> ahriman ${safe(response.version)}`);
|
||||||
if (status === "building") return "yellow";
|
|
||||||
if (status === "failed") return "critical";
|
|
||||||
if (status === "success") return "success";
|
|
||||||
return "inactive";
|
|
||||||
};
|
|
||||||
|
|
||||||
architectureBadge
|
|
||||||
.attr("src", `https://img.shields.io/badge/architecture-${response.architecture}-informational`)
|
|
||||||
.attr("alt", response.architecture);
|
|
||||||
repositoryBadge
|
|
||||||
.attr("src", `https://img.shields.io/badge/repository-${response.repository.replace(/-/g, "--")}-informational`)
|
|
||||||
.attr("alt", response.repository);
|
|
||||||
statusBadge
|
statusBadge
|
||||||
.attr("src", `https://img.shields.io/badge/service%20status-${response.status.status}-${badgeColor(response.status.status)}`)
|
.popover("dispose")
|
||||||
.attr("alt", response.status.status)
|
.attr("data-bs-content", `${response.status.status} at ${new Date(1000 * response.status.timestamp).toISOString()}`)
|
||||||
.attr("title", `at ${new Date(1000 * response.status.timestamp).toISOString()}`);
|
.popover();
|
||||||
versionBadge
|
statusBadge.removeClass();
|
||||||
.attr("src", `https://img.shields.io/badge/version-${response.version}-informational`)
|
statusBadge.addClass("btn");
|
||||||
.attr("alt", response.version);
|
statusBadge.addClass(badgeClass(response.status.status));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function safe(string) {
|
|
||||||
return String(string)
|
|
||||||
.replace(/&/g, "&")
|
|
||||||
.replace(/</g, "<")
|
|
||||||
.replace(/>/g, ">")
|
|
||||||
.replace(/"/g, """);
|
|
||||||
}
|
|
||||||
|
|
||||||
function statusFormat(value) {
|
function statusFormat(value) {
|
||||||
const cellClass = status => {
|
const cellClass = status => {
|
||||||
if (status === "pending") return "table-warning";
|
if (status === "pending") return "table-warning";
|
||||||
@ -155,6 +159,7 @@
|
|||||||
|
|
||||||
$(() => {
|
$(() => {
|
||||||
table.bootstrapTable({});
|
table.bootstrapTable({});
|
||||||
|
statusBadge.popover();
|
||||||
reload();
|
reload();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
31
package/share/ahriman/templates/error.jinja2
Normal file
31
package/share/ahriman/templates/error.jinja2
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Error</title>
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<link rel="shortcut icon" href="/static/favicon.ico">
|
||||||
|
|
||||||
|
{% include "utils/style.jinja2" %}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
{% include "utils/bootstrap-scripts.jinja2" %}
|
||||||
|
|
||||||
|
<div class="d-flex flex-row align-items-center">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-12 text-center">
|
||||||
|
<span class="display-1 d-block">{{ code }}</span>
|
||||||
|
<div class="mb-4 lead">{{ reason }}</div>
|
||||||
|
<a class="btn btn-link" style="text-decoration: none" href="/" title="home"><i class="bi bi-house"></i> home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -10,19 +10,22 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
{% include "utils/bootstrap-scripts.jinja2" %}
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Arch linux user repository</h1>
|
<h1>Arch linux user repository</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
{% if pgp_key is not none %}
|
{% if pgp_key is not none %}
|
||||||
<p>This repository is signed with <a href="https://pgp.mit.edu/pks/lookup?search=0x{{ pgp_key }}&fingerprint=on&op=index" title="key search">{{ pgp_key }}</a> by default.</p>
|
<p>This repository is signed with <a href="https://keyserver.ubuntu.com/pks/lookup?search=0x{{ pgp_key }}&fingerprint=on&op=index" title="key search">{{ pgp_key }}</a> by default.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<pre>$ cat /etc/pacman.conf
|
<p>In order to use this repository edit your <code>/etc/pacman.conf</code> as following:</p>
|
||||||
[{{ repository }}]
|
|
||||||
|
<pre class="language-ini"><code id="pacman-conf" class="language-ini">[{{ repository }}]
|
||||||
Server = {{ link_path }}
|
Server = {{ link_path }}
|
||||||
SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Package{% if has_package_signed %}Required{% else %}Never{% endif %} TrustedOnly</pre>
|
SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Package{% if has_package_signed %}Required{% else %}Never{% endif %} TrustedOnly</code><button id="copy-btn" type="button" class="btn language-ini" onclick="copyPacmanConf()"><i class="bi bi-clipboard"></i> copy</button></pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -83,16 +86,24 @@ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Pa
|
|||||||
<footer class="d-flex flex-wrap justify-content-between align-items-center border-top">
|
<footer class="d-flex flex-wrap justify-content-between align-items-center border-top">
|
||||||
<ul class="nav">
|
<ul class="nav">
|
||||||
{% if homepage is not none %}
|
{% if homepage is not none %}
|
||||||
<li><a class="nav-link" href="{{ homepage }}" title="homepage">homepage</a></li>
|
<li><a class="nav-link" href="{{ homepage }}" title="homepage"><i class="bi bi-house"></i> homepage</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="nav">
|
<ul class="nav">
|
||||||
<li><a class="nav-link" href="https://github.com/arcan1s/ahriman" title="sources">ahriman</a></li>
|
<li><a class="nav-link" href="https://github.com/arcan1s/ahriman" title="sources"><i class="bi bi-github"></i> ahriman</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include "utils/bootstrap-scripts.jinja2" %}
|
<script>
|
||||||
|
const pacmanConf = $("#pacman-conf");
|
||||||
|
const pacmanConfCopyButton = $("#copy-btn");
|
||||||
|
|
||||||
|
async function copyPacmanConf() {
|
||||||
|
const conf = pacmanConf.text();
|
||||||
|
await copyToClipboard(conf, pacmanConfCopyButton);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
@ -4,9 +4,38 @@
|
|||||||
|
|
||||||
<script src="https://unpkg.com/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.min.js"></script>
|
<script src="https://unpkg.com/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.min.js"></script>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js" integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3" crossorigin="anonymous"></script>
|
||||||
<script src="https://unpkg.com/bootstrap-table@1.20.2/dist/bootstrap-table.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.min.js" integrity="sha384-IDwe1+LCz02ROU9k972gdyvl+AESN10+x7tBKgc9I5HFtuNz0wWnPclzo6p9vxnk" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://unpkg.com/bootstrap-table@1.21.1/dist/bootstrap-table.min.js"></script>
|
||||||
|
|
||||||
<script src="https://unpkg.com/bootstrap-table@1.20.2/dist/extensions/export/bootstrap-table-export.min.js"></script>
|
<script src="https://unpkg.com/bootstrap-table@1.21.1/dist/extensions/export/bootstrap-table-export.min.js"></script>
|
||||||
|
|
||||||
<script src="https://unpkg.com/bootstrap-table@1.20.2/dist/extensions/resizable/bootstrap-table-resizable.js"></script>
|
<script src="https://unpkg.com/bootstrap-table@1.21.1/dist/extensions/resizable/bootstrap-table-resizable.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
async function copyToClipboard(text, button) {
|
||||||
|
if (navigator.clipboard === undefined) {
|
||||||
|
const input = document.createElement("textarea");
|
||||||
|
input.innerHTML = text;
|
||||||
|
document.body.appendChild(input);
|
||||||
|
input.select();
|
||||||
|
document.execCommand("copy");
|
||||||
|
document.body.removeChild(input);
|
||||||
|
} else {
|
||||||
|
await navigator.clipboard.writeText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.html("<i class=\"bi bi-clipboard-check\"></i> copied");
|
||||||
|
setTimeout(()=> {
|
||||||
|
button.html("<i class=\"bi bi-clipboard\"></i> copy");
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function safe(string) {
|
||||||
|
return String(string)
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
.replace(/"/g, """);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
@ -1,9 +1,26 @@
|
|||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" type="text/css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous" type="text/css">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.3/font/bootstrap-icons.css" type="text/css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.2/font/bootstrap-icons.css" type="text/css">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://unpkg.com/bootstrap-table@1.20.2/dist/bootstrap-table.min.css" type="text/css">
|
<link rel="stylesheet" href="https://unpkg.com/bootstrap-table@1.21.1/dist/bootstrap-table.min.css" type="text/css">
|
||||||
|
|
||||||
<link href="https://unpkg.com/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.css" rel="stylesheet">
|
<link rel="stylesheet" href="https://unpkg.com/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.css" type="text/css">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootswatch@5.2.2/dist/cosmo/bootstrap.min.css" integrity="sha256-5t++JZpgVLzo9vF7snO5Qw0y3fA5/NkoJENWB7kpg0E=" crossorigin="anonymous" type="text/css">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.pre-scrollable {
|
||||||
|
display: block;
|
||||||
|
max-height: 680px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"] {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"] button {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 5px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
23
setup.py
23
setup.py
@ -52,29 +52,35 @@ setup(
|
|||||||
"package/bin/ahriman",
|
"package/bin/ahriman",
|
||||||
],
|
],
|
||||||
data_files=[
|
data_files=[
|
||||||
|
# configuration
|
||||||
("share/ahriman/settings", [
|
("share/ahriman/settings", [
|
||||||
"package/share/ahriman/settings/ahriman.ini",
|
"package/share/ahriman/settings/ahriman.ini",
|
||||||
]),
|
]),
|
||||||
("share/ahriman/settings/ahriman.ini.d", [
|
("share/ahriman/settings/ahriman.ini.d", [
|
||||||
"package/share/ahriman/settings/ahriman.ini.d/logging.ini",
|
"package/share/ahriman/settings/ahriman.ini.d/logging.ini",
|
||||||
]),
|
]),
|
||||||
|
# systemd files
|
||||||
("lib/systemd/system", [
|
("lib/systemd/system", [
|
||||||
"package/lib/systemd/system/ahriman@.service",
|
"package/lib/systemd/system/ahriman@.service",
|
||||||
"package/lib/systemd/system/ahriman@.timer",
|
"package/lib/systemd/system/ahriman@.timer",
|
||||||
"package/lib/systemd/system/ahriman-web@.service",
|
"package/lib/systemd/system/ahriman-web@.service",
|
||||||
]),
|
]),
|
||||||
|
# templates
|
||||||
("share/ahriman/templates", [
|
("share/ahriman/templates", [
|
||||||
"package/share/ahriman/templates/build-status.jinja2",
|
"package/share/ahriman/templates/build-status.jinja2",
|
||||||
"package/share/ahriman/templates/email-index.jinja2",
|
"package/share/ahriman/templates/email-index.jinja2",
|
||||||
|
"package/share/ahriman/templates/error.jinja2",
|
||||||
"package/share/ahriman/templates/repo-index.jinja2",
|
"package/share/ahriman/templates/repo-index.jinja2",
|
||||||
"package/share/ahriman/templates/shell",
|
"package/share/ahriman/templates/shell",
|
||||||
"package/share/ahriman/templates/telegram-index.jinja2",
|
"package/share/ahriman/templates/telegram-index.jinja2",
|
||||||
]),
|
]),
|
||||||
("share/ahriman/templates/build-status", [
|
("share/ahriman/templates/build-status", [
|
||||||
"package/share/ahriman/templates/build-status/failed-modal.jinja2",
|
"package/share/ahriman/templates/build-status/alerts.jinja2",
|
||||||
|
"package/share/ahriman/templates/build-status/key-import-modal.jinja2",
|
||||||
"package/share/ahriman/templates/build-status/login-modal.jinja2",
|
"package/share/ahriman/templates/build-status/login-modal.jinja2",
|
||||||
"package/share/ahriman/templates/build-status/package-add-modal.jinja2",
|
"package/share/ahriman/templates/build-status/package-add-modal.jinja2",
|
||||||
"package/share/ahriman/templates/build-status/success-modal.jinja2",
|
"package/share/ahriman/templates/build-status/package-info-modal.jinja2",
|
||||||
|
"package/share/ahriman/templates/build-status/package-rebuild-modal.jinja2",
|
||||||
"package/share/ahriman/templates/build-status/table.jinja2",
|
"package/share/ahriman/templates/build-status/table.jinja2",
|
||||||
]),
|
]),
|
||||||
("share/ahriman/templates/static", [
|
("share/ahriman/templates/static", [
|
||||||
@ -84,9 +90,17 @@ setup(
|
|||||||
"package/share/ahriman/templates/utils/bootstrap-scripts.jinja2",
|
"package/share/ahriman/templates/utils/bootstrap-scripts.jinja2",
|
||||||
"package/share/ahriman/templates/utils/style.jinja2",
|
"package/share/ahriman/templates/utils/style.jinja2",
|
||||||
]),
|
]),
|
||||||
|
# man pages
|
||||||
("share/man/man1", [
|
("share/man/man1", [
|
||||||
"docs/ahriman.1",
|
"docs/ahriman.1",
|
||||||
])
|
]),
|
||||||
|
# shell completions
|
||||||
|
("share/bash-completion/completions", [
|
||||||
|
"docs/completions/bash/_ahriman",
|
||||||
|
]),
|
||||||
|
("share/zsh/site-functions", [
|
||||||
|
"docs/completions/zsh/_ahriman",
|
||||||
|
]),
|
||||||
],
|
],
|
||||||
|
|
||||||
extras_require={
|
extras_require={
|
||||||
@ -100,7 +114,9 @@ setup(
|
|||||||
"Sphinx",
|
"Sphinx",
|
||||||
"argparse-manpage",
|
"argparse-manpage",
|
||||||
"pydeps",
|
"pydeps",
|
||||||
|
"shtab",
|
||||||
"sphinx-argparse",
|
"sphinx-argparse",
|
||||||
|
"sphinx-rtd-theme>=1.1.1", # https://stackoverflow.com/a/74355734
|
||||||
"sphinxcontrib-napoleon",
|
"sphinxcontrib-napoleon",
|
||||||
],
|
],
|
||||||
# FIXME technically this dependency is required, but in some cases we do not have access to
|
# FIXME technically this dependency is required, but in some cases we do not have access to
|
||||||
@ -130,6 +146,7 @@ setup(
|
|||||||
"aiohttp_session",
|
"aiohttp_session",
|
||||||
"aiohttp_security",
|
"aiohttp_security",
|
||||||
"cryptography",
|
"cryptography",
|
||||||
|
"requests-unixsocket", # required by unix socket support
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
# pylint: disable=too-many-lines
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
@ -67,13 +68,14 @@ def _parser() -> argparse.ArgumentParser:
|
|||||||
parser = argparse.ArgumentParser(prog="ahriman", description="ArcH linux ReposItory MANager",
|
parser = argparse.ArgumentParser(prog="ahriman", description="ArcH linux ReposItory MANager",
|
||||||
epilog="Argument list can also be read from file by using @ prefix.",
|
epilog="Argument list can also be read from file by using @ prefix.",
|
||||||
fromfile_prefix_chars="@", formatter_class=_formatter)
|
fromfile_prefix_chars="@", formatter_class=_formatter)
|
||||||
parser.add_argument("-a", "--architecture", help="target architectures (can be used multiple times)",
|
parser.add_argument("-a", "--architecture", help="target architectures. For several subcommands it can be used "
|
||||||
action="append")
|
"multiple times", action="append")
|
||||||
parser.add_argument("-c", "--configuration", help="configuration path", type=Path, default=Path("/etc/ahriman.ini"))
|
parser.add_argument("-c", "--configuration", help="configuration path", type=Path, default=Path("/etc/ahriman.ini"))
|
||||||
parser.add_argument("--force", help="force run, remove file lock", action="store_true")
|
parser.add_argument("--force", help="force run, remove file lock", action="store_true")
|
||||||
parser.add_argument("-l", "--lock", help="lock file", type=Path,
|
parser.add_argument("-l", "--lock", help="lock file", type=Path,
|
||||||
default=Path(tempfile.gettempdir()) / "ahriman.lock")
|
default=Path(tempfile.gettempdir()) / "ahriman.lock")
|
||||||
parser.add_argument("--no-report", help="force disable reporting to web service", action="store_true")
|
parser.add_argument("--report", help="force enable or disable reporting to web service",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
parser.add_argument("-q", "--quiet", help="force disable any logging", action="store_true")
|
parser.add_argument("-q", "--quiet", help="force disable any logging", action="store_true")
|
||||||
parser.add_argument("--unsafe", help="allow to run ahriman as non-ahriman user. Some actions might be unavailable",
|
parser.add_argument("--unsafe", help="allow to run ahriman as non-ahriman user. Some actions might be unavailable",
|
||||||
action="store_true")
|
action="store_true")
|
||||||
@ -82,6 +84,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_daemon_parser(subparsers)
|
||||||
_set_help_parser(subparsers)
|
_set_help_parser(subparsers)
|
||||||
_set_help_commands_unsafe_parser(subparsers)
|
_set_help_commands_unsafe_parser(subparsers)
|
||||||
_set_key_import_parser(subparsers)
|
_set_key_import_parser(subparsers)
|
||||||
@ -93,6 +96,7 @@ def _parser() -> argparse.ArgumentParser:
|
|||||||
_set_patch_add_parser(subparsers)
|
_set_patch_add_parser(subparsers)
|
||||||
_set_patch_list_parser(subparsers)
|
_set_patch_list_parser(subparsers)
|
||||||
_set_patch_remove_parser(subparsers)
|
_set_patch_remove_parser(subparsers)
|
||||||
|
_set_patch_set_add_parser(subparsers)
|
||||||
_set_repo_backup_parser(subparsers)
|
_set_repo_backup_parser(subparsers)
|
||||||
_set_repo_check_parser(subparsers)
|
_set_repo_check_parser(subparsers)
|
||||||
_set_repo_clean_parser(subparsers)
|
_set_repo_clean_parser(subparsers)
|
||||||
@ -105,6 +109,7 @@ def _parser() -> argparse.ArgumentParser:
|
|||||||
_set_repo_sign_parser(subparsers)
|
_set_repo_sign_parser(subparsers)
|
||||||
_set_repo_status_update_parser(subparsers)
|
_set_repo_status_update_parser(subparsers)
|
||||||
_set_repo_sync_parser(subparsers)
|
_set_repo_sync_parser(subparsers)
|
||||||
|
_set_repo_tree_parser(subparsers)
|
||||||
_set_repo_triggers_parser(subparsers)
|
_set_repo_triggers_parser(subparsers)
|
||||||
_set_repo_update_parser(subparsers)
|
_set_repo_update_parser(subparsers)
|
||||||
_set_shell_parser(subparsers)
|
_set_shell_parser(subparsers)
|
||||||
@ -129,14 +134,44 @@ def _set_aur_search_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
"""
|
"""
|
||||||
parser = root.add_parser("aur-search", aliases=["search"], help="search for package",
|
parser = root.add_parser("aur-search", aliases=["search"], help="search for package",
|
||||||
description="search for package in AUR using API", formatter_class=_formatter)
|
description="search for package in AUR using API", formatter_class=_formatter)
|
||||||
parser.add_argument("search", help="search terms, can be specified multiple times, result will match all terms",
|
parser.add_argument("search", help="search terms, can be specified multiple times, the result will match all terms",
|
||||||
nargs="+")
|
nargs="+")
|
||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||||
parser.add_argument("-i", "--info", help="show additional package information", action="store_true")
|
parser.add_argument("--info", help="show additional package information",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
parser.add_argument("--sort-by", help="sort field by this field. In case if two packages have the same value of "
|
parser.add_argument("--sort-by", help="sort field by this field. In case if two packages have the same value of "
|
||||||
"the specified field, they will be always sorted by name",
|
"the specified field, they will be always sorted by name",
|
||||||
default="name", choices=sorted(handlers.Search.SORT_FIELDS))
|
default="name", choices=sorted(handlers.Search.SORT_FIELDS))
|
||||||
parser.set_defaults(handler=handlers.Search, architecture=[""], lock=None, no_report=True, quiet=True, unsafe=True)
|
parser.set_defaults(handler=handlers.Search, architecture=[""], lock=None, report=False, quiet=True, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def _set_daemon_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for daemon subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("daemon", help="run application as daemon",
|
||||||
|
description="start process which periodically will run update process",
|
||||||
|
formatter_class=_formatter)
|
||||||
|
parser.add_argument("-i", "--interval", help="interval between runs in seconds", type=int, default=60 * 60 * 12)
|
||||||
|
parser.add_argument("--aur", help="enable or disable checking for AUR updates. Implies --no-vcs",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--local", help="enable or disable checking of local packages for updates",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--manual", help="include or exclude manual updates",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--vcs", help="enable or disable checking of VCS packages",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("-y", "--refresh", help="download fresh package databases from the mirror before actions, "
|
||||||
|
"-yy to force refresh even if up to date",
|
||||||
|
action="count", default=False)
|
||||||
|
parser.set_defaults(handler=handlers.Daemon, dry_run=False, exit_code=False, package=[])
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -154,7 +189,7 @@ def _set_help_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
description="show help message for application or command and exit",
|
description="show help message for application or command and exit",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.add_argument("command", help="show help message for specific command", nargs="?")
|
parser.add_argument("command", help="show help message for specific command", nargs="?")
|
||||||
parser.set_defaults(handler=handlers.Help, architecture=[""], lock=None, no_report=True, quiet=True,
|
parser.set_defaults(handler=handlers.Help, architecture=[""], lock=None, report=False, quiet=True,
|
||||||
unsafe=True, parser=_parser)
|
unsafe=True, parser=_parser)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -173,7 +208,7 @@ def _set_help_commands_unsafe_parser(root: SubParserAction) -> argparse.Argument
|
|||||||
description="list unsafe commands as defined in default args", formatter_class=_formatter)
|
description="list unsafe commands as defined in default args", formatter_class=_formatter)
|
||||||
parser.add_argument("--command", help="instead of showing commands, just test command line for unsafe subcommand "
|
parser.add_argument("--command", help="instead of showing commands, just test command line for unsafe subcommand "
|
||||||
"and return 0 in case if command is safe and 1 otherwise")
|
"and return 0 in case if command is safe and 1 otherwise")
|
||||||
parser.set_defaults(handler=handlers.UnsafeCommands, architecture=[""], lock=None, no_report=True, quiet=True,
|
parser.set_defaults(handler=handlers.UnsafeCommands, architecture=[""], lock=None, report=False, quiet=True,
|
||||||
unsafe=True, parser=_parser)
|
unsafe=True, parser=_parser)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -195,9 +230,9 @@ def _set_key_import_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
"fail in case if key is not known for build user. This subcommand can be used "
|
"fail in case if key is not known for build user. This subcommand can be used "
|
||||||
"in order to import the PGP key to user keychain.",
|
"in order to import the PGP key to user keychain.",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.add_argument("--key-server", help="key server for key import", default="pgp.mit.edu")
|
parser.add_argument("--key-server", help="key server for key import", default="keyserver.ubuntu.com")
|
||||||
parser.add_argument("key", help="PGP key to import from public server")
|
parser.add_argument("key", help="PGP key to import from public server")
|
||||||
parser.set_defaults(handler=handlers.KeyImport, architecture=[""], lock=None, no_report=True)
|
parser.set_defaults(handler=handlers.KeyImport, architecture=[""], lock=None, report=False)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -227,6 +262,9 @@ def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
parser.add_argument("package", help="package source (base name, path to local files, remote URL)", nargs="+")
|
parser.add_argument("package", help="package source (base name, path to local files, remote URL)", nargs="+")
|
||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||||
parser.add_argument("-n", "--now", help="run update function after", action="store_true")
|
parser.add_argument("-n", "--now", help="run update function after", action="store_true")
|
||||||
|
parser.add_argument("-y", "--refresh", help="download fresh package databases from the mirror before actions, "
|
||||||
|
"-yy to force refresh even if up to date",
|
||||||
|
action="count", default=False)
|
||||||
parser.add_argument("-s", "--source", help="explicitly specify the package source for this command",
|
parser.add_argument("-s", "--source", help="explicitly specify the package source for this command",
|
||||||
type=PackageSource, choices=enum_values(PackageSource), default=PackageSource.Auto)
|
type=PackageSource, choices=enum_values(PackageSource), default=PackageSource.Auto)
|
||||||
parser.add_argument("--without-dependencies", help="do not add dependencies", action="store_true")
|
parser.add_argument("--without-dependencies", help="do not add dependencies", action="store_true")
|
||||||
@ -268,10 +306,11 @@ def _set_package_status_parser(root: SubParserAction) -> argparse.ArgumentParser
|
|||||||
parser.add_argument("package", help="filter status by package base", nargs="*")
|
parser.add_argument("package", help="filter status by package base", nargs="*")
|
||||||
parser.add_argument("--ahriman", help="get service status itself", action="store_true")
|
parser.add_argument("--ahriman", help="get service status itself", action="store_true")
|
||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||||
parser.add_argument("-i", "--info", help="show additional package information", action="store_true")
|
parser.add_argument("--info", help="show additional package information",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
parser.add_argument("-s", "--status", help="filter packages by status",
|
parser.add_argument("-s", "--status", help="filter packages by status",
|
||||||
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum))
|
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum))
|
||||||
parser.set_defaults(handler=handlers.Status, lock=None, no_report=True, quiet=True, unsafe=True)
|
parser.set_defaults(handler=handlers.Status, lock=None, report=False, quiet=True, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -290,8 +329,8 @@ def _set_package_status_remove_parser(root: SubParserAction) -> argparse.Argumen
|
|||||||
epilog="Please note that this subcommand does not remove the package itself, it just "
|
epilog="Please note that this subcommand does not remove the package itself, it just "
|
||||||
"clears the status page.",
|
"clears the status page.",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.add_argument("package", help="remove specified packages", nargs="+")
|
parser.add_argument("package", help="remove specified packages from status page", nargs="+")
|
||||||
parser.set_defaults(handler=handlers.StatusUpdate, action=Action.Remove, lock=None, no_report=True, quiet=True,
|
parser.set_defaults(handler=handlers.StatusUpdate, action=Action.Remove, lock=None, report=False, quiet=True,
|
||||||
unsafe=True)
|
unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -311,16 +350,16 @@ def _set_package_status_update_parser(root: SubParserAction) -> argparse.Argumen
|
|||||||
parser.add_argument("package", help="set status for specified packages. "
|
parser.add_argument("package", help="set status for specified packages. "
|
||||||
"If no packages supplied, service status will be updated",
|
"If no packages supplied, service status will be updated",
|
||||||
nargs="*")
|
nargs="*")
|
||||||
parser.add_argument("-s", "--status", help="new status",
|
parser.add_argument("-s", "--status", help="new package build status",
|
||||||
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum), default=BuildStatusEnum.Success)
|
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum), default=BuildStatusEnum.Success)
|
||||||
parser.set_defaults(handler=handlers.StatusUpdate, action=Action.Update, lock=None, no_report=True, quiet=True,
|
parser.set_defaults(handler=handlers.StatusUpdate, action=Action.Update, lock=None, report=False, quiet=True,
|
||||||
unsafe=True)
|
unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
def _set_patch_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
def _set_patch_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
"""
|
"""
|
||||||
add parser for new patch subcommand
|
add parser for new single-function patch subcommand
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
root(SubParserAction): subparsers for the commands
|
root(SubParserAction): subparsers for the commands
|
||||||
@ -328,17 +367,19 @@ def _set_patch_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
Returns:
|
Returns:
|
||||||
argparse.ArgumentParser: created argument parser
|
argparse.ArgumentParser: created argument parser
|
||||||
"""
|
"""
|
||||||
parser = root.add_parser("patch-add", help="add patch set", description="create or update source patches",
|
parser = root.add_parser("patch-add", help="add patch for PKGBUILD function",
|
||||||
epilog="In order to add a patch set for the package you will need to clone "
|
description="create or update patched PKGBUILD function or variable",
|
||||||
"the AUR package manually, add required changes (e.g. external patches, "
|
epilog="Unlike ``patch-set-add``, this function allows to patch only one PKGBUILD "
|
||||||
"edit PKGBUILD) and run command, e.g. ``ahriman patch path/to/directory``. "
|
"function, e.g. typing ``ahriman patch-add ahriman pkgver`` it will change the "
|
||||||
"By default it tracks *.patch and *.diff files, but this behavior can be changed "
|
"``pkgver`` inside PKGBUILD, typing ``ahriman patch-add ahriman build()`` "
|
||||||
"by using --track option",
|
"it will change ``build()`` function inside PKGBUILD",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.add_argument("package", help="path to directory with changed files for patch addition/update")
|
parser.add_argument("package", help="package base")
|
||||||
parser.add_argument("-t", "--track", help="files which has to be tracked", action="append",
|
parser.add_argument("variable", help="PKGBUILD variable or function name. If variable is a function, "
|
||||||
default=["*.diff", "*.patch"])
|
"it must end with ()")
|
||||||
parser.set_defaults(handler=handlers.Patch, action=Action.Update, architecture=[""], lock=None, no_report=True)
|
parser.add_argument("patch", help="path to file which contains function or variable value. If not set, "
|
||||||
|
"the value will be read from stdin", type=Path, nargs="?")
|
||||||
|
parser.set_defaults(handler=handlers.Patch, action=Action.Update, architecture=[""], lock=None, report=False)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -356,7 +397,9 @@ def _set_patch_list_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
description="list available patches for the package", formatter_class=_formatter)
|
description="list available patches for the package", formatter_class=_formatter)
|
||||||
parser.add_argument("package", help="package base", nargs="?")
|
parser.add_argument("package", help="package base", nargs="?")
|
||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||||
parser.set_defaults(handler=handlers.Patch, action=Action.List, architecture=[""], lock=None, no_report=True)
|
parser.add_argument("-v", "--variable", help="if set, show only patches for specified PKGBUILD variables",
|
||||||
|
action="append")
|
||||||
|
parser.set_defaults(handler=handlers.Patch, action=Action.List, architecture=[""], lock=None, report=False)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -373,7 +416,36 @@ def _set_patch_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
parser = root.add_parser("patch-remove", help="remove patch set", description="remove patches for the package",
|
parser = root.add_parser("patch-remove", help="remove patch set", description="remove patches for the package",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.add_argument("package", help="package base")
|
parser.add_argument("package", help="package base")
|
||||||
parser.set_defaults(handler=handlers.Patch, action=Action.Remove, architecture=[""], lock=None, no_report=True)
|
parser.add_argument("-v", "--variable", help="should be used for single-function patches in case if you wold like "
|
||||||
|
"to remove only specified PKGBUILD variables. In case if not set, "
|
||||||
|
"it will remove all patches related to the package",
|
||||||
|
action="append")
|
||||||
|
parser.set_defaults(handler=handlers.Patch, action=Action.Remove, architecture=[""], lock=None, report=False)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def _set_patch_set_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for new full-diff patch subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("patch-set-add", help="add patch set", description="create or update source patches",
|
||||||
|
epilog="In order to add a patch set for the package you will need to clone "
|
||||||
|
"the AUR package manually, add required changes (e.g. external patches, "
|
||||||
|
"edit PKGBUILD) and run command, e.g. ``ahriman patch-set-add path/to/directory``. "
|
||||||
|
"By default it tracks *.patch and *.diff files, but this behavior can be changed "
|
||||||
|
"by using --track option",
|
||||||
|
formatter_class=_formatter)
|
||||||
|
parser.add_argument("package", help="path to directory with changed files for patch addition/update", type=Path)
|
||||||
|
parser.add_argument("-t", "--track", help="files which has to be tracked", action="append",
|
||||||
|
default=["*.diff", "*.patch"])
|
||||||
|
parser.set_defaults(handler=handlers.Patch, action=Action.Update, architecture=[""], lock=None, report=False,
|
||||||
|
variable=None)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -388,9 +460,9 @@ def _set_repo_backup_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
argparse.ArgumentParser: created argument parser
|
argparse.ArgumentParser: created argument parser
|
||||||
"""
|
"""
|
||||||
parser = root.add_parser("repo-backup", help="backup repository data",
|
parser = root.add_parser("repo-backup", help="backup repository data",
|
||||||
description="backup settings and database", formatter_class=_formatter)
|
description="backup repository settings and database", formatter_class=_formatter)
|
||||||
parser.add_argument("path", help="path of the output archive", type=Path)
|
parser.add_argument("path", help="path of the output archive", type=Path)
|
||||||
parser.set_defaults(handler=handlers.Backup, architecture=[""], lock=None, no_report=True, unsafe=True)
|
parser.set_defaults(handler=handlers.Backup, architecture=[""], lock=None, report=False, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -405,12 +477,16 @@ def _set_repo_check_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
argparse.ArgumentParser: created argument parser
|
argparse.ArgumentParser: created argument parser
|
||||||
"""
|
"""
|
||||||
parser = root.add_parser("repo-check", aliases=["check"], help="check for updates",
|
parser = root.add_parser("repo-check", aliases=["check"], help="check for updates",
|
||||||
description="check for packages updates. Same as update --dry-run --no-manual",
|
description="check for packages updates. Same as repo-update --dry-run --no-manual",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.add_argument("package", help="filter check by package base", nargs="*")
|
parser.add_argument("package", help="filter check by package base", nargs="*")
|
||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||||
parser.add_argument("--no-vcs", help="do not check VCS packages", action="store_true")
|
parser.add_argument("--vcs", help="enable or disable checking of VCS packages",
|
||||||
parser.set_defaults(handler=handlers.Update, dry_run=True, no_aur=False, no_local=False, no_manual=True)
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("-y", "--refresh", help="download fresh package databases from the mirror before actions, "
|
||||||
|
"-yy to force refresh even if up to date",
|
||||||
|
action="count", default=False)
|
||||||
|
parser.set_defaults(handler=handlers.Update, dry_run=True, aur=True, local=True, manual=False)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -430,10 +506,15 @@ def _set_repo_clean_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
"you should not run this command manually. Also in case if you are going to clear "
|
"you should not run this command manually. Also in case if you are going to clear "
|
||||||
"the chroot directories you will need root privileges.",
|
"the chroot directories you will need root privileges.",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.add_argument("--cache", help="clear directory with package caches", action="store_true")
|
parser.add_argument("--cache", help="clear directory with package caches",
|
||||||
parser.add_argument("--chroot", help="clear build chroot", action="store_true")
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
parser.add_argument("--manual", help="clear manually added packages queue", action="store_true")
|
parser.add_argument("--chroot", help="clear build chroot", action=argparse.BooleanOptionalAction, default=False)
|
||||||
parser.add_argument("--packages", help="clear directory with built packages", action="store_true")
|
parser.add_argument("--manual", help="clear manually added packages queue",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
|
parser.add_argument("--packages", help="clear directory with built packages",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
|
parser.add_argument("--pacman", help="clear directory with pacman local database cache",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
parser.set_defaults(handler=handlers.Clean, quiet=True, unsafe=True)
|
parser.set_defaults(handler=handlers.Clean, quiet=True, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -451,7 +532,7 @@ def _set_repo_config_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
parser = root.add_parser("repo-config", aliases=["config"], help="dump configuration",
|
parser = root.add_parser("repo-config", aliases=["config"], help="dump configuration",
|
||||||
description="dump configuration for the specified architecture",
|
description="dump configuration for the specified architecture",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.set_defaults(handler=handlers.Dump, lock=None, no_report=True, quiet=True, unsafe=True)
|
parser.set_defaults(handler=handlers.Dump, lock=None, report=False, quiet=True, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -467,13 +548,13 @@ def _set_repo_rebuild_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
"""
|
"""
|
||||||
parser = root.add_parser("repo-rebuild", aliases=["rebuild"], help="rebuild repository",
|
parser = root.add_parser("repo-rebuild", aliases=["rebuild"], help="rebuild repository",
|
||||||
description="force rebuild whole repository", formatter_class=_formatter)
|
description="force rebuild whole repository", formatter_class=_formatter)
|
||||||
parser.add_argument("--depends-on", help="only rebuild packages that depend on specified package", action="append")
|
parser.add_argument("--depends-on", help="only rebuild packages that depend on specified packages", action="append")
|
||||||
parser.add_argument("--dry-run", help="just perform check for packages without rebuild process itself",
|
parser.add_argument("--dry-run", help="just perform check for packages without rebuild process itself",
|
||||||
action="store_true")
|
action="store_true")
|
||||||
parser.add_argument("--from-database",
|
parser.add_argument("--from-database",
|
||||||
help="read packages from database instead of filesystem. This feature in particular is "
|
help="read packages from database instead of filesystem. This feature in particular is "
|
||||||
"required in case if you would like to restore repository from another repository "
|
"required in case if you would like to restore repository from another repository "
|
||||||
"instance. Note however that in order to restore packages you need to have original "
|
"instance. Note, however, that in order to restore packages you need to have original "
|
||||||
"ahriman instance run with web service and have run repo-update at least once.",
|
"ahriman instance run with web service and have run repo-update at least once.",
|
||||||
action="store_true")
|
action="store_true")
|
||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||||
@ -495,7 +576,6 @@ def _set_repo_remove_unknown_parser(root: SubParserAction) -> argparse.ArgumentP
|
|||||||
description="remove packages which are missing in AUR and do not have local PKGBUILDs",
|
description="remove packages which are missing in AUR and do not have local PKGBUILDs",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.add_argument("--dry-run", help="just perform check for packages without removal", action="store_true")
|
parser.add_argument("--dry-run", help="just perform check for packages without removal", action="store_true")
|
||||||
parser.add_argument("-i", "--info", help="show additional package information", action="store_true")
|
|
||||||
parser.set_defaults(handler=handlers.RemoveUnknown)
|
parser.set_defaults(handler=handlers.RemoveUnknown)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -532,7 +612,7 @@ def _set_repo_restore_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
description="restore settings and database", formatter_class=_formatter)
|
description="restore settings and database", formatter_class=_formatter)
|
||||||
parser.add_argument("path", help="path of the input archive", type=Path)
|
parser.add_argument("path", help="path of the input archive", type=Path)
|
||||||
parser.add_argument("-o", "--output", help="root path of the extracted files", type=Path, default=Path("/"))
|
parser.add_argument("-o", "--output", help="root path of the extracted files", type=Path, default=Path("/"))
|
||||||
parser.set_defaults(handler=handlers.Restore, architecture=[""], lock=None, no_report=True, unsafe=True)
|
parser.set_defaults(handler=handlers.Restore, architecture=[""], lock=None, report=False, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -554,14 +634,18 @@ def _set_repo_setup_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
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"))
|
||||||
parser.add_argument("--no-multilib", help="do not add multilib repository", action="store_true")
|
parser.add_argument("--makeflags-jobs", help="append MAKEFLAGS variable with parallelism set to number of cores",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--multilib", help="add or do not multilib repository",
|
||||||
|
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("--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))
|
||||||
parser.add_argument("--web-port", help="port of the web service", type=int)
|
parser.add_argument("--web-port", help="port of the web service", type=int)
|
||||||
parser.set_defaults(handler=handlers.Setup, lock=None, no_report=True, quiet=True, unsafe=True)
|
parser.add_argument("--web-unix-socket", help="path to unix socket used for interprocess communications", type=Path)
|
||||||
|
parser.set_defaults(handler=handlers.Setup, lock=None, report=False, quiet=True, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -598,7 +682,7 @@ def _set_repo_status_update_parser(root: SubParserAction) -> argparse.ArgumentPa
|
|||||||
description="update repository status on the status page", formatter_class=_formatter)
|
description="update repository status on the status page", formatter_class=_formatter)
|
||||||
parser.add_argument("-s", "--status", help="new status",
|
parser.add_argument("-s", "--status", help="new status",
|
||||||
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum), default=BuildStatusEnum.Success)
|
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum), default=BuildStatusEnum.Success)
|
||||||
parser.set_defaults(handler=handlers.StatusUpdate, action=Action.Update, lock=None, no_report=True, package=[],
|
parser.set_defaults(handler=handlers.StatusUpdate, action=Action.Update, lock=None, report=False, package=[],
|
||||||
quiet=True, unsafe=True)
|
quiet=True, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -621,6 +705,23 @@ def _set_repo_sync_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def _set_repo_tree_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repository tree subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-tree", help="dump repository tree",
|
||||||
|
description="dump repository tree based on packages dependencies",
|
||||||
|
formatter_class=_formatter)
|
||||||
|
parser.set_defaults(handler=handlers.Structure, lock=None, report=False, quiet=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
def _set_repo_triggers_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
def _set_repo_triggers_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
"""
|
"""
|
||||||
add parser for repository triggers subcommand
|
add parser for repository triggers subcommand
|
||||||
@ -635,7 +736,7 @@ def _set_repo_triggers_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
description="run triggers on empty build result as configured by settings",
|
description="run triggers on empty build result as configured by settings",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.add_argument("trigger", help="instead of running all triggers as set by configuration, just process "
|
parser.add_argument("trigger", help="instead of running all triggers as set by configuration, just process "
|
||||||
"specified ones oin order of metion", nargs="*")
|
"specified ones in order of mention", nargs="*")
|
||||||
parser.set_defaults(handler=handlers.Triggers)
|
parser.set_defaults(handler=handlers.Triggers)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -656,10 +757,17 @@ def _set_repo_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
parser.add_argument("package", help="filter check by package base", nargs="*")
|
parser.add_argument("package", help="filter check by package base", nargs="*")
|
||||||
parser.add_argument("--dry-run", help="just perform check for updates, same as check command", action="store_true")
|
parser.add_argument("--dry-run", help="just perform check for updates, same as check command", action="store_true")
|
||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||||
parser.add_argument("--no-aur", help="do not check for AUR updates. Implies --no-vcs", action="store_true")
|
parser.add_argument("--aur", help="enable or disable checking for AUR updates. Implies --no-vcs",
|
||||||
parser.add_argument("--no-local", help="do not check local packages for updates", action="store_true")
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
parser.add_argument("--no-manual", help="do not include manual updates", action="store_true")
|
parser.add_argument("--local", help="enable or disable checking of local packages for updates",
|
||||||
parser.add_argument("--no-vcs", help="do not check VCS packages", action="store_true")
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--manual", help="include or exclude manual updates",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--vcs", help="enable or disable checking of VCS packages",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("-y", "--refresh", help="download fresh package databases from the mirror before actions, "
|
||||||
|
"-yy to force refresh even if up to date",
|
||||||
|
action="count", default=False)
|
||||||
parser.set_defaults(handler=handlers.Update)
|
parser.set_defaults(handler=handlers.Update)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -674,11 +782,12 @@ def _set_shell_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
Returns:
|
Returns:
|
||||||
argparse.ArgumentParser: created argument parser
|
argparse.ArgumentParser: created argument parser
|
||||||
"""
|
"""
|
||||||
parser = root.add_parser("shell", help="envoke python shell",
|
parser = root.add_parser("shell", help="invoke python shell",
|
||||||
description="drop into python shell while having created application",
|
description="drop into python shell while having created application",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
|
parser.add_argument("code", help="instead of dropping into shell, just execute the specified code", nargs="?")
|
||||||
parser.add_argument("-v", "--verbose", help=argparse.SUPPRESS, action="store_true")
|
parser.add_argument("-v", "--verbose", help=argparse.SUPPRESS, action="store_true")
|
||||||
parser.set_defaults(handler=handlers.Shell, lock=None, no_report=True)
|
parser.set_defaults(handler=handlers.Shell, lock=None, report=False)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@ -695,15 +804,16 @@ def _set_user_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
parser = root.add_parser("user-add", help="create or update user",
|
parser = root.add_parser("user-add", help="create or update user",
|
||||||
description="update user for web services with the given password and role. "
|
description="update user for web services with the given password and role. "
|
||||||
"In case if password was not entered it will be asked interactively",
|
"In case if password was not entered it will be asked interactively",
|
||||||
|
epilog="In case of first run (i.e. if password salt is not set yet) this action requires "
|
||||||
|
"root privileges because it performs write to filesystem configuration.",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.add_argument("username", help="username for web service")
|
parser.add_argument("username", help="username for web service")
|
||||||
parser.add_argument("--as-service", help="add user as service user", action="store_true")
|
|
||||||
parser.add_argument("-p", "--password", help="user password. Blank password will be treated as empty password, "
|
parser.add_argument("-p", "--password", help="user password. Blank password will be treated as empty password, "
|
||||||
"which is in particular must be used for OAuth2 authorization type.")
|
"which is in particular must be used for OAuth2 authorization type.")
|
||||||
parser.add_argument("-r", "--role", help="user access level",
|
parser.add_argument("-r", "--role", help="user access level",
|
||||||
type=UserAccess, choices=enum_values(UserAccess), default=UserAccess.Read)
|
type=UserAccess, choices=enum_values(UserAccess), default=UserAccess.Read)
|
||||||
parser.add_argument("-s", "--secure", help="set file permissions to user-only", action="store_true")
|
parser.add_argument("-s", "--secure", help="set file permissions to user-only", action="store_true")
|
||||||
parser.set_defaults(handler=handlers.Users, action=Action.Update, architecture=[""], lock=None, no_report=True,
|
parser.set_defaults(handler=handlers.Users, action=Action.Update, architecture=[""], lock=None, report=False,
|
||||||
quiet=True, unsafe=True)
|
quiet=True, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -724,7 +834,7 @@ def _set_user_list_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
parser.add_argument("username", help="filter users by username", nargs="?")
|
parser.add_argument("username", help="filter users by username", nargs="?")
|
||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||||
parser.add_argument("-r", "--role", help="filter users by role", type=UserAccess, choices=enum_values(UserAccess))
|
parser.add_argument("-r", "--role", help="filter users by role", type=UserAccess, choices=enum_values(UserAccess))
|
||||||
parser.set_defaults(handler=handlers.Users, action=Action.List, architecture=[""], lock=None, no_report=True, # nosec
|
parser.set_defaults(handler=handlers.Users, action=Action.List, architecture=[""], lock=None, report=False, # nosec
|
||||||
password="", quiet=True, unsafe=True)
|
password="", quiet=True, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -743,8 +853,7 @@ def _set_user_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
description="remove user from the user mapping and update the configuration",
|
description="remove user from the user mapping and update the configuration",
|
||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.add_argument("username", help="username for web service")
|
parser.add_argument("username", help="username for web service")
|
||||||
parser.add_argument("-s", "--secure", help="set file permissions to user-only", action="store_true")
|
parser.set_defaults(handler=handlers.Users, action=Action.Remove, architecture=[""], lock=None, report=False, # nosec
|
||||||
parser.set_defaults(handler=handlers.Users, action=Action.Remove, architecture=[""], lock=None, no_report=True, # nosec
|
|
||||||
password="", quiet=True, unsafe=True)
|
password="", quiet=True, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -761,7 +870,7 @@ def _set_version_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
"""
|
"""
|
||||||
parser = root.add_parser("version", help="application version",
|
parser = root.add_parser("version", help="application version",
|
||||||
description="print application and its dependencies versions", formatter_class=_formatter)
|
description="print application and its dependencies versions", formatter_class=_formatter)
|
||||||
parser.set_defaults(handler=handlers.Versions, architecture=[""], lock=None, no_report=True, quiet=True,
|
parser.set_defaults(handler=handlers.Versions, architecture=[""], lock=None, report=False, quiet=True,
|
||||||
unsafe=True)
|
unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -777,7 +886,7 @@ def _set_web_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
argparse.ArgumentParser: created argument parser
|
argparse.ArgumentParser: created argument parser
|
||||||
"""
|
"""
|
||||||
parser = root.add_parser("web", help="web server", description="start web server", formatter_class=_formatter)
|
parser = root.add_parser("web", help="web server", description="start web server", formatter_class=_formatter)
|
||||||
parser.set_defaults(handler=handlers.Web, lock=None, no_report=True, parser=_parser)
|
parser.set_defaults(handler=handlers.Web, lock=None, report=False, parser=_parser)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,12 +36,12 @@ class Application(ApplicationPackages, ApplicationRepository):
|
|||||||
>>> from ahriman.models.package_source import PackageSource
|
>>> from ahriman.models.package_source import PackageSource
|
||||||
>>>
|
>>>
|
||||||
>>> configuration = Configuration()
|
>>> configuration = Configuration()
|
||||||
>>> application = Application("x86_64", configuration, no_report=False, unsafe=False)
|
>>> application = Application("x86_64", configuration, report=True, unsafe=False)
|
||||||
>>> # add packages to build queue
|
>>> # add packages to build queue
|
||||||
>>> application.add(["ahriman"], PackageSource.AUR, without_dependencies=False)
|
>>> application.add(["ahriman"], PackageSource.AUR, without_dependencies=False)
|
||||||
>>>
|
>>>
|
||||||
>>> # check for updates
|
>>> # check for updates
|
||||||
>>> updates = application.updates([], no_aur=False, no_local=False, no_manual=False, no_vcs=False, log_fn=print)
|
>>> updates = application.updates([], aur=True, local=True, manual=True, vcs=True, log_fn=print)
|
||||||
>>> # updates for specified packages
|
>>> # updates for specified packages
|
||||||
>>> application.update(updates)
|
>>> application.update(updates)
|
||||||
|
|
||||||
@ -49,15 +49,6 @@ class Application(ApplicationPackages, ApplicationRepository):
|
|||||||
be used instead.
|
be used instead.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _finalize(self, result: Result) -> None:
|
|
||||||
"""
|
|
||||||
generate report and sync to remote server
|
|
||||||
|
|
||||||
Args:
|
|
||||||
result(Result): build result
|
|
||||||
"""
|
|
||||||
self.repository.process_triggers(result)
|
|
||||||
|
|
||||||
def _known_packages(self) -> Set[str]:
|
def _known_packages(self) -> Set[str]:
|
||||||
"""
|
"""
|
||||||
load packages from repository and pacman repositories
|
load packages from repository and pacman repositories
|
||||||
@ -71,5 +62,28 @@ class Application(ApplicationPackages, ApplicationRepository):
|
|||||||
for package, properties in base.packages.items():
|
for package, properties in base.packages.items():
|
||||||
known_packages.add(package)
|
known_packages.add(package)
|
||||||
known_packages.update(properties.provides)
|
known_packages.update(properties.provides)
|
||||||
known_packages.update(self.repository.pacman.all_packages())
|
known_packages.update(self.repository.pacman.packages())
|
||||||
return known_packages
|
return known_packages
|
||||||
|
|
||||||
|
def on_result(self, result: Result) -> None:
|
||||||
|
"""
|
||||||
|
generate report and sync to remote server
|
||||||
|
|
||||||
|
Args:
|
||||||
|
result(Result): build result
|
||||||
|
"""
|
||||||
|
packages = self.repository.packages()
|
||||||
|
self.repository.triggers.on_result(result, packages)
|
||||||
|
|
||||||
|
def on_start(self) -> None:
|
||||||
|
"""
|
||||||
|
run triggers on start of the application
|
||||||
|
"""
|
||||||
|
self.repository.triggers.on_start()
|
||||||
|
|
||||||
|
def on_stop(self) -> None:
|
||||||
|
"""
|
||||||
|
run triggers on stop of the application. Note, however, that in most cases this method should not be called
|
||||||
|
directly as it will be called after on_start action
|
||||||
|
"""
|
||||||
|
self.repository.triggers.on_stop()
|
||||||
|
@ -37,18 +37,6 @@ class ApplicationPackages(ApplicationProperties):
|
|||||||
package control class
|
package control class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _finalize(self, result: Result) -> None:
|
|
||||||
"""
|
|
||||||
generate report and sync to remote server
|
|
||||||
|
|
||||||
Args:
|
|
||||||
result(Result): build result
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: not implemented method
|
|
||||||
"""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def _known_packages(self) -> Set[str]:
|
def _known_packages(self) -> Set[str]:
|
||||||
"""
|
"""
|
||||||
load packages from repository and pacman repositories
|
load packages from repository and pacman repositories
|
||||||
@ -61,6 +49,18 @@ class ApplicationPackages(ApplicationProperties):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def on_result(self, result: Result) -> None:
|
||||||
|
"""
|
||||||
|
generate report and sync to remote server
|
||||||
|
|
||||||
|
Args:
|
||||||
|
result(Result): build result
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
NotImplementedError: not implemented method
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def _add_archive(self, source: str, *_: Any) -> None:
|
def _add_archive(self, source: str, *_: Any) -> None:
|
||||||
"""
|
"""
|
||||||
add package from archive
|
add package from archive
|
||||||
@ -86,8 +86,7 @@ class ApplicationPackages(ApplicationProperties):
|
|||||||
self.database.build_queue_insert(package)
|
self.database.build_queue_insert(package)
|
||||||
self.database.remote_update(package)
|
self.database.remote_update(package)
|
||||||
|
|
||||||
with TemporaryDirectory(ignore_cleanup_errors=True) as dir_name, \
|
with TemporaryDirectory(ignore_cleanup_errors=True) as dir_name, (local_dir := Path(dir_name)):
|
||||||
(local_dir := Path(dir_name)): # pylint: disable=confusing-with-statement
|
|
||||||
Sources.load(local_dir, package, self.database.patches_get(package.base), self.repository.paths)
|
Sources.load(local_dir, package, self.database.patches_get(package.base), self.repository.paths)
|
||||||
self._process_dependencies(local_dir, known_packages, without_dependencies)
|
self._process_dependencies(local_dir, known_packages, without_dependencies)
|
||||||
|
|
||||||
@ -187,4 +186,4 @@ class ApplicationPackages(ApplicationProperties):
|
|||||||
names(Iterable[str]): list of packages (either base or name) to remove
|
names(Iterable[str]): list of packages (either base or name) to remove
|
||||||
"""
|
"""
|
||||||
self.repository.process_remove(names)
|
self.repository.process_remove(names)
|
||||||
self._finalize(Result())
|
self.on_result(Result())
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#
|
#
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.database import SQLite
|
from ahriman.core.database import SQLite
|
||||||
from ahriman.core.lazy_logging import LazyLogging
|
from ahriman.core.log import LazyLogging
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
|
|
||||||
|
|
||||||
@ -34,17 +34,21 @@ class ApplicationProperties(LazyLogging):
|
|||||||
repository(Repository): repository instance
|
repository(Repository): repository instance
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, architecture: str, configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
def __init__(self, architecture: str, configuration: Configuration, *,
|
||||||
|
report: bool, unsafe: bool, refresh_pacman_database: int = 0) -> None:
|
||||||
"""
|
"""
|
||||||
default constructor
|
default constructor
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
|
refresh_pacman_database(int, optional): pacman database syncronization level, ``0`` is disabled
|
||||||
|
(Default value = 0)
|
||||||
"""
|
"""
|
||||||
self.configuration = configuration
|
self.configuration = configuration
|
||||||
self.architecture = architecture
|
self.architecture = architecture
|
||||||
self.database = SQLite.load(configuration)
|
self.database = SQLite.load(configuration)
|
||||||
self.repository = Repository(architecture, configuration, self.database, no_report, unsafe)
|
self.repository = Repository.load(architecture, configuration, self.database, report=report, unsafe=unsafe,
|
||||||
|
refresh_pacman_database=refresh_pacman_database)
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
import shutil
|
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Callable, Iterable, List
|
from typing import Callable, Iterable, List
|
||||||
|
|
||||||
@ -35,7 +33,7 @@ class ApplicationRepository(ApplicationProperties):
|
|||||||
repository control class
|
repository control class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _finalize(self, result: Result) -> None:
|
def on_result(self, result: Result) -> None:
|
||||||
"""
|
"""
|
||||||
generate report and sync to remote server
|
generate report and sync to remote server
|
||||||
|
|
||||||
@ -47,15 +45,16 @@ class ApplicationRepository(ApplicationProperties):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def clean(self, cache: bool, chroot: bool, manual: bool, packages: bool) -> None:
|
def clean(self, *, cache: bool, chroot: bool, manual: bool, packages: bool, pacman: bool) -> None:
|
||||||
"""
|
"""
|
||||||
run all clean methods. Warning: some functions might not be available under non-root
|
run all clean methods. Warning: some functions might not be available under non-root
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
cache(bool): clear directory with package caches
|
cache(bool): clear directory with package caches
|
||||||
chroot(bool): clear build chroot
|
chroot(bool): clear build chroot
|
||||||
manual(bool): clear directory with manually added packages
|
manual(bool): clear directory with manually added packages' bases
|
||||||
packages(bool): clear directory with built packages
|
packages(bool): clear directory with built packages
|
||||||
|
pacman(bool): clear directory with pacman databases
|
||||||
"""
|
"""
|
||||||
if cache:
|
if cache:
|
||||||
self.repository.clear_cache()
|
self.repository.clear_cache()
|
||||||
@ -65,6 +64,8 @@ class ApplicationRepository(ApplicationProperties):
|
|||||||
self.repository.clear_queue()
|
self.repository.clear_queue()
|
||||||
if packages:
|
if packages:
|
||||||
self.repository.clear_packages()
|
self.repository.clear_packages()
|
||||||
|
if pacman:
|
||||||
|
self.repository.clear_pacman()
|
||||||
|
|
||||||
def sign(self, packages: Iterable[str]) -> None:
|
def sign(self, packages: Iterable[str]) -> None:
|
||||||
"""
|
"""
|
||||||
@ -82,14 +83,11 @@ class ApplicationRepository(ApplicationProperties):
|
|||||||
if archive.filepath is None:
|
if archive.filepath is None:
|
||||||
self.logger.warning("filepath is empty for %s", package.base)
|
self.logger.warning("filepath is empty for %s", package.base)
|
||||||
continue # avoid mypy warning
|
continue # avoid mypy warning
|
||||||
src = self.repository.paths.repository / archive.filepath
|
self.repository.sign.process_sign_package(archive.filepath, package.base)
|
||||||
dst = self.repository.paths.packages / archive.filepath
|
|
||||||
shutil.copy(src, dst)
|
|
||||||
# run generic update function
|
|
||||||
self.update([])
|
|
||||||
# sign repository database if set
|
# sign repository database if set
|
||||||
self.repository.sign.process_sign_repository(self.repository.repo.repo_path)
|
self.repository.sign.process_sign_repository(self.repository.repo.repo_path)
|
||||||
self._finalize(Result())
|
# process triggers
|
||||||
|
self.on_result(Result())
|
||||||
|
|
||||||
def unknown(self) -> List[str]:
|
def unknown(self) -> List[str]:
|
||||||
"""
|
"""
|
||||||
@ -139,7 +137,7 @@ class ApplicationRepository(ApplicationProperties):
|
|||||||
if not paths:
|
if not paths:
|
||||||
return # don't need to process if no update supplied
|
return # don't need to process if no update supplied
|
||||||
update_result = self.repository.process_update(paths)
|
update_result = self.repository.process_update(paths)
|
||||||
self._finalize(result.merge(update_result))
|
self.on_result(result.merge(update_result))
|
||||||
|
|
||||||
# process built packages
|
# process built packages
|
||||||
build_result = Result()
|
build_result = Result()
|
||||||
@ -147,8 +145,8 @@ class ApplicationRepository(ApplicationProperties):
|
|||||||
process_update(packages, build_result)
|
process_update(packages, build_result)
|
||||||
|
|
||||||
# process manual packages
|
# process manual packages
|
||||||
tree = Tree.load(updates, self.repository.paths, self.database)
|
tree = Tree.resolve(updates, self.repository.paths, self.database)
|
||||||
for num, level in enumerate(tree.levels()):
|
for num, level in enumerate(tree):
|
||||||
self.logger.info("processing level #%i %s", num, [package.base for package in level])
|
self.logger.info("processing level #%i %s", num, [package.base for package in level])
|
||||||
build_result = self.repository.process_build(level)
|
build_result = self.repository.process_build(level)
|
||||||
packages = self.repository.packages_built()
|
packages = self.repository.packages_built()
|
||||||
@ -156,17 +154,17 @@ class ApplicationRepository(ApplicationProperties):
|
|||||||
|
|
||||||
return build_result
|
return build_result
|
||||||
|
|
||||||
def updates(self, filter_packages: Iterable[str], no_aur: bool, no_local: bool, no_manual: bool, no_vcs: bool,
|
def updates(self, filter_packages: Iterable[str], *,
|
||||||
log_fn: Callable[[str], None]) -> List[Package]:
|
aur: bool, local: bool, manual: bool, vcs: bool, log_fn: Callable[[str], None]) -> List[Package]:
|
||||||
"""
|
"""
|
||||||
get list of packages to run update process
|
get list of packages to run update process
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
filter_packages(Iterable[str]): do not check every package just specified in the list
|
filter_packages(Iterable[str]): do not check every package just specified in the list
|
||||||
no_aur(bool): do not check for aur updates
|
aur(bool): enable or disable checking for AUR updates
|
||||||
no_local(bool): do not check local packages for updates
|
local(bool): enable or disable checking of local packages for updates
|
||||||
no_manual(bool): do not check for manual updates
|
manual(bool): include or exclude manual updates
|
||||||
no_vcs(bool): do not check VCS packages
|
vcs(bool): enable or disable checking of VCS packages
|
||||||
log_fn(Callable[[str], None]): logger function to log updates
|
log_fn(Callable[[str], None]): logger function to log updates
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -174,17 +172,21 @@ class ApplicationRepository(ApplicationProperties):
|
|||||||
"""
|
"""
|
||||||
updates = {}
|
updates = {}
|
||||||
|
|
||||||
if not no_aur:
|
if aur:
|
||||||
updates.update({package.base: package for package in self.repository.updates_aur(filter_packages, no_vcs)})
|
updates.update({package.base: package for package in self.repository.updates_aur(filter_packages, vcs=vcs)})
|
||||||
if not no_local:
|
if local:
|
||||||
updates.update({package.base: package for package in self.repository.updates_local()})
|
updates.update({package.base: package for package in self.repository.updates_local()})
|
||||||
if not no_manual:
|
if manual:
|
||||||
updates.update({package.base: package for package in self.repository.updates_manual()})
|
updates.update({package.base: package for package in self.repository.updates_manual()})
|
||||||
|
|
||||||
local_versions = {package.base: package.version for package in self.repository.packages()}
|
local_versions = {package.base: package.version for package in self.repository.packages()}
|
||||||
updated_packages = [package for _, package in sorted(updates.items())]
|
updated_packages = [package for _, package in sorted(updates.items())]
|
||||||
for package in updated_packages:
|
|
||||||
UpdatePrinter(package, local_versions.get(package.base)).print(
|
# reorder updates according to the dependency tree
|
||||||
verbose=True, log_fn=log_fn, separator=" -> ")
|
tree = Tree.resolve(updated_packages, self.repository.paths, self.database)
|
||||||
|
for level in tree:
|
||||||
|
for package in level:
|
||||||
|
UpdatePrinter(package, local_versions.get(package.base)).print(
|
||||||
|
verbose=True, log_fn=log_fn, separator=" -> ")
|
||||||
|
|
||||||
return updated_packages
|
return updated_packages
|
||||||
|
@ -22,6 +22,7 @@ from ahriman.application.handlers.handler import Handler
|
|||||||
from ahriman.application.handlers.add import Add
|
from ahriman.application.handlers.add import Add
|
||||||
from ahriman.application.handlers.backup import Backup
|
from ahriman.application.handlers.backup import Backup
|
||||||
from ahriman.application.handlers.clean import Clean
|
from ahriman.application.handlers.clean import Clean
|
||||||
|
from ahriman.application.handlers.daemon import Daemon
|
||||||
from ahriman.application.handlers.dump import Dump
|
from ahriman.application.handlers.dump import Dump
|
||||||
from ahriman.application.handlers.help import Help
|
from ahriman.application.handlers.help import Help
|
||||||
from ahriman.application.handlers.key_import import KeyImport
|
from ahriman.application.handlers.key_import import KeyImport
|
||||||
@ -36,6 +37,7 @@ from ahriman.application.handlers.shell import Shell
|
|||||||
from ahriman.application.handlers.sign import Sign
|
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.structure import Structure
|
||||||
from ahriman.application.handlers.triggers import Triggers
|
from ahriman.application.handlers.triggers import Triggers
|
||||||
from ahriman.application.handlers.unsafe_commands import UnsafeCommands
|
from ahriman.application.handlers.unsafe_commands import UnsafeCommands
|
||||||
from ahriman.application.handlers.update import Update
|
from ahriman.application.handlers.update import Update
|
||||||
|
@ -32,8 +32,8 @@ 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, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -41,14 +41,17 @@ class Add(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
application = Application(architecture, configuration, no_report, unsafe)
|
application = Application(architecture, configuration,
|
||||||
|
report=report, unsafe=unsafe, refresh_pacman_database=args.refresh)
|
||||||
|
application.on_start()
|
||||||
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
|
||||||
|
|
||||||
packages = application.updates(args.package, True, True, False, True, application.logger.info)
|
packages = application.updates(args.package, aur=False, local=False, manual=True, vcs=False,
|
||||||
|
log_fn=application.logger.info)
|
||||||
result = application.update(packages)
|
result = application.update(packages)
|
||||||
Add.check_if_empty(args.exit_code, result.is_empty)
|
Add.check_if_empty(args.exit_code, result.is_empty)
|
||||||
|
@ -37,8 +37,8 @@ class Backup(Handler):
|
|||||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ class Backup(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
backup_paths = Backup.get_paths(configuration)
|
backup_paths = Backup.get_paths(configuration)
|
||||||
@ -57,7 +57,7 @@ class Backup(Handler):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get_paths(configuration: Configuration) -> Set[Path]:
|
def get_paths(configuration: Configuration) -> Set[Path]:
|
||||||
"""
|
"""
|
||||||
extract paths to backup
|
extract paths to back up
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
|
@ -32,8 +32,8 @@ 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, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -41,8 +41,10 @@ class Clean(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
Application(architecture, configuration, no_report, unsafe).clean(
|
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||||
args.cache, args.chroot, args.manual, args.packages)
|
application.on_start()
|
||||||
|
application.clean(cache=args.cache, chroot=args.chroot, manual=args.manual, packages=args.packages,
|
||||||
|
pacman=args.pacman)
|
||||||
|
52
src/ahriman/application/handlers/daemon.py
Normal file
52
src/ahriman/application/handlers/daemon.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2021-2022 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
|
||||||
|
import threading
|
||||||
|
|
||||||
|
from typing import Type
|
||||||
|
|
||||||
|
from ahriman.application.handlers import Handler
|
||||||
|
from ahriman.core.configuration import Configuration
|
||||||
|
|
||||||
|
|
||||||
|
class Daemon(Handler):
|
||||||
|
"""
|
||||||
|
daemon packages handler
|
||||||
|
"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
|
report: bool, unsafe: bool) -> None:
|
||||||
|
"""
|
||||||
|
callback for command line
|
||||||
|
|
||||||
|
Args:
|
||||||
|
args(argparse.Namespace): command line args
|
||||||
|
architecture(str): repository architecture
|
||||||
|
configuration(Configuration): configuration instance
|
||||||
|
report(bool): force enable or disable reporting
|
||||||
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
|
"""
|
||||||
|
from ahriman.application.handlers import Update
|
||||||
|
Update.run(args, architecture, configuration, report=report, unsafe=unsafe)
|
||||||
|
timer = threading.Timer(args.interval, Daemon.run, args=[args, architecture, configuration],
|
||||||
|
kwargs={"report": report, "unsafe": unsafe})
|
||||||
|
timer.start()
|
||||||
|
timer.join()
|
@ -34,8 +34,8 @@ class Dump(Handler):
|
|||||||
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ class Dump(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
dump = configuration.dump()
|
dump = configuration.dump()
|
||||||
|
@ -27,7 +27,8 @@ from typing import List, Type
|
|||||||
|
|
||||||
from ahriman.application.lock import Lock
|
from ahriman.application.lock import Lock
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.exceptions import ExitCode, MissingArchitecture, MultipleArchitectures
|
from ahriman.core.exceptions import ExitCode, MissingArchitectureError, MultipleArchitecturesError
|
||||||
|
from ahriman.core.log import Log
|
||||||
from ahriman.models.repository_paths import RepositoryPaths
|
from ahriman.models.repository_paths import RepositoryPaths
|
||||||
|
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ class Handler:
|
|||||||
be called directly. The recommended way is to call ``execute`` class method, e.g.::
|
be called directly. The recommended way is to call ``execute`` class method, e.g.::
|
||||||
|
|
||||||
>>> from ahriman.application.handlers import Add
|
>>> from ahriman.application.handlers import Add
|
||||||
|
>>>
|
||||||
>>> Add.execute(args)
|
>>> Add.execute(args)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -67,7 +69,7 @@ class Handler:
|
|||||||
if not cls.ALLOW_AUTO_ARCHITECTURE_RUN and args.architecture is None:
|
if not cls.ALLOW_AUTO_ARCHITECTURE_RUN and args.architecture is None:
|
||||||
# for some parsers (e.g. config) we need to run with specific architecture
|
# for some parsers (e.g. config) we need to run with specific architecture
|
||||||
# for those cases architecture must be set explicitly
|
# for those cases architecture must be set explicitly
|
||||||
raise MissingArchitecture(args.command)
|
raise MissingArchitectureError(args.command)
|
||||||
if args.architecture: # architecture is specified explicitly
|
if args.architecture: # architecture is specified explicitly
|
||||||
return sorted(set(args.architecture))
|
return sorted(set(args.architecture))
|
||||||
|
|
||||||
@ -78,7 +80,7 @@ class Handler:
|
|||||||
architectures = RepositoryPaths.known_architectures(root)
|
architectures = RepositoryPaths.known_architectures(root)
|
||||||
|
|
||||||
if not architectures: # well we did not find anything
|
if not architectures: # well we did not find anything
|
||||||
raise MissingArchitecture(args.command)
|
raise MissingArchitectureError(args.command)
|
||||||
return sorted(architectures)
|
return sorted(architectures)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -94,9 +96,10 @@ class Handler:
|
|||||||
bool: True on success, False otherwise
|
bool: True on success, False otherwise
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
configuration = Configuration.from_path(args.configuration, architecture, args.quiet)
|
configuration = Configuration.from_path(args.configuration, architecture)
|
||||||
|
Log.load(configuration, quiet=args.quiet, report=args.report)
|
||||||
with Lock(args, architecture, configuration):
|
with Lock(args, architecture, configuration):
|
||||||
cls.run(args, architecture, configuration, args.no_report, args.unsafe)
|
cls.run(args, architecture, configuration, report=args.report, unsafe=args.unsafe)
|
||||||
return True
|
return True
|
||||||
except ExitCode:
|
except ExitCode:
|
||||||
return False
|
return False
|
||||||
@ -124,7 +127,7 @@ class Handler:
|
|||||||
# actually we do not have to spawn another process if it is single-process application, do we?
|
# actually we do not have to spawn another process if it is single-process application, do we?
|
||||||
if len(architectures) > 1:
|
if len(architectures) > 1:
|
||||||
if not cls.ALLOW_MULTI_ARCHITECTURE_RUN:
|
if not cls.ALLOW_MULTI_ARCHITECTURE_RUN:
|
||||||
raise MultipleArchitectures(args.command)
|
raise MultipleArchitecturesError(args.command)
|
||||||
|
|
||||||
with Pool(len(architectures)) as pool:
|
with Pool(len(architectures)) as pool:
|
||||||
result = pool.starmap(
|
result = pool.starmap(
|
||||||
@ -135,8 +138,8 @@ class Handler:
|
|||||||
return 0 if all(result) else 1
|
return 0 if all(result) else 1
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -144,7 +147,7 @@ class Handler:
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
|
@ -33,8 +33,8 @@ class Help(Handler):
|
|||||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ class Help(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
parser: argparse.ArgumentParser = args.parser()
|
parser: argparse.ArgumentParser = args.parser()
|
||||||
|
@ -34,8 +34,8 @@ class KeyImport(Handler):
|
|||||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -43,8 +43,8 @@ class KeyImport(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
Application(architecture, configuration, no_report, unsafe).repository.sign.key_import(
|
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||||
args.key_server, args.key)
|
application.repository.sign.key_import(args.key_server, args.key)
|
||||||
|
@ -18,17 +18,19 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
import argparse
|
import argparse
|
||||||
|
import sys
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Optional, Type
|
from typing import List, Optional, Tuple, Type
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers import Handler
|
from ahriman.application.handlers import Handler
|
||||||
from ahriman.core.build_tools.sources import Sources
|
from ahriman.core.build_tools.sources import Sources
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import StringPrinter
|
from ahriman.core.formatters import PatchPrinter
|
||||||
from ahriman.models.action import Action
|
from ahriman.models.action import Action
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
|
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
||||||
|
|
||||||
|
|
||||||
class Patch(Handler):
|
class Patch(Handler):
|
||||||
@ -37,8 +39,8 @@ 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, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -46,56 +48,98 @@ class Patch(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
application = Application(architecture, configuration, no_report, unsafe)
|
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||||
|
application.on_start()
|
||||||
|
|
||||||
if args.action == Action.List:
|
if args.action == Action.Update and args.variable is not None:
|
||||||
Patch.patch_set_list(application, args.package, args.exit_code)
|
patch = Patch.patch_create_from_function(args.variable, args.patch)
|
||||||
|
Patch.patch_set_create(application, args.package, patch)
|
||||||
|
elif args.action == Action.Update and args.variable is None:
|
||||||
|
package_base, patch = Patch.patch_create_from_diff(args.package, args.track)
|
||||||
|
Patch.patch_set_create(application, package_base, patch)
|
||||||
|
elif args.action == Action.List:
|
||||||
|
Patch.patch_set_list(application, args.package, args.variable, args.exit_code)
|
||||||
elif args.action == Action.Remove:
|
elif args.action == Action.Remove:
|
||||||
Patch.patch_set_remove(application, args.package)
|
Patch.patch_set_remove(application, args.package, args.variable)
|
||||||
elif args.action == Action.Update:
|
|
||||||
Patch.patch_set_create(application, Path(args.package), args.track)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def patch_set_create(application: Application, sources_dir: Path, track: List[str]) -> None:
|
def patch_create_from_diff(sources_dir: Path, track: List[str]) -> Tuple[str, PkgbuildPatch]:
|
||||||
|
"""
|
||||||
|
create PKGBUILD plain diff patches from sources directory
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sources_dir(Path): path to directory with the package sources
|
||||||
|
track(List[str]): track files which match the glob before creating the patch
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple[str, PkgbuildPatch]: package base and created PKGBUILD patch based on the diff from master HEAD
|
||||||
|
to current files
|
||||||
|
"""
|
||||||
|
package = Package.from_build(sources_dir)
|
||||||
|
patch = Sources.patch_create(sources_dir, *track)
|
||||||
|
return package.base, PkgbuildPatch(None, patch)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def patch_create_from_function(variable: str, patch_path: Optional[Path]) -> PkgbuildPatch:
|
||||||
|
"""
|
||||||
|
create single-function patch set for the package base
|
||||||
|
|
||||||
|
Args:
|
||||||
|
variable(str): function or variable name inside PKGBUILD
|
||||||
|
patch_path(Path): optional path to patch content. If not set, it will be read from stdin
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
PkgbuildPatch: created patch for the PKGBUILD function
|
||||||
|
"""
|
||||||
|
if patch_path is None:
|
||||||
|
print("Post new function or variable value below. Press Ctrl-D to finish:", file=sys.stderr)
|
||||||
|
patch = "".join(list(sys.stdin))
|
||||||
|
else:
|
||||||
|
patch = patch_path.read_text(encoding="utf8")
|
||||||
|
patch = patch.strip() # remove spaces around the patch
|
||||||
|
return PkgbuildPatch(variable, patch)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def patch_set_create(application: Application, package_base: str, patch: PkgbuildPatch) -> None:
|
||||||
"""
|
"""
|
||||||
create patch set for the package base
|
create patch set for the package base
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
application(Application): application instance
|
application(Application): application instance
|
||||||
sources_dir(Path): path to directory with the package sources
|
package_base(str): package base
|
||||||
track(List[str]): track files which match the glob before creating the patch
|
patch(PkgbuildPatch): patch descriptor
|
||||||
"""
|
"""
|
||||||
package = Package.from_build(sources_dir)
|
application.database.patches_insert(package_base, patch)
|
||||||
patch = Sources.patch_create(sources_dir, *track)
|
|
||||||
application.database.patches_insert(package.base, patch)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def patch_set_list(application: Application, package_base: Optional[str], exit_code: bool) -> None:
|
def patch_set_list(application: Application, package_base: Optional[str], variables: List[str],
|
||||||
|
exit_code: bool) -> None:
|
||||||
"""
|
"""
|
||||||
list patches available for the package base
|
list patches available for the package base
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
application(Application): application instance
|
application(Application): application instance
|
||||||
package_base(Optional[str]): package base
|
package_base(Optional[str]): package base
|
||||||
|
variables(List[str]): extract patches only for specified PKGBUILD variables
|
||||||
exit_code(bool): exit with error on empty search result
|
exit_code(bool): exit with error on empty search result
|
||||||
"""
|
"""
|
||||||
patches = application.database.patches_list(package_base)
|
patches = application.database.patches_list(package_base, variables)
|
||||||
Patch.check_if_empty(exit_code, not patches)
|
Patch.check_if_empty(exit_code, not patches)
|
||||||
|
|
||||||
for base, patch in patches.items():
|
for base, patch in patches.items():
|
||||||
content = base if package_base is None else patch
|
PatchPrinter(base, patch).print(verbose=True, separator=" = ")
|
||||||
StringPrinter(content).print(verbose=True)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def patch_set_remove(application: Application, package_base: str) -> None:
|
def patch_set_remove(application: Application, package_base: str, variables: List[str]) -> None:
|
||||||
"""
|
"""
|
||||||
remove patch set for the package base
|
remove patch set for the package base
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
application(Application): application instance
|
application(Application): application instance
|
||||||
package_base(str): package base
|
package_base(str): package base
|
||||||
|
variables(List[str]): remove patches only for specified PKGBUILD variables
|
||||||
"""
|
"""
|
||||||
application.database.patches_remove(package_base)
|
application.database.patches_remove(package_base, variables)
|
||||||
|
@ -34,8 +34,8 @@ 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, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -43,16 +43,16 @@ class Rebuild(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): 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, unsafe)
|
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||||
if args.from_database:
|
application.on_start()
|
||||||
updates = Rebuild.extract_packages(application)
|
|
||||||
else:
|
packages = Rebuild.extract_packages(application, from_database=args.from_database)
|
||||||
updates = application.repository.packages_depend_on(depends_on)
|
updates = application.repository.packages_depend_on(packages, depends_on)
|
||||||
|
|
||||||
Rebuild.check_if_empty(args.exit_code, not updates)
|
Rebuild.check_if_empty(args.exit_code, not updates)
|
||||||
if args.dry_run:
|
if args.dry_run:
|
||||||
@ -64,14 +64,17 @@ class Rebuild(Handler):
|
|||||||
Rebuild.check_if_empty(args.exit_code, result.is_empty)
|
Rebuild.check_if_empty(args.exit_code, result.is_empty)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def extract_packages(application: Application) -> List[Package]:
|
def extract_packages(application: Application, *, from_database: bool) -> List[Package]:
|
||||||
"""
|
"""
|
||||||
extract packages from database file
|
extract packages from database file
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
application(Application): application instance
|
application(Application): application instance
|
||||||
|
from_database(bool): extract packages from database instead of repository filesystem
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[Package]: list of packages which were stored in database
|
List[Package]: list of packages which were stored in database
|
||||||
"""
|
"""
|
||||||
return [package for (package, _) in application.database.packages_get()]
|
if from_database:
|
||||||
|
return [package for (package, _) in application.database.packages_get()]
|
||||||
|
return application.repository.packages()
|
||||||
|
@ -32,8 +32,8 @@ 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, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -41,7 +41,9 @@ class Remove(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
Application(architecture, configuration, no_report, unsafe).remove(args.package)
|
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||||
|
application.on_start()
|
||||||
|
application.remove(args.package)
|
||||||
|
@ -33,8 +33,8 @@ 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, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -42,15 +42,16 @@ class RemoveUnknown(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
application = Application(architecture, configuration, no_report, unsafe)
|
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||||
|
application.on_start()
|
||||||
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):
|
||||||
StringPrinter(package).print(args.info)
|
StringPrinter(package).print(False)
|
||||||
return
|
return
|
||||||
|
|
||||||
application.remove(unknown_packages)
|
application.remove(unknown_packages)
|
||||||
|
@ -34,8 +34,8 @@ class Restore(Handler):
|
|||||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ class Restore(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
with TarFile(args.path) as archive:
|
with TarFile(args.path) as archive:
|
||||||
|
@ -26,7 +26,7 @@ from ahriman.application.application import Application
|
|||||||
from ahriman.application.handlers import Handler
|
from ahriman.application.handlers import Handler
|
||||||
from ahriman.core.alpm.remote import AUR, Official
|
from ahriman.core.alpm.remote import AUR, Official
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.exceptions import InvalidOption
|
from ahriman.core.exceptions import OptionError
|
||||||
from ahriman.core.formatters import AurPrinter
|
from ahriman.core.formatters import AurPrinter
|
||||||
from ahriman.models.aur_package import AURPackage
|
from ahriman.models.aur_package import AURPackage
|
||||||
|
|
||||||
@ -43,8 +43,8 @@ class Search(Handler):
|
|||||||
SORT_FIELDS = {field.name for field in fields(AURPackage) if field.default_factory is not list}
|
SORT_FIELDS = {field.name for field in fields(AURPackage) if field.default_factory is not list}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -52,10 +52,10 @@ class Search(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
application = Application(architecture, configuration, no_report, unsafe)
|
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||||
|
|
||||||
official_packages_list = Official.multisearch(*args.search, pacman=application.repository.pacman)
|
official_packages_list = Official.multisearch(*args.search, pacman=application.repository.pacman)
|
||||||
aur_packages_list = AUR.multisearch(*args.search, pacman=application.repository.pacman)
|
aur_packages_list = AUR.multisearch(*args.search, pacman=application.repository.pacman)
|
||||||
@ -82,7 +82,7 @@ class Search(Handler):
|
|||||||
InvalidOption: if search fields is not in list of allowed ones
|
InvalidOption: if search fields is not in list of allowed ones
|
||||||
"""
|
"""
|
||||||
if sort_by not in Search.SORT_FIELDS:
|
if sort_by not in Search.SORT_FIELDS:
|
||||||
raise InvalidOption(sort_by)
|
raise OptionError(sort_by)
|
||||||
# always sort by package name at the last
|
# always sort by package name at the last
|
||||||
# well technically it is not a string, but we can deal with it
|
# well technically it is not a string, but we can deal with it
|
||||||
comparator: Callable[[AURPackage], Tuple[str, str]] =\
|
comparator: Callable[[AURPackage], Tuple[str, str]] =\
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from pwd import getpwuid
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
@ -34,21 +35,19 @@ class Setup(Handler):
|
|||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
ARCHBUILD_COMMAND_PATH(Path): (class attribute) default devtools command
|
ARCHBUILD_COMMAND_PATH(Path): (class attribute) default devtools command
|
||||||
BIN_DIR_PATH(Path): (class attribute) directory for custom binaries
|
|
||||||
MIRRORLIST_PATH(Path): (class attribute) path to pacman default mirrorlist (used by multilib repository)
|
MIRRORLIST_PATH(Path): (class attribute) path to pacman default mirrorlist (used by multilib repository)
|
||||||
SUDOERS_PATH(Path): (class attribute) path to sudoers.d include configuration
|
SUDOERS_DIR_PATH(Path): (class attribute) path to sudoers.d includes directory
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
||||||
|
|
||||||
ARCHBUILD_COMMAND_PATH = Path("/usr/bin/archbuild")
|
ARCHBUILD_COMMAND_PATH = Path("/usr/bin/archbuild")
|
||||||
BIN_DIR_PATH = Path("/usr/local/bin")
|
|
||||||
MIRRORLIST_PATH = Path("/etc/pacman.d/mirrorlist")
|
MIRRORLIST_PATH = Path("/etc/pacman.d/mirrorlist")
|
||||||
SUDOERS_PATH = Path("/etc/sudoers.d/ahriman")
|
SUDOERS_DIR_PATH = Path("/etc/sudoers.d")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -56,39 +55,43 @@ class Setup(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
Setup.configuration_create_ahriman(args, architecture, args.repository, configuration.include)
|
Setup.configuration_create_ahriman(args, architecture, args.repository, configuration.include,
|
||||||
|
configuration.repository_paths)
|
||||||
configuration.reload()
|
configuration.reload()
|
||||||
|
|
||||||
application = Application(architecture, configuration, no_report, unsafe)
|
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||||
|
|
||||||
Setup.configuration_create_makepkg(args.packager, application.repository.paths)
|
Setup.configuration_create_makepkg(args.packager, args.makeflags_jobs, application.repository.paths)
|
||||||
Setup.executable_create(args.build_command, architecture)
|
Setup.executable_create(application.repository.paths, 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,
|
||||||
args.no_multilib, args.repository, application.repository.paths)
|
args.multilib, args.repository, application.repository.paths)
|
||||||
Setup.configuration_create_sudo(args.build_command, architecture)
|
Setup.configuration_create_sudo(application.repository.paths, args.build_command, architecture)
|
||||||
|
|
||||||
application.repository.repo.init()
|
application.repository.repo.init()
|
||||||
|
# lazy database sync
|
||||||
|
application.repository.pacman.handle # pylint: disable=pointless-statement
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def build_command(prefix: str, architecture: str) -> Path:
|
def build_command(root: Path, prefix: str, architecture: str) -> Path:
|
||||||
"""
|
"""
|
||||||
generate build command name
|
generate build command name
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
root(Path): root directory for the build command (must be root of the repository)
|
||||||
prefix(str): command prefix in {prefix}-{architecture}-build
|
prefix(str): command prefix in {prefix}-{architecture}-build
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Path: valid devtools command name
|
Path: valid devtools command name
|
||||||
"""
|
"""
|
||||||
return Setup.BIN_DIR_PATH / f"{prefix}-{architecture}-build"
|
return root / f"{prefix}-{architecture}-build"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def configuration_create_ahriman(args: argparse.Namespace, architecture: str, repository: str,
|
def configuration_create_ahriman(args: argparse.Namespace, architecture: str, repository: str,
|
||||||
include_path: Path) -> None:
|
include_path: Path, paths: RepositoryPaths) -> None:
|
||||||
"""
|
"""
|
||||||
create service specific configuration
|
create service specific configuration
|
||||||
|
|
||||||
@ -97,11 +100,13 @@ class Setup(Handler):
|
|||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
repository(str): repository name
|
repository(str): repository name
|
||||||
include_path(Path): path to directory with configuration includes
|
include_path(Path): path to directory with configuration includes
|
||||||
|
paths(RepositoryPaths): repository paths instance
|
||||||
"""
|
"""
|
||||||
configuration = Configuration()
|
configuration = Configuration()
|
||||||
|
|
||||||
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)))
|
build_command = Setup.build_command(paths.root, args.build_command, architecture)
|
||||||
|
configuration.set_option(section, "build_command", str(build_command))
|
||||||
configuration.set_option("repository", "name", repository)
|
configuration.set_option("repository", "name", repository)
|
||||||
if args.build_as_user is not None:
|
if args.build_as_user is not None:
|
||||||
configuration.set_option(section, "makechrootpkg_flags", f"-U {args.build_as_user}")
|
configuration.set_option(section, "makechrootpkg_flags", f"-U {args.build_as_user}")
|
||||||
@ -115,25 +120,34 @@ class Setup(Handler):
|
|||||||
section = Configuration.section_name("web", architecture)
|
section = Configuration.section_name("web", architecture)
|
||||||
configuration.set_option(section, "port", str(args.web_port))
|
configuration.set_option(section, "port", str(args.web_port))
|
||||||
|
|
||||||
target = include_path / "setup-overrides.ini"
|
if args.web_unix_socket is not None:
|
||||||
|
section = Configuration.section_name("web", architecture)
|
||||||
|
configuration.set_option(section, "unix_socket", str(args.web_unix_socket))
|
||||||
|
|
||||||
|
target = include_path / "00-setup-overrides.ini"
|
||||||
with target.open("w") as ahriman_configuration:
|
with target.open("w") as ahriman_configuration:
|
||||||
configuration.write(ahriman_configuration)
|
configuration.write(ahriman_configuration)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def configuration_create_devtools(prefix: str, architecture: str, source: Path,
|
def configuration_create_devtools(prefix: str, architecture: str, source: Path,
|
||||||
no_multilib: bool, repository: str, paths: RepositoryPaths) -> None:
|
multilib: bool, repository: str, paths: RepositoryPaths) -> None:
|
||||||
"""
|
"""
|
||||||
create configuration for devtools based on ``source`` configuration
|
create configuration for devtools based on ``source`` configuration
|
||||||
|
|
||||||
|
Note:
|
||||||
|
devtools does not allow to specify the pacman configuration, thus we still have to use configuration in /usr
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
prefix(str): command prefix in {prefix}-{architecture}-build
|
prefix(str): command prefix in {prefix}-{architecture}-build
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
source(Path): path to source configuration file
|
source(Path): path to source configuration file
|
||||||
no_multilib(bool): do not add multilib repository
|
multilib(bool): add or do not multilib repository to the configuration
|
||||||
repository(str): repository name
|
repository(str): repository name
|
||||||
paths(RepositoryPaths): repository paths instance
|
paths(RepositoryPaths): repository paths instance
|
||||||
"""
|
"""
|
||||||
configuration = Configuration()
|
# allow_no_value=True is required because pacman uses boolean configuration in which just keys present
|
||||||
|
# (e.g. NoProgressBar) which will lead to exception
|
||||||
|
configuration = Configuration(allow_no_value=True)
|
||||||
# preserve case
|
# preserve case
|
||||||
# stupid mypy thinks that it is impossible
|
# stupid mypy thinks that it is impossible
|
||||||
configuration.optionxform = lambda key: key # type: ignore
|
configuration.optionxform = lambda key: key # type: ignore
|
||||||
@ -146,7 +160,7 @@ class Setup(Handler):
|
|||||||
configuration.set_option("options", "Architecture", architecture)
|
configuration.set_option("options", "Architecture", architecture)
|
||||||
|
|
||||||
# add multilib
|
# add multilib
|
||||||
if not no_multilib:
|
if multilib:
|
||||||
configuration.set_option("multilib", "Include", str(Setup.MIRRORLIST_PATH))
|
configuration.set_option("multilib", "Include", str(Setup.MIRRORLIST_PATH))
|
||||||
|
|
||||||
# add repository itself
|
# add repository itself
|
||||||
@ -158,38 +172,50 @@ class Setup(Handler):
|
|||||||
configuration.write(devtools_configuration)
|
configuration.write(devtools_configuration)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def configuration_create_makepkg(packager: str, paths: RepositoryPaths) -> None:
|
def configuration_create_makepkg(packager: str, makeflags_jobs: bool, paths: RepositoryPaths) -> None:
|
||||||
"""
|
"""
|
||||||
create configuration for makepkg
|
create configuration for makepkg
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
packager(str): packager identifier (e.g. name, email)
|
packager(str): packager identifier (e.g. name, email)
|
||||||
|
makeflags_jobs(bool): set MAKEFLAGS variable to number of cores
|
||||||
paths(RepositoryPaths): repository paths instance
|
paths(RepositoryPaths): repository paths instance
|
||||||
"""
|
"""
|
||||||
(paths.root / ".makepkg.conf").write_text(f"PACKAGER='{packager}'\n", encoding="utf8")
|
|
||||||
|
content = f"PACKAGER='{packager}'\n"
|
||||||
|
if makeflags_jobs:
|
||||||
|
content += """MAKEFLAGS="-j$(nproc)"\n"""
|
||||||
|
|
||||||
|
uid, _ = paths.root_owner
|
||||||
|
home_dir = Path(getpwuid(uid).pw_dir)
|
||||||
|
(home_dir / ".makepkg.conf").write_text(content, encoding="utf8")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def configuration_create_sudo(prefix: str, architecture: str) -> None:
|
def configuration_create_sudo(paths: RepositoryPaths, prefix: str, architecture: str) -> None:
|
||||||
"""
|
"""
|
||||||
create configuration to run build command with sudo without password
|
create configuration to run build command with sudo without password
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
paths(RepositoryPaths): repository paths instance
|
||||||
prefix(str): command prefix in {prefix}-{architecture}-build
|
prefix(str): command prefix in {prefix}-{architecture}-build
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
"""
|
"""
|
||||||
command = Setup.build_command(prefix, architecture)
|
command = Setup.build_command(paths.root, prefix, architecture)
|
||||||
Setup.SUDOERS_PATH.write_text(f"ahriman ALL=(ALL) NOPASSWD: {command} *\n", encoding="utf8")
|
sudoers_file = Setup.build_command(Setup.SUDOERS_DIR_PATH, prefix, architecture)
|
||||||
Setup.SUDOERS_PATH.chmod(0o400) # security!
|
sudoers_file.write_text(f"ahriman ALL=(ALL) NOPASSWD: {command} *\n", encoding="utf8")
|
||||||
|
sudoers_file.chmod(0o400) # security!
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def executable_create(prefix: str, architecture: str) -> None:
|
def executable_create(paths: RepositoryPaths, prefix: str, architecture: str) -> None:
|
||||||
"""
|
"""
|
||||||
create executable for the service
|
create executable for the service
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
paths(RepositoryPaths): repository paths instance
|
||||||
prefix(str): command prefix in {prefix}-{architecture}-build
|
prefix(str): command prefix in {prefix}-{architecture}-build
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
"""
|
"""
|
||||||
command = Setup.build_command(prefix, architecture)
|
command = Setup.build_command(paths.root, prefix, architecture)
|
||||||
command.unlink(missing_ok=True)
|
command.unlink(missing_ok=True)
|
||||||
command.symlink_to(Setup.ARCHBUILD_COMMAND_PATH)
|
command.symlink_to(Setup.ARCHBUILD_COMMAND_PATH)
|
||||||
|
paths.chown(command) # we would like to keep owner inside ahriman's home
|
||||||
|
@ -38,8 +38,8 @@ class Shell(Handler):
|
|||||||
ALLOW_MULTI_ARCHITECTURE_RUN = False
|
ALLOW_MULTI_ARCHITECTURE_RUN = False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -47,13 +47,17 @@ class Shell(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
# pylint: disable=possibly-unused-variable
|
# pylint: disable=possibly-unused-variable
|
||||||
application = Application(architecture, configuration, no_report, unsafe)
|
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
# licensed by https://creativecommons.org/licenses/by-sa/3.0
|
# licensed by https://creativecommons.org/licenses/by-sa/3.0
|
||||||
path = Path(sys.prefix) / "share" / "ahriman" / "templates" / "shell"
|
path = Path(sys.prefix) / "share" / "ahriman" / "templates" / "shell"
|
||||||
StringPrinter(path.read_text(encoding="utf8")).print(verbose=False)
|
StringPrinter(path.read_text(encoding="utf8")).print(verbose=False)
|
||||||
code.interact(local=locals())
|
# we only want to pass application isntance inside
|
||||||
|
if args.code is None:
|
||||||
|
code.interact(local={"application": application})
|
||||||
|
else:
|
||||||
|
code.InteractiveConsole(locals={"application": application}).runcode(args.code)
|
||||||
|
@ -32,8 +32,8 @@ 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, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ class Sign(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
Application(architecture, configuration, no_report, unsafe).sign(args.package)
|
Application(architecture, configuration, report=report, unsafe=unsafe).sign(args.package)
|
||||||
|
@ -37,8 +37,8 @@ class Status(Handler):
|
|||||||
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -46,11 +46,11 @@ class Status(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): 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, unsafe=unsafe).repository.reporter
|
client = Application(architecture, configuration, report=True, unsafe=unsafe).repository.reporter
|
||||||
if args.ahriman:
|
if args.ahriman:
|
||||||
service_status = client.get_internal()
|
service_status = client.get_internal()
|
||||||
StatusPrinter(service_status.status).print(args.info)
|
StatusPrinter(service_status.status).print(args.info)
|
||||||
|
@ -35,8 +35,8 @@ class StatusUpdate(Handler):
|
|||||||
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -44,11 +44,11 @@ class StatusUpdate(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): 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, unsafe=unsafe).repository.reporter
|
client = Application(architecture, configuration, report=True, 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
|
||||||
|
56
src/ahriman/application/handlers/structure.py
Normal file
56
src/ahriman/application/handlers/structure.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2021-2022 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 Type
|
||||||
|
|
||||||
|
from ahriman.application.application import Application
|
||||||
|
from ahriman.application.handlers import Handler
|
||||||
|
from ahriman.core.configuration import Configuration
|
||||||
|
from ahriman.core.formatters import TreePrinter
|
||||||
|
from ahriman.core.tree import Tree
|
||||||
|
|
||||||
|
|
||||||
|
class Structure(Handler):
|
||||||
|
"""
|
||||||
|
dump repository structure handler
|
||||||
|
"""
|
||||||
|
|
||||||
|
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
|
report: bool, unsafe: bool) -> None:
|
||||||
|
"""
|
||||||
|
callback for command line
|
||||||
|
|
||||||
|
Args:
|
||||||
|
args(argparse.Namespace): command line args
|
||||||
|
architecture(str): repository architecture
|
||||||
|
configuration(Configuration): configuration instance
|
||||||
|
report(bool): force enable or disable reporting
|
||||||
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
|
"""
|
||||||
|
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||||
|
packages = application.repository.packages()
|
||||||
|
|
||||||
|
tree = Tree.resolve(packages, application.repository.paths, application.database)
|
||||||
|
for num, level in enumerate(tree):
|
||||||
|
TreePrinter(num, level).print(verbose=True, separator=" ")
|
@ -33,8 +33,8 @@ class Triggers(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, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -42,11 +42,12 @@ class Triggers(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
application = Application(architecture, configuration, no_report, unsafe)
|
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||||
if args.trigger:
|
if args.trigger:
|
||||||
loader = application.repository.triggers
|
loader = application.repository.triggers
|
||||||
loader.triggers = [loader.load_trigger(trigger) for trigger in args.trigger]
|
loader.triggers = [loader.load_trigger(trigger) for trigger in args.trigger]
|
||||||
application.repository.process_triggers(Result())
|
application.on_start()
|
||||||
|
application.on_result(Result())
|
||||||
|
@ -35,8 +35,8 @@ class UnsafeCommands(Handler):
|
|||||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ class UnsafeCommands(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
parser = args.parser()
|
parser = args.parser()
|
||||||
@ -79,6 +79,7 @@ class UnsafeCommands(Handler):
|
|||||||
Returns:
|
Returns:
|
||||||
List[str]: list of commands with default unsafe flag
|
List[str]: list of commands with default unsafe flag
|
||||||
"""
|
"""
|
||||||
|
# should never fail
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
subparser = next(action for action in parser._actions if isinstance(action, argparse._SubParsersAction))
|
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")]
|
return [action_name for action_name, action in subparser.choices.items() if action.get_default("unsafe")]
|
||||||
|
@ -32,8 +32,8 @@ 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, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -41,12 +41,14 @@ class Update(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
application = Application(architecture, configuration, no_report, unsafe)
|
application = Application(architecture, configuration, report=report, unsafe=unsafe,
|
||||||
packages = application.updates(args.package, args.no_aur, args.no_local, args.no_manual, args.no_vcs,
|
refresh_pacman_database=args.refresh)
|
||||||
Update.log_fn(application, args.dry_run))
|
application.on_start()
|
||||||
|
packages = application.updates(args.package, aur=args.aur, local=args.local, manual=args.manual, vcs=args.vcs,
|
||||||
|
log_fn=Update.log_fn(application, args.dry_run))
|
||||||
Update.check_if_empty(args.exit_code, not packages)
|
Update.check_if_empty(args.exit_code, not packages)
|
||||||
if args.dry_run:
|
if args.dry_run:
|
||||||
return
|
return
|
||||||
|
@ -21,11 +21,12 @@ import argparse
|
|||||||
import getpass
|
import getpass
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Type
|
from typing import Optional, Tuple, Type
|
||||||
|
|
||||||
from ahriman.application.handlers import Handler
|
from ahriman.application.handlers import Handler
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.database import SQLite
|
from ahriman.core.database import SQLite
|
||||||
|
from ahriman.core.exceptions import PasswordError
|
||||||
from ahriman.core.formatters import UserPrinter
|
from ahriman.core.formatters import UserPrinter
|
||||||
from ahriman.models.action import Action
|
from ahriman.models.action import Action
|
||||||
from ahriman.models.user import User
|
from ahriman.models.user import User
|
||||||
@ -39,8 +40,8 @@ class Users(Handler):
|
|||||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -48,18 +49,19 @@ class Users(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
database = SQLite.load(configuration)
|
database = SQLite.load(configuration)
|
||||||
|
|
||||||
if args.action == Action.Update:
|
if args.action == Action.Update:
|
||||||
salt = Users.get_salt(configuration)
|
old_salt, salt = Users.get_salt(configuration)
|
||||||
user = Users.user_create(args)
|
user = Users.user_create(args)
|
||||||
|
|
||||||
auth_configuration = Users.configuration_get(configuration.include)
|
if old_salt is None:
|
||||||
|
auth_configuration = Users.configuration_get(configuration.include)
|
||||||
|
Users.configuration_create(auth_configuration, salt, args.secure)
|
||||||
|
|
||||||
Users.configuration_create(auth_configuration, user, salt, args.as_service, args.secure)
|
|
||||||
database.user_update(user.hash_password(salt))
|
database.user_update(user.hash_password(salt))
|
||||||
elif args.action == Action.List:
|
elif args.action == Action.List:
|
||||||
users = database.user_list(args.username, args.role)
|
users = database.user_list(args.username, args.role)
|
||||||
@ -70,22 +72,16 @@ class Users(Handler):
|
|||||||
database.user_remove(args.username)
|
database.user_remove(args.username)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def configuration_create(configuration: Configuration, user: User, salt: str,
|
def configuration_create(configuration: Configuration, salt: str, secure: bool) -> None:
|
||||||
as_service_user: bool, secure: bool) -> None:
|
|
||||||
"""
|
"""
|
||||||
enable configuration if it has been disabled
|
enable configuration if it has been disabled
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
user(User): user descriptor
|
|
||||||
salt(str): password hash salt
|
salt(str): password hash salt
|
||||||
as_service_user(bool): add user as service user, also set password and user to configuration
|
|
||||||
secure(bool): if true then set file permissions to 0o600
|
secure(bool): if true then set file permissions to 0o600
|
||||||
"""
|
"""
|
||||||
configuration.set_option("auth", "salt", salt)
|
configuration.set_option("auth", "salt", salt)
|
||||||
if as_service_user:
|
|
||||||
configuration.set_option("web", "username", user.username)
|
|
||||||
configuration.set_option("web", "password", user.password)
|
|
||||||
Users.configuration_write(configuration, secure)
|
Users.configuration_write(configuration, secure)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -99,7 +95,7 @@ class Users(Handler):
|
|||||||
Returns:
|
Returns:
|
||||||
Configuration: configuration instance. In case if there are local settings they will be loaded
|
Configuration: configuration instance. In case if there are local settings they will be loaded
|
||||||
"""
|
"""
|
||||||
target = include_path / "auth.ini"
|
target = include_path / "00-auth.ini"
|
||||||
configuration = Configuration()
|
configuration = Configuration()
|
||||||
configuration.load(target)
|
configuration.load(target)
|
||||||
|
|
||||||
@ -123,7 +119,7 @@ class Users(Handler):
|
|||||||
path.chmod(0o600)
|
path.chmod(0o600)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_salt(configuration: Configuration, salt_length: int = 20) -> str:
|
def get_salt(configuration: Configuration, salt_length: int = 20) -> Tuple[Optional[str], str]:
|
||||||
"""
|
"""
|
||||||
get salt from configuration or create new string
|
get salt from configuration or create new string
|
||||||
|
|
||||||
@ -132,11 +128,12 @@ class Users(Handler):
|
|||||||
salt_length(int, optional): salt length (Default value = 20)
|
salt_length(int, optional): salt length (Default value = 20)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: current salt
|
Tuple[Optional[str], str]: tuple containing salt from configuration if any and actual salt which must be
|
||||||
|
used for password hash
|
||||||
"""
|
"""
|
||||||
if salt := configuration.get("auth", "salt", fallback=None):
|
if salt := configuration.get("auth", "salt", fallback=None):
|
||||||
return salt
|
return salt, salt
|
||||||
return User.generate_password(salt_length)
|
return None, User.generate_password(salt_length)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def user_create(args: argparse.Namespace) -> User:
|
def user_create(args: argparse.Namespace) -> User:
|
||||||
@ -149,7 +146,15 @@ class Users(Handler):
|
|||||||
Returns:
|
Returns:
|
||||||
User: built user descriptor
|
User: built user descriptor
|
||||||
"""
|
"""
|
||||||
|
def read_password() -> str:
|
||||||
|
first_password = getpass.getpass()
|
||||||
|
second_password = getpass.getpass("Repeat password: ")
|
||||||
|
if first_password != second_password:
|
||||||
|
raise PasswordError("passwords don't match")
|
||||||
|
return first_password
|
||||||
|
|
||||||
password = args.password
|
password = args.password
|
||||||
if password is None:
|
if password is None:
|
||||||
password = getpass.getpass()
|
password = read_password()
|
||||||
|
|
||||||
return User(username=args.username, password=password, access=args.role)
|
return User(username=args.username, password=password, access=args.role)
|
||||||
|
@ -37,8 +37,8 @@ class Versions(Handler):
|
|||||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ class Versions(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
"""
|
"""
|
||||||
VersionPrinter(f"Module version {version.__version__}",
|
VersionPrinter(f"Module version {version.__version__}",
|
||||||
|
@ -35,8 +35,8 @@ class Web(Handler):
|
|||||||
ALLOW_MULTI_ARCHITECTURE_RUN = False # required to be able to spawn external processes
|
ALLOW_MULTI_ARCHITECTURE_RUN = False # required to be able to spawn external processes
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||||
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
report: bool, unsafe: bool) -> None:
|
||||||
"""
|
"""
|
||||||
callback for command line
|
callback for command line
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ class Web(Handler):
|
|||||||
args(argparse.Namespace): command line args
|
args(argparse.Namespace): command line args
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
report(bool): force enable or disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): 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
|
||||||
|
@ -27,8 +27,8 @@ from typing import Literal, Optional, Type
|
|||||||
|
|
||||||
from ahriman import version
|
from ahriman import version
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.exceptions import DuplicateRun
|
from ahriman.core.exceptions import DuplicateRunError
|
||||||
from ahriman.core.lazy_logging import LazyLogging
|
from ahriman.core.log import LazyLogging
|
||||||
from ahriman.core.status.client import Client
|
from ahriman.core.status.client import Client
|
||||||
from ahriman.core.util import check_user
|
from ahriman.core.util import check_user
|
||||||
from ahriman.models.build_status import BuildStatusEnum
|
from ahriman.models.build_status import BuildStatusEnum
|
||||||
@ -73,7 +73,7 @@ class Lock(LazyLogging):
|
|||||||
self.unsafe = args.unsafe
|
self.unsafe = args.unsafe
|
||||||
|
|
||||||
self.paths = configuration.repository_paths
|
self.paths = configuration.repository_paths
|
||||||
self.reporter = Client() if args.no_report else Client.load(configuration)
|
self.reporter = Client.load(configuration, report=args.report)
|
||||||
|
|
||||||
def __enter__(self) -> Lock:
|
def __enter__(self) -> Lock:
|
||||||
"""
|
"""
|
||||||
@ -122,7 +122,7 @@ class Lock(LazyLogging):
|
|||||||
"""
|
"""
|
||||||
check if current user is actually owner of ahriman root
|
check if current user is actually owner of ahriman root
|
||||||
"""
|
"""
|
||||||
check_user(self.paths, self.unsafe)
|
check_user(self.paths, unsafe=self.unsafe)
|
||||||
|
|
||||||
def clear(self) -> None:
|
def clear(self) -> None:
|
||||||
"""
|
"""
|
||||||
@ -144,4 +144,4 @@ class Lock(LazyLogging):
|
|||||||
try:
|
try:
|
||||||
self.path.touch(exist_ok=self.force)
|
self.path.touch(exist_ok=self.force)
|
||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
raise DuplicateRun()
|
raise DuplicateRunError()
|
||||||
|
@ -17,3 +17,82 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
from contextvars import ContextVar
|
||||||
|
from typing import Any, Dict, Iterator, TypeVar
|
||||||
|
|
||||||
|
from ahriman.models.context_key import ContextKey
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
|
class _Context:
|
||||||
|
"""
|
||||||
|
simple ahriman global context implementation
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
"""
|
||||||
|
default constructor. Must not be used directly
|
||||||
|
"""
|
||||||
|
self._content: Dict[str, Any] = {}
|
||||||
|
|
||||||
|
def get(self, key: ContextKey[T]) -> T:
|
||||||
|
"""
|
||||||
|
get value for the specified key
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key(ContextKey[T]): context key name
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
T: value associated with the key
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
KeyError: in case if the specified context variable was not found
|
||||||
|
ValueError: in case if type of value is not an instance of specified return type
|
||||||
|
"""
|
||||||
|
if key.key not in self._content:
|
||||||
|
raise KeyError(key.key)
|
||||||
|
value = self._content[key.key]
|
||||||
|
if not isinstance(value, key.return_type):
|
||||||
|
raise ValueError(f"Value {value} is not an instance of {key.return_type}")
|
||||||
|
return value
|
||||||
|
|
||||||
|
def set(self, key: ContextKey[T], value: T) -> None:
|
||||||
|
"""
|
||||||
|
set value for the specified key
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key(ContextKey[T]): context key name
|
||||||
|
value(T): context value associated with the specified key
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
KeyError: in case if the specified context variable already exists
|
||||||
|
ValueError: in case if type of value is not an instance of specified return type
|
||||||
|
"""
|
||||||
|
if key.key in self._content:
|
||||||
|
raise KeyError(key.key)
|
||||||
|
if not isinstance(value, key.return_type):
|
||||||
|
raise ValueError(f"Value {value} is not an instance of {key.return_type}")
|
||||||
|
self._content[key.key] = value
|
||||||
|
|
||||||
|
def __iter__(self) -> Iterator[str]:
|
||||||
|
"""
|
||||||
|
iterate over keys in local storage
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: context key iterator
|
||||||
|
"""
|
||||||
|
return iter(self._content)
|
||||||
|
|
||||||
|
def __len__(self) -> int:
|
||||||
|
"""
|
||||||
|
get count of the context variables set
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: count of stored context variables
|
||||||
|
"""
|
||||||
|
return len(self._content)
|
||||||
|
|
||||||
|
|
||||||
|
context = ContextVar("context", default=_Context())
|
||||||
|
@ -17,13 +17,18 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
from pyalpm import Handle, Package, SIG_PACKAGE # type: ignore
|
import shutil
|
||||||
from typing import Generator, Set
|
|
||||||
|
from pathlib import Path
|
||||||
|
from pyalpm import DB, Handle, Package, SIG_PACKAGE, error as PyalpmError # type: ignore
|
||||||
|
from typing import Any, Callable, Generator, Set
|
||||||
|
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
from ahriman.core.log import LazyLogging
|
||||||
|
from ahriman.models.repository_paths import RepositoryPaths
|
||||||
|
|
||||||
|
|
||||||
class Pacman:
|
class Pacman(LazyLogging):
|
||||||
"""
|
"""
|
||||||
alpm wrapper
|
alpm wrapper
|
||||||
|
|
||||||
@ -31,35 +36,139 @@ class Pacman:
|
|||||||
handle(Handle): pyalpm root ``Handle``
|
handle(Handle): pyalpm root ``Handle``
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, configuration: Configuration) -> None:
|
handle: Handle
|
||||||
|
|
||||||
|
def __init__(self, architecture: str, configuration: Configuration, *, refresh_database: int) -> None:
|
||||||
"""
|
"""
|
||||||
default constructor
|
default constructor
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
|
refresh_database(int): synchronize local cache to remote. If set to ``0``, no syncronization will be
|
||||||
|
enabled, if set to ``1`` - normal syncronization, if set to ``2`` - force syncronization
|
||||||
"""
|
"""
|
||||||
root = configuration.get("alpm", "root")
|
self.__create_handle_fn: Callable[[], Handle] = lambda: self.__create_handle(
|
||||||
pacman_root = configuration.getpath("alpm", "database")
|
architecture, configuration, refresh_database=refresh_database)
|
||||||
self.handle = Handle(root, str(pacman_root))
|
|
||||||
for repository in configuration.getlist("alpm", "repositories"):
|
|
||||||
self.handle.register_syncdb(repository, SIG_PACKAGE)
|
|
||||||
|
|
||||||
def all_packages(self) -> Set[str]:
|
def __create_handle(self, architecture: str, configuration: Configuration, *, refresh_database: int) -> Handle:
|
||||||
"""
|
"""
|
||||||
get list of packages known for alpm
|
create lazy handle function
|
||||||
|
|
||||||
|
Args:
|
||||||
|
architecture(str): repository architecture
|
||||||
|
configuration(Configuration): configuration instance
|
||||||
|
refresh_database(int): synchronize local cache to remote. If set to ``0``, no syncronization will be
|
||||||
|
enabled, if set to ``1`` - normal syncronization, if set to ``2`` - force syncronization
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Set[str]: list of package names
|
Handle: fully initialized pacman handle
|
||||||
"""
|
"""
|
||||||
result: Set[str] = set()
|
root = configuration.getpath("alpm", "root")
|
||||||
for database in self.handle.get_syncdbs():
|
pacman_root = configuration.getpath("alpm", "database")
|
||||||
for package in database.pkgcache:
|
use_ahriman_cache = configuration.getboolean("alpm", "use_ahriman_cache")
|
||||||
result.add(package.name) # package itself
|
mirror = configuration.get("alpm", "mirror")
|
||||||
result.update(package.provides) # provides list for meta-packages
|
paths = configuration.repository_paths
|
||||||
|
database_path = paths.pacman if use_ahriman_cache else pacman_root
|
||||||
|
|
||||||
return result
|
handle = Handle(str(root), str(database_path))
|
||||||
|
for repository in configuration.getlist("alpm", "repositories"):
|
||||||
|
database = self.database_init(handle, repository, mirror, architecture)
|
||||||
|
self.database_copy(handle, database, pacman_root, paths, use_ahriman_cache=use_ahriman_cache)
|
||||||
|
|
||||||
def get(self, package_name: str) -> Generator[Package, None, None]:
|
if use_ahriman_cache and refresh_database:
|
||||||
|
self.database_sync(handle, force=refresh_database > 1)
|
||||||
|
|
||||||
|
return handle
|
||||||
|
|
||||||
|
def __getattr__(self, item: str) -> Any:
|
||||||
|
"""
|
||||||
|
pacman handle extractor
|
||||||
|
|
||||||
|
Args:
|
||||||
|
item(str): property name
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Any: attribute by its name
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
AttributeError: in case if no such attribute found
|
||||||
|
"""
|
||||||
|
if item == "handle":
|
||||||
|
handle = self.__create_handle_fn()
|
||||||
|
setattr(self, item, handle)
|
||||||
|
return handle
|
||||||
|
return super().__getattr__(item) # required for logging attribute
|
||||||
|
|
||||||
|
def database_copy(self, handle: Handle, database: DB, pacman_root: Path, paths: RepositoryPaths, *,
|
||||||
|
use_ahriman_cache: bool) -> None:
|
||||||
|
"""
|
||||||
|
copy database from the operating system root to the ahriman local home
|
||||||
|
|
||||||
|
Args:
|
||||||
|
handle(Handle): pacman handle which will be used for database copying
|
||||||
|
database(DB): pacman database instance to be copied
|
||||||
|
pacman_root(Path): operating system pacman root
|
||||||
|
paths(RepositoryPaths): repository paths instance
|
||||||
|
use_ahriman_cache(bool): use local ahriman cache instead of system one
|
||||||
|
"""
|
||||||
|
def repository_database(root: Path) -> Path:
|
||||||
|
return root / "sync" / f"{database.name}.db"
|
||||||
|
|
||||||
|
if not use_ahriman_cache:
|
||||||
|
return
|
||||||
|
# copy root database if no local copy found
|
||||||
|
pacman_db_path = Path(handle.dbpath)
|
||||||
|
if not pacman_db_path.is_dir():
|
||||||
|
return # root directory does not exist yet
|
||||||
|
dst = repository_database(pacman_db_path)
|
||||||
|
if dst.is_file():
|
||||||
|
return # file already exists, do not copy
|
||||||
|
src = repository_database(pacman_root)
|
||||||
|
if not src.is_file():
|
||||||
|
self.logger.warning("repository %s is set to be used, however, no working copy was found", database.name)
|
||||||
|
return # database for some reasons deos not exist
|
||||||
|
self.logger.info("copy pacman database from operating system root to ahriman's home")
|
||||||
|
shutil.copy(src, dst)
|
||||||
|
paths.chown(dst)
|
||||||
|
|
||||||
|
def database_init(self, handle: Handle, repository: str, mirror: str, architecture: str) -> DB:
|
||||||
|
"""
|
||||||
|
create database instance from pacman handler and set its properties
|
||||||
|
|
||||||
|
Args:
|
||||||
|
handle(Handle): pacman handle which will be used for database initializing
|
||||||
|
repository(str): pacman repository name (e.g. core)
|
||||||
|
mirror(str): arch linux mirror url
|
||||||
|
architecture(str): repository architecture
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
DB: loaded pacman database instance
|
||||||
|
"""
|
||||||
|
self.logger.info("loading pacman databases")
|
||||||
|
database: DB = handle.register_syncdb(repository, SIG_PACKAGE)
|
||||||
|
# replace variables in mirror address
|
||||||
|
database.servers = [mirror.replace("$repo", repository).replace("$arch", architecture)]
|
||||||
|
return database
|
||||||
|
|
||||||
|
def database_sync(self, handle: Handle, *, force: bool) -> None:
|
||||||
|
"""
|
||||||
|
sync local database
|
||||||
|
|
||||||
|
Args:
|
||||||
|
handle(Handle): pacman handle which will be used for database sync
|
||||||
|
force(bool): force database syncronization (same as ``pacman -Syy``)
|
||||||
|
"""
|
||||||
|
self.logger.info("refresh ahriman's home pacman database (force refresh %s)", force)
|
||||||
|
transaction = handle.init_transaction()
|
||||||
|
for database in handle.get_syncdbs():
|
||||||
|
try:
|
||||||
|
database.update(force)
|
||||||
|
except PyalpmError:
|
||||||
|
self.logger.exception("exception during update %s", database.name)
|
||||||
|
transaction.release()
|
||||||
|
|
||||||
|
def package_get(self, package_name: str) -> Generator[Package, None, None]:
|
||||||
"""
|
"""
|
||||||
retrieve list of the packages from the repository by name
|
retrieve list of the packages from the repository by name
|
||||||
|
|
||||||
@ -74,3 +183,18 @@ class Pacman:
|
|||||||
if package is None:
|
if package is None:
|
||||||
continue
|
continue
|
||||||
yield package
|
yield package
|
||||||
|
|
||||||
|
def packages(self) -> Set[str]:
|
||||||
|
"""
|
||||||
|
get list of packages known for alpm
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Set[str]: list of package names
|
||||||
|
"""
|
||||||
|
result: Set[str] = set()
|
||||||
|
for database in self.handle.get_syncdbs():
|
||||||
|
for package in database.pkgcache:
|
||||||
|
result.add(package.name) # package itself
|
||||||
|
result.update(package.provides) # provides list for meta-packages
|
||||||
|
|
||||||
|
return result
|
||||||
|
@ -23,7 +23,7 @@ from typing import Any, Dict, List, Type
|
|||||||
|
|
||||||
from ahriman.core.alpm.pacman import Pacman
|
from ahriman.core.alpm.pacman import Pacman
|
||||||
from ahriman.core.alpm.remote import Remote
|
from ahriman.core.alpm.remote import Remote
|
||||||
from ahriman.core.exceptions import InvalidPackageInfo
|
from ahriman.core.exceptions import PackageInfoError, UnknownPackageError
|
||||||
from ahriman.core.util import exception_response_text
|
from ahriman.core.util import exception_response_text
|
||||||
from ahriman.models.aur_package import AURPackage
|
from ahriman.models.aur_package import AURPackage
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ class AUR(Remote):
|
|||||||
response_type = response["type"]
|
response_type = response["type"]
|
||||||
if response_type == "error":
|
if response_type == "error":
|
||||||
error_details = response.get("error", "Unknown API error")
|
error_details = response.get("error", "Unknown API error")
|
||||||
raise InvalidPackageInfo(error_details)
|
raise PackageInfoError(error_details)
|
||||||
return [AURPackage.from_json(package) for package in response["results"]]
|
return [AURPackage.from_json(package) for package in response["results"]]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -140,7 +140,10 @@ class AUR(Remote):
|
|||||||
AURPackage: package which match the package name
|
AURPackage: package which match the package name
|
||||||
"""
|
"""
|
||||||
packages = self.make_request("info", package_name)
|
packages = self.make_request("info", package_name)
|
||||||
return next(package for package in packages if package.name == package_name)
|
try:
|
||||||
|
return next(package for package in packages if package.name == package_name)
|
||||||
|
except StopIteration:
|
||||||
|
raise UnknownPackageError(package_name)
|
||||||
|
|
||||||
def package_search(self, *keywords: str, pacman: Pacman) -> List[AURPackage]:
|
def package_search(self, *keywords: str, pacman: Pacman) -> List[AURPackage]:
|
||||||
"""
|
"""
|
||||||
|
@ -23,7 +23,7 @@ from typing import Any, Dict, List, Type
|
|||||||
|
|
||||||
from ahriman.core.alpm.pacman import Pacman
|
from ahriman.core.alpm.pacman import Pacman
|
||||||
from ahriman.core.alpm.remote import Remote
|
from ahriman.core.alpm.remote import Remote
|
||||||
from ahriman.core.exceptions import InvalidPackageInfo
|
from ahriman.core.exceptions import PackageInfoError, UnknownPackageError
|
||||||
from ahriman.core.util import exception_response_text
|
from ahriman.core.util import exception_response_text
|
||||||
from ahriman.models.aur_package import AURPackage
|
from ahriman.models.aur_package import AURPackage
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ class Official(Remote):
|
|||||||
InvalidPackageInfo: for error API response
|
InvalidPackageInfo: for error API response
|
||||||
"""
|
"""
|
||||||
if not response["valid"]:
|
if not response["valid"]:
|
||||||
raise InvalidPackageInfo("API validation error")
|
raise PackageInfoError("API validation error")
|
||||||
return [AURPackage.from_repo(package) for package in response["results"]]
|
return [AURPackage.from_repo(package) for package in response["results"]]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -128,7 +128,10 @@ class Official(Remote):
|
|||||||
AURPackage: package which match the package name
|
AURPackage: package which match the package name
|
||||||
"""
|
"""
|
||||||
packages = self.make_request(package_name, by="name")
|
packages = self.make_request(package_name, by="name")
|
||||||
return next(package for package in packages if package.name == package_name)
|
try:
|
||||||
|
return next(package for package in packages if package.name == package_name)
|
||||||
|
except StopIteration:
|
||||||
|
raise UnknownPackageError(package_name)
|
||||||
|
|
||||||
def package_search(self, *keywords: str, pacman: Pacman) -> List[AURPackage]:
|
def package_search(self, *keywords: str, pacman: Pacman) -> List[AURPackage]:
|
||||||
"""
|
"""
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#
|
#
|
||||||
from ahriman.core.alpm.pacman import Pacman
|
from ahriman.core.alpm.pacman import Pacman
|
||||||
from ahriman.core.alpm.remote import Official
|
from ahriman.core.alpm.remote import Official
|
||||||
|
from ahriman.core.exceptions import UnknownPackageError
|
||||||
from ahriman.models.aur_package import AURPackage
|
from ahriman.models.aur_package import AURPackage
|
||||||
|
|
||||||
|
|
||||||
@ -48,4 +49,7 @@ class OfficialSyncdb(Official):
|
|||||||
Returns:
|
Returns:
|
||||||
AURPackage: package which match the package name
|
AURPackage: package which match the package name
|
||||||
"""
|
"""
|
||||||
return next(AURPackage.from_pacman(package) for package in pacman.get(package_name))
|
try:
|
||||||
|
return next(AURPackage.from_pacman(package) for package in pacman.package_get(package_name))
|
||||||
|
except StopIteration:
|
||||||
|
raise UnknownPackageError(package_name)
|
||||||
|
@ -22,7 +22,7 @@ from __future__ import annotations
|
|||||||
from typing import Dict, List, Type
|
from typing import Dict, List, Type
|
||||||
|
|
||||||
from ahriman.core.alpm.pacman import Pacman
|
from ahriman.core.alpm.pacman import Pacman
|
||||||
from ahriman.core.lazy_logging import LazyLogging
|
from ahriman.core.log import LazyLogging
|
||||||
from ahriman.models.aur_package import AURPackage
|
from ahriman.models.aur_package import AURPackage
|
||||||
|
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ class Remote(LazyLogging):
|
|||||||
"""
|
"""
|
||||||
instance = cls()
|
instance = cls()
|
||||||
packages: Dict[str, AURPackage] = {}
|
packages: Dict[str, AURPackage] = {}
|
||||||
for term in filter(lambda word: len(word) > 3, keywords):
|
for term in filter(lambda word: len(word) >= 3, keywords):
|
||||||
portion = instance.search(term, pacman=pacman)
|
portion = instance.search(term, pacman=pacman)
|
||||||
packages = {
|
packages = {
|
||||||
package.name: package # not mistake to group them by name
|
package.name: package # not mistake to group them by name
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from ahriman.core.exceptions import BuildFailed
|
from ahriman.core.exceptions import BuildError
|
||||||
from ahriman.core.lazy_logging import LazyLogging
|
from ahriman.core.log import LazyLogging
|
||||||
from ahriman.core.util import check_output
|
from ahriman.core.util import check_output
|
||||||
from ahriman.models.repository_paths import RepositoryPaths
|
from ahriman.models.repository_paths import RepositoryPaths
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ class Repo(LazyLogging):
|
|||||||
"""
|
"""
|
||||||
Repo._check_output(
|
Repo._check_output(
|
||||||
"repo-add", *self.sign_args, "-R", str(self.repo_path), str(path),
|
"repo-add", *self.sign_args, "-R", str(self.repo_path), str(path),
|
||||||
exception=BuildFailed(path.name),
|
exception=BuildError(path.name),
|
||||||
cwd=self.paths.repository,
|
cwd=self.paths.repository,
|
||||||
logger=self.logger,
|
logger=self.logger,
|
||||||
user=self.uid)
|
user=self.uid)
|
||||||
@ -81,12 +81,8 @@ class Repo(LazyLogging):
|
|||||||
"""
|
"""
|
||||||
create empty repository database
|
create empty repository database
|
||||||
"""
|
"""
|
||||||
Repo._check_output(
|
Repo._check_output("repo-add", *self.sign_args, str(self.repo_path),
|
||||||
"repo-add", *self.sign_args, str(self.repo_path),
|
cwd=self.paths.repository, logger=self.logger, user=self.uid)
|
||||||
exception=None,
|
|
||||||
cwd=self.paths.repository,
|
|
||||||
logger=self.logger,
|
|
||||||
user=self.uid)
|
|
||||||
|
|
||||||
def remove(self, package: str, filename: Path) -> None:
|
def remove(self, package: str, filename: Path) -> None:
|
||||||
"""
|
"""
|
||||||
@ -103,7 +99,7 @@ class Repo(LazyLogging):
|
|||||||
# remove package from registry
|
# remove package from registry
|
||||||
Repo._check_output(
|
Repo._check_output(
|
||||||
"repo-remove", *self.sign_args, str(self.repo_path), package,
|
"repo-remove", *self.sign_args, str(self.repo_path), package,
|
||||||
exception=BuildFailed(package),
|
exception=BuildError(package),
|
||||||
cwd=self.paths.repository,
|
cwd=self.paths.repository,
|
||||||
logger=self.logger,
|
logger=self.logger,
|
||||||
user=self.uid)
|
user=self.uid)
|
||||||
|
@ -23,7 +23,7 @@ from typing import Optional, Type
|
|||||||
|
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.database import SQLite
|
from ahriman.core.database import SQLite
|
||||||
from ahriman.core.lazy_logging import LazyLogging
|
from ahriman.core.log import LazyLogging
|
||||||
from ahriman.models.auth_settings import AuthSettings
|
from ahriman.models.auth_settings import AuthSettings
|
||||||
from ahriman.models.user_access import UserAccess
|
from ahriman.models.user_access import UserAccess
|
||||||
|
|
||||||
@ -55,14 +55,14 @@ class Auth(LazyLogging):
|
|||||||
def auth_control(self) -> str:
|
def auth_control(self) -> str:
|
||||||
"""
|
"""
|
||||||
This workaround is required to make different behaviour for login interface.
|
This workaround is required to make different behaviour for login interface.
|
||||||
In case of internal authentication it must provide an interface (modal form) to login with button sends POST
|
In case of internal authentication it must provide an interface (modal form) to log in with button sends POST
|
||||||
request. But for an external providers behaviour can be different: e.g. OAuth provider requires sending GET
|
request. But for an external providers behaviour can be different: e.g. OAuth provider requires sending GET
|
||||||
request to external resource
|
request to external resource
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: login control as html code to insert
|
str: login control as html code to insert
|
||||||
"""
|
"""
|
||||||
return """<button type="button" class="btn btn-link" data-bs-toggle="modal" data-bs-target="#loginForm" style="text-decoration: none">login</button>"""
|
return """<button type="button" class="btn btn-link" data-bs-toggle="modal" data-bs-target="#login-modal" style="text-decoration: none"><i class="bi bi-box-arrow-in-right"></i> login</button>"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load(cls: Type[Auth], configuration: Configuration, database: SQLite) -> Auth:
|
def load(cls: Type[Auth], configuration: Configuration, database: SQLite) -> Auth:
|
||||||
|
@ -29,61 +29,65 @@ except ImportError:
|
|||||||
__all__ = ["authorized_userid", "check_authorized", "forget", "remember"]
|
__all__ = ["authorized_userid", "check_authorized", "forget", "remember"]
|
||||||
|
|
||||||
|
|
||||||
async def authorized_userid(*args: Any) -> Any:
|
async def authorized_userid(*args: Any, **kwargs: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
handle aiohttp security methods
|
handle aiohttp security methods
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*args(Any): argument list as provided by authorized_userid function
|
*args(Any): argument list as provided by authorized_userid function
|
||||||
|
**kwargs(Any): named argument list as provided by authorized_userid function
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Any: None in case if no aiohttp_security module found and function call otherwise
|
Any: None in case if no aiohttp_security module found and function call otherwise
|
||||||
"""
|
"""
|
||||||
if _has_aiohttp_security:
|
if _has_aiohttp_security:
|
||||||
return await aiohttp_security.authorized_userid(*args) # pylint: disable=no-value-for-parameter
|
return await aiohttp_security.authorized_userid(*args, **kwargs) # pylint: disable=no-value-for-parameter
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def check_authorized(*args: Any) -> Any:
|
async def check_authorized(*args: Any, **kwargs: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
handle aiohttp security methods
|
handle aiohttp security methods
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*args(Any): argument list as provided by check_authorized function
|
*args(Any): argument list as provided by check_authorized function
|
||||||
|
**kwargs(Any): named argument list as provided by authorized_userid function
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Any: None in case if no aiohttp_security module found and function call otherwise
|
Any: None in case if no aiohttp_security module found and function call otherwise
|
||||||
"""
|
"""
|
||||||
if _has_aiohttp_security:
|
if _has_aiohttp_security:
|
||||||
return await aiohttp_security.check_authorized(*args) # pylint: disable=no-value-for-parameter
|
return await aiohttp_security.check_authorized(*args, **kwargs) # pylint: disable=no-value-for-parameter
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def forget(*args: Any) -> Any:
|
async def forget(*args: Any, **kwargs: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
handle aiohttp security methods
|
handle aiohttp security methods
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*args(Any): argument list as provided by forget function
|
*args(Any): argument list as provided by forget function
|
||||||
|
**kwargs(Any): named argument list as provided by authorized_userid function
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Any: None in case if no aiohttp_security module found and function call otherwise
|
Any: None in case if no aiohttp_security module found and function call otherwise
|
||||||
"""
|
"""
|
||||||
if _has_aiohttp_security:
|
if _has_aiohttp_security:
|
||||||
return await aiohttp_security.forget(*args) # pylint: disable=no-value-for-parameter
|
return await aiohttp_security.forget(*args, **kwargs) # pylint: disable=no-value-for-parameter
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def remember(*args: Any) -> Any:
|
async def remember(*args: Any, **kwargs: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
handle disabled auth
|
handle disabled auth
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*args(Any): argument list as provided by remember function
|
*args(Any): argument list as provided by remember function
|
||||||
|
**kwargs(Any): named argument list as provided by authorized_userid function
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Any: None in case if no aiohttp_security module found and function call otherwise
|
Any: None in case if no aiohttp_security module found and function call otherwise
|
||||||
"""
|
"""
|
||||||
if _has_aiohttp_security:
|
if _has_aiohttp_security:
|
||||||
return await aiohttp_security.remember(*args) # pylint: disable=no-value-for-parameter
|
return await aiohttp_security.remember(*args, **kwargs) # pylint: disable=no-value-for-parameter
|
||||||
return None
|
return None
|
||||||
|
@ -32,7 +32,7 @@ class Mapping(Auth):
|
|||||||
user authorization based on mapping from configuration file
|
user authorization based on mapping from configuration file
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
salt(str): random generated string to salt passwords
|
salt(str): random generated string to salted password
|
||||||
database(SQLite): database instance
|
database(SQLite): database instance
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user