mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-06-27 14:22:10 +00:00
Compare commits
38 Commits
feature/pk
...
2.10.2
Author | SHA1 | Date | |
---|---|---|---|
b58d8d96ff | |||
4abe3b8963 | |||
237fec3f85 | |||
bd0f850d25 | |||
5904727da2 | |||
263c53bac5 | |||
6743f1d62a | |||
931ff9bd98 | |||
6b3fc3a6a0 | |||
b7852f55c8 | |||
721b447767 | |||
b80ea80e9d | |||
8e9da5baab | |||
a443abb94e | |||
61c565ab0d | |||
10100b20e1 | |||
2922bb9d72 | |||
17f5f41e36 | |||
c22ddd71d9 | |||
4b984afb64 | |||
d495163fdd | |||
041e9536bf | |||
1625fddccd | |||
8f2c33fe5d | |||
d064e46af6 | |||
5627c9cca0 | |||
8731cee8ea | |||
01a4d68ce6 | |||
8f0a6cf6b5 | |||
d96e3c97db | |||
1cf027cb55 | |||
8e0e57e193 | |||
f855e645cc | |||
8ab0df2bed | |||
840921f585 | |||
6f566b0c6c | |||
d06399db2c | |||
70e9e3e822 |
2
.github/workflows/setup.sh
vendored
2
.github/workflows/setup.sh
vendored
@ -10,7 +10,7 @@ echo -e '[arcanisrepo]\nServer = http://repo.arcanis.me/$arch\nSigLevel = Never'
|
||||
# refresh the image
|
||||
pacman --noconfirm -Syu
|
||||
# main dependencies
|
||||
pacman --noconfirm -Sy base-devel devtools git pyalpm python-cerberus python-inflection python-passlib python-requests python-srcinfo sudo
|
||||
pacman --noconfirm -Sy base-devel devtools git pyalpm python-cerberus python-inflection python-passlib python-requests python-srcinfo python-systemd sudo
|
||||
# make dependencies
|
||||
pacman --noconfirm -Sy python-build python-installer python-wheel
|
||||
# optional dependencies
|
||||
|
@ -6,7 +6,7 @@ formats:
|
||||
build:
|
||||
os: ubuntu-20.04
|
||||
tools:
|
||||
python: "3.10"
|
||||
python: "3.11"
|
||||
|
||||
sphinx:
|
||||
builder: html
|
||||
|
@ -34,7 +34,7 @@ Again, the most checks can be performed by `make check` command, though some add
|
||||
do foo. With very very very long
|
||||
docstring
|
||||
|
||||
Note:
|
||||
Notes:
|
||||
Very important note about this function
|
||||
|
||||
Args:
|
||||
@ -102,6 +102,9 @@ Again, the most checks can be performed by `make check` command, though some add
|
||||
|
||||
@property
|
||||
def property(self) -> Any: ...
|
||||
|
||||
@cached_property
|
||||
def property_cached(self) -> Any: ... # cached property has to be treated as normal one
|
||||
|
||||
@classmethod
|
||||
def class_method(cls) -> Self: ...
|
||||
|
15
Dockerfile
15
Dockerfile
@ -6,7 +6,7 @@ ENV AHRIMAN_DEBUG=""
|
||||
ENV AHRIMAN_FORCE_ROOT=""
|
||||
ENV AHRIMAN_HOST="0.0.0.0"
|
||||
ENV AHRIMAN_MULTILIB="yes"
|
||||
ENV AHRIMAN_OUTPUT="syslog"
|
||||
ENV AHRIMAN_OUTPUT=""
|
||||
ENV AHRIMAN_PACKAGER="ahriman bot <ahriman@example.com>"
|
||||
ENV AHRIMAN_PACMAN_MIRROR=""
|
||||
ENV AHRIMAN_PORT=""
|
||||
@ -28,15 +28,12 @@ RUN useradd -m -d "/home/build" -s "/usr/bin/nologin" build && \
|
||||
COPY "docker/install-aur-package.sh" "/usr/local/bin/install-aur-package"
|
||||
## install package dependencies
|
||||
## 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-cerberus python-inflection python-passlib python-requests python-srcinfo && \
|
||||
pacman --noconfirm -Sy python-build python-installer python-wheel && \
|
||||
pacman --noconfirm -Sy breezy mercurial python-aiohttp python-aiohttp-cors python-boto3 python-cryptography python-jinja python-requests-unixsocket rsync subversion && \
|
||||
RUN pacman -Sy --noconfirm --asdeps devtools git pyalpm python-cerberus python-inflection python-passlib python-requests python-srcinfo && \
|
||||
pacman -Sy --noconfirm --asdeps python-build python-installer python-wheel && \
|
||||
pacman -Sy --noconfirm --asdeps breezy mercurial python-aiohttp python-aiohttp-cors python-boto3 python-cryptography python-jinja python-requests-unixsocket python-systemd rsync subversion && \
|
||||
runuser -u build -- install-aur-package python-aioauth-client python-aiohttp-apispec-git python-aiohttp-jinja2 \
|
||||
python-aiohttp-debugtoolbar python-aiohttp-session python-aiohttp-security
|
||||
|
||||
# cleanup unused
|
||||
RUN find "/var/cache/pacman/pkg" -type f -delete
|
||||
|
||||
# install ahriman
|
||||
## copy tree
|
||||
COPY --chown=build . "/home/build/ahriman"
|
||||
@ -48,6 +45,10 @@ RUN cd "/home/build/ahriman" && \
|
||||
runuser -u build -- makepkg --noconfirm --install --skipchecksums && \
|
||||
cd / && rm -r "/home/build/ahriman"
|
||||
|
||||
# cleanup unused
|
||||
RUN find "/var/cache/pacman/pkg" -type f -delete
|
||||
RUN pacman -Qdtq | pacman -Rscn --noconfirm -
|
||||
|
||||
VOLUME ["/var/lib/ahriman"]
|
||||
|
||||
# minimal runtime ahriman setup
|
||||
|
@ -16,7 +16,7 @@ Wrapper for managing custom repository inspired by [repo-scripts](https://github
|
||||
* VCS packages support.
|
||||
* Official repository support.
|
||||
* Ability to patch AUR packages and even create package from local PKGBUILDs.
|
||||
* Sign support with gpg (repository, package, per package settings).
|
||||
* Sign support with gpg (repository, package), multiple packagers support.
|
||||
* 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:
|
||||
|
||||
|
@ -15,15 +15,10 @@ database = $AHRIMAN_REPOSITORY_ROOT/ahriman.db
|
||||
host = $AHRIMAN_HOST
|
||||
|
||||
EOF
|
||||
sed -i "s|handlers = syslog_handler|handlers = ${AHRIMAN_OUTPUT}_handler|g" "/etc/ahriman.ini.d/logging.ini"
|
||||
|
||||
AHRIMAN_DEFAULT_ARGS=("--architecture" "$AHRIMAN_ARCHITECTURE")
|
||||
if [[ "$AHRIMAN_OUTPUT" == "syslog" ]]; then
|
||||
if [ ! -e "/dev/log" ]; then
|
||||
# by default ahriman uses syslog which is not available inside container
|
||||
# to make noise less we force quiet mode in case if /dev/log was not mounted
|
||||
AHRIMAN_DEFAULT_ARGS+=("--quiet")
|
||||
fi
|
||||
if [ -n "$AHRIMAN_OUTPUT" ]; then
|
||||
AHRIMAN_DEFAULT_ARGS+=("--log-handler" "$AHRIMAN_OUTPUT")
|
||||
fi
|
||||
|
||||
# create repository root inside the [[mounted]] directory and set correct ownership
|
||||
@ -63,7 +58,7 @@ systemd-machine-id-setup &> /dev/null
|
||||
# otherwise we prepend executable by sudo command
|
||||
if [ -n "$AHRIMAN_FORCE_ROOT" ]; then
|
||||
AHRIMAN_EXECUTABLE=("ahriman")
|
||||
elif ahriman help-commands-unsafe --command="$*" &> /dev/null; then
|
||||
elif ahriman help-commands-unsafe -- "$@" &> /dev/null; then
|
||||
AHRIMAN_EXECUTABLE=("sudo" "-u" "$AHRIMAN_USER" "--" "ahriman")
|
||||
else
|
||||
AHRIMAN_EXECUTABLE=("ahriman")
|
||||
|
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 750 KiB After Width: | Height: | Size: 829 KiB |
126
docs/ahriman.1
126
docs/ahriman.1
@ -1,9 +1,9 @@
|
||||
.TH AHRIMAN "1" "2023\-04\-09" "ahriman" "Generated Python Manual"
|
||||
.TH AHRIMAN "1" "2023\-08\-07" "ahriman" "Generated Python Manual"
|
||||
.SH NAME
|
||||
ahriman
|
||||
.SH SYNOPSIS
|
||||
.B ahriman
|
||||
[-h] [-a ARCHITECTURE] [-c CONFIGURATION] [--force] [-l LOCK] [--report | --no-report] [-q] [--unsafe] [-V] {aur-search,search,help,help-commands-unsafe,help-updates,help-version,version,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-daemon,daemon,repo-rebuild,rebuild,repo-remove-unknown,remove-unknown,repo-report,report,repo-restore,repo-sign,sign,repo-status-update,repo-sync,sync,repo-tree,repo-triggers,repo-update,update,service-clean,clean,repo-clean,service-config,config,repo-config,service-config-validate,config-validate,repo-config-validate,service-key-import,key-import,service-setup,init,repo-init,repo-setup,setup,service-shell,shell,user-add,user-list,user-remove,web} ...
|
||||
[-h] [-a ARCHITECTURE] [-c CONFIGURATION] [--force] [-l LOCK] [--log-handler {console,syslog,journald}] [--report | --no-report] [-q] [--unsafe] [-V] {aur-search,search,help,help-commands-unsafe,help-updates,help-version,version,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-create-keyring,repo-create-mirrorlist,repo-daemon,daemon,repo-rebuild,rebuild,repo-remove-unknown,remove-unknown,repo-report,report,repo-restore,repo-sign,sign,repo-status-update,repo-sync,sync,repo-tree,repo-triggers,repo-update,update,service-clean,clean,repo-clean,service-config,config,repo-config,service-config-validate,config-validate,repo-config-validate,service-key-import,key-import,service-setup,init,repo-init,repo-setup,setup,service-shell,shell,user-add,user-list,user-remove,web} ...
|
||||
.SH DESCRIPTION
|
||||
ArcH linux ReposItory MANager
|
||||
|
||||
@ -24,9 +24,13 @@ force run, remove file lock
|
||||
\fB\-l\fR \fI\,LOCK\/\fR, \fB\-\-lock\fR \fI\,LOCK\/\fR
|
||||
lock file
|
||||
|
||||
.TP
|
||||
\fB\-\-log\-handler\fR \fI\,{console,syslog,journald}\/\fR
|
||||
explicit log handler specification. If none set, the handler will be guessed from environment
|
||||
|
||||
.TP
|
||||
\fB\-\-report\fR, \fB\-\-no\-report\fR
|
||||
force enable or disable reporting to web service (default: True)
|
||||
force enable or disable reporting to web service
|
||||
|
||||
.TP
|
||||
\fB\-q\fR, \fB\-\-quiet\fR
|
||||
@ -91,6 +95,12 @@ backup repository data
|
||||
\fBahriman\fR \fI\,repo\-check\/\fR
|
||||
check for updates
|
||||
.TP
|
||||
\fBahriman\fR \fI\,repo\-create\-keyring\/\fR
|
||||
create keyring package
|
||||
.TP
|
||||
\fBahriman\fR \fI\,repo\-create\-mirrorlist\/\fR
|
||||
create mirrorlist package
|
||||
.TP
|
||||
\fBahriman\fR \fI\,repo\-daemon\/\fR
|
||||
run application as daemon
|
||||
.TP
|
||||
@ -172,7 +182,7 @@ return non\-zero exit status if result is empty
|
||||
|
||||
.TP
|
||||
\fB\-\-info\fR, \fB\-\-no\-info\fR
|
||||
show additional package information (default: False)
|
||||
show additional package information
|
||||
|
||||
.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,submitter,url,url_path,version}\/\fR
|
||||
@ -189,13 +199,12 @@ show help message for application or command and exit
|
||||
show help message for specific command
|
||||
|
||||
.SH COMMAND \fI\,'ahriman help\-commands\-unsafe'\/\fR
|
||||
usage: ahriman help\-commands\-unsafe [\-h] [\-\-command COMMAND]
|
||||
usage: ahriman help\-commands\-unsafe [\-h] [command ...]
|
||||
|
||||
list unsafe commands as defined in default args
|
||||
|
||||
.SH OPTIONS \fI\,'ahriman help\-commands\-unsafe'\/\fR
|
||||
.TP
|
||||
\fB\-\-command\fR \fI\,COMMAND\/\fR
|
||||
\fBcommand\fR
|
||||
instead of showing commands, just test command line for unsafe subcommand and return 0 in case if command is safe and 1
|
||||
otherwise
|
||||
|
||||
@ -216,7 +225,7 @@ print application and its dependencies versions
|
||||
|
||||
.SH COMMAND \fI\,'ahriman package\-add'\/\fR
|
||||
usage: ahriman package\-add [\-h] [\-\-dependencies | \-\-no\-dependencies] [\-e] [\-n] [\-y]
|
||||
[\-s {auto,archive,aur,directory,local,remote,repository}]
|
||||
[\-s {auto,archive,aur,directory,local,remote,repository}] [\-u USERNAME]
|
||||
package [package ...]
|
||||
|
||||
add existing or new package to the build queue
|
||||
@ -228,7 +237,7 @@ package source (base name, path to local files, remote URL)
|
||||
.SH OPTIONS \fI\,'ahriman package\-add'\/\fR
|
||||
.TP
|
||||
\fB\-\-dependencies\fR, \fB\-\-no\-dependencies\fR
|
||||
process missing package dependencies (default: True)
|
||||
process missing package dependencies
|
||||
|
||||
.TP
|
||||
\fB\-e\fR, \fB\-\-exit\-code\fR
|
||||
@ -246,6 +255,10 @@ download fresh package databases from the mirror before actions, \-yy to force r
|
||||
\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
|
||||
|
||||
.TP
|
||||
\fB\-u\fR \fI\,USERNAME\/\fR, \fB\-\-username\fR \fI\,USERNAME\/\fR
|
||||
build as user
|
||||
|
||||
.SH COMMAND \fI\,'ahriman package\-remove'\/\fR
|
||||
usage: ahriman package\-remove [\-h] package [package ...]
|
||||
|
||||
@ -276,7 +289,7 @@ return non\-zero exit status if result is empty
|
||||
|
||||
.TP
|
||||
\fB\-\-info\fR, \fB\-\-no\-info\fR
|
||||
show additional package information (default: False)
|
||||
show additional package information
|
||||
|
||||
.TP
|
||||
\fB\-s\fR \fI\,{unknown,pending,building,failed,success}\/\fR, \fB\-\-status\fR \fI\,{unknown,pending,building,failed,success}\/\fR
|
||||
@ -394,12 +407,22 @@ return non\-zero exit status if result is empty
|
||||
|
||||
.TP
|
||||
\fB\-\-vcs\fR, \fB\-\-no\-vcs\fR
|
||||
fetch actual version of VCS packages (default: True)
|
||||
fetch actual version of VCS packages
|
||||
|
||||
.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 repo\-create\-keyring'\/\fR
|
||||
usage: ahriman repo\-create\-keyring [\-h]
|
||||
|
||||
create package which contains list of trusted keys as set by configuration. Note, that this action will only create package, the package itself has to be built manually
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-create\-mirrorlist'\/\fR
|
||||
usage: ahriman repo\-create\-mirrorlist [\-h]
|
||||
|
||||
create package which contains list of available mirrors as set by configuration. Note, that this action will only create package, the package itself has to be built manually
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-daemon'\/\fR
|
||||
usage: ahriman repo\-daemon [\-h] [\-i INTERVAL] [\-\-aur | \-\-no\-aur] [\-\-dependencies | \-\-no\-dependencies]
|
||||
[\-\-local | \-\-no\-local] [\-\-manual | \-\-no\-manual] [\-\-vcs | \-\-no\-vcs] [\-y]
|
||||
@ -413,23 +436,23 @@ interval between runs in seconds
|
||||
|
||||
.TP
|
||||
\fB\-\-aur\fR, \fB\-\-no\-aur\fR
|
||||
enable or disable checking for AUR updates (default: True)
|
||||
enable or disable checking for AUR updates
|
||||
|
||||
.TP
|
||||
\fB\-\-dependencies\fR, \fB\-\-no\-dependencies\fR
|
||||
process missing package dependencies (default: True)
|
||||
process missing package dependencies
|
||||
|
||||
.TP
|
||||
\fB\-\-local\fR, \fB\-\-no\-local\fR
|
||||
enable or disable checking of local packages for updates (default: True)
|
||||
enable or disable checking of local packages for updates
|
||||
|
||||
.TP
|
||||
\fB\-\-manual\fR, \fB\-\-no\-manual\fR
|
||||
include or exclude manual updates (default: True)
|
||||
include or exclude manual updates
|
||||
|
||||
.TP
|
||||
\fB\-\-vcs\fR, \fB\-\-no\-vcs\fR
|
||||
fetch actual version of VCS packages (default: True)
|
||||
fetch actual version of VCS packages
|
||||
|
||||
.TP
|
||||
\fB\-y\fR, \fB\-\-refresh\fR
|
||||
@ -437,6 +460,7 @@ download fresh package databases from the mirror before actions, \-yy to force r
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-rebuild'\/\fR
|
||||
usage: ahriman repo\-rebuild [\-h] [\-\-depends\-on DEPENDS_ON] [\-\-dry\-run] [\-\-from\-database] [\-e]
|
||||
[\-s {unknown,pending,building,failed,success}] [\-u USERNAME]
|
||||
|
||||
force rebuild whole repository
|
||||
|
||||
@ -459,6 +483,14 @@ original ahriman instance run with web service and have run repo\-update at leas
|
||||
\fB\-e\fR, \fB\-\-exit\-code\fR
|
||||
return non\-zero exit status if result is empty
|
||||
|
||||
.TP
|
||||
\fB\-s\fR \fI\,{unknown,pending,building,failed,success}\/\fR, \fB\-\-status\fR \fI\,{unknown,pending,building,failed,success}\/\fR
|
||||
filter packages by status. Requires \-\-from\-database to be set
|
||||
|
||||
.TP
|
||||
\fB\-u\fR \fI\,USERNAME\/\fR, \fB\-\-username\fR \fI\,USERNAME\/\fR
|
||||
build as user
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-remove\-unknown'\/\fR
|
||||
usage: ahriman repo\-remove\-unknown [\-h] [\-\-dry\-run]
|
||||
|
||||
@ -528,7 +560,7 @@ instead of running all triggers as set by configuration, just process specified
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-update'\/\fR
|
||||
usage: ahriman repo\-update [\-h] [\-\-aur | \-\-no\-aur] [\-\-dependencies | \-\-no\-dependencies] [\-\-dry\-run] [\-e]
|
||||
[\-\-local | \-\-no\-local] [\-\-manual | \-\-no\-manual] [\-\-vcs | \-\-no\-vcs] [\-y]
|
||||
[\-\-local | \-\-no\-local] [\-\-manual | \-\-no\-manual] [\-u USERNAME] [\-\-vcs | \-\-no\-vcs] [\-y]
|
||||
[package ...]
|
||||
|
||||
check for packages updates and run build process if requested
|
||||
@ -540,11 +572,11 @@ filter check by package base
|
||||
.SH OPTIONS \fI\,'ahriman repo\-update'\/\fR
|
||||
.TP
|
||||
\fB\-\-aur\fR, \fB\-\-no\-aur\fR
|
||||
enable or disable checking for AUR updates (default: True)
|
||||
enable or disable checking for AUR updates
|
||||
|
||||
.TP
|
||||
\fB\-\-dependencies\fR, \fB\-\-no\-dependencies\fR
|
||||
process missing package dependencies (default: True)
|
||||
process missing package dependencies
|
||||
|
||||
.TP
|
||||
\fB\-\-dry\-run\fR
|
||||
@ -556,15 +588,19 @@ return non\-zero exit status if result is empty
|
||||
|
||||
.TP
|
||||
\fB\-\-local\fR, \fB\-\-no\-local\fR
|
||||
enable or disable checking of local packages for updates (default: True)
|
||||
enable or disable checking of local packages for updates
|
||||
|
||||
.TP
|
||||
\fB\-\-manual\fR, \fB\-\-no\-manual\fR
|
||||
include or exclude manual updates (default: True)
|
||||
include or exclude manual updates
|
||||
|
||||
.TP
|
||||
\fB\-u\fR \fI\,USERNAME\/\fR, \fB\-\-username\fR \fI\,USERNAME\/\fR
|
||||
build as user
|
||||
|
||||
.TP
|
||||
\fB\-\-vcs\fR, \fB\-\-no\-vcs\fR
|
||||
fetch actual version of VCS packages (default: True)
|
||||
fetch actual version of VCS packages
|
||||
|
||||
.TP
|
||||
\fB\-y\fR, \fB\-\-refresh\fR
|
||||
@ -579,23 +615,23 @@ remove local caches
|
||||
.SH OPTIONS \fI\,'ahriman service\-clean'\/\fR
|
||||
.TP
|
||||
\fB\-\-cache\fR, \fB\-\-no\-cache\fR
|
||||
clear directory with package caches (default: False)
|
||||
clear directory with package caches
|
||||
|
||||
.TP
|
||||
\fB\-\-chroot\fR, \fB\-\-no\-chroot\fR
|
||||
clear build chroot (default: False)
|
||||
clear build chroot
|
||||
|
||||
.TP
|
||||
\fB\-\-manual\fR, \fB\-\-no\-manual\fR
|
||||
clear manually added packages queue (default: False)
|
||||
clear manually added packages queue
|
||||
|
||||
.TP
|
||||
\fB\-\-packages\fR, \fB\-\-no\-packages\fR
|
||||
clear directory with built packages (default: False)
|
||||
clear directory with built packages
|
||||
|
||||
.TP
|
||||
\fB\-\-pacman\fR, \fB\-\-no\-pacman\fR
|
||||
clear directory with pacman local database cache (default: False)
|
||||
clear directory with pacman local database cache
|
||||
|
||||
.SH COMMAND \fI\,'ahriman service\-config'\/\fR
|
||||
usage: ahriman service\-config [\-h] [\-\-secure | \-\-no\-secure]
|
||||
@ -605,7 +641,7 @@ dump configuration for the specified architecture
|
||||
.SH OPTIONS \fI\,'ahriman service\-config'\/\fR
|
||||
.TP
|
||||
\fB\-\-secure\fR, \fB\-\-no\-secure\fR
|
||||
hide passwords and secrets from output (default: True)
|
||||
hide passwords and secrets from output
|
||||
|
||||
.SH COMMAND \fI\,'ahriman service\-config\-validate'\/\fR
|
||||
usage: ahriman service\-config\-validate [\-h] [\-e]
|
||||
@ -633,9 +669,10 @@ key server for key import
|
||||
|
||||
.SH COMMAND \fI\,'ahriman service\-setup'\/\fR
|
||||
usage: ahriman service\-setup [\-h] [\-\-build\-as\-user BUILD_AS_USER] [\-\-build\-command BUILD_COMMAND]
|
||||
[\-\-from\-configuration FROM_CONFIGURATION] [\-\-makeflags\-jobs | \-\-no\-makeflags\-jobs]
|
||||
[\-\-mirror MIRROR] [\-\-multilib | \-\-no\-multilib] \-\-packager PACKAGER \-\-repository REPOSITORY
|
||||
[\-\-sign\-key SIGN_KEY] [\-\-sign\-target {disabled,packages,repository}] [\-\-web\-port WEB_PORT]
|
||||
[\-\-from\-configuration FROM_CONFIGURATION] [\-\-generate\-salt | \-\-no\-generate\-salt]
|
||||
[\-\-makeflags\-jobs | \-\-no\-makeflags\-jobs] [\-\-mirror MIRROR] [\-\-multilib | \-\-no\-multilib]
|
||||
\-\-packager PACKAGER \-\-repository REPOSITORY [\-\-sign\-key SIGN_KEY]
|
||||
[\-\-sign\-target {disabled,packages,repository}] [\-\-web\-port WEB_PORT]
|
||||
[\-\-web\-unix\-socket WEB_UNIX_SOCKET]
|
||||
|
||||
create initial service configuration, requires root
|
||||
@ -653,9 +690,13 @@ build command prefix
|
||||
\fB\-\-from\-configuration\fR \fI\,FROM_CONFIGURATION\/\fR
|
||||
path to default devtools pacman configuration
|
||||
|
||||
.TP
|
||||
\fB\-\-generate\-salt\fR, \fB\-\-no\-generate\-salt\fR
|
||||
generate salt for user passwords
|
||||
|
||||
.TP
|
||||
\fB\-\-makeflags\-jobs\fR, \fB\-\-no\-makeflags\-jobs\fR
|
||||
append MAKEFLAGS variable with parallelism set to number of cores (default: True)
|
||||
append MAKEFLAGS variable with parallelism set to number of cores
|
||||
|
||||
.TP
|
||||
\fB\-\-mirror\fR \fI\,MIRROR\/\fR
|
||||
@ -663,7 +704,7 @@ use the specified explicitly mirror instead of including mirrorlist
|
||||
|
||||
.TP
|
||||
\fB\-\-multilib\fR, \fB\-\-no\-multilib\fR
|
||||
add or do not multilib repository (default: True)
|
||||
add or do not multilib repository
|
||||
|
||||
.TP
|
||||
\fB\-\-packager\fR \fI\,PACKAGER\/\fR
|
||||
@ -692,14 +733,15 @@ path to unix socket used for interprocess communications
|
||||
.SH COMMAND \fI\,'ahriman service\-shell'\/\fR
|
||||
usage: ahriman service\-shell [\-h] [code]
|
||||
|
||||
drop into python shell while having created application
|
||||
drop into python shell
|
||||
|
||||
.TP
|
||||
\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
|
||||
usage: ahriman user\-add [\-h] [\-\-key KEY] [\-\-packager PACKAGER] [\-p PASSWORD] [\-r {unauthorized,read,reporter,full}]
|
||||
username
|
||||
|
||||
update user for web services with the given password and role. In case if password was not entered it will be asked interactively
|
||||
|
||||
@ -708,6 +750,14 @@ update user for web services with the given password and role. In case if passwo
|
||||
username for web service
|
||||
|
||||
.SH OPTIONS \fI\,'ahriman user\-add'\/\fR
|
||||
.TP
|
||||
\fB\-\-key\fR \fI\,KEY\/\fR
|
||||
optional PGP key used by this user. The private key must be imported
|
||||
|
||||
.TP
|
||||
\fB\-\-packager\fR \fI\,PACKAGER\/\fR
|
||||
optional packager id used for build process in form of `Name Surname <mail@example.com>`
|
||||
|
||||
.TP
|
||||
\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
|
||||
@ -717,10 +767,6 @@ authorization type.
|
||||
\fB\-r\fR \fI\,{unauthorized,read,reporter,full}\/\fR, \fB\-\-role\fR \fI\,{unauthorized,read,reporter,full}\/\fR
|
||||
user access level
|
||||
|
||||
.TP
|
||||
\fB\-s\fR, \fB\-\-secure\fR
|
||||
set file permissions to user\-only
|
||||
|
||||
.SH COMMAND \fI\,'ahriman user\-list'\/\fR
|
||||
usage: ahriman user\-list [\-h] [\-e] [\-r {unauthorized,read,reporter,full}] [username]
|
||||
|
||||
@ -756,7 +802,7 @@ start web server
|
||||
.SH COMMENTS
|
||||
Argument list can also be read from file by using @ prefix.
|
||||
|
||||
.SH AUTHORS
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
ahriman team
|
||||
.fi
|
||||
|
@ -60,6 +60,22 @@ ahriman.core.database.migrations.m006\_packages\_architecture\_required module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.database.migrations.m007\_check\_depends module
|
||||
------------------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.database.migrations.m007_check_depends
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.database.migrations.m008\_packagers module
|
||||
-------------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.database.migrations.m008_packagers
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
|
@ -20,6 +20,14 @@ ahriman.core.formatters.build\_printer module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.formatters.configuration\_paths\_printer module
|
||||
------------------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.formatters.configuration_paths_printer
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.formatters.configuration\_printer module
|
||||
-----------------------------------------------------
|
||||
|
||||
|
@ -20,6 +20,14 @@ ahriman.core.log.http\_log\_handler module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.log.journal\_handler module
|
||||
----------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.log.journal_handler
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.log.lazy\_logging module
|
||||
-------------------------------------
|
||||
|
||||
|
@ -19,6 +19,7 @@ Subpackages
|
||||
ahriman.core.repository
|
||||
ahriman.core.sign
|
||||
ahriman.core.status
|
||||
ahriman.core.support
|
||||
ahriman.core.triggers
|
||||
ahriman.core.upload
|
||||
|
||||
|
37
docs/ahriman.core.support.pkgbuild.rst
Normal file
37
docs/ahriman.core.support.pkgbuild.rst
Normal file
@ -0,0 +1,37 @@
|
||||
ahriman.core.support.pkgbuild package
|
||||
=====================================
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
ahriman.core.support.pkgbuild.keyring\_generator module
|
||||
-------------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.support.pkgbuild.keyring_generator
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.support.pkgbuild.mirrorlist\_generator module
|
||||
----------------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.support.pkgbuild.mirrorlist_generator
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.support.pkgbuild.pkgbuild\_generator module
|
||||
--------------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.support.pkgbuild.pkgbuild_generator
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
.. automodule:: ahriman.core.support.pkgbuild
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
45
docs/ahriman.core.support.rst
Normal file
45
docs/ahriman.core.support.rst
Normal file
@ -0,0 +1,45 @@
|
||||
ahriman.core.support package
|
||||
============================
|
||||
|
||||
Subpackages
|
||||
-----------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
ahriman.core.support.pkgbuild
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
ahriman.core.support.keyring\_trigger module
|
||||
--------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.support.keyring_trigger
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.support.mirrorlist\_trigger module
|
||||
-----------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.support.mirrorlist_trigger
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.support.package\_creator module
|
||||
--------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.support.package_creator
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
.. automodule:: ahriman.core.support
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
@ -60,6 +60,14 @@ ahriman.models.internal\_status module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.log\_handler module
|
||||
----------------------------------
|
||||
|
||||
.. automodule:: ahriman.models.log_handler
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.log\_record\_id module
|
||||
-------------------------------------
|
||||
|
||||
@ -108,6 +116,22 @@ ahriman.models.package\_source module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.packagers module
|
||||
-------------------------------
|
||||
|
||||
.. automodule:: ahriman.models.packagers
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.pacman\_synchronization module
|
||||
---------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.models.pacman_synchronization
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.pkgbuild\_patch module
|
||||
-------------------------------------
|
||||
|
||||
|
@ -33,6 +33,7 @@ This package contains everything required for the most of application actions an
|
||||
* ``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.build_tools`` is a package which provides wrapper for ``devtools`` commands.
|
||||
* ``ahriman.core.configuration`` contains extension for standard ``configparser`` library and some validation related classes.
|
||||
* ``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.gitremote`` is a package with remote PKGBUILD triggers. Should not be called directly.
|
||||
@ -41,12 +42,12 @@ This package contains everything required for the most of application actions an
|
||||
* ``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.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.support`` provides plugins for support packages (mirrorlist and keyring) generation.
|
||||
* ``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, should not be called directly.
|
||||
|
||||
This package also provides some generic functions and classes which may be used by other packages:
|
||||
|
||||
* ``ahriman.core.configuration.Configuration`` is an extension for standard ``configparser`` library.
|
||||
* ``ahriman.core.exceptions`` provides custom exceptions.
|
||||
* ``ahriman.core.spawn.Spawn`` is a tool which can spawn another ``ahriman`` process. This feature is used by web application.
|
||||
* ``ahriman.core.tree`` is a dependency tree implementation.
|
||||
@ -62,20 +63,23 @@ It provides models for any other part of application. Unlike ``ahriman.core`` pa
|
||||
Web application. It is important that this package is isolated from any other to allow it to be optional feature (i.e. dependencies which are required by the package are optional).
|
||||
|
||||
* ``ahriman.web.middlewares`` provides middlewares for request handlers.
|
||||
* ``ahriman.web.schemas`` provides schemas (actually copy paste from dataclasses) used by swagger documentation.
|
||||
* ``ahriman.web.views`` contains web views derived from aiohttp view class.
|
||||
* ``ahriman.web.apispec`` provides generators for swagger documentation.
|
||||
* ``ahriman.web.cors`` contains helpers for cross origin resource sharing middlewares.
|
||||
* ``ahriman.web.routes`` creates routes for web application.
|
||||
* ``ahriman.web.web`` provides main web application functions (e.g. start, initialization).
|
||||
|
||||
Application run
|
||||
---------------
|
||||
|
||||
* Parse command line arguments, find command and related handler which is set by parser.
|
||||
* Call ``Handler.execute`` method.
|
||||
* Define list of architectures to run. In case if there is more than one architecture specified run several subprocesses or process in current process otherwise. Class attribute ``ALLOW_MULTI_ARCHITECTURE_RUN`` controls whether application can be run in multiple processes or not - this feature is required for some handlers (e.g. ``Web``) which should be able to spawn child process in daemon mode (it is impossible to do from daemonic processes).
|
||||
* In each child process call lock functions.
|
||||
* After success checks pass control to ``Handler.run`` method defined by specific handler class.
|
||||
* 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``.
|
||||
#. Parse command line arguments, find command and related handler which is set by parser.
|
||||
#. Call ``Handler.execute`` method.
|
||||
#. Define list of architectures to run. In case if there is more than one architecture specified run several subprocesses or process in current process otherwise. Class attribute ``ALLOW_MULTI_ARCHITECTURE_RUN`` controls whether application can be run in multiple processes or not - this feature is required for some handlers (e.g. ``Web``) which should be able to spawn child process in daemon mode (it is impossible to do from daemonic processes).
|
||||
#. In each child process call lock functions.
|
||||
#. After success checks pass control to ``Handler.run`` method defined by specific handler class.
|
||||
#. 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``.
|
||||
|
||||
In the most cases handlers spawn god class ``ahriman.application.application.Application`` class and call required methods.
|
||||
|
||||
@ -114,7 +118,7 @@ Schema and data migrations
|
||||
|
||||
The schema migration are applied according to current ``pragma user_info`` values, located at ``ahriman.core.database.migrations`` package and named as ``m000_migration_name.py`` (the preceding ``m`` is required in order to import migration content for tests). Additional class ``ahriman.core.database.migrations.Migrations`` reads all migrations automatically and applies them in alphabetical order.
|
||||
|
||||
These migrations also contain data migrations. Though the recommended way is to migrate data directly from SQL requests, sometimes it is required to have external data (like packages list) in order to set correct data. To do so, special method `migrate_data` is used.
|
||||
These migrations can also contain data migrations. Though the recommended way is to migrate data directly from SQL requests, sometimes it is required to have external data (like packages list) in order to set correct data. To do so, special method `migrate_data` is used.
|
||||
|
||||
Type conversions
|
||||
^^^^^^^^^^^^^^^^
|
||||
@ -126,6 +130,12 @@ By default, it parses rows into python dictionary. In addition, the following ps
|
||||
Basic flows
|
||||
-----------
|
||||
|
||||
By default package build operations are performed with ``PACKAGER`` which is specified in ``makepkg.conf``, however, it is possible to override this variable from command line; in this case service performs lookup in the following way:
|
||||
|
||||
* If packager is not set, it reads environment variables (e.g. ``SUDO_USER`` and ``USER``), otherwise it uses value from command line.
|
||||
* It checks users for the specified username and tries to extract packager variable from it.
|
||||
* If packager value has been found, it will be passed as ``PACKAGER`` system variable (sudo configuration required).
|
||||
|
||||
Add new packages or rebuild existing
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@ -140,7 +150,7 @@ This logic can be overwritten by specifying the ``source`` parameter, which is p
|
||||
Rebuild packages
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Same as add function for every package in repository. Optional filter by reverse dependency can be supplied.
|
||||
Same as add function for every package in repository. Optional filters by reverse dependency or build status can be supplied.
|
||||
|
||||
Remove packages
|
||||
^^^^^^^^^^^^^^^
|
||||
@ -224,7 +234,7 @@ OAuth provider uses library definitions (``aioauth-client``) in order *authentic
|
||||
|
||||
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 addition, web service checks the source socket used. In case if it belongs to ``socket.AF_UNIX`` family, it will skip any further 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.
|
||||
|
||||
@ -319,3 +329,5 @@ External calls
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Web application provides external calls to control main service. It spawns child process with specific arguments and waits for its termination. This feature must be used either with authorization or in safe (i.e. when status page is not available world-wide) environment.
|
||||
|
||||
For most actions it also extracts user from authentication (if provided) and passes it to underlying process.
|
||||
|
@ -1,18 +1,18 @@
|
||||
# AUTOMATICALLY GENERATED by `shtab`
|
||||
|
||||
_shtab_ahriman_subparsers=('aur-search' 'search' 'help' 'help-commands-unsafe' 'help-updates' 'help-version' 'version' '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-daemon' 'daemon' 'repo-rebuild' 'rebuild' 'repo-remove-unknown' 'remove-unknown' 'repo-report' 'report' 'repo-restore' 'repo-sign' 'sign' 'repo-status-update' 'repo-sync' 'sync' 'repo-tree' 'repo-triggers' 'repo-update' 'update' 'service-clean' 'clean' 'repo-clean' 'service-config' 'config' 'repo-config' 'service-config-validate' 'config-validate' 'repo-config-validate' 'service-key-import' 'key-import' 'service-setup' 'init' 'repo-init' 'repo-setup' 'setup' 'service-shell' 'shell' 'user-add' 'user-list' 'user-remove' 'web')
|
||||
_shtab_ahriman_subparsers=('aur-search' 'search' 'help' 'help-commands-unsafe' 'help-updates' 'help-version' 'version' '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-create-keyring' 'repo-create-mirrorlist' 'repo-daemon' 'daemon' 'repo-rebuild' 'rebuild' 'repo-remove-unknown' 'remove-unknown' 'repo-report' 'report' 'repo-restore' 'repo-sign' 'sign' 'repo-status-update' 'repo-sync' 'sync' 'repo-tree' 'repo-triggers' 'repo-update' 'update' 'service-clean' 'clean' 'repo-clean' 'service-config' 'config' 'repo-config' 'service-config-validate' 'config-validate' 'repo-config-validate' 'service-key-import' 'key-import' 'service-setup' 'init' 'repo-init' 'repo-setup' 'setup' 'service-shell' 'shell' 'user-add' 'user-list' 'user-remove' 'web')
|
||||
|
||||
_shtab_ahriman_option_strings=('-h' '--help' '-a' '--architecture' '-c' '--configuration' '--force' '-l' '--lock' '--report' '--no-report' '-q' '--quiet' '--unsafe' '-V' '--version')
|
||||
_shtab_ahriman_option_strings=('-h' '--help' '-a' '--architecture' '-c' '--configuration' '--force' '-l' '--lock' '--log-handler' '--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_help_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_help_commands_unsafe_option_strings=('-h' '--help' '--command')
|
||||
_shtab_ahriman_help_commands_unsafe_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_help_updates_option_strings=('-h' '--help' '-e' '--exit-code')
|
||||
_shtab_ahriman_help_version_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_version_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_package_add_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source')
|
||||
_shtab_ahriman_add_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source')
|
||||
_shtab_ahriman_package_update_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source')
|
||||
_shtab_ahriman_package_add_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username')
|
||||
_shtab_ahriman_add_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username')
|
||||
_shtab_ahriman_package_update_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username')
|
||||
_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')
|
||||
@ -27,10 +27,12 @@ _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_create_keyring_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_repo_create_mirrorlist_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_repo_daemon_option_strings=('-h' '--help' '-i' '--interval' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||
_shtab_ahriman_daemon_option_strings=('-h' '--help' '-i' '--interval' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||
_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_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '-e' '--exit-code' '-s' '--status' '-u' '--username')
|
||||
_shtab_ahriman_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '-e' '--exit-code' '-s' '--status' '-u' '--username')
|
||||
_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')
|
||||
@ -43,8 +45,8 @@ _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' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--dry-run' '-e' '--exit-code' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||
_shtab_ahriman_update_option_strings=('-h' '--help' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--dry-run' '-e' '--exit-code' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||
_shtab_ahriman_repo_update_option_strings=('-h' '--help' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--dry-run' '-e' '--exit-code' '--local' '--no-local' '--manual' '--no-manual' '-u' '--username' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||
_shtab_ahriman_update_option_strings=('-h' '--help' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--dry-run' '-e' '--exit-code' '--local' '--no-local' '--manual' '--no-manual' '-u' '--username' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||
_shtab_ahriman_service_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_clean_option_strings=('-h' '--help' '--cache' '--no-cache' '--chroot' '--no-chroot' '--manual' '--no-manual' '--packages' '--no-packages' '--pacman' '--no-pacman')
|
||||
@ -56,21 +58,22 @@ _shtab_ahriman_config_validate_option_strings=('-h' '--help' '-e' '--exit-code')
|
||||
_shtab_ahriman_repo_config_validate_option_strings=('-h' '--help' '-e' '--exit-code')
|
||||
_shtab_ahriman_service_key_import_option_strings=('-h' '--help' '--key-server')
|
||||
_shtab_ahriman_key_import_option_strings=('-h' '--help' '--key-server')
|
||||
_shtab_ahriman_service_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--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' '--mirror' '--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' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_repo_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--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' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_service_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--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' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--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' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_repo_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--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' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_service_shell_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_shell_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_user_add_option_strings=('-h' '--help' '-p' '--password' '-r' '--role' '-s' '--secure')
|
||||
_shtab_ahriman_user_add_option_strings=('-h' '--help' '--key' '--packager' '-p' '--password' '-r' '--role')
|
||||
_shtab_ahriman_user_list_option_strings=('-h' '--help' '-e' '--exit-code' '-r' '--role')
|
||||
_shtab_ahriman_user_remove_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_web_option_strings=('-h' '--help')
|
||||
|
||||
|
||||
|
||||
_shtab_ahriman_pos_0_choices=('aur-search' 'search' 'help' 'help-commands-unsafe' 'help-updates' 'help-version' 'version' '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-daemon' 'daemon' 'repo-rebuild' 'rebuild' 'repo-remove-unknown' 'remove-unknown' 'repo-report' 'report' 'repo-restore' 'repo-sign' 'sign' 'repo-status-update' 'repo-sync' 'sync' 'repo-tree' 'repo-triggers' 'repo-update' 'update' 'service-clean' 'clean' 'repo-clean' 'service-config' 'config' 'repo-config' 'service-config-validate' 'config-validate' 'repo-config-validate' 'service-key-import' 'key-import' 'service-setup' 'init' 'repo-init' 'repo-setup' 'setup' 'service-shell' 'shell' 'user-add' 'user-list' 'user-remove' 'web')
|
||||
_shtab_ahriman_pos_0_choices=('aur-search' 'search' 'help' 'help-commands-unsafe' 'help-updates' 'help-version' 'version' '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-create-keyring' 'repo-create-mirrorlist' 'repo-daemon' 'daemon' 'repo-rebuild' 'rebuild' 'repo-remove-unknown' 'remove-unknown' 'repo-report' 'report' 'repo-restore' 'repo-sign' 'sign' 'repo-status-update' 'repo-sync' 'sync' 'repo-tree' 'repo-triggers' 'repo-update' 'update' 'service-clean' 'clean' 'repo-clean' 'service-config' 'config' 'repo-config' 'service-config-validate' 'config-validate' 'repo-config-validate' 'service-key-import' 'key-import' 'service-setup' 'init' 'repo-init' 'repo-setup' 'setup' 'service-shell' 'shell' 'user-add' 'user-list' 'user-remove' 'web')
|
||||
_shtab_ahriman___log_handler_choices=('console' 'syslog' 'journald')
|
||||
_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' 'submitter' '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' 'submitter' 'url' 'url_path' 'version')
|
||||
_shtab_ahriman_package_add__s_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
|
||||
@ -87,6 +90,10 @@ _shtab_ahriman_package_status_update__s_choices=('unknown' 'pending' 'building'
|
||||
_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_rebuild__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||
_shtab_ahriman_repo_rebuild___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||
_shtab_ahriman_rebuild__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||
_shtab_ahriman_rebuild___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||
_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_service_setup___sign_target_choices=('disabled' 'packages' 'repository')
|
||||
@ -126,6 +133,7 @@ _shtab_ahriman_search___info_nargs=0
|
||||
_shtab_ahriman_search___no_info_nargs=0
|
||||
_shtab_ahriman_help__h_nargs=0
|
||||
_shtab_ahriman_help___help_nargs=0
|
||||
_shtab_ahriman_help_commands_unsafe_pos_0_nargs=*
|
||||
_shtab_ahriman_help_commands_unsafe__h_nargs=0
|
||||
_shtab_ahriman_help_commands_unsafe___help_nargs=0
|
||||
_shtab_ahriman_help_updates__h_nargs=0
|
||||
@ -230,6 +238,10 @@ _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_create_keyring__h_nargs=0
|
||||
_shtab_ahriman_repo_create_keyring___help_nargs=0
|
||||
_shtab_ahriman_repo_create_mirrorlist__h_nargs=0
|
||||
_shtab_ahriman_repo_create_mirrorlist___help_nargs=0
|
||||
_shtab_ahriman_repo_daemon__h_nargs=0
|
||||
_shtab_ahriman_repo_daemon___help_nargs=0
|
||||
_shtab_ahriman_repo_daemon___aur_nargs=0
|
||||
@ -401,30 +413,40 @@ _shtab_ahriman_key_import__h_nargs=0
|
||||
_shtab_ahriman_key_import___help_nargs=0
|
||||
_shtab_ahriman_service_setup__h_nargs=0
|
||||
_shtab_ahriman_service_setup___help_nargs=0
|
||||
_shtab_ahriman_service_setup___generate_salt_nargs=0
|
||||
_shtab_ahriman_service_setup___no_generate_salt_nargs=0
|
||||
_shtab_ahriman_service_setup___makeflags_jobs_nargs=0
|
||||
_shtab_ahriman_service_setup___no_makeflags_jobs_nargs=0
|
||||
_shtab_ahriman_service_setup___multilib_nargs=0
|
||||
_shtab_ahriman_service_setup___no_multilib_nargs=0
|
||||
_shtab_ahriman_init__h_nargs=0
|
||||
_shtab_ahriman_init___help_nargs=0
|
||||
_shtab_ahriman_init___generate_salt_nargs=0
|
||||
_shtab_ahriman_init___no_generate_salt_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___generate_salt_nargs=0
|
||||
_shtab_ahriman_repo_init___no_generate_salt_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_repo_setup__h_nargs=0
|
||||
_shtab_ahriman_repo_setup___help_nargs=0
|
||||
_shtab_ahriman_repo_setup___generate_salt_nargs=0
|
||||
_shtab_ahriman_repo_setup___no_generate_salt_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_setup__h_nargs=0
|
||||
_shtab_ahriman_setup___help_nargs=0
|
||||
_shtab_ahriman_setup___generate_salt_nargs=0
|
||||
_shtab_ahriman_setup___no_generate_salt_nargs=0
|
||||
_shtab_ahriman_setup___makeflags_jobs_nargs=0
|
||||
_shtab_ahriman_setup___no_makeflags_jobs_nargs=0
|
||||
_shtab_ahriman_setup___multilib_nargs=0
|
||||
@ -439,8 +461,6 @@ _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
|
||||
@ -469,7 +489,7 @@ _shtab_replace_nonword() {
|
||||
# set default values (called for the initial parser & any subparsers)
|
||||
_set_parser_defaults() {
|
||||
local subparsers_var="${prefix}_subparsers[@]"
|
||||
sub_parsers=${!subparsers_var}
|
||||
sub_parsers=${!subparsers_var-}
|
||||
|
||||
local current_option_strings_var="${prefix}_option_strings[@]"
|
||||
current_option_strings=${!current_option_strings_var}
|
||||
@ -486,13 +506,13 @@ _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}"
|
||||
current_action_compgen="${!current_action_compgen_var-}"
|
||||
|
||||
local current_action_choices_var="${current_action}_choices[@]"
|
||||
current_action_choices="${!current_action_choices_var}"
|
||||
current_action_choices="${!current_action_choices_var-}"
|
||||
|
||||
local current_action_nargs_var="${current_action}_nargs"
|
||||
if [ -n "${!current_action_nargs_var}" ]; then
|
||||
if [ -n "${!current_action_nargs_var-}" ]; then
|
||||
current_action_nargs="${!current_action_nargs_var}"
|
||||
else
|
||||
current_action_nargs=1
|
||||
@ -514,8 +534,8 @@ _shtab_ahriman() {
|
||||
local completing_word="${COMP_WORDS[COMP_CWORD]}"
|
||||
COMPREPLY=()
|
||||
|
||||
prefix=_shtab_ahriman
|
||||
word_index=0
|
||||
local prefix=_shtab_ahriman
|
||||
local word_index=0
|
||||
_set_parser_defaults
|
||||
word_index=1
|
||||
|
||||
@ -524,13 +544,13 @@ _shtab_ahriman() {
|
||||
while [ $word_index -ne $COMP_CWORD ]; do
|
||||
local this_word="${COMP_WORDS[$word_index]}"
|
||||
|
||||
if [[ -n $sub_parsers && " ${sub_parsers[@]} " =~ " ${this_word} " ]]; then
|
||||
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
|
||||
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
|
||||
|
@ -36,6 +36,8 @@ _shtab_ahriman_commands() {
|
||||
"repo-clean:remove local caches"
|
||||
"repo-config:dump configuration for the specified architecture"
|
||||
"repo-config-validate:validate configuration and print found errors"
|
||||
"repo-create-keyring:create package which contains list of trusted keys as set by configuration. Note, that this action will only create package, the package itself has to be built manually"
|
||||
"repo-create-mirrorlist:create package which contains list of available mirrors as set by configuration. Note, that this action will only create package, the package itself has to be built manually"
|
||||
"repo-daemon:start process which periodically will run update process"
|
||||
"repo-init:create initial service configuration, requires root"
|
||||
"repo-rebuild:force rebuild whole repository"
|
||||
@ -56,9 +58,9 @@ _shtab_ahriman_commands() {
|
||||
"service-config-validate:validate configuration and print found errors"
|
||||
"service-key-import:import PGP key from public sources to the repository user"
|
||||
"service-setup:create initial service configuration, requires root"
|
||||
"service-shell:drop into python shell while having created application"
|
||||
"service-shell:drop into python shell"
|
||||
"setup:create initial service configuration, requires root"
|
||||
"shell:drop into python shell while having created application"
|
||||
"shell:drop into python shell"
|
||||
"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"
|
||||
@ -75,85 +77,87 @@ _shtab_ahriman_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]"
|
||||
"*"{-a,--architecture}"[target architectures. For several subcommands it can be used multiple times (default\: None)]:architecture:"
|
||||
{-c,--configuration}"[configuration path (default\: \/etc\/ahriman.ini)]:configuration:"
|
||||
"--force[force run, remove file lock (default\: False)]"
|
||||
{-l,--lock}"[lock file (default\: \/tmp\/ahriman.lock)]:lock:"
|
||||
"--log-handler[explicit log handler specification. If none set, the handler will be guessed from environment (default\: None)]:log_handler:(console syslog journald)"
|
||||
{--report,--no-report}"[force enable or disable reporting to web service (default\: True)]:report:"
|
||||
{-q,--quiet}"[force disable any logging (default\: False)]"
|
||||
"--unsafe[allow to run ahriman as non-ahriman user. Some actions might be unavailable (default\: False)]"
|
||||
"(- : *)"{-V,--version}"[show program\'s version number and exit]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: \%(default)s)]:dependencies:"
|
||||
{-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)"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{-n,--now}"[run update function after (default\: False)]"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
{-s,--source}"[explicitly specify the package source for this command (default\: PackageSource.Auto)]:source:(auto archive aur directory local remote repository)"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
"(*):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 submitter url url_path version)"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--info,--no-info}"[show additional package information (default\: False)]: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 (default\: name)]:sort_by:(description first_submitted id last_modified maintainer name num_votes out_of_date package_base package_base_id popularity repository submitter 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}"[fetch actual version 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:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
"(*)::filter check by package base (default\: None):"
|
||||
)
|
||||
|
||||
_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:"
|
||||
{--cache,--no-cache}"[clear directory with package caches (default\: False)]:cache:"
|
||||
{--chroot,--no-chroot}"[clear build chroot (default\: False)]:chroot:"
|
||||
{--manual,--no-manual}"[clear manually added packages queue (default\: False)]:manual:"
|
||||
{--packages,--no-packages}"[clear directory with built packages (default\: False)]:packages:"
|
||||
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: False)]:pacman:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_config_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--secure,--no-secure}"[hide passwords and secrets from output (default\: \%(default)s)]:secure:"
|
||||
{--secure,--no-secure}"[hide passwords and secrets from output (default\: True)]:secure:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_config_validate_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid (default\: False)]"
|
||||
)
|
||||
|
||||
_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 (default\: \%(default)s)]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: \%(default)s)]:dependencies:"
|
||||
{--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}"[fetch actual version 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]"
|
||||
{-i,--interval}"[interval between runs in seconds (default\: 43200)]:interval:"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates (default\: True)]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: True)]:local:"
|
||||
{--manual,--no-manual}"[include or exclude manual updates (default\: True)]:manual:"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_help_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
":show help message for specific command:"
|
||||
":show help message for specific command (default\: None):"
|
||||
)
|
||||
|
||||
_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:"
|
||||
"(*)::instead of showing commands, just test command line for unsafe subcommand and return 0 in case if command is safe and 1 otherwise (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_help_updates_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit code if updates available]"
|
||||
{-e,--exit-code}"[return non-zero exit code if updates available (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_help_version_options=(
|
||||
@ -162,33 +166,35 @@ _shtab_ahriman_help_version_options=(
|
||||
|
||||
_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:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
|
||||
{--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:"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
"--build-command[build command prefix (default\: ahriman)]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration (default\: \/usr\/share\/devtools\/pacman.conf.d\/extra.conf)]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords (default\: False)]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]: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:"
|
||||
"--key-server[key server for key import (default\: keyserver.ubuntu.com)]:key_server:"
|
||||
":PGP key to import from public server:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_package_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: \%(default)s)]:dependencies:"
|
||||
{-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)"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{-n,--now}"[run update function after (default\: False)]"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
{-s,--source}"[explicitly specify the package source for this command (default\: PackageSource.Auto)]:source:(auto archive aur directory local remote repository)"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
"(*):package source (base name, path to local files, remote URL):"
|
||||
)
|
||||
|
||||
@ -199,11 +205,11 @@ _shtab_ahriman_package_remove_options=(
|
||||
|
||||
_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:"
|
||||
"--ahriman[get service status itself (default\: False)]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--info,--no-info}"[show additional package information (default\: False)]:info:"
|
||||
{-s,--status}"[filter packages by status (default\: None)]:status:(unknown pending building failed success)"
|
||||
"(*)::filter status by package base (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_package_status_remove_options=(
|
||||
@ -213,17 +219,18 @@ _shtab_ahriman_package_status_remove_options=(
|
||||
|
||||
_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:"
|
||||
{-s,--status}"[new package build status (default\: BuildStatusEnum.Success)]:status:(unknown pending building failed success)"
|
||||
"(*)::set status for specified packages. If no packages supplied, service status will be updated (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_package_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: \%(default)s)]:dependencies:"
|
||||
{-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)"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{-n,--now}"[run update function after (default\: False)]"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
{-s,--source}"[explicitly specify the package source for this command (default\: PackageSource.Auto)]:source:(auto archive aur directory local remote repository)"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
"(*):package source (base name, path to local files, remote URL):"
|
||||
)
|
||||
|
||||
@ -231,34 +238,36 @@ _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:"
|
||||
":path to file which contains function or variable value. If not set, the value will be read from stdin (default\: None):"
|
||||
)
|
||||
|
||||
_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:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
"*"{-v,--variable}"[if set, show only patches for specified PKGBUILD variables (default\: None)]:variable:"
|
||||
":package base (default\: None):"
|
||||
)
|
||||
|
||||
_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:"
|
||||
"*"{-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 (default\: None)]: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:"
|
||||
"*"{-t,--track}"[files which has to be tracked (default\: \[\'\*.diff\', \'\*.patch\'\])]: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]"
|
||||
"*--depends-on[only rebuild packages that depend on specified packages (default\: None)]:depends_on:"
|
||||
"--dry-run[just perform check for packages without rebuild process itself (default\: False)]"
|
||||
"--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. (default\: False)]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{-s,--status}"[filter packages by status. Requires --from-database to be set (default\: None)]:status:(unknown pending building failed success)"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_remove_options=(
|
||||
@ -268,7 +277,7 @@ _shtab_ahriman_remove_options=(
|
||||
|
||||
_shtab_ahriman_remove_unknown_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--dry-run[just perform check for packages without removal]"
|
||||
"--dry-run[just perform check for packages without removal (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_backup_options=(
|
||||
@ -278,69 +287,80 @@ _shtab_ahriman_repo_backup_options=(
|
||||
|
||||
_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}"[fetch actual version 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:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
"(*)::filter check by package base (default\: None):"
|
||||
)
|
||||
|
||||
_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:"
|
||||
{--cache,--no-cache}"[clear directory with package caches (default\: False)]:cache:"
|
||||
{--chroot,--no-chroot}"[clear build chroot (default\: False)]:chroot:"
|
||||
{--manual,--no-manual}"[clear manually added packages queue (default\: False)]:manual:"
|
||||
{--packages,--no-packages}"[clear directory with built packages (default\: False)]:packages:"
|
||||
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: False)]:pacman:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_config_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--secure,--no-secure}"[hide passwords and secrets from output (default\: \%(default)s)]:secure:"
|
||||
{--secure,--no-secure}"[hide passwords and secrets from output (default\: True)]:secure:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_config_validate_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_create_keyring_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_create_mirrorlist_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_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 (default\: \%(default)s)]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: \%(default)s)]:dependencies:"
|
||||
{--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}"[fetch actual version 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]"
|
||||
{-i,--interval}"[interval between runs in seconds (default\: 43200)]:interval:"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates (default\: True)]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: True)]:local:"
|
||||
{--manual,--no-manual}"[include or exclude manual updates (default\: True)]:manual:"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
)
|
||||
|
||||
_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:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
|
||||
{--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:"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
"--build-command[build command prefix (default\: ahriman)]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration (default\: \/usr\/share\/devtools\/pacman.conf.d\/extra.conf)]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords (default\: False)]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]: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]"
|
||||
"*--depends-on[only rebuild packages that depend on specified packages (default\: None)]:depends_on:"
|
||||
"--dry-run[just perform check for packages without rebuild process itself (default\: False)]"
|
||||
"--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. (default\: False)]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{-s,--status}"[filter packages by status. Requires --from-database to be set (default\: None)]:status:(unknown pending building failed success)"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_remove_unknown_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--dry-run[just perform check for packages without removal]"
|
||||
"--dry-run[just perform check for packages without removal (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_report_options=(
|
||||
@ -349,34 +369,35 @@ _shtab_ahriman_repo_report_options=(
|
||||
|
||||
_shtab_ahriman_repo_restore_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-o,--output}"[root path of the extracted files]:output:"
|
||||
{-o,--output}"[root path of the extracted files (default\: \/)]: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:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
|
||||
{--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:"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
"--build-command[build command prefix (default\: ahriman)]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration (default\: \/usr\/share\/devtools\/pacman.conf.d\/extra.conf)]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords (default\: False)]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]:web_unix_socket:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_sign_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*)::sign only specified packages:"
|
||||
"(*)::sign only specified packages (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_status_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-s,--status}"[new status]:status:(unknown pending building failed success)"
|
||||
{-s,--status}"[new status (default\: BuildStatusEnum.Success)]:status:(unknown pending building failed success)"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_sync_options=(
|
||||
@ -389,20 +410,21 @@ _shtab_ahriman_repo_tree_options=(
|
||||
|
||||
_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:"
|
||||
"(*)::instead of running all triggers as set by configuration, just process specified ones in order of mention (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates (default\: \%(default)s)]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: \%(default)s)]:dependencies:"
|
||||
"--dry-run[just perform check for updates, same as check command]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{--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}"[fetch actual version 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:"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates (default\: True)]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
"--dry-run[just perform check for updates, same as check command (default\: False)]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: True)]:local:"
|
||||
{--manual,--no-manual}"[include or exclude manual updates (default\: True)]:manual:"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
"(*)::filter check by package base (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_report_options=(
|
||||
@ -411,97 +433,99 @@ _shtab_ahriman_report_options=(
|
||||
|
||||
_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 submitter url url_path version)"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--info,--no-info}"[show additional package information (default\: False)]: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 (default\: name)]:sort_by:(description first_submitted id last_modified maintainer name num_votes out_of_date package_base package_base_id popularity repository submitter url url_path version)"
|
||||
"(*):search terms, can be specified multiple times, the result will match all terms:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_service_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:"
|
||||
{--cache,--no-cache}"[clear directory with package caches (default\: False)]:cache:"
|
||||
{--chroot,--no-chroot}"[clear build chroot (default\: False)]:chroot:"
|
||||
{--manual,--no-manual}"[clear manually added packages queue (default\: False)]:manual:"
|
||||
{--packages,--no-packages}"[clear directory with built packages (default\: False)]:packages:"
|
||||
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: False)]:pacman:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_service_config_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--secure,--no-secure}"[hide passwords and secrets from output (default\: \%(default)s)]:secure:"
|
||||
{--secure,--no-secure}"[hide passwords and secrets from output (default\: True)]:secure:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_service_config_validate_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_service_key_import_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--key-server[key server for key import]:key_server:"
|
||||
"--key-server[key server for key import (default\: keyserver.ubuntu.com)]:key_server:"
|
||||
":PGP key to import from public server:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_service_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:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
|
||||
{--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:"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
"--build-command[build command prefix (default\: ahriman)]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration (default\: \/usr\/share\/devtools\/pacman.conf.d\/extra.conf)]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords (default\: False)]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]:web_unix_socket:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_service_shell_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
":instead of dropping into shell, just execute the specified code:"
|
||||
":instead of dropping into shell, just execute the specified code (default\: None):"
|
||||
)
|
||||
|
||||
_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:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
|
||||
{--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:"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
"--build-command[build command prefix (default\: ahriman)]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration (default\: \/usr\/share\/devtools\/pacman.conf.d\/extra.conf)]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords (default\: False)]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]: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:"
|
||||
":instead of dropping into shell, just execute the specified code (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_sign_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*)::sign only specified packages:"
|
||||
"(*)::sign only specified packages (default\: None):"
|
||||
)
|
||||
|
||||
_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:"
|
||||
"--ahriman[get service status itself (default\: False)]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--info,--no-info}"[show additional package information (default\: False)]:info:"
|
||||
{-s,--status}"[filter packages by status (default\: None)]:status:(unknown pending building failed success)"
|
||||
"(*)::filter status by package base (default\: None):"
|
||||
)
|
||||
|
||||
_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:"
|
||||
{-s,--status}"[new package build status (default\: BuildStatusEnum.Success)]:status:(unknown pending building failed success)"
|
||||
"(*)::set status for specified packages. If no packages supplied, service status will be updated (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_sync_options=(
|
||||
@ -510,30 +534,32 @@ _shtab_ahriman_sync_options=(
|
||||
|
||||
_shtab_ahriman_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates (default\: \%(default)s)]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: \%(default)s)]:dependencies:"
|
||||
"--dry-run[just perform check for updates, same as check command]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{--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}"[fetch actual version 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:"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates (default\: True)]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
"--dry-run[just perform check for updates, same as check command (default\: False)]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: True)]:local:"
|
||||
{--manual,--no-manual}"[include or exclude manual updates (default\: True)]:manual:"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
"(*)::filter check by package base (default\: None):"
|
||||
)
|
||||
|
||||
_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]"
|
||||
"--key[optional PGP key used by this user. The private key must be imported (default\: None)]:key:"
|
||||
"--packager[optional packager id used for build process in form of \`Name Surname \<mail\@example.com\>\` (default\: None)]:packager:"
|
||||
{-p,--password}"[user password. Blank password will be treated as empty password, which is in particular must be used for OAuth2 authorization type. (default\: None)]:password:"
|
||||
{-r,--role}"[user access level (default\: UserAccess.Read)]:role:(unauthorized read reporter full)"
|
||||
":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:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{-r,--role}"[filter users by role (default\: None)]:role:(unauthorized read reporter full)"
|
||||
":filter users by username (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_user_remove_options=(
|
||||
@ -556,7 +582,7 @@ _shtab_ahriman() {
|
||||
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
|
||||
_arguments -C -s $_shtab_ahriman_options
|
||||
|
||||
case $state in
|
||||
ahriman)
|
||||
@ -564,70 +590,72 @@ _shtab_ahriman() {
|
||||
(( 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 ;;
|
||||
config-validate) _arguments -C $_shtab_ahriman_config_validate_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 ;;
|
||||
help-updates) _arguments -C $_shtab_ahriman_help_updates_options ;;
|
||||
help-version) _arguments -C $_shtab_ahriman_help_version_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-config-validate) _arguments -C $_shtab_ahriman_repo_config_validate_options ;;
|
||||
repo-daemon) _arguments -C $_shtab_ahriman_repo_daemon_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 ;;
|
||||
service-clean) _arguments -C $_shtab_ahriman_service_clean_options ;;
|
||||
service-config) _arguments -C $_shtab_ahriman_service_config_options ;;
|
||||
service-config-validate) _arguments -C $_shtab_ahriman_service_config_validate_options ;;
|
||||
service-key-import) _arguments -C $_shtab_ahriman_service_key_import_options ;;
|
||||
service-setup) _arguments -C $_shtab_ahriman_service_setup_options ;;
|
||||
service-shell) _arguments -C $_shtab_ahriman_service_shell_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 ;;
|
||||
add) _arguments -C -s $_shtab_ahriman_add_options ;;
|
||||
aur-search) _arguments -C -s $_shtab_ahriman_aur_search_options ;;
|
||||
check) _arguments -C -s $_shtab_ahriman_check_options ;;
|
||||
clean) _arguments -C -s $_shtab_ahriman_clean_options ;;
|
||||
config) _arguments -C -s $_shtab_ahriman_config_options ;;
|
||||
config-validate) _arguments -C -s $_shtab_ahriman_config_validate_options ;;
|
||||
daemon) _arguments -C -s $_shtab_ahriman_daemon_options ;;
|
||||
help) _arguments -C -s $_shtab_ahriman_help_options ;;
|
||||
help-commands-unsafe) _arguments -C -s $_shtab_ahriman_help_commands_unsafe_options ;;
|
||||
help-updates) _arguments -C -s $_shtab_ahriman_help_updates_options ;;
|
||||
help-version) _arguments -C -s $_shtab_ahriman_help_version_options ;;
|
||||
init) _arguments -C -s $_shtab_ahriman_init_options ;;
|
||||
key-import) _arguments -C -s $_shtab_ahriman_key_import_options ;;
|
||||
package-add) _arguments -C -s $_shtab_ahriman_package_add_options ;;
|
||||
package-remove) _arguments -C -s $_shtab_ahriman_package_remove_options ;;
|
||||
package-status) _arguments -C -s $_shtab_ahriman_package_status_options ;;
|
||||
package-status-remove) _arguments -C -s $_shtab_ahriman_package_status_remove_options ;;
|
||||
package-status-update) _arguments -C -s $_shtab_ahriman_package_status_update_options ;;
|
||||
package-update) _arguments -C -s $_shtab_ahriman_package_update_options ;;
|
||||
patch-add) _arguments -C -s $_shtab_ahriman_patch_add_options ;;
|
||||
patch-list) _arguments -C -s $_shtab_ahriman_patch_list_options ;;
|
||||
patch-remove) _arguments -C -s $_shtab_ahriman_patch_remove_options ;;
|
||||
patch-set-add) _arguments -C -s $_shtab_ahriman_patch_set_add_options ;;
|
||||
rebuild) _arguments -C -s $_shtab_ahriman_rebuild_options ;;
|
||||
remove) _arguments -C -s $_shtab_ahriman_remove_options ;;
|
||||
remove-unknown) _arguments -C -s $_shtab_ahriman_remove_unknown_options ;;
|
||||
repo-backup) _arguments -C -s $_shtab_ahriman_repo_backup_options ;;
|
||||
repo-check) _arguments -C -s $_shtab_ahriman_repo_check_options ;;
|
||||
repo-clean) _arguments -C -s $_shtab_ahriman_repo_clean_options ;;
|
||||
repo-config) _arguments -C -s $_shtab_ahriman_repo_config_options ;;
|
||||
repo-config-validate) _arguments -C -s $_shtab_ahriman_repo_config_validate_options ;;
|
||||
repo-create-keyring) _arguments -C -s $_shtab_ahriman_repo_create_keyring_options ;;
|
||||
repo-create-mirrorlist) _arguments -C -s $_shtab_ahriman_repo_create_mirrorlist_options ;;
|
||||
repo-daemon) _arguments -C -s $_shtab_ahriman_repo_daemon_options ;;
|
||||
repo-init) _arguments -C -s $_shtab_ahriman_repo_init_options ;;
|
||||
repo-rebuild) _arguments -C -s $_shtab_ahriman_repo_rebuild_options ;;
|
||||
repo-remove-unknown) _arguments -C -s $_shtab_ahriman_repo_remove_unknown_options ;;
|
||||
repo-report) _arguments -C -s $_shtab_ahriman_repo_report_options ;;
|
||||
repo-restore) _arguments -C -s $_shtab_ahriman_repo_restore_options ;;
|
||||
repo-setup) _arguments -C -s $_shtab_ahriman_repo_setup_options ;;
|
||||
repo-sign) _arguments -C -s $_shtab_ahriman_repo_sign_options ;;
|
||||
repo-status-update) _arguments -C -s $_shtab_ahriman_repo_status_update_options ;;
|
||||
repo-sync) _arguments -C -s $_shtab_ahriman_repo_sync_options ;;
|
||||
repo-tree) _arguments -C -s $_shtab_ahriman_repo_tree_options ;;
|
||||
repo-triggers) _arguments -C -s $_shtab_ahriman_repo_triggers_options ;;
|
||||
repo-update) _arguments -C -s $_shtab_ahriman_repo_update_options ;;
|
||||
report) _arguments -C -s $_shtab_ahriman_report_options ;;
|
||||
search) _arguments -C -s $_shtab_ahriman_search_options ;;
|
||||
service-clean) _arguments -C -s $_shtab_ahriman_service_clean_options ;;
|
||||
service-config) _arguments -C -s $_shtab_ahriman_service_config_options ;;
|
||||
service-config-validate) _arguments -C -s $_shtab_ahriman_service_config_validate_options ;;
|
||||
service-key-import) _arguments -C -s $_shtab_ahriman_service_key_import_options ;;
|
||||
service-setup) _arguments -C -s $_shtab_ahriman_service_setup_options ;;
|
||||
service-shell) _arguments -C -s $_shtab_ahriman_service_shell_options ;;
|
||||
setup) _arguments -C -s $_shtab_ahriman_setup_options ;;
|
||||
shell) _arguments -C -s $_shtab_ahriman_shell_options ;;
|
||||
sign) _arguments -C -s $_shtab_ahriman_sign_options ;;
|
||||
status) _arguments -C -s $_shtab_ahriman_status_options ;;
|
||||
status-update) _arguments -C -s $_shtab_ahriman_status_update_options ;;
|
||||
sync) _arguments -C -s $_shtab_ahriman_sync_options ;;
|
||||
update) _arguments -C -s $_shtab_ahriman_update_options ;;
|
||||
user-add) _arguments -C -s $_shtab_ahriman_user_add_options ;;
|
||||
user-list) _arguments -C -s $_shtab_ahriman_user_list_options ;;
|
||||
user-remove) _arguments -C -s $_shtab_ahriman_user_remove_options ;;
|
||||
version) _arguments -C -s $_shtab_ahriman_version_options ;;
|
||||
web) _arguments -C -s $_shtab_ahriman_web_options ;;
|
||||
esac
|
||||
esac
|
||||
}
|
||||
|
10
docs/conf.py
10
docs/conf.py
@ -14,7 +14,6 @@ import os
|
||||
import sys
|
||||
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
from ahriman.version import __version__
|
||||
|
||||
@ -24,13 +23,6 @@ sys.path.insert(0, str(basedir))
|
||||
|
||||
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
|
||||
|
||||
for module in (
|
||||
"pyalpm",
|
||||
):
|
||||
if module in sys.modules:
|
||||
continue
|
||||
sys.modules[module] = mock.Mock()
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
@ -92,6 +84,8 @@ autoclass_content = "both"
|
||||
|
||||
autodoc_member_order = "groupwise"
|
||||
|
||||
autodoc_mock_imports = ["pyalpm"]
|
||||
|
||||
autodoc_default_options = {
|
||||
"no-undoc-members": True,
|
||||
}
|
||||
|
@ -30,8 +30,8 @@ Base configuration settings.
|
||||
* ``logging`` - path to logging configuration, string, required. Check ``logging.ini`` for reference.
|
||||
* ``suppress_http_log_errors`` - suppress http log errors, boolean, optional, default ``no``. If set to ``yes``, any http log errors (e.g. if web server is not available, but http logging is enabled) will be suppressed.
|
||||
|
||||
``alpm`` group
|
||||
--------------
|
||||
``alpm:*`` groups
|
||||
-----------------
|
||||
|
||||
libalpm and AUR related configuration. Group name can refer to architecture, e.g. ``alpm:x86_64`` can be used for x86_64 architecture specific settings.
|
||||
|
||||
@ -69,6 +69,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.
|
||||
* ``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_known`` - optional list of ``ahriman.core.triggers.Trigger`` class implementations which are not run automatically and used only for trigger discovery and configuration validation.
|
||||
* ``vcs_allowed_age`` - maximal age in seconds of the VCS packages before their version will be updated with its remote source, int, optional, default ``604800``.
|
||||
|
||||
``repository`` group
|
||||
@ -86,7 +87,6 @@ Settings for signing packages or repository. Group name can refer to architectur
|
||||
|
||||
* ``target`` - configuration flag to enable signing, space separated list of strings, required. Allowed values are ``package`` (sign each package separately), ``repository`` (sign repository database file).
|
||||
* ``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.
|
||||
|
||||
``web:*`` groups
|
||||
----------------
|
||||
@ -107,6 +107,41 @@ Web server settings. If any of ``host``/``port`` is not set, web integration wil
|
||||
* ``unix_socket_unsafe`` - set unsafe (o+w) permissions to unix socket, boolean, optional, default ``yes``. This option is enabled by default, because it is supposed that unix socket is created in safe environment (only web service is supposed to be used in unsafe), but it can be disabled by configuration.
|
||||
* ``username`` - username to authorize in web service in order to update service status, string, required in case if authorization enabled.
|
||||
|
||||
``keyring`` group
|
||||
--------------------
|
||||
|
||||
Keyring package generator plugin.
|
||||
|
||||
* ``target`` - list of generator settings sections, space separated list of strings, required. It must point to valid section name.
|
||||
|
||||
Keyring generator plugin
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* ``description`` - keyring package description, string, optional, default is ``repo PGP keyring``, where ``repo`` is the repository name.
|
||||
* ``homepage`` - url to homepage location if any, string, optional.
|
||||
* ``license`` - list of licenses which are applied to this package, space separated list of strings, optional, default is ``Unlicense``.
|
||||
* ``package`` - keyring package name, string, optional, default is ``repo-keyring``, where ``repo`` is the repository name.
|
||||
* ``packagers`` - list of packagers keys, space separated list of strings, optional, if not set, the ``key_*`` options from ``sign`` group will be used.
|
||||
* ``revoked`` - list of revoked packagers keys, space separated list of strings, optional.
|
||||
* ``trusted`` - list of master keys, space separated list of strings, optional, if not set, the ``key`` option from ``sign`` group will be used.
|
||||
|
||||
``mirrorlist`` group
|
||||
--------------------
|
||||
|
||||
Mirrorlist package generator plugin.
|
||||
|
||||
* ``target`` - list of generator settings sections, space separated list of strings, required. It must point to valid section name.
|
||||
|
||||
Mirrorlist generator plugin
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* ``description`` - mirrorlist package description, string, optional, default is ``repo mirror list for use by pacman``, where ``repo`` is the repository name.
|
||||
* ``homepage`` - url to homepage location if any, string, optional.
|
||||
* ``license`` - list of licenses which are applied to this package, space separated list of strings, optional, default is ``Unlicense``.
|
||||
* ``package`` - mirrorlist package name, string, optional, default is ``repo-mirrorlist``, where ``repo`` is the repository name.
|
||||
* ``path`` - absolute path to generated mirrorlist file, string, optional, default is ``/etc/pacman.d/repo-mirrorlist``, where ``repo`` is the repository name.
|
||||
* ``servers`` - list of repository mirrors, space separated list of strings, required.
|
||||
|
||||
``remote-pull`` group
|
||||
---------------------
|
||||
|
||||
|
113
docs/faq.rst
113
docs/faq.rst
@ -1,4 +1,3 @@
|
||||
|
||||
FAQ
|
||||
===
|
||||
|
||||
@ -197,7 +196,7 @@ Alternatively you can create full-diff patches, which are calculated by using ``
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo -u ahriman ahriman patch-set-add /path/to/local/directory/with/PKGBUILD
|
||||
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).
|
||||
|
||||
@ -392,7 +391,7 @@ The following environment variables are supported:
|
||||
* ``AHRIMAN_FORCE_ROOT`` - force run ahriman as root instead of guessing by subcommand.
|
||||
* ``AHRIMAN_HOST`` - host for the web interface, default is ``0.0.0.0``.
|
||||
* ``AHRIMAN_MULTILIB`` - if set (default) multilib repository will be used, disabled otherwise.
|
||||
* ``AHRIMAN_OUTPUT`` - controls logging handler, e.g. ``syslog``, ``console``. The name must be found in logging configuration. Note that if ``syslog`` (the default) handler is used you will need to mount ``/dev/log`` inside container because it is not available there.
|
||||
* ``AHRIMAN_OUTPUT`` - controls logging handler, e.g. ``syslog``, ``console``. The name must be found in logging configuration. Note that if ``syslog`` handler is used you will need to mount ``/dev/log`` inside container because it is not available there.
|
||||
* ``AHRIMAN_PACKAGER`` - packager name from which packages will be built, default is ``ahriman bot <ahriman@example.com>``.
|
||||
* ``AHRIMAN_PACMAN_MIRROR`` - override pacman mirror server if set.
|
||||
* ``AHRIMAN_PORT`` - HTTP server port if any, default is empty.
|
||||
@ -664,7 +663,7 @@ How to report by email
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
yay -S python-jinja
|
||||
yay -S --asdeps python-jinja
|
||||
|
||||
#.
|
||||
Configure the service:
|
||||
@ -691,7 +690,7 @@ How to generate index page for S3
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
yay -S python-jinja
|
||||
yay -S --asdeps python-jinja
|
||||
|
||||
#.
|
||||
Configure the service:
|
||||
@ -715,7 +714,7 @@ How to post build report to telegram
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
yay -S python-jinja
|
||||
yay -S --asdeps python-jinja
|
||||
|
||||
#.
|
||||
Register bot in telegram. You can do it by talking with `@BotFather <https://t.me/botfather>`_. For more details please refer to `official documentation <https://core.telegram.org/bots>`_.
|
||||
@ -754,6 +753,80 @@ If you did everything fine you should receive the message with the next update.
|
||||
|
||||
(replace ``${CHAT_ID}`` and ``${API_KEY}`` with the values from configuration).
|
||||
|
||||
Maintenance packages
|
||||
--------------------
|
||||
|
||||
Generate keyring package
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The application provides special plugin which generates keyring package. This plugin heavily depends on ``sign`` group settings, however it is possible to override them. The minimal package can be generated in the following way:
|
||||
|
||||
#.
|
||||
Edit configuration:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[keyring]
|
||||
target = keyring_generator
|
||||
|
||||
By default it will use ``sign.key`` as trusted key and all other keys as packagers ones. For all available options refer to :doc:`configuration <configuration>`.
|
||||
|
||||
#.
|
||||
Create package source files:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo -u ahriman ahriman repo-create-keyring
|
||||
|
||||
This command will generate PKGBUILD, revoked and trusted listings and keyring itself and will register the package in database.
|
||||
|
||||
#.
|
||||
Build new package as usual:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo -u ahriman ahriman package-add aur-clone-keyring --source local --now
|
||||
|
||||
where ``aur-clone`` is your repository name.
|
||||
|
||||
This plugin might have some issues, in case of any of them, kindly create `new issue <https://github.com/arcan1s/ahriman/issues/new/choose>`_.
|
||||
|
||||
Generate mirrorlist package
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The application provides special plugin which generates mirrorlist package also. It is possible to distribute this package as usual later. The package can be generated in the following way:
|
||||
|
||||
#.
|
||||
Edit configuration:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[mirrorlist]
|
||||
target = mirrorlist_generator
|
||||
|
||||
[mirrorlist_generator]
|
||||
servers = https://repo.example.com/$arch
|
||||
|
||||
The ``mirrorlist_generator.servers`` must contain list of available mirrors, the ``$arch`` and ``$repo`` variables are supported. For more options kindly refer to :doc:`configuration <configuration>`.
|
||||
|
||||
#.
|
||||
Create package source files:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo -u ahriman ahriman repo-create-mirrorlist
|
||||
|
||||
This command will generate PKGBUILD and mirrorlist file and will register the package in database.
|
||||
|
||||
#.
|
||||
Build new package as usual:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo -u ahriman ahriman package-add aur-clone-mirrorlist --source local --now
|
||||
|
||||
where ``aur-clone`` is your repository name.
|
||||
|
||||
Web service
|
||||
-----------
|
||||
|
||||
@ -765,7 +838,7 @@ How to setup web service
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
yay -S python-aiohttp python-aiohttp-jinja2
|
||||
yay -S --asdeps python-aiohttp python-aiohttp-jinja2 python-aiohttp-apispec>=3.0.0 python-aiohttp-cors
|
||||
|
||||
#.
|
||||
Configure service:
|
||||
@ -786,15 +859,16 @@ How to enable basic authorization
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
yay -S python-aiohttp-security python-aiohttp-session python-cryptography
|
||||
yay -S --asdeps python-aiohttp-security python-aiohttp-session python-cryptography
|
||||
|
||||
#.
|
||||
Configure the service to enable authorization:
|
||||
Configure the service to enable authorization (``salt`` can be generated as any random string):
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[auth]
|
||||
target = configuration
|
||||
salt = somerandomstring
|
||||
|
||||
#.
|
||||
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):
|
||||
@ -842,7 +916,7 @@ How to enable OAuth authorization
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
yay -S python-aiohttp-security python-aiohttp-session python-cryptography python-aioauth-client
|
||||
yay -S --asdeps python-aiohttp-security python-aiohttp-session python-cryptography python-aioauth-client
|
||||
|
||||
#.
|
||||
Configure the service:
|
||||
@ -860,7 +934,7 @@ How to enable OAuth authorization
|
||||
Configure ``oauth_provider`` and ``oauth_scopes`` in case if you would like to use different from Google provider. Scope must grant access to user email. ``web.address`` is required to make callback URL available from internet.
|
||||
|
||||
#.
|
||||
Create service user:
|
||||
If you are not going to use unix socket, you also need to create service user (remember to set ``auth.salt`` option before):
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
@ -954,6 +1028,11 @@ Don't know, haven't tried it. But it lacks of documentation at least.
|
||||
* ``repoctl`` is able to store old packages.
|
||||
* Ability to host repository from same command in ``repoctl`` vs external services (e.g. nginx) in ``ahriman``.
|
||||
|
||||
`repod <https://gitlab.archlinux.org/archlinux/repod>`_
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
Official tool provided by distribution, has clean logic, but it is just a helper for ``repo-add``, e.g. it doesn't work with AUR and all packages builds have to be handled separately.
|
||||
|
||||
`repo-scripts <https://github.com/arcan1s/repo-scripts>`_
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
@ -975,13 +1054,17 @@ It is automation tools for ``repoctl`` mentioned above. Except for using shell i
|
||||
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).
|
||||
|
||||
You can also edit configuration and forward logs to ``stderr``, just change ``handlers`` value, e.g.:
|
||||
By default, the service writes logs to ``journald`` which can be accessed by using ``journalctl`` command (logs are written to the journal of the user under which command is run). In order to retrieve logs for the process you can use the following command:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sed -i 's/handlers = syslog_handler/handlers = console_handler/g' /etc/ahriman.ini.d/logging.ini
|
||||
sudo journalctl SYSLOG_IDENTIFIER=ahriman
|
||||
|
||||
You can also ask to forward logs to ``stderr``, just set ``--log-handler`` flag, e.g.:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ahriman --log-handler console ...
|
||||
|
||||
You can even configure logging as you wish, but kindly refer to python ``logging`` module `configuration <https://docs.python.org/3/library/logging.config.html>`_. The application uses java concept to log messages, e.g. class ``Application`` imported from ``ahriman.application.application`` package will have logger called ``ahriman.application.application.Application``. In order to e.g. change logger name for whole application package it is possible to change values for ``ahriman.application`` package; thus editing ``ahriman`` logger configuration will change logging for whole application (unless there are overrides for another logger).
|
||||
|
||||
|
@ -12,7 +12,7 @@ Features
|
||||
* VCS packages support.
|
||||
* Official repository support.
|
||||
* Ability to patch AUR packages and even create package from local PKGBUILDs.
|
||||
* Sign support with gpg (repository, package, per package settings).
|
||||
* Sign support with gpg (repository, package), multiple packagers support.
|
||||
* 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.
|
||||
|
||||
|
@ -32,11 +32,11 @@ Initial setup
|
||||
ln -s /usr/bin/archbuild /usr/local/bin/ahriman-x86_64-build
|
||||
|
||||
#.
|
||||
Create configuration file (same as previous ``pacman-{name}.conf``):
|
||||
Create configuration file (same as previous ``{name}.conf``):
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cp /usr/share/devtools/pacman-{extra,ahriman}.conf
|
||||
cp /usr/share/devtools/pacman.conf.d/{extra,ahriman}.conf
|
||||
|
||||
#.
|
||||
Change configuration file, add your own repository, add multilib repository etc:
|
||||
@ -44,11 +44,11 @@ Initial setup
|
||||
.. code-block:: shell
|
||||
|
||||
echo '[multilib]' | tee -a /usr/share/devtools/pacman-ahriman.conf
|
||||
echo 'Include = /etc/pacman.d/mirrorlist' | tee -a /usr/share/devtools/pacman-ahriman.conf
|
||||
echo 'Include = /etc/pacman.d/mirrorlist' | tee -a /usr/share/devtools/pacman.conf.d/ahriman.conf
|
||||
|
||||
echo '[aur-clone]' | tee -a /usr/share/devtools/pacman-ahriman.conf
|
||||
echo 'SigLevel = Optional TrustAll' | tee -a /usr/share/devtools/pacman-ahriman.conf
|
||||
echo 'Server = file:///var/lib/ahriman/repository/$arch' | tee -a /usr/share/devtools/pacman-ahriman.conf
|
||||
echo 'SigLevel = Optional TrustAll' | tee -a /usr/share/devtools/pacman.conf.d/ahriman.conf
|
||||
echo 'Server = file:///var/lib/ahriman/repository/$arch' | tee -a /usr/share/devtools/pacman.conf.d/ahriman.conf
|
||||
|
||||
#.
|
||||
Set ``build_command`` option to point to your command:
|
||||
@ -64,7 +64,7 @@ Initial setup
|
||||
.. code-block:: shell
|
||||
|
||||
echo 'Cmnd_Alias CARCHBUILD_CMD = /usr/local/bin/ahriman-x86_64-build *' | tee -a /etc/sudoers.d/ahriman
|
||||
echo 'ahriman ALL=(ALL) NOPASSWD: CARCHBUILD_CMD' | tee -a /etc/sudoers.d/ahriman
|
||||
echo 'ahriman ALL=(ALL) NOPASSWD:SETENV: CARCHBUILD_CMD' | tee -a /etc/sudoers.d/ahriman
|
||||
chmod 400 /etc/sudoers.d/ahriman
|
||||
|
||||
This command supports several arguments, kindly refer to its help message.
|
||||
|
@ -31,6 +31,16 @@ This trigger will be called right after build process (``on_result``). It will p
|
||||
|
||||
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.support.KeyringTrigger``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Generator for keyring package. This trigger will extract keys from local keychain and pack them into keyring specific format. This trigger will generate sources including PKGBUILD, which can be used later for package building.
|
||||
|
||||
``ahriman.core.support.MirrorlistTrigger``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Simple generator for mirrorlist package, based on the urls which were set by configuration. This trigger will generate sources including PKGBUILD, which can be used later for package building.
|
||||
|
||||
``ahriman.core.upload.UploadTrigger``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@ -73,7 +83,7 @@ The ``context`` also implements collection methods such as ``__iter__`` and ``__
|
||||
Trigger example
|
||||
---------------
|
||||
|
||||
Lets consider example of reporting trigger (e.g. `slack <https://slack.com/>`_, which provides easy HTTP API for integration triggers).gre
|
||||
Lets consider example of reporting trigger (e.g. `slack <https://slack.com/>`_, which provides easy HTTP API for integration triggers).
|
||||
|
||||
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``).
|
||||
|
||||
|
BIN
github-logo.png
Normal file
BIN
github-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
@ -1,13 +1,13 @@
|
||||
# Maintainer: Evgeniy Alekseev
|
||||
|
||||
pkgname='ahriman'
|
||||
pkgver=2.8.0
|
||||
pkgver=2.10.2
|
||||
pkgrel=1
|
||||
pkgdesc="ArcH linux ReposItory MANager"
|
||||
arch=('any')
|
||||
url="https://github.com/arcan1s/ahriman"
|
||||
license=('GPL3')
|
||||
depends=('devtools' 'git' 'pyalpm' 'python-cerberus' 'python-inflection' 'python-passlib' 'python-requests' 'python-srcinfo')
|
||||
depends=('devtools>=1:1.0.0' 'git' 'pyalpm' 'python-cerberus' 'python-inflection' 'python-passlib' 'python-requests' 'python-srcinfo')
|
||||
makedepends=('python-build' 'python-installer' 'python-wheel')
|
||||
optdepends=('breezy: -bzr packages support'
|
||||
'darcs: -darcs packages support'
|
||||
@ -24,11 +24,13 @@ optdepends=('breezy: -bzr packages support'
|
||||
'python-cryptography: web server with authorization'
|
||||
'python-requests-unixsocket: client report to web server by unix socket'
|
||||
'python-jinja: html report generation'
|
||||
'python-systemd: journal support'
|
||||
'rsync: sync by using rsync'
|
||||
'subversion: -svn packages support')
|
||||
source=("https://github.com/arcan1s/ahriman/releases/download/$pkgver/$pkgname-$pkgver-src.tar.xz"
|
||||
'ahriman.sysusers'
|
||||
'ahriman.tmpfiles')
|
||||
install="$pkgname.install"
|
||||
backup=('etc/ahriman.ini'
|
||||
'etc/ahriman.ini.d/logging.ini')
|
||||
|
||||
@ -52,6 +54,6 @@ package() {
|
||||
install -Dm644 "$srcdir/$pkgname.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/$pkgname.conf"
|
||||
}
|
||||
|
||||
sha512sums=('112b0d8aac68e5330bbdd2b86a59c8a9af8ab7a7c636489623c8460bb90f1318585851edd2a97a8ce20e2d2ad93b847b522685df707c190aa39d23ab908fa8ef'
|
||||
sha512sums=('19841842641520b573cdde6cb80a7cfcd69756d323fdfeebc2eee2d264a1325ead4ab2f8383bb369f7896bfc1de59d7358f133f4afeb90a9b9f0695f482a58d0'
|
||||
'53d37efec812afebf86281716259f9ea78a307b83897166c72777251c3eebcb587ecee375d907514781fb2a5c808cbb24ef9f3f244f12740155d0603bf213131'
|
||||
'62b2eccc352d33853ef243c9cddd63663014aa97b87242f1b5bc5099a7dbd69ff3821f24ffc58e1b7f2387bd4e9e9712cc4c67f661b1724ad99cdf09b3717794')
|
||||
|
25
package/archlinux/ahriman.install
Normal file
25
package/archlinux/ahriman.install
Normal file
@ -0,0 +1,25 @@
|
||||
post_upgrade() {
|
||||
local breakpoints=(
|
||||
2.9.0-1
|
||||
)
|
||||
|
||||
for v in "${breakpoints[@]}"; do
|
||||
if [[ $(vercmp "$v" "$2") -eq 1 ]]; then
|
||||
"_${v//[.-]/_}_changes"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
_2_9_0_1_changes() {
|
||||
cat << EOF
|
||||
It was found that you were upgrading from old-devtools package to the new one, which requires manual intervention:
|
||||
|
||||
* make sure that devtools are upgraded to the latest release;
|
||||
* merge service configuration if required;
|
||||
* run setup command (i.e. sudo ahriman service-setup) with the same arguments as you did before;
|
||||
* remove build chroot: sudo rm -r /var/lib/ahriman/chroot/ahriman-x86_64/;
|
||||
* update local databases: sudo -u ahriman ahriman update --no-aur --no-local --no-manual -yy;
|
||||
|
||||
For more information kindly refer to changelog https://github.com/arcan1s/ahriman/releases/tag/2.9.0
|
||||
EOF
|
||||
}
|
@ -1 +1 @@
|
||||
u ahriman 643 "ArcH linux ReposItory MANager" /var/lib/ahriman
|
||||
u ahriman 643 "ArcH linux ReposItory MANager" /var/lib/ahriman
|
||||
|
@ -1,2 +1 @@
|
||||
d /var/lib/ahriman 0755 ahriman ahriman
|
||||
d /var/log/ahriman 0755 ahriman ahriman
|
||||
d /var/lib/ahriman 0755 ahriman ahriman
|
@ -7,7 +7,7 @@ suppress_http_log_errors = yes
|
||||
[alpm]
|
||||
database = /var/lib/pacman
|
||||
mirror = https://geo.mirror.pkgbuild.com/$repo/os/$arch
|
||||
repositories = core extra community multilib
|
||||
repositories = core extra multilib
|
||||
root = /
|
||||
use_ahriman_cache = yes
|
||||
|
||||
@ -25,6 +25,7 @@ ignore_packages =
|
||||
makechrootpkg_flags =
|
||||
makepkg_flags = --nocolor --ignorearch
|
||||
triggers = ahriman.core.gitremote.RemotePullTrigger ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger ahriman.core.gitremote.RemotePushTrigger
|
||||
triggers_known = ahriman.core.gitremote.RemotePullTrigger ahriman.core.gitremote.RemotePushTrigger ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger ahriman.core.support.KeyringTrigger ahriman.core.support.MirrorlistTrigger
|
||||
vcs_allowed_age = 604800
|
||||
|
||||
[repository]
|
||||
@ -34,6 +35,12 @@ root = /var/lib/ahriman
|
||||
[sign]
|
||||
target =
|
||||
|
||||
[keyring]
|
||||
target =
|
||||
|
||||
[mirrorlist]
|
||||
target =
|
||||
|
||||
[remote-pull]
|
||||
target =
|
||||
|
||||
|
@ -2,17 +2,23 @@
|
||||
keys = root,http,stderr,boto3,botocore,nose,s3transfer
|
||||
|
||||
[handlers]
|
||||
keys = console_handler,syslog_handler
|
||||
keys = console_handler,journald_handler,syslog_handler
|
||||
|
||||
[formatters]
|
||||
keys = generic_format,syslog_format
|
||||
|
||||
[handler_console_handler]
|
||||
class = StreamHandler
|
||||
class = logging.StreamHandler
|
||||
level = DEBUG
|
||||
formatter = generic_format
|
||||
args = (sys.stderr,)
|
||||
|
||||
[handler_journald_handler]
|
||||
class = ahriman.core.log.journal_handler.JournalHandler
|
||||
level = DEBUG
|
||||
formatter = syslog_format
|
||||
kwargs = {"SYSLOG_IDENTIFIER": "ahriman"}
|
||||
|
||||
[handler_syslog_handler]
|
||||
class = logging.handlers.SysLogHandler
|
||||
level = DEBUG
|
||||
@ -21,20 +27,16 @@ args = ("/dev/log",)
|
||||
|
||||
[formatter_generic_format]
|
||||
format = [%(levelname)s %(asctime)s] [%(name)s]: %(message)s
|
||||
datefmt =
|
||||
|
||||
[formatter_syslog_format]
|
||||
format = [%(levelname)s] [%(name)s]: %(message)s
|
||||
datefmt =
|
||||
|
||||
[logger_root]
|
||||
level = DEBUG
|
||||
handlers = syslog_handler
|
||||
qualname = root
|
||||
|
||||
[logger_http]
|
||||
level = DEBUG
|
||||
handlers = syslog_handler
|
||||
qualname = http
|
||||
propagate = 0
|
||||
|
||||
@ -45,24 +47,20 @@ qualname = stderr
|
||||
|
||||
[logger_boto3]
|
||||
level = INFO
|
||||
handlers = syslog_handler
|
||||
qualname = boto3
|
||||
propagate = 0
|
||||
|
||||
[logger_botocore]
|
||||
level = INFO
|
||||
handlers = syslog_handler
|
||||
qualname = botocore
|
||||
propagate = 0
|
||||
|
||||
[logger_nose]
|
||||
level = INFO
|
||||
handlers = syslog_handler
|
||||
qualname = nose
|
||||
propagate = 0
|
||||
|
||||
[logger_s3transfer]
|
||||
level = INFO
|
||||
handlers = syslog_handler
|
||||
qualname = s3transfer
|
||||
propagate = 0
|
||||
|
@ -63,6 +63,8 @@
|
||||
|
||||
<table id="packages" class="table table-striped table-hover"
|
||||
data-export-options='{"fileName": "packages"}'
|
||||
data-filter-control="true"
|
||||
data-filter-control-visible="false"
|
||||
data-page-list="[10, 25, 50, 100, all]"
|
||||
data-page-size="10"
|
||||
data-pagination="true"
|
||||
@ -72,6 +74,7 @@
|
||||
data-show-columns-search="true"
|
||||
data-show-columns-toggle-all="true"
|
||||
data-show-export="true"
|
||||
data-show-filter-control-switch="true"
|
||||
data-show-fullscreen="true"
|
||||
data-show-search-clear-button="true"
|
||||
data-sortable="true"
|
||||
@ -82,13 +85,14 @@
|
||||
<thead class="table-primary">
|
||||
<tr>
|
||||
<th data-checkbox="true"></th>
|
||||
<th data-sortable="true" data-switchable="false" data-field="base">package base</th>
|
||||
<th data-sortable="true" data-field="version">version</th>
|
||||
<th data-sortable="true" data-field="packages">packages</th>
|
||||
<th data-sortable="true" data-visible="false" data-field="groups">groups</th>
|
||||
<th data-sortable="true" data-visible="false" data-field="licenses">licenses</th>
|
||||
<th data-sortable="true" data-field="timestamp">last update</th>
|
||||
<th data-sortable="true" data-cell-style="statusFormat" data-field="status">status</th>
|
||||
<th data-sortable="true" data-switchable="false" data-field="base" data-filter-control="input" data-filter-control-placeholder="(any base)">package base</th>
|
||||
<th data-sortable="true" data-field="version" data-filter-control="input" data-filter-control-placeholder="(any version)">version</th>
|
||||
<th data-sortable="true" data-field="packages" data-filter-control="input" data-filter-control-placeholder="(any package)">packages</th>
|
||||
<th data-sortable="true" data-visible="false" data-field="groups" data-filter-control="select" data-filter-data="func:filterListGroups" data-filter-custom-search="filterList" data-filter-control-placeholder="(any group)">groups</th>
|
||||
<th data-sortable="true" data-visible="false" data-field="licenses" data-filter-control="select" data-filter-data="func:filterListLicenses" data-filter-custom-search="filterList" data-filter-control-placeholder="(any license)">licenses</th>
|
||||
<th data-sortable="true" data-visible="false" data-field="packager" data-filter-control="select" data-filter-custom-search="filterContains" data-filter-control-placeholder="(any packager)">packager</th>
|
||||
<th data-sortable="true" data-field="timestamp" data-filter-control="input" data-filter-custom-search="filterDateRange" data-filter-control-placeholder="(any date)">last update</th>
|
||||
<th data-sortable="true" data-cell-style="statusFormat" data-field="status" data-filter-control="select" data-filter-control-placeholder="(any status)">status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
@ -84,7 +84,7 @@
|
||||
showSuccess("Success", `Key ${key} has been imported`);
|
||||
},
|
||||
error: (jqXHR, _, errorThrown) => {
|
||||
const message = _ => { return `Could not import key ${key} from ${server}`; };
|
||||
const message = _ => `Could not import key ${key} from ${server}`;
|
||||
showFailure("Action failed", message, jqXHR, errorThrown);
|
||||
},
|
||||
});
|
||||
|
@ -60,8 +60,8 @@
|
||||
const packages = packageInput.val();
|
||||
if (packages) {
|
||||
packageAddModal.modal("hide");
|
||||
const onSuccess = update => { return `Packages ${update} have been added`; };
|
||||
const onFailure = error => { return `Package addition failed: ${error}`; };
|
||||
const onSuccess = update => `Packages ${update} have been added`;
|
||||
const onFailure = error => `Package addition failed: ${error}`;
|
||||
doPackageAction("/api/v1/service/add", [packages], onSuccess, onFailure);
|
||||
}
|
||||
}
|
||||
@ -70,8 +70,8 @@
|
||||
const packages = packageInput.val();
|
||||
if (packages) {
|
||||
packageAddModal.modal("hide");
|
||||
const onSuccess = update => { return `Packages ${update} have been requested`; };
|
||||
const onFailure = error => { return `Package request failed: ${error}`; };
|
||||
const onSuccess = update => `Packages ${update} have been requested`;
|
||||
const onFailure = error => `Package request failed: ${error}`;
|
||||
doPackageAction("/api/v1/service/request", [packages], onSuccess, onFailure);
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@
|
||||
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}`; };
|
||||
const message = error => `Could not load package ${packageBase} logs: ${error}`;
|
||||
showFailure("Load failure", message, jqXHR, errorThrown);
|
||||
}
|
||||
},
|
||||
|
@ -33,8 +33,8 @@
|
||||
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}`; };
|
||||
const onSuccess = update => `Repository rebuild has been run for packages which depend on ${update}`;
|
||||
const onFailure = error => `Repository rebuild failed: ${error}`;
|
||||
doPackageAction("/api/v1/service/rebuild", [packages], onSuccess, onFailure);
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,25 @@
|
||||
table.bootstrapTable(method, {field: "id", values: [data.id]});
|
||||
} else showLogs(data.id);
|
||||
});
|
||||
table.on("created-controls.bs.table", () => {
|
||||
const pickerInput = $(".bootstrap-table-filter-control-timestamp");
|
||||
pickerInput.daterangepicker({
|
||||
autoUpdateInput: false,
|
||||
locale: {
|
||||
cancelLabel: "Clear",
|
||||
},
|
||||
});
|
||||
|
||||
pickerInput.on("apply.daterangepicker", (event, picker) => {
|
||||
pickerInput.val(`${picker.startDate.format("YYYY-MM-DD")} - ${picker.endDate.format("YYYY-MM-DD")}`);
|
||||
table.bootstrapTable("triggerSearch");
|
||||
});
|
||||
|
||||
pickerInput.on("cancel.daterangepicker", () => {
|
||||
pickerInput.val("");
|
||||
table.bootstrapTable("triggerSearch");
|
||||
});
|
||||
});
|
||||
|
||||
const repositoryBadge = $("#badge-repository");
|
||||
const statusBadge = $("#badge-status");
|
||||
@ -37,21 +56,21 @@
|
||||
}
|
||||
|
||||
function getSelection() {
|
||||
return table.bootstrapTable("getSelections").map(row => { return row.id; });
|
||||
return table.bootstrapTable("getSelections").map(row => row.id);
|
||||
}
|
||||
|
||||
function removePackages() {
|
||||
const onSuccess = update => { return `Packages ${update} have been removed`; };
|
||||
const onFailure = error => { return `Could not remove packages: ${error}`; };
|
||||
const onSuccess = update => `Packages ${update} have been removed`;
|
||||
const onFailure = error => `Could not remove packages: ${error}`;
|
||||
doPackageAction("/api/v1/service/remove", getSelection(), onSuccess, onFailure);
|
||||
}
|
||||
|
||||
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}`; };
|
||||
? ["/api/v1/service/update", _ => "Repository update has been run"]
|
||||
: ["/api/v1/service/add", update => `Run update for packages ${update}`];
|
||||
const onFailure = error => `Packages update failed: ${error}`;
|
||||
doPackageAction(url, currentSelection, onSuccess, onFailure);
|
||||
}
|
||||
|
||||
@ -81,13 +100,13 @@
|
||||
success: response => {
|
||||
const extractListProperties = (description, property) => {
|
||||
return Object.values(description.packages)
|
||||
.map(pkg => { return pkg[property]; })
|
||||
.reduce((left, right) => { return left.concat(right); }, []);
|
||||
.map(pkg => pkg[property])
|
||||
.reduce((left, right) => left.concat(right), []);
|
||||
};
|
||||
const listToTable = data => {
|
||||
return Array.from(new Set(data))
|
||||
.sort()
|
||||
.map(entry => { return safe(entry); })
|
||||
.map(entry => safe(entry))
|
||||
.join("<br>");
|
||||
};
|
||||
|
||||
@ -98,6 +117,7 @@
|
||||
id: package_base,
|
||||
base: web_url ? `<a href="${safe(web_url)}" title="${safe(package_base)}">${safe(package_base)}</a>` : safe(package_base),
|
||||
version: safe(description.package.version),
|
||||
packager: description.package.packager ? safe(description.package.packager) : "",
|
||||
packages: listToTable(Object.keys(description.package.packages)),
|
||||
groups: listToTable(extractListProperties(description.package, "groups")),
|
||||
licenses: listToTable(extractListProperties(description.package, "licenses")),
|
||||
@ -120,8 +140,8 @@
|
||||
table.bootstrapTable("hideLoading");
|
||||
} else {
|
||||
// other errors
|
||||
const messaga = error => { return `Could not load list of packages: ${error}`; };
|
||||
showFailure("Load failure", messaga, jqXHR, errorThrown);
|
||||
const message = error => `Could not load list of packages: ${error}`;
|
||||
showFailure("Load failure", message, jqXHR, errorThrown);
|
||||
}
|
||||
hideControls(true);
|
||||
},
|
||||
@ -157,6 +177,18 @@
|
||||
return {classes: cellClass(value)};
|
||||
}
|
||||
|
||||
function filterListGroups() {
|
||||
return extractDataList(table.bootstrapTable("getData"), "groups");
|
||||
}
|
||||
|
||||
function filterListLicenses() {
|
||||
return extractDataList(table.bootstrapTable("getData"), "licenses");
|
||||
}
|
||||
|
||||
function filterListPackagers() {
|
||||
return extractDataList(table.bootstrapTable("getData"), "packager");
|
||||
}
|
||||
|
||||
$(() => {
|
||||
table.bootstrapTable({});
|
||||
statusBadge.popover();
|
||||
|
@ -31,6 +31,8 @@ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Pa
|
||||
<div class="container">
|
||||
<table id="packages" class="table table-striped table-hover"
|
||||
data-export-options='{"fileName": "packages"}'
|
||||
data-filter-control="true"
|
||||
data-filter-control-visible="false"
|
||||
data-page-list="[10, 25, 50, 100, all]"
|
||||
data-page-size="10"
|
||||
data-pagination="true"
|
||||
@ -40,6 +42,7 @@ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Pa
|
||||
data-show-columns-search="true"
|
||||
data-show-columns-toggle-all="true"
|
||||
data-show-export="true"
|
||||
data-show-filter-control-switch="true"
|
||||
data-show-fullscreen="true"
|
||||
data-show-search-clear-button="true"
|
||||
data-sortable="true"
|
||||
@ -48,17 +51,17 @@ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Pa
|
||||
data-toggle="table">
|
||||
<thead class="table-primary">
|
||||
<tr>
|
||||
<th data-sortable="true" data-switchable="false">package</th>
|
||||
<th data-sortable="true">version</th>
|
||||
<th data-sortable="true" data-visible="false">architecture</th>
|
||||
<th data-sortable="true" data-visible="false">description</th>
|
||||
<th data-sortable="true" data-visible="false">upstream url</th>
|
||||
<th data-sortable="true" data-visible="false">licenses</th>
|
||||
<th data-sortable="true" data-visible="false">groups</th>
|
||||
<th data-sortable="true" data-visible="false">depends</th>
|
||||
<th data-sortable="true">archive size</th>
|
||||
<th data-sortable="true">installed size</th>
|
||||
<th data-sortable="true">build date</th>
|
||||
<th data-sortable="true" data-switchable="false" data-field="name" data-filter-control="input" data-filter-control-placeholder="(any package)">package</th>
|
||||
<th data-sortable="true" data-field="version" data-filter-control="input" data-filter-control-placeholder="(any version)">version</th>
|
||||
<th data-sortable="true" data-visible="false" data-field="architecture" data-filter-control="select" data-filter-control-placeholder="(any arch)">architecture</th>
|
||||
<th data-sortable="true" data-visible="false" data-field="description" data-filter-control="input" data-filter-control-placeholder="(any description)">description</th>
|
||||
<th data-sortable="true" data-visible="false" data-field="url">upstream url</th>
|
||||
<th data-sortable="true" data-visible="false" data-field="licenses" data-filter-control="select" data-filter-data="func:filterListLicenses" data-filter-custom-search="filterList" data-filter-control-placeholder="(any license)">licenses</th>
|
||||
<th data-sortable="true" data-visible="false" data-field="groups" data-filter-control="select" data-filter-data="func:filterListGroups" data-filter-custom-search="filterList" data-filter-control-placeholder="(any group)">groups</th>
|
||||
<th data-sortable="true" data-visible="false" data-field="depends" data-filter-control="select" data-filter-data="func:filterListDepends" data-filter-custom-search="filterList" data-filter-control-placeholder="(any depends)">depends</th>
|
||||
<th data-sortable="true" data-field="archive_size">archive size</th>
|
||||
<th data-sortable="true" data-field="installed_size">installed size</th>
|
||||
<th data-sortable="true" data-field="timestamp" data-filter-control="input" data-filter-custom-search="filterDateRange" data-filter-control-placeholder="(any date)">build date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@ -96,6 +99,27 @@ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Pa
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const table = $("#packages");
|
||||
table.on("created-controls.bs.table", () => {
|
||||
const pickerInput = $(".bootstrap-table-filter-control-timestamp");
|
||||
pickerInput.daterangepicker({
|
||||
autoUpdateInput: false,
|
||||
locale: {
|
||||
cancelLabel: "Clear",
|
||||
},
|
||||
});
|
||||
|
||||
pickerInput.on("apply.daterangepicker", (event, picker) => {
|
||||
pickerInput.val(`${picker.startDate.format("YYYY-MM-DD")} - ${picker.endDate.format("YYYY-MM-DD")}`);
|
||||
table.bootstrapTable("triggerSearch");
|
||||
});
|
||||
|
||||
pickerInput.on("cancel.daterangepicker", () => {
|
||||
pickerInput.val("");
|
||||
table.bootstrapTable("triggerSearch");
|
||||
});
|
||||
});
|
||||
|
||||
const pacmanConf = $("#pacman-conf");
|
||||
const pacmanConfCopyButton = $("#copy-btn");
|
||||
|
||||
@ -103,6 +127,18 @@ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Pa
|
||||
const conf = pacmanConf.text();
|
||||
await copyToClipboard(conf, pacmanConfCopyButton);
|
||||
}
|
||||
|
||||
function filterListDepends() {
|
||||
return extractDataList(table.bootstrapTable("getData"), "depends");
|
||||
}
|
||||
|
||||
function filterListGroups() {
|
||||
return extractDataList(table.bootstrapTable("getData"), "groups");
|
||||
}
|
||||
|
||||
function filterListLicenses() {
|
||||
return extractDataList(table.bootstrapTable("getData"), "licenses");
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
@ -1,16 +1,21 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.min.js" integrity="sha384-NXgwF8Kv9SSAr+jemKKcbvQsz+teULH/a5UNJvZc6kP47hZgl62M1vGnw6gHQhb1" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://unpkg.com/tableexport.jquery.plugin/tableExport.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.4/moment.min.js" integrity="sha384-8hHkOkbWN1TLWwet/jpbJ0zbx3FJDeYJgQ8dX1mRrv/vfCfHCqFSFZYCgaMML3z9" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/daterangepicker@3.1.0/daterangepicker.min.js" integrity="sha384-u4eJN1VWrTf/FnYYQJo2kqJyVxEQf5UmWY4iUcNAoLenOEtEuCkfwc5bKvZOWBi5" crossorigin="anonymous" type="application/javascript"></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/tableexport.jquery.plugin@1.28.0/tableExport.min.js" integrity="sha384-1Rz4Kz/y1rSWw+ZsjTcxB684XgofbO8iizY+UFIzCwFeQ+QUyhBNWBMh/STOyomI" crossorigin="anonymous" type="application/javascript"></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://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://cdn.jsdelivr.net/npm/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.min.js" integrity="sha384-IazMVNyYoUNx6357fWJoqtHYUWWCNHIXxFVtbpVgvImQNWuRP2WbHPaIb3QF8j97" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://unpkg.com/bootstrap-table@1.21.1/dist/extensions/export/bootstrap-table-export.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js" integrity="sha384-cuYeSxntonz0PPNlHhBs68uyIAVpIIOZZ5JqeqvYYIcEL727kskC66kF92t6Xl2V" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/bootstrap-table.min.js" integrity="sha384-GVLHfbEvuGA/RFiQ3MK2ClEJkWYJXABg55t9LpoDPZFGIsSq8xhFlQydm5poV2jW" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://unpkg.com/bootstrap-table@1.21.1/dist/extensions/resizable/bootstrap-table-resizable.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.21.4/dist/extensions/export/bootstrap-table-export.min.js" integrity="sha384-jeldDadm+qM2RwGER3qVqxFgWVpAEJ7Jie+0rlYj8ni3KkQA654T8TSXDtol022X" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.21.4/dist/extensions/resizable/bootstrap-table-resizable.js" integrity="sha384-wd8Vc6Febikdnsnk9vthRWRvMwffw246vhqiqNO3aSNe1maTEA07Vh3zAQiSyDji" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.21.4/dist/extensions/filter-control/bootstrap-table-filter-control.js" integrity="sha384-B6xNXlSOaOFxjlKo9OW3htbox+9/DcaEcjPPEi1+pTMwH5Tzc/s2wNTYriHz7Tb8" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script>
|
||||
async function copyToClipboard(text, button) {
|
||||
@ -38,4 +43,28 @@
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """);
|
||||
}
|
||||
|
||||
function extractDataList(data, column) {
|
||||
const elements = data.flatMap(row => row[column].split("<br>")).filter(v => v); // remove empty elements from array
|
||||
return Array.from(new Set(elements)).sort();
|
||||
}
|
||||
|
||||
function filterContains(text, value) {
|
||||
return value.includes(text.toLowerCase().trim());
|
||||
}
|
||||
|
||||
function filterDateRange(text, value) {
|
||||
const asOfStartOfDay = date => date.setUTCHours(0, 0, 0, 0);
|
||||
|
||||
const [minDate, maxDate] = text.split(" - ");
|
||||
const buildDate = asOfStartOfDay(new Date(value));
|
||||
|
||||
return (buildDate >= asOfStartOfDay(new Date(minDate))) && (buildDate <= asOfStartOfDay(new Date(maxDate)));
|
||||
}
|
||||
|
||||
function filterList(index, value, field, data) {
|
||||
const dataList = extractDataList(data, field);
|
||||
// the library removes all symbols from string, so it is just string
|
||||
return value.includes(dataList[index].toLowerCase());
|
||||
}
|
||||
</script>
|
||||
|
@ -1,11 +1,15 @@
|
||||
<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.10.2/font/bootstrap-icons.css" type="text/css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous" type="text/css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.4/font/bootstrap-icons.css" integrity="sha384-LrVLJJYk9OiJmjNDakUBU7kS9qCT8wk1j2OU7ncpsfB3QS37UPdkCuq3ZD1MugNY" crossorigin="anonymous" type="text/css">
|
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/bootstrap-table@1.21.1/dist/bootstrap-table.min.css" type="text/css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-table@1.21.4/dist/bootstrap-table.min.css" integrity="sha384-pTEAhytv7JmEG2D7qiW5gY0lI5EKZ9n3CNmj6Qp+U3qhnmH2qnnN9KJbVwbtMHN0" crossorigin="anonymous" type="text/css">
|
||||
|
||||
<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/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.css" integrity="sha384-1sLxvR8mXzjhvFY9f8mzXl97DNLepeZ0PnRiMMdm/rQsKjsrPZPJxYle2wwT2PMg" crossorigin="anonymous" 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">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-table@1.21.4/dist/extensions/filter-control/bootstrap-table-filter-control.css" integrity="sha384-4Glx18jZ0Un+yDG6KUpYJ/af8hkssJ02jRASuFv23gfCl0mTXaVMPI9cB4cn3GvE" crossorigin="anonymous" type="text/css">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootswatch@5.2.3/dist/cosmo/bootstrap.min.css" integrity="sha384-P1PBFVifKf1Ww0gS5B8A0siIeDpcFd4uU7S68LA1XMdE0R+y1WN3DR4HcLc9csRC" crossorigin="anonymous" type="text/css">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/daterangepicker@3.1.0/daterangepicker.css" integrity="sha384-zLkQsiLfAQqGeIJeKLC+rcCR1YoYaQFLCL7cLDUoKE1ajKJzySpjzWGfYS2vjSG+" crossorigin="anonymous" type="text/css">
|
||||
|
||||
<style>
|
||||
.pre-scrollable {
|
||||
|
4
setup.py
4
setup.py
@ -119,7 +119,9 @@ setup(
|
||||
"shtab",
|
||||
"sphinx-argparse",
|
||||
"sphinx-rtd-theme>=1.1.1", # https://stackoverflow.com/a/74355734
|
||||
"sphinxcontrib-napoleon",
|
||||
],
|
||||
"journald": [
|
||||
"systemd-python",
|
||||
],
|
||||
# FIXME technically this dependency is required, but in some cases we do not have access to
|
||||
# the libalpm which is required in order to install the package. Thus in case if we do not
|
||||
|
@ -27,9 +27,10 @@ from typing import TypeVar
|
||||
|
||||
from ahriman import version
|
||||
from ahriman.application import handlers
|
||||
from ahriman.core.util import enum_values
|
||||
from ahriman.core.util import enum_values, extract_user
|
||||
from ahriman.models.action import Action
|
||||
from ahriman.models.build_status import BuildStatusEnum
|
||||
from ahriman.models.log_handler import LogHandler
|
||||
from ahriman.models.package_source import PackageSource
|
||||
from ahriman.models.sign_settings import SignSettings
|
||||
from ahriman.models.user_access import UserAccess
|
||||
@ -58,6 +59,7 @@ def _formatter(prog: str) -> argparse.HelpFormatter:
|
||||
return argparse.ArgumentDefaultsHelpFormatter(prog, width=120)
|
||||
|
||||
|
||||
# pylint: disable=too-many-statements
|
||||
def _parser() -> argparse.ArgumentParser:
|
||||
"""
|
||||
command line parser generator
|
||||
@ -70,10 +72,14 @@ def _parser() -> argparse.ArgumentParser:
|
||||
fromfile_prefix_chars="@", formatter_class=_formatter)
|
||||
parser.add_argument("-a", "--architecture", help="target architectures. For several subcommands it can be used "
|
||||
"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("-l", "--lock", help="lock file", type=Path,
|
||||
default=Path(tempfile.gettempdir()) / "ahriman.lock")
|
||||
parser.add_argument("--log-handler", help="explicit log handler specification. If none set, the handler will be "
|
||||
"guessed from environment",
|
||||
type=LogHandler, choices=enum_values(LogHandler))
|
||||
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")
|
||||
@ -99,6 +105,8 @@ def _parser() -> argparse.ArgumentParser:
|
||||
_set_patch_set_add_parser(subparsers)
|
||||
_set_repo_backup_parser(subparsers)
|
||||
_set_repo_check_parser(subparsers)
|
||||
_set_repo_create_keyring_parser(subparsers)
|
||||
_set_repo_create_mirrorlist_parser(subparsers)
|
||||
_set_repo_daemon_parser(subparsers)
|
||||
_set_repo_rebuild_parser(subparsers)
|
||||
_set_repo_remove_unknown_parser(subparsers)
|
||||
@ -179,8 +187,8 @@ def _set_help_commands_unsafe_parser(root: SubParserAction) -> argparse.Argument
|
||||
"""
|
||||
parser = root.add_parser("help-commands-unsafe", help="list unsafe commands",
|
||||
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 "
|
||||
"and return 0 in case if command is safe and 1 otherwise")
|
||||
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", nargs="*")
|
||||
parser.set_defaults(handler=handlers.UnsafeCommands, architecture=[""], lock=None, report=False, quiet=True,
|
||||
unsafe=True, parser=_parser)
|
||||
return parser
|
||||
@ -254,6 +262,7 @@ def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
action="count", default=False)
|
||||
parser.add_argument("-s", "--source", help="explicitly specify the package source for this command",
|
||||
type=PackageSource, choices=enum_values(PackageSource), default=PackageSource.Auto)
|
||||
parser.add_argument("-u", "--username", help="build as user", default=extract_user())
|
||||
parser.set_defaults(handler=handlers.Add)
|
||||
return parser
|
||||
|
||||
@ -473,7 +482,46 @@ def _set_repo_check_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
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, dependencies=False, dry_run=True, aur=True, local=True, manual=False)
|
||||
parser.set_defaults(handler=handlers.Update, dependencies=False, dry_run=True, aur=True, local=True, manual=False,
|
||||
username=None)
|
||||
return parser
|
||||
|
||||
|
||||
def _set_repo_create_keyring_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
"""
|
||||
add parser for create-keyring subcommand
|
||||
|
||||
Args:
|
||||
root(SubParserAction): subparsers for the commands
|
||||
|
||||
Returns:
|
||||
argparse.ArgumentParser: created argument parser
|
||||
"""
|
||||
parser = root.add_parser("repo-create-keyring", help="create keyring package",
|
||||
description="create package which contains list of trusted keys as set by "
|
||||
"configuration. Note, that this action will only create package, the package "
|
||||
"itself has to be built manually",
|
||||
formatter_class=_formatter)
|
||||
parser.set_defaults(handler=handlers.Triggers, trigger=["ahriman.core.support.KeyringTrigger"])
|
||||
return parser
|
||||
|
||||
|
||||
def _set_repo_create_mirrorlist_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
"""
|
||||
add parser for create-mirrorlist subcommand
|
||||
|
||||
Args:
|
||||
root(SubParserAction): subparsers for the commands
|
||||
|
||||
Returns:
|
||||
argparse.ArgumentParser: created argument parser
|
||||
"""
|
||||
parser = root.add_parser("repo-create-mirrorlist", help="create mirrorlist package",
|
||||
description="create package which contains list of available mirrors as set by "
|
||||
"configuration. Note, that this action will only create package, the package "
|
||||
"itself has to be built manually",
|
||||
formatter_class=_formatter)
|
||||
parser.set_defaults(handler=handlers.Triggers, trigger=["ahriman.core.support.MirrorlistTrigger"])
|
||||
return parser
|
||||
|
||||
|
||||
@ -530,6 +578,9 @@ def _set_repo_rebuild_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
"ahriman instance run with web service and have run repo-update at least once.",
|
||||
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("-s", "--status", help="filter packages by status. Requires --from-database to be set",
|
||||
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum))
|
||||
parser.add_argument("-u", "--username", help="build as user", default=extract_user())
|
||||
parser.set_defaults(handler=handlers.Rebuild)
|
||||
return parser
|
||||
|
||||
@ -704,6 +755,7 @@ def _set_repo_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
action=argparse.BooleanOptionalAction, default=True)
|
||||
parser.add_argument("--manual", help="include or exclude manual updates",
|
||||
action=argparse.BooleanOptionalAction, default=True)
|
||||
parser.add_argument("-u", "--username", help="build as user", default=extract_user())
|
||||
parser.add_argument("--vcs", help="fetch actual version of VCS packages",
|
||||
action=argparse.BooleanOptionalAction, default=True)
|
||||
parser.add_argument("-y", "--refresh", help="download fresh package databases from the mirror before actions, "
|
||||
@ -822,7 +874,9 @@ def _set_service_setup_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
parser.add_argument("--build-as-user", help="force makepkg user to the specific one")
|
||||
parser.add_argument("--build-command", help="build command prefix", default="ahriman")
|
||||
parser.add_argument("--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.conf.d" / "extra.conf")
|
||||
parser.add_argument("--generate-salt", help="generate salt for user passwords",
|
||||
action=argparse.BooleanOptionalAction, default=False)
|
||||
parser.add_argument("--makeflags-jobs", help="append MAKEFLAGS variable with parallelism set to number of cores",
|
||||
action=argparse.BooleanOptionalAction, default=True)
|
||||
parser.add_argument("--mirror", help="use the specified explicitly mirror instead of including mirrorlist")
|
||||
@ -850,8 +904,7 @@ def _set_service_shell_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
argparse.ArgumentParser: created argument parser
|
||||
"""
|
||||
parser = root.add_parser("service-shell", aliases=["shell"], help="invoke python shell",
|
||||
description="drop into python shell while having created application",
|
||||
formatter_class=_formatter)
|
||||
description="drop into python shell", 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.set_defaults(handler=handlers.Shell, lock=None, report=False)
|
||||
@ -871,15 +924,15 @@ def _set_user_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
parser = root.add_parser("user-add", help="create or update user",
|
||||
description="update user for web services with the given password and role. "
|
||||
"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)
|
||||
parser.add_argument("username", help="username for web service")
|
||||
parser.add_argument("--key", help="optional PGP key used by this user. The private key must be imported")
|
||||
parser.add_argument("--packager", help="optional packager id used for build process in form of "
|
||||
"`Name Surname <mail@example.com>`")
|
||||
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.")
|
||||
parser.add_argument("-r", "--role", help="user access level",
|
||||
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.set_defaults(handler=handlers.Users, action=Action.Update, architecture=[""], lock=None, report=False,
|
||||
quiet=True)
|
||||
return parser
|
||||
@ -901,8 +954,8 @@ def _set_user_list_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
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("-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, report=False, # nosec
|
||||
password="", quiet=True, unsafe=True)
|
||||
parser.set_defaults(handler=handlers.Users, action=Action.List, architecture=[""], lock=None, report=False,
|
||||
quiet=True, unsafe=True)
|
||||
return parser
|
||||
|
||||
|
||||
@ -920,8 +973,8 @@ def _set_user_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
description="remove user from the user mapping and update the configuration",
|
||||
formatter_class=_formatter)
|
||||
parser.add_argument("username", help="username for web service")
|
||||
parser.set_defaults(handler=handlers.Users, action=Action.Remove, architecture=[""], lock=None, report=False, # nosec
|
||||
password="", quiet=True)
|
||||
parser.set_defaults(handler=handlers.Users, action=Action.Remove, architecture=[""], lock=None, report=False,
|
||||
quiet=True)
|
||||
return parser
|
||||
|
||||
|
||||
|
@ -17,10 +17,12 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from collections.abc import Iterable
|
||||
from collections.abc import Callable, Iterable
|
||||
|
||||
from ahriman.application.application.application_packages import ApplicationPackages
|
||||
from ahriman.application.application.application_repository import ApplicationRepository
|
||||
from ahriman.core.formatters import UpdatePrinter
|
||||
from ahriman.core.tree import Tree
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.result import Result
|
||||
|
||||
@ -37,12 +39,12 @@ class Application(ApplicationPackages, ApplicationRepository):
|
||||
>>> from ahriman.models.package_source import PackageSource
|
||||
>>>
|
||||
>>> configuration = Configuration()
|
||||
>>> application = Application("x86_64", configuration, report=True, unsafe=False)
|
||||
>>> application = Application("x86_64", configuration, report=True)
|
||||
>>> # add packages to build queue
|
||||
>>> application.add(["ahriman"], PackageSource.AUR, without_dependencies=False)
|
||||
>>> application.add(["ahriman"], PackageSource.AUR)
|
||||
>>>
|
||||
>>> # check for updates
|
||||
>>> updates = application.updates([], aur=True, local=True, manual=True, vcs=True, log_fn=print)
|
||||
>>> updates = application.updates([], aur=True, local=True, manual=True, vcs=True)
|
||||
>>> # updates for specified packages
|
||||
>>> application.update(updates)
|
||||
|
||||
@ -89,6 +91,22 @@ class Application(ApplicationPackages, ApplicationRepository):
|
||||
"""
|
||||
self.repository.triggers.on_stop()
|
||||
|
||||
def print_updates(self, packages: list[Package], *, log_fn: Callable[[str], None]) -> None:
|
||||
"""
|
||||
print list of packages to be built. This method will build dependency tree and print updates accordingly
|
||||
|
||||
Args:
|
||||
packages(list[Package]): package list to be printed
|
||||
log_fn(Callable[[str], None]): logger function to log updates
|
||||
"""
|
||||
local_versions = {package.base: package.version for package in self.repository.packages()}
|
||||
|
||||
tree = Tree.resolve(packages)
|
||||
for level in tree:
|
||||
for package in level:
|
||||
UpdatePrinter(package, local_versions.get(package.base)).print(
|
||||
verbose=True, log_fn=log_fn, separator=" -> ")
|
||||
|
||||
def with_dependencies(self, packages: list[Package], *, process_dependencies: bool) -> list[Package]:
|
||||
"""
|
||||
add missing dependencies to list of packages
|
||||
@ -96,21 +114,25 @@ class Application(ApplicationPackages, ApplicationRepository):
|
||||
Args:
|
||||
packages(list[Package]): list of source packages of which dependencies have to be processed
|
||||
process_dependencies(bool): if no set, dependencies will not be processed
|
||||
|
||||
Returns:
|
||||
list[Package]: updated packages list. Packager for dependencies will be copied from
|
||||
original package
|
||||
"""
|
||||
def missing_dependencies(source: Iterable[Package]) -> set[str]:
|
||||
# build initial list of dependencies
|
||||
result = set()
|
||||
for package in source:
|
||||
result.update(package.depends_build)
|
||||
def missing_dependencies(source: Iterable[Package]) -> dict[str, str | None]:
|
||||
# append list of known packages with packages which are in current sources
|
||||
satisfied_packages = known_packages | {
|
||||
single
|
||||
for package in source
|
||||
for single in package.packages_full
|
||||
}
|
||||
|
||||
# remove ones which are already well-known
|
||||
result = result.difference(known_packages)
|
||||
|
||||
# remove ones which are in this list already
|
||||
for package in source:
|
||||
result = result.difference(package.packages_full)
|
||||
|
||||
return result
|
||||
return {
|
||||
dependency: package.packager
|
||||
for package in source
|
||||
for dependency in package.depends_build
|
||||
if dependency not in satisfied_packages
|
||||
}
|
||||
|
||||
if not process_dependencies or not packages:
|
||||
return packages
|
||||
@ -119,8 +141,11 @@ class Application(ApplicationPackages, ApplicationRepository):
|
||||
with_dependencies = {package.base: package for package in packages}
|
||||
|
||||
while missing := missing_dependencies(with_dependencies.values()):
|
||||
for package_name in missing:
|
||||
package = Package.from_aur(package_name, self.repository.pacman)
|
||||
for package_name, username in missing.items():
|
||||
package = Package.from_aur(package_name, self.repository.pacman, username)
|
||||
with_dependencies[package.base] = package
|
||||
# register package in local database
|
||||
self.database.remote_update(package)
|
||||
self.repository.reporter.set_unknown(package)
|
||||
|
||||
return list(with_dependencies.values())
|
||||
|
@ -26,6 +26,7 @@ from typing import Any
|
||||
|
||||
from ahriman.application.application.application_properties import ApplicationProperties
|
||||
from ahriman.core.build_tools.sources import Sources
|
||||
from ahriman.core.exceptions import UnknownPackageError
|
||||
from ahriman.core.util import package_like
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.package_source import PackageSource
|
||||
@ -43,20 +44,26 @@ class ApplicationPackages(ApplicationProperties):
|
||||
|
||||
Args:
|
||||
source(str): path to package archive
|
||||
|
||||
Raises:
|
||||
UnknownPackageError: if specified path doesn't exist
|
||||
"""
|
||||
local_path = Path(source)
|
||||
if not local_path.is_file():
|
||||
raise UnknownPackageError(source)
|
||||
|
||||
dst = self.repository.paths.packages / local_path.name
|
||||
shutil.copy(local_path, dst)
|
||||
|
||||
def _add_aur(self, source: str) -> None:
|
||||
def _add_aur(self, source: str, username: str | None) -> None:
|
||||
"""
|
||||
add package from AUR
|
||||
|
||||
Args:
|
||||
source(str): package base name
|
||||
username(str | None): optional override of username for build process
|
||||
"""
|
||||
package = Package.from_aur(source, self.repository.pacman)
|
||||
|
||||
package = Package.from_aur(source, self.repository.pacman, username)
|
||||
self.database.build_queue_insert(package)
|
||||
self.database.remote_update(package)
|
||||
|
||||
@ -68,21 +75,32 @@ class ApplicationPackages(ApplicationProperties):
|
||||
source(str): path to local directory
|
||||
"""
|
||||
local_dir = Path(source)
|
||||
if not local_dir.is_dir():
|
||||
raise UnknownPackageError(source)
|
||||
|
||||
for full_path in filter(package_like, local_dir.iterdir()):
|
||||
self._add_archive(str(full_path))
|
||||
|
||||
def _add_local(self, source: str) -> None:
|
||||
def _add_local(self, source: str, username: str | None) -> None:
|
||||
"""
|
||||
add package from local PKGBUILDs
|
||||
|
||||
Args:
|
||||
source(str): path to directory with local source files
|
||||
username(str | None): optional override of username for build process
|
||||
|
||||
Raises:
|
||||
UnknownPackageError: if specified package is unknown or doesn't exist
|
||||
"""
|
||||
source_dir = Path(source)
|
||||
package = Package.from_build(source_dir, self.architecture)
|
||||
cache_dir = self.repository.paths.cache_for(package.base)
|
||||
shutil.copytree(source_dir, cache_dir) # copy package to store in caches
|
||||
Sources.init(cache_dir) # we need to run init command in directory where we do have permissions
|
||||
if (source_dir := Path(source)).is_dir():
|
||||
package = Package.from_build(source_dir, self.architecture, username)
|
||||
cache_dir = self.repository.paths.cache_for(package.base)
|
||||
shutil.copytree(source_dir, cache_dir) # copy package to store in caches
|
||||
Sources.init(cache_dir) # we need to run init command in directory where we do have permissions
|
||||
elif (source_dir := self.repository.paths.cache_for(source)).is_dir():
|
||||
package = Package.from_build(source_dir, self.architecture, username)
|
||||
else:
|
||||
raise UnknownPackageError(source)
|
||||
|
||||
self.database.build_queue_insert(package)
|
||||
|
||||
@ -95,36 +113,41 @@ class ApplicationPackages(ApplicationProperties):
|
||||
"""
|
||||
dst = self.repository.paths.packages / Path(source).name # URL is path, is not it?
|
||||
# timeout=None to suppress pylint warns. Also suppress bandit warnings
|
||||
response = requests.get(source, stream=True, timeout=None) # nosec
|
||||
response.raise_for_status()
|
||||
try:
|
||||
response = requests.get(source, stream=True, timeout=None) # nosec
|
||||
response.raise_for_status()
|
||||
except Exception:
|
||||
raise UnknownPackageError(source)
|
||||
|
||||
with dst.open("wb") as local_file:
|
||||
for chunk in response.iter_content(chunk_size=1024):
|
||||
local_file.write(chunk)
|
||||
|
||||
def _add_repository(self, source: str, *_: Any) -> None:
|
||||
def _add_repository(self, source: str, username: str | None) -> None:
|
||||
"""
|
||||
add package from official repository
|
||||
|
||||
Args:
|
||||
source(str): package base name
|
||||
username(str | None): optional override of username for build process
|
||||
"""
|
||||
package = Package.from_official(source, self.repository.pacman)
|
||||
package = Package.from_official(source, self.repository.pacman, username)
|
||||
self.database.build_queue_insert(package)
|
||||
self.database.remote_update(package)
|
||||
|
||||
def add(self, names: Iterable[str], source: PackageSource) -> None:
|
||||
def add(self, names: Iterable[str], source: PackageSource, username: str | None = None) -> None:
|
||||
"""
|
||||
add packages for the next build
|
||||
|
||||
Args:
|
||||
names(Iterable[str]): list of package bases to add
|
||||
source(PackageSource): package source to add
|
||||
username(str | None, optional): optional override of username for build process (Default value = None)
|
||||
"""
|
||||
for name in names:
|
||||
resolved_source = source.resolve(name)
|
||||
fn = getattr(self, f"_add_{resolved_source.value}")
|
||||
fn(name)
|
||||
fn(name, username)
|
||||
|
||||
def on_result(self, result: Result) -> None:
|
||||
"""
|
||||
|
@ -35,7 +35,7 @@ class ApplicationProperties(LazyLogging):
|
||||
repository(Repository): repository instance
|
||||
"""
|
||||
|
||||
def __init__(self, architecture: str, configuration: Configuration, *, report: bool, unsafe: bool,
|
||||
def __init__(self, architecture: str, configuration: Configuration, *, report: bool,
|
||||
refresh_pacman_database: PacmanSynchronization = PacmanSynchronization.Disabled) -> None:
|
||||
"""
|
||||
default constructor
|
||||
@ -44,12 +44,11 @@ class ApplicationProperties(LazyLogging):
|
||||
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
|
||||
refresh_pacman_database(PacmanSynchronization, optional): pacman database synchronization level
|
||||
(Default value = PacmanSynchronization.Disabled)
|
||||
"""
|
||||
self.configuration = configuration
|
||||
self.architecture = architecture
|
||||
self.database = SQLite.load(configuration)
|
||||
self.repository = Repository.load(architecture, configuration, self.database, report=report, unsafe=unsafe,
|
||||
self.repository = Repository.load(architecture, configuration, self.database, report=report,
|
||||
refresh_pacman_database=refresh_pacman_database)
|
||||
|
@ -17,14 +17,14 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from collections.abc import Callable, Iterable
|
||||
from collections.abc import Iterable
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.application.application.application_properties import ApplicationProperties
|
||||
from ahriman.core.build_tools.sources import Sources
|
||||
from ahriman.core.formatters import UpdatePrinter
|
||||
from ahriman.core.tree import Tree
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.packagers import Packagers
|
||||
from ahriman.models.result import Result
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ class ApplicationRepository(ApplicationProperties):
|
||||
if archive.filepath is None:
|
||||
self.logger.warning("filepath is empty for %s", package.base)
|
||||
continue # avoid mypy warning
|
||||
self.repository.sign.process_sign_package(archive.filepath, package.base)
|
||||
self.repository.sign.process_sign_package(archive.filepath, None)
|
||||
# sign repository database if set
|
||||
self.repository.sign.process_sign_repository(self.repository.repo.repo_path)
|
||||
# process triggers
|
||||
@ -104,14 +104,14 @@ class ApplicationRepository(ApplicationProperties):
|
||||
packages: list[str] = []
|
||||
for single in probe.packages:
|
||||
try:
|
||||
_ = Package.from_aur(single, self.repository.pacman)
|
||||
_ = Package.from_aur(single, self.repository.pacman, None)
|
||||
except Exception:
|
||||
packages.append(single)
|
||||
return packages
|
||||
|
||||
def unknown_local(probe: Package) -> list[str]:
|
||||
cache_dir = self.repository.paths.cache_for(probe.base)
|
||||
local = Package.from_build(cache_dir, self.architecture)
|
||||
local = Package.from_build(cache_dir, self.architecture, None)
|
||||
packages = set(probe.packages.keys()).difference(local.packages.keys())
|
||||
return list(packages)
|
||||
|
||||
@ -123,12 +123,14 @@ class ApplicationRepository(ApplicationProperties):
|
||||
result.extend(unknown_aur(package)) # local package not found
|
||||
return result
|
||||
|
||||
def update(self, updates: Iterable[Package]) -> Result:
|
||||
def update(self, updates: Iterable[Package], packagers: Packagers | None = None) -> Result:
|
||||
"""
|
||||
run package updates
|
||||
|
||||
Args:
|
||||
updates(Iterable[Package]): list of packages to update
|
||||
packagers(Packagers | None, optional): optional override of username for build process
|
||||
(Default value = None)
|
||||
|
||||
Returns:
|
||||
Result: update result
|
||||
@ -136,7 +138,7 @@ class ApplicationRepository(ApplicationProperties):
|
||||
def process_update(paths: Iterable[Path], result: Result) -> None:
|
||||
if not paths:
|
||||
return # don't need to process if no update supplied
|
||||
update_result = self.repository.process_update(paths)
|
||||
update_result = self.repository.process_update(paths, packagers)
|
||||
self.on_result(result.merge(update_result))
|
||||
|
||||
# process built packages
|
||||
@ -148,14 +150,14 @@ class ApplicationRepository(ApplicationProperties):
|
||||
tree = Tree.resolve(updates)
|
||||
for num, level in enumerate(tree):
|
||||
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, packagers)
|
||||
packages = self.repository.packages_built()
|
||||
process_update(packages, build_result)
|
||||
|
||||
return build_result
|
||||
|
||||
def updates(self, filter_packages: Iterable[str], *,
|
||||
aur: bool, local: bool, manual: bool, vcs: bool, log_fn: Callable[[str], None]) -> list[Package]:
|
||||
aur: bool, local: bool, manual: bool, vcs: bool) -> list[Package]:
|
||||
"""
|
||||
get list of packages to run update process
|
||||
|
||||
@ -165,7 +167,6 @@ class ApplicationRepository(ApplicationProperties):
|
||||
local(bool): enable or disable checking of local packages for updates
|
||||
manual(bool): include or exclude manual updates
|
||||
vcs(bool): enable or disable checking of VCS packages
|
||||
log_fn(Callable[[str], None]): logger function to log updates
|
||||
|
||||
Returns:
|
||||
list[Package]: list of out-of-dated packages
|
||||
@ -179,14 +180,4 @@ class ApplicationRepository(ApplicationProperties):
|
||||
if 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()}
|
||||
updated_packages = [package for _, package in sorted(updates.items())]
|
||||
|
||||
# reorder updates according to the dependency tree
|
||||
tree = Tree.resolve(updated_packages)
|
||||
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 [package for _, package in sorted(updates.items())]
|
||||
|
@ -22,6 +22,7 @@ import argparse
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.packagers import Packagers
|
||||
|
||||
|
||||
class Add(Handler):
|
||||
@ -30,8 +31,7 @@ class Add(Handler):
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -40,17 +40,17 @@ class Add(Handler):
|
||||
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, refresh_pacman_database=args.refresh)
|
||||
application = Application(architecture, configuration, report=report, refresh_pacman_database=args.refresh)
|
||||
application.on_start()
|
||||
application.add(args.package, args.source)
|
||||
application.add(args.package, args.source, args.username)
|
||||
if not args.now:
|
||||
return
|
||||
|
||||
packages = application.updates(args.package, aur=False, local=False, manual=True, vcs=False,
|
||||
log_fn=application.logger.info)
|
||||
packages = application.updates(args.package, aur=False, local=False, manual=True, vcs=False)
|
||||
packages = application.with_dependencies(packages, process_dependencies=args.dependencies)
|
||||
result = application.update(packages)
|
||||
packagers = Packagers(args.username, {package.base: package.packager for package in packages})
|
||||
|
||||
application.print_updates(packages, log_fn=application.logger.info)
|
||||
result = application.update(packages, packagers)
|
||||
Add.check_if_empty(args.exit_code, result.is_empty)
|
||||
|
@ -36,8 +36,7 @@ class Backup(Handler):
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -46,7 +45,6 @@ class Backup(Handler):
|
||||
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
|
||||
"""
|
||||
backup_paths = Backup.get_paths(configuration)
|
||||
with TarFile(args.path, mode="w") as archive: # well we don't actually use compression
|
||||
|
@ -30,8 +30,7 @@ class Clean(Handler):
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -40,9 +39,8 @@ class Clean(Handler):
|
||||
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)
|
||||
application = Application(architecture, configuration, report=report)
|
||||
application.on_start()
|
||||
application.clean(cache=args.cache, chroot=args.chroot, manual=args.manual, packages=args.packages,
|
||||
pacman=args.pacman)
|
||||
|
@ -30,8 +30,7 @@ class Daemon(Handler):
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -40,11 +39,10 @@ class Daemon(Handler):
|
||||
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)
|
||||
Update.run(args, architecture, configuration, report=report)
|
||||
timer = threading.Timer(args.interval, Daemon.run, args=[args, architecture, configuration],
|
||||
kwargs={"report": report, "unsafe": unsafe})
|
||||
kwargs={"report": report})
|
||||
timer.start()
|
||||
timer.join()
|
||||
|
@ -21,7 +21,7 @@ import argparse
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import ConfigurationPrinter
|
||||
from ahriman.core.formatters import ConfigurationPathsPrinter, ConfigurationPrinter, StringPrinter
|
||||
|
||||
|
||||
class Dump(Handler):
|
||||
@ -32,8 +32,7 @@ class Dump(Handler):
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -42,8 +41,13 @@ class Dump(Handler):
|
||||
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
|
||||
"""
|
||||
root, _ = configuration.check_loaded()
|
||||
ConfigurationPathsPrinter(root, configuration.includes).print(verbose=True, separator=" = ")
|
||||
|
||||
# empty line
|
||||
StringPrinter("").print(verbose=False)
|
||||
|
||||
dump = configuration.dump()
|
||||
for section, values in sorted(dump.items()):
|
||||
ConfigurationPrinter(section, values).print(verbose=not args.secure, separator=" = ")
|
||||
|
@ -94,9 +94,10 @@ class Handler:
|
||||
"""
|
||||
try:
|
||||
configuration = Configuration.from_path(args.configuration, architecture)
|
||||
Log.load(configuration, quiet=args.quiet, report=args.report)
|
||||
log_handler = Log.handler(args.log_handler)
|
||||
Log.load(configuration, log_handler, quiet=args.quiet, report=args.report)
|
||||
with Lock(args, architecture, configuration):
|
||||
cls.run(args, architecture, configuration, report=args.report, unsafe=args.unsafe)
|
||||
cls.run(args, architecture, configuration, report=args.report)
|
||||
return True
|
||||
except ExitCode:
|
||||
return False
|
||||
@ -135,8 +136,7 @@ class Handler:
|
||||
return 0 if all(result) else 1
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -145,7 +145,6 @@ class Handler:
|
||||
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
|
||||
|
||||
Raises:
|
||||
NotImplementedError: not implemented method
|
||||
|
@ -31,8 +31,7 @@ class Help(Handler):
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -41,7 +40,6 @@ class Help(Handler):
|
||||
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
|
||||
"""
|
||||
parser: argparse.ArgumentParser = args.parser()
|
||||
if args.command is None:
|
||||
|
@ -32,8 +32,7 @@ class KeyImport(Handler):
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -42,7 +41,6 @@ class KeyImport(Handler):
|
||||
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)
|
||||
application = Application(architecture, configuration, report=report)
|
||||
application.repository.sign.key_import(args.key_server, args.key)
|
||||
|
@ -38,8 +38,7 @@ class Patch(Handler):
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -48,9 +47,8 @@ class Patch(Handler):
|
||||
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)
|
||||
application = Application(architecture, configuration, report=report)
|
||||
application.on_start()
|
||||
|
||||
if args.action == Action.Update and args.variable is not None:
|
||||
@ -78,7 +76,7 @@ class Patch(Handler):
|
||||
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, architecture)
|
||||
package = Package.from_build(sources_dir, architecture, None)
|
||||
patch = Sources.patch_create(sources_dir, *track)
|
||||
return package.base, PkgbuildPatch(None, patch)
|
||||
|
||||
|
@ -22,7 +22,7 @@ import argparse
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import UpdatePrinter
|
||||
from ahriman.models.build_status import BuildStatusEnum
|
||||
from ahriman.models.package import Package
|
||||
|
||||
|
||||
@ -32,8 +32,7 @@ class Rebuild(Handler):
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -42,35 +41,40 @@ class Rebuild(Handler):
|
||||
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)
|
||||
application = Application(architecture, configuration, report=report)
|
||||
application.on_start()
|
||||
|
||||
packages = Rebuild.extract_packages(application, from_database=args.from_database)
|
||||
packages = Rebuild.extract_packages(application, args.status, from_database=args.from_database)
|
||||
updates = application.repository.packages_depend_on(packages, args.depends_on or None)
|
||||
|
||||
Rebuild.check_if_empty(args.exit_code, not updates)
|
||||
if args.dry_run:
|
||||
for package in updates:
|
||||
UpdatePrinter(package, package.version).print(verbose=True)
|
||||
application.print_updates(updates, log_fn=print)
|
||||
return
|
||||
|
||||
result = application.update(updates)
|
||||
result = application.update(updates, args.username)
|
||||
Rebuild.check_if_empty(args.exit_code, result.is_empty)
|
||||
|
||||
@staticmethod
|
||||
def extract_packages(application: Application, *, from_database: bool) -> list[Package]:
|
||||
def extract_packages(application: Application, status: BuildStatusEnum | None, *,
|
||||
from_database: bool) -> list[Package]:
|
||||
"""
|
||||
extract packages from database file
|
||||
|
||||
Args:
|
||||
application(Application): application instance
|
||||
status(BuildStatusEnum | None): optional filter by package status
|
||||
from_database(bool): extract packages from database instead of repository filesystem
|
||||
|
||||
Returns:
|
||||
list[Package]: list of packages which were stored in database
|
||||
"""
|
||||
if from_database:
|
||||
return [package for (package, _) in application.database.packages_get()]
|
||||
return [
|
||||
package
|
||||
for (package, last_status) in application.database.packages_get()
|
||||
if status is None or last_status.status == status
|
||||
]
|
||||
|
||||
return application.repository.packages()
|
||||
|
@ -30,8 +30,7 @@ class Remove(Handler):
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -40,8 +39,7 @@ class Remove(Handler):
|
||||
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)
|
||||
application = Application(architecture, configuration, report=report)
|
||||
application.on_start()
|
||||
application.remove(args.package)
|
||||
|
@ -31,8 +31,7 @@ class RemoveUnknown(Handler):
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -41,9 +40,8 @@ class RemoveUnknown(Handler):
|
||||
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)
|
||||
application = Application(architecture, configuration, report=report)
|
||||
application.on_start()
|
||||
unknown_packages = application.unknown()
|
||||
|
||||
|
@ -33,8 +33,7 @@ class Restore(Handler):
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -43,7 +42,6 @@ class Restore(Handler):
|
||||
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
|
||||
"""
|
||||
with TarFile(args.path) as archive:
|
||||
archive.extractall(path=args.output)
|
||||
|
@ -47,8 +47,7 @@ class Search(Handler):
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -57,9 +56,8 @@ class Search(Handler):
|
||||
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)
|
||||
application = Application(architecture, configuration, report=report)
|
||||
|
||||
official_packages_list = Official.multisearch(*args.search, pacman=application.repository.pacman)
|
||||
aur_packages_list = AUR.multisearch(*args.search, pacman=application.repository.pacman)
|
||||
|
@ -35,8 +35,7 @@ class ServiceUpdates(Handler):
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -45,11 +44,10 @@ class ServiceUpdates(Handler):
|
||||
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)
|
||||
application = Application(architecture, configuration, report=report)
|
||||
|
||||
remote = Package.from_aur("ahriman", application.repository.pacman)
|
||||
remote = Package.from_aur("ahriman", application.repository.pacman, None)
|
||||
release = remote.version.rsplit("-", 1)[-1] # we don't store pkgrel locally, so we just append it
|
||||
local_version = f"{version.__version__}-{release}"
|
||||
|
||||
|
@ -26,6 +26,7 @@ from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
from ahriman.models.user import User
|
||||
|
||||
|
||||
class Setup(Handler):
|
||||
@ -40,13 +41,12 @@ class Setup(Handler):
|
||||
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
||||
|
||||
ARCHBUILD_COMMAND_PATH = Path("/usr/bin/archbuild")
|
||||
MIRRORLIST_PATH = Path("/etc/pacman.d/mirrorlist")
|
||||
SUDOERS_DIR_PATH = Path("/etc/sudoers.d")
|
||||
ARCHBUILD_COMMAND_PATH = Path("/usr") / "bin" / "archbuild"
|
||||
MIRRORLIST_PATH = Path("/etc") / "pacman.d" / "mirrorlist"
|
||||
SUDOERS_DIR_PATH = Path("/etc") / "sudoers.d"
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -55,12 +55,11 @@ class Setup(Handler):
|
||||
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
|
||||
"""
|
||||
Setup.configuration_create_ahriman(args, architecture, args.repository, configuration)
|
||||
configuration.reload()
|
||||
|
||||
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||
application = Application(architecture, configuration, report=report)
|
||||
|
||||
Setup.configuration_create_makepkg(args.packager, args.makeflags_jobs, application.repository.paths)
|
||||
Setup.executable_create(application.repository.paths, args.build_command, architecture)
|
||||
@ -126,6 +125,9 @@ class Setup(Handler):
|
||||
if args.web_unix_socket is not None:
|
||||
configuration.set_option(section, "unix_socket", str(args.web_unix_socket))
|
||||
|
||||
if args.generate_salt:
|
||||
configuration.set_option("auth", "salt", User.generate_password(20))
|
||||
|
||||
target = root.include / "00-setup-overrides.ini"
|
||||
with target.open("w") as ahriman_configuration:
|
||||
configuration.write(ahriman_configuration)
|
||||
@ -136,7 +138,7 @@ class Setup(Handler):
|
||||
"""
|
||||
create configuration for devtools based on ``source`` configuration
|
||||
|
||||
Note:
|
||||
Notes:
|
||||
devtools does not allow to specify the pacman configuration, thus we still have to use configuration in /usr
|
||||
|
||||
Args:
|
||||
@ -175,10 +177,10 @@ class Setup(Handler):
|
||||
configuration.set_option(section, "Server", mirror)
|
||||
|
||||
# add repository itself
|
||||
configuration.set_option(repository, "SigLevel", "Optional TrustAll") # we don't care
|
||||
configuration.set_option(repository, "SigLevel", "Never") # we don't care
|
||||
configuration.set_option(repository, "Server", f"file://{paths.repository}")
|
||||
|
||||
target = source.parent / f"pacman-{prefix}-{architecture}.conf"
|
||||
target = source.parent / f"{prefix}-{architecture}.conf"
|
||||
with target.open("w") as devtools_configuration:
|
||||
configuration.write(devtools_configuration)
|
||||
|
||||
@ -213,7 +215,7 @@ class Setup(Handler):
|
||||
"""
|
||||
command = Setup.build_command(paths.root, prefix, architecture)
|
||||
sudoers_file = Setup.build_command(Setup.SUDOERS_DIR_PATH, prefix, architecture)
|
||||
sudoers_file.write_text(f"ahriman ALL=(ALL) NOPASSWD: {command} *\n", encoding="utf8")
|
||||
sudoers_file.write_text(f"ahriman ALL=(ALL) NOPASSWD:SETENV: {command} *\n", encoding="utf8")
|
||||
sudoers_file.chmod(0o400) # security!
|
||||
|
||||
@staticmethod
|
||||
|
@ -23,7 +23,6 @@ import sys
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import StringPrinter
|
||||
@ -37,8 +36,7 @@ class Shell(Handler):
|
||||
ALLOW_MULTI_ARCHITECTURE_RUN = False
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -47,16 +45,13 @@ class Shell(Handler):
|
||||
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
|
||||
"""
|
||||
# pylint: disable=possibly-unused-variable
|
||||
application = Application(architecture, configuration, report=report, unsafe=unsafe)
|
||||
if args.verbose:
|
||||
# licensed by https://creativecommons.org/licenses/by-sa/3.0
|
||||
path = Path(sys.prefix) / "share" / "ahriman" / "templates" / "shell"
|
||||
StringPrinter(path.read_text(encoding="utf8")).print(verbose=False)
|
||||
# we only want to pass application instance inside
|
||||
local_variables = {"architecture": architecture, "configuration": configuration}
|
||||
if args.code is None:
|
||||
code.interact(local={"application": application})
|
||||
code.interact(local=local_variables)
|
||||
else:
|
||||
code.InteractiveConsole(locals={"application": application}).runcode(args.code)
|
||||
code.InteractiveConsole(locals=local_variables).runcode(args.code)
|
||||
|
@ -30,8 +30,7 @@ class Sign(Handler):
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -40,6 +39,5 @@ class Sign(Handler):
|
||||
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(architecture, configuration, report=report, unsafe=unsafe).sign(args.package)
|
||||
Application(architecture, configuration, report=report).sign(args.package)
|
||||
|
@ -37,8 +37,7 @@ class Status(Handler):
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -47,10 +46,9 @@ class Status(Handler):
|
||||
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
|
||||
"""
|
||||
# we are using reporter here
|
||||
client = Application(architecture, configuration, report=True, unsafe=unsafe).repository.reporter
|
||||
client = Application(architecture, configuration, report=True).repository.reporter
|
||||
if args.ahriman:
|
||||
service_status = client.get_internal()
|
||||
StatusPrinter(service_status.status).print(verbose=args.info)
|
||||
|
@ -33,8 +33,7 @@ class StatusUpdate(Handler):
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -43,10 +42,9 @@ class StatusUpdate(Handler):
|
||||
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
|
||||
"""
|
||||
# we are using reporter here
|
||||
client = Application(architecture, configuration, report=True, unsafe=unsafe).repository.reporter
|
||||
client = Application(architecture, configuration, report=True).repository.reporter
|
||||
|
||||
if args.action == Action.Update and args.package:
|
||||
# update packages statuses
|
||||
|
@ -34,8 +34,7 @@ class Structure(Handler):
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -44,9 +43,8 @@ class Structure(Handler):
|
||||
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)
|
||||
application = Application(architecture, configuration, report=report)
|
||||
packages = application.repository.packages()
|
||||
|
||||
tree = Tree.resolve(packages)
|
||||
|
@ -31,8 +31,7 @@ class Triggers(Handler):
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -41,9 +40,8 @@ class Triggers(Handler):
|
||||
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)
|
||||
application = Application(architecture, configuration, report=report)
|
||||
if args.trigger:
|
||||
loader = application.repository.triggers
|
||||
loader.triggers = [loader.load_trigger(trigger, architecture, configuration) for trigger in args.trigger]
|
||||
|
@ -18,7 +18,6 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import argparse
|
||||
import shlex
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
@ -33,8 +32,7 @@ class UnsafeCommands(Handler):
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -43,18 +41,17 @@ class UnsafeCommands(Handler):
|
||||
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
|
||||
"""
|
||||
parser = args.parser()
|
||||
unsafe_commands = UnsafeCommands.get_unsafe_commands(parser)
|
||||
if args.command is None:
|
||||
if args.command:
|
||||
UnsafeCommands.check_unsafe(args.command, unsafe_commands, parser)
|
||||
else:
|
||||
for command in unsafe_commands:
|
||||
StringPrinter(command).print(verbose=True)
|
||||
else:
|
||||
UnsafeCommands.check_unsafe(args.command, unsafe_commands, parser)
|
||||
|
||||
@staticmethod
|
||||
def check_unsafe(command: str, unsafe_commands: list[str], parser: argparse.ArgumentParser) -> None:
|
||||
def check_unsafe(command: list[str], unsafe_commands: list[str], parser: argparse.ArgumentParser) -> None:
|
||||
"""
|
||||
check if command is unsafe
|
||||
|
||||
@ -63,7 +60,7 @@ class UnsafeCommands(Handler):
|
||||
unsafe_commands(list[str]): list of unsafe commands
|
||||
parser(argparse.ArgumentParser): generated argument parser
|
||||
"""
|
||||
args = parser.parse_args(shlex.split(command))
|
||||
args = parser.parse_args(command)
|
||||
UnsafeCommands.check_if_empty(True, args.command in unsafe_commands)
|
||||
|
||||
@staticmethod
|
||||
@ -79,5 +76,6 @@ class UnsafeCommands(Handler):
|
||||
"""
|
||||
# should never fail
|
||||
# pylint: disable=protected-access
|
||||
subparser = next(action for action in parser._actions if isinstance(action, argparse._SubParsersAction))
|
||||
return sorted(action_name for action_name, action in subparser.choices.items() if action.get_default("unsafe"))
|
||||
subparser = next((action for action in parser._actions if isinstance(action, argparse._SubParsersAction)), None)
|
||||
actions = subparser.choices if subparser is not None else {}
|
||||
return sorted(action_name for action_name, action in actions.items() if action.get_default("unsafe"))
|
||||
|
@ -24,6 +24,7 @@ from collections.abc import Callable
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.packagers import Packagers
|
||||
|
||||
|
||||
class Update(Handler):
|
||||
@ -32,8 +33,7 @@ class Update(Handler):
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -42,19 +42,19 @@ class Update(Handler):
|
||||
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,
|
||||
refresh_pacman_database=args.refresh)
|
||||
application = Application(architecture, configuration, report=report, refresh_pacman_database=args.refresh)
|
||||
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))
|
||||
packages = application.updates(args.package, aur=args.aur, local=args.local, manual=args.manual, vcs=args.vcs)
|
||||
Update.check_if_empty(args.exit_code, not packages)
|
||||
if args.dry_run:
|
||||
return
|
||||
|
||||
packages = application.with_dependencies(packages, process_dependencies=args.dependencies)
|
||||
result = application.update(packages)
|
||||
packagers = Packagers(args.username, {package.base: package.packager for package in packages})
|
||||
|
||||
application.print_updates(packages, log_fn=application.logger.info)
|
||||
result = application.update(packages, packagers)
|
||||
Update.check_if_empty(args.exit_code, result.is_empty)
|
||||
|
||||
@staticmethod
|
||||
|
@ -20,8 +20,6 @@
|
||||
import argparse
|
||||
import getpass
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.database import SQLite
|
||||
@ -39,8 +37,7 @@ class Users(Handler):
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -49,18 +46,13 @@ class Users(Handler):
|
||||
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
|
||||
"""
|
||||
database = SQLite.load(configuration)
|
||||
|
||||
if args.action == Action.Update:
|
||||
old_salt, salt = Users.get_salt(configuration)
|
||||
user = Users.user_create(args)
|
||||
|
||||
if old_salt is None:
|
||||
auth_configuration = Users.configuration_get(configuration.include)
|
||||
Users.configuration_create(auth_configuration, salt, args.secure)
|
||||
|
||||
# if password is left blank we are not going to require salt to be set
|
||||
salt = configuration.get("auth", "salt") if user.password else ""
|
||||
database.user_update(user.hash_password(salt))
|
||||
elif args.action == Action.List:
|
||||
users = database.user_list(args.username, args.role)
|
||||
@ -70,70 +62,6 @@ class Users(Handler):
|
||||
elif args.action == Action.Remove:
|
||||
database.user_remove(args.username)
|
||||
|
||||
@staticmethod
|
||||
def configuration_create(configuration: Configuration, salt: str, secure: bool) -> None:
|
||||
"""
|
||||
enable configuration if it has been disabled
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
salt(str): password hash salt
|
||||
secure(bool): if true then set file permissions to 0o600
|
||||
"""
|
||||
configuration.set_option("auth", "salt", salt)
|
||||
Users.configuration_write(configuration, secure)
|
||||
|
||||
@staticmethod
|
||||
def configuration_get(include_path: Path) -> Configuration:
|
||||
"""
|
||||
create configuration instance
|
||||
|
||||
Args:
|
||||
include_path(Path): path to directory with configuration includes
|
||||
|
||||
Returns:
|
||||
Configuration: configuration instance. In case if there are local settings they will be loaded
|
||||
"""
|
||||
target = include_path / "00-auth.ini"
|
||||
configuration = Configuration()
|
||||
configuration.load(target)
|
||||
|
||||
configuration.architecture = "" # not user anyway
|
||||
|
||||
return configuration
|
||||
|
||||
@staticmethod
|
||||
def configuration_write(configuration: Configuration, secure: bool) -> None:
|
||||
"""
|
||||
write configuration file
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
secure(bool): if true then set file permissions to 0o600
|
||||
"""
|
||||
path, _ = configuration.check_loaded()
|
||||
with path.open("w") as ahriman_configuration:
|
||||
configuration.write(ahriman_configuration)
|
||||
if secure:
|
||||
path.chmod(0o600)
|
||||
|
||||
@staticmethod
|
||||
def get_salt(configuration: Configuration, salt_length: int = 20) -> tuple[str | None, str]:
|
||||
"""
|
||||
get salt from configuration or create new string
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
salt_length(int, optional): salt length (Default value = 20)
|
||||
|
||||
Returns:
|
||||
tuple[str | None, 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):
|
||||
return salt, salt
|
||||
return None, User.generate_password(salt_length)
|
||||
|
||||
@staticmethod
|
||||
def user_create(args: argparse.Namespace) -> User:
|
||||
"""
|
||||
@ -156,4 +84,5 @@ class Users(Handler):
|
||||
if password is None:
|
||||
password = read_password()
|
||||
|
||||
return User(username=args.username, password=password, access=args.role)
|
||||
return User(username=args.username, password=password, access=args.role,
|
||||
packager_id=args.packager, key=args.key)
|
||||
|
@ -39,8 +39,7 @@ class Validate(Handler):
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -49,7 +48,6 @@ class Validate(Handler):
|
||||
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
|
||||
"""
|
||||
schema = Validate.schema(architecture, configuration)
|
||||
validator = Validator(configuration=configuration, schema=schema)
|
||||
@ -78,7 +76,9 @@ class Validate(Handler):
|
||||
|
||||
# create trigger loader instance
|
||||
loader = TriggerLoader()
|
||||
for trigger in loader.selected_triggers(configuration):
|
||||
triggers = loader.selected_triggers(configuration) + loader.known_triggers(configuration)
|
||||
|
||||
for trigger in set(triggers):
|
||||
try:
|
||||
trigger_class = loader.load_trigger_class(trigger)
|
||||
except ExtensionError:
|
||||
|
@ -42,8 +42,7 @@ class Versions(Handler):
|
||||
PEP423_PACKAGE_NAME = re.compile(r"^[A-Za-z0-9._-]+")
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -52,7 +51,6 @@ class Versions(Handler):
|
||||
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
|
||||
"""
|
||||
VersionPrinter(f"Module version {version.__version__}",
|
||||
{"Python": sys.version}).print(verbose=False, separator=" ")
|
||||
|
@ -19,6 +19,8 @@
|
||||
#
|
||||
import argparse
|
||||
|
||||
from collections.abc import Generator
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.spawn import Spawn
|
||||
@ -31,10 +33,10 @@ class Web(Handler):
|
||||
|
||||
ALLOW_AUTO_ARCHITECTURE_RUN = False
|
||||
ALLOW_MULTI_ARCHITECTURE_RUN = False # required to be able to spawn external processes
|
||||
COMMAND_ARGS_WHITELIST = ["force", "log_handler", ""]
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *,
|
||||
report: bool, unsafe: bool) -> None:
|
||||
def run(cls, args: argparse.Namespace, architecture: str, configuration: Configuration, *, report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
@ -43,12 +45,12 @@ class Web(Handler):
|
||||
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
|
||||
"""
|
||||
# we are using local import for optional dependencies
|
||||
from ahriman.web.web import run_server, setup_service
|
||||
|
||||
spawner = Spawn(args.parser(), architecture, configuration)
|
||||
spawner_args = Web.extract_arguments(args, architecture, configuration)
|
||||
spawner = Spawn(args.parser(), architecture, list(spawner_args))
|
||||
spawner.start()
|
||||
|
||||
application = setup_service(architecture, configuration, spawner)
|
||||
@ -57,3 +59,33 @@ class Web(Handler):
|
||||
# terminate spawn process at the last
|
||||
spawner.stop()
|
||||
spawner.join()
|
||||
|
||||
@staticmethod
|
||||
def extract_arguments(args: argparse.Namespace, architecture: str,
|
||||
configuration: Configuration) -> Generator[str, None, None]:
|
||||
"""
|
||||
extract list of arguments used for current command, except for command specific ones
|
||||
|
||||
Args:
|
||||
args(argparse.Namespace): command line args
|
||||
architecture(str): repository architecture
|
||||
configuration(Configuration): configuration instance
|
||||
|
||||
Returns:
|
||||
Generator[str, None, None]: command line arguments which were used for this specific command
|
||||
"""
|
||||
# read architecture from the same argument list
|
||||
yield from ["--architecture", architecture]
|
||||
# read configuration path from current settings
|
||||
if (configuration_path := configuration.path) is not None:
|
||||
yield from ["--configuration", str(configuration_path)]
|
||||
|
||||
# arguments from command line
|
||||
if args.force:
|
||||
yield "--force"
|
||||
if args.log_handler is not None:
|
||||
yield from ["--log-handler", args.log_handler.value]
|
||||
if args.quiet:
|
||||
yield "--quiet"
|
||||
if args.unsafe:
|
||||
yield "--unsafe"
|
||||
|
@ -86,6 +86,7 @@ class Lock(LazyLogging):
|
||||
check if current user is actually owner of ahriman root
|
||||
"""
|
||||
check_user(self.paths, unsafe=self.unsafe)
|
||||
self.paths.tree_create()
|
||||
|
||||
def clear(self) -> None:
|
||||
"""
|
||||
@ -116,7 +117,7 @@ class Lock(LazyLogging):
|
||||
1. Check user UID
|
||||
2. Check if there is lock file
|
||||
3. Check web status watcher status
|
||||
4. Create lock file
|
||||
4. Create lock file and directory tree
|
||||
5. Report to status page if enabled
|
||||
|
||||
Returns:
|
||||
|
@ -20,9 +20,9 @@
|
||||
import shutil
|
||||
|
||||
from collections.abc import Callable, Generator
|
||||
from functools import cached_property
|
||||
from pathlib import Path
|
||||
from pyalpm import DB, Handle, Package, SIG_PACKAGE, error as PyalpmError # type: ignore[import]
|
||||
from typing import Any
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.log import LazyLogging
|
||||
@ -34,13 +34,8 @@ from ahriman.models.repository_paths import RepositoryPaths
|
||||
class Pacman(LazyLogging):
|
||||
"""
|
||||
alpm wrapper
|
||||
|
||||
Attributes:
|
||||
handle(Handle): pyalpm root ``Handle``
|
||||
"""
|
||||
|
||||
handle: Handle
|
||||
|
||||
def __init__(self, architecture: str, configuration: Configuration, *,
|
||||
refresh_database: PacmanSynchronization) -> None:
|
||||
"""
|
||||
@ -84,6 +79,16 @@ class Pacman(LazyLogging):
|
||||
|
||||
return handle
|
||||
|
||||
@cached_property
|
||||
def handle(self) -> Handle:
|
||||
"""
|
||||
pyalpm handle
|
||||
|
||||
Returns:
|
||||
Handle: generated pyalpm handle instance
|
||||
"""
|
||||
return self.__create_handle_fn()
|
||||
|
||||
def database_copy(self, handle: Handle, database: DB, pacman_root: Path, paths: RepositoryPaths, *,
|
||||
use_ahriman_cache: bool) -> None:
|
||||
"""
|
||||
@ -184,22 +189,3 @@ class Pacman(LazyLogging):
|
||||
result.update(trim_package(provides) for provides in package.provides)
|
||||
|
||||
return result
|
||||
|
||||
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
|
||||
|
@ -115,7 +115,11 @@ class AUR(Remote):
|
||||
query[key] = value
|
||||
|
||||
try:
|
||||
response = requests.get(self.DEFAULT_RPC_URL, params=query, timeout=self.DEFAULT_TIMEOUT)
|
||||
response = requests.get(
|
||||
self.DEFAULT_RPC_URL,
|
||||
params=query,
|
||||
headers={"User-Agent": self.DEFAULT_USER_AGENT},
|
||||
timeout=self.DEFAULT_TIMEOUT)
|
||||
response.raise_for_status()
|
||||
return self.parse_response(response.json())
|
||||
except requests.HTTPError as e:
|
||||
|
@ -34,13 +34,15 @@ class Official(Remote):
|
||||
|
||||
Attributes:
|
||||
DEFAULT_ARCHLINUX_URL(str): (class attribute) default archlinux url
|
||||
DEFAULT_ARCHLINUX_GIT_URL(str): (class attribute) default url for git packages
|
||||
DEFAULT_SEARCH_REPOSITORIES(list[str]): (class attribute) default list of repositories to search
|
||||
DEFAULT_RPC_URL(str): (class attribute) default archlinux repositories RPC url
|
||||
DEFAULT_TIMEOUT(int): (class attribute) HTTP request timeout in seconds
|
||||
"""
|
||||
|
||||
DEFAULT_ARCHLINUX_GIT_URL = "https://gitlab.archlinux.org"
|
||||
DEFAULT_ARCHLINUX_URL = "https://archlinux.org"
|
||||
DEFAULT_SEARCH_REPOSITORIES = ["Core", "Extra", "Multilib", "Community"]
|
||||
DEFAULT_SEARCH_REPOSITORIES = ["Core", "Extra", "Multilib"]
|
||||
DEFAULT_RPC_URL = "https://archlinux.org/packages/search/json"
|
||||
DEFAULT_TIMEOUT = 30
|
||||
|
||||
@ -56,9 +58,7 @@ class Official(Remote):
|
||||
Returns:
|
||||
str: git url for the specific base
|
||||
"""
|
||||
if repository.lower() in ("core", "extra", "testing", "kde-unstable"):
|
||||
return "https://github.com/archlinux/svntogit-packages.git" # hardcoded, ok
|
||||
return "https://github.com/archlinux/svntogit-community.git"
|
||||
return f"{Official.DEFAULT_ARCHLINUX_GIT_URL}/archlinux/packaging/packages/{package_base}.git"
|
||||
|
||||
@classmethod
|
||||
def remote_web_url(cls, package_base: str) -> str:
|
||||
@ -106,6 +106,7 @@ class Official(Remote):
|
||||
response = requests.get(
|
||||
self.DEFAULT_RPC_URL,
|
||||
params={by: args, "repo": self.DEFAULT_SEARCH_REPOSITORIES},
|
||||
headers={"User-Agent": self.DEFAULT_USER_AGENT},
|
||||
timeout=self.DEFAULT_TIMEOUT)
|
||||
response.raise_for_status()
|
||||
return self.parse_response(response.json())
|
||||
|
@ -17,6 +17,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from ahriman import version
|
||||
from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.log import LazyLogging
|
||||
from ahriman.models.aur_package import AURPackage
|
||||
@ -26,6 +27,9 @@ class Remote(LazyLogging):
|
||||
"""
|
||||
base class for remote package search
|
||||
|
||||
Attributes:
|
||||
DEFAULT_USER_AGENT(str): (class attribute) default user agent
|
||||
|
||||
Examples:
|
||||
These classes are designed to be used without instancing. In order to achieve it several class methods are
|
||||
provided: ``info``, ``multisearch`` and ``search``. Thus, the basic flow is the following::
|
||||
@ -39,6 +43,8 @@ class Remote(LazyLogging):
|
||||
directly, whereas ``multisearch`` splits search one by one and finds intersection between search results.
|
||||
"""
|
||||
|
||||
DEFAULT_USER_AGENT = f"ahriman/{version.__version__}"
|
||||
|
||||
@classmethod
|
||||
def info(cls, package_name: str, *, pacman: Pacman) -> AURPackage:
|
||||
"""
|
||||
|
@ -125,6 +125,12 @@ class Sources(LazyLogging):
|
||||
Sources._check_output("git", "init", "--initial-branch", instance.DEFAULT_BRANCH,
|
||||
cwd=sources_dir, logger=instance.logger)
|
||||
|
||||
# extract local files...
|
||||
files = ["PKGBUILD", ".SRCINFO"] + [str(path) for path in Package.local_files(sources_dir)]
|
||||
instance.add(sources_dir, *files)
|
||||
# ...and commit them
|
||||
instance.commit(sources_dir, author="ahriman <ahriman@localhost>")
|
||||
|
||||
@staticmethod
|
||||
def load(sources_dir: Path, package: Package, patches: list[PkgbuildPatch], paths: RepositoryPaths) -> None:
|
||||
"""
|
||||
|
@ -59,12 +59,13 @@ class Task(LazyLogging):
|
||||
self.makepkg_flags = configuration.getlist("build", "makepkg_flags", fallback=[])
|
||||
self.makechrootpkg_flags = configuration.getlist("build", "makechrootpkg_flags", fallback=[])
|
||||
|
||||
def build(self, sources_dir: Path) -> list[Path]:
|
||||
def build(self, sources_dir: Path, packager: str | None = None) -> list[Path]:
|
||||
"""
|
||||
run package build
|
||||
|
||||
Args:
|
||||
sources_dir(Path): path to where sources are
|
||||
packager(str | None, optional): optional packager override (Default value = None)
|
||||
|
||||
Returns:
|
||||
list[Path]: paths of produced packages
|
||||
@ -75,12 +76,18 @@ class Task(LazyLogging):
|
||||
command.extend(["--"] + self.makepkg_flags)
|
||||
self.logger.info("using %s for %s", command, self.package.base)
|
||||
|
||||
environment: dict[str, str] = {}
|
||||
if packager is not None:
|
||||
environment["PACKAGER"] = packager
|
||||
self.logger.info("using environment variables %s", environment)
|
||||
|
||||
Task._check_output(
|
||||
*command,
|
||||
exception=BuildError(self.package.base),
|
||||
cwd=sources_dir,
|
||||
logger=self.logger,
|
||||
user=self.uid)
|
||||
user=self.uid,
|
||||
environment=environment)
|
||||
|
||||
# well it is not actually correct, but we can deal with it
|
||||
packages = Task._check_output(
|
||||
|
@ -38,6 +38,7 @@ class Configuration(configparser.RawConfigParser):
|
||||
Required by dump and merging functions
|
||||
SYSTEM_CONFIGURATION_PATH(Path): (class attribute) default system configuration path distributed by package
|
||||
architecture(str | None): repository architecture
|
||||
includes(list[Path]): list of includes which were read
|
||||
path(Path | None): path to root configuration file
|
||||
|
||||
Examples:
|
||||
@ -78,6 +79,7 @@ class Configuration(configparser.RawConfigParser):
|
||||
})
|
||||
self.architecture: str | None = None
|
||||
self.path: Path | None = None
|
||||
self.includes: list[Path] = []
|
||||
|
||||
@property
|
||||
def include(self) -> Path:
|
||||
@ -99,6 +101,16 @@ class Configuration(configparser.RawConfigParser):
|
||||
"""
|
||||
return self.getpath("settings", "logging")
|
||||
|
||||
@property
|
||||
def repository_name(self) -> str:
|
||||
"""
|
||||
repository name as defined by configuration
|
||||
|
||||
Returns:
|
||||
str: repository name from configuration
|
||||
"""
|
||||
return self.get("repository", "name")
|
||||
|
||||
@property
|
||||
def repository_paths(self) -> RepositoryPaths:
|
||||
"""
|
||||
@ -183,7 +195,7 @@ class Configuration(configparser.RawConfigParser):
|
||||
}
|
||||
|
||||
# pylint and mypy are too stupid to find these methods
|
||||
# pylint: disable=missing-function-docstring,multiple-statements,unused-argument
|
||||
# pylint: disable=missing-function-docstring,unused-argument
|
||||
def getlist(self, *args: Any, **kwargs: Any) -> list[str]: ... # type: ignore[empty-body]
|
||||
|
||||
def getpath(self, *args: Any, **kwargs: Any) -> Path: ... # type: ignore[empty-body]
|
||||
@ -233,11 +245,13 @@ class Configuration(configparser.RawConfigParser):
|
||||
"""
|
||||
load configuration includes
|
||||
"""
|
||||
self.includes = [] # reset state
|
||||
try:
|
||||
for path in sorted(self.include.glob("*.ini")):
|
||||
if path == self.logging_path:
|
||||
continue # we don't want to load logging explicitly
|
||||
self.read(path)
|
||||
self.includes.append(path)
|
||||
except (FileNotFoundError, configparser.NoOptionError, configparser.NoSectionError):
|
||||
pass
|
||||
|
||||
|
@ -163,6 +163,11 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = {
|
||||
"coerce": "list",
|
||||
"schema": {"type": "string"},
|
||||
},
|
||||
"triggers_known": {
|
||||
"type": "list",
|
||||
"coerce": "list",
|
||||
"schema": {"type": "string"},
|
||||
},
|
||||
"vcs_allowed_age": {
|
||||
"type": "integer",
|
||||
"coerce": "integer",
|
||||
@ -186,10 +191,6 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = {
|
||||
"sign": {
|
||||
"type": "dict",
|
||||
"allow_unknown": True,
|
||||
"keysrules": {
|
||||
"type": "string",
|
||||
"anyof_regex": ["^target$", "^key$", "^key_.*"],
|
||||
},
|
||||
"schema": {
|
||||
"target": {
|
||||
"type": "list",
|
||||
|
@ -144,6 +144,24 @@ class Validator(RootValidator):
|
||||
if constraint and url.scheme not in constraint:
|
||||
self._error(field, f"Url {value} scheme must be one of {constraint}")
|
||||
|
||||
def _validate_path_is_absolute(self, constraint: bool, field: str, value: Path) -> None:
|
||||
"""
|
||||
check if path is absolute or not
|
||||
|
||||
Args:
|
||||
constraint(bool): True in case if path must be absolute and False if it must be relative
|
||||
field(str): field name to be checked
|
||||
value(Path): value to be checked
|
||||
|
||||
Examples:
|
||||
The rule's arguments are validated against this schema:
|
||||
{"type": "boolean"}
|
||||
"""
|
||||
if constraint and not value.is_absolute():
|
||||
self._error(field, f"Path {value} must be absolute")
|
||||
if not constraint and value.is_absolute():
|
||||
self._error(field, f"Path {value} must be relative")
|
||||
|
||||
def _validate_path_exists(self, constraint: bool, field: str, value: Path) -> None:
|
||||
"""
|
||||
check if paths exists
|
||||
@ -159,3 +177,5 @@ class Validator(RootValidator):
|
||||
"""
|
||||
if constraint and not value.exists():
|
||||
self._error(field, f"Path {value} must exist")
|
||||
if not constraint and value.exists():
|
||||
self._error(field, f"Path {value} must not exist")
|
||||
|
80
src/ahriman/core/database/migrations/m007_check_depends.py
Normal file
80
src/ahriman/core/database/migrations/m007_check_depends.py
Normal file
@ -0,0 +1,80 @@
|
||||
#
|
||||
# Copyright (c) 2021-2023 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from sqlite3 import Connection
|
||||
|
||||
from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.util import package_like
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.pacman_synchronization import PacmanSynchronization
|
||||
|
||||
|
||||
__all__ = ["migrate_data", "steps"]
|
||||
|
||||
|
||||
steps = [
|
||||
"""
|
||||
alter table packages add column check_depends json
|
||||
""",
|
||||
]
|
||||
|
||||
|
||||
def migrate_data(connection: Connection, configuration: Configuration) -> None:
|
||||
"""
|
||||
perform data migration
|
||||
|
||||
Args:
|
||||
connection(Connection): database connection
|
||||
configuration(Configuration): configuration instance
|
||||
"""
|
||||
migrate_package_check_depends(connection, configuration)
|
||||
|
||||
|
||||
def migrate_package_check_depends(connection: Connection, configuration: Configuration) -> None:
|
||||
"""
|
||||
migrate package check depends fields
|
||||
|
||||
Args:
|
||||
connection(Connection): database connection
|
||||
configuration(Configuration): configuration instance
|
||||
"""
|
||||
if not configuration.repository_paths.repository.is_dir():
|
||||
return
|
||||
|
||||
_, architecture = configuration.check_loaded()
|
||||
pacman = Pacman(architecture, configuration, refresh_database=PacmanSynchronization.Disabled)
|
||||
|
||||
package_list = []
|
||||
for full_path in filter(package_like, configuration.repository_paths.repository.iterdir()):
|
||||
base = Package.from_archive(full_path, pacman, remote=None)
|
||||
for package, description in base.packages.items():
|
||||
package_list.append({
|
||||
"check_depends": description.check_depends,
|
||||
"package": package,
|
||||
})
|
||||
|
||||
connection.executemany(
|
||||
"""
|
||||
update packages set
|
||||
check_depends = :check_depends
|
||||
where package = :package
|
||||
""",
|
||||
package_list
|
||||
)
|
85
src/ahriman/core/database/migrations/m008_packagers.py
Normal file
85
src/ahriman/core/database/migrations/m008_packagers.py
Normal file
@ -0,0 +1,85 @@
|
||||
#
|
||||
# Copyright (c) 2021-2023 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from sqlite3 import Connection
|
||||
|
||||
from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.util import package_like
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.pacman_synchronization import PacmanSynchronization
|
||||
|
||||
|
||||
__all__ = ["migrate_data", "steps"]
|
||||
|
||||
|
||||
steps = [
|
||||
"""
|
||||
alter table users add column packager_id
|
||||
""",
|
||||
"""
|
||||
alter table users add column key_id
|
||||
""",
|
||||
"""
|
||||
alter table package_bases add column packager
|
||||
""",
|
||||
]
|
||||
|
||||
|
||||
def migrate_data(connection: Connection, configuration: Configuration) -> None:
|
||||
"""
|
||||
perform data migration
|
||||
|
||||
Args:
|
||||
connection(Connection): database connection
|
||||
configuration(Configuration): configuration instance
|
||||
"""
|
||||
migrate_package_base_packager(connection, configuration)
|
||||
|
||||
|
||||
def migrate_package_base_packager(connection: Connection, configuration: Configuration) -> None:
|
||||
"""
|
||||
migrate package packager field
|
||||
|
||||
Args:
|
||||
connection(Connection): database connection
|
||||
configuration(Configuration): configuration instance
|
||||
"""
|
||||
if not configuration.repository_paths.repository.is_dir():
|
||||
return
|
||||
|
||||
_, architecture = configuration.check_loaded()
|
||||
pacman = Pacman(architecture, configuration, refresh_database=PacmanSynchronization.Disabled)
|
||||
|
||||
package_list = []
|
||||
for full_path in filter(package_like, configuration.repository_paths.repository.iterdir()):
|
||||
package = Package.from_archive(full_path, pacman, remote=None)
|
||||
package_list.append({
|
||||
"package_base": package.base,
|
||||
"packager": package.packager,
|
||||
})
|
||||
|
||||
connection.executemany(
|
||||
"""
|
||||
update package_bases set
|
||||
packager = :packager
|
||||
where package_base = :package_base
|
||||
""",
|
||||
package_list
|
||||
)
|
@ -57,8 +57,9 @@ class AuthOperations(Operations):
|
||||
|
||||
def run(connection: Connection) -> list[User]:
|
||||
return [
|
||||
User(username=cursor["username"], password=cursor["password"], access=UserAccess(cursor["access"]))
|
||||
for cursor in connection.execute(
|
||||
User(username=row["username"], password=row["password"], access=UserAccess(row["access"]),
|
||||
packager_id=row["packager_id"], key=row["key_id"])
|
||||
for row in connection.execute(
|
||||
"""
|
||||
select * from users
|
||||
where (:username is null or username = :username) and (:access is null or access = :access)
|
||||
@ -91,12 +92,13 @@ class AuthOperations(Operations):
|
||||
connection.execute(
|
||||
"""
|
||||
insert into users
|
||||
(username, access, password)
|
||||
(username, access, password, packager_id, key_id)
|
||||
values
|
||||
(:username, :access, :password)
|
||||
(:username, :access, :password, :packager_id, :key_id)
|
||||
on conflict (username) do update set
|
||||
access = :access, password = :password
|
||||
access = :access, password = :password, packager_id = :packager_id, key_id = :key_id
|
||||
""",
|
||||
{"username": user.username.lower(), "access": user.access.value, "password": user.password})
|
||||
{"username": user.username.lower(), "access": user.access.value, "password": user.password,
|
||||
"packager_id": user.packager_id, "key_id": user.key})
|
||||
|
||||
self.with_connection(run, commit=True)
|
||||
|
@ -76,11 +76,12 @@ class PackageOperations(Operations):
|
||||
connection.execute(
|
||||
"""
|
||||
insert into package_bases
|
||||
(package_base, version, source, branch, git_url, path, web_url)
|
||||
(package_base, version, source, branch, git_url, path, web_url, packager)
|
||||
values
|
||||
(:package_base, :version, :source, :branch, :git_url, :path, :web_url)
|
||||
(:package_base, :version, :source, :branch, :git_url, :path, :web_url, :packager)
|
||||
on conflict (package_base) do update set
|
||||
version = :version, branch = :branch, git_url = :git_url, path = :path, web_url = :web_url, source = :source
|
||||
version = :version, branch = :branch, git_url = :git_url, path = :path, web_url = :web_url,
|
||||
source = :source, packager = :packager
|
||||
""",
|
||||
{
|
||||
"package_base": package.base,
|
||||
@ -90,6 +91,7 @@ class PackageOperations(Operations):
|
||||
"path": package.remote.path if package.remote is not None else None,
|
||||
"web_url": package.remote.web_url if package.remote is not None else None,
|
||||
"source": package.remote.source.value if package.remote is not None else None,
|
||||
"packager": package.packager,
|
||||
}
|
||||
)
|
||||
|
||||
@ -113,17 +115,17 @@ class PackageOperations(Operations):
|
||||
(package, package_base, architecture, archive_size,
|
||||
build_date, depends, description, filename,
|
||||
"groups", installed_size, licenses, provides,
|
||||
url, make_depends, opt_depends)
|
||||
url, make_depends, opt_depends, check_depends)
|
||||
values
|
||||
(:package, :package_base, :architecture, :archive_size,
|
||||
:build_date, :depends, :description, :filename,
|
||||
:groups, :installed_size, :licenses, :provides,
|
||||
:url, :make_depends, :opt_depends)
|
||||
:url, :make_depends, :opt_depends, :check_depends)
|
||||
on conflict (package, architecture) do update set
|
||||
package_base = :package_base, archive_size = :archive_size,
|
||||
build_date = :build_date, depends = :depends, description = :description, filename = :filename,
|
||||
"groups" = :groups, installed_size = :installed_size, licenses = :licenses, provides = :provides,
|
||||
url = :url, make_depends = :make_depends, opt_depends = :opt_depends
|
||||
url = :url, make_depends = :make_depends, opt_depends = :opt_depends, check_depends = :check_depends
|
||||
""",
|
||||
package_list)
|
||||
|
||||
@ -163,8 +165,9 @@ class PackageOperations(Operations):
|
||||
base=row["package_base"],
|
||||
version=row["version"],
|
||||
remote=RemoteSource.from_json(row),
|
||||
packages={})
|
||||
for row in connection.execute("""select * from package_bases""")
|
||||
packages={},
|
||||
packager=row["packager"] or None,
|
||||
) for row in connection.execute("""select * from package_bases""")
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
@ -77,8 +77,8 @@ class PatchOperations(Operations):
|
||||
"""
|
||||
def run(connection: Connection) -> list[tuple[str, PkgbuildPatch]]:
|
||||
return [
|
||||
(cursor["package_base"], PkgbuildPatch(cursor["variable"], cursor["patch"]))
|
||||
for cursor in connection.execute(
|
||||
(row["package_base"], PkgbuildPatch(row["variable"], row["patch"]))
|
||||
for row in connection.execute(
|
||||
"""select * from patches where :package_base is null or package_base = :package_base""",
|
||||
{"package_base": package_base})
|
||||
]
|
||||
|
@ -194,6 +194,18 @@ class PasswordError(ValueError):
|
||||
ValueError.__init__(self, f"Password error: {details}")
|
||||
|
||||
|
||||
class PkgbuildGeneratorError(RuntimeError):
|
||||
"""
|
||||
exception class for support type triggers
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""
|
||||
default constructor
|
||||
"""
|
||||
RuntimeError.__init__(self, "Could not generate package")
|
||||
|
||||
|
||||
class ReportError(RuntimeError):
|
||||
"""
|
||||
report generation exception
|
||||
|
@ -22,6 +22,7 @@ from ahriman.core.formatters.string_printer import StringPrinter
|
||||
|
||||
from ahriman.core.formatters.aur_printer import AurPrinter
|
||||
from ahriman.core.formatters.build_printer import BuildPrinter
|
||||
from ahriman.core.formatters.configuration_paths_printer import ConfigurationPathsPrinter
|
||||
from ahriman.core.formatters.configuration_printer import ConfigurationPrinter
|
||||
from ahriman.core.formatters.package_printer import PackagePrinter
|
||||
from ahriman.core.formatters.patch_printer import PatchPrinter
|
||||
|
52
src/ahriman/core/formatters/configuration_paths_printer.py
Normal file
52
src/ahriman/core/formatters/configuration_paths_printer.py
Normal file
@ -0,0 +1,52 @@
|
||||
#
|
||||
# Copyright (c) 2021-2023 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.core.formatters import StringPrinter
|
||||
from ahriman.models.property import Property
|
||||
|
||||
|
||||
class ConfigurationPathsPrinter(StringPrinter):
|
||||
"""
|
||||
print configuration paths
|
||||
|
||||
Attributes:
|
||||
includes(list[Path]): list of include files
|
||||
"""
|
||||
|
||||
def __init__(self, root: Path, includes: list[Path]) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
root(Path): path to root configuration file
|
||||
includes(list[Path]): list of include files
|
||||
"""
|
||||
StringPrinter.__init__(self, str(root))
|
||||
self.includes = includes
|
||||
|
||||
def properties(self) -> list[Property]:
|
||||
"""
|
||||
convert content into printable data
|
||||
|
||||
Returns:
|
||||
list[Property]: list of content properties
|
||||
"""
|
||||
return [Property("Include", str(path), is_required=True) for path in self.includes]
|
@ -27,6 +27,7 @@ from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.exceptions import GitRemoteError
|
||||
from ahriman.core.log import LazyLogging
|
||||
from ahriman.core.util import walk
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.package_source import PackageSource
|
||||
from ahriman.models.remote_source import RemoteSource
|
||||
|
||||
@ -36,16 +37,18 @@ class RemotePull(LazyLogging):
|
||||
fetch PKGBUILDs from remote repository and use them for following actions
|
||||
|
||||
Attributes:
|
||||
architecture(str): repository architecture
|
||||
remote_source(RemoteSource): repository remote source (remote pull url and branch)
|
||||
repository_paths(RepositoryPaths): repository paths instance
|
||||
"""
|
||||
|
||||
def __init__(self, configuration: Configuration, section: str) -> None:
|
||||
def __init__(self, configuration: Configuration, architecture: str, section: str) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
architecture(str): repository architecture
|
||||
section(str): settings section name
|
||||
"""
|
||||
self.remote_source = RemoteSource(
|
||||
@ -55,8 +58,30 @@ class RemotePull(LazyLogging):
|
||||
branch=configuration.get(section, "pull_branch", fallback="master"),
|
||||
source=PackageSource.Local,
|
||||
)
|
||||
self.architecture = architecture
|
||||
self.repository_paths = configuration.repository_paths
|
||||
|
||||
def package_copy(self, pkgbuild_path: Path) -> None:
|
||||
"""
|
||||
copy single PKGBUILD content to the repository tree
|
||||
|
||||
Args:
|
||||
pkgbuild_path(Path): path to PKGBUILD to copy
|
||||
"""
|
||||
cloned_pkgbuild_dir = pkgbuild_path.parent
|
||||
|
||||
# load package from the PKGBUILD, because it might be possible that name doesn't match
|
||||
# e.g. if we have just cloned repo with just one PKGBUILD
|
||||
package = Package.from_build(cloned_pkgbuild_dir, self.architecture, None)
|
||||
package_base = package.base
|
||||
local_pkgbuild_dir = self.repository_paths.cache_for(package_base)
|
||||
|
||||
# copy source ignoring the git files
|
||||
shutil.copytree(cloned_pkgbuild_dir, local_pkgbuild_dir,
|
||||
ignore=shutil.ignore_patterns(".git*"), dirs_exist_ok=True)
|
||||
# initialized git repository is required for local sources
|
||||
Sources.init(local_pkgbuild_dir)
|
||||
|
||||
def repo_clone(self) -> None:
|
||||
"""
|
||||
clone repository from remote source
|
||||
@ -74,11 +99,7 @@ class RemotePull(LazyLogging):
|
||||
clone_dir(Path): path to temporary cloned directory
|
||||
"""
|
||||
for pkgbuild_path in filter(lambda path: path.name == "PKGBUILD", walk(clone_dir)):
|
||||
cloned_pkgbuild_dir = pkgbuild_path.parent
|
||||
package_base = cloned_pkgbuild_dir.name
|
||||
local_pkgbuild_dir = self.repository_paths.cache_for(package_base)
|
||||
shutil.copytree(cloned_pkgbuild_dir, local_pkgbuild_dir, dirs_exist_ok=True)
|
||||
Sources.init(local_pkgbuild_dir) # initialized git repository is required for local sources
|
||||
self.package_copy(pkgbuild_path)
|
||||
|
||||
def run(self) -> None:
|
||||
"""
|
||||
|
@ -87,5 +87,5 @@ class RemotePullTrigger(Trigger):
|
||||
for target in self.targets:
|
||||
section, _ = self.configuration.gettype(
|
||||
target, self.architecture, fallback=self.CONFIGURATION_SCHEMA_FALLBACK)
|
||||
runner = RemotePull(self.configuration, section)
|
||||
runner = RemotePull(self.configuration, self.architecture, section)
|
||||
runner.run()
|
||||
|
@ -44,13 +44,13 @@ class RemotePush(LazyLogging):
|
||||
remote_source(RemoteSource): repository remote source (remote pull url and branch)
|
||||
"""
|
||||
|
||||
def __init__(self, configuration: Configuration, database: SQLite, section: str) -> None:
|
||||
def __init__(self, database: SQLite, configuration: Configuration, section: str) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
database(SQLite): database instance
|
||||
configuration(Configuration): configuration instance
|
||||
section(str): settings section name
|
||||
"""
|
||||
self.database = database
|
||||
@ -79,6 +79,7 @@ class RemotePush(LazyLogging):
|
||||
package_target_dir = target_dir / package.base
|
||||
shutil.rmtree(package_target_dir, ignore_errors=True)
|
||||
# ...secondly, we clone whole tree...
|
||||
# fetch is used intentionally here in order to avoid copying downloaded blobs
|
||||
Sources.fetch(package_target_dir, package.remote)
|
||||
# ...and last, but not least, we remove the dot-git directory...
|
||||
for git_file in package_target_dir.glob(".git*"):
|
||||
|
@ -105,5 +105,5 @@ class RemotePushTrigger(Trigger):
|
||||
for target in self.targets:
|
||||
section, _ = self.configuration.gettype(
|
||||
target, self.architecture, fallback=self.CONFIGURATION_SCHEMA_FALLBACK)
|
||||
runner = RemotePush(self.configuration, database, section)
|
||||
runner = RemotePush(database, self.configuration, section)
|
||||
runner.run(result)
|
||||
|
47
src/ahriman/core/log/journal_handler.py
Normal file
47
src/ahriman/core/log/journal_handler.py
Normal file
@ -0,0 +1,47 @@
|
||||
#
|
||||
# Copyright (c) 2021-2023 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from logging import NullHandler
|
||||
from typing import Any
|
||||
|
||||
|
||||
__all__ = ["JournalHandler"]
|
||||
|
||||
|
||||
class _JournalHandler(NullHandler):
|
||||
"""
|
||||
wrapper for unexpected args and kwargs
|
||||
"""
|
||||
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
*args(Any): positional arguments
|
||||
**kwargs(Any): keyword arguments
|
||||
"""
|
||||
NullHandler.__init__(self)
|
||||
del args, kwargs
|
||||
|
||||
|
||||
try:
|
||||
from systemd.journal import JournalHandler # type: ignore[import]
|
||||
except ImportError:
|
||||
JournalHandler = _JournalHandler
|
@ -21,18 +21,24 @@ import contextlib
|
||||
import logging
|
||||
|
||||
from collections.abc import Generator
|
||||
from functools import cached_property
|
||||
from typing import Any
|
||||
|
||||
|
||||
class LazyLogging:
|
||||
"""
|
||||
wrapper for the logger library inspired by scala lazy logging module
|
||||
|
||||
Attributes:
|
||||
logger(logging.Logger): class logger instance
|
||||
"""
|
||||
|
||||
logger: logging.Logger
|
||||
@cached_property
|
||||
def logger(self) -> logging.Logger:
|
||||
"""
|
||||
get class logger instance
|
||||
|
||||
Returns:
|
||||
logging.Logger: class logger instance
|
||||
"""
|
||||
return logging.getLogger(self.logger_name)
|
||||
|
||||
@property
|
||||
def logger_name(self) -> str:
|
||||
@ -89,22 +95,3 @@ class LazyLogging:
|
||||
yield
|
||||
finally:
|
||||
self._package_logger_reset()
|
||||
|
||||
def __getattr__(self, item: str) -> Any:
|
||||
"""
|
||||
logger extractor
|
||||
|
||||
Args:
|
||||
item(str): property name
|
||||
|
||||
Returns:
|
||||
Any: attribute by its name
|
||||
|
||||
Raises:
|
||||
AttributeError: in case if no such attribute found
|
||||
"""
|
||||
if item == "logger":
|
||||
logger = logging.getLogger(self.logger_name)
|
||||
setattr(self, item, logger)
|
||||
return logger
|
||||
raise AttributeError(f"'{self.__class__.__qualname__}' object has no attribute '{item}'")
|
||||
|
@ -20,9 +20,11 @@
|
||||
import logging
|
||||
|
||||
from logging.config import fileConfig
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.log.http_log_handler import HttpLogHandler
|
||||
from ahriman.models.log_handler import LogHandler
|
||||
|
||||
|
||||
class Log:
|
||||
@ -32,24 +34,65 @@ class Log:
|
||||
Attributes:
|
||||
DEFAULT_LOG_FORMAT(str): (class attribute) default log format (in case of fallback)
|
||||
DEFAULT_LOG_LEVEL(int): (class attribute) default log level (in case of fallback)
|
||||
DEFAULT_SYSLOG_DEVICE(Path): (class attribute) default path to syslog device
|
||||
"""
|
||||
|
||||
DEFAULT_LOG_FORMAT = "[%(levelname)s %(asctime)s] [%(filename)s:%(lineno)d %(funcName)s]: %(message)s"
|
||||
DEFAULT_LOG_LEVEL = logging.DEBUG
|
||||
DEFAULT_SYSLOG_DEVICE = Path("/dev") / "log"
|
||||
|
||||
@staticmethod
|
||||
def load(configuration: Configuration, *, quiet: bool, report: bool) -> None:
|
||||
def handler(selected: LogHandler | None) -> LogHandler:
|
||||
"""
|
||||
try to guess default log handler. In case if ``selected`` is set, it will return specified value with appended
|
||||
_handler suffix. Otherwise, it will try to import journald handler and returns ``journald_handler`` if library
|
||||
is available. Otherwise, it will check if there is ``/dev/log`` device and returns ``syslog_handler`` in this
|
||||
case. And, finally, it will fall back to ``console_handler`` if none were found
|
||||
|
||||
Args:
|
||||
selected(LogHandler | None): user specified handler if any
|
||||
|
||||
Returns:
|
||||
LogHandler: selected log handler
|
||||
"""
|
||||
if selected is not None:
|
||||
return selected
|
||||
|
||||
try:
|
||||
from systemd.journal import JournalHandler # type: ignore[import]
|
||||
del JournalHandler
|
||||
return LogHandler.Journald # journald import was found
|
||||
except ImportError:
|
||||
if Log.DEFAULT_SYSLOG_DEVICE.exists():
|
||||
return LogHandler.Syslog
|
||||
return LogHandler.Console
|
||||
|
||||
@staticmethod
|
||||
def load(configuration: Configuration, handler: LogHandler, *, quiet: bool, report: bool) -> None:
|
||||
"""
|
||||
setup logging settings from configuration
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
handler(LogHandler): selected default log handler, which will be used if no handlers were set
|
||||
quiet(bool): force disable any log messages
|
||||
report(bool): force enable or disable reporting
|
||||
"""
|
||||
default_handler = f"{handler.value}_handler"
|
||||
|
||||
try:
|
||||
path = configuration.logging_path
|
||||
fileConfig(path)
|
||||
log_configuration = Configuration()
|
||||
log_configuration.read(configuration.logging_path)
|
||||
|
||||
# set handlers if they are not set
|
||||
for section in filter(lambda s: s.startswith("logger_"), log_configuration.sections()):
|
||||
if "handlers" in log_configuration[section]:
|
||||
continue
|
||||
log_configuration.set_option(section, "handlers", default_handler)
|
||||
|
||||
# load logging configuration
|
||||
fileConfig(log_configuration, disable_existing_loggers=True)
|
||||
logging.debug("using %s logger", default_handler)
|
||||
except Exception:
|
||||
logging.basicConfig(filename=None, format=Log.DEFAULT_LOG_FORMAT,
|
||||
level=Log.DEFAULT_LOG_LEVEL)
|
||||
|
@ -57,4 +57,4 @@ class HTML(Report, JinjaTemplate):
|
||||
result(Result): build result
|
||||
"""
|
||||
html = self.make_html(Result(success=packages), self.template_path)
|
||||
self.report_path.write_text(html)
|
||||
self.report_path.write_text(html, encoding="utf8")
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user