Compare commits

..

704 Commits

Author SHA1 Message Date
d283dccc1e type: update for new cors release 2025-03-17 13:56:59 +02:00
8a4e900ab9 docs: update docs
This commit includes following changes
* add newly added option to configuration referenec
* remove few legacy options from configuration schemas used for
  validation, which might lead to errors during validation.
  Note, however, that settings will be still read by the service
* add link to aurcache
* hide service-setup command description under spoiler
2025-03-17 13:43:04 +02:00
fa6cf8ce36 website: use date instead of version for listing logs
website: make dropdown from logs versions to add some space
2025-03-13 15:45:31 +02:00
a706fbb751 bug: handle dependencies iteratively (fix #141)
It has been found that if there are missing dependencies than whole
process will break instead of just skipping packages. During package
addition it is fine-ish, but it will break updates run
2025-03-13 15:45:27 +02:00
9a23f5c79d refactor: streamline migrations 2025-03-09 23:22:24 +02:00
aaab9069bf docs: rebuild indices 2025-03-09 15:43:41 +02:00
f00b575641 type: use ClassVar decorator for class attributes 2025-03-09 15:43:27 +02:00
6f57ed550b
feat: refine log system (#142)
* refine package logging

* add interface

* revert version selection

* replace tuple with model

* rename column in logs table, add coverters

* generate process identifier for child proocesses
2025-03-09 14:46:33 +02:00
08640d9108 feat: add dashboard (#139) 2025-02-24 00:10:15 +02:00
65324633b4 feat: add counters to repository stats overview 2025-02-24 00:10:15 +02:00
ed67898012 fix: parse non-utf pkgbuilds as well (#140)
it has been reported that duriing reading pkgbuilds with latin-1 charset
the execption will be raised. Well, it is one more point to rewrite
parser to use own impl instead of shlex and parse raw byte array instead
2025-02-24 00:10:15 +02:00
a1a8dd68e8 type: remove unused ignore directive 2025-02-24 00:10:15 +02:00
a9505386c2 fix: force dry run build on task initialization for VCS packages
Previously if package is VCS and version in PKGBUILD doesn't match to
AUR one, then makepkg will update pkgbuild ignoring all previous pkgrel
patches

With this change during task init dry ryn process is always run for vcs
packages
2025-02-24 00:10:15 +02:00
a07b20bf50 Release 2.17.1 2025-01-06 01:14:28 +02:00
ed70897c39 fix: suppress traceback in shell if no ipython installed
Old implementation was showing import error, new implementation instead
hides it behind separated call and if-else check
2025-01-06 01:07:13 +02:00
0423c3e67c Release 2.17.0 2024-12-29 18:07:23 +02:00
571f62327f build: remove unused line from dockerfile 2024-12-24 16:49:30 +02:00
286ff4bcef fix: update packages properties after rebuild
This case leads to issue when it is impossible to update list of
implicit dependencies correctly in case of multi-packages
2024-12-24 15:13:18 +02:00
0660c33de3 chore: copyright update 2024-12-23 16:03:26 +02:00
c8421e97ee fix: fix pkgbuild parsing in case if comment mark is followed by token
without whitespaces

In this case, the next line was ignored
2024-12-23 15:55:07 +02:00
bc2288afc1 fix: suppress codefactor warning 2024-12-23 01:52:23 +02:00
503c8b0355
feat: make apispec dependency optional (#138) 2024-12-22 20:33:31 +02:00
6738f9206d type: remove unused typeguard 2024-12-21 17:02:09 +02:00
f865e998b0 feat: add link to logo 2024-12-19 12:47:17 +02:00
4880ca4fee feat: use IPython shell if available 2024-12-18 15:41:36 +02:00
56114ecc1e Release 2.16.0 2024-12-01 21:05:56 +02:00
57ab3ffb8f build: fix tox release target 2024-12-01 21:04:47 +02:00
8b08bfe3b4 ci: create regress job 2024-12-01 17:45:20 +02:00
e34356989d fix: invalid call in package-status-update subcommand 2024-12-01 17:37:12 +02:00
7c7804a9f4 build: allow to execute command from container from entrypoint 2024-11-29 16:17:45 +02:00
c4a56f1454 ci: add daily job 2024-11-26 11:55:08 +02:00
1caed156ad docs: add description about privileged and non--privileged container 2024-11-24 23:52:49 +02:00
45a620c40b fix: process list patch values in http requests
This commit parses values from post request as well as always serializes
values for the web interface
2024-11-22 17:22:37 +02:00
3c1fdec0e9 fix: serialize patches inside double quotes if there are variables inside (#137)
Old behaviour leads to variable to be serialized always in single quotes
(if shlex decides to quote it). It doesn't allow to expand variables during execution,
so those values should be put inside double quotes instead. This commit
checks if there is sign char in the variable and quotes manually,
otherwise returning shlex call
2024-11-19 14:39:48 +02:00
f5d7085325 fix: correctly serialize patches from database (#137)
If value is stored as array in database it is serialized as json, but
read as normal string, which lead to innability to use list patches

This fix also removes any postprocessing (unquoting) for functions
2024-11-19 02:42:28 +02:00
0cc35e70e3 build: docker image generation improvements
There are two major changes here. First of all, the image generation now
consist of two separated stages, the build itself and the production
image generation. Secondly, the packages inside image are now installed
as they were at the time of the root image generation (defined by stat
command)

Another side change is that container does not longer ship syncronized
(and out-of-dated) pacman databases; they have to be synced manually
2024-11-15 17:07:37 +02:00
f09082dff2 fix: fix parsing pkgbuild in case if comment starts with multiple sharps (#136) 2024-11-13 17:56:27 +02:00
8d53a59a6a feat: notify users about outdated password hashes used 2024-11-13 16:18:44 +02:00
20e7ba3b1d style: fix some typos and warnings 2024-11-11 18:07:13 +02:00
4b5a645f8d docs: architecture doc update 2024-11-10 16:19:22 +02:00
6a3c16a646 build: move dockerfile to docker directory 2024-11-06 17:18:31 +02:00
93ce7f9a51
feat: use split packages (#135)
* move argument parsers to handlers themselves

* use hatchling instead of flit

* Revert "use hatchling instead of flit"

This reverts commit d18d146d79.

* add package-splitt script

* replace simplify walk method

* split packages

* explicitly install packages

* separate support triggers from main package

* add docs examples

* sort actions

* docs update

* add metapackage

* review fixes
2024-11-01 16:07:04 +02:00
6fe77eb465 test: remove duplicated descriptions from tests 2024-10-24 01:22:16 +03:00
7c6c24a46d feat: allow append list options 2024-10-24 01:22:16 +03:00
f48993ccd5 build: update aur packages list for docker image build 2024-10-07 16:03:23 +03:00
22600a9eac chore: contributing guide update 2024-10-06 15:06:22 +03:00
b167df904b build: use tool.flit.external-data to distribute data 2024-10-05 17:17:16 +03:00
cd0ac7a7bd chore: replace passlib with bcrypt
passlib uses deprecated crypt module which is deprecated and scheduled
for removal in 3.13. Unfortunately, this module seems to be
unmaintained, so this commit replaces passlib with bcrypt, unfortunately
breaking current passwords
2024-10-05 16:35:27 +03:00
910d178c71 docs: replace svg with dot 2024-09-30 14:48:21 +03:00
1e7d4daf18 feat: add package copy subcommand 2024-09-27 17:23:04 +03:00
7bc4810377 fix: change category for dependencies api docs 2024-09-27 14:43:05 +03:00
aa66e76db7 feat: show implicit dependencies for packages 2024-09-27 14:41:45 +03:00
e0f9e38f44 Release 2.15.2 2024-09-26 16:58:19 +03:00
d6cdb5bea5 fix: fix pkgbuild parsing in some cases
It has been found that there are two cases in which pkgbuild was not
parsed correctly

1. Major case in which there is quotation mark inside comment line,
   which would cause ValueError: No closing quotation error
2. Minor case, if there are utf symbols in pkgbuild file (e.g.
   hieroglyphs, see ttf-google-fonts-git), it will case incorrect
   reading in `_is_escaped` method
2024-09-26 16:48:38 +03:00
6d157ca809 fix: do not copy own database during pyalpm initialization
Previous implementation lead to warning in logs in case if the
repository itself wasn't configured on the host
2024-09-25 14:31:32 +03:00
5486ae4a19 fix: suppress info logging during version check 2024-09-25 14:23:53 +03:00
8bdf420cdc feat: suppress info log during vcs version calculation 2024-09-25 07:15:51 +03:00
2deca6d715 refactor: even further improvements for Handler.check_status method 2024-09-25 07:15:51 +03:00
180adf3f33 type: remove unused ignore comment 2024-09-25 07:15:51 +03:00
634054926d docs: improve application help messages 2024-09-24 17:58:08 +03:00
53baaac61e Release 2.15.1 2024-09-24 11:18:38 +03:00
d2a93a94e3 feat: enable changes calculation in unit 2024-09-24 11:01:37 +03:00
7134aea125 refactor: rename Handler.check_if_empty to check_status 2024-09-24 01:36:33 +03:00
740d537618 fix: bump pkgrel if the local version is newer than remote
In case of VCS packages, if PKGBUILD contains older version, the pkgrel
remains the same during the rebuild process. This fix bumps pkgrel in
any case if the local version is newer than the remote
2024-09-23 16:30:33 +03:00
9f78e79f1f build: reduce docker image size 2024-09-23 14:37:36 +03:00
09456141f5 docs: update web preview picture 2024-09-23 14:03:12 +03:00
9e30e98e90 fix: allow colon in options interpolation 2024-09-23 13:52:49 +03:00
df2e98a1d3 Release 2.15.0 2024-09-23 03:32:01 +03:00
24993047c6 build: speedup pacman 2024-09-23 03:30:17 +03:00
b20e844cc9 website: add logo to api docs 2024-09-23 02:39:54 +03:00
ce75ccb405 docs: update configuration references in docs 2024-09-22 15:16:34 +03:00
1acff852d0 docs: add logo 2024-09-22 14:21:01 +03:00
62320e8ec6 feat: drop explicit makepkg usage (#134)
* generate filenames without using makepkg

* pkgbuild parser impl

* completely remove makepkg calls

* simplify typed get

* try to improve parser

* docs and recipes updatte

* never raise keyerror instead return empty string

* udpate tests

* add support of array expansion

* docs update

* tests update

* handle quoted control sequences correctly

* expand bash

* allow packages without package function

* docs update

* add moroe tests

* small improovements

* support escaped arrays and functions
2024-09-21 03:57:22 +03:00
1089bab526 type: ignore too-many-positional-arguments 2024-09-20 23:22:33 +03:00
0e0012a6e0 chore: refresh icons 2024-09-20 03:29:18 +03:00
fbbb80d091 Revert "fix: update Repo.init to the latest pacman release"
This reverts commit 99ca0cb2fd.
2024-09-20 01:48:09 +03:00
5316427371 fix: limit amount of fetches used for changes
The issue appears in case if - somehow - unknown commit sha has been
stored. In this scenario it would try to fetch infinitely
2024-09-20 01:48:03 +03:00
0fa748f302 feat: calculate changes on package addition as well 2024-09-20 01:48:03 +03:00
7a3d32dcfa fix: do not treat cached vcs packages as local 2024-09-20 01:47:58 +03:00
a396126a79 feat: calculate and store changes for each update 2024-09-17 15:01:45 +03:00
9785835c0e docs: improve class init docs 2024-09-15 15:13:54 +03:00
c4f4e37731 feat: get rid of jquery (#133) 2024-09-05 02:26:52 +03:00
f43ee2fd1d build: make cerberus dependency optional 2024-09-04 22:28:25 +03:00
f7a50e5294 feat: implement stats subcommand (#132) 2024-09-04 22:28:25 +03:00
ddd3c3f06f feat: allow filter events by timestamp 2024-09-04 22:28:25 +03:00
242f3d4d34 chore: add rss generation to samples 2024-09-04 22:28:25 +03:00
303f9ff03c feat: add event log and update chart to package info modal 2024-09-04 22:28:25 +03:00
65fac09d8d feat: remove duplicates from the toast 2024-09-04 22:28:25 +03:00
aaf7adbac1 refactor: simplify Validator class 2024-09-04 22:28:25 +03:00
9e011990ee feat: allow cross reference in the configuration (#131) 2024-09-04 22:28:25 +03:00
529d4caa0e feat: implement rss generation (#130) 2024-09-04 22:28:25 +03:00
d7c4fccf98 feat: add ability to log sql statements 2024-09-04 22:28:25 +03:00
1e30838be4 feat: serve logs and events from the newest to oldest, but keep the
ordering

So basically initial implementation, with limit=1, would emit the oldest
record in series. New implementation will return the most recent one
instead

The response is still sorted by ascension
2024-09-04 22:28:25 +03:00
d57276f214 feat: log package update events 2024-09-04 22:28:25 +03:00
31e59df2c8 refactor: allow event to receive keyword arguments
This change also replaces the dataclass implementation of the class to
custom one
2024-09-04 22:28:25 +03:00
23cd843e44 feat: add timer for metrics purposes 2024-09-04 22:28:25 +03:00
c08a292070 docs: update booleans in docs 2024-09-04 22:28:25 +03:00
5163aa4dca feat: implement audit log tables and methods (#129) 2024-09-04 22:28:25 +03:00
69f0966ff1 feat: replace scan paths options to single one
It has been found that previous system didn't allow to configure
specific cases (e.g. a whitelisted directory inside /usr/lib/cmake). The
current solution replaces two options to single one, which also allows a
regular expressions

Also PackageArchive class has been moved to core package, because it is
more about service rather than model
2024-09-04 22:25:54 +03:00
16308dc3ae Release 2.14.1 2024-09-04 22:01:04 +03:00
962599e937 bug: fix removal of the packages
It has been broken since reporter improvements, because it effectivelly
1) didn't call remove functions in database
2) used empty repository identifier for web service

With those changes it also raises exception when you try to call id on
empty identifier
2024-09-04 21:50:33 +03:00
758a81e3db chore: small contributing guide update 2024-09-04 21:49:31 +03:00
84942e3c98 refactor: fix some IDE warnings 2024-09-04 21:49:31 +03:00
6f8b1509d7 build: update pytest configuration to suppress deprecation warnings 2024-09-04 21:49:31 +03:00
b4372ff583 Release 2.14.0 2024-08-23 14:37:05 +03:00
41fc7bffbb docs: improve waiter classes docs 2024-08-23 14:33:07 +03:00
300f5026c4 feat: add ability to suppress git hints
It can be done by setting options in command. The commit author/email is
also now using this logic
2024-08-23 14:33:07 +03:00
10aa91a033 feat: add blacklisted paths to implicit dependencies processing
It has been found that in some cases additional packages have been added
as dependencies, like usr/share/applications, usr/lib/cmake, etc

This commit adds an ability to blacklist specific paths from processing
2024-08-23 14:33:07 +03:00
4169851eaa docs: split faq into multiple files 2024-08-20 16:44:40 +03:00
4d9e06156d feat: add support of pam authentication
Add naive implementation of user password check by calling su command.
Also change some authentication method to require username to be string
instead of optional string
2024-08-20 16:44:40 +03:00
af2269c64a fix: print current and updated version correctly
The issue appears in case if versions ar the same (e.g. rebuild); in
this case printer doesn't increment version as builder does.

Also util has been renamed to utils, keeping backward compatibiltiy
2024-08-16 16:24:11 +03:00
f44fa19c42 feat: optimize archive reading
Instead of trying to load every database and look for files, this commit
introduces the optimization in which, the service loads packages first,
groups them by database and load files later.

In some cases it significantly descreases times for loading files
2024-08-14 17:07:10 +03:00
fd3c6343f1 fix: explicitly process list of packages
Small workaround to remove debug packages from being processed
2024-08-14 17:07:10 +03:00
9edff2826f fix: remove trailit slash when loading packages files from a database 2024-08-14 17:07:10 +03:00
b38ecfb35c fix: skip debug packages as well 2024-08-14 17:07:10 +03:00
3c7c748b4a docs: update documentation for implicit dependencies resolution 2024-08-14 17:07:10 +03:00
434057ec49 feat: remove excess dependencies leaves (#128)
This mr improves implicit dependencies processing by reducing tree leaves by using the following algorithm:

* remove paths which belong to any base package
* remove packages which are (opt)dependencies of one of the package which provides same path. It also tries to handle circular dependencies by excluding them from being "satisfied"
* remove packages which are already satisfied by any children path
2024-08-14 17:07:10 +03:00
a01b090c2b feat: improve lock mechanisms
* improve lock mechanisms

* use /run/ahriman for sockett

* better water
2024-08-14 17:07:10 +03:00
8ffc1299f0 feat: implement local reporter mode (#126)
* implement local reporter mode

* simplify watcher class

* review changes

* do not update unknown status

* allow empty key patches via api

* fix some pylint warnings in tests
2024-08-14 17:07:10 +03:00
02b13de7f4 feat: allow to use simplified keys for context
Initial implementation requires explicit context key name to be set.
Though it is still useful sometimes (e.g. if there should be two
variables with the same type), in the most used scenarios internally
only type is required. This commit extends set and get methods to allow
to construct ContextKey from type directly

Also it breaks old keys, since - in order to reduce amount of possible
mistakes - internal classes uses this generation method
2024-08-14 17:07:10 +03:00
50a045434d feat: add abillity to check broken dependencies (#122)
* implement elf dynamic linking check

* load local database too in pacman wrapper
2024-08-14 17:07:10 +03:00
7bbe3242d4 type: drop MiddlewareType in favour of Middleware builtin 2024-08-14 17:07:10 +03:00
a9cb357182 type: fix mypy warn for fresh unixsocket release 2024-08-14 17:07:10 +03:00
feec9141b2 type: remove another unused mypy directive 2024-08-14 17:07:10 +03:00
148ef09e70 build: use requests-unixsocket2 fork
Since requests-2.32.0, the http+unix url scheme is brokek, check
https://github.com/msabramo/requests-unixsocket/issues/73 for more
details
2024-08-14 17:07:10 +03:00
5ff635db70 Release 2.13.8 2024-05-12 11:53:19 +03:00
9df5820bce fix: drop integrity check for javascript
It has been added to improve security, however, it changes over time for
no reason ¯\_(ツ)_/¯ I guess either cdn was hacked or fuck js
2024-05-12 11:49:12 +03:00
b7d3493ae3 Release 2.13.7 2024-05-09 13:26:40 +03:00
f8b725d175 fix: parse array variable from command 2024-05-09 13:21:42 +03:00
46b3c82aca Release 2.13.6 2024-05-05 21:59:30 +03:00
0d34432c9a fix: update integrity checksums for momentjs and daterangepicker 2024-05-05 21:17:30 +03:00
3cd9cff4ee refactor: update code to the latest python (3.12+) 2024-05-05 21:17:30 +03:00
9e02d7a38f fix: remove debug packages together with normal ones (#124) 2024-05-05 21:17:30 +03:00
9819ed761e Release 2.13.5 2024-04-04 13:33:03 +03:00
99ca0cb2fd fix: update Repo.init to the latest pacman release 2024-04-04 13:16:05 +03:00
ea3cb6e766 build: install base-devel package 2024-04-04 13:16:03 +03:00
0ae4941321 fix: lazy web component initialization
In some cases (probably slow internet) in place initialization can cause
exception, because elements are not available yet. This commit moves
events initialization to $()
2024-04-04 13:14:17 +03:00
855b55237b feat: add ability to disable debug packages distribution
The feature is implemented as supplying !debug option to makepkg when
generating package list. In this case debug packages still will be
built, however, they will not be added to the repository
2024-04-04 13:14:17 +03:00
59d14665a5 docs: update docs 2024-02-10 03:12:09 +02:00
414eb93b1e Release 2.13.4 2024-02-09 17:47:01 +02:00
14721913a4 fix: return only built packages from task
Since the last updates makepkg --packagelist also adds debug packages
which causes errors
2024-02-09 17:37:50 +02:00
f68e48fb47 refactor: rename packages http methods to own package
docs: update docs import
2024-01-22 02:20:11 +02:00
77cceb4c10 Release 2.13.3 2024-01-13 01:24:30 +02:00
eca22fdaed fix: replace logo and name in title to just icon 2024-01-12 01:25:46 +02:00
719af3676e Release 2.13.2 2024-01-08 22:48:55 +02:00
6c63ad6df5 fix: report only unique result entries
since builder intro the triggers are called with merged result, thus it
would lead to duplicated callouts
2024-01-08 22:46:42 +02:00
497a115535 Release 2.13.1 2024-01-08 21:17:35 +02:00
91598951c5 fix: do not raise 404 in case of unknown package on patches endpoints
Previous improvements raise 404 error in case if no packages were found
for patches endpoints. However, in case of multirepo setup this feature
doesn't work properly because package can be located in any other
repository different from default
2024-01-08 14:32:40 +02:00
f364e00bea build: pass ssh agent to tox release env 2024-01-08 14:22:53 +02:00
87c87d6455 Release 2.13.0 2024-01-05 22:48:03 +02:00
265de3dc72 ci: explicit isolated build for old ubuntu tox 2024-01-05 22:47:28 +02:00
d06c02a1c7 docs: add comments to configuration 2024-01-05 22:24:37 +02:00
29bb6284b0 test: add pytlint imports plugin and fix errors 2024-01-05 19:52:51 +02:00
70b7fcf47a refactor: fix pylint warnings in tests 2024-01-05 16:40:38 +02:00
706808fc97 refactor: simplify lock processing in worker trigger 2024-01-05 16:11:32 +02:00
7e5f21c26d refactor: split Path elements to / and first directory 2024-01-05 15:22:46 +02:00
9a7f55605a docs: url spelling 2024-01-05 12:37:23 +02:00
6085e88f5e chore: add index page recipe 2024-01-05 12:34:55 +02:00
56e97040d6 feat: read username if email is not available for oauth provider
Also add recipe for OAuth with GitHub setup
2024-01-05 12:28:31 +02:00
9510a14b90 refactor: use root RequestException instead of the one from subpackage 2024-01-05 11:48:38 +02:00
6eeef39fe5 fix: safe urls for packages
String catenation used for url generators didn't encode package names
which could lead to missing data in case if e.g. there is slash (/) in
package name
2024-01-03 14:28:20 +02:00
0e6434faad refactor: remove custom access logger
It is fine when application is able to log request, however, normally it
produces a lot noise, which has been handled by adding special logger.
However, nowadays it requires a lot endpoints to be filtered and doesn't
provide any choice.

Instead of it lets disable access logger by default and let users decide
do they need or not to see access log messages
2024-01-03 12:18:50 +02:00
768132bb6c chore: copyright update 2024-01-03 12:09:10 +02:00
f1095fe007 feat: raise 404 in case if package is unknown for logs and patches 2024-01-03 12:09:10 +02:00
1af04448c9 feat: threadsafe services
In the most cases it was enough to just add lock. In case of worker
trigger, since there is atomic operation on timer, it was also required
to add queue (coz python doesn't have atomics)
2024-01-03 12:09:10 +02:00
aad607eaef feat: add workers autodicsovery feature (#121)
* add workers autodicsovery feature

* suppress erros while retrieving worker list

* update recipes

* fix tests and update docs

* filter health checks

* ping based workers
2024-01-03 02:25:24 +02:00
3347212bf2 chore: make yamll style consistent 2023-12-29 03:57:13 +02:00
f3e9fbf9d0 refactor: fix warnings and typos, cleanup code 2023-12-28 16:53:45 +02:00
c3dacd6883 build: install aiohttp-cors from aur 2023-12-28 16:05:48 +02:00
624b4619f1 chore: add daemon unit 2023-12-28 15:24:14 +02:00
215fe7a592 test: add tests to check args list
Some parsers are shared between different subcommands. It causes errors
when wwe add new arguments to one of them. This commit adds some tests
to cover those cases (except for well-known differencies)
2023-12-27 15:01:07 +02:00
dd8d5d130b refactor: use AppKey's instead of string identifiers for web application 2023-12-27 13:53:23 +02:00
b4fa10781b feat: allow to run daemon mode with split packages check (#120) 2023-12-27 03:05:44 +02:00
f6cdd806b2 feat: add healh-check like endpoint, support of healthcheck in docker compose 2023-12-21 17:49:35 +02:00
cf9a1e7bec docs: add reference how to copy package 2023-12-21 02:14:27 +02:00
1b93f4f5e0 fix: drop debug toolbar 2023-12-20 16:26:14 +02:00
a872ecfc23 docs: docs review 2023-12-20 10:00:12 +02:00
c130f52163 chore: add configuration recipes 2023-12-20 10:00:12 +02:00
5fb93bd331 build: drop makefile
It has been a while since we moved to tox. Lets also drop makefile since
it seems to be useless with tox
2023-12-17 02:26:52 +02:00
58e702213d docs: restore docs for the view 2023-12-15 16:17:19 +02:00
e784032bc6 feat: add ability to disable specific routes (#119) 2023-12-15 14:34:03 +02:00
c54b14b833 feat: add ability to run build process to remote instances (#118) 2023-12-13 15:38:51 +02:00
e61b246216 fix: correct url for update requests in remote-call trigger 2023-12-11 15:43:28 +02:00
2a9eab5f1a feat: changes screen implementation (#117)
Add support of changes generation. Changes will be generated (unless explicitly asked not to) automatically during check process (i.e. `repo-update --dry-run` and aliases) and uploaded to the remote server. Changes can be reviewed either by web interface or by special subcommands.

Changes will be automatically cleared during next successful build
2023-11-30 14:56:41 +02:00
acc204de6d fix: use event instead of chained timer for daemon
Old solution causes amount of thread to be growing as well as stack is
increased during each iteration. Instead of cycle-free implementation,
this commit just uses while cycle
2023-11-30 13:40:59 +02:00
0991dbb59c type: update to the typed aiohttp release 2023-11-23 15:35:38 +02:00
18d17d4d52 feat: forbid form data in html
It has been a while since all pages have moved to json instead of form
data, except for login page. This commit changes login to json data
instead of form one
2023-11-16 16:42:27 +02:00
de7184fc3a feat: add separated web client for ahriman web services 2023-11-14 16:41:33 +02:00
2d21c999d1 docs: move timeout settings from web to status group 2023-11-13 16:53:16 +02:00
ff78577d61 Release 2.12.2 2023-11-13 12:26:00 +02:00
eb6eda578c style: highligh __del__ methods in formatting 2023-11-13 12:16:30 +02:00
e823fd3f27 fix: fix some security issues 2023-11-12 22:22:05 +02:00
e4a857dad0 feat: add separated switch for status reporting 2023-11-11 15:18:17 +02:00
fc8f6c2985 feat: extend result class 2023-11-10 17:09:01 +02:00
bb6414f9d4 fix: pass packagers object insteaed of string during rebuild 2023-11-08 16:05:27 +02:00
064ac6811c build: rename push action to release 2023-11-06 23:25:29 +02:00
7d16142b3b Release 2.12.1 2023-11-06 16:31:56 +02:00
69a79a2e64 fix: show unique upstream urls only 2023-11-06 16:29:18 +02:00
5b4bff9c93 Release 2.12.0 2023-11-06 15:50:11 +02:00
3f8b9eaed6 feat: add upstream and aur urls to package info modal 2023-11-06 15:46:32 +02:00
deab8ddae6 feat: serve favicon in root 2023-11-06 15:46:32 +02:00
eacb6ec729 build: remove spaces from names 2023-11-06 14:04:15 +02:00
dc2eebce39 docs: correct crossreference in docs 2023-11-06 14:04:15 +02:00
6b755b4828 refactor: replace enum with intenum and strenum 2023-11-05 13:26:11 +02:00
a73341e885 feat: allow to pass repository identifier to all database methods 2023-11-05 13:26:11 +02:00
969aa78c95 build: remove unused files from tarball 2023-11-05 13:26:11 +02:00
df787657aa chore: add metthod definition order plugin to pylint
Also reorder some methods to fix errors
2023-11-05 13:26:11 +02:00
eec94521a7 feat: read old web sections 2023-11-04 13:34:53 +02:00
b18000c777 feat: improve small screens views
also fix case when invalid repository id has been sent
2023-11-01 16:38:53 +02:00
dbaff5f981 fix: reset logs window manually 2023-10-31 12:33:57 +02:00
ae84ca0c56 fix: correct month serialization 2023-10-31 10:13:25 +02:00
8f047f9a96 feat: add patch controls to web, review web, enrich info tab (#115)
* add ability to specify one-time patch on package addition

* support vars in interface
2023-10-29 23:41:20 +02:00
54bd016c17 refactor: drop _check_output class attribute 2023-10-23 02:24:53 +03:00
42f77742f8 refactor: add ability to pass anything as environment variable to build task 2023-10-23 02:24:41 +03:00
46bb9c95d0 fix: make toggle button works on small displays 2023-10-21 15:18:09 +03:00
5dd4763a80 fix: write new line for telegram index 2023-10-21 03:56:48 +03:00
45eba6a6e3 fix: do not automatically add unknown local packages
Instead of automatic package addition now it is required to add package
manually after clone. Less magic, plus would allow to use caches for
multi-repo setup (see #109)
2023-10-21 01:33:12 +03:00
4c1d0abb85 feat: add ability to run multiple commands on success 2023-10-19 04:34:49 +03:00
1e00bf9398 feat: allow to use single web instance for all repositories (#114)
* Allow to use single web instance for any repository

* some improvements

* drop includes from user home directory, introduce new variables to docker

The old solution didn't actually work as expected, because devtools
configuration belongs to filesystem (as well as sudo one), so it was
still required to run setup command.

In order to handle additional repositories, the POSTSETUP and PRESETUP
commands variables have been introduced. FAQ has been updated as well

* raise 404 in case if repository is unknown
2023-10-17 03:58:50 +03:00
bf9a46936c chore: update comments to the latest mypy release 2023-10-12 20:31:00 +03:00
a0b17981e3 feat: add ability to override oauth2 icon 2023-10-07 18:12:17 +03:00
c440f5bbd5 fix: whitelist environment variables instead of passing all of them
Earlier applied fix bc9682373d introduced
errors with interaction, because (in docker container) HOME variable was
passed also to subprocesses. This fix limits variables to be passed to
the whitelisted ones
2023-10-02 16:37:20 +03:00
8ff567cac3 feat: add __call__ method to printers 2023-10-01 15:14:18 +03:00
9fe760efdf feat: load http views dynamically (#113) 2023-09-30 01:24:04 +03:00
bc9682373d fix: processes in docker images and pass full environment to
subprocesses

Since 1.0.4 release devtools require systemd to be run in order to
create slice for unit
2023-09-29 03:57:26 +03:00
aedcbf1985 fix: fix documentation building 2023-09-28 15:09:33 +03:00
26b991bf47 feat: add pagination to packages list 2023-09-11 18:08:26 +03:00
8bf422b02a docs: update documentation to new api calls 2023-09-11 15:57:00 +03:00
0c920832c9 fix: add note about pacman configuration 2023-09-10 23:48:03 +03:00
bef8d33570 feat: improve template processing (#112)
* Improve template processing

* docs update, config validation rules update
2023-09-08 23:38:07 +03:00
b540ced77f perf: limit clone and fetch by the latest commit 2023-09-08 15:52:59 +03:00
723b6971dd fix: correct version check in postinstall script 2023-09-08 14:48:31 +03:00
59356e905a feat: allow to use one application for multiple repositories (#111)
* allow to use one application for multiple repositories

* update tests

* handle None append argument everywhere

* rewrite repository definition logic

* drop optional flags from docs

* support of new schema in systemd units

* add migration docs and ability to migrate tree automatically

* use repostory id instead

* verbose multiarchitectureerror

* object path support for s3 sync

* fix tests after rebase
2023-09-08 14:01:07 +03:00
99eecdebf3 feat: pagination support for logs request 2023-09-08 01:41:36 +03:00
5e42dd4e70 fix: mark failed packages as failed in console handler 2023-09-06 18:22:05 +03:00
4ec7e2d129 docs: mock cryptography import due to build errors 2023-09-05 18:37:46 +03:00
9a521af078 feat: show help message if no command specified 2023-09-05 18:26:22 +03:00
d1132b49fc feat: add ability to skip migrations
This feature can be used in order to handle conflicting migrations
2023-09-02 14:30:50 +03:00
2c21ae26c3 ci: publish docker image to ghcr 2023-08-28 03:21:25 +03:00
bba90b3eb8 Release 2.11.0 2023-08-27 02:12:21 +03:00
3cac53ac11 add ability to partition tree before calculationn 2023-08-27 01:55:57 +03:00
9fa6722eaa small improvements on code smell
* fix some grammar/typo errors
* change some statements to be more clear
* use pattern matching for enum processing
2023-08-25 04:15:10 +03:00
1d4ed0e0c3 force rtd theme
Since Aug, 22 rtd doesn't force its theme anymore, leaving it as default
2023-08-23 15:27:51 +03:00
2cda4a2469 use http client class for all http requests 2023-08-23 03:27:42 +03:00
9406537a15 bump pylintrc 2023-08-21 02:55:08 +03:00
598af7d9db verbose subprocess exception handle annd quite git 2023-08-21 01:35:43 +03:00
6530afbfc7 review exception raise
In some cases for better readability of logs, exceptions are now raised
without parent exception stacktrace. Also updated docs and contributing
guidelines
2023-08-20 17:03:46 +03:00
ad1c0051c4 Remote call trigger support (#105)
* add support of remote task tracking
* add remote call trigger implementation
* docs update
* add cross-service upload
* add notes about user
* add more ability to control upload
* multipart upload with signatures as well as safe file save
* configuration reference update
* rename watcher methods
* erase logs based on current package version

Old implementation has used process id instead, but it leads to log
removal in case of remote process trigger

* add --server flag for setup command
* restore behavior of the httploghandler
2023-08-20 03:44:31 +03:00
5b172ad20b update gh actions install script 2023-08-17 16:33:02 +03:00
42fccb76ef add dummy type fields for pkgbuild generators
This field is required in order to pass config validation in case if
section name differs from default one. Also by default keyring_generator
and mirrorlist_generator have been renamed to keyring-generator and
mirrorlist-generator respectively for consistence
2023-08-17 16:02:15 +03:00
c37f67c558 close descriptor after uploading archive on github 2023-08-15 02:31:46 +03:00
89d9b581bd contributing guide update 2023-08-14 02:51:14 +03:00
116dc0b329 resoolve dependencies by using local cache too (#107) 2023-08-14 02:31:24 +03:00
e3ed36fafd add ability to read values from environment variables
It makes sense to read some values from environment. In particular this
feature is useful in case of running application in containers in ci/cd

See #108 for more details
2023-08-14 01:48:08 +03:00
573ade4ba5 remove unused absolute path validator (#106)
Extracted path is always absolute, so there is no need to check it
2023-08-13 20:48:07 +03:00
9259d9c727 Local packages support improvements (#104)
* handle git author correctly
* make remote source required argument
2023-08-13 15:45:53 +03:00
c863ee063c make auth.salt parameter optional
Used implementation of the hasher includes salt itself, thus additional
salt is optional and can be safely (in terms of security) treat as empty
string
2023-08-11 16:31:47 +03:00
480c3a54b8 full support of pep517
Since llast upgrade build is broken. Lets fully migrate to
pyproject.toml. Note for maintaners: because data_files option is
deprectated (see https://github.com/pypa/setuptools/discussions/2648)
you will have to install files manually inside your packaging process
2023-08-11 03:55:31 +03:00
3b3ef43863 automatically bump pkgrel on version duplicates
The new --(no-)increment flag has been added to add, update and rebuild
subcommands. In case if it is true and package version is the same as in
repository, it will automatically bump pkgrel appending (increasing)
minor part of it (e.g. 1.0.0-1 -> 1.0.0-1.1).

Inn order to implement this, the shadow (e.g. it will not store it in
database) patch for pkgrel will be created
2023-08-08 03:14:47 +03:00
368db86dde Release 2.10.2 2023-08-08 02:54:23 +03:00
adf6a0a952 remove napoleon contrib dependency 2023-08-08 02:53:08 +03:00
575a618096 fix issues with remote pull triggers (see #103)
* The issue appears when repository contains PKGBUILD in root. In this
  case it will copy tree with loosing package information, because
  the repository will be cloned to temporary path with random generated
  name
* The issue appears when branch which is different from master is used
  for any reposittory with git files (e.g. single-pkgbuild repo or repo
  with submodules)
2023-08-08 02:34:44 +03:00
2c03354d4a Release 2.10.1 2023-07-28 03:21:19 +03:00
4008aa2e0a do not create application in shell handler
The main reason for having shell handler is to be able to fix if
something (e.g. migrations) goes wrong. In this way we need to reduce
actions inside this wrapper
2023-07-28 03:06:28 +03:00
9cb39f6767 rase 405 error in case if GET login method is used whereas no aioauth
library installed
2023-07-23 03:01:25 +03:00
c7de182f3d optimize schemas import 2023-07-23 02:24:39 +03:00
d21c3fdf9f Release 2.10.0 2023-07-22 05:28:57 +03:00
9f2fe219c8 add support of table filter controls (#101) 2023-07-21 02:10:26 +03:00
ad570aae0f remove unsafe flag from handlers
This flag became reduntant there and tree creation has been moved to
lock
2023-07-07 03:25:05 +03:00
116b65d92a fix code block in docs 2023-07-06 19:17:11 +03:00
5e5171cf3e add salt generator to setup command instead 2023-07-06 19:16:49 +03:00
af3360e84a register dependency package before build
If package has been added as dependency, the service miss remote as well
as causes some 400 errors in reporter
2023-07-06 03:11:19 +03:00
95f52f7ebe handle packages load from aur by package name also
In general package names array may not contain package base, thus it
leads to inability to load packages from aur by its base during update
process
2023-07-01 15:55:04 +03:00
f5fe200247 explicitly pass user agent for the arch linux sites requests 2023-06-26 02:52:08 +03:00
a1c12200b8 print configuration paths in dump command 2023-06-11 15:11:34 +03:00
09839f755a remove salt generation from users handler
It causes issues, because users handler is operating with service user,
but writtinng salt requires root privileges
2023-06-05 05:25:10 +03:00
fcd4d60cad complitely disable signature check for local repository in devtools
It appears that with optional level pacman still tries to validate the
key, which can lead to errors whille processing in docker container
2023-06-05 04:41:03 +03:00
3681473942 packager documentation update 2023-06-05 03:40:02 +03:00
4dd5a1e82e packagers support (#100) 2023-06-05 02:37:19 +03:00
cbd1d3d5b8 use autodoc_mock_imports instead of custom mocking for docs 2023-05-31 19:17:16 +03:00
e3347aec2d use cached property instead of custom __getattr__ implementation 2023-05-31 19:17:16 +03:00
3ad6cd27c6 support check dependencies 2023-05-31 19:17:16 +03:00
54a68279be mimic parent arguments during spawn process (#99) 2023-05-30 18:09:35 +03:00
d99091a3b4 do not terminate child process explicitly
This feature sometimes causes the main process termination. Since the
child process has been already terminated (or going to) there is no need
to terminate it manually
2023-05-29 17:27:04 +03:00
be6cf5b8af fix case where it was impossible to create session if user and password
are required

Issue appears if auth is enabled and unix socket is disabled and caused
by d81e91e117
2023-05-29 17:23:57 +03:00
91e548569d runtime logger handler selector 2023-05-29 03:41:11 +03:00
6c3b2ef266 add repod reference to faq 2023-05-26 12:58:25 +03:00
785607c70b allow to filter packages for rebuild by their statuses 2023-05-25 17:41:54 +03:00
d22a3152db fix documentation error 2023-05-25 16:31:47 +03:00
adb5b58a1d Support type triggers (#96)
* implement mirrorlist package generator

* implement keyring package generator

* docs update

* do not skip empty lines

* fill remote source for local packages

* faq update
2023-05-25 16:27:16 +03:00
8b2601beaa switch to explicit journald logger instead of syslog 2023-05-25 04:44:38 +03:00
9116a4370e update optional dependencies list 2023-05-24 15:39:36 +03:00
da93fdc77a bump rtd image 2023-05-24 03:58:14 +03:00
8bbd643551 update packaging files
also remove makedependencies after installation in docker
2023-05-22 18:23:06 +03:00
6834dd442c Release 2.9.0 2023-05-22 17:04:32 +03:00
d23e3cbbea update models index 2023-05-22 17:02:55 +03:00
6bc6bdaeae migrate to the latest devtools & archlinux git changes
This migration includes
* removal of community repository as it is no more
* fixed paths for devtools configurations
* migration of archlinux packaging git url
2023-05-22 16:51:27 +03:00
7458c73c7d disable debugpanel for now 2023-05-04 14:30:27 +03:00
2cecbb3d53 do not assign path in context manager as it is deprectated 2023-05-04 14:29:39 +03:00
c73a6c7bae PEP-673 use Self as return type for classmethods (#94)
* PEP-673 use Self as return type for classmethods

* add dummy test file

* remove python3.10 compat
2023-05-04 03:28:08 +03:00
0b70b5af45 fix flapping tests for oauth
Original implementation sends requests to httpbin which sometimes might
not be available. With proposed changes we are blocking redirects and
just check request itself
2023-05-03 14:53:35 +03:00
fde75a14c2 PEP-561 complaint: add py.typed marker 2023-04-17 18:56:49 +03:00
1e0d1a5a32 fix some pycharm warnings 2023-04-17 02:23:50 +03:00
75919637e8 suppress status errors also if option is set 2023-04-15 05:05:55 +03:00
467d109cfc add referencne to api docs to docs 2023-04-14 05:06:53 +03:00
a131c77699 add reference to api documentation from main page 2023-04-12 04:22:49 +03:00
10fbc31d2a PEP-585 complaint: remove type aliases (#93) 2023-04-12 04:09:28 +03:00
7e0d12b8b1 docs update 2023-04-10 21:13:43 +03:00
7ab00ee579 Release 2.8.0 2023-04-09 13:06:54 +03:00
2d62148ee6 try to remove unknown packages from api 2023-04-06 18:14:36 +03:00
c1f2d5ff4a hide cookie key and salt from config output 2023-04-06 00:31:50 +03:00
2888649ced optimize imports 2023-04-06 00:24:39 +03:00
63855f5964 argument annootation update 2023-04-06 00:24:39 +03:00
8bf665d7d3 fix license url 2023-04-06 00:24:39 +03:00
a7ac77ce4d extract schemas automatically from views 2023-04-06 00:24:39 +03:00
fc01bf3d1c use api generated docs instead of comments (#92) 2023-04-06 00:24:39 +03:00
d81e91e117 execute request in context methods instead of handling them each time
manually
2023-03-23 12:43:04 +02:00
57f62ba163 Release 2.7.1 2023-03-06 01:15:47 +02:00
ded896ee1b gracefully terminate web server
In previous revisions server was terminated by itself, thus no lock or
socket was removed. In new version, graceful termination of the queue
has been added as well as server now handles singals
2023-03-06 01:13:41 +02:00
1fdcea0524 replace InitializeException with InitializeError in docs 2023-03-02 11:07:59 +02:00
a93f43dcd0 simplify login ttl processing 2023-02-24 16:52:55 +02:00
20974dae6f add more validation rules 2023-02-23 15:18:56 +02:00
cbcfff27b8 add ability to read cookie secret from config 2023-02-22 18:47:56 +02:00
96f394bab0 Release 2.7.0 2023-02-20 03:05:08 +02:00
aae3c82f3d update dependencies before build (#91)
Old implementation has used add step in order to fetch dependencies,
which could lead to build errors in case if dependency list was updated.

New solution uses dependencies which are declared at current version and
fetch them (if required and if enabled) before update process.

Closes #90
2023-02-12 06:02:30 +03:00
ab9e1fb1bd handle .gitignore file correctly in remote push trigger 2023-02-11 04:41:24 +02:00
82322f7a6c mask mypy warning
The newest mypy produces the following warning:

src/ahriman/application/handlers/search.py:43: error: Non-overlapping identity check (left operand type: "Union[_DefaultFactory[Any], Literal[_MISSING_TYPE.MISSING]]", right operand type: "Type[List[Any]]")  [comparison-overlap]

which is more likely caused by updated dataclass models to protoocol (however decorators are still calllable). This commit masks problematic line from checking
2023-02-09 22:46:08 +02:00
125da217d3 hide passwords and secrets from repo-config subcommand by default 2023-02-05 16:44:48 +02:00
d113c65c81 note about local database update (see #85) 2023-01-31 14:47:58 +02:00
050041b2de handle architecture specific fields for dependencies
This change requires srcinfo at least 0.1.2 version. Unfortunatelly aur
api don't support architecture specific arrays for now, so we just leave
it as is

Closes #82
2023-01-31 14:34:09 +02:00
e0ed636d7e filter empty packages from database
In some cases (e.g. during addition of the package to build queue) we don't have
full information about package inself; in these cases we produce lines
with empty architecture, which duplicates normal ones.

This commit changes architecture column type to required and also
filters packages which don't have architecture set yet.

Closes #83
2023-01-30 17:57:13 +02:00
61feb2ebc7 trim version from provides list
Closes #87
2023-01-30 17:27:34 +02:00
da1c6b0101 add ability to suppress http logging errors (#86) 2023-01-30 17:19:01 +02:00
c1718b3862 calculate dependencies based on package information (#89) 2023-01-30 17:28:05 +03:00
34fe8128aa remove debug line 2023-01-27 16:41:41 +02:00
a78c48ed4d Release 2.6.1 2023-01-25 15:28:27 +02:00
e368396653 make oauth client trully optional (#84)
Same old song, after migraiton to packages some optional modules are
being imported globally which lead to making hard dependency
2023-01-25 15:25:42 +02:00
f4abd83568 enable lock for web service 2023-01-18 01:39:55 +02:00
e6888ba788 Release 2.6.0 2023-01-16 01:35:12 +02:00
a78050c1bf add notes about non-x86_64 architecture setup 2023-01-15 18:16:29 +02:00
93876307f8 add ability to override pacman mirror in devtools configuration
This commit also extends configuration of the multilib option, adding
the ability to exlcude multilib repository from repositories list

Note, that in order to support repository list and mirror correctly,
alpm configuration section is now architectture specific
2023-01-15 18:05:15 +02:00
4d482520cd add note about other authroization options to gitremote triggers 2023-01-13 17:27:19 +02:00
461fbd40ce consider vcs flag and vcs_allowed_age during local packages update 2023-01-12 15:37:05 +02:00
419da3db89 add ability to check for service updates 2023-01-12 15:37:05 +02:00
00ca06ffab subcommand review
Some commands have been moved to another group and thus having another
default name (old subcommands are still available...for now):

* daemon -> repo-daemon
* key-import -> service-key-import
* repo-clean -> service-clean
* repo-config -> service-config
* repo-config-validate -> service-config-validate
* repo-setup -> service-setup
* repo-shell -> service-shell
* version -> help-version
2023-01-12 15:37:05 +02:00
5a05c8ce91 expose trigger configuration schema
Note that this commit contains the following breaking changes:

* remote pull and remote push triggers are now enabled by default (with
  empty target list)
* remote pull and remote push triggers now require target option to be
  set (old behaviour had fallback on `gitremote`)
* validation is now considered to be stable, so it is enabled by default
  in docker image (can be disabled however)
2023-01-10 03:33:52 +02:00
b09aea13af add config validator subcommand (#80)
* add config validator subcommand

* add --exit-code flag

* docs & faq update
2023-01-09 18:22:29 +03:00
04a52f759d sort unsafe commands response 2023-01-04 18:00:10 +02:00
ef6cf0f00b review unsafe commands access
Some commands were made unsafe in old versions, but nowadays they can be
run without having special privileges.

There was also a bug in which status commands were not available if you
are not ahriman user and unix socket is used. It has been fixed by
switching to manual socket creation (see also
https://github.com/aio-libs/aiohttp/issues/4155)
2023-01-04 17:45:44 +02:00
ab650b7417 copyright update 2023-01-04 03:43:10 +02:00
7ca5b3a363 Release 2.5.4 2023-01-03 01:59:25 +02:00
666fa98075 add notes about documentation and methods inside class
Because I always forget which way I used before
2023-01-03 01:53:10 +02:00
684ef33dbc Correct way to allow setting context with existing
This reverts commit 11732a8609.

Original solution has introduced special workaround (strict flag) which
contradicts the concept of immutable context. Moreover, it introduces
possible side-effects, because child process will use the one set by
parent instead of having own one.

The correct solution is to re-create context in process entry point

Sorry, it was Jan 1 and I was drunk :(
2023-01-03 00:48:14 +02:00
cf35addaa5 Release 2.5.3 2023-01-02 03:24:11 +02:00
11732a8609 allow setting context with existing
In case of running command from web interface, it will raise exception
because context has been copied with subprocesses
2023-01-02 03:21:15 +02:00
64cc8fd6b0 Release 2.5.2 2023-01-02 01:57:09 +02:00
4202751e9c remote all gitfiles in git remote trigger
In case if there is .gitignore file with asterics, the pkgbuild upload
would not appear
2023-01-02 01:45:50 +02:00
41515f6c95 Release 2.5.1 2022-12-31 14:58:37 +02:00
ac92b506e0 remote log for calculate version as it cleans logs 2022-12-31 14:48:21 +02:00
5bbd1ad9a9 fully lazy handle load
In case of immediate handle load it would try to sync databases (or at
least to create database files), which is not possible in case if
command is run as non-ahriman user. This commit makes handle load lazy
and allows to run some commands as non-ahriman user
2022-12-31 14:48:21 +02:00
541d8d9b39 Release 2.5.0 2022-12-31 02:02:37 +02:00
e41dd09a8a force upgrade sphinx documentation 2022-12-30 22:58:13 +02:00
8e65263b90 add completion files generated by shtab 2022-12-30 21:19:23 +02:00
afc488255c allow 3 symbols for package search 2022-12-30 21:19:23 +02:00
effc120a43 improve VCS packages checks
* Unlike older version, currently service will always try to pull AUR
  package to check version. Previously if no-vcs flag is set, it would
  ignore VCS packages completelly
* Introduce build.vcs_allowed_age option. If set, it will skip version
  calculation if package age (now - build_date) is less than this value
2022-12-30 21:19:23 +02:00
4b27e102ef change another boolean info option to boolean action 2022-12-29 03:15:48 +02:00
e0126bb811 add repo-structure subcommand
This commit also changes Tree class, replacing load method by resolve
2022-12-27 10:35:03 +02:00
8c04dc4c2a fix property description in docs 2022-12-26 02:32:14 +02:00
83e9d7c523 write patches via gitremote push trigger (#79)
* write patches via gitremote push trigger

* implement context variables intead of custom database class
2022-12-25 02:10:38 +03:00
9be4a89c08 Release 2.4.1 2022-12-11 05:17:10 +02:00
0f8596db1e replace alert bodals with toasts 2022-12-09 11:33:19 +02:00
c403c45d72 remove badges from status page 2022-12-09 00:58:03 +02:00
00dbd90953 check that package has been created during setup workflow 2022-12-06 11:09:56 +02:00
3e299d9685 Release 2.4.0 2022-12-05 00:25:53 +02:00
e20637f7ad do not update database via pacman, use ahriman's own databses 2022-12-04 23:45:10 +02:00
5a09d46f9a Some minor documentation related fixes
* Improve some wording (again)
* Change default type for refresh option to False (does not affect
  behavior)
* Update docstrings to reflect last changes
* Configuration.__convert_path has been replaced by shlex
* aiosecurity functions support kwargs now
2022-12-04 02:10:46 +02:00
90be3276dd improve wording in documentation 2022-12-02 15:45:01 +02:00
a4f646eb2a do not trigger update on sign command 2022-12-02 01:41:23 +02:00
ebd06cb443 improve setup command by --makeflags-jobs argument and fix repository sign on creation 2022-12-02 01:41:23 +02:00
fe66c6c45c implement support of unix socket for server
This feature can be used for unauthorized access to apis - e.g. for
reporting service if it is run on the same machine. Since now it becomes
recommended way for the interprocess communication, thus some options
(e.g. creating user with as-service flag) are no longer available now
2022-12-02 01:41:23 +02:00
bba58352e0 do not invoke configuration write in case if no salt or user was written 2022-12-02 01:41:23 +02:00
41cc58ed31 add rebuild implementation to interface 2022-12-02 01:41:23 +02:00
20e45845ba make package actions as dropdown 2022-12-02 01:41:23 +02:00
9fa1fa108f add key-import button to interface 2022-12-02 01:41:23 +02:00
577bd9e5f8 add demos links 2022-11-24 02:38:33 +02:00
20b9c1fa4a add security notes 2022-11-24 02:38:33 +02:00
a7c9183aa0 add curl examples to web views 2022-11-24 02:38:33 +02:00
9e0dd3ae97 build docs together with web views 2022-11-24 02:38:33 +02:00
f4e4e88e82 change respone for service requests 2022-11-24 02:38:33 +02:00
2684e4b3f4 add fallback for copying to clipboard 2022-11-24 02:38:33 +02:00
45f5006db3 add show/hide password button 2022-11-24 02:38:33 +02:00
b26aa2145f update web preview picture 2022-11-24 02:38:33 +02:00
4462eba860 render httpunauthorized as html in plain http requests 2022-11-22 23:40:27 +02:00
f2c23bad17 allow scrolling with fixed copy button position 2022-11-22 22:20:21 +02:00
1603086b96 change logging module imports 2022-11-22 22:20:21 +02:00
b6f6ee8c76 change wording for package actions 2022-11-22 15:46:49 +02:00
b71d1f6e3d fix login and logout buttons decorations 2022-11-22 11:17:59 +02:00
7883746e53 add more notes about docker 2022-11-22 10:49:46 +02:00
ae9118654d check log record in handler instead of client 2022-11-22 02:30:37 +02:00
81fa73f725 ask users to repeat password
In case if password is asked via getpass, it is possible to make typo
and user will not see the mistake. In order to avoid it, additional
confirmation has been added
2022-11-22 02:19:37 +02:00
14cb548c3b Extended package status page (#76)
* implement log storage at backend
* handle process id during removal. During one process we can write logs from different packages in different times (e.g. check and update later) and we would like to store all logs belong to the same process
* set package context in main functions
* implement logs support in interface
* filter out logs posting http logs
* add timestamp to log records
* hide getting logs under reporter permission

List of breaking changes:

* `ahriman.core.lazy_logging.LazyLogging` has been renamed to `ahriman.core.log.LazyLogging`
* `ahriman.core.configuration.Configuration.from_path` does not have `quiet` attribute now
* `ahriman.core.configuration.Configuration` class does not have `load_logging` method now
* `ahriman.core.status.client.Client.load` requires `report` argument now
2022-11-22 02:58:22 +03:00
2eb93a6090 Release 2.3.0 2022-11-16 00:53:48 +02:00
dd6ef38c99 remote threadname from logging
Since application is mostly singlethreaded it makes no sense to log it
2022-11-14 23:21:06 +02:00
415dc42313 Release 2.3.0rc4 2022-11-14 01:02:27 +02:00
3e1af17796 fix case when no files were commited in remote push trigger
The issue appears together with --intent-to-add flag for adding new
files. Original testing has been performed by having already added new
files, thus it passed all checks.

This commit also adds `commit_author` option which will allow to
overwrite the author.
2022-11-14 00:59:43 +02:00
880cebe54f Release 2.3.0rc3 2022-11-11 21:20:55 +02:00
cbcc796a3a rollback cwd parameter for clone 2022-11-11 21:19:27 +02:00
dc8a52f6c0 Release 2.3.0rc2 2022-11-11 17:25:11 +02:00
34c93e53cc Fix issue when there is no cached source directory yet (closes #75) 2022-11-11 17:23:15 +02:00
f7ec24523b Release 2.3.0rc1 2022-11-11 16:36:13 +02:00
f817b32976 use intersection of from_database and depends_on filters for the rebuild subcommand
Old logic used OR condition, i.e. if set from-database, it would ignore
the --depends-on flag. In new logic it calculates dependencies based on
the package list, which can be retrieved from database
2022-11-11 16:02:19 +02:00
9fc2b681d4 limit max module size and improve some help messages 2022-11-11 16:01:54 +02:00
59ff0589ab speedup docker build command by adding dockerignore listing 2022-11-11 12:47:31 +02:00
1b53de6f2b man update 2022-11-10 20:10:07 +02:00
41080c5ff8 add exec to shell subcommand 2022-11-10 18:52:55 +02:00
791ce4f242 make exception optional argument for check_output method 2022-11-10 18:05:32 +02:00
b75bd30658 replace several store_true keys to booleanoptionalaction alternative (#74) 2022-11-10 18:34:01 +03:00
b3b3cad706 write .makepkg.conf to home dir instead of repository root (#72) 2022-11-08 17:02:13 +02:00
82b932371b add ability to use ahriman pacman database instead of system one (#71)
By default this feature is enabled. On the first run it will copy (if
exists) databases from filesystem to local cache (one per each
architecture). Later it will use this cache for all alpm operations. In
order to update this cache, some commands (mainly package building)
provide `-y`/`--refresh` option which has same semantics as pacman -Sy
does.

Note however that due to extending `Pacman` class some methods were
renamed in order to be more descriptive:
* `Pacman.all_packages` -> `Pacman.packages`
* `Pacman.get` -> `Pacman.package_get`

This commit also adds multilib repository to the default docker image
which was missed.
2022-11-08 17:26:51 +03:00
45fb2f3c46 improve repo-setup command
* Move devtools executable to ahriman home, because we don't really
  need to use executable inside root
* Use named sudoers file instead of single file. It will allow easily to
  remove file as well as use setup command for several
  repositories/architectures
2022-11-06 14:25:44 +02:00
4a5b9d9fa1 fix case in which if no source PKGBUILDs were updated, an exception will occur 2022-11-03 03:39:54 +02:00
2f8316ecb0 faq update 2022-11-02 17:15:17 +02:00
77ad35fce8 docs update 2022-11-02 04:17:26 +02:00
48da4646cf change gitremote api to be same as report and upload
These changes are keeping fallback to old settings, but will allow to
run multiple git targets with different settings
2022-11-02 04:09:42 +02:00
3d98dd267a fix update handler tests
If daemon tests are run before the update handler it causes test
failure, because there are other calls
2022-10-31 11:51:12 +02:00
09678a3ae1 add possibility to run full update
In case if packages are not set from web, the spawner will run full
repository update
2022-10-31 02:41:24 +02:00
8e2732f6fe add daemon subcommand
This command emulates default systemd timer and can be useful in docker
container in order to run 24/7
2022-10-31 01:38:01 +02:00
73e311a41c implement single-function patches (#69) 2022-10-30 03:11:03 +03:00
1e8388af5d drop ahriman.core.triggers.Trigger.run method
In order to force new triggers to use on_result method, the old method
has been removed. However, default on_result method still checks if the
old method exists and tries to run it
2022-10-19 20:07:31 +03:00
c1d74726b7 fix rtd docs building
Commit 9d016f51b5 introduced kw_only
dataclasess which require python 3.10+
2022-10-18 02:24:18 +03:00
f2ddcc6d23 disallow no values in configuration
This option could lead to missing warnings about missing or invalid
configuration values because code usually expects that values are exists
and not empty unless it is explicitly specified.

However, pacman configuration still requires this option in order to be
able to deal with boolean values
2022-10-18 02:13:01 +03:00
a5ce6b78dd Add gitremote triggers (#68)
* add gitremote pull trigger

* add push gitremote trigger

* docs update
2022-10-18 01:46:27 +03:00
1a83dd6f5a extend triggers to on_start and on_stop methods
This commit also replaces old run method to new on_result
2022-09-26 01:22:54 +03:00
16a33f7729 add minimal install step to workflow 2022-09-17 14:52:08 +03:00
fb21b1da53 make sqlite import consistent 2022-09-17 14:32:21 +03:00
8394004943 Release 2.2.2 2022-09-17 04:05:06 +03:00
75c6bf6119 skip architecture list patching in case if any architecture is set 2022-09-17 04:04:28 +03:00
7e20ff5184 Release 2.2.1 2022-09-14 04:49:08 +03:00
757614f5a0 docs update 2022-09-14 04:48:11 +03:00
43166e5f94 Release 2.2.0 2022-09-14 03:28:28 +03:00
43696b9920 Make optional dependencies trully optional (#67)
The issue appears when there is no boto, jinja and some other libraries
are not installed because the classes which use these libraries are
still being imported inside the package file. The fix removes those
imports from package root, because they should not be here, in fact,
content of report and upload packages must be imported only inside the
trigger class and only if they are actually required

This commit also adds setuptools as required dependency since it is used
for some parsers (previously it was provided dependency)
2022-09-11 01:44:06 +03:00
8befee58fe patch architecture list in runtime (#66) 2022-08-09 15:18:20 +03:00
9d016f51b5 frozen dataclasses 2022-07-26 14:40:28 +03:00
c5fbccd519 reduce docker image size a bit 2022-07-18 11:42:26 +03:00
eae5748a30 Release 2.1.0 2022-07-02 15:42:39 +03:00
695ef708b6 simplify tmpdir method 2022-06-28 19:11:38 +03:00
26408e82c0 review loggers once more
This commit makes loggers like java.util.logging with fully qualified
logger name which is created by LazyLogging trait
2022-06-28 11:00:45 +03:00
7b647a9b5a fix case with package name which cannot be downloaded
(without special settings)

The issue appears if file or its version contains one of special URI
characters, e.g. +. Theu will be interpreted as query parameters by
(some) servers (e.g. S3 works in this way). In this commit we rename
archive to the one with safe name.
2022-06-27 18:53:48 +03:00
fac228d6c6 review loggers once more
This commit makes loggers like java.util.logging with fully qualified
logger name which is created by LazyLogging trait
2022-06-27 01:41:49 +03:00
eb5ac5a52b bump web libraries
also encode strings for the views
2022-06-24 12:03:38 +03:00
047925dcfe review loggers 2022-06-21 11:48:42 +03:00
b8d2775050 replace if with while for telelgram reporting 2022-06-10 12:02:00 +03:00
bf959ceb5f Release 2.0.0 2022-06-05 20:46:32 +03:00
945b6d0ac0 small docs update 2022-06-04 15:24:14 +03:00
5df9f30e37 do not pass timestamp to pretty_datetime functioon 2022-05-31 21:26:39 +03:00
1ea3911531 rewrite api under single /api endpoint 2022-05-29 17:15:49 +03:00
d7966e419d add shell and version parser 2022-05-27 18:34:07 +03:00
3a5268993e update readme 2022-05-22 16:00:24 +03:00
ad84895e18 do not bump timestamp on empty updates 2022-05-21 04:19:04 +03:00
b1dfafe275 dynamic html load (#63)
* dynamic html load
* split by classes
2022-05-20 22:29:36 +03:00
375f9fcfb7 add ability to run only speicifed triggers from command line
This commit also restores repo-report and repo-sync subcommands
2022-05-12 18:43:36 +03:00
04dcaa93ab fix case when provided trigger path is directory
If trigger is directory and we have permissions to read it, the loaded
will try to load this from it and will fail with IsADirectoryError
2022-05-12 07:22:50 +03:00
f42c2c57fb add not about pacman database update 2022-05-11 04:30:24 +03:00
dc3562a4ec add contribution guide 2022-05-11 03:17:37 +03:00
dda94f8f9e Release 2.0.0rc11 2022-05-10 06:03:33 +03:00
709db6a5ed fix bug with checking file
The bug appear when the file exists or doesn't, but we don't have
permissions to read it. This one must be treated as missed permission
2022-05-10 06:01:41 +03:00
89a2d8e298 Release 2.0.0rc10 2022-05-09 21:51:35 +03:00
b9cd98235e triggers implementation (#62) 2022-05-09 20:00:20 +03:00
1905360f8f Release 2.0.0rc9 2022-05-08 03:58:53 +03:00
a7018d9f7d fix error with missing sources
In case if package has local cache it will fail to load because no
remote source set. Particially this case can be observed during tree
load
2022-05-08 03:56:54 +03:00
73057bc08d Release 2.0.0rc8 2022-05-06 20:55:54 +03:00
7f87863734 shorten public imports 2022-05-06 04:08:05 +03:00
2dac5a2520 Docs update (#61)
* Improve sphinx documentation

* update faq formatting

* fix setup doc

* fix docs according to the generated htmls
2022-05-06 02:54:37 +03:00
720edc24ba correct archllinux wording in readme 2022-05-06 02:54:37 +03:00
fe9711d24f add __all__ attribute 2022-05-06 02:54:37 +03:00
c73a2a4aa9 add note about ahriman to index page 2022-05-06 02:54:37 +03:00
571f720ae2 Complete official repository support (#59) 2022-05-03 00:49:32 +03:00
5030395025 rename classes in order to make documentation reference work 2022-04-18 05:30:02 +03:00
03633d47ea readthedoc integration 2022-04-18 04:39:40 +03:00
1a575d6db8 move documentation to tox 2022-04-18 01:48:36 +03:00
cdc018ad07 apply data migration in the same transaction block with schema migration 2022-04-18 01:19:38 +03:00
f806c8918e fix target naming 2022-04-18 01:19:20 +03:00
4daff81d5f Docstring update (#58)
* migrate docstrings from reST to google format

* add raises note

Also change behaviour of the `from_option` method to fallback to
disabled instead of raising exception on unknown option

* fix part of warnings for sphinx

* make identation a bit more readable

* review fixes

* add verbose description for properties to make them parsed by sphinx extenstion

* add demo sphinx generator
2022-04-17 20:25:28 +03:00
06bd29b78d Release 2.0.0rc7 2022-04-11 00:48:08 +03:00
c67ac3730c docs update 2022-04-11 00:46:46 +03:00
c094d4ee79 add backup and restore subcommands 2022-04-10 21:34:34 +03:00
3cb479ba4b merge restore to rebuild commannd 2022-04-10 01:51:12 +03:00
307a7f4a71 Release 2.0.0rc6 2022-04-09 17:34:23 +03:00
25734876de do not render failed packages in jinja (#57)
basic templates require package info which is unavailable if package
wasn't built
2022-04-09 17:31:13 +03:00
53df735eb2 Release 2.0.0rc5 2022-04-08 04:42:05 +03:00
fb7275f9dd change telegram default index to telegram-index 2022-04-08 04:32:34 +03:00
f01af5f54a force git run from the same dir to clone 2022-04-08 04:04:06 +03:00
1abe8d291f fix users migration 2022-04-08 03:45:17 +03:00
1a83e55d64 add telegram integraion 2022-04-08 03:41:07 +03:00
b8e17c4879 Release 2.0.0rc4 2022-04-08 01:14:35 +03:00
bee41dcc55 trim versions before dependency list calculation
When dependencies list contains same package with version it tries to
find packages which don't exists
2022-04-07 20:32:55 +03:00
9f7995fb2f add support of repository restoration 2022-04-07 04:49:07 +03:00
9ce1c36f35 add support of officiall repositories api 2022-04-07 04:19:37 +03:00
4990ce4198 fix descriptions 2022-04-06 01:48:03 +03:00
8f18ead4cc Release 2.0.0rc3 2022-04-04 02:40:17 +03:00
7ea50887a4 allow any tag for push 2022-04-04 02:39:56 +03:00
97ec5bfa41 Release 2.0.0rc2 2022-04-04 02:27:19 +03:00
5fcc15191a change regex for sed 2022-04-04 02:26:42 +03:00
c5f086a7c6 Release 2.0.0-rc1 2022-04-04 02:18:31 +03:00
432ca0cc48 better processing for subcommands
Old versions cached full output to memory and only after that printed it
into log. This behaviour causes issues in case if operation stucks and
you would need to find the step at which it does. New check_output
method uses Popen directly and iterates over stdout lines

Also changed behaviour from merging stderr into stdout to separate
stderr logging.

Any other behaviour of the function must be the same.

Also changed GPG.key_import method to disable local signing since it
seems it is useless (and may break process in case if there is no
private key)
2022-04-04 00:03:22 +03:00
1a0322b32e docs update 2022-04-03 01:44:11 +03:00
fc086c0d87 remove implicit user from docker 2022-04-01 18:39:24 +03:00
d5503b22ba add configurable exit codes to some commands (#55) 2022-04-01 18:30:11 +03:00
a132b1544a create user in docker container
also fix user reading and add nocolor flag by default
2022-03-31 03:25:53 +03:00
63acae4b1c configure docker to work with tags 2022-03-31 02:19:48 +03:00
8e6473d2a0 add help command 2022-03-31 02:18:39 +03:00
fdcbcc4541 update license years 2022-03-31 01:49:31 +03:00
83931f5cf4 port part of settings to database (#54) 2022-03-31 01:48:06 +03:00
d4eadf0013 migrate to tox
this also requires to move default configuration files to share/ahriman.
Thus the following features have been added
* default configuration is not stored in /usr/share/ahriman/settings
* package installed via PKGBUILD now copies files from /usr
* configuration class now fallbacks to default in /usr
2022-03-21 04:38:42 +03:00
04174a3e6d deprecate init/repo-init command
In current workflow you need to run setup to run init (because of
repository name), but you need to run init before setup (because of
repository tree rights).

New solution just add `Repo.init()` method call to setup subcommand
after config reload to make sure that repository name has been applied.
In addition chown method as well as setuid method for check_output have
been added.
2022-03-21 01:32:11 +03:00
041b3824c1 enable privileged mode for the docker 2022-03-20 04:05:43 +03:00
a11cce43ff fallback to AUR source in case of PermissionError exception 2022-03-20 03:46:56 +03:00
1388df9a7e add fallback for utf option 2022-03-20 03:16:33 +03:00
6ee1c8ef5a replace pspec with spec 2022-03-20 03:08:51 +03:00
a7c6d95b34 add console printer
also add python-requests as explicit dependency and escape symbols in
repository name for badges in default tempate
2022-03-20 02:31:50 +03:00
060c7412b1 ALLOW_AUTO_ARCHITECTURE_RUN flag for unsafe commands 2022-03-19 03:08:45 +03:00
93406483fe docker hub integration 2022-03-14 00:08:21 +03:00
046febc440 add docker support (#52)
* add docker support

* make shellcheck happy
2022-03-13 23:43:25 +03:00
9964a96296 strict test checks 2022-03-04 02:04:52 +03:00
9529525cb5 set success status on up to date packages 2022-02-06 06:22:58 +03:00
fa4c1c6205 Release 1.8.0 2022-02-06 05:45:50 +03:00
f9b1d89756 update for new aiohttp api 2022-02-06 04:05:33 +03:00
9197b416e6 use own aur wrapper (#49) 2022-02-06 03:44:57 +03:00
f54a2fe740 Release 1.7.0 2021-12-26 02:01:09 +03:00
d1f990eac8 make mypy happy 2021-12-26 01:58:55 +03:00
1e85c1db70 handle dependencies recursively 2021-12-22 19:35:09 +03:00
32aaa4a1f8 initial implementation of the local git clones (#48) 2021-12-22 15:56:24 +03:00
a9e20f0958 do not read aur_url from settings, use repository property instead 2021-11-15 11:27:41 +03:00
32b129a806 Release 1.6.4 2021-11-10 21:29:45 +03:00
2752e68ade handle packages which have been removed from the repository (#45)
* handle packages which have been removed from the repository

* manually remove packages which have been removed from the base
2021-11-10 01:37:25 +03:00
5b678149dc Release 1.6.3 2021-11-04 21:32:27 +03:00
79e1cff421 take python laziness into account 2021-11-04 21:30:34 +03:00
2e07de4a12 Release 1.6.2 2021-10-28 03:20:52 +03:00
7e3ef889e8 improve configuration extension
* Allow spaces in lists. This feature has been done in the way as shell
  interprets arguments by using quotation marks
* Clear current content on reload
2021-10-28 03:19:50 +03:00
52b54a9d05 add nginx configuration to the faq 2021-10-27 03:35:33 +03:00
c0f7f81050 Release 1.6.1 2021-10-27 03:16:53 +03:00
38af344bde update license headers 2021-10-27 03:14:39 +03:00
62496478ae add update printer which will print current version if any 2021-10-27 03:11:43 +03:00
ce48169aad use PackageSource enum for Package.load method
When using add function it sill tries to load data with invalid source
2021-10-27 02:49:23 +03:00
21845bc934 Release 1.6.0 2021-10-27 01:59:36 +03:00
249003de0a drop no-quiet option and change tree_create message error to warn 2021-10-27 01:57:54 +03:00
d8704e9c75 remove help sample from readme because it changes faster than om able to maintain it 2021-10-26 04:53:45 +03:00
0a8b172e9c unify aur.search method
due to specific of the AUR API in order to reduce the code we are using
own wrapper and work with it instead of direct library calls
2021-10-26 04:49:55 +03:00
7d782f120d Add ability to show more info in search and status subcommands
This feature also introduces the followiing changes
* aur-search command now works as expected with multiterms
* printer classes for managing of data print
* --sort-by argument for aur-search subcommand instead of using package
  name
* --quiet argument now has also --no-quite option
* if --quite is supplied, the log level will be set to warn instead of
  critical to be able to see error messages
* pretty_datetime function now also supports datetime objects
* BuildStatus is now pure dataclass
2021-10-26 04:27:36 +03:00
9057ecf67a always update environnment before any action 2021-10-24 04:14:57 +03:00
35df354c14 split application class into traits 2021-10-23 13:44:57 +03:00
4d4e5e9dde add patches to clean command 2021-10-20 03:22:16 +03:00
ff24188ca1 add ability to download package from external links (e.g. HTTP) 2021-10-20 03:09:58 +03:00
9d4f85624d add ability to read argument list from file 2021-10-20 02:15:59 +03:00
295f810222 logger improvements
* remove build log since it has no usages actually (replaced by root
  logger)
* decrease boto3 log levels to INFO by default to reduce noice
2021-10-20 02:12:49 +03:00
d8523bd83b always return json in responses 2021-10-20 02:12:39 +03:00
be017ed102 Release 1.5.0 2021-10-18 03:48:24 +03:00
c73f24f8c6 minor architecture description update 2021-10-18 03:35:39 +03:00
0d806e3471 add repo-status-update subcommand 2021-10-17 06:38:49 +03:00
20962f0385 allow to use multiple upload and report targets with the same name
In this feature target option must allways point to section name instead
of type. Type will be read from type option. In case if type option is
not presented it will try to check if section with architecture exists
(e.g. target = email, section = email:x86_64); if it does, the correct
section name and type will be used. Otherwise it will check if the
specified section exists; if it does, seection name and type will be
returned.
2021-10-17 06:06:08 +03:00
fd38dfd176 split github upload into generic http method and github specific
We might use some features from the http upload for another parser
2021-10-15 23:36:26 +03:00
5f7f58041d docs update 2021-10-15 04:55:46 +03:00
233b1f7f39 disallow to create tree in case of unsafe run 2021-10-14 04:53:09 +03:00
a83f1d5aa5 use generic removal method 2021-10-14 04:08:21 +03:00
be09c04e78 change method spelling
in order to sort method correctly we are going to use the following
namiing schema:

{subject}_{action}_{details}

This schema still have some exceptions, e.g. single word methods, bool
methods (is_) and getters in case if they are singular (i.e. there is
no any other method with this subject)
2021-10-14 04:01:54 +03:00
bfbbb987ad add test for every file 2021-10-14 03:34:12 +03:00
04f365f1a6 aggressive small case 2021-10-14 03:13:15 +03:00
86bd49ed1b exactly one called with instead of last call check 2021-10-14 03:12:45 +03:00
f6ad609616 github upload support (#41) 2021-10-14 02:30:13 +03:00
2f5790f69f add ability to add manually stored packages (#40)
* add ability to add manually stored packages

* update tests

* handle manual packages in remove-unknown method

* live fixes

also rename branches to has_remotes method and change return type
2021-10-12 21:15:35 +03:00
faaf72a840 improve scripts
move logic to separated shell scripts and also create shell script for
repository setup

Also force create directory according to systemd recommendations
2021-10-11 02:20:16 +03:00
ef44895b0d more verbose help messages 2021-10-07 01:56:22 +03:00
5cfffbcd46 patch control subcommands 2021-10-05 08:57:42 +03:00
3e0058620b patch support (#35) 2021-10-03 15:20:36 +03:00
e897e2cde2 do not write anything on httpexceptions in log 2021-10-03 02:05:28 +03:00
edef4944f6 replace no-log with quiet
Also behavior of the flag has been changed: now it disables logs at all
2021-10-03 01:59:33 +03:00
a4eaf87116 Release 1.4.1 2021-10-03 01:02:41 +03:00
1192f12f91 do not use set_defaults for architecture arguments
according to the source code defaults always updates the values
dictionary. This in this specific case it is impossible to override the
value it will be always empty list.

In order to handle it we are adding another property to the Handler
class which allows to run with None architecture list.

This particular set_defaults behaviour is still useful for other cases
when we have to run command without any specific architecture
2021-10-03 00:59:24 +03:00
444da87fdc Release 1.4.0 2021-10-01 09:25:35 +03:00
6be6614e6d add package request endpoint 2021-10-01 08:58:50 +03:00
8add507957 docs update 2021-09-26 14:39:35 +03:00
af5363d158 add index url 2021-09-26 14:29:42 +03:00
d60c553ea2 add debugtoolbar support 2021-09-26 12:31:12 +03:00
5a6d0e0000 set both value and innerText during search
current implementation just adds package name with the description which
is incorrect
2021-09-26 10:34:21 +03:00
427ba0f0ea add ability to specify package source explicitly during the addition 2021-09-26 09:55:14 +03:00
266d2bd77d define permissions in views directly 2021-09-25 17:03:46 +03:00
f333e89bd1 only set file rights if requested 2021-09-23 20:36:22 +03:00
659db071a1 raise httpexception instead of returning it from a function 2021-09-19 14:28:24 +03:00
56c642e2a9 add manpage 2021-09-19 13:56:11 +03:00
845bc9b5e8 Release 1.3.0 2021-09-18 06:28:52 +03:00
57f45fdc89 better reload 2021-09-17 19:15:53 +03:00
ba483173af update aioauth-client to newest version 2021-09-17 18:45:43 +03:00
6d1f641e50 add ability to reload authentication module 2021-09-17 16:05:38 +03:00
0cf7756ec4 add ability to remove an user
also replace old user by new one before creation
2021-09-16 02:41:56 +03:00
b561bcc25d remove own implementations of getlist and getpath method in order to use
converters feature
2021-09-14 03:57:20 +03:00
25d76b0482 add ability to filter status response by package status 2021-09-13 23:27:36 +03:00
d2fe4b044f raise InvalidCommand exception in case if remove option supplied without
package
2021-09-13 22:38:38 +03:00
22272167e6 change spelling for distro name 2021-09-13 02:49:22 +03:00
38dce8c0fe add target for architecture and also update it 2021-09-13 02:01:48 +03:00
68aa327670 expiration on server side support (#33) 2021-09-13 01:18:04 +03:00
04f6af58d9 send data in json_responses in case of error instead of text 2021-09-12 22:41:02 +03:00
41c8f4c35f return description from the search 2021-09-12 22:31:34 +03:00
168b2f6880 OAuth2 (#32)
* make auth method asyncs

* oauth2 demo support

* full coverage

* update docs
2021-09-12 21:41:38 +03:00
14e8eee986 remove deprecated access status 2021-09-11 23:06:30 +03:00
88c8c929dc add error description to modals 2021-09-11 23:05:51 +03:00
5bb244cbe8 add static files support and cookie expiration settings 2021-09-11 16:34:43 +03:00
f3fd0780fb documentation update 2021-09-10 03:32:45 +03:00
11c03a9041 Add ability to trigger updates from the web (#31)
* add external process spawner and update test cases

* pass no_report to handlers

* provide service api endpoints

* do not spawn process for single architecture run

* pass no report to handlers

* make _call method of handlers public and also simplify process spawn

* move update under add

* implement actions from web page

* clear logging & improve l&f
2021-09-10 00:33:35 +03:00
214f319123 add option to set user-password for service when updating its hash 2021-09-05 15:40:03 +03:00
cfbc9d3267 move api endpoints to status-api 2021-09-05 06:46:14 +03:00
0f4c89145b allow head for every get request 2021-09-05 06:41:50 +03:00
49a05d0520 add repository name to base tempalte 2021-09-05 06:15:24 +03:00
19d1e17727 allow read only pages to be requested without authorization 2021-09-05 06:09:43 +03:00
d7bf647493 update docs 2021-09-05 05:38:45 +03:00
19ba2ba8e5 migration of jinja tempaltes to bootstrap (#30) 2021-09-05 05:27:58 +03:00
f49894107a add remove uknown method (#29) 2021-09-03 02:28:27 +03:00
233ba9c415 add license header to __init__.py 2021-09-02 23:43:05 +03:00
b7cff0a19d Auth support (#25)
* initial auth implementation

* add create user parser

* add tests

* update dependencies list

* add login annd logout to index also improve auth

* realworld fixes

* add method set_option to Configuration and also use it everywhere
* split CreateUser handler to additional read method
* check user duplicate on auth mapping read
* generate salt by using passlib instead of random.choice
* case-insensetive usernames
* update dependencies
* update configuration reference
* improve tests

* fix codefactor errors

* hide fields if authorization is enabled, but no auth supplied

* add settings object for auth provider

* readme update
2021-09-02 23:36:00 +03:00
60b94b9ac0 use {} instead of dict literal according to pylint recommendation 2021-08-22 13:24:42 +03:00
284f449225 Release 1.2.6 2021-08-21 16:19:21 +03:00
d18df0935e Release 1.2.5 2021-08-19 02:36:05 +03:00
c15cc4b853 disable manpages building for now since it requires installed distribution 2021-08-19 02:35:48 +03:00
fc67778e89 Release 1.2.4 2021-08-19 00:45:58 +03:00
39ac9d4e1f include setup.cfg to tarball 2021-08-19 00:45:26 +03:00
bc923b0e8f Release 1.2.3 2021-08-19 00:18:12 +03:00
2842e40bf7 split S3.sync to different methods 2021-08-18 23:59:18 +03:00
343768e015 guess mime type for local files 2021-08-18 05:04:26 +03:00
8f55cc600e add manpage generator 2021-08-17 04:05:18 +03:00
c757554148 Release 1.2.2 2021-08-17 01:03:04 +03:00
899603e4b9 fix typo in log naming 2021-08-17 01:02:42 +03:00
f488105fd2 Release 1.2.1 2021-08-17 00:52:09 +03:00
2e89b9483f logging rethink
* well lets replace f-strings by %s as it is originally recommended
* use syslog handler by default
2021-08-17 00:23:34 +03:00
d3a00e1937 use asyncmock from unittest library 2021-08-11 21:09:10 +03:00
d9b4015be5 Release 1.2.0 2021-08-11 05:02:23 +03:00
c6b550761b cleanup and speedup runs 2021-08-11 04:59:45 +03:00
0129ec39ec use nosec instead of disabling mktemp rule 2021-08-11 02:51:29 +03:00
62661c9fb1 add bandit integration and fix its warnings 2021-08-11 02:45:13 +03:00
78636c2035 web templates improvements
* enable jinja autoescape by default for jinja raw generator
* allow to search by multiple strings (OR)
* replace test templates by symlink
2021-08-11 02:12:14 +03:00
47c4e5bb42 move web server to loopback by default 2021-08-11 02:02:18 +03:00
d548fa02f0 add docstrings for every fixture and test methods
also add tests for missing components
2021-08-11 01:55:27 +03:00
b5c6c286f7 skip update process if no update supplied 2021-08-10 23:25:12 +03:00
aad599be67 Native s3 sync (#23)
* Native S3 sync implementation

* fix imports

* fix paths reading

* install s3 components duriing test stage
2021-08-10 23:18:56 +03:00
f8ff2cbf5b Release 1.1.0 2021-07-05 22:11:14 +03:00
dad3f418ad handle provides list 2021-07-05 22:08:04 +03:00
c455bd34ce install types for mypy 2021-06-28 02:54:20 +03:00
69b319d39a remove type: ignore for newest python 2021-06-28 02:32:54 +03:00
33cfa8fef8 Feature/all archs (#21)
* add init subcommand

* add also init command to repository object

* add ability to generate list of architectures

* check if architecture list is not empty
2021-05-23 16:40:40 +03:00
9d37e3ae23 imply no-log for every unsafe parser (#20) 2021-05-19 23:30:59 +03:00
2eb2d3a70a allow to specify list of package dependencies in rebuild target
also replace nargs= by action=append in non-positional args. It is
required to make arguments parsing result more predictable and
consistent
2021-04-18 13:34:27 +03:00
46389b87e7 Release 1.0.0 2021-04-10 01:38:55 +03:00
856a94ff00 import pgp key implementation (#17)
* import pgp key implementation

* do not ask confirmation for local sign. Also add argparser test

* superseed requests by python-aur package

* ...and drop --skippgpcheck makgepkg flag by default
2021-04-10 01:37:45 +03:00
a0e6009876 better naming for actions 2021-04-09 20:02:17 +03:00
f2b39fe439 add search subparser (#15) 2021-04-09 11:57:06 +03:00
213b2c65a0 Add web status route (#13)
* add status route

* typed status and get status at the start of application
2021-04-08 01:48:53 +03:00
a416214e5f Move search line inside extended report option 2021-04-06 17:03:34 +03:00
e5966c497f Release 0.22.1 2021-04-06 05:54:04 +03:00
fbccb1394d format long line 2021-04-06 05:53:38 +03:00
01887ec44b add ability to skip email report generation for empty update list 2021-04-06 05:51:50 +03:00
4d4ddffa8f Release 0.22.0 2021-04-06 05:46:12 +03:00
4729c0ea5f Email report (#11)
* Demo email report implementation

* improved ssl mode

* correct default option spelling and more fields to be hidden for not
extended reports
2021-04-06 05:45:17 +03:00
035a23a8de Release 0.21.4 2021-04-05 02:28:38 +03:00
0d37ce5095 drop changelog
the main reason is that it uses github to generate changelog. Thus it
will be updated AFTER release is created
2021-04-05 02:27:12 +03:00
70465b5044 Release 0.21.3 2021-04-05 02:22:44 +03:00
81afa23d98 update changelog at correct step
also fix commit filter and do not update sha anymore
2021-04-05 02:22:11 +03:00
1b979725a3 Release 0.21.2 2021-04-05 02:01:28 +03:00
c2c7ee6292 add changelog generator to both gh-actions and repository 2021-04-05 02:00:05 +03:00
a3fe361596 Release 0.21.1 2021-04-05 00:45:12 +03:00
20d13f1c10 use globing instead 2021-04-05 00:44:39 +03:00
6c96c9e73a Release 0.21.0 2021-04-05 00:38:23 +03:00
9b08b0694e try to make auto archive upload 2021-04-05 00:37:03 +03:00
fcb892f39f implicit type conversion from command line 2021-04-04 23:53:30 +03:00
1785b0470f more options in setup command 2021-04-04 15:42:06 +03:00
c04f940ad3 fix check errors 2021-04-04 14:00:42 +03:00
207da4caa7 100% coverage 2021-04-03 21:30:57 +03:00
cad85b0f20 add ability to fitler by dependency list 2021-04-02 04:20:39 +03:00
3e8e54857f add ability to remove package from status page 2021-04-02 01:26:46 +03:00
6470b13511 Release 0.20.0 2021-04-01 02:38:59 +03:00
4e08297311 constistent classmethod and staticmethod usage
General idea is to use classmethod for every constructor and
statismethod otherwise.
Also use self and cls whenever it's possible to call static and class
methods
2021-03-31 04:29:08 +03:00
32c3c52874 change arch specific section naming from section_arch to section:arch
Some archs can have _ in their name. Also in future we can use sections
with similar names
2021-03-31 02:31:14 +03:00
e637a647c5 Release 0.19.0 2021-03-31 02:19:44 +03:00
e21b990777 add now argument to add command 2021-03-31 02:19:13 +03:00
c0be7f7a17 filter out every foreign arch in config 2021-03-31 01:55:39 +03:00
612cb2fa22 read sign targets from correct path 2021-03-31 00:11:05 +03:00
cf276f2398 make configuration object arch-specific 2021-03-31 00:04:13 +03:00
4ca2348f0d more verbose variables 2021-03-30 05:29:13 +03:00
eb02e1e62b merge settings groups instead of using whole group 2021-03-30 04:58:15 +03:00
8d7d508bb2 move rsync and s3 options to configuration 2021-03-30 02:38:18 +03:00
a875225b78 verbose help message 2021-03-30 02:25:23 +03:00
5449dec32a add status badge 2021-03-30 02:01:59 +03:00
eb7f3b2484 rename gpg test to correct naming 2021-03-30 01:53:23 +03:00
e87402fdde add more tests 2021-03-30 01:42:01 +03:00
3996055f56 Release 0.18.0 2021-03-29 11:48:54 +03:00
74fc283078 more properties to be shown in status pages 2021-03-29 11:48:32 +03:00
eb92f75384 architecture depending pacman.conf 2021-03-29 10:08:11 +03:00
63529633ec add status update subcommand
also satisfy pylint with too big method with too much variables
2021-03-29 04:17:10 +03:00
930b47c704 Release 0.17.0 2021-03-29 03:25:43 +03:00
a89888769f Setup command (#9)
* block issues without templates

* add setup subcommand

* handle devtools config correctly
2021-03-29 03:24:58 +03:00
b6bc1b77dc more templates 2021-03-29 00:13:20 +03:00
4a462502e7 Add issue templates 2021-03-28 23:50:41 +03:00
f383b04754 try to integrate with github workflows 2021-03-28 23:13:42 +03:00
d744fe1647 remove unused import 2021-03-28 16:24:51 +03:00
6f1b37c4cb add sign command (#7) (#8) 2021-03-28 16:24:00 +03:00
5cb3fd5853 Release 0.16.0 2021-03-28 15:38:12 +03:00
60b8477cde Add tests (#1) (#5)
* add models tests (#1)

also replace single quote to double one to confort PEP docstring
+ move _check_output to class properties to make it available for
mocking

* alpm tests implementation

* try to replace os with pathlib

* update tests for pathlib

* fix includes glob and trim version from dependencies

* build_tools package tests

* repository component tests

* add sign tests

* complete status tests

* handle exceptions in actual_version calls

* complete core tests

* move configuration to root conftest

* application tests

* complete application tests

* change copyright to more generic one

* base web tests

* complete web tests

* complete testkit

also add argument parsers test
2021-03-28 15:30:51 +03:00
826 changed files with 49866 additions and 20394 deletions

View File

@ -1 +1,6 @@
skips: ['B101', 'B104', 'B105', 'B106', 'B404']
skips:
- B101
- B104
- B105
- B106
- B404

View File

@ -1 +1,3 @@
skips: ['B404', 'B603']
skips:
- B404
- B603

View File

@ -9,5 +9,4 @@ Put `closes #ISSUE` in case if the pull requests solves one of the opened issues
### Checklist
- [ ] Tests to cover new code
- [ ] `make check` passed
- [ ] `make tests` passed
- [ ] `tox` passed

View File

@ -1,42 +0,0 @@
name: docker image
on:
push:
branches: [ master ]
tags:
- '*'
- '!*rc*'
jobs:
docker-image:
runs-on: ubuntu-latest
steps:
- name: extract docker metadata
id: meta
uses: docker/metadata-action@v3
with:
images: |
arcan1s/ahriman
tags: |
type=ref,event=tag
type=edge
- name: setup QEMU
uses: docker/setup-qemu-action@v1
- name: setup docker buildx
uses: docker/setup-buildx-action@v1
- name: login to docker hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: build an image and push
uses: docker/build-push-action@v2
with:
push: true
tags: ${{ steps.meta.outputs.tags }}

53
.github/workflows/docker.yml vendored Normal file
View File

@ -0,0 +1,53 @@
name: Docker image
on:
push:
branches:
- master
tags:
- '*'
- '!*rc*'
jobs:
docker-image:
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- uses: docker/setup-qemu-action@v2
- uses: docker/setup-buildx-action@v2
- name: Login to docker hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to github container registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract docker metadata
id: meta
uses: docker/metadata-action@v3
with:
images: |
arcan1s/ahriman
ghcr.io/arcan1s/ahriman
tags: |
type=semver,pattern={{raw}}
type=edge
- name: Build an image and push
uses: docker/build-push-action@v4
with:
file: docker/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}

136
.github/workflows/regress.yml vendored Normal file
View File

@ -0,0 +1,136 @@
name: Regress
on: workflow_dispatch
jobs:
run-regress-tests:
runs-on: ubuntu-latest
services:
ahriman:
image: arcan1s/ahriman:edge
env:
AHRIMAN_PORT: 8080
AHRIMAN_UNIX_SOCKET: /var/lib/ahriman/ahriman/ahriman-web.sock
options: --privileged --entrypoint entrypoint-web
ports:
- 8080
volumes:
- repo:/var/lib/ahriman
container:
image: arcan1s/ahriman:edge
env:
AHRIMAN_DEBUG: y
AHRIMAN_OUTPUT: console
AHRIMAN_PORT: 8080
AHRIMAN_UNIX_SOCKET: /var/lib/ahriman/ahriman/ahriman-web.sock
options: --privileged
volumes:
- repo:/var/lib/ahriman
steps:
- uses: actions/checkout@v3
- run: pacman -Sy
- name: Init repository
run: entrypoint help
- name: Print configuration
run: |
ahriman \
--log-handler "$AHRIMAN_OUTPUT" \
service-config
- name: Validate configuration
run: |
ahriman \
--log-handler "$AHRIMAN_OUTPUT" \
service-config-validate
- name: Create a user
run: |
sudo -u ahriman ahriman \
--log-handler "$AHRIMAN_OUTPUT" \
user-add \
--packager "github actions <actions@github.com>" \
--password ahriman \
--role full \
ahriman
- name: Fetch users
run: |
ahriman \
--log-handler "$AHRIMAN_OUTPUT" \
user-list \
--exit-code
- name: Add package
run: |
sudo -u ahriman ahriman \
--log-handler "$AHRIMAN_OUTPUT" \
package-add \
--exit-code \
--now \
--refresh \
ahriman
- name: Update status of the package
run: |
ahriman \
--log-handler "$AHRIMAN_OUTPUT" \
package-status-update \
--status failed \
ahriman
- name: Request status of the package
run: |
ahriman \
--log-handler "$AHRIMAN_OUTPUT" \
package-status \
--exit-code \
--info \
--status failed \
ahriman
- name: Update packages
run: |
sudo -u ahriman ahriman \
--log-handler "$AHRIMAN_OUTPUT" \
repo-update \
--exit-code \
|| true
- name: Add patch
run: |
echo '${pkgver%%.*}' | \
sudo -u ahriman ahriman \
--log-handler "$AHRIMAN_OUTPUT" \
patch-add \
ahriman \
pkgrel
- name: Retrieve patches
run: |
ahriman \
--log-handler "$AHRIMAN_OUTPUT" \
patch-list \
--exit-code \
ahriman
- name: Rebuild packages
run: |
sudo -u ahriman ahriman \
--log-handler "$AHRIMAN_OUTPUT" \
repo-rebuild \
--depends-on python \
--exit-code
- name: Remove package
run: |
sudo -u ahriman ahriman \
--log-handler "$AHRIMAN_OUTPUT" \
package-remove \
ahriman

View File

@ -1,4 +1,4 @@
name: release
name: Release
on:
push:
@ -11,31 +11,36 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: extract version
- name: Extract version
id: version
run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/}
- name: create changelog
- name: Create changelog
id: changelog
uses: jaywcjlove/changelog-generator@main
with:
token: ${{ secrets.GITHUB_TOKEN }}
filter: 'Release \d+\.\d+\.\d+'
- name: create archive
run: make archive
- name: Install dependencies
uses: ConorMacBride/install-package@v1.1.0
with:
apt: tox
- name: Create archive
run: tox -e archive
env:
VERSION: ${{ steps.version.outputs.VERSION }}
- name: release
- name: Publish release
uses: softprops/action-gh-release@v1
with:
body: |
${{ steps.changelog.outputs.compareurl }}
${{ steps.changelog.outputs.changelog }}
files: ahriman-*-src.tar.xz
files: dist/ahriman-*.tar.gz
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -6,55 +6,59 @@ set -ex
[[ $1 = "minimal" ]] && MINIMAL_INSTALL=1
# install dependencies
echo -e '[arcanisrepo]\nServer = http://repo.arcanis.me/$arch\nSigLevel = Never' | tee -a /etc/pacman.conf
echo -e '[arcanisrepo]\nServer = https://repo.arcanis.me/$arch\nSigLevel = Never' | tee -a /etc/pacman.conf
# refresh the image
pacman --noconfirm -Syu
pacman -Syyu --noconfirm
# main dependencies
pacman --noconfirm -Sy base-devel devtools git pyalpm python-cerberus python-inflection python-passlib python-requests python-srcinfo sudo
pacman -S --noconfirm devtools git pyalpm python-bcrypt python-inflection python-pyelftools python-requests python-systemd sudo
# make dependencies
pacman --noconfirm -Sy python-build python-installer python-wheel
pacman -S --noconfirm --asdeps base-devel python-build python-flit python-installer python-tox python-wheel
# optional dependencies
if [[ -z $MINIMAL_INSTALL ]]; then
# VCS support
pacman --noconfirm -Sy breezy darcs mercurial subversion
# web server
pacman --noconfirm -Sy python-aioauth-client python-aiohttp python-aiohttp-apispec-git python-aiohttp-cors python-aiohttp-debugtoolbar python-aiohttp-jinja2 python-aiohttp-security python-aiohttp-session python-cryptography python-jinja
pacman -S --noconfirm python-aioauth-client python-aiohttp python-aiohttp-apispec-git python-aiohttp-cors python-aiohttp-jinja2 python-aiohttp-security python-aiohttp-session python-cryptography python-jinja
# additional features
pacman --noconfirm -Sy gnupg python-boto3 rsync
pacman -S --noconfirm gnupg ipython python-boto3 python-cerberus python-matplotlib rsync
fi
# FIXME since 1.0.4 devtools requires dbus to be run, which doesn't work now in container
cp "docker/systemd-nspawn.sh" "/usr/local/bin/systemd-nspawn"
# create fresh tarball
make VERSION=1.0.0 archlinux # well, it does not really matter which version we will put here
tox -e archive
# run makepkg
mv ahriman-*-src.tar.xz package/archlinux
PKGVER=$(python -c "from src.ahriman import __version__; print(__version__)")
mv "dist/ahriman-$PKGVER.tar.gz" package/archlinux
chmod +777 package/archlinux # because fuck you that's why
cd package/archlinux
sudo -u nobody -- makepkg -cf --skipchecksums --noconfirm
pacman --noconfirm -U ahriman-1.0.0-1-any.pkg.tar.zst
sudo -u nobody -- makepkg --packagelist | grep "ahriman-core-$PKGVER" | pacman -U --noconfirm --nodeps -
if [[ -z $MINIMAL_INSTALL ]]; then
sudo -u nobody -- makepkg --packagelist | grep "ahriman-triggers-$PKGVER" | pacman -U --noconfirm --nodeps -
sudo -u nobody -- makepkg --packagelist | grep "ahriman-web-$PKGVER" | pacman -U --noconfirm --nodeps -
fi
# create machine-id which is required by build tools
systemd-machine-id-setup
# special thing for the container, because /dev/log interface is not available there
sed -i "s/handlers = syslog_handler/handlers = console_handler/g" /etc/ahriman.ini.d/logging.ini
# remove unused dependencies
pacman -Qdtq | pacman -Rscn --noconfirm -
# initial setup command as root
[[ -z $MINIMAL_INSTALL ]] && WEB_ARGS=("--web-port" "8080")
ahriman -a x86_64 service-setup --packager "ahriman bot <ahriman@example.com>" --repository "github" "${WEB_ARGS[@]}"
# validate configuration
ahriman -a x86_64 service-config-validate --exit-code
ahriman -a x86_64 -r "github" service-setup --packager "ahriman bot <ahriman@example.com>" "${WEB_ARGS[@]}"
# enable services
systemctl enable ahriman-web@x86_64
systemctl enable ahriman@x86_64.timer
systemctl enable ahriman@x86_64-github.timer
if [[ -z $MINIMAL_INSTALL ]]; then
# validate configuration
ahriman service-config-validate --exit-code
# run web service (detached)
sudo -u ahriman -- ahriman -a x86_64 web &
systemctl enable ahriman-web
sudo -u ahriman -- ahriman web &
WEB_PID=$!
sleep 15s # wait for the web service activation
fi
# add the first package
# the build itself does not really work in the container
sudo -u ahriman -- ahriman package-add --now yay
sudo -u ahriman -- ahriman --log-handler console package-add --now ahriman
# check if package was actually installed
test -n "$(find "/var/lib/ahriman/repository/x86_64" -name "yay*pkg*")"
test -n "$(find "/var/lib/ahriman/repository/github/x86_64" -name "ahriman*pkg*")"
# run package check
sudo -u ahriman -- ahriman repo-update
# stop web service lol

View File

@ -1,10 +1,12 @@
name: setup
name: Setup
on:
push:
branches: [ master ]
branches:
- master
pull_request:
branches: [ master ]
branches:
- master
jobs:
run-setup-minimal:
@ -12,15 +14,15 @@ jobs:
runs-on: ubuntu-latest
container:
image: archlinux:latest
image: archlinux:base
options: --privileged -w /build
volumes:
- ${{ github.workspace }}:/build
options: --privileged -w /build
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: setup the minimal service in arch linux container
- name: Setup the minimal service in arch linux container
run: .github/workflows/setup.sh minimal
run-setup:
@ -28,13 +30,13 @@ jobs:
runs-on: ubuntu-latest
container:
image: archlinux:latest
image: archlinux:base
volumes:
- ${{ github.workspace }}:/build
options: --privileged -w /build
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: setup the service in arch linux container
- name: Setup the service in arch linux container
run: .github/workflows/setup.sh

View File

@ -4,7 +4,7 @@
set -ex
# install dependencies
pacman --noconfirm -Syu base-devel python-setuptools python-tox
pacman --noconfirm -Syyu base-devel python-tox
# run test and check targets
make check tests
tox

View File

@ -1,10 +1,14 @@
name: tests
name: Tests
on:
push:
branches: [ master ]
branches:
- master
pull_request:
branches: [ master ]
branches:
- master
schedule:
- cron: 1 0 * * *
jobs:
run-tests:
@ -12,13 +16,13 @@ jobs:
runs-on: ubuntu-latest
container:
image: archlinux:latest
image: archlinux:base
options: -w /build
volumes:
- ${{ github.workspace }}:/build
options: -w /build
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: run check and tests in arch linux container
- name: Run check and tests in arch linux container
run: .github/workflows/tests.sh

806
.pylintrc
View File

@ -1,28 +1,78 @@
[MASTER]
[MAIN]
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
# Clear in-memory caches upon conclusion of linting. Useful if running pylint
# in a server-like mode.
clear-cache-post-run=no
# Load and enable all available extensions. Use --list-extensions to see a list
# all available extensions.
#enable-all-extensions=
# In error mode, messages with a category besides ERROR or FATAL are
# suppressed, and no reports are done by default. Error mode is compatible with
# disabling specific errors.
#errors-only=
# Always return a 0 (non-error) status code, even if lint errors are found.
# This is primarily useful in continuous integration scripts.
#exit-zero=
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code.
extension-pkg-allow-list=
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code. (This is an alternative name to extension-pkg-allow-list
# for backward compatibility.)
extension-pkg-whitelist=
# Specify a score threshold to be exceeded before program exits with error.
fail-under=10.0
# Return non-zero exit code if any of these messages/categories are detected,
# even if score is above --fail-under value. Syntax same as enable. Messages
# specified are enabled, while categories only check already-enabled messages.
fail-on=
# Add files or directories to the blacklist. They should be base names, not
# paths.
# Specify a score threshold under which the program will exit with error.
fail-under=10
# Interpret the stdin as a python script, whose filename needs to be passed as
# the module_or_package argument.
#from-stdin=
# Files or directories to be skipped. They should be base names, not paths.
ignore=CVS
# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
ignore-patterns=
# Add files or directories matching the regular expressions patterns to the
# ignore-list. The regex matches against paths and can be in Posix or Windows
# format. Because '\\' represents the directory delimiter on Windows systems,
# it can't be used as an escape character.
ignore-paths=
# Files or directories matching the regular expression patterns are skipped.
# The regex matches against base names, not paths. The default value ignores
# Emacs file locks
ignore-patterns=^\.#
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis). It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
init-hook='import sys; sys.path.append("pylint_plugins")'
# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
# number of processors available to use.
jobs=0
# number of processors available to use, and will cap the count on Windows to
# avoid hangs.
jobs=1
# Control the amount of potential inferred values when inferring a single
# object. This can help the performance when dealing with large functions or
@ -31,11 +81,27 @@ limit-inference-results=100
# List of plugins (as comma separated values of python module names) to load,
# usually to register additional checkers.
load-plugins=
load-plugins=pylint.extensions.docparams,
pylint.extensions.bad_builtin,
definition_order,
import_order,
# Pickle collected data for later comparisons.
persistent=yes
# Minimum Python version to use for version dependent checks. Will default to
# the version used to run pylint.
py-version=3.11
# Discover python modules and packages in the file system subtree.
recursive=no
# Add paths to the list of the source roots. Supports globbing patterns. The
# source root is an absolute path or a path relative to the current working
# directory used to determine a package namespace for modules located under the
# source root.
source-roots=
# When enabled, pylint would attempt to guess common misconfiguration and emit
# user-friendly hints instead of false-positive error messages.
suggestion-mode=yes
@ -44,18 +110,318 @@ suggestion-mode=yes
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
# In verbose mode, extra non-checker-related info will be displayed.
#verbose=
[BASIC]
# Naming style matching correct argument names.
argument-naming-style=snake_case
# Regular expression matching correct argument names. Overrides argument-
# naming-style. If left empty, argument names will be checked with the set
# naming style.
#argument-rgx=
# Naming style matching correct attribute names.
attr-naming-style=snake_case
# Regular expression matching correct attribute names. Overrides attr-naming-
# style. If left empty, attribute names will be checked with the set naming
# style.
#attr-rgx=
bad-functions=print,
# Bad variable names which should always be refused, separated by a comma.
bad-names=foo,
bar,
baz,
toto,
tutu,
tata
# Bad variable names regexes, separated by a comma. If names match any regex,
# they will always be refused
bad-names-rgxs=
# Naming style matching correct class attribute names.
class-attribute-naming-style=any
# Regular expression matching correct class attribute names. Overrides class-
# attribute-naming-style. If left empty, class attribute names will be checked
# with the set naming style.
#class-attribute-rgx=
# Naming style matching correct class constant names.
class-const-naming-style=UPPER_CASE
# Regular expression matching correct class constant names. Overrides class-
# const-naming-style. If left empty, class constant names will be checked with
# the set naming style.
#class-const-rgx=
# Naming style matching correct class names.
class-naming-style=PascalCase
# Regular expression matching correct class names. Overrides class-naming-
# style. If left empty, class names will be checked with the set naming style.
#class-rgx=
# Naming style matching correct constant names.
const-naming-style=UPPER_CASE
# Regular expression matching correct constant names. Overrides const-naming-
# style. If left empty, constant names will be checked with the set naming
# style.
#const-rgx=
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
# Naming style matching correct function names.
function-naming-style=snake_case
# Regular expression matching correct function names. Overrides function-
# naming-style. If left empty, function names will be checked with the set
# naming style.
#function-rgx=
# Good variable names which should always be accepted, separated by a comma.
good-names=i,
j,
k,
ex,
Run,
_
# Good variable names regexes, separated by a comma. If names match any regex,
# they will always be accepted
good-names-rgxs=
# Include a hint for the correct naming format with invalid-name.
include-naming-hint=no
# Naming style matching correct inline iteration names.
inlinevar-naming-style=any
# Regular expression matching correct inline iteration names. Overrides
# inlinevar-naming-style. If left empty, inline iteration names will be checked
# with the set naming style.
#inlinevar-rgx=
# Naming style matching correct method names.
method-naming-style=snake_case
# Regular expression matching correct method names. Overrides method-naming-
# style. If left empty, method names will be checked with the set naming style.
#method-rgx=
# Naming style matching correct module names.
module-naming-style=snake_case
# Regular expression matching correct module names. Overrides module-naming-
# style. If left empty, module names will be checked with the set naming style.
#module-rgx=
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
# These decorators are taken in consideration only for invalid-name.
property-classes=abc.abstractproperty
# Regular expression matching correct type alias names. If left empty, type
# alias names will be checked with the set naming style.
#typealias-rgx=
# Regular expression matching correct type variable names. If left empty, type
# variable names will be checked with the set naming style.
#typevar-rgx=
# Naming style matching correct variable names.
variable-naming-style=snake_case
# Regular expression matching correct variable names. Overrides variable-
# naming-style. If left empty, variable names will be checked with the set
# naming style.
#variable-rgx=
[CLASSES]
# Warn about protected attribute access inside special methods
check-protected-access-in-special-methods=no
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,
__new__,
setUp,
asyncSetUp,
__post_init__
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,_fields,_replace,_source,_make,os._exit
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
[DESIGN]
# List of regular expressions of class ancestor names to ignore when counting
# public methods (see R0903)
exclude-too-few-public-methods=
# List of qualified class names to ignore when counting class parents (see
# R0901)
ignored-parents=
# Maximum number of arguments for function / method.
max-args=5
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Maximum number of boolean expressions in an if statement (see R0916).
max-bool-expr=5
# Maximum number of branch for function / method body.
max-branches=12
# Maximum number of locals for function / method body.
max-locals=15
# Maximum number of parents for a class (see R0901).
max-parents=15
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
# Maximum number of return / yield for function / method body.
max-returns=6
# Maximum number of statements in function / method body.
max-statements=50
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
[EXCEPTIONS]
# Exceptions that will emit a warning when caught.
overgeneral-exceptions=builtins.BaseException,builtins.Exception
[FORMAT]
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Maximum number of characters on a single line.
max-line-length=100
# Maximum number of lines in a module.
max-module-lines=1000
# Allow the body of a class to be on the same line as the declaration if body
# contains single statement.
single-line-class-stmt=no
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
[IMPORTS]
# List of modules that can be imported at any level, not just the top level
# one.
allow-any-import-level=
# Allow explicit reexports by alias from a package __init__.
allow-reexport-from-package=no
# Allow wildcard imports from modules that define __all__.
allow-wildcard-with-all=no
# Deprecated modules which should not be used, separated by a comma.
deprecated-modules=
# Output a graph (.gv or any supported image format) of external dependencies
# to the given file (report RP0402 must not be disabled).
ext-import-graph=
# Output a graph (.gv or any supported image format) of all (i.e. internal and
# external) dependencies to the given file (report RP0402 must not be
# disabled).
import-graph=
# Output a graph (.gv or any supported image format) of internal dependencies
# to the given file (report RP0402 must not be disabled).
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=enchant
# Couples of modules and preferred modules, separated by a comma.
preferred-modules=
[LOGGING]
# The type of string formatting that logging methods do. `old` means using %
# formatting, `new` is for `{}` formatting.
logging-format-style=old
# Logging modules to check that the string format arguments are in logging
# function parameter format.
logging-modules=logging
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
confidence=
# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE,
# UNDEFINED.
confidence=HIGH,
CONTROL_FLOW,
INFERENCE,
INFERENCE_FAILURE,
UNDEFINED
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once). You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# disable everything first and then re-enable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use "--disable=all --enable=classes
@ -78,13 +444,11 @@ disable=raw-checker-failed,
too-few-public-methods,
too-many-instance-attributes,
broad-except,
too-many-ancestors,
fixme,
too-many-arguments,
duplicate-code,
cyclic-import,
confusing-with-statement,
too-many-positional-arguments,
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
@ -93,29 +457,22 @@ disable=raw-checker-failed,
enable=c-extension-no-member
[REPORTS]
[METHOD_ARGS]
# Python expression which should return a score less than or equal to 10. You
# have access to the variables 'error', 'warning', 'refactor', and 'convention'
# which contain the number of messages in each category, as well as 'statement'
# which is the total number of statements analyzed. This score is used by the
# global evaluation report (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# List of qualified names (i.e., library.method) which require a timeout
# parameter e.g. 'requests.api.get,requests.api.post'
timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details.
#msg-template=
# Set the output format. Available formats are text, parseable, colorized, json
# and msvs (visual studio). You can also give a reporter class, e.g.
# mypackage.mymodule.MyReporterClass.
output-format=text
[MISCELLANEOUS]
# Tells whether to display a full report or only the messages.
reports=no
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,
XXX,
TODO
# Activate the evaluation score.
score=yes
# Regular expression of note tags to take in consideration.
notes-rgx=
[REFACTORING]
@ -127,154 +484,85 @@ max-nested-blocks=5
# inconsistent-return-statements if a never returning function is called then
# it will be considered as an explicit return statement and no message will be
# printed.
never-returning-functions=sys.exit
never-returning-functions=sys.exit,argparse.parse_error
[FORMAT]
[REPORTS]
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
# Python expression which should return a score less than or equal to 10. You
# have access to the variables 'fatal', 'error', 'warning', 'refactor',
# 'convention', and 'info' which contain the number of messages in each
# category, as well as 'statement' which is the total number of statements
# analyzed. This score is used by the global evaluation report (RP0004).
evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10))
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details.
msg-template=
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
# Set the output format. Available formats are text, parseable, colorized, json
# and msvs (visual studio). You can also give a reporter class, e.g.
# mypackage.mymodule.MyReporterClass.
#output-format=
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Tells whether to display a full report or only the messages.
reports=no
# Maximum number of characters on a single line.
max-line-length=100
# Maximum number of lines in a module.
max-module-lines=400
# Allow the body of a class to be on the same line as the declaration if body
# contains single statement.
single-line-class-stmt=no
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
# Activate the evaluation score.
score=yes
[BASIC]
[SIMILARITIES]
# Naming style matching correct argument names.
argument-naming-style=snake_case
# Comments are removed from the similarity computation
ignore-comments=yes
# Regular expression matching correct argument names. Overrides argument-
# naming-style.
#argument-rgx=
# Docstrings are removed from the similarity computation
ignore-docstrings=yes
# Naming style matching correct attribute names.
attr-naming-style=snake_case
# Imports are removed from the similarity computation
ignore-imports=yes
# Regular expression matching correct attribute names. Overrides attr-naming-
# style.
#attr-rgx=
# Signatures are removed from the similarity computation
ignore-signatures=yes
# Bad variable names which should always be refused, separated by a comma.
bad-names=foo,
bar,
baz,
toto,
tutu,
tata
# Minimum lines number of a similarity.
min-similarity-lines=4
# Bad variable names regexes, separated by a comma. If names match any regex,
# they will always be refused
bad-names-rgxs=
# Naming style matching correct class attribute names.
class-attribute-naming-style=any
[SPELLING]
# Regular expression matching correct class attribute names. Overrides class-
# attribute-naming-style.
#class-attribute-rgx=
# Limits count of emitted suggestions for spelling mistakes.
max-spelling-suggestions=4
# Naming style matching correct class names.
class-naming-style=PascalCase
# Spelling dictionary name. No available dictionaries : You need to install
# both the python package and the system dependency for enchant to work..
spelling-dict=
# Regular expression matching correct class names. Overrides class-naming-
# style.
#class-rgx=
# List of comma separated words that should be considered directives if they
# appear at the beginning of a comment and should not be checked.
spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:
# Naming style matching correct constant names.
const-naming-style=UPPER_CASE
# List of comma separated words that should not be checked.
spelling-ignore-words=
# Regular expression matching correct constant names. Overrides const-naming-
# style.
#const-rgx=
# A path to a file that contains the private dictionary; one word per line.
spelling-private-dict-file=
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
# Tells whether to store unknown words to the private dictionary (see the
# --spelling-private-dict-file option) instead of raising a message.
spelling-store-unknown-words=no
# Naming style matching correct function names.
function-naming-style=snake_case
# Regular expression matching correct function names. Overrides function-
# naming-style.
#function-rgx=
[STRING]
# Good variable names which should always be accepted, separated by a comma.
good-names=i,
j,
k,
ex,
Run,
_
# This flag controls whether inconsistent-quotes generates a warning when the
# character used as a quote delimiter is used inconsistently within a module.
check-quote-consistency=no
# Good variable names regexes, separated by a comma. If names match any regex,
# they will always be accepted
good-names-rgxs=
# Include a hint for the correct naming format with invalid-name.
include-naming-hint=no
# Naming style matching correct inline iteration names.
inlinevar-naming-style=any
# Regular expression matching correct inline iteration names. Overrides
# inlinevar-naming-style.
#inlinevar-rgx=
# Naming style matching correct method names.
method-naming-style=snake_case
# Regular expression matching correct method names. Overrides method-naming-
# style.
#method-rgx=
# Naming style matching correct module names.
module-naming-style=snake_case
# Regular expression matching correct module names. Overrides module-naming-
# style.
#module-rgx=
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=^_
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
# These decorators are taken in consideration only for invalid-name.
property-classes=abc.abstractproperty
# Naming style matching correct variable names.
variable-naming-style=snake_case
# Regular expression matching correct variable names. Overrides variable-
# naming-style.
#variable-rgx=
# This flag controls whether the implicit-str-concat should generate a warning
# on implicit string concatenation in sequences defined over several lines.
check-str-concat-over-line-jumps=no
[TYPECHECK]
@ -289,10 +577,6 @@ contextmanager-decorators=contextlib.contextmanager
# expressions are accepted.
generated-members=
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# Tells whether to warn about missing members when the owner of the attribute
# is inferred to be None.
ignore-none=yes
@ -305,16 +589,16 @@ ignore-none=yes
# the rest of the inferred objects.
ignore-on-opaque-inference=yes
# List of symbolic message names to ignore for Mixin members.
ignored-checks-for-mixins=no-member,
not-async-context-manager,
not-context-manager,
attribute-defined-outside-init
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis). It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=
ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace
# Show a hint with possible names when a member name was not found. The aspect
# of finding the hint is based on edit distance.
@ -328,67 +612,13 @@ missing-member-hint-distance=1
# showing a hint for a missing member.
missing-member-max-choices=1
# Regex pattern to define which classes are considered mixins.
mixin-class-rgx=.*[Mm]ixin
# List of decorators that change the signature of a decorated function.
signature-mutators=
[SIMILARITIES]
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
# Minimum lines number of a similarity.
min-similarity-lines=4
[LOGGING]
# The type of string formatting that logging methods do. `old` means using %
# formatting, `new` is for `{}` formatting.
logging-format-style=old
# Logging modules to check that the string format arguments are in logging
# function parameter format.
logging-modules=logging
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,
XXX,
TODO
# Regular expression of note tags to take in consideration.
#notes-rgx=
[SPELLING]
# Limits count of emitted suggestions for spelling mistakes.
max-spelling-suggestions=4
# Spelling dictionary name. Available dictionaries: none. To make it work,
# install the python-enchant package.
spelling-dict=
# List of comma separated words that should not be checked.
spelling-ignore-words=
# A path to a file that contains the private dictionary; one word per line.
spelling-private-dict-file=
# Tells whether to store unknown words to the private dictionary (see the
# --spelling-private-dict-file option) instead of raising a message.
spelling-store-unknown-words=no
[VARIABLES]
# List of additional names supposed to be defined in builtins. Remember that
@ -398,6 +628,9 @@ additional-builtins=
# Tells whether unused global variables should be treated as a violation.
allow-global-unused-variables=yes
# List of names allowed to shadow builtins
allowed-redefined-builtins=
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,
@ -407,8 +640,7 @@ callbacks=cb_,
# not be used).
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
# Argument names that match this expression will be ignored. Default to name
# with leading underscore.
# Argument names that match this expression will be ignored.
ignored-argument-names=_.*|^ignored_|^unused_
# Tells whether we should check for unused import in __init__ files.
@ -417,121 +649,3 @@ init-import=no
# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
[STRING]
# This flag controls whether inconsistent-quotes generates a warning when the
# character used as a quote delimiter is used inconsistently within a module.
check-quote-consistency=no
# This flag controls whether the implicit-str-concat should generate a warning
# on implicit string concatenation in sequences defined over several lines.
check-str-concat-over-line-jumps=no
[IMPORTS]
# List of modules that can be imported at any level, not just the top level
# one.
allow-any-import-level=
# Allow wildcard imports from modules that define __all__.
allow-wildcard-with-all=no
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
# Deprecated modules which should not be used, separated by a comma.
deprecated-modules=optparse,tkinter.tix
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled).
ext-import-graph=
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled).
import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled).
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=enchant
# Couples of modules and preferred modules, separated by a comma.
preferred-modules=
[DESIGN]
# Maximum number of arguments for function / method.
max-args=5
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Maximum number of boolean expressions in an if statement (see R0916).
max-bool-expr=5
# Maximum number of branch for function / method body.
max-branches=12
# Maximum number of locals for function / method body.
max-locals=15
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
# Maximum number of return / yield for function / method body.
max-returns=6
# Maximum number of statements in function / method body.
max-statements=50
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
[CLASSES]
# Warn about protected attribute access inside special methods
check-protected-access-in-special-methods=no
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,
__new__,
setUp,
__post_init__
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,
_fields,
_replace,
_source,
_make
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=cls
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "BaseException, Exception".
overgeneral-exceptions=builtins.BaseException,
builtins.Exception

View File

@ -1,17 +1,11 @@
version: 2
formats:
- pdf
build:
os: ubuntu-20.04
tools:
python: "3.10"
sphinx:
builder: html
configuration: docs/conf.py
fail_on_warning: true
python: "3.12"
apt_packages:
- graphviz
python:
install:
@ -20,5 +14,13 @@ python:
extra_requirements:
- docs
- s3
- validator
- web
system_packages: true
formats:
- pdf
sphinx:
builder: html
configuration: docs/conf.py
fail_on_warning: true

View File

@ -19,14 +19,14 @@ There are some strict limitation for suggested pull requests:
### Code formatting
In order to resolve all difficult cases the `autopep8` is used. You can perform formatting at any time by running `make check` or running `autopep8` command directly.
In order to resolve all difficult cases the `autopep8` is used. You can perform formatting at any time by running `tox` or running `autopep8` command directly.
### Code style
Again, the most checks can be performed by `make check` command, though some additional guidelines must be applied:
Again, the most checks can be performed by `tox` command, though some additional guidelines must be applied:
* Every class, every function (including private and protected), every attribute must be documented. The project follows [Google style documentation](https://google.github.io/styleguide/pyguide.html). The only exception is local functions.
* Correct way to document function, if section is empty, e.g. no notes or there are no args, it should be omitted:
* Correct way to document function (if a section is empty, e.g. no notes or there are no args, it should be omitted) is the following:
```python
def foo(argument: str, *, flag: bool = False) -> int:
@ -34,8 +34,9 @@ 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
Probably multi-line
Args:
argument(str): an argument. This argument has
@ -43,10 +44,11 @@ Again, the most checks can be performed by `make check` command, though some add
flag(bool, optional): a flag (Default value = False)
Returns:
int: result
int: result with
long description
Raises:
RuntimeException: a local function error occurs
RuntimeError: a local function error occurs
Examples:
Very informative example how to use this function, e.g.::
@ -64,11 +66,12 @@ Again, the most checks can be performed by `make check` command, though some add
```python
class Clazz(BaseClazz):
"""
brand-new implementation of ``BaseClazz``
brand-new implementation of :class:`BaseClazz`
Attributes:
CLAZZ_ATTRIBUTE(int): (class attribute) a brand-new class attribute
instance_attribute(str): an instance attribute
with the long description
Examples:
Very informative class usage example, e.g.::
@ -77,22 +80,23 @@ Again, the most checks can be performed by `make check` command, though some add
>>> clazz = Clazz()
"""
CLAZZ_ATTRIBUTE = 42
CLAZZ_ATTRIBUTE: ClassVar[int] = 42
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""
default constructor
Args:
*args(Any): positional arguments
**kwargs(Any): keyword arguments
**kwargs(Any): keyword arguments
"""
self.instance_attribute = ""
```
Note missing comment for the `__init__` method, which is the special case.
* Type annotations are the must, even for local functions. For the function argument `self` (for instance methods) and `cls` (for class methods) should not be annotated.
* For collection types built-in classes must be used if possible (e.g. `dict` instead of `typing.Dict`, `tuple` instead of `typing.Tuple`). In case if built-in type is not available, but `collections.abc` provides interface, it must be used (e.g. `collections.abc.Awaitable` instead of `typing.Awaitable`, `collections.abc.Iterable` instead of `typing.Iterable`). For union classes, the bar operator (`|`) must be used (e.g. `float | int` instead of `typing.Union[float, int]`), which also includes `typinng.Optional` (e.g. `str | None` instead of `Optional[str]`).
* `classmethod` should always return `Self`. In case of mypy warning (e.g. if there is a branch in which function doesn't return the instance of `cls`) consider using `staticmethod` instead.
* For collection types built-in classes must be used if possible (e.g. `dict` instead of `typing.Dict`, `tuple` instead of `typing.Tuple`). In case if built-in type is not available, but `collections.abc` provides interface, it must be used (e.g. `collections.abc.Awaitable` instead of `typing.Awaitable`, `collections.abc.Iterable` instead of `typing.Iterable`). For union classes, the bar operator (`|`) must be used (e.g. `float | int` instead of `typing.Union[float, int]`), which also includes `typing.Optional` (e.g. `str | None` instead of `Optional[str]`).
* `classmethod` should (almost) always return `Self`. In case of mypy warning (e.g. if there is a branch in which function doesn't return the instance of `cls`) consider using `staticmethod` instead.
* Class attributes must be decorated as `ClassVar[...]`.
* Recommended order of function definitions in class:
```python
@ -102,6 +106,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: ...
@ -118,15 +125,23 @@ Again, the most checks can be performed by `make check` command, though some add
def __hash__(self) -> int: ... # basically any magic (or look-alike) method
```
Methods inside one group should be ordered alphabetically, the only exception is `__init__` method (`__post__init__` for dataclasses) which should be defined first. For test methods it is recommended to follow the order in which functions are defined.
Methods inside one group should be ordered alphabetically, the only exceptions are `__init__` (`__post_init__` for dataclasses), `__new__` and `__del__` methods which should be defined first. For test methods it is recommended to follow the order in which functions are defined.
Though, we would like to highlight abstract methods (i.e. ones which raise `NotImplementedError`), we still keep in global order at the moment.
For the most cases there is custom `pylint` plugin, which performs checks automatically.
* Abstract methods must raise `NotImplementedError` instead of using `abc.abstractmethod`. The reason behind this restriction is the fact that we have class/static abstract methods for those we need to define their attribute first making the code harder to read.
* For any path interactions `pathlib.Path` must be used.
* Configuration interactions must go through `ahriman.core.configuration.Configuration` class instance.
* In case if class load requires some actions, it is recommended to create class method which can be used for class instantiating.
* The code must follow the exception safety, unless it is explicitly asked by end user. It means that most exceptions must be handled and printed to log, no other actions must be done (e.g. raising another exception).
* The most (expected) exceptions must be handled and printed to log, allowing service to continue work. However, fatal and (in some cases) unexpected exceptions may lead to the application termination.
* Exceptions without parameters should be raised without parentheses, e.g.:
```python
raise RuntimeError
```
* For the external command `ahriman.core.util.check_output` function must be used.
* Every temporary file/directory must be removed at the end of processing, no matter what. The `tempfile` module provides good ways to do it.
* Import order must be the following:
@ -155,19 +170,16 @@ Again, the most checks can be performed by `make check` command, though some add
* One file should define only one class, exception is class satellites in case if file length remains less than 400 lines.
* It is possible to create file which contains some functions (e.g. `ahriman.core.util`), but in this case you would need to define `__all__` attribute.
* The file size mentioned above must be applicable in general. In case of big classes consider splitting them into traits. Note, however, that `pylint` includes comments and docstrings into counter, thus you need to check file size by other tools.
* No global variable is allowed outside of `ahriman.version` module. `ahriman.core.context` is also special case.
* No global variable is allowed outside of `ahriman` module. `ahriman.core.context` is also special case.
* Single quotes are not allowed. The reason behind this restriction is the fact that docstrings must be written by using double quotes only, and we would like to make style consistent.
* If your class writes anything to log, the `ahriman.core.log.LazyLogging` trait must be used.
* Web API methods must be documented by using `aiohttp_apispec` library. Schema testing mostly should be implemented in related view class tests. Recommended example for documentation (excluding comments):
* Web API methods must be documented by using `aiohttp_apispec` library. The schema testing mostly should be implemented in related view class tests. Recommended example for documentation (excluding comments):
```python
import aiohttp_apispec
from marshmallow import Schema, fields
from ahriman.web.schemas.auth_schema import AuthSchema
from ahriman.web.schemas.error_schema import ErrorSchema
from ahriman.web.schemas.package_name_schema import PackageNameSchema
from ahriman.web.apispec.decorators import apidocs
from ahriman.web.schemas import PackageNameSchema, PaginationSchema
from ahriman.web.views.base import BaseView
@ -184,27 +196,82 @@ Again, the most checks can be performed by `make check` command, though some add
class Foo(BaseView):
POST_PERMISSION = ...
ROUTES = ...
@aiohttp_apispec.docs(
@apidocs(
tags=["Tag"],
summary="Do foo",
description="Extended description of the method which does foo",
responses={
200: {"description": "Success response", "schema": ResponseSchema},
204: {"description": "Success response"}, # example without json schema response
400: {"description": "Bad data is supplied", "schema": ErrorSchema}, # exception raised by this method
401: {"description": "Authorization required", "schema": ErrorSchema}, # should be always presented
403: {"description": "Access is forbidden", "schema": ErrorSchema}, # should be always presented
500: {"description": "Internal server error", "schema": ErrorSchema}, # should be always presented
},
security=[{"token": [POST_PERMISSION]}],
error_400_enabled=True, # exception raised by this method
error_404_description="Repository is unknown",
schema=ResponseSchema, # leave empty if no responses here
match_schema=PackageNameSchema,
query_schema=PaginationSchema,
body_schema=RequestSchema(many=True),
)
@aiohttp_apispec.cookies_schema(AuthSchema) # should be always presented
@aiohttp_apispec.match_info_schema(PackageNameSchema)
@aiohttp_apispec.json_schema(RequestSchema(many=True))
async def post(self) -> None: ...
```
* It is allowed to change web API to add new fields or remove optional ones. However, in case of model changes, new API version must be introduced.
* On the other hand, it is allowed to change method signatures, however, it is recommended to add new parameters as optional if possible. Deprecated API can be dropped during major release.
* Enumerations (`Enum` classes) are allowed and recommended. However, it is recommended to use `StrEnum` class if there are from/to string conversions and `IntEnum` otherwise.
### Other checks
The projects also uses typing checks (provided by `mypy`) and some linter checks provided by `pylint` and `bandit`. Those checks must be passed successfully for any open pull requests.
## Developers how to
### Run automated checks
```shell
tox
```
Must be usually done before any pushes.
### Generate documentation templates
```shell
tox -e docs
```
Must be usually done if there are changes in modules structure.
### Create release
```shell
tox -m release -- major.minor.patch
```
The command above will generate documentation, tags, etc., and will push them to GitHub. Other things will be handled by GitHub workflows automatically.
### Hotfixes policy
Sometimes it is required to publish hotfix with specific commits, but some features have been already committed, which should not be included to the hotfix. In this case, some manual steps are required:
1. Create new branch from the last stable release (`major.minor.patch`):
```shell
git checkout -b release/major.minor major.minor.patch
```
2. Cherry-pick desired commit(s):
```shell
git cherry-pick <commit-sha>
```
Alternatively, make changes to the new branch and commit them.
3. Push newly created branch to remote:
```shell
git push --set-upstream origin release/major.minor
```
4. Proceed to release as usual:
```shell
tox -m release -- major.minor.patch+1
```

View File

@ -1,57 +0,0 @@
FROM archlinux:base
# image configuration
ENV AHRIMAN_ARCHITECTURE="x86_64"
ENV AHRIMAN_DEBUG=""
ENV AHRIMAN_FORCE_ROOT=""
ENV AHRIMAN_HOST="0.0.0.0"
ENV AHRIMAN_MULTILIB="yes"
ENV AHRIMAN_OUTPUT="syslog"
ENV AHRIMAN_PACKAGER="ahriman bot <ahriman@example.com>"
ENV AHRIMAN_PACMAN_MIRROR=""
ENV AHRIMAN_PORT=""
ENV AHRIMAN_REPOSITORY="aur-clone"
ENV AHRIMAN_REPOSITORY_ROOT="/var/lib/ahriman/ahriman"
ENV AHRIMAN_UNIX_SOCKET=""
ENV AHRIMAN_USER="ahriman"
ENV AHRIMAN_VALIDATE_CONFIGURATION="yes"
# install environment
## update pacman.conf with multilib
RUN echo "[multilib]" >> "/etc/pacman.conf" && \
echo "Include = /etc/pacman.d/mirrorlist" >> "/etc/pacman.conf"
## install minimal required packages
RUN pacman --noconfirm -Syu binutils fakeroot git make sudo
## create build user
RUN useradd -m -d "/home/build" -s "/usr/bin/nologin" build && \
echo "build ALL=(ALL) NOPASSWD: ALL" > "/etc/sudoers.d/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 && \
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"
## create package archive and install it
RUN cd "/home/build/ahriman" && \
make VERSION=$(python -c "from src.ahriman.version import __version__; print(__version__)") archlinux && \
cp ./*-src.tar.xz "package/archlinux" && \
cd "package/archlinux" && \
runuser -u build -- makepkg --noconfirm --install --skipchecksums && \
cd / && rm -r "/home/build/ahriman"
VOLUME ["/var/lib/ahriman"]
# minimal runtime ahriman setup
COPY "docker/entrypoint.sh" "/usr/local/bin/entrypoint"
ENTRYPOINT ["entrypoint"]
# default command
CMD ["repo-update", "--refresh"]

View File

@ -1,59 +0,0 @@
.PHONY: archive archlinux check clean directory html push specification tests version
.DEFAULT_GOAL := archlinux
PROJECT := ahriman
FILES := AUTHORS CONTRIBUTING.md COPYING Makefile README.md SECURITY.md docs package src setup.py tox.ini web.png
TARGET_FILES := $(addprefix $(PROJECT)/, $(FILES))
IGNORE_FILES := package/archlinux src/.mypy_cache
$(TARGET_FILES) : $(addprefix $(PROJECT), %) : $(addprefix ., %) directory version
@cp -rp $< $@
archive: archive_directory
tar cJf "$(PROJECT)-$(VERSION)-src.tar.xz" "$(PROJECT)"
rm -rf "$(PROJECT)"
archive_directory: $(TARGET_FILES)
rm -fr $(addprefix $(PROJECT)/, $(IGNORE_FILES))
find "$(PROJECT)" -type f -name "*.pyc" -delete
find "$(PROJECT)" -depth -type d -name "__pycache__" -execdir rm -rf {} +
find "$(PROJECT)" -depth -type d -name "*.egg-info" -execdir rm -rf {} +
archlinux: archive
sed -i "s/pkgver=.*/pkgver=$(VERSION)/" package/archlinux/PKGBUILD
check: clean
tox -e check
clean:
find . -type f -name "$(PROJECT)-*-src.tar.xz" -delete
rm -rf "$(PROJECT)"
directory: clean
mkdir "$(PROJECT)"
html: specification
rm -rf docs/html
tox -e docs-html
push: specification archlinux
git add package/archlinux/PKGBUILD src/ahriman/version.py docs/ahriman-architecture.svg docs/ahriman.1 docs/completions/
git commit -m "Release $(VERSION)"
git tag "$(VERSION)"
git push
git push --tags
specification:
# make sure that old files are removed
find docs -type f -name "$(PROJECT)*.rst" -delete
tox -e docs
tests: clean
tox -e tests
version:
ifndef VERSION
$(error VERSION is required, but not set)
endif
sed -i 's/^__version__ = .*/__version__ = "$(VERSION)"/' src/ahriman/version.py

View File

@ -1,41 +1,44 @@
# ArcH linux ReposItory MANager
[![tests status](https://github.com/arcan1s/ahriman/actions/workflows/run-tests.yml/badge.svg)](https://github.com/arcan1s/ahriman/actions/workflows/run-tests.yml)
[![setup status](https://github.com/arcan1s/ahriman/actions/workflows/run-setup.yml/badge.svg)](https://github.com/arcan1s/ahriman/actions/workflows/run-setup.yml)
[![Docker Image Version (latest semver)](https://img.shields.io/docker/v/arcan1s/ahriman?label=docker%20image)](https://hub.docker.com/r/arcan1s/ahriman)
[![tests status](https://github.com/arcan1s/ahriman/actions/workflows/tests.yml/badge.svg)](https://github.com/arcan1s/ahriman/actions/workflows/tests.yml)
[![setup status](https://github.com/arcan1s/ahriman/actions/workflows/setup.yml/badge.svg)](https://github.com/arcan1s/ahriman/actions/workflows/setup.yml)
[![Docker Image Version (latest semver)](https://img.shields.io/docker/v/arcan1s/ahriman?label=Docker%20image&sort=semver)](https://hub.docker.com/r/arcan1s/ahriman)
[![CodeFactor](https://www.codefactor.io/repository/github/arcan1s/ahriman/badge)](https://www.codefactor.io/repository/github/arcan1s/ahriman)
[![Documentation Status](https://readthedocs.org/projects/ahriman/badge/?version=latest)](https://ahriman.readthedocs.io/?badge=latest)
[![Documentation Status](https://readthedocs.org/projects/ahriman/badge/?version=latest)](https://ahriman.readthedocs.io)
Wrapper for managing custom repository inspired by [repo-scripts](https://github.com/arcan1s/repo-scripts).
## Features
* Install-configure-forget manager for the very own repository.
* Multi-architecture support.
* Multi architecture and repository support.
* Dependency manager.
* 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).
* Triggers for repository updates, e.g. synchronization to remote services (rsync, s3 and github) and report generation (email, html, telegram).
* Various rebuild options with ability to automatically bump package version.
* 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:
![web interface](web.png)
## Installation and run
For installation details kindly refer to the [documentation](https://ahriman.readthedocs.io/en/latest/setup.html). For application commands it is possible to get information by using `--help`/`help` command or by using man page ([web version](https://ahriman.readthedocs.io/en/latest/command-line.html)).
For installation details kindly refer to the [documentation](https://ahriman.readthedocs.io/en/stable/setup.html). For application commands it is possible to get information by using `--help`/`help` command or by using man page ([web version](https://ahriman.readthedocs.io/en/stable/command-line.html)).
## Configuration
Every available option is described in the [documentation](https://ahriman.readthedocs.io/en/latest/configuration.html).
Every available option is described in the [documentation](https://ahriman.readthedocs.io/en/stable/configuration.html).
The application provides reasonable defaults which allow to use it out-of-box; however additional steps (like configuring build toolchain and sudoers) are recommended and can be easily achieved by following install instructions.
## [FAQ](https://ahriman.readthedocs.io/en/latest/faq.html)
## [FAQ](https://ahriman.readthedocs.io/en/stable/faq/index.html)
## Live demos
* [Build status page](https://ahriman-demo.arcanis.me). You can log in as `demo` user by using `demo` password. However, you will not be able to run tasks. [HTTP API documentation](https://ahriman-demo.arcanis.me/api-docs) is also available.
* [Repository index](http://repo.arcanis.me/x86_64/index.html).
* [Repository index](https://repo.arcanis.me/arcanisrepo/x86_64/).
* [Telegram feed](https://t.me/arcanisrepo).
Do you have any success story? You can [share it](https://github.com/arcan1s/ahriman/issues/new?template=04-discussion.md)!

140
docker/Dockerfile Normal file
View File

@ -0,0 +1,140 @@
# build image
FROM archlinux:base AS build
# install environment
## create build user
RUN useradd -m -d "/home/build" -s "/usr/bin/nologin" build
## extract container creation date and set mirror for this timestamp, set PKGEXT and refresh database next
RUN echo "Server = https://archive.archlinux.org/repos/$(stat -c "%y" "/var/lib/pacman" | cut -d " " -f 1 | sed "s,-,/,g")/\$repo/os/\$arch" > "/etc/pacman.d/mirrorlist" && \
pacman -Sy
## setup package cache
RUN runuser -u build -- mkdir "/tmp/pkg" && \
echo "PKGDEST=/tmp/pkg" >> "/etc/makepkg.conf" && \
echo "[options]" >> "/etc/pacman.conf" && \
echo "CacheDir = /tmp/pkg/" >> "/etc/pacman.conf"
## install anc configure sudo
RUN pacman -S --noconfirm --asdeps sudo && \
echo "build ALL=(ALL) NOPASSWD: ALL" > "/etc/sudoers.d/build"
## copy install script
COPY "docker/install-aur-package.sh" "/usr/local/bin/install-aur-package"
## install package dependencies
RUN pacman -S --noconfirm --asdeps \
devtools \
git \
pyalpm \
python-bcrypt \
python-inflection \
python-pyelftools \
python-requests \
&& \
pacman -S --noconfirm --asdeps \
base-devel \
python-build \
python-flit \
python-installer \
python-tox \
python-wheel \
&& \
pacman -S --noconfirm --asdeps \
git \
python-aiohttp \
python-boto3 \
python-cerberus \
python-cryptography \
python-jinja \
python-systemd \
rsync \
&& \
runuser -u build -- install-aur-package \
python-aioauth-client \
python-sphinx-typlog-theme \
python-webargs \
python-aiohttp-apispec-git \
python-aiohttp-cors \
python-aiohttp-jinja2 \
python-aiohttp-session \
python-aiohttp-security \
python-requests-unixsocket2
# install ahriman
## copy tree
COPY --chown=build . "/home/build/ahriman"
## create package archive and install it
RUN cd "/home/build/ahriman" && \
tox -e archive && \
cp ./dist/*.tar.gz "package/archlinux" && \
cd "package/archlinux" && \
runuser -u build -- makepkg --noconfirm --skipchecksums && \
cd / && rm -r "/home/build/ahriman"
# main image
FROM archlinux:base AS ahriman
# image configuration
ENV AHRIMAN_ARCHITECTURE="x86_64"
ENV AHRIMAN_DEBUG=""
ENV AHRIMAN_FORCE_ROOT=""
ENV AHRIMAN_HOST="0.0.0.0"
ENV AHRIMAN_MULTILIB="yes"
ENV AHRIMAN_OUTPUT=""
ENV AHRIMAN_PACKAGER="ahriman bot <ahriman@example.com>"
ENV AHRIMAN_PACMAN_MIRROR=""
ENV AHRIMAN_PORT=""
ENV AHRIMAN_POSTSETUP_COMMAND=""
ENV AHRIMAN_PRESETUP_COMMAND=""
ENV AHRIMAN_REPOSITORY="aur"
ENV AHRIMAN_REPOSITORY_SERVER=""
ENV AHRIMAN_REPOSITORY_ROOT="/var/lib/ahriman/ahriman"
ENV AHRIMAN_UNIX_SOCKET=""
ENV AHRIMAN_USER="ahriman"
ENV AHRIMAN_VALIDATE_CONFIGURATION="yes"
# install environment
## update pacman.conf with multilib
RUN echo "[multilib]" >> "/etc/pacman.conf" && \
echo "Include = /etc/pacman.d/mirrorlist" >> "/etc/pacman.conf"
## copy built packages from build image and setup repository
COPY --from=build "/tmp/pkg" "/var/cache/pacman/pkg"
RUN repo-add "/var/cache/pacman/pkg/core.db.tar.zst" "/var/cache/pacman/pkg/"*.pkg.tar.zst && \
repo-add "/var/cache/pacman/pkg/extra.db.tar.zst" && \
repo-add "/var/cache/pacman/pkg/multilib.db.tar.zst"
## set local directory to use as repository and refresh database
RUN cp "/etc/pacman.d/mirrorlist" "/etc/pacman.d/mirrorlist.orig" && \
echo "Server = file:///var/cache/pacman/pkg" > "/etc/pacman.d/mirrorlist" && \
cp "/etc/pacman.conf" "/etc/pacman.conf.orig" && \
sed -i "s/SigLevel *=.*/SigLevel = Optional/g" "/etc/pacman.conf" && \
pacman -Sy
## install package and its optional dependencies
RUN pacman -S --noconfirm ahriman
RUN pacman -S --noconfirm --asdeps \
python-aioauth-client \
python-aiohttp-apispec-git \
python-aiohttp-security \
python-aiohttp-session \
python-boto3 \
python-cerberus \
python-cryptography \
python-systemd \
python-requests-unixsocket2 \
rsync \
sudo
## clear cache and restore system
RUN find "/var/cache/pacman/pkg" "/var/lib/pacman/sync" -type "f,l" -delete && \
cp "/etc/pacman.d/mirrorlist.orig" "/etc/pacman.d/mirrorlist" && \
cp "/etc/pacman.conf.orig" "/etc/pacman.conf"
VOLUME ["/var/lib/ahriman"]
# minimal runtime ahriman setup
## FIXME since 1.0.4 devtools requires dbus to be run, which doesn't work now in container
COPY "docker/systemd-nspawn.sh" "/usr/local/bin/systemd-nspawn"
## entrypoint setup
COPY "docker/entrypoint.sh" "/usr/local/bin/entrypoint"
COPY "docker/entrypoint-web.sh" "/usr/local/bin/entrypoint-web"
ENTRYPOINT ["entrypoint"]
# default command
CMD ["repo-update", "--refresh"]

5
docker/entrypoint-web.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
# Special workaround for running web service in github actions, must not be usually used in real environment,
# consider running web command explicitly instead
exec entrypoint web "$@"

View File

@ -4,26 +4,19 @@ set -e
[ -n "$AHRIMAN_DEBUG" ] && set -x
# configuration tune
cat <<EOF > "/etc/ahriman.ini.d/00-docker.ini"
cat <<EOF > "/etc/ahriman.ini.d/01-docker.ini"
[repository]
root = $AHRIMAN_REPOSITORY_ROOT
[settings]
database = $AHRIMAN_REPOSITORY_ROOT/ahriman.db
[web]
host = $AHRIMAN_HOST
EOF
sed -i "s|handlers = syslog_handler|handlers = ${AHRIMAN_OUTPUT}_handler|g" "/etc/ahriman.ini.d/logging.ini"
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
AHRIMAN_DEFAULT_ARGS+=("--repository" "$AHRIMAN_REPOSITORY")
if [ -n "$AHRIMAN_OUTPUT" ]; then
AHRIMAN_DEFAULT_ARGS+=("--log-handler" "$AHRIMAN_OUTPUT")
fi
# create repository root inside the [[mounted]] directory and set correct ownership
@ -38,20 +31,25 @@ chown "$AHRIMAN_USER":"$AHRIMAN_USER" "$AHRIMAN_GNUPG_HOME"
# run built-in setup command
AHRIMAN_SETUP_ARGS=("--build-as-user" "$AHRIMAN_USER")
AHRIMAN_SETUP_ARGS+=("--packager" "$AHRIMAN_PACKAGER")
AHRIMAN_SETUP_ARGS+=("--repository" "$AHRIMAN_REPOSITORY")
if [ -z "$AHRIMAN_MULTILIB" ]; then
AHRIMAN_SETUP_ARGS+=("--no-multilib")
fi
if [ -n "$AHRIMAN_PACMAN_MIRROR" ]; then
AHRIMAN_SETUP_ARGS+=("--mirror" "$AHRIMAN_PACMAN_MIRROR")
fi
if [ -n "$AHRIMAN_REPOSITORY_SERVER" ]; then
AHRIMAN_SETUP_ARGS+=("--server" "$AHRIMAN_REPOSITORY_SERVER")
fi
if [ -n "$AHRIMAN_PORT" ]; then
AHRIMAN_SETUP_ARGS+=("--web-port" "$AHRIMAN_PORT")
fi
if [ -n "$AHRIMAN_UNIX_SOCKET" ]; then
AHRIMAN_SETUP_ARGS+=("--web-unix-socket" "$AHRIMAN_UNIX_SOCKET")
fi
[ -n "$AHRIMAN_PRESETUP_COMMAND" ] && eval "$AHRIMAN_PRESETUP_COMMAND"
ahriman "${AHRIMAN_DEFAULT_ARGS[@]}" service-setup "${AHRIMAN_SETUP_ARGS[@]}"
[ -n "$AHRIMAN_POSTSETUP_COMMAND" ] && eval "$AHRIMAN_POSTSETUP_COMMAND"
# validate configuration if set
[ -n "$AHRIMAN_VALIDATE_CONFIGURATION" ] && ahriman "${AHRIMAN_DEFAULT_ARGS[@]}" service-config-validate --exit-code
@ -59,12 +57,15 @@ ahriman "${AHRIMAN_DEFAULT_ARGS[@]}" service-setup "${AHRIMAN_SETUP_ARGS[@]}"
# create machine-id which is required by build tools
systemd-machine-id-setup &> /dev/null
# special workaround to emulate /bin/bash entrypoint if first argument starts with /
[[ "$1" =~ ^/.* ]] && exec "$@"
# if AHRIMAN_FORCE_ROOT is set or command is unsafe we can run without sudo
# otherwise we prepend executable by sudo command
if [ -n "$AHRIMAN_FORCE_ROOT" ]; then
AHRIMAN_EXECUTABLE=("ahriman")
elif ahriman help-commands-unsafe --command="$*" &> /dev/null; then
AHRIMAN_EXECUTABLE=("sudo" "-u" "$AHRIMAN_USER" "--" "ahriman")
elif ahriman help-commands-unsafe -- "$@" &> /dev/null; then
AHRIMAN_EXECUTABLE=("sudo" "-E" "-u" "$AHRIMAN_USER" "--" "ahriman")
else
AHRIMAN_EXECUTABLE=("ahriman")
fi

View File

@ -4,9 +4,13 @@ set -e
for PACKAGE in "$@"; do
BUILD_DIR="$(mktemp -d)"
# clone the remote source
git clone https://aur.archlinux.org/"$PACKAGE".git "$BUILD_DIR"
cd "$BUILD_DIR"
makepkg --noconfirm --install --rmdeps --syncdeps
# checkout to the image date
git checkout "$(git rev-list -1 --before="$(stat -c "%y" "/var/lib/pacman" | cut -d " " -f 1)" master)"
# build and install the package
makepkg --nocheck --noconfirm --install --rmdeps --syncdeps
cd /
rm -r "$BUILD_DIR"
done

15
docker/systemd-nspawn.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
# Since https://gitlab.archlinux.org/archlinux/devtools/-/commit/5f4fd52e3836ddddb25a0f9e15d0acfed06f693d
# it is impossible to start devtools inside docker container, because it requires slice registering
# which is impossible because there is no init in container
is_slice() {
[[ $1 =~ ^--slice* ]]
}
allowed=()
for arg in "$@"; do
is_slice "$arg" && allowed+=("--keep-unit") || allowed+=("$arg")
done
exec /usr/bin/systemd-nspawn "${allowed[@]}"

1846
docs/_static/architecture.dot vendored Normal file

File diff suppressed because it is too large Load Diff

721
docs/_static/logo.svg vendored Normal file
View File

@ -0,0 +1,721 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="800"
height="800"
version="1.1"
id="svg106"
sodipodi:docname="logo.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview106"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="1.8720703"
inkscape:cx="511.73292"
inkscape:cy="499.71414"
inkscape:window-width="3840"
inkscape:window-height="2160"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg106" />
<path
fill="#132b6d"
d="m 387.66175,2.9352426 c 109.978,-0.5206001 203.504,31.4880054 285.824,108.1504174 159.376,148.42203 165.076,403.05807 17.164,561.4021 -72.884,78.02402 -172.364,120.98802 -278.558,124.58202 -105.508,0.092 -196.612,-29.306 -277.44,-100.25401 C -17.844855,562.95974 -40.874855,327.5097 78.894545,164.89367 155.84375,60.416853 261.60375,10.958044 387.66175,2.9352426 Z"
id="path1"
style="stroke-width:2" />
<defs
id="defs2">
<linearGradient
id="gradient_0"
gradientUnits="userSpaceOnUse"
x1="361.42581"
y1="223.77209"
x2="195.62669"
y2="358.78311"
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
<stop
offset="0"
stop-color="#C29024"
id="stop1" />
<stop
offset="1"
stop-color="#DCBB57"
id="stop2" />
</linearGradient>
</defs>
<path
fill="url(#gradient_0)"
d="M 351.39175,758.48578 C 168.77575,730.12777 41.748945,587.64375 38.358945,403.44571 34.725145,206.00568 197.09775,42.52665 394.25175,39.316449 c 199.908,-3.255 364.866,156.319231 367.572,354.681261 1.264,13.294 -0.766,28.52001 -2.266,41.84201 -22.772,202.34804 -192.312,343.02406 -397.788,324.19806 -2.656,-0.244 -8.104,-0.266 -10.378,-1.552 z"
id="path2"
style="fill:url(#gradient_0);stroke-width:2" />
<path
fill="#fade6b"
d="m 322.01375,466.26772 c -11.018,-19.004 -31.84,-33.106 -51.826,-41.634 -1.678,-0.714 -7.54,-2.124 -8.182,-3.564 l 0.732,-0.666 c 4,0.842 8.334,3.966 12.02,5.806 6.386,3.184 15.572,2.11 22.174,5.236 4.75,2.248 4.01,8.946 6.388,12.528 4.924,7.418 31.496,22.526 25.196,30.44801 -1.88,2.366 3.59,25.088 -6.502,27.406 9.19,-11.64 6.228,-23.022 0,-35.56001 z"
id="path3"
style="stroke-width:2" />
<path
fill="#f1ead8"
d="m 607.74175,596.82375 c 1.336,0.334 2.464,0.632 3.666,1.342 -20.054,9.052 -64.106,28.032 -86.62,22.686 4.1,-6.492 9.65,-12.676 16.658,-16.064 19.842,0.438 47.962,-0.334 66.296,-7.964 z"
id="path4"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 501.15175,566.49574 c 6.586,7.622 13.706,16.72001 22.154,22.30601 4.128,2.764 8.214,4.434 12.892,6.05 9.566,1.388 23.592,3.746 32.986,1.972 14.562,-1.188 28.228,-3.904 42.224,-8.022 l -1.062,3.132 c -0.626,1.91 -1.408,3.284 -2.604,4.89 -18.334,7.63 -46.454,8.402 -66.296,7.964 -7.008,3.388 -12.558,9.572 -16.658,16.064 -9.11,-5.624 -25.204,-20.256 -33.116,-27.858 -0.438,-2.818 -1.834,-5.878 -2.786,-8.594 3.066,-7.94801 11.252,-13.00801 12.266,-17.90401 z"
id="path5"
style="stroke-width:2" />
<path
fill="#f1ead8"
d="m 279.36575,419.47772 c 17.368,-2.17 52.85,13.874 66.39,23.914 16.654,12.346 42.944,41.42201 46.084,62.86401 l -0.632,0.818 c -7.4,-0.814 -14.928,-3.078 -22.004,0 -15.638,-34.97 -32.316,-54.81001 -66.512,-75.00601 -7.612,-4.496 -15.806,-7.926 -23.326,-12.59 z"
id="path6"
style="stroke-width:2" />
<path
fill="#f2e8a9"
d="m 358.50775,559.66374 c 12.018,13.204 20.532,31.28401 42.394,32.76001 26.828,1.808 75.452,-16.66001 100.25,-25.92801 -1.014,4.896 -9.2,9.956 -12.266,17.90401 0.952,2.716 2.348,5.776 2.786,8.594 -23.926,3.644 -42.772,14.97 -73.036,18.024 -31.48,3.176 -57.178,-20.208 -60.128,-51.35401 z"
id="path7"
style="stroke-width:2" />
<defs
id="defs8">
<linearGradient
id="gradient_1"
gradientUnits="userSpaceOnUse"
x1="251.38866"
y1="364.7413"
x2="250.98038"
y2="386.04666"
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
<stop
offset="0"
stop-color="#8B5E10"
id="stop7" />
<stop
offset="1"
stop-color="#CF9A22"
id="stop8" />
</linearGradient>
</defs>
<path
fill="url(#gradient_1)"
d="m 310.19775,643.62576 c 2.576,-42.33201 43.824,-23.71801 68.946,-13.31801 29.856,12.36001 44.646,14.27401 76.866,17.40001 6.062,0.588 19.738,0.234 24.164,5.272 -4.906,4.506 -30.934,9.33 -37.886,8.6 -14.06,-1.944 -28.422,0.378 -42.516,0.02 -15.588,-0.394 -24.788,-3.174 -41.264,-0.02 -10.692,-0.35 -39.162,-6.928 -48.31,-12.01 l -0.164,-0.692 c -4.454,-4.498 -8.004,-10.198 -11.632,-15.38 h 1.106 c 3.348,3.464 6.672,7.448 10.69,10.128 z"
id="path8"
style="fill:url(#gradient_1);stroke-width:2" />
<path
fill="#e4c267"
d="m 533.18975,212.81168 3.008,1.8 c 104.752,81.45401 120.284,223.88804 39.258,327.17806 -4.874,6.214 -10.864,11.518 -15.55,17.874 -13.234,7.248 -22.01,22.26601 -36.562,27.66201 -3.272,-0.346 -14.796,-14.16001 -18.132,-17.28801 9.246,-9.45 22.016,-16.352 32.638,-26.984 75.99,-76.05602 84.014,-197.54404 14.068,-280.22005 -6.722,-7.946 -14.4,-14.688 -21.786,-21.97401 2.61,-8.98 1.014,-18.91 3.058,-28.048 z"
id="path9"
style="stroke-width:2" />
<defs
id="defs10">
<linearGradient
id="gradient_2"
gradientUnits="userSpaceOnUse"
x1="383.45288"
y1="318.2124"
x2="295.73892"
y2="203.79875"
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
<stop
offset="0"
stop-color="#BF9029"
id="stop9" />
<stop
offset="1"
stop-color="#F5D354"
id="stop10" />
</linearGradient>
</defs>
<path
fill="url(#gradient_2)"
d="m 434.37375,137.51566 c 2.598,-0.164 5.328,-0.374 7.914,0 44.516,7.77801 92.47,33.43601 126.896,61.38602 7.438,7.668 16.4,14.876 22.864,23.372 2.62,2.794 5.176,5.692 8.21,8.044 5.566,3.826 22.78,23.15001 28.692,29.00401 l 0.008,0.522 c 0.052,5.284 2.926,14.418 2.624,16.914 1.07,8.98 6.816,17.276 9.974,25.644 32.534,86.22402 17.178,181.23004 -38.442,254.80205 -9.59,12.686 -20.71,25.49601 -33.178,35.41401 -3.856,3.068 -7.42,3.966 -0.752,4.206 -9.394,1.774 -23.42,-0.584 -32.986,-1.972 -4.678,-1.616 -8.764,-3.286 -12.892,-6.05 12.516,-9.682 25.068,-17.99401 36.6,-29.13801 4.686,-6.356 10.676,-11.66 15.55,-17.874 81.026,-103.29002 65.494,-245.72405 -39.258,-327.17806 l -3.008,-1.8 c -2.044,9.138 -0.448,19.068 -3.058,28.048 -20.19,-16.736 -57.964,-41.348 -84.916,-44.78 -4.862,6.39 -8.658,12.616 -14.43,18.532 -7.806,8.378 -15.312,17.27 -22.424,26.248 v -3.898 c -1.506,1.596 -4.512,4.54 -4.34,6.828 l 0.516,0.474 c -0.566,1.138 -1.052,2.3 -1.93,3.238 l -1.24,0.028 0.2,1.06001 c -4.05,-8.60801 1.232,-15.75801 3.436,-23.75601 26.818,-41.54401 24.194,-53.60601 -19.526,-73.22601 16.782,-3.452 30.824,-15.02601 48.896,-14.09201 z"
id="path10"
style="fill:url(#gradient_2);stroke-width:2" />
<path
fill="#e7aa1f"
d="m 592.04775,222.27368 c 2.62,2.794 5.176,5.692 8.21,8.044 8.066,13.52 19.78,29.05401 28.692,42.98401 -6.366,-3.072 -23.312,-30.26801 -30.038,-38.90201 -2.778,-3.566 -7.95,-7.296 -6.864,-12.126 z"
id="path11"
style="stroke-width:2" />
<path
fill="#051053"
d="m 600.25775,230.31768 c 5.566,3.826 22.78,23.15001 28.692,29.00401 l 0.008,0.522 c 0.052,5.284 2.926,14.418 2.624,16.914 -0.81,-1.204 -1.734,-2.318 -2.632,-3.456 -8.912,-13.93 -20.626,-29.46401 -28.692,-42.98401 z"
id="path12"
style="stroke-width:2" />
<path
fill="#bf8a24"
d="m 536.19775,214.61168 c -9.436,-16.308 -80.554,-44.98201 -95.5,-43.60601 -2.88,-2.338 -5.638,-6.154 -7.546,-9.334 13.846,-0.878 61.092,18.238 74.408,25.094 7.224,3.72 43.202,27.84801 43.214,27.84601 3.21,2.37 5.956,5.258 9.132,7.662 4.042,5.416 9.626,9.648 14.302,14.496 93.102,96.54202 79.466,249.74005 -15.778,339.83206 -3.328,3.14801 -18.614,17.85401 -22.232,18.25001 -4.678,-1.616 -8.764,-3.286 -12.892,-6.05 12.516,-9.682 25.068,-17.99401 36.6,-29.13801 4.686,-6.356 10.676,-11.66 15.55,-17.874 81.026,-103.29002 65.494,-245.72405 -39.258,-327.17806 z"
id="path13"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 434.37375,137.51566 c 2.598,-0.164 5.328,-0.374 7.914,0 44.516,7.77801 92.47,33.43601 126.896,61.38602 2.568,7.928 14.072,10.708 15.774,18.372 l -0.474,0.94 -2.092,0.246 c -0.048,0.186 -10.608,12.996 -11.95,12.526 -3.166,-1.106 -7.656,-9.138 -10.536,-8.712 -3.176,-2.404 -5.922,-5.292 -9.132,-7.662 -0.012,0.002 -35.99,-24.12601 -43.214,-27.84601 -13.316,-6.856 -60.562,-25.972 -74.408,-25.094 1.908,3.18 4.666,6.996 7.546,9.334 14.946,-1.376 86.064,27.29801 95.5,43.60601 l -3.008,-1.8 c -2.044,9.138 -0.448,19.068 -3.058,28.048 -20.19,-16.736 -57.964,-41.348 -84.916,-44.78 -4.862,6.39 -8.658,12.616 -14.43,18.532 -7.806,8.378 -15.312,17.27 -22.424,26.248 v -3.898 c -1.506,1.596 -4.512,4.54 -4.34,6.828 l 0.516,0.474 c -0.566,1.138 -1.052,2.3 -1.93,3.238 l -1.24,0.028 0.2,1.06001 c -4.05,-8.60801 1.232,-15.75801 3.436,-23.75601 26.818,-41.54401 24.194,-53.60601 -19.526,-73.22601 16.782,-3.452 30.824,-15.02601 48.896,-14.09201 z"
id="path14"
style="stroke-width:2" />
<path
fill="#e7aa1f"
d="m 412.09175,152.87167 c 12.74,-3.468 25.54,-4.784 38.71,-3.946 -6.848,2.32 -14.484,5.572 -20.016,10.326 8.062,3.682 21.354,5.528 30.612,8.39 19.908,6.152 75.712,30.48001 89.376,46.97001 -0.012,0.002 -35.99,-24.12601 -43.214,-27.84601 -13.316,-6.856 -60.562,-25.972 -74.408,-25.094 1.908,3.18 4.666,6.996 7.546,9.334 14.946,-1.376 86.064,27.29801 95.5,43.60601 l -3.008,-1.8 c -17.866,-18.572 -65.548,-36.19801 -90.902,-40.93001 3.608,7.782 6.348,15.752 2.928,24.19801 -4.862,6.39 -8.658,12.616 -14.43,18.532 -7.806,8.378 -15.312,17.27 -22.424,26.248 v -3.898 c 22.078,-32.98 57.308,-46.31801 3.73,-84.09001 z"
id="path15"
style="stroke-width:2" />
<path
fill="#f1ead8"
d="m 442.28775,171.88167 c 25.354,4.732 73.036,22.35801 90.902,40.93001 -2.044,9.138 -0.448,19.068 -3.058,28.048 -20.19,-16.736 -57.964,-41.348 -84.916,-44.78 3.42,-8.44601 0.68,-16.41601 -2.928,-24.19801 z"
id="path16"
style="stroke-width:2" />
<defs
id="defs17">
<linearGradient
id="gradient_3"
gradientUnits="userSpaceOnUse"
x1="259.85068"
y1="248.27858"
x2="350.85385"
y2="408.95212"
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
<stop
offset="0"
stop-color="#061757"
id="stop16" />
<stop
offset="1"
stop-color="#1C4897"
id="stop17" />
</linearGradient>
</defs>
<path
fill="url(#gradient_3)"
d="m 628.94975,259.32169 c 35.888,36.25 71.52,72.79001 107.964,108.48002 6.736,6.598 18.816,21.616 24.91,26.196 1.264,13.294 -0.766,28.52001 -2.266,41.84201 -22.772,202.34804 -192.312,343.02406 -397.788,324.19806 -2.656,-0.244 -8.104,-0.266 -10.378,-1.552 -4.572,-6.652 -23.912,-22.76601 -31.626,-30.48801 l -117.162,-117.50802 c -11.006,-10.966 -46.288,-42.43401 -53.304,-54.48401 -4.57,-5.32 -10.27,-9.648 -14.854,-15.058 4.872,0.144 18.938,7.52 23.586,10.336 6.858,1.708 20.052,4.126 26.25,6.798 0.434,-1.258 0.146,-2.694 0,-3.998 0.138,-1.692 0.09,-3.306 0,-5 3.348,0.634 6.652,2.408 10.05,2.2 13.202,5.656 24.534,12.708 34.05,23.62 3.788,3.09 7.482,6.23801 11.126,9.49601 4.716,4.008 9.52,7.936 13.794,12.424 1.884,0.704 5.45,2.046 6.762,3.614 1.584,0.97 3.154,2.014 4.78,2.904 7.256,3.166 14.768,8.762 21.092,13.49 1.516,2.334 3.288,4.486 5.016,6.664 l 7.45,10.00201 c 3.628,5.182 7.178,10.882 11.632,15.38 l 0.164,0.692 c 9.148,5.082 37.618,11.66 48.31,12.01 16.476,-3.154 25.676,-0.374 41.264,0.02 14.094,0.358 28.456,-1.964 42.516,-0.02 6.952,0.73 32.98,-4.094 37.886,-8.6 7.398,7.31 18.44,8.658 28.374,7.392 40.55,-5.168 97.53,-34.27201 123.034,-67.37801 -2.714,-0.424 9.054,-10.22 9.25,-12.97 -7.204,1.354 -10.72,9.924 -18.264,10.996 -3.768,2.22 -7.816,4.312 -11.16,7.146 -1.202,-0.71 -2.33,-1.008 -3.666,-1.342 1.196,-1.606 1.978,-2.98 2.604,-4.89 l 1.062,-3.132 c -13.996,4.118 -27.662,6.834 -42.224,8.022 -6.668,-0.24 -3.104,-1.138 0.752,-4.206 12.468,-9.918 23.588,-22.72801 33.178,-35.41401 55.62,-73.57201 70.976,-168.57803 38.442,-254.80205 -3.158,-8.368 -8.904,-16.664 -9.974,-25.644 0.302,-2.496 -2.572,-11.63 -2.624,-16.914 z"
id="path17"
style="fill:url(#gradient_3);stroke-width:2" />
<path
fill="#fade6b"
d="m 637.21175,576.96974 c 4.14,-2.36 8.288,-4.69 12.494,-6.932 -5.274,7.16 -11.4,17.29401 -18.124,22.95601 -2.714,-0.424 9.054,-10.22 9.25,-12.97 -7.204,1.354 -10.72,9.924 -18.264,10.996 3.782,-3.136 14.3,-8.644 15.882,-12.846 z"
id="path18"
style="stroke-width:2" />
<path
fill="#f2e8a9"
d="m 637.21175,576.96974 1.238,1.20401 c -1.582,4.202 -12.1,9.71 -15.882,12.846 -3.768,2.22 -7.816,4.312 -11.16,7.146 -1.202,-0.71 -2.33,-1.008 -3.666,-1.342 1.196,-1.606 1.978,-2.98 2.604,-4.89 l 1.062,-3.132 c 9.172,-3.09 17.482,-6.914 25.804,-11.83201 z"
id="path19"
style="stroke-width:2" />
<path
fill="#e7aa1f"
d="m 358.50775,661.57976 c 16.476,-3.154 25.676,-0.374 41.264,0.02 14.094,0.358 28.456,-1.964 42.516,-0.02 -25.31,6.146 -58.224,4.784 -83.78,0 z"
id="path20"
style="stroke-width:2" />
<defs
id="defs21">
<linearGradient
id="gradient_4"
gradientUnits="userSpaceOnUse"
x1="178.9133"
y1="342.13019"
x2="155.9601"
y2="362.37878"
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
<stop
offset="0"
stop-color="#CC991E"
id="stop20" />
<stop
offset="1"
stop-color="#F2B831"
id="stop21" />
</linearGradient>
</defs>
<path
fill="url(#gradient_4)"
d="m 134.44575,540.94774 c 4.872,0.144 18.938,7.52 23.586,10.336 6.858,1.708 20.052,4.126 26.25,6.798 0.434,-1.258 0.146,-2.694 0,-3.998 0.138,-1.692 0.09,-3.306 0,-5 3.348,0.634 6.652,2.408 10.05,2.2 13.202,5.656 24.534,12.708 34.05,23.62 3.788,3.09 7.482,6.23801 11.126,9.49601 4.716,4.008 9.52,7.936 13.794,12.424 1.884,0.704 5.45,2.046 6.762,3.614 1.584,0.97 3.154,2.014 4.78,2.904 7.256,3.166 14.768,8.762 21.092,13.49 1.516,2.334 3.288,4.486 5.016,6.664 l 7.45,10.00201 c 3.628,5.182 7.178,10.882 11.632,15.38 l 0.164,0.692 c -22.282,-4.896 -55.696,-23.88201 -74.236,-37.44601 -6.744,-4.934 -12.552,-11.388 -19.652,-15.766 -6.676,-4.12 -15.06,-5.966 -22.186,-9.388 -16.632,-7.988 -30.922,-18.98801 -44.824,-30.96401 -4.57,-5.32 -10.27,-9.648 -14.854,-15.058 z"
id="path21"
style="fill:url(#gradient_4);stroke-width:2" />
<path
fill="#d6991c"
d="m 158.03175,551.28374 c 6.858,1.708 20.052,4.126 26.25,6.798 1.448,0.596 2.168,1.102 2.948,2.48 l -0.558,0.666 c -3.77,-0.136 -27.166,-8.046 -28.64,-9.944 z"
id="path22"
style="stroke-width:2" />
<path
fill="#bf8a24"
d="m 242.85175,607.32775 c 7.25,0.168 31.11,8.666 40.444,11.75 -14.638,0.038 -27.2,-6.238 -40.444,-11.75 z"
id="path23"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 232.69375,596.82375 c 6.662,0.62 22.044,5.462 27.37,3.614 1.584,0.97 3.154,2.014 4.78,2.904 -4.194,1.55 -18.89,-0.318 -26.814,1.446 z"
id="path24"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 209.78375,574.90374 c -2.394,-0.948 -7.676,-3.032 -7.456,-6.196 5.142,-1.48 19.682,5.378 26.054,6.196 3.788,3.09 7.482,6.23801 11.126,9.49601 l -0.16,0.142 c -3.374,0.606 -25.568,-7.70801 -29.564,-9.63801 z"
id="path25"
style="stroke-width:2" />
<path
fill="#d6991c"
d="m 209.78375,574.90374 c 3.996,1.93 26.19,10.24401 29.564,9.63801 l 0.16,-0.142 c 4.716,4.008 9.52,7.936 13.794,12.424 1.884,0.704 5.45,2.046 6.762,3.614 -5.326,1.848 -20.708,-2.994 -27.37,-3.614 -10.77,-1.75 -16.314,-4.876 -19.558,-16.004 -1.528,-1.78 -2.85,-3.59801 -3.352,-5.91601 z"
id="path26"
style="stroke-width:2" />
<path
fill="#bf8a24"
d="m 209.78375,574.90374 c 3.996,1.93 26.19,10.24401 29.564,9.63801 l 0.16,-0.142 c 4.716,4.008 9.52,7.936 13.794,12.424 v 0 c -11.244,-0.884 -22.286,-6.858 -31.866,-12.424 -2.804,-0.374 -5.434,-2.774 -8.3,-3.58 -1.528,-1.78 -2.85,-3.59801 -3.352,-5.91601 z"
id="path27"
style="stroke-width:2" />
<path
fill="#ad7214"
d="m 221.43575,584.39975 c 6.578,-0.56 30.096,8.298 31.866,12.424 -11.244,-0.884 -22.286,-6.858 -31.866,-12.424 z"
id="path28"
style="stroke-width:2" />
<path
fill="#132b6d"
d="m 266.41175,531.65974 c -4.998,-0.03 -11.098,-9.27801 -14.01,-12.81601 -78.2,-95.08401 -44.296,-239.09604 68.622,-289.88605 14.626,-6.58 87.39,-28.004 83.98,-12.018 0.29,5.32 -5.89,12.826 -5.742,19.654 l 0.8,-0.356 0.256,-0.984 c 0.838,-3.116 3.132,-7.658 4.686,-10.42 v 0 c -2.204,7.998 -7.486,15.148 -3.436,23.75601 l -0.2,-1.06001 1.24,-0.028 c 0.878,-0.938 1.364,-2.1 1.93,-3.238 l -0.516,-0.474 c -0.172,-2.288 2.834,-5.232 4.34,-6.828 v 3.898 c 7.112,-8.978 14.618,-17.87 22.424,-26.248 l 0.5,0.152 c 8.212,2.444 16.47,3.944 24.602,6.854 58.574,20.972 106.85,72.05001 120.456,133.45202 1.73,7.81001 2.632,15.79601 4.472,23.57201 0.174,4.016 1.316,11.12 -0.142,14.692 l -1.322,0.664 1.154,0.176 c 1.286,3.432 0.364,9.786 0.31,13.526 0.428,4.816 0.606,10.62001 0,15.40801 -1.662,4.574 -2.66,9.378 -3.582,14.148 -0.862,5.382 -1.694,10.842 -3.742,15.924 -1.502,3.656 -3.308,7.462 -4.308,11.294 -0.442,4.27201 -3.664,10.89601 -6.116,14.42401 -2.28,4.28 -4.82,10.524 -8.172,14.028 -2.766,4.198 -5.424,8.452 -8.062,12.73 l -10.636,13.256 c -0.812,1.354 -10.158,11.70601 -11.41,12.74801 -4.732,2.976 -7.86,5.02 -11.552,9.288 -4.794,2.344 -9.02,6.04 -13.816,8.136 -4.916,2.576 -9.95,5.226 -14.068,8.998 -5.336,1.804 -10.23,3.636 -15.1,6.486 -3,0.812 -11.478,3.87 -14.124,3.644 -5.37,1.882 -11.066,2.43 -16.396,4.486 l -14.888,2.206 c -3.228,-0.058 -14.524,1.172 -16.482,0 -2.668,0.884 -14.2,-1.2 -17.154,-2.206 -4.388,-1.97 -13.234,-3.4 -15.17,-4.486 -15.284,-4 -26.706,-61.61201 4.84,-58.55001 5.12,0.178 10.212,1.104 15.266,1.896 -0.322,-4.59 -1.47,-8.966 -2.758,-13.362 -31.792,-69.38401 -101.182,-95.30202 -174.692,-84.31001 28.904,2.816 52.742,14.29 77.006,28.634 14.684,13.388 42.828,39.46001 22.146,59.30801 -4.42,-5.66 -9.796,-10.928 -13.456,-17.124 l -1.134,0.23 0.924,-0.544 0.246,0.612 -1.168,-0.966 c -0.378,1.04 0.1,2.79 0.238,3.908 -0.494,8.656 -0.63,17.812 -1.922,26.378 -0.986,1.08 -1.914,2.264 -3.172,3.032 -4.348,3.636 -8.422,7.43801 -12.466,11.40401 -1.992,-3.07 -5.034,-6.59401 -6.57,-9.84601 -2.598,-1.562 -2.622,-4.334 -3.65,-6.816 l -0.892,0.308 c -0.248,2.022 1.28,3.668 1.268,5.77 l -0.744,0.738 c 2.36,3.862 7.746,10.52601 7.948,15.01601 -5.642,-0.656 -11.25,-1.548 -16.884,-2.268 z"
id="path29"
style="stroke-width:2" />
<path
fill="#f1be39"
d="m 271.23775,505.65573 4.11,2.688 c 0.612,3.864 2.48,7.024 4.018,10.568 -2.598,-1.562 -2.622,-4.334 -3.65,-6.816 l -0.892,0.308 c -0.248,2.022 1.28,3.668 1.268,5.77 l -0.744,0.738 c -1.114,-4.514 -3.114,-8.68 -4.11,-13.256 z"
id="path30"
style="stroke-width:2" />
<path
fill="#051053"
d="m 397.67375,507.07373 c 2.356,4.01 4.79,7.942 7.33,11.838 -3.3,-1.106 -7.652,-4.4 -10.786,-4.59 l 1.848,-0.566 c 1.032,-1.614 0.804,-4.254 1.44,-6.188 z"
id="path31"
style="stroke-width:2" />
<path
fill="#0f0e1a"
d="m 393.38575,498.19573 c 3.194,2.542 2.828,5.462 4.288,8.878 l -0.168,0.494 c -0.636,1.934 -0.408,4.574 -1.44,6.188 l -1.848,0.566 c -4.74,-0.682 -9.642,-1.346 -13.34,-4.66 5.12,0.178 10.212,1.104 15.266,1.896 -0.322,-4.59 -1.47,-8.966 -2.758,-13.362 z"
id="path32"
style="stroke-width:2" />
<path
fill="#f1be39"
d="m 405.00375,216.93968 c 0.29,5.32 -5.89,12.826 -5.742,19.654 l 0.8,-0.356 0.256,-0.984 c 0.838,-3.116 3.132,-7.658 4.686,-10.42 v 0 c -2.204,7.998 -7.486,15.148 -3.436,23.75601 l -0.2,-1.06001 1.24,-0.028 c 0.878,-0.938 1.364,-2.1 1.93,-3.238 l -0.516,-0.474 c -0.172,-2.288 2.834,-5.232 4.34,-6.828 v 3.898 c -5.74,7.47601 -10.278,15.97801 -14.976,24.13401 2.614,-16.47 4.536,-32.74201 11.618,-48.05401 z"
id="path33"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 376.03775,568.21174 c 3.14,-7.134 6.892,-14.264 9.44,-21.616 2.51,8.576 3.87,17.374 5.73,26.102 -4.388,-1.97 -13.234,-3.4 -15.17,-4.486 z"
id="path34"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 275.34775,508.34373 c 7.554,3.424 15.174,6.414 23.054,9.01 -4.348,3.636 -8.422,7.43801 -12.466,11.40401 -1.992,-3.07 -5.034,-6.59401 -6.57,-9.84601 -1.538,-3.544 -3.406,-6.704 -4.018,-10.568 z"
id="path35"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 580.81575,378.64171 c 0.174,4.016 1.316,11.12 -0.142,14.692 l -1.322,0.664 c -8.51,-1.606 -16.614,-3.178 -25.25,-4.102 8.398,-6.016 16.886,-8.52 26.714,-11.254 z"
id="path36"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 554.10175,411.69971 c 8.586,-2.24 17.924,-2.716 26.714,-4 0.428,4.816 0.606,10.62001 0,15.40801 -8.872,-2.66 -19.79,-5.044 -26.714,-11.40801 z"
id="path37"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 413.80575,549.08374 c 5.198,7.878 7.314,17.22 11.038,25.82 -3.228,-0.058 -14.524,1.172 -16.482,0 1.018,-8.646 2.216,-17.686 5.444,-25.82 z"
id="path38"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 526.91575,484.43773 c 9.316,1.67 19.154,5.096 27.98,8.488 -2.766,4.198 -5.424,8.452 -8.062,12.73 -7.26,-6.506 -15.232,-12.516 -19.918,-21.218 z"
id="path39"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 549.10575,437.25572 c 9.318,-0.64 18.79,-0.084 28.128,0 -0.862,5.382 -1.694,10.842 -3.742,15.924 -8.43,-5.086 -16.78,-9.56 -24.386,-15.924 z"
id="path40"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 439.73175,543.29174 1.36,1.452 c 6.326,6.73 9.89,15.802 15.036,23.468 -5.37,1.882 -11.066,2.43 -16.396,4.486 z"
id="path41"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 539.67175,462.21972 c 9.972,-0.004 19.626,1.052 29.512,2.254 -0.442,4.27201 -3.664,10.89601 -6.116,14.42401 -8.166,-3.222 -17.172,-10.556 -23.396,-16.67801 z"
id="path42"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 488.88575,521.69573 c 7.732,3.84201 19.168,12.47201 24.35,19.25201 -4.794,2.344 -9.02,6.04 -13.816,8.136 -4.688,-8.85 -7.936,-17.748 -10.534,-27.38801 z"
id="path43"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 509.94175,505.65573 c 5.494,1.07 8.69,2.82 13.364,5.902 5.104,1.702 8.644,4.112 12.892,7.354 -0.812,1.354 -10.158,11.70601 -11.41,12.74801 -2.844,-4.58 -6.188,-9.33401 -8.274,-14.30601 -2.536,-3.532 -4.474,-7.872 -6.572,-11.698 z"
id="path44"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 465.35375,533.92774 c 7.502,6.24 15.294,15.644 19.998,24.154 -5.336,1.804 -10.23,3.636 -15.1,6.486 -3.214,-9.588 -4.238,-20.568 -4.898,-30.64 z"
id="path45"
style="stroke-width:2" />
<path
fill="#2356ae"
d="M 351.39175,758.48578 C 168.77575,730.12777 41.748945,587.64375 38.358945,403.44571 34.725145,206.00568 197.09775,42.52665 394.25175,39.316449 c 199.908,-3.255 364.866,156.319231 367.572,354.681261 -6.094,-4.58 -18.174,-19.598 -24.91,-26.196 -36.444,-35.69001 -72.076,-72.23002 -107.964,-108.48002 -5.912,-5.854 -23.126,-25.17801 -28.692,-29.00401 -3.034,-2.352 -5.59,-5.25 -8.21,-8.044 -6.464,-8.496 -15.426,-15.704 -22.864,-23.372 -34.426,-27.95001 -82.38,-53.60801 -126.896,-61.38602 -2.586,-0.374 -5.316,-0.164 -7.914,0 -18.072,-0.934 -32.114,10.64001 -48.896,14.09201 43.72,19.62 46.344,31.682 19.526,73.22601 v 0 c -1.554,2.762 -3.848,7.304 -4.686,10.42 l -0.256,0.984 -0.8,0.356 c -0.148,-6.828 6.032,-14.334 5.742,-19.654 3.41,-15.986 -69.354,5.438 -83.98,12.018 -112.918,50.79001 -146.822,194.80204 -68.622,289.88605 2.912,3.538 9.012,12.78601 14.01,12.81601 5.634,0.72 11.242,1.612 16.884,2.268 -0.202,-4.49 -5.588,-11.15401 -7.948,-15.01601 l 0.744,-0.738 c 0.012,-2.102 -1.516,-3.748 -1.268,-5.77 l 0.892,-0.308 c 1.028,2.482 1.052,5.254 3.65,6.816 1.536,3.252 4.578,6.77601 6.57,9.84601 4.044,-3.966 8.118,-7.76801 12.466,-11.40401 1.258,-0.768 2.186,-1.952 3.172,-3.032 1.292,-8.566 1.428,-17.722 1.922,-26.378 -0.138,-1.118 -0.616,-2.868 -0.238,-3.908 l 1.168,0.966 -0.246,-0.612 -0.924,0.544 1.134,-0.23 c 3.66,6.196 9.036,11.464 13.456,17.124 20.682,-19.848 -7.462,-45.92001 -22.146,-59.30801 8.322,2.714 22.978,21.546 26.672,29.42201 2.368,5.048 2.81,14.832 4.236,17.488 3.938,-9.238 -6.242,-21.60201 -4.594,-23.16201 6.228,12.53801 9.19,23.92001 0,35.56001 -11.034,9.136 -29.284,21.156 -36.122,33.99601 -15.95,29.946 -3.004,58.48801 7.948,85.92401 1.766,3.338 5.028,8.098 5.668,11.75001 h -1.106 l -7.45,-10.00201 c -1.728,-2.178 -3.5,-4.33 -5.016,-6.664 -6.324,-4.728 -13.836,-10.324 -21.092,-13.49 -1.626,-0.89 -3.196,-1.934 -4.78,-2.904 -1.312,-1.568 -4.878,-2.91 -6.762,-3.614 -4.274,-4.488 -9.078,-8.416 -13.794,-12.424 -3.644,-3.258 -7.338,-6.40601 -11.126,-9.49601 -9.516,-10.912 -20.848,-17.964 -34.05,-23.62 -3.398,0.208 -6.702,-1.566 -10.05,-2.2 0.09,1.694 0.138,3.308 0,5 0.146,1.304 0.434,2.74 0,3.998 -6.198,-2.672 -19.392,-5.09 -26.25,-6.798 -4.648,-2.816 -18.714,-10.192 -23.586,-10.336 4.584,5.41 10.284,9.738 14.854,15.058 7.016,12.05 42.298,43.51801 53.304,54.48401 l 117.162,117.50802 c 7.714,7.722 27.054,23.83601 31.626,30.48801 z"
id="path46"
style="stroke-width:2" />
<path
fill="#132b6d"
d="m 179.65375,204.78568 0.312,-1.174 0.54,0.326 c 1.66,8.908 0.01,23.462 3.776,31.23 -0.946,2.464 -0.94,5.09 -2.088,7.614 -0.896,-7.214 -1.61,-14.446 -2.54,-21.656 -0.13,-5.46 -0.212,-10.878 0,-16.34 z"
id="path47"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 125.81775,276.75769 c 2.17,11.74 9.116,22.444 12.934,33.79201 l -0.57,0.518 c -1.16,-3.654 -7.662,-20.46601 -9.84,-22.36001 l -0.976,0.068 c -1.38,1.692 -2.846,2.256 -4.866,3.024 -2.616,6.924 -1.898,24.47801 -3.168,33.15201 -0.472,-15.43 -0.356,-34.15801 6.486,-48.19401 z"
id="path48"
style="stroke-width:2" />
<path
fill="#132b6d"
d="m 274.23575,141.76967 c -2.074,7.182 -3.328,13.142 -2.998,20.634 -4.176,2.324 -7.592,4.762 -11.174,7.91 v -2.354 c 1.878,-6.262 2.766,-12.768 4.78,-19.034 3.524,-1.72 6.27,-4.824 9.392,-7.156 z"
id="path49"
style="stroke-width:2" />
<path
fill="#132b6d"
d="m 371.74975,108.36966 c -3.86,7.4 -7.354,14.524 -9.404,22.688 v 0 c -3.648,0.82 -7.228,1.122 -10.954,1.38 4.392,-6.38 5.642,-13.5 10.954,-19.87 l 1.312,1.376 c 2.71,-0.242 5.8,-4.024 8.092,-5.574 z"
id="path50"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 268.33575,131.05766 c -1.042,5.972 -2.31,11.92001 -3.492,17.86801 -2.014,6.266 -2.902,12.772 -4.78,19.034 -1.326,-4.864 3.318,-9.734 1.244,-14.208 -22.57,-10.084 -17.62,14.712 -26.708,18.13 6.172,-15.816 20.434,-30.548 33.736,-40.82401 z"
id="path51"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 179.65375,196.07968 c -0.244,2.936 -0.14,5.77 0,8.706 -0.212,5.462 -0.13,10.88 0,16.34 -2.87,1.676 -3.574,6.084 -4.174,9.192 -1.636,3.874 -3.642,7.834 -4.67,11.914 l -0.244,0.106 0.41,-0.728 -0.192,-0.106 c 2.75,-11.394 5.076,-8.03 -4.17,-11.186 -1.178,2.228 -4.1,9.672 -5.944,10.542 4.934,-15.602 12.448,-29.868 18.984,-44.78 z"
id="path52"
style="stroke-width:2" />
<path
fill="#132b6d"
d="m 456.12775,109.52166 c 3.564,1.658 10.414,-0.138 14.124,-1.152 -9.878,8.046 -21.92,17.846 -27.964,29.146 -2.586,-0.374 -5.316,-0.164 -7.914,0 l -6.334,-3.096 c 7.916,-6.85 14.976,-14.806 22.762,-21.852 1.752,-1.066 3.52,-2.074 5.326,-3.046 z"
id="path53"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 100.50375,364.60771 c 8.122,7.8 22.772,25.956 30.762,31.252 0.936,5.038 2.374,10.71 2.462,15.774 -12.286,-9.396 -17.796,-19.394 -28.126,-27.642 0.096,1.026 0.082,1.858 -0.212,2.84 -2.522,-7.432 -3.886,-14.462 -4.886,-22.224 z"
id="path54"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 96.515745,442.51972 c 8.566005,4.34 36.750005,23.486 42.236005,30.46001 l 0.276,0.808 c 6.398,2.844 8.096,8.69 8.058,15.766 l -0.588,-0.544 c -1.434,-1.32 -10.678,-7.62 -12.052,-7.594 -5.946,-3.566 -23.722,-21.69601 -29.056,-20.70801 -3.03,-6.03 -5.978005,-12.092 -8.874005,-18.188 z"
id="path55"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 121.77975,525.87374 c 19.42,6.36 38.498,14.12 57.874,20.722 l 0.548,0.758 1.826,-0.056 c 1.258,1.488 1.388,4.868 2.254,6.786 0.146,1.304 0.434,2.74 0,3.998 -6.198,-2.672 -19.392,-5.09 -26.25,-6.798 -4.648,-2.816 -18.714,-10.192 -23.586,-10.336 -4.45,-4.812 -8.812,-9.764 -12.666,-15.074 z"
id="path56"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 271.23775,162.40367 c 7.99,-6.254 18.884,-10.416 28.25,-14.234 16.76,-6.832 13.44,-7.376 25.658,-19.48401 10.768,-10.672 29.362,-23.208 44.058,-28.062 -2.508,3.886 -5.042,7.672 -6.858,11.944 -5.312,6.37 -6.562,13.49 -10.954,19.87 -0.974,1.678 -1.832,2.932 -3.262,4.254 l -0.532,-0.056 c 0.956,-3.102 4.54,-2.84 3.518,-6.662 l -2.128,-2.174 c -8.514,3.742 -77.504,34.61201 -77.75,34.60401 z"
id="path57"
style="stroke-width:2" />
<defs
id="defs58">
<linearGradient
id="gradient_5"
gradientUnits="userSpaceOnUse"
x1="145.13785"
y1="328.17804"
x2="117.22018"
y2="280.89636"
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
<stop
offset="0"
stop-color="#D79A18"
id="stop57" />
<stop
offset="1"
stop-color="#F6C842"
id="stop58" />
</linearGradient>
</defs>
<path
fill="url(#gradient_5)"
d="m 105.38975,460.70772 c 5.334,-0.988 23.11,17.14201 29.056,20.70801 4.286,3.456 9.396,6.13 13.392,9.86 0.278,-2.39 0.424,-4.632 1.462,-6.838 l 0.504,-0.106 c 0.058,-0.954 -0.086,-7.128 0.79,-5.038 1.712,4.084 3.956,1.936 4.492,8.664 l 0.486,-0.014 c 2.38,7.206 8.172,8.99 13.068,13.884 l -0.348,0.398 c 2.612,0.138 4.874,0.24 7.188,1.558 0.816,0.698 1.66,1.344 2.532,1.97 l 0.462,1.048 c -1.04,0.308 -0.606,0.28 -1.274,0.272 3.704,0.932 3.808,4.058 4.994,7.248 v 0 c 2.772,3.696 5.17,7.268 6.946,11.55201 -1.732,-0.248 -24.262,-10.67601 -16.892,-1.472 2.482,3.098 5.226,7.084 8.34,9.526 2.636,1.906 4.292,5.756 7.29,7.02 h 1.262 l -1.262,2.344 c 0.818,1.872 1.938,2.472 3.716,3.304 l -0.66,0.048 c -2.968,0.184 -9.982,-2.572 -6.652,2.44 0.09,1.694 0.138,3.308 0,5 -0.866,-1.918 -0.996,-5.298 -2.254,-6.786 l -1.826,0.056 -0.548,-0.758 c -0.52,-3.778 -6.05,-8.072 -8.808,-10.5 -24.584,-13.75401 -54.27,-50.32801 -65.456,-75.38802 z"
id="path58"
style="fill:url(#gradient_5);stroke-width:2" />
<path
fill="#f1be39"
d="m 170.84575,536.09574 c 0.178,0.002 16.806,6.982 17.032,7.196 0.818,1.872 1.938,2.472 3.716,3.304 l -0.66,0.048 c -2.968,0.184 -9.982,-2.572 -6.652,2.44 0.09,1.694 0.138,3.308 0,5 -0.866,-1.918 -0.996,-5.298 -2.254,-6.786 l -1.826,0.056 -0.548,-0.758 c -0.52,-3.778 -6.05,-8.072 -8.808,-10.5 z"
id="path59"
style="stroke-width:2" />
<path
fill="#bf8a24"
d="m 182.19375,514.32173 c -5.22,-0.312 -16.074,-7.81 -20,-10.892 -0.398,-0.312 -4.628,-3.938 -2.568,-3.994 4.124,-0.114 11.04,6.52 14.26,8.908 0.87,-0.988 2.086,-1.036 3.314,-1.27 3.704,0.932 3.808,4.058 4.994,7.248 z"
id="path60"
style="stroke-width:2" />
<path
fill="#d6991c"
d="m 177.19975,507.07373 c 3.704,0.932 3.808,4.058 4.994,7.248 -2.664,-2.118 -5.5,-4.052 -8.308,-5.978 0.87,-0.988 2.086,-1.036 3.314,-1.27 z"
id="path61"
style="stroke-width:2" />
<defs
id="defs62">
<linearGradient
id="gradient_6"
gradientUnits="userSpaceOnUse"
x1="238.76126"
y1="143.77654"
x2="270.52316"
y2="95.432106"
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
<stop
offset="0"
stop-color="#FAD84F"
id="stop61" />
<stop
offset="1"
stop-color="#FFF5A9"
id="stop62" />
</linearGradient>
</defs>
<path
fill="url(#gradient_6)"
d="m 362.34575,131.05766 c 26.81,-3.184 19.722,-1.768 42.234,-13.04 19.684,-9.856 41.194,-16.094 63.324,-15.652 -4.056,2.182 -8.086,4.39 -11.776,7.156 -1.806,0.972 -3.574,1.98 -5.326,3.046 -7.786,7.046 -14.846,15.002 -22.762,21.852 l 6.334,3.096 c -18.072,-0.934 -32.114,10.64001 -48.896,14.09201 -3.1,0.442 -6.45,0.35 -9.44,1.264 -3.958,1.83 -9.35,-0.016 -13.526,1.328 l -0.166,0.49 c 4.412,1.276 9.87,1.98 13.692,4.562 -11.014,0.822 -21.384,-2.856 -32.396,-2.412 -0.74,-0.772 -5.22,0.294 -7.562,-0.282 l 0.286,-0.044 c -8.446,-2.598 -0.096,-4.918 2.406,-7.588 6.796,-3.554 22.95,-8.952 23.574,-17.86801 z"
id="path62"
style="fill:url(#gradient_6);stroke-width:2" />
<path
fill="#e4c267"
d="m 341.76375,151.60767 c 11.034,-5.176 26.9,-6.422 39.114,-7.498 -2.7,3.496 -6.968,3.658 -4.84,8.762 -3.958,1.83 -9.35,-0.016 -13.526,1.328 l -0.166,0.49 c -4.888,-1.222 -8.504,-1.066 -13.358,0 -2.746,0.4 -8.482,-0.994 -10.622,-2.552 l 0.184,-0.502 -0.088,0.422 0.506,-0.548 z"
id="path63"
style="stroke-width:2" />
<path
fill="#f1be39"
d="m 424.84375,132.43766 c 9.142,-6.23 14.826,-16.674 25.958,-19.87 -7.786,7.046 -14.846,15.002 -22.762,21.852 l 6.334,3.096 c -18.072,-0.934 -32.114,10.64001 -48.896,14.09201 -3.1,0.442 -6.45,0.35 -9.44,1.264 -2.128,-5.104 2.14,-5.266 4.84,-8.762 8.736,-2.842 14.512,-8.95201 24.126,-9.69001 2.98,-2.124 16.504,-3.504 19.84,-1.982 z"
id="path64"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 405.00375,134.41966 c 2.98,-2.124 16.504,-3.504 19.84,-1.982 -3.412,3.298 -15.364,2.648 -19.84,1.982 z"
id="path65"
style="stroke-width:2" />
<path
fill="#f1be39"
d="m 348.98775,127.79966 2.128,2.174 c 1.022,3.822 -2.562,3.56 -3.518,6.662 l 0.532,0.056 c 1.43,-1.322 2.288,-2.576 3.262,-4.254 3.726,-0.258 7.306,-0.56 10.954,-1.38 -0.624,8.91601 -16.778,14.31401 -23.574,17.86801 -7.41,2.68 -9.978,8.094 -16.164,11.038 -3.652,1.74 -27.878,3.596 -21.164,11.206 l -1.672,0.284 6.764,0.428 c -13.404,2.41 -17.64,4.718 -29.284,7.922 6.38,1.602 10.798,-2.57 18.448,0.768 h 2.702 l -0.042,1.276 c -7.05,4.88 -18.516,5.498 -27.53,13.56001 -1.344,1.2 -2.83,2.678 -4.418,3.494 -4.23,1.326 -8.724,2.754 -13.11,3.378 -1.89,1.25 -12.68,4.234 -15.272,4.588 v 0 -2.082 l -2.28,-3.718 c -4.61,0.068 -7.042,12.34 -7.368,15.872 -8.018,0.742 -11.65,9.846 -16.818,14.858 -3.88,-1.22 -4.476,2.806 -6.472,5.164 -1.86,1.146 -4.982,3.384 -5.056,5.82 1.124,1.468 1.626,2.97 2.234,4.704 v 0 c -0.316,5.61801 1.456,4.99401 6.442,4.89801 -1.14,1.822 -2.366,3.564 -3.62,5.31 -1.95,2.246 -3.464,4.796 -5.056,7.3 -3.182,5.058 -6.5,9.462 -10.092,14.184 l -0.804,0.272 c -2.854,3.482 -4.438,8.244 -6.946,12.09 0.062,-2.884 0.094,-5.748 0,-8.632 -0.152,-5.29 -0.606,-10.77 0,-16.034 -4.278,6.658 -7.876,14.308 -9.904,21.966 l -0.172,-0.658 c -0.69,-2.716 -0.326,-5.508 -1.658,-8.056 -2.812,3.078 -0.546,7.956 -1.82,11.414 -2.326,1.824 -3.704,3.838 -4.96,6.498 0.362,13.11001 -0.04,26.34401 -0.64,39.44401 -2.058,-8.594 -3.944,-31.802 -5.008,-35.10001 -1.466,3.81001 -4.786,9.06401 -5.378,12.93801 -1.004,6.558 0.336,12.898 -1.634,19.682 l -0.152,-2.372 c -1.242,0.97 -0.692,3.5 -1.568,4.852 -0.888,5.956 -6.352,24.62201 -2.024,29.02001 l 1.026,-0.056 c 0.982,-1.328 1.022,-2.274 0.998,-3.888 2.54,11.112 6.984,15.086 6.272,27.338 -4.292,-5.588 -5.538,-12.7 -9.37,-18.494 -3.122,10.1 -3.688,19.896 -1.048,30.034 0.382,1.46 5.496,9.346 2.684,9.412 -1.922,-1.014 -3.814,-2.066 -5.696,-3.148 v 6.18601 l 5.696,5.592 -0.786,0.856 c 0.296,2.89 2.728,6.41 -0.85,8.024 -1.37,-0.752 -2.74,-1.49 -4.06,-2.326 1.508,3.706 4.194,6.776 5.696,10.326 -5.51,8.998 8.018,9.652 6.644,16.822 -2.168,-1.12 -4.022,-2.238 -6.51,-2.394 l -0.58,0.476 c 1.212,3.574 5.104,5.87 8.18,7.788 l 0.106,0.944 c 2.112,1.702 5.154,3.652 6.672,5.856 l -0.092,0.576 c -1.6,-0.072 -10.62,-4.306 -6.686,-0.158 3.098,4.66401 7.5,8.32001 11.042,12.63001 1.028,1.378 2.036,2.636 2.66,4.248 l -0.342,0.572 c -2.3,-0.9 -3.438,-2.91 -5.976,-3.28 2.058,3.032 5.576,4.756 7.89,7.506 -6.846,-3.492 -13.43,-7.156 -19.826,-11.44 1.408,2.746 2.824,5.372 4.552,7.934 -0.206,1.33 -0.332,2.17 0,3.506 l -0.486,0.014 c -0.536,-6.728 -2.78,-4.58 -4.492,-8.664 -0.876,-2.09 -0.732,4.084 -0.79,5.038 l -0.504,0.106 c -1.038,2.206 -1.184,4.448 -1.462,6.838 -3.996,-3.73 -9.106,-6.404 -13.392,-9.86 1.374,-0.026 10.618,6.274 12.052,7.594 l 0.588,0.544 c 0.038,-7.076 -1.66,-12.922 -8.058,-15.766 l -0.276,-0.808 c 1.184,0.176 3.7,2.69 4.754,3.524 -1.57,-16.19201 -6.668,-17.95401 -15.372,-31.30601 -8.38,-12.854 -23.376,-43.43601 -22.744,-58.36601 0.294,-0.982 0.308,-1.814 0.212,-2.84 10.33,8.248 15.84,18.246 28.126,27.642 -0.088,-5.064 -1.526,-10.736 -2.462,-15.774 0.614,-23.334 -11.684,-42.03401 -11.934,-70.90801 1.27,-8.674 0.552,-26.22801 3.168,-33.15201 2.02,-0.768 3.486,-1.332 4.866,-3.024 l 0.976,-0.068 c 2.178,1.894 8.68,18.70601 9.84,22.36001 l 0.57,-0.518 c 1.386,0.9 2.382,2.54 3.39,3.858 1.862,-13.02001 6.618,-19.94201 9.452,-31.46801 3.608,-14.66 3.426,-26.278 9.076,-42.08001 1.844,-0.87 4.766,-8.314 5.944,-10.542 9.246,3.156 6.92,-0.208 4.17,11.186 l 0.192,0.106 -0.41,0.728 0.244,-0.106 c 1.028,-4.08 3.034,-8.04 4.67,-11.914 0.6,-3.108 1.304,-7.516 4.174,-9.192 0.93,7.21 1.644,14.442 2.54,21.656 1.148,-2.524 1.142,-5.15 2.088,-7.614 8.798,-9.326 16.32,-19.906 24.89,-29.486 4.756,-5.318 10.938,-9.912 15.132,-15.63401 4.15,-5.656 5.632,-12.712 10.296,-18.166 9.088,-3.418 4.138,-28.214 26.708,-18.13 2.074,4.474 -2.57,9.344 -1.244,14.208 v 2.354 c 3.582,-3.148 6.998,-5.586 11.174,-7.91 v 0 c 0.246,0.008 69.236,-30.86201 77.75,-34.60401 z"
id="path66"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 182.19375,266.87369 c 0.564,-0.782 2.61,-7.412 3.094,-3.452 0.322,2.642 1.102,21.51 -3.094,19.486 -0.152,-5.29 -0.606,-10.77 0,-16.034 z"
id="path67"
style="stroke-width:2" />
<path
fill="#e7aa1f"
d="m 125.81775,310.5497 c 2.45,2.318 5.498,11.792 7.544,15.398 2.698,4.748 6.998,5.738 5.39,11.534 l -0.768,0.906 -0.92,-0.342 c -4.658,-6.078 -8.65,-19.842 -11.246,-27.496 z"
id="path68"
style="stroke-width:2" />
<path
fill="#e7aa1f"
d="m 238.02975,204.78568 c 5.564,-5.62 15.092,-21.80401 23.426,-22.17401 -1.03,1.272 -5.95,6.208 -5.208,7.716 -1.792,1.966 -4.054,3.62801 -5.628,5.75201 -3.67,1.584 -4.516,5.316 -6.108,8.706 2.69,-0.91 5.97,-2.338 8.79,-2.506 -1.89,1.25 -12.68,4.234 -15.272,4.588 v 0 z"
id="path69"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 295.69975,180.57167 h 2.702 c -8.5,7.116 -21.784,5.136 -31.99,7.612 -3.338,1.062 -6.97,1.058 -10.164,2.144 -0.742,-1.508 4.178,-6.444 5.208,-7.716 1.96,-1.942 7.53,-0.964 9.782,0 8.094,-2.064 16.232,-1.644 24.462,-2.04 z"
id="path70"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 261.45575,182.61167 c 1.96,-1.942 7.53,-0.964 9.782,0 -9.012,0.558 -6.586,5.252 -4.826,5.572 -3.338,1.062 -6.97,1.058 -10.164,2.144 -0.742,-1.508 4.178,-6.444 5.208,-7.716 z"
id="path71"
style="stroke-width:2" />
<path
fill="#bf8a24"
d="m 200.03575,242.78168 c 1.124,1.468 1.626,2.97 2.234,4.704 v 0 c -0.316,5.61801 1.456,4.99401 6.442,4.89801 -1.14,1.822 -2.366,3.564 -3.62,5.31 -1.95,2.246 -3.464,4.796 -5.056,7.3 -3.182,5.058 -6.5,9.462 -10.092,14.184 l -0.804,0.272 c 0.992,-2.136 -0.112,-2.814 -0.734,-4.852 -1.902,-6.224 8.246,-26.224 11.63,-31.81601 z"
id="path72"
style="stroke-width:2" />
<path
fill="#f1be39"
d="m 202.26975,247.48568 v 0 c -0.316,5.61801 1.456,4.99401 6.442,4.89801 -1.14,1.822 -2.366,3.564 -3.62,5.31 -1.95,2.246 -3.464,4.796 -5.056,7.3 -0.992,-6.32 1.244,-11.428 2.234,-17.50801 z"
id="path73"
style="stroke-width:2" />
<path
fill="#d6991c"
d="m 298.40175,180.57167 -0.042,1.276 c -7.05,4.88 -18.516,5.498 -27.53,13.56001 -1.344,1.2 -2.83,2.678 -4.418,3.494 -4.23,1.326 -8.724,2.754 -13.11,3.378 -2.82,0.168 -6.1,1.596 -8.79,2.506 1.592,-3.39 2.438,-7.122 6.108,-8.706 1.574,-2.124 3.836,-3.78601 5.628,-5.75201 3.194,-1.086 6.826,-1.082 10.164,-2.144 10.206,-2.476 23.49,-0.496 31.99,-7.612 z"
id="path74"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 271.23775,193.48968 c -1.194,1.158 -4.558,3.824 -4.826,5.412 -4.23,1.326 -8.724,2.754 -13.11,3.378 -2.82,0.168 -6.1,1.596 -8.79,2.506 1.592,-3.39 2.438,-7.122 6.108,-8.706 6.902,-0.504 13.82,-1.276 20.618,-2.59 z"
id="path75"
style="stroke-width:2" />
<path
fill="#d6991c"
d="m 149.29975,466.26772 c -9.304,-9.342 -10.01,-43.218 -10.518,-57.68401 -0.538,-15.364 -1.234,-63.88401 4.522,-71.25001 l 0.256,0.428 -0.55,-0.498 c 0.858,0.034 1.536,1.384 3.084,1.57 -0.638,1.076 -2.192,1.04 -2.766,2.208 -3.374,6.87 -7.36,60.42401 -3.304,71.67401 l 1.144,0.50401 0.542,-0.48001 c -0.028,-1.786 0.016,-3.3 0.432,-5.04 v 6.18601 l 5.696,5.592 -0.786,0.856 c 0.296,2.89 2.728,6.41 -0.85,8.024 -1.37,-0.752 -2.74,-1.49 -4.06,-2.326 1.508,3.706 4.194,6.776 5.696,10.326 -5.51,8.998 8.018,9.652 6.644,16.822 -2.168,-1.12 -4.022,-2.238 -6.51,-2.394 l -0.58,0.476 c 1.212,3.574 5.104,5.87 8.18,7.788 l 0.106,0.944 c 2.112,1.702 5.154,3.652 6.672,5.856 l -0.092,0.576 c -1.6,-0.072 -10.62,-4.306 -6.686,-0.158 3.098,4.66401 7.5,8.32001 11.042,12.63001 1.028,1.378 2.036,2.636 2.66,4.248 l -0.342,0.572 c -2.3,-0.9 -3.438,-2.91 -5.976,-3.28 2.058,3.032 5.576,4.756 7.89,7.506 -6.846,-3.492 -13.43,-7.156 -19.826,-11.44 1.408,2.746 2.824,5.372 4.552,7.934 -0.206,1.33 -0.332,2.17 0,3.506 l -0.486,0.014 c -0.536,-6.728 -2.78,-4.58 -4.492,-8.664 -0.876,-2.09 -0.732,4.084 -0.79,5.038 l -0.504,0.106 c 0.334,-4.398 -0.07,-7.204 1.72,-11.458 -1.008,-2.202 -1.76,-4.234 -1.72,-6.71201 z"
id="path76"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 149.29975,466.26772 c 2.55,1.562 4.34,4.17401 5.39,6.94401 l -0.242,0.898 c -1.33,0.158 -2.298,-0.53 -3.428,-1.13 -1.008,-2.202 -1.76,-4.234 -1.72,-6.71201 z"
id="path77"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 234.59975,171.88167 c 9.088,-3.418 4.138,-28.214 26.708,-18.13 2.074,4.474 -2.57,9.344 -1.244,14.208 v 2.354 c -1.148,1.816 -5.864,3.458 -7.922,4.874 -14.14,9.736 -15.23,14.912 -24.894,26.40001 -6.982,8.3 -15.26,15.5 -22.134,23.932 -11.878,14.576 -27.774,39.38201 -41.434,51.23801 0.79,-11.36 12.096,-43.94801 11.8,-46.44001 0.6,-3.108 1.304,-7.516 4.174,-9.192 0.93,7.21 1.644,14.442 2.54,21.656 1.148,-2.524 1.142,-5.15 2.088,-7.614 8.798,-9.326 16.32,-19.906 24.89,-29.486 4.756,-5.318 10.938,-9.912 15.132,-15.63401 4.15,-5.656 5.632,-12.712 10.296,-18.166 z"
id="path78"
style="stroke-width:2" />
<path
fill="#bf8a24"
d="m 306.53575,171.88167 -6.764,-0.428 1.672,-0.284 c -6.714,-7.61 17.512,-9.466 21.164,-11.206 6.186,-2.944 8.754,-8.358 16.164,-11.038 -2.502,2.67 -10.852,4.99 -2.406,7.588 l -0.286,0.044 c 2.342,0.576 6.822,-0.49 7.562,0.282 11.012,-0.444 21.382,3.234 32.396,2.412 -3.822,-2.582 -9.28,-3.286 -13.692,-4.562 l 0.166,-0.49 c 4.176,-1.344 9.568,0.502 13.526,-1.328 2.99,-0.914 6.34,-0.822 9.44,-1.264 43.72,19.62 46.344,31.682 19.526,73.22601 v 0 c -1.554,2.762 -3.848,7.304 -4.686,10.42 l -0.256,0.984 -0.8,0.356 c -0.148,-6.828 6.032,-14.334 5.742,-19.654 3.41,-15.986 -69.354,5.438 -83.98,12.018 -112.918,50.79001 -146.822,194.80204 -68.622,289.88605 2.912,3.538 9.012,12.78601 14.01,12.81601 5.634,0.72 11.242,1.612 16.884,2.268 -0.202,-4.49 -5.588,-11.15401 -7.948,-15.01601 l 0.744,-0.738 c 0.012,-2.102 -1.516,-3.748 -1.268,-5.77 l 0.892,-0.308 c 1.028,2.482 1.052,5.254 3.65,6.816 1.536,3.252 4.578,6.77601 6.57,9.84601 4.044,-3.966 8.118,-7.76801 12.466,-11.40401 1.258,-0.768 2.186,-1.952 3.172,-3.032 1.292,-8.566 1.428,-17.722 1.922,-26.378 -0.138,-1.118 -0.616,-2.868 -0.238,-3.908 l 1.168,0.966 -0.246,-0.612 -0.924,0.544 1.134,-0.23 c 3.66,6.196 9.036,11.464 13.456,17.124 20.682,-19.848 -7.462,-45.92001 -22.146,-59.30801 8.322,2.714 22.978,21.546 26.672,29.42201 2.368,5.048 2.81,14.832 4.236,17.488 3.938,-9.238 -6.242,-21.60201 -4.594,-23.16201 6.228,12.53801 9.19,23.92001 0,35.56001 -11.034,9.136 -29.284,21.156 -36.122,33.99601 -15.95,29.946 -3.004,58.48801 7.948,85.92401 1.766,3.338 5.028,8.098 5.668,11.75001 h -1.106 l -7.45,-10.00201 c -1.728,-2.178 -3.5,-4.33 -5.016,-6.664 -6.324,-4.728 -13.836,-10.324 -21.092,-13.49 -1.626,-0.89 -3.196,-1.934 -4.78,-2.904 -1.312,-1.568 -4.878,-2.91 -6.762,-3.614 -4.274,-4.488 -9.078,-8.416 -13.794,-12.424 -3.644,-3.258 -7.338,-6.40601 -11.126,-9.49601 -9.516,-10.912 -20.848,-17.964 -34.05,-23.62 -3.398,0.208 -6.702,-1.566 -10.05,-2.2 -3.33,-5.012 3.684,-2.256 6.652,-2.44 l 0.66,-0.048 c -1.778,-0.832 -2.898,-1.432 -3.716,-3.304 l 1.262,-2.344 h -1.262 c -2.998,-1.264 -4.654,-5.114 -7.29,-7.02 -3.114,-2.442 -5.858,-6.428 -8.34,-9.526 -7.37,-9.20401 15.16,1.224 16.892,1.472 -1.776,-4.28401 -4.174,-7.85601 -6.946,-11.55201 v 0 c -1.186,-3.19 -1.29,-6.316 -4.994,-7.248 0.668,0.008 0.234,0.036 1.274,-0.272 l -0.462,-1.048 c -0.872,-0.626 -1.716,-1.272 -2.532,-1.97 -2.314,-1.318 -4.576,-1.42 -7.188,-1.558 l 0.348,-0.398 c -4.896,-4.894 -10.688,-6.678 -13.068,-13.884 -0.332,-1.336 -0.206,-2.176 0,-3.506 -1.728,-2.562 -3.144,-5.188 -4.552,-7.934 6.396,4.284 12.98,7.948 19.826,11.44 -2.314,-2.75 -5.832,-4.474 -7.89,-7.506 2.538,0.37 3.676,2.38 5.976,3.28 l 0.342,-0.572 c -0.624,-1.612 -1.632,-2.87 -2.66,-4.248 -3.542,-4.31 -7.944,-7.966 -11.042,-12.63001 -3.934,-4.148 5.086,0.086 6.686,0.158 l 0.092,-0.576 c -1.518,-2.204 -4.56,-4.154 -6.672,-5.856 l -0.106,-0.944 c -3.076,-1.918 -6.968,-4.214 -8.18,-7.788 l 0.58,-0.476 c 2.488,0.156 4.342,1.274 6.51,2.394 1.374,-7.17 -12.154,-7.824 -6.644,-16.822 -1.502,-3.55 -4.188,-6.62 -5.696,-10.326 1.32,0.836 2.69,1.574 4.06,2.326 3.578,-1.614 1.146,-5.134 0.85,-8.024 l 0.786,-0.856 -5.696,-5.592 v -6.18601 c 1.882,1.082 3.774,2.134 5.696,3.148 2.812,-0.066 -2.302,-7.952 -2.684,-9.412 -2.64,-10.138 -2.074,-19.934 1.048,-30.034 3.832,5.794 5.078,12.906 9.37,18.494 0.712,-12.252 -3.732,-16.226 -6.272,-27.338 0.024,1.614 -0.016,2.56 -0.998,3.888 l -1.026,0.056 c -4.328,-4.398 1.136,-23.06401 2.024,-29.02001 0.876,-1.352 0.326,-3.882 1.568,-4.852 l 0.152,2.372 c 1.97,-6.784 0.63,-13.124 1.634,-19.682 0.592,-3.874 3.912,-9.128 5.378,-12.93801 1.064,3.29801 2.95,26.50601 5.008,35.10001 0.6,-13.1 1.002,-26.334 0.64,-39.44401 1.256,-2.66 2.634,-4.674 4.96,-6.498 1.274,-3.458 -0.992,-8.336 1.82,-11.414 1.332,2.548 0.968,5.34 1.658,8.056 l 0.172,0.658 c 2.028,-7.658 5.626,-15.308 9.904,-21.966 -0.606,5.264 -0.152,10.744 0,16.034 0.094,2.884 0.062,5.748 0,8.632 2.508,-3.846 4.092,-8.608 6.946,-12.09 l 0.804,-0.272 c 3.592,-4.722 6.91,-9.126 10.092,-14.184 1.592,-2.504 3.106,-5.054 5.056,-7.3 1.254,-1.746 2.48,-3.488 3.62,-5.31 -4.986,0.096 -6.758,0.72 -6.442,-4.89801 v 0 c -0.608,-1.734 -1.11,-3.236 -2.234,-4.704 0.074,-2.436 3.196,-4.674 5.056,-5.82 1.996,-2.358 2.592,-6.384 6.472,-5.164 5.168,-5.012 8.8,-14.116 16.818,-14.858 0.326,-3.532 2.758,-15.804 7.368,-15.872 l 2.28,3.718 v 2.082 0 c 2.592,-0.354 13.382,-3.338 15.272,-4.588 4.386,-0.624 8.88,-2.052 13.11,-3.378 1.588,-0.816 3.074,-2.294 4.418,-3.494 9.014,-8.06201 20.48,-8.68001 27.53,-13.56001 l 0.042,-1.276 h -2.702 c -7.65,-3.338 -12.068,0.834 -18.448,-0.768 11.644,-3.204 15.88,-5.512 29.284,-7.922 z"
id="path79"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 154.48175,356.6817 c 1.552,0.2 3.084,0.076 4.642,0 -0.404,2.63801 -0.692,5.29001 -1.092,7.92601 -1.188,-2.608 -2.544,-5.248 -3.55,-7.92601 z"
id="path80"
style="stroke-width:2" />
<path
fill="#e7aa1f"
d="m 159.12375,442.51972 c 0.384,2.614 0.992,5.194 1.546,7.778 -3.03,-2.766 -6.444,-5.21 -9.65,-7.778 l 0.538,0.054 c 2.192,0.234 4.934,1.556 6.996,1.18 z"
id="path81"
style="stroke-width:2" />
<path
fill="#e7aa1f"
d="m 175.47975,498.19573 c 0.814,1.764 4.086,6.738 0,5.588 -2.314,-1.318 -4.576,-1.42 -7.188,-1.558 l 0.348,-0.398 c 2.21,-2.024 4.874,-1.53 6.84,-3.632 z"
id="path82"
style="stroke-width:2" />
<path
fill="#ad7214"
d="m 155.57175,466.26772 c 9.084,-1.716 12.038,4.78201 11.562,12.49601 l -0.52,0.134 c -3.542,-4.31 -7.944,-7.966 -11.042,-12.63001 z"
id="path83"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 155.57175,459.04972 c -3.076,-1.918 -6.968,-4.214 -8.18,-7.788 l 0.58,-0.476 c 2.488,0.156 4.342,1.274 6.51,2.394 2.566,1.4 4.326,3.672 6.188,5.87 1.02,1.764 1.71,3.5 2.37,5.424 -2.364,-1.688 -4.912,-4.152 -7.468,-5.424 z"
id="path84"
style="stroke-width:2" />
<path
fill="#d6991c"
d="m 180.58775,533.92774 c -3.114,-2.442 -5.858,-6.428 -8.34,-9.526 -7.37,-9.20401 15.16,1.224 16.892,1.472 6.636,13.13 -9.994,0.33 -16.85,-2.24 3.11,3.16 6.322,6.268 8.298,10.294 z"
id="path85"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 266.41175,531.65974 c 5.634,0.72 11.242,1.612 16.884,2.268 -0.584,3.624 -3.86,8.832 -5.208,12.668 -3.562,-5.308 -7.8,-9.892 -11.676,-14.936 z"
id="path86"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 142.14175,426.03172 c 1.32,0.836 2.69,1.574 4.06,2.326 4.29,3.432 12.174,7.82 12.862,13.616 l 0.06,0.546 -0.57,1.234 c -2.062,0.376 -4.804,-0.946 -6.996,-1.18 l -0.538,-0.054 c -1,-2.096 -2.014,-4.15 -3.182,-6.162 -1.502,-3.55 -4.188,-6.62 -5.696,-10.326 z"
id="path87"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 142.14175,407.69971 c 1.882,1.082 3.774,2.134 5.696,3.148 3.018,1.372 5.362,4.13001 7.734,6.39601 0.206,2.976 0.198,5.812 0,8.788 -2.638,-2.122 -5.196,-4.312 -7.734,-6.554 l -5.696,-5.592 z"
id="path88"
style="stroke-width:2" />
<path
fill="#f1be39"
d="m 155.57175,484.43773 c 2.938,2.218 18.9,12.614 19.908,13.758 -1.966,2.102 -4.63,1.608 -6.84,3.632 -4.896,-4.894 -10.688,-6.678 -13.068,-13.884 -0.332,-1.336 -0.206,-2.176 0,-3.506 z"
id="path89"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 303.49575,487.94373 c -0.138,-1.118 -0.616,-2.868 -0.238,-3.908 l 1.168,0.966 -0.246,-0.612 -0.924,0.544 1.134,-0.23 c 3.66,6.196 9.036,11.464 13.456,17.124 -2.234,2.422 -5.066,4.484 -7.648,6.516 -1.722,-5.352 -6.16,-14.438 -4.026,-19.786 l -0.84,-0.608 c -0.8,1.028 -0.922,2.05 -1.224,3.294 z"
id="path90"
style="stroke-width:2" />
<path
fill="#f1be39"
d="m 343.64175,156.83967 c 11.012,-0.444 21.382,3.234 32.396,2.412 v 0 c 2.758,1.782 6.394,1.874 9.44,3.152 -10.682,1.228 -39.754,-2.68 -41.606,-1.904 0.806,1.616 2.88,2.336 4.224,3.502 l -1.41,0.542 0.34,0.15 -1.298,-0.124 c -4.908,-6.008 -9.214,-5.39 -10.248,-6.48 2.774,-0.232 5.512,-0.324 8.162,-1.25 z"
id="path91"
style="stroke-width:2" />
<path
fill="#e7aa1f"
d="m 376.03775,152.87167 c 2.99,-0.914 6.34,-0.822 9.44,-1.264 43.72,19.62 46.344,31.682 19.526,73.22601 v 0 c 5.832,-22.874 34.842,-43.05801 -2.732,-64.07601 -11.18,-6.254 -18.164,-10.16 -31.452,-6.352 l -0.424,1.2 -0.404,-0.834 c 3.842,4.244 26.77,7.59 30.22,14.342 -1.308,0.37 -18.904,-9.996 -23.724,-10.5 l -0.45,0.638 v 0 c -3.822,-2.582 -9.28,-3.286 -13.692,-4.562 l 0.166,-0.49 c 4.176,-1.344 9.568,0.502 13.526,-1.328 z"
id="path92"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 168.63975,291.53969 c 1.274,-3.458 -0.992,-8.336 1.82,-11.414 1.332,2.548 0.968,5.34 1.658,8.056 l 0.172,0.658 c 2.774,10.994 2.712,19.95201 -1.444,30.43201 -1.604,-9.654 -3.796,-17.92201 -2.206,-27.73201 z"
id="path93"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 149.29975,337.4817 c 0.876,-1.352 0.326,-3.882 1.568,-4.852 l 0.152,2.372 c 1.894,5.472 9.814,16.574 8.104,21.68 -1.558,0.076 -3.09,0.2 -4.642,0 -1.126,-2.77 -2.134,-5.716 -3.462,-8.39 -1.878,5.094 -2.658,8.81 -1.72,14.26601 0.024,1.614 -0.016,2.56 -0.998,3.888 l -1.026,0.056 c -4.328,-4.398 1.136,-23.06401 2.024,-29.02001 z"
id="path94"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 306.53575,171.88167 -6.764,-0.428 1.672,-0.284 c -6.714,-7.61 17.512,-9.466 21.164,-11.206 6.186,-2.944 8.754,-8.358 16.164,-11.038 -2.502,2.67 -10.852,4.99 -2.406,7.588 l -0.286,0.044 c 2.342,0.576 6.822,-0.49 7.562,0.282 -2.65,0.926 -5.388,1.018 -8.162,1.25 1.034,1.09 5.34,0.472 10.248,6.48 -3.348,-0.918 -27.976,0.078 -32.714,1.348 4.33,2.232 9.916,1.048 14.594,3.258 l 0.012,0.634 c -3.474,2.758 -16.412,2.3 -21.084,2.072 z"
id="path95"
style="stroke-width:2" />
<path
fill="#ad7214"
d="m 187.87775,540.94774 c 14.452,-1.578 18.17,9.438 25.354,17.744 17.95,20.75601 34.99,32.52001 57.314,46.64401 2.982,1.888 11.55,9.15 14.164,9.758 -0.954,-3.75 -7.964,-27.508 -9.222,-29.136 -2.72,-3.514 -11.288,-7.96801 -15.268,-11.09401 -12.18,-9.558 -46.938,-41.988 -52.316,-57.27201 l 0.808,-0.238 c 9.448,21.46801 48.068,54.83801 66.636,67.04602 1.412,2.178 10.994,29.386 10.588,32.432 -6.324,-4.728 -13.836,-10.324 -21.092,-13.49 -1.626,-0.89 -3.196,-1.934 -4.78,-2.904 -1.312,-1.568 -4.878,-2.91 -6.762,-3.614 -4.274,-4.488 -9.078,-8.416 -13.794,-12.424 -3.644,-3.258 -7.338,-6.40601 -11.126,-9.49601 -9.516,-10.912 -20.848,-17.964 -34.05,-23.62 -3.398,0.208 -6.702,-1.566 -10.05,-2.2 -3.33,-5.012 3.684,-2.256 6.652,-2.44 l 0.66,-0.048 c -1.778,-0.832 -2.898,-1.432 -3.716,-3.304 l 1.262,-2.344 z"
id="path96"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 189.13975,540.94774 c 5.534,2.624 11.97,2.904 15.952,8.136 -3.688,-0.196 -7.236,-1.452 -10.76,-2.488 h -2.738 c -1.778,-0.832 -2.898,-1.432 -3.716,-3.304 z"
id="path97"
style="stroke-width:2" />
<path
fill="#d6991c"
d="m 184.28175,549.08374 c -3.33,-5.012 3.684,-2.256 6.652,-2.44 l 0.66,-0.048 h 2.738 c 3.524,1.036 7.072,2.292 10.76,2.488 1.886,2.01 3.24,4.586 4.692,6.922 -3.318,-1.236 -12.546,-5.238 -15.452,-4.722 v 0 c -3.398,0.208 -6.702,-1.566 -10.05,-2.2 z"
id="path98"
style="stroke-width:2" />
<path
fill="#e7aa1f"
d="m 184.28175,549.08374 c -3.33,-5.012 3.684,-2.256 6.652,-2.44 l 0.66,-0.048 h 2.738 c -4.344,0.788 -4.744,0.478 -1.17,2.97 l -0.606,-0.004 c -4.844,0.006 -0.282,1.608 1.776,1.722 v 0 c -3.398,0.208 -6.702,-1.566 -10.05,-2.2 z"
id="path99"
style="stroke-width:2" />
<path
fill="#d6991c"
d="m 228.38175,216.93968 c 0.326,-3.532 2.758,-15.804 7.368,-15.872 l 2.28,3.718 v 2.082 0 c -6.518,12.316 13.27,-2.088 15.158,-2.352 -0.618,2.432 -27.42,25.384 -31.64,31.524 -3.73,5.426 -11.42,18.06801 -16.456,21.65401 1.254,-1.746 2.48,-3.488 3.62,-5.31 -4.986,0.096 -6.758,0.72 -6.442,-4.89801 v 0 c -0.608,-1.734 -1.11,-3.236 -2.234,-4.704 0.074,-2.436 3.196,-4.674 5.056,-5.82 1.996,-2.358 2.592,-6.384 6.472,-5.164 5.168,-5.012 8.8,-14.116 16.818,-14.858 z"
id="path100"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 232.69375,222.27368 v 0 c -2.516,5.136 -7.8,8.384 -11.258,12.894 0.908,-3.178 1.606,-7.628 3.46,-10.334 2.71,0.164 5.344,-1.512 7.798,-2.56 z"
id="path101"
style="stroke-width:2" />
<path
fill="#e4c267"
d="m 205.09175,236.96168 c 1.996,-2.358 2.592,-6.384 6.472,-5.164 -1.882,3.976 -3.154,7.958 -2.26,12.41 l 0.746,0.966 c 1.808,0.074 2.558,-0.808 4.2,-1.294 -0.568,2.526 -3.898,6.34801 -5.538,8.50401 -4.986,0.096 -6.758,0.72 -6.442,-4.89801 v 0 c -0.608,-1.734 -1.11,-3.236 -2.234,-4.704 0.074,-2.436 3.196,-4.674 5.056,-5.82 z"
id="path102"
style="stroke-width:2" />
<path
fill="#d6991c"
d="m 200.03575,242.78168 c 0.074,-2.436 3.196,-4.674 5.056,-5.82 -1.032,3.436 -2.298,6.974 -2.822,10.524 v 0 c -0.608,-1.734 -1.11,-3.236 -2.234,-4.704 z"
id="path103"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 228.38175,216.93968 c 0.326,-3.532 2.758,-15.804 7.368,-15.872 l 2.28,3.718 v 2.082 c -1.486,1.796 -3.142,3.526 -3.43,5.944 4.566,-0.902 8.72,-2.206 13.04,-3.914 -4.882,4.584 -9.786,9.102 -14.946,13.376 v 0 c -2.454,1.048 -5.088,2.724 -7.798,2.56 0.764,-2.614 2.36,-5.384 3.486,-7.894 z"
id="path104"
style="stroke-width:2" />
<path
fill="#fade6b"
d="m 358.50775,173.44367 c 18.416,-4.38 53.464,-10.342 55.298,16.884 -24.86,0.57 -35.762,0.938 -60.484,4.82201 l -0.202,-0.514 c 1.278,-0.93 3.428,-0.886 4.184,-1.712 6.046,-6.58801 1.738,-6.33201 2.402,-12.86401 0.52,-5.102 6.456,-5.5 -0.302,-6.478 z"
id="path105"
style="stroke-width:2" />
<defs
id="defs106">
<linearGradient
id="gradient_7"
gradientUnits="userSpaceOnUse"
x1="141.16791"
y1="268.56354"
x2="265.50784"
y2="226.48077"
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
<stop
offset="0"
stop-color="#E1AF37"
id="stop105" />
<stop
offset="1"
stop-color="#FCDE74"
id="stop106" />
</linearGradient>
</defs>
<path
fill="url(#gradient_7)"
d="m 208.71175,517.35373 c -86.018,-118.12402 -12.156,-301.82605 129.714,-339.49006 6.44,-1.71 13.438,-3.836 20.082,-4.42 l 0.896,0.138 c 6.758,0.978 0.822,1.376 0.302,6.478 -0.664,6.532 3.644,6.276 -2.402,12.86401 -0.756,0.826 -2.906,0.782 -4.184,1.712 l 0.202,0.514 c -12.89,3.57 -25.456,7.312 -37.754,12.642 -137.6,59.63401 -168.028,233.46204 -63.62,337.58006 7.44,7.418 16.184,13.6 23.4,21.124 0.094,5.944 0.338,11.96801 0,17.90401 -18.568,-12.20801 -57.188,-45.57801 -66.636,-67.04602 z"
id="path106"
style="fill:url(#gradient_7);stroke-width:2" />
</svg>

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -0,0 +1,51 @@
Writing own handler
===================
It is possible to extend the application by adding own custom commands. To do so it is required to implement class, which derives from ``ahriman.application.handlers.handler.Handler`` and put it to the ``ahriman.application.handlers`` package. The class later will be loaded automatically and included to each command run.
Let's imagine, that the new class implements ``help-web``, which prints server information to the stdout. To do so, we need to implement base ``ahriman.application.handlers.handler.Handler.run`` method which is entry point for all subcommands:
.. code-block:: python
from ahriman.application.application import Application
from ahriman.application.handlers.handler import Handler
class HelpWeb(Handler):
@classmethod
def run(cls, args: argparse.Namespace, repository_id: RepositoryId, configuration: Configuration, *,
report: bool) -> None:
# load application instance
# report is set to True to make sure that web client is loaded
application = Application(repository_id, configuration, report=True)
# extract web client
client = application.repository.reporter
# send request to the server
response = client.make_request("GET", f"{client.address}/api/v1/info")
result = response.json()
print(result)
The main functionality of the class is already described, but command is still not available yet. To do so, it is required to set ``arguments`` property, which is the list of the functions, each of them which takes argument parser object, creates new subcommand and returns the modified parser, e.g.:
.. code-block:: python
import argparse
from ahriman.application.handlers.handler import SubParserAction
...
@staticmethod
def set_parser(root: SubParserAction) -> argparse.ArgumentParser:
parser = root.add_parser("help-web", help="get web server status",
description="request server info and print it to stdout")
arguments = set_parser
In addition, ``ahriman.application.handlers.handler.Handler.ALLOW_MULTI_ARCHITECTURE_RUN`` can be set to ``False`` in order to disable multiprocess run (e.g. in case if there are conflicting operations, like writing to stdout).
Save the file above as ``/usr/lib/python3.12/site-packages/ahriman/application/handlers/help_web.py`` (replace ``python3.12`` with actual python version) and you are set.
For more examples and details, please check builtin handlers and classes documentations.

View File

@ -1,6 +1,12 @@
Advanced usage
==============
.. toctree::
:maxdepth: 2
handlers
views
Depending on the goal the package can be used in different ways. Nevertheless, in the most cases you will need some basic classes
.. code-block:: python
@ -9,9 +15,10 @@ Depending on the goal the package can be used in different ways. Nevertheless, i
from ahriman.core.configuration import Configuration
from ahriman.core.database import SQLite
from ahriman.models.repository_id import RepositoryId
architecture = "x86_64"
configuration = Configuration.from_path(Path("/etc/ahriman.ini"), architecture)
repository_id = RepositoryId("x86_64", "aur")
configuration = Configuration.from_path(Path("/etc/ahriman.ini"), repository_id)
database = SQLite.load(configuration)
At this point there are ``configuration`` and ``database`` instances which can be used later at any time anywhere, e.g.
@ -26,8 +33,10 @@ Almost all actions are wrapped by ``ahriman.core.repository.Repository`` class
.. code-block:: python
from ahriman.core.repository import Repository
from ahriman.models.pacman_synchronization import PacmanSynchronization
repository = Repository(architecture, configuration, database, report=True, unsafe=False)
repository = Repository(repository_id, configuration, database,
report=True, refresh_pacman_database=PacmanSynchronization.Disabled)
And the ``repository`` instance can be used to perform repository maintenance

View File

@ -0,0 +1,41 @@
Writing own API endpoint
========================
The web service loads views dynamically, thus it is possible to add custom API endpoint or even web page. The view must be derived from ``ahriman.web.views.base.BaseView`` and should implement desired HTTP methods. The API specification will be also loaded automatically if available, but optional. The implementation must be saved into the ``ahriman.web.views`` package
Let's consider example of API endpoint which always returns 204 with no response:
.. code-block:: python
from aiohttp.web import Response, HTTPNoContent
from ahriman.web.views.base import BaseView
class PingView(BaseView):
async def get(self) -> Response:
# do nothing, just raise 204 response
# check public methods of the BaseView class for all available controls
raise HTTPNoContent
The ``get()`` method can be decorated by ``aiohttp_apispec`` methods, but we will leave it for a self-study, please, consider to check examples of usages in the main package.
In order to view to be added to the route list correctly, few more properties are required to be set. First of all, it is required to specify ``ROUTES`` (list of strings), which contains list of all available routes, e.g.:
.. code-block:: python
...
ROUTES = ["/api/v1/ping"]
In addition, it is also recommended to specify permission level for using this endpoint. Since this endpoint neither does anything nor returns sensitive information, it can be set to ``UserAccess.Unauthorized``:
.. code-block:: python
...
GET_PERMISSION = UserAccess.Unauthorized
That's all. Just save the file as ``/usr/lib/python3.12/site-packages/ahriman/web/views/ping.py`` (replace ``python3.12`` with actual python version) and restart web server.
For more examples and details, please check builtin handlers and classes documentations.

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 762 KiB

View File

@ -1,6 +1,14 @@
ahriman.application.application package
=======================================
Subpackages
-----------
.. toctree::
:maxdepth: 4
ahriman.application.application.workers
Submodules
----------
@ -36,6 +44,14 @@ ahriman.application.application.application\_repository module
:no-undoc-members:
:show-inheritance:
ahriman.application.application.updates\_iterator module
--------------------------------------------------------
.. automodule:: ahriman.application.application.updates_iterator
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------

View File

@ -0,0 +1,37 @@
ahriman.application.application.workers package
===============================================
Submodules
----------
ahriman.application.application.workers.local\_updater module
-------------------------------------------------------------
.. automodule:: ahriman.application.application.workers.local_updater
:members:
:no-undoc-members:
:show-inheritance:
ahriman.application.application.workers.remote\_updater module
--------------------------------------------------------------
.. automodule:: ahriman.application.application.workers.remote_updater
:members:
:no-undoc-members:
:show-inheritance:
ahriman.application.application.workers.updater module
------------------------------------------------------
.. automodule:: ahriman.application.application.workers.updater
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.application.application.workers
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -20,6 +20,14 @@ ahriman.application.handlers.backup module
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.change module
------------------------------------------
.. automodule:: ahriman.application.handlers.change
:members:
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.clean module
-----------------------------------------
@ -28,6 +36,14 @@ ahriman.application.handlers.clean module
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.copy module
----------------------------------------
.. automodule:: ahriman.application.handlers.copy
:members:
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.daemon module
------------------------------------------
@ -100,6 +116,14 @@ ahriman.application.handlers.remove\_unknown module
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.repositories module
------------------------------------------------
.. automodule:: ahriman.application.handlers.repositories
:members:
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.restore module
-------------------------------------------
@ -108,6 +132,14 @@ ahriman.application.handlers.restore module
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.run module
---------------------------------------
.. automodule:: ahriman.application.handlers.run
:members:
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.search module
------------------------------------------
@ -148,6 +180,14 @@ ahriman.application.handlers.sign module
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.statistics module
----------------------------------------------
.. automodule:: ahriman.application.handlers.statistics
:members:
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.status module
------------------------------------------
@ -172,6 +212,14 @@ ahriman.application.handlers.structure module
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.tree\_migrate module
-------------------------------------------------
.. automodule:: ahriman.application.handlers.tree_migrate
:members:
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.triggers module
--------------------------------------------
@ -180,6 +228,14 @@ ahriman.application.handlers.triggers module
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.triggers\_support module
-----------------------------------------------------
.. automodule:: ahriman.application.handlers.triggers_support
:members:
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.unsafe\_commands module
----------------------------------------------------

View File

@ -21,6 +21,22 @@ ahriman.application.ahriman module
:no-undoc-members:
:show-inheritance:
ahriman.application.help\_formatter module
------------------------------------------
.. automodule:: ahriman.application.help_formatter
:members:
:no-undoc-members:
:show-inheritance:
ahriman.application.interactive\_shell module
---------------------------------------------
.. automodule:: ahriman.application.interactive_shell
:members:
:no-undoc-members:
:show-inheritance:
ahriman.application.lock module
-------------------------------

View File

@ -20,6 +20,22 @@ ahriman.core.alpm.pacman module
:no-undoc-members:
:show-inheritance:
ahriman.core.alpm.pacman\_database module
-----------------------------------------
.. automodule:: ahriman.core.alpm.pacman_database
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.alpm.pkgbuild\_parser module
-----------------------------------------
.. automodule:: ahriman.core.alpm.pkgbuild_parser
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.alpm.repo module
-----------------------------

View File

@ -36,6 +36,14 @@ ahriman.core.auth.oauth module
:no-undoc-members:
:show-inheritance:
ahriman.core.auth.pam module
----------------------------
.. automodule:: ahriman.core.auth.pam
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------

View File

@ -4,6 +4,14 @@ ahriman.core.build\_tools package
Submodules
----------
ahriman.core.build\_tools.package\_archive module
-------------------------------------------------
.. automodule:: ahriman.core.build_tools.package_archive
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.build\_tools.sources module
----------------------------------------

View File

@ -12,6 +12,14 @@ ahriman.core.configuration.configuration module
:no-undoc-members:
:show-inheritance:
ahriman.core.configuration.configuration\_multi\_dict module
------------------------------------------------------------
.. automodule:: ahriman.core.configuration.configuration_multi_dict
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.configuration.schema module
----------------------------------------
@ -20,6 +28,22 @@ ahriman.core.configuration.schema module
:no-undoc-members:
:show-inheritance:
ahriman.core.configuration.shell\_interpolator module
-----------------------------------------------------
.. automodule:: ahriman.core.configuration.shell_interpolator
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.configuration.shell\_template module
-------------------------------------------------
.. automodule:: ahriman.core.configuration.shell_template
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.configuration.validator module
-------------------------------------------

View File

@ -60,6 +60,78 @@ 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:
ahriman.core.database.migrations.m009\_local\_source module
-----------------------------------------------------------
.. automodule:: ahriman.core.database.migrations.m009_local_source
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.database.migrations.m010\_version\_based\_logs\_removal module
---------------------------------------------------------------------------
.. automodule:: ahriman.core.database.migrations.m010_version_based_logs_removal
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.database.migrations.m011\_repository\_name module
--------------------------------------------------------------
.. automodule:: ahriman.core.database.migrations.m011_repository_name
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.database.migrations.m012\_last\_commit\_sha module
---------------------------------------------------------------
.. automodule:: ahriman.core.database.migrations.m012_last_commit_sha
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.database.migrations.m013\_dependencies module
----------------------------------------------------------
.. automodule:: ahriman.core.database.migrations.m013_dependencies
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.database.migrations.m014\_auditlog module
------------------------------------------------------
.. automodule:: ahriman.core.database.migrations.m014_auditlog
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.database.migrations.m015\_logs\_process\_id module
---------------------------------------------------------------
.. automodule:: ahriman.core.database.migrations.m015_logs_process_id
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------

View File

@ -20,6 +20,30 @@ ahriman.core.database.operations.build\_operations module
:no-undoc-members:
:show-inheritance:
ahriman.core.database.operations.changes\_operations module
-----------------------------------------------------------
.. automodule:: ahriman.core.database.operations.changes_operations
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.database.operations.dependencies\_operations module
----------------------------------------------------------------
.. automodule:: ahriman.core.database.operations.dependencies_operations
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.database.operations.event\_operations module
---------------------------------------------------------
.. automodule:: ahriman.core.database.operations.event_operations
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.database.operations.logs\_operations module
--------------------------------------------------------

View File

@ -0,0 +1,45 @@
ahriman.core.distributed package
================================
Submodules
----------
ahriman.core.distributed.distributed\_system module
---------------------------------------------------
.. automodule:: ahriman.core.distributed.distributed_system
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.distributed.worker\_loader\_trigger module
-------------------------------------------------------
.. automodule:: ahriman.core.distributed.worker_loader_trigger
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.distributed.worker\_trigger module
-----------------------------------------------
.. automodule:: ahriman.core.distributed.worker_trigger
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.distributed.workers\_cache module
----------------------------------------------
.. automodule:: ahriman.core.distributed.workers_cache
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.core.distributed
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -20,6 +20,22 @@ ahriman.core.formatters.build\_printer module
:no-undoc-members:
:show-inheritance:
ahriman.core.formatters.changes\_printer module
-----------------------------------------------
.. automodule:: ahriman.core.formatters.changes_printer
:members:
: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
-----------------------------------------------------
@ -28,6 +44,14 @@ ahriman.core.formatters.configuration\_printer module
:no-undoc-members:
:show-inheritance:
ahriman.core.formatters.event\_stats\_printer module
----------------------------------------------------
.. automodule:: ahriman.core.formatters.event_stats_printer
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.formatters.package\_printer module
-----------------------------------------------
@ -36,6 +60,14 @@ ahriman.core.formatters.package\_printer module
:no-undoc-members:
:show-inheritance:
ahriman.core.formatters.package\_stats\_printer module
------------------------------------------------------
.. automodule:: ahriman.core.formatters.package_stats_printer
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.formatters.patch\_printer module
---------------------------------------------
@ -52,6 +84,22 @@ ahriman.core.formatters.printer module
:no-undoc-members:
:show-inheritance:
ahriman.core.formatters.repository\_printer module
--------------------------------------------------
.. automodule:: ahriman.core.formatters.repository_printer
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.formatters.repository\_stats\_printer module
---------------------------------------------------------
.. automodule:: ahriman.core.formatters.repository_stats_printer
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.formatters.status\_printer module
----------------------------------------------

View File

@ -0,0 +1,29 @@
ahriman.core.http package
=========================
Submodules
----------
ahriman.core.http.sync\_ahriman\_client module
----------------------------------------------
.. automodule:: ahriman.core.http.sync_ahriman_client
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.http.sync\_http\_client module
-------------------------------------------
.. automodule:: ahriman.core.http.sync_http_client
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.core.http
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -4,14 +4,6 @@ ahriman.core.log package
Submodules
----------
ahriman.core.log.filtered\_access\_logger module
------------------------------------------------
.. automodule:: ahriman.core.log.filtered_access_logger
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.log.http\_log\_handler module
------------------------------------------
@ -20,6 +12,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
-------------------------------------
@ -28,10 +28,10 @@ ahriman.core.log.lazy\_logging module
:no-undoc-members:
:show-inheritance:
ahriman.core.log.log module
---------------------------
ahriman.core.log.log\_loader module
-----------------------------------
.. automodule:: ahriman.core.log.log
.. automodule:: ahriman.core.log.log_loader
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -36,6 +36,14 @@ ahriman.core.report.jinja\_template module
:no-undoc-members:
:show-inheritance:
ahriman.core.report.remote\_call module
---------------------------------------
.. automodule:: ahriman.core.report.remote_call
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.report.report module
---------------------------------
@ -52,6 +60,14 @@ ahriman.core.report.report\_trigger module
:no-undoc-members:
:show-inheritance:
ahriman.core.report.rss module
------------------------------
.. automodule:: ahriman.core.report.rss
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.report.telegram module
-----------------------------------

View File

@ -12,6 +12,14 @@ ahriman.core.repository.cleaner module
:no-undoc-members:
:show-inheritance:
ahriman.core.repository.event\_logger module
--------------------------------------------
.. automodule:: ahriman.core.repository.event_logger
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.repository.executor module
---------------------------------------
@ -20,6 +28,14 @@ ahriman.core.repository.executor module
:no-undoc-members:
:show-inheritance:
ahriman.core.repository.package\_info module
--------------------------------------------
.. automodule:: ahriman.core.repository.package_info
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.repository.repository module
-----------------------------------------

View File

@ -12,13 +12,16 @@ Subpackages
ahriman.core.build_tools
ahriman.core.configuration
ahriman.core.database
ahriman.core.distributed
ahriman.core.formatters
ahriman.core.gitremote
ahriman.core.http
ahriman.core.log
ahriman.core.report
ahriman.core.repository
ahriman.core.sign
ahriman.core.status
ahriman.core.support
ahriman.core.triggers
ahriman.core.upload
@ -33,6 +36,14 @@ ahriman.core.exceptions module
:no-undoc-members:
:show-inheritance:
ahriman.core.module\_loader module
----------------------------------
.. automodule:: ahriman.core.module_loader
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.spawn module
-------------------------
@ -49,6 +60,14 @@ ahriman.core.tree module
:no-undoc-members:
:show-inheritance:
ahriman.core.types module
-------------------------
.. automodule:: ahriman.core.types
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.util module
------------------------
@ -57,6 +76,14 @@ ahriman.core.util module
:no-undoc-members:
:show-inheritance:
ahriman.core.utils module
-------------------------
.. automodule:: ahriman.core.utils
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------

View File

@ -12,6 +12,14 @@ ahriman.core.status.client module
:no-undoc-members:
:show-inheritance:
ahriman.core.status.local\_client module
----------------------------------------
.. automodule:: ahriman.core.status.local_client
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.status.watcher module
----------------------------------

View 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:

View 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:

View File

@ -20,6 +20,14 @@ ahriman.core.upload.http\_upload module
:no-undoc-members:
:show-inheritance:
ahriman.core.upload.remote\_service module
------------------------------------------
.. automodule:: ahriman.core.upload.remote_service
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.upload.rsync module
--------------------------------

View File

@ -36,6 +36,14 @@ ahriman.models.build\_status module
:no-undoc-members:
:show-inheritance:
ahriman.models.changes module
-----------------------------
.. automodule:: ahriman.models.changes
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.context\_key module
----------------------------------
@ -52,6 +60,30 @@ ahriman.models.counters module
:no-undoc-members:
:show-inheritance:
ahriman.models.dependencies module
----------------------------------
.. automodule:: ahriman.models.dependencies
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.event module
---------------------------
.. automodule:: ahriman.models.event
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.filesystem\_package module
-----------------------------------------
.. automodule:: ahriman.models.filesystem_package
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.internal\_status module
--------------------------------------
@ -60,6 +92,22 @@ 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 module
---------------------------------
.. automodule:: ahriman.models.log_record
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.log\_record\_id module
-------------------------------------
@ -68,6 +116,14 @@ ahriman.models.log\_record\_id module
:no-undoc-members:
:show-inheritance:
ahriman.models.metrics\_timer module
------------------------------------
.. automodule:: ahriman.models.metrics_timer
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.migration module
-------------------------------
@ -108,6 +164,14 @@ 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
---------------------------------------------
@ -116,6 +180,14 @@ ahriman.models.pacman\_synchronization module
:no-undoc-members:
:show-inheritance:
ahriman.models.pkgbuild module
------------------------------
.. automodule:: ahriman.models.pkgbuild
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.pkgbuild\_patch module
-------------------------------------
@ -124,6 +196,14 @@ ahriman.models.pkgbuild\_patch module
:no-undoc-members:
:show-inheritance:
ahriman.models.process\_status module
-------------------------------------
.. automodule:: ahriman.models.process_status
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.property module
------------------------------
@ -148,6 +228,14 @@ ahriman.models.report\_settings module
:no-undoc-members:
:show-inheritance:
ahriman.models.repository\_id module
------------------------------------
.. automodule:: ahriman.models.repository_id
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.repository\_paths module
---------------------------------------
@ -156,6 +244,14 @@ ahriman.models.repository\_paths module
:no-undoc-members:
:show-inheritance:
ahriman.models.repository\_stats module
---------------------------------------
.. automodule:: ahriman.models.repository_stats
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.result module
----------------------------
@ -164,6 +260,22 @@ ahriman.models.result module
:no-undoc-members:
:show-inheritance:
ahriman.models.scan\_paths module
---------------------------------
.. automodule:: ahriman.models.scan_paths
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.series\_statistics module
----------------------------------------
.. automodule:: ahriman.models.series_statistics
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.sign\_settings module
------------------------------------
@ -204,6 +316,22 @@ ahriman.models.user\_access module
:no-undoc-members:
:show-inheritance:
ahriman.models.waiter module
----------------------------
.. automodule:: ahriman.models.waiter
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.worker module
----------------------------
.. automodule:: ahriman.models.worker
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------

View File

@ -12,17 +12,6 @@ Subpackages
ahriman.models
ahriman.web
Submodules
----------
ahriman.version module
----------------------
.. automodule:: ahriman.version
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------

View File

@ -0,0 +1,29 @@
ahriman.web.apispec package
===========================
Submodules
----------
ahriman.web.apispec.decorators module
-------------------------------------
.. automodule:: ahriman.web.apispec.decorators
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.apispec.info module
-------------------------------
.. automodule:: ahriman.web.apispec.info
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.web.apispec
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -7,6 +7,7 @@ Subpackages
.. toctree::
:maxdepth: 4
ahriman.web.apispec
ahriman.web.middlewares
ahriman.web.schemas
ahriman.web.views
@ -14,14 +15,6 @@ Subpackages
Submodules
----------
ahriman.web.apispec module
--------------------------
.. automodule:: ahriman.web.apispec
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.cors module
-----------------------
@ -30,6 +23,14 @@ ahriman.web.cors module
:no-undoc-members:
:show-inheritance:
ahriman.web.keys module
-----------------------
.. automodule:: ahriman.web.keys
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.routes module
-------------------------

View File

@ -20,6 +20,22 @@ ahriman.web.schemas.auth\_schema module
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.build\_options\_schema module
-------------------------------------------------
.. automodule:: ahriman.web.schemas.build_options_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.changes\_schema module
------------------------------------------
.. automodule:: ahriman.web.schemas.changes_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.counters\_schema module
-------------------------------------------
@ -28,6 +44,14 @@ ahriman.web.schemas.counters\_schema module
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.dependencies\_schema module
-----------------------------------------------
.. automodule:: ahriman.web.schemas.dependencies_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.error\_schema module
----------------------------------------
@ -36,6 +60,38 @@ ahriman.web.schemas.error\_schema module
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.event\_schema module
----------------------------------------
.. automodule:: ahriman.web.schemas.event_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.event\_search\_schema module
------------------------------------------------
.. automodule:: ahriman.web.schemas.event_search_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.file\_schema module
---------------------------------------
.. automodule:: ahriman.web.schemas.file_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.info\_schema module
---------------------------------------
.. automodule:: ahriman.web.schemas.info_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.internal\_status\_schema module
---------------------------------------------------
@ -60,6 +116,14 @@ ahriman.web.schemas.login\_schema module
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.logs\_rotate\_schema module
-----------------------------------------------
.. automodule:: ahriman.web.schemas.logs_rotate_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.logs\_schema module
---------------------------------------
@ -92,6 +156,14 @@ ahriman.web.schemas.package\_names\_schema module
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.package\_patch\_schema module
-------------------------------------------------
.. automodule:: ahriman.web.schemas.package_patch_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.package\_properties\_schema module
------------------------------------------------------
@ -116,6 +188,38 @@ ahriman.web.schemas.package\_status\_schema module
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.package\_version\_schema module
---------------------------------------------------
.. automodule:: ahriman.web.schemas.package_version_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.pagination\_schema module
---------------------------------------------
.. automodule:: ahriman.web.schemas.pagination_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.patch\_name\_schema module
----------------------------------------------
.. automodule:: ahriman.web.schemas.patch_name_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.patch\_schema module
----------------------------------------
.. automodule:: ahriman.web.schemas.patch_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.pgp\_key\_id\_schema module
-----------------------------------------------
@ -132,6 +236,22 @@ ahriman.web.schemas.pgp\_key\_schema module
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.process\_id\_schema module
----------------------------------------------
.. automodule:: ahriman.web.schemas.process_id_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.process\_schema module
------------------------------------------
.. automodule:: ahriman.web.schemas.process_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.remote\_schema module
-----------------------------------------
@ -140,6 +260,22 @@ ahriman.web.schemas.remote\_schema module
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.repository\_id\_schema module
-------------------------------------------------
.. automodule:: ahriman.web.schemas.repository_id_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.repository\_stats\_schema module
----------------------------------------------------
.. automodule:: ahriman.web.schemas.repository_stats_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.search\_schema module
-----------------------------------------
@ -156,6 +292,22 @@ ahriman.web.schemas.status\_schema module
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.update\_flags\_schema module
------------------------------------------------
.. automodule:: ahriman.web.schemas.update_flags_schema
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.schemas.worker\_schema module
-----------------------------------------
.. automodule:: ahriman.web.schemas.worker_schema
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------

View File

@ -8,9 +8,8 @@ Subpackages
:maxdepth: 4
ahriman.web.views.api
ahriman.web.views.service
ahriman.web.views.status
ahriman.web.views.user
ahriman.web.views.v1
ahriman.web.views.v2
Submodules
----------
@ -31,6 +30,22 @@ ahriman.web.views.index module
:no-undoc-members:
:show-inheritance:
ahriman.web.views.static module
-------------------------------
.. automodule:: ahriman.web.views.static
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.status\_view\_guard module
--------------------------------------------
.. automodule:: ahriman.web.views.status_view_guard
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------

View File

@ -1,69 +0,0 @@
ahriman.web.views.service package
=================================
Submodules
----------
ahriman.web.views.service.add module
------------------------------------
.. automodule:: ahriman.web.views.service.add
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.service.pgp module
------------------------------------
.. automodule:: ahriman.web.views.service.pgp
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.service.rebuild module
----------------------------------------
.. automodule:: ahriman.web.views.service.rebuild
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.service.remove module
---------------------------------------
.. automodule:: ahriman.web.views.service.remove
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.service.request module
----------------------------------------
.. automodule:: ahriman.web.views.service.request
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.service.search module
---------------------------------------
.. automodule:: ahriman.web.views.service.search
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.service.update module
---------------------------------------
.. automodule:: ahriman.web.views.service.update
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.web.views.service
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -1,45 +0,0 @@
ahriman.web.views.status package
================================
Submodules
----------
ahriman.web.views.status.logs module
------------------------------------
.. automodule:: ahriman.web.views.status.logs
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.status.package module
---------------------------------------
.. automodule:: ahriman.web.views.status.package
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.status.packages module
----------------------------------------
.. automodule:: ahriman.web.views.status.packages
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.status.status module
--------------------------------------
.. automodule:: ahriman.web.views.status.status
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.web.views.status
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -1,29 +0,0 @@
ahriman.web.views.user package
==============================
Submodules
----------
ahriman.web.views.user.login module
-----------------------------------
.. automodule:: ahriman.web.views.user.login
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.user.logout module
------------------------------------
.. automodule:: ahriman.web.views.user.logout
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.web.views.user
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -0,0 +1,21 @@
ahriman.web.views.v1.auditlog package
=====================================
Submodules
----------
ahriman.web.views.v1.auditlog.events module
-------------------------------------------
.. automodule:: ahriman.web.views.v1.auditlog.events
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.web.views.v1.auditlog
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -0,0 +1,21 @@
ahriman.web.views.v1.distributed package
========================================
Submodules
----------
ahriman.web.views.v1.distributed.workers module
-----------------------------------------------
.. automodule:: ahriman.web.views.v1.distributed.workers
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.web.views.v1.distributed
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -0,0 +1,69 @@
ahriman.web.views.v1.packages package
=====================================
Submodules
----------
ahriman.web.views.v1.packages.changes module
--------------------------------------------
.. automodule:: ahriman.web.views.v1.packages.changes
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.packages.dependencies module
-------------------------------------------------
.. automodule:: ahriman.web.views.v1.packages.dependencies
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.packages.logs module
-----------------------------------------
.. automodule:: ahriman.web.views.v1.packages.logs
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.packages.package module
--------------------------------------------
.. automodule:: ahriman.web.views.v1.packages.package
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.packages.packages module
---------------------------------------------
.. automodule:: ahriman.web.views.v1.packages.packages
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.packages.patch module
------------------------------------------
.. automodule:: ahriman.web.views.v1.packages.patch
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.packages.patches module
--------------------------------------------
.. automodule:: ahriman.web.views.v1.packages.patches
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.web.views.v1.packages
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -0,0 +1,23 @@
ahriman.web.views.v1 package
============================
Subpackages
-----------
.. toctree::
:maxdepth: 4
ahriman.web.views.v1.auditlog
ahriman.web.views.v1.distributed
ahriman.web.views.v1.packages
ahriman.web.views.v1.service
ahriman.web.views.v1.status
ahriman.web.views.v1.user
Module contents
---------------
.. automodule:: ahriman.web.views.v1
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -0,0 +1,93 @@
ahriman.web.views.v1.service package
====================================
Submodules
----------
ahriman.web.views.v1.service.add module
---------------------------------------
.. automodule:: ahriman.web.views.v1.service.add
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.service.logs module
----------------------------------------
.. automodule:: ahriman.web.views.v1.service.logs
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.service.pgp module
---------------------------------------
.. automodule:: ahriman.web.views.v1.service.pgp
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.service.process module
-------------------------------------------
.. automodule:: ahriman.web.views.v1.service.process
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.service.rebuild module
-------------------------------------------
.. automodule:: ahriman.web.views.v1.service.rebuild
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.service.remove module
------------------------------------------
.. automodule:: ahriman.web.views.v1.service.remove
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.service.request module
-------------------------------------------
.. automodule:: ahriman.web.views.v1.service.request
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.service.search module
------------------------------------------
.. automodule:: ahriman.web.views.v1.service.search
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.service.update module
------------------------------------------
.. automodule:: ahriman.web.views.v1.service.update
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.service.upload module
------------------------------------------
.. automodule:: ahriman.web.views.v1.service.upload
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.web.views.v1.service
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -0,0 +1,37 @@
ahriman.web.views.v1.status package
===================================
Submodules
----------
ahriman.web.views.v1.status.info module
---------------------------------------
.. automodule:: ahriman.web.views.v1.status.info
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.status.repositories module
-----------------------------------------------
.. automodule:: ahriman.web.views.v1.status.repositories
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.status.status module
-----------------------------------------
.. automodule:: ahriman.web.views.v1.status.status
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.web.views.v1.status
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -0,0 +1,29 @@
ahriman.web.views.v1.user package
=================================
Submodules
----------
ahriman.web.views.v1.user.login module
--------------------------------------
.. automodule:: ahriman.web.views.v1.user.login
:members:
:no-undoc-members:
:show-inheritance:
ahriman.web.views.v1.user.logout module
---------------------------------------
.. automodule:: ahriman.web.views.v1.user.logout
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.web.views.v1.user
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -0,0 +1,21 @@
ahriman.web.views.v2.packages package
=====================================
Submodules
----------
ahriman.web.views.v2.packages.logs module
-----------------------------------------
.. automodule:: ahriman.web.views.v2.packages.logs
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.web.views.v2.packages
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -0,0 +1,18 @@
ahriman.web.views.v2 package
============================
Subpackages
-----------
.. toctree::
:maxdepth: 4
ahriman.web.views.v2.packages
Module contents
---------------
.. automodule:: ahriman.web.views.v2
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -6,23 +6,25 @@ Package structure
Packages have strict rules of importing:
* ``ahriman.application`` package must not be used anywhere except for itself.
* ``ahriman.application`` package must not be used outside of this package.
* ``ahriman.core`` and ``ahriman.models`` packages don't have any import restriction. Actually we would like to totally restrict importing of ``core`` package from ``models``, but it is impossible at the moment.
* ``ahriman.web`` package is allowed to be imported from ``ahriman.application`` (web handler only, only ``ahriman.web.web`` methods). It also must not be imported globally, only local import is allowed.
* ``ahriman.web`` package is allowed to be imported from ``ahriman.application`` (web handler only, only ``ahriman.web.web`` methods).
* The idea remains the same for all imports, if an package requires some specific dependencies, it must be imported locally to keep dependencies optional.
Full dependency diagram:
.. image:: ahriman-architecture.svg
:target: _images/ahriman-architecture.svg
.. graphviz:: _static/architecture.dot
:alt: architecture
``ahriman.application`` package
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This package contains application (aka executable) related classes and everything for that. It also contains package called ``ahriman.application.handlers`` in which all available subcommands are described as separated classes derived from base ``ahriman.application.handlers.Handler`` class.
This package contains application (aka executable) related classes and everything for it. It also contains package called ``ahriman.application.handlers`` in which all available subcommands are described as separated classes derived from the base ``ahriman.application.handlers.handler.Handler`` class. Those classes are being loaded dynamically through the lookup of the ``ahriman.application.handlers`` package.
``ahriman.application.application.Application`` (god class) is used for any interaction from parsers with repository. It is divided into multiple traits by functions (package related and repository related) in the same package.
``ahriman.application.application.workers`` package contains specific wrappers for local and remote build processes.
``ahriman.application.ahriman`` contains only command line parses and executes specified ``Handler`` on success, ``ahriman.application.lock.Lock`` is additional class which provides file-based lock and also performs some common checks.
``ahriman.core`` package
@ -30,31 +32,37 @@ This package contains application (aka executable) related classes and everythin
This package contains everything required for the most of application actions and it is separated into several packages:
* ``ahriman.core.alpm`` package controls pacman related functions. It provides wrappers for ``pyalpm`` library and safe calls for repository tools (``repo-add`` and ``repo-remove``). Also this package contains ``ahriman.core.alpm.remote`` package which provides wrapper for remote sources (e.g. AUR RPC and official repositories RPC).
* ``ahriman.core.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.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) and some other helpers.
* ``ahriman.core.auth`` package provides classes for authorization methods used by web mostly. Base class is ``ahriman.core.auth.Auth`` which must be instantiated by ``load`` method. This package is only required by the ``ahriman.web`` package.
* ``ahriman.core.build_tools`` is a package which provides wrapper for ``devtools`` commands.
* ``ahriman.core.database`` is everything including data and schema migrations for database.
* ``ahriman.core.configuration`` contains extensions for standard ``configparser`` module and some validation related classes.
* ``ahriman.core.database`` is everything for database, including data and schema migrations.
* ``ahriman.core.distributed`` package with triggers and helpers for distributed build system.
* ``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.
* ``ahriman.core.log`` is a log utils package. It includes logger loader class, custom HTTP based logger and access logger for HTTP services with additional filters.
* ``ahriman.core.http`` package provides HTTP clients which can be used later by other classes.
* ``ahriman.core.log`` is a log utils package. It includes logger loader class, custom HTTP based logger and some wrappers.
* ``ahriman.core.report`` is a package with reporting triggers. Should not be called directly.
* ``ahriman.core.repository`` contains several traits and base repository (``ahriman.core.repository.Repository`` class) implementation.
* ``ahriman.core.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.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.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``, ``ahriman.core.upload`` and other built-in triggers 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.module_loader`` provides ``implementations`` method which can be used for dynamic classes load. In particular, this method is used for web views and application handlers loading.
* ``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.
* ``ahriman.core.types`` are an additional global types for mypy checks.
* ``ahriman.core.utils`` contains some useful functions which are not the part of any other class.
``ahriman.models`` package
^^^^^^^^^^^^^^^^^^^^^^^^^^
It provides models for any other part of application. Unlike ``ahriman.core`` package classes from here provide only conversion methods (e.g. create class from another or convert to). Mostly case classes and enumerations.
It provides models for any other part of application. Unlike ``ahriman.core`` package classes from here provide only conversion methods (e.g. create class from another or convert to). It is mostly presented by case classes and enumerations.
``ahriman.web`` package
^^^^^^^^^^^^^^^^^^^^^^^
@ -62,24 +70,27 @@ 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.views`` contains web views derived from aiohttp view class.
* ``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. Those classes are loaded dynamically through the filesystem lookup.
* ``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 subcommand and related handler which is set by the 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 continue in current process otherwise. Class attribute ``ALLOW_MULTI_ARCHITECTURE_RUN`` controls whether the application can be run in multiple processes or not - this feature is required for some handlers (e.g. ``Config``, which utilizes stdout to print messages).
#. 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.
Application is designed to run from ``systemd`` services and provides parametrized by architecture timer and service file for that.
The application is designed to run from ``systemd`` services and provides parametrized by repository identifier timer and service file for that.
Subcommand design
^^^^^^^^^^^^^^^^^
@ -89,13 +100,58 @@ All subcommands are divided into several groups depending on the role they are d
* ``aur`` (``aur-search``) group is for AUR operations.
* ``help`` (e.g. ``help``) are system commands.
* ``package`` subcommands (e.g. ``package-add``) allow to perform single package actions.
* ``patch`` subcommands (e.g. ``pacth-list``) are the special case of ``package`` subcommands introduced in order to control patches for packages.
* ``patch`` subcommands (e.g. ``patch-list``) are the special case of ``package`` subcommands introduced in order to control patches for packages.
* ``repo`` subcommands (e.g. ``repo-check``) usually perform actions on whole repository.
* ``service`` subcommands (e.g. ``service-setup``) perform actions which are related to whole service managing: create repository, show configuration.
* ``user`` subcommands (``user-add``) are intended for user management.
* ``web`` subcommands are related to web service management.
For historical reasons and in order to keep backward compatibility some subcommands have aliases to their shorter forms or even other groups, but the service doesn't guarantee that they will remain unchanged.
For historical reasons and in order to keep backward compatibility some subcommands have aliases to their shorter forms or even other groups, but the application doesn't guarantee that they will remain unchanged.
Filesystem tree
---------------
The application supports two types of trees, one is for the legacy configuration (when there were no explicit repository name configuration available) and another one is the new-style tree. This document describes only new-style tree in order to avoid deprecated structures.
Having default root as ``/var/lib/ahriman`` (differs from container though), the directory structure is the following:
.. code-block::
/var/lib/ahriman/
├── ahriman.db
├── cache
├── chroot
│ └── aur
├── packages
│ └── aur
│ └── x86_64
├── pacman
│ └── aur
│ └── x86_64
│ ├── local
│ │ └── ALPM_DB_VERSION
│ └── sync
│ ├── core.db
│ ├── extra.db
│ └── multilib.db
└── repository
└── aur
└── x86_64
├── aur.db -> aur.db.tar.gz
├── aur.db.tar.gz
├── aur.files -> aur.files.tar.gz
└── aur.files.tar.gz
There are multiple subdirectories, some of them are commons for any repository, but some of them are not.
* ``cache`` is a directory with locally stored PKGBUILD's and VCS packages. It is common for all repositories and architectures.
* ``chroot/{repository}`` is a chroot directory for ``devtools``. It is specific for each repository, but shared for different architectures inside (the ``devtools`` handles architectures automatically).
* ``packages/{repository}/{architecture}`` is a directory with prebuilt packages. When a package is built, first it will be uploaded to this directory and later will be handled by update process. It is architecture and repository specific.
* ``pacman/{repository}/{architecture}`` is the repository and architecture specific caches for pacman's databases.
* ``repository/{repository}/{architecture}`` is a repository packages directory.
Normally you should avoid direct interaction with the application tree. For tree migration process refer to the :doc:`migration notes <migrations/index>`.
Database
--------
@ -105,52 +161,69 @@ The service uses SQLite database in order to store some internal info.
Database instance
^^^^^^^^^^^^^^^^^
All methods related to specific part of database (basically operations per table) are split into different traits located inside ``ahriman.core.database.operations`` package. The base trait ``ahriman.core.database.operations.Operations`` also provides generic methods for database access (e.g. row converters and transactional support).
All methods related to the specific part of database (basically operations per table) are split into different traits located inside ``ahriman.core.database.operations`` package. The base trait ``ahriman.core.database.operations.Operations`` also provides generic methods for database access (e.g. row converters and transactional support).
The ``ahriman.core.database.SQLite`` class itself derives from all of these traits and implements methods for initialization, including migrations.
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.
The schema migrations 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 queries, 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
^^^^^^^^^^^^^^^^
By default, it parses rows into python dictionary. In addition, the following pseudo-types are supported:
* ``dict[str, Any]``, ``list[Any]`` - for storing JSON data structures in database (technically there is no restriction on types for dictionary keys and values, but it is recommended to use only string keys). The type is stored as ``json`` data type and ``json.loads`` and ``json.dumps`` methods are used in order to read and write from/to database respectively.
* ``dict[str, Any]`` and ``list[Any]`` - for storing JSON data structures in database (technically there is no restriction on types for dictionary keys and values, but it is recommended to use only string keys). The type is stored as ``json`` data type and ``json.loads`` and ``json.dumps`` methods are used in order to read and write from/to database respectively.
Basic flows
-----------
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. ``DOAS_USER``, ``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 (additional sudo configuration to pass environment variables might be required).
Add new packages or rebuild existing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Idea is to copy package to the directory from which it will be handled at the next update run. Different variants are supported:
The idea is to add package to a build queue from which it will be handled automatically during the next update run. Different variants are supported:
* If supplied argument is file then application moves the file to the directory with built packages. Same rule applies for directory, but in this case it copies every package-like file from the specified directory.
* If supplied argument is directory and there is ``PKGBUILD`` file there it will be treated as local package. In this case it will queue this package to build and copy source files (``PKGBUILD`` and ``.SRCINFO``) to caches.
* If supplied argument is not file then application tries to lookup for the specified name in AUR and clones it into the directory with manual updates. This scenario can also handle package dependencies which are missing in repositories.
* If supplied argument is file, then application moves the file to the directory with the built packages. Same rule is applied for directory, but in this case it copies every package-like file from the specified directory.
* If supplied argument is directory and there is ``PKGBUILD`` file there, it will be treated as local package. In this case it will queue this package to build and copy source files (``PKGBUILD`` and ``.SRCINFO``) to caches.
* If supplied argument looks like URL (i.e. it has scheme, which is neither ``data`` nor ``file``, e.g. ``http://``), it tries to download the package from the specified remote source.
* If supplied argument is not file then application tries to lookup for the specified name in AUR and clones it into the temporary directory, from which it will be added into the build queue. This scenario can also handle package dependencies which are missing in repositories.
This logic can be overwritten by specifying the ``source`` parameter, which is partially useful if you would like to add package from AUR, but there is local directory cloned from AUR.
This logic can be overwritten by specifying the ``source`` parameter, which is partially useful if you would like to add package from AUR, but there is local directory cloned from AUR. Also the official repositories calls are hidden behind explicit source definition.
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
^^^^^^^^^^^^^^^
This flow removes package from filesystem, updates repository database and also runs synchronization and reporting methods.
Check outdated packages
^^^^^^^^^^^^^^^^^^^^^^^
There are few ways for packages to be marked as out-of-date and hence requiring rebuild. Those are following:
#. User requested update of the package. It can be caused by calling ``package-add`` subcommand (or ``package-update`` with arguments).
#. The most common way for packages to be marked as out-of-dated is that the version in AUR (or the official repositories) is newer than in the repository.
#. In addition to the above, if package is named as VCS (e.g. has suffix ``-git``) and the last update was more than specified threshold ago, the service will also try to fetch sources and check if the revision is newer than the built one.
#. In addition, there is ability to check if the dependencies of the package have been updated (e.g. if linked library has been renamed or the modules directory - e.g. in case of python and ruby packages - has been changed). And if so, the package will be marked as out-of-dated as well.
Update packages
^^^^^^^^^^^^^^^
This feature is divided into to stages: check AUR for updates and run rebuild for required packages. Whereas check does not do anything except for check itself, update flow is the following:
This feature is divided into the following stages: check AUR for updates and run rebuild for required packages. The package update flow is the following:
#. Process every built package first. Those packages are usually added manually.
#. Run sync and report methods.
@ -158,6 +231,7 @@ This feature is divided into to stages: check AUR for updates and run rebuild fo
#. For each level of tree it does:
#. Download package data from AUR.
#. Bump ``pkgrel`` if there is duplicate version in the local repository (see explanation below).
#. Build every package in clean chroot.
#. Sign packages if required.
#. Add packages to database and sign database if required.
@ -165,18 +239,71 @@ This feature is divided into to stages: check AUR for updates and run rebuild fo
After any step any package data is being removed.
In case if there are configured workers, the build process itself will be delegated to the remote instances. Packages will be partitioned to the chunks according to the amount of configured workers.
Distributed builds
^^^^^^^^^^^^^^^^^^
This feature consists of two parts:
* Upload built packages to the node.
* Delegate packages building to separated nodes.
The upload process is performed via special API endpoint, which is disabled by default, and is performed in several steps:
#. Upload package to temporary file.
#. Copy content from temporary file to the built package directory with dot (``.``) prefix.
#. Rename copied file, removing preceding dot.
After success upload, the update process must be called as usual in order to copy built packages to the main repository tree.
On the other side, the delegation uses upload feature, but in addition it also calls external services in order to trigger build process. The packages are separated into the chunks based on the amount of the configured workers and their dependencies.
pkgrel bump rules
^^^^^^^^^^^^^^^^^
The application is able to automatically bump package release (``pkgrel`` variable) during the build process if there is duplicated version in the repository. The version will be incremented as following:
#. Get version of the remote package.
#. Get version of the local package if available.
#. If the local version is not set, proceed with the remote one.
#. If the local version is set and the remote version is newer than local one, proceed with remote.
#. Extract ``pkgrel`` value.
#. If it has ``major.minor`` notation (e.g. ``1.1``), then increment last part by 1, e.g. ``1.1 -> 1.2``, ``1.0.1 -> 1.0.2``.
#. If ``pkgrel`` is a number (e.g. ``1``), then append 1 to the end of the string, e.g. ``1 -> 1.1``.
Implicit dependencies resolution
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In addition to the depends/optional/make/check depends lists the server also handles implicit dependencies. After success build, the application traverse through the build tree and finds:
* Libraries to which the binaries (ELF-files) are linked. To do so, the ``NEEDED`` section of the ELF-files is read.
* Directories which contains files of the package, but do not belong to this package. This case covers, for example, python and ruby submodules.
Having the initial dependencies tree, the application is looking for packages which contains those (both files and directories) paths and creates the initial packages list. After that, the packages list is reduced in the following way:
* From any leaf exclude the package itself and possible debug packages.
* If the entry (i.e. file or directory) belongs to the package which is in base group, it will be removed.
* If there is a package which depends on the another package which provide the same entry, the package will be removed.
* After that, if there is a package which *optionally* depends on the another package in the remaining list, the package will be removed.
* And finally, if there is any path, which is the child of the entry, and it contains the same package, the package from the smaller entry will be removed.
Those paths are also filtered by regular expressions set in the configuration.
All those implicit dependencies are stored in the database and extracted on each check. In case if any of the repository packages doesn't contain any entry anymore (e.g. so version has been changed or modules directory has been changed), the dependent package will be marked as out-of-dated.
Core functions reference
------------------------
Configuration
^^^^^^^^^^^^^
``ahriman.core.configuration.Configuration`` class provides some additional methods (e.g. ``getpath`` and ``getlist``) and also combines multiple files into single configuration dictionary using architecture overrides. It is the recommended way to deal with settings.
``ahriman.core.configuration.Configuration`` class provides some additional methods (e.g. ``getpath`` and ``getlist``) and also combines multiple files into single configuration dictionary using repository identifier overrides. It is the recommended way to deal with settings.
Enumerations
^^^^^^^^^^^^
All enumerations are derived from ``str`` and ``enum.Enum``. Integer enumerations are not allowed, because most of operations require conversions from string variable. Derivation from string class is required to make json conversions implicitly (e.g. during calling ``json.dumps`` methods).
All enumerations are derived from ``enum.StrEnum``. Integer enumerations in general are not allowed, because most of operations require conversions from string variable. Derivation from string based enumeration is required to make json conversions implicitly (e.g. during calling ``json.dumps`` methods).
In addition, some enumerations provide ``from_option`` class methods in order to allow some flexibility while reading configuration options.
@ -190,7 +317,7 @@ Context variables
Package provides implicit global variables which can be accessed from ``ahriman.core`` package as ``context`` variable, wrapped by ``contextvars.ContextVar`` class. The value of the variable is defaulting to private ``_Context`` class which is defined in the same module. The default values - such as ``database`` and ``sign`` - are being set on the service initialization.
The ``_Context`` class itself mimics default collection interface (as is Mapping) and can be modified by ``_Context.set`` method. The stored variables can be achieved by ``_Context.get`` method, which is unlike default ``Mapping`` interface also performs type and presence checks.
The ``_Context`` class itself mimics default collection interface (as is ``Mapping``) and can be modified by ``_Context.set`` method. The stored variables can be achieved by ``_Context.get`` method, which is unlike default ``Mapping`` interface also performs type and presence checks.
In order to provide statically typed interface, the ``ahriman.models.context_key.ContextKey`` class is used for both ``_Content.get`` and ``_Content.set`` methods; the context instance itself, however, does not store information about types.
@ -202,16 +329,16 @@ Some packages provide different behaviour depending on configuration settings. I
Authorization
^^^^^^^^^^^^^
The package provides several authorization methods: disabled, based on configuration and OAuth2.
The package provides several authorization methods: disabled, based on configuration, PAM and OAuth2.
Disabled (default) authorization provider just allows everything for everyone and does not have any specific configuration (it uses some default configuration parameters though). It also provides generic interface for derived classes.
Mapping (aka configuration) provider uses hashed passwords with salt from the database in order to authenticate users. This provider also enables user permission checking (read/write) (authorization). Thus, it defines the following methods:
Mapping (aka configuration) provider uses hashed passwords with optional salt from the database in order to authenticate users. This provider also enables user permission checking (read/write) (authorization). Thus, it defines the following methods:
* ``check_credentials`` - user password validation (authentication).
* ``verify_access`` - user permission validation (authorization).
Passwords must be stored in database as ``hash(password + salt)``, where ``password`` is user defined password (taken from user input), ``salt`` is random string (any length) defined globally in configuration and ``hash`` is secure hash function. Thus, the following configuration
Passwords must be stored in database as ``hash(password + salt)``, where ``password`` is user defined password (taken from user input), ``salt`` is random string (any length) defined globally in configuration and ``hash`` is a secure hash function. Thus, the following configuration
.. code-block::
@ -224,9 +351,9 @@ 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. Note, however, that this behaviour can be disabled by configuration.
In order to configure users there are special commands.
In order to configure users there are special subcommands.
Triggers
^^^^^^^^
@ -237,7 +364,7 @@ The main idea is to load classes by their full path (e.g. ``ahriman.core.upload.
The loaded triggers will be called with ``ahriman.models.result.Result`` and ``list[Packages]`` arguments, which describes the process result and current repository packages respectively. Any exception raised will be suppressed and will generate an exception message in logs.
In addition triggers can implement ``on_start`` and ``on_stop`` actions which will be called on the application start and right before the application exit. The ``on_start`` action is usually being called from handlers directly in order to make sure that no trigger will be run when it is not required (e.g. on user management). As soon as ``on_start`` action is called, the additional flag will be set; ``ahriman.core.triggers.TriggerLoader`` class implements ``__del__`` method in which, if the flag is set, the ``on_stop`` actions will be called.
In addition triggers can implement ``on_start`` and ``on_stop`` actions which will be called on the application start and right before the application exit respectively. The ``on_start`` action is usually being called from handlers directly in order to make sure that no trigger will be run when it is not required (e.g. on user management). As soon as ``on_start`` action is called, the additional flag will be set; ``ahriman.core.triggers.TriggerLoader`` class implements ``__del__`` method in which, if the flag is set, the ``on_stop`` actions will be called.
For more details how to deal with the triggers, refer to :doc:`documentation <triggers>` and modules descriptions.
@ -248,16 +375,33 @@ There are several supported synchronization providers, currently they are ``rsyn
``rsync`` provider does not have any specific logic except for running external rsync application with configured arguments. The service does not handle SSH configuration, thus it has to be configured before running application manually.
``s3`` provider uses ``boto3`` package and implements sync feature. The files are stored in architecture directory (e.g. if bucket is ``repository``, packages will be stored in ``repository/x86_64`` for the ``x86_64`` architecture), bucket must be created before any action and API key must have permissions to write to the bucket. No external configuration required. In order to upload only changed files the service compares calculated hashes with the Amazon ETags, used realization is described `here <https://teppen.io/2018/10/23/aws_s3_verify_etags/>`_.
``s3`` provider uses ``boto3`` package and implements sync feature. The files are stored in architecture specific directory (e.g. if bucket is ``repository``, packages will be stored in ``repository/aur/x86_64`` for the ``aur`` repository and ``x86_64`` architecture), bucket must be created before any action and API key must have permissions to write to the bucket. No external configuration required. In order to upload only changed files the service compares calculated hashes with the Amazon ETags, the implementation used is described `here <https://teppen.io/2018/10/23/aws_s3_verify_etags/>`__.
``github`` provider authenticates through basic auth, API key with repository write permissions is required. There will be created a release with the name of the architecture in case if it does not exist; files will be uploaded to the release assets. It also stores array of files and their MD5 checksums in release body in order to upload only changed ones. According to the Github API in case if there is already uploaded asset with the same name (e.g. database files), asset will be removed first.
``github`` provider authenticates through basic auth, API key with repository write permissions is required. There will be created a release with the name of the architecture in case if it does not exist; files will be uploaded to the release assets. It also stores array of files and their MD5 checksums in release body in order to upload only changed ones. According to the GitHub API in case if there is already uploaded asset with the same name (e.g. database files), asset will be removed first.
PKGBUILD parsing
^^^^^^^^^^^^^^^^
The application provides a house-made shell parser ``ahriman.core.alpm.pkgbuild_parser.PkgbuildParser`` to process PKGBUILDs and extract package data from them. It relies on the ``shlex.shlex`` parser with some configuration tweaks and adds some token post-processing.
#. During the parser process, firstly, it extract next token from the source file (basically, the word) and tries to match it to the variable assignment. If so, then just processes accordingly.
#. If it is not an assignment, the parser checks if the token was quoted.
#. If it wasn't quoted then the parser tries to match the array starts (two consecutive tokens like ``array=`` and ``(``) or it is function (``function``, ``()`` and ``{``).
#. The arrays are processed until the next closing bracket ``)``. After extraction, the parser tries to expand an array according to bash rules (``prefix{first,second}suffix`` constructions).
#. The functions are just read until the closing bracket ``}`` and then reread whole text from the input string without a tokenization.
All extracted fields are packed as ``ahriman.models.pkgbuild_patch.PkgbuildPatch`` and then can be used as ``ahriman.models.pkgbuild.Pkgbuild`` instance.
The PKGBUILD class also provides some additional functions on top of that:
* Ability to extract fields defined inside ``package*()`` functions, which are in particular used for the multi-packages.
* Shell substitution, which supports constructions ``$var`` (including ``${var}``), ``${var#(#)pattern}``, ``${var%(%)pattern}`` and ``${var/(/)pattern/replacement}`` (including ``#pattern`` and ``%pattern``).
Additional features
^^^^^^^^^^^^^^^^^^^
Some features require optional dependencies to be installed:
* Version control executables (e.g. ``git``, ``svn``) for VCS packages.
* ``gnupg`` application for package and repository sign feature.
* ``rsync`` application for rsync based repository sync.
* ``boto3`` python package for ``S3`` sync.
@ -269,11 +413,10 @@ Web application
Web application requires the following python packages to be installed:
* Core part requires ``aiohttp`` (application itself), ``aiohttp_jinja2`` and ``Jinja2`` (HTML generation from templates).
* Additional web features also require ``aiohttp-apispec`` (autogenerated documentation), ``aiohttp_cors`` (CORS support, required by documentation)
* In addition, ``aiohttp_debugtoolbar`` is required for debug panel. Please note that this option does not work together with authorization and basically must not be used in production.
* Additional web features also require ``aiohttp-apispec`` (autogenerated documentation), ``aiohttp_cors`` (CORS support, required by documentation).
* In addition, authorization feature requires ``aiohttp_security``, ``aiohttp_session`` and ``cryptography``.
* In addition to base authorization dependencies, OAuth2 also requires ``aioauth-client`` library.
* In addition if you would like to disable authorization for local access (recommended way in order to run the application itself with reporting support), the ``requests-unixsocket`` library is required.
* In addition if you would like to disable authorization for local access (recommended way in order to run the application itself with reporting support), the ``requests-unixsocket2`` library is required.
Middlewares
^^^^^^^^^^^
@ -292,30 +435,37 @@ Web views
All web views are defined in separated package and derived from ``ahriman.web.views.base.Base`` class which provides typed interfaces for web application.
REST API supports both form and JSON data, but the last one is recommended.
REST API supports only JSON data.
Different APIs are separated into different packages:
* ``ahriman.web.views.api`` not a real API, but some views which provide OpenAPI support.
* ``ahriman.web.views.service`` provides views for application controls.
* ``ahriman.web.views.status`` package provides REST API for application reporting.
* ``ahriman.web.views.user`` package provides login and logout methods which can be called without authorization.
* ``ahriman.web.views.*.auditlog`` provides event log API.
* ``ahriman.web.views.*.distributed`` is an API for builders interaction for multi-node setup.
* ``ahriman.web.views.*.packages`` contains views which provide information about existing packages.
* ``ahriman.web.views.*.service`` provides views for application controls.
* ``ahriman.web.views.*.status`` package provides REST API for application reporting.
* ``ahriman.web.views.*.user`` package provides login and logout methods which can be called without authorization.
The views are also divided by supporting API versions (e.g. ``v1``, ``v2``).
Templating
^^^^^^^^^^
Package provides base jinja templates which can be overridden by settings. Vanilla templates are actively using bootstrap library.
Package provides base jinja templates which can be overridden by settings. Vanilla templates actively use bootstrap library.
Requests and scopes
^^^^^^^^^^^^^^^^^^^
Service provides optional authorization which can be turned on in settings. In order to control user access there are two levels of authorization - read-only (only GET-like requests) and write (anything) which are provided by each web view directly.
Service provides optional authorization which can be turned on in settings. In order to control user access there are two levels of authorization - read-only (only GET-like requests) and write (anything), settings for which are provided by each web view directly.
If this feature is configured any request will be prohibited without authentication. In addition, configuration flag ``auth.allow_read_only`` can be used in order to allow read-only operations - reading index page and packages - without authorization.
For authenticated users it uses encrypted session cookies to store tokens; encryption key is generated each time at the start of the application. It also stores expiration time of the session inside.
For authenticated users it uses encrypted session cookies to store tokens; encryption key is read from configuration or generated at the start of the application if not set. It also stores expiration time of the session inside.
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 the underlying process.

View File

@ -1,638 +0,0 @@
#compdef ahriman
# AUTOMATICALLY GENERATED by `shtab`
_shtab_ahriman_commands() {
local _commands=(
"add:add existing or new package to the build queue"
"aur-search:search for package in AUR using API"
"check:check for packages updates. Same as repo-update --dry-run --no-manual"
"clean:remove local caches"
"config:dump configuration for the specified architecture"
"config-validate:validate configuration and print found errors"
"daemon:start process which periodically will run update process"
"help:show help message for application or command and exit"
"help-commands-unsafe:list unsafe commands as defined in default args"
"help-updates:request AUR for current version and compare with current service version"
"help-version:print application and its dependencies versions"
"init:create initial service configuration, requires root"
"key-import:import PGP key from public sources to the repository user"
"package-add:add existing or new package to the build queue"
"package-remove:remove package from the repository"
"package-status:request status of the package"
"package-status-remove:remove the package from the status page"
"package-status-update:update package status on the status page"
"package-update:add existing or new package to the build queue"
"patch-add:create or update patched PKGBUILD function or variable"
"patch-list:list available patches for the package"
"patch-remove:remove patches for the package"
"patch-set-add:create or update source patches"
"rebuild:force rebuild whole repository"
"remove:remove package from the repository"
"remove-unknown:remove packages which are missing in AUR and do not have local PKGBUILDs"
"repo-backup:backup repository settings and database"
"repo-check:check for packages updates. Same as repo-update --dry-run --no-manual"
"repo-clean:remove local caches"
"repo-config:dump configuration for the specified architecture"
"repo-config-validate:validate configuration and print found errors"
"repo-daemon:start process which periodically will run update process"
"repo-init:create initial service configuration, requires root"
"repo-rebuild:force rebuild whole repository"
"repo-remove-unknown:remove packages which are missing in AUR and do not have local PKGBUILDs"
"repo-report:generate repository report according to current settings"
"repo-restore:restore settings and database"
"repo-setup:create initial service configuration, requires root"
"repo-sign:(re-)sign packages and repository database according to current settings"
"repo-status-update:update repository status on the status page"
"repo-sync:sync repository files to remote server according to current settings"
"repo-tree:dump repository tree based on packages dependencies"
"repo-triggers:run triggers on empty build result as configured by settings"
"repo-update:check for packages updates and run build process if requested"
"report:generate repository report according to current settings"
"search:search for package in AUR using API"
"service-clean:remove local caches"
"service-config:dump configuration for the specified architecture"
"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"
"setup:create initial service configuration, requires root"
"shell:drop into python shell while having created application"
"sign:(re-)sign packages and repository database according to current settings"
"status:request status of the package"
"status-update:update package status on the status page"
"sync:sync repository files to remote server according to current settings"
"update:check for packages updates and run build process if requested"
"user-add:update user for web services with the given password and role. In case if password was not entered it will be asked interactively"
"user-list:list users from the user mapping and their roles"
"user-remove:remove user from the user mapping and update the configuration"
"version:print application and its dependencies versions"
"web:start web server"
)
_describe 'ahriman commands' _commands
}
_shtab_ahriman_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"*"{-a,--architecture}"[target architectures. For several subcommands it can be used multiple times]:architecture:"
{-c,--configuration}"[configuration path]:configuration:"
"--force[force run, remove file lock]"
{-l,--lock}"[lock file]:lock:"
{--report,--no-report}"[force enable or disable reporting to web service]:report:"
{-q,--quiet}"[force disable any logging]"
"--unsafe[allow to run ahriman as non-ahriman user. Some actions might be unavailable]"
"(- : *)"{-V,--version}"[show program\'s version number and exit]"
)
_shtab_ahriman_add_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{--dependencies,--no-dependencies}"[process missing package dependencies]: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)"
"(*):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]: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)"
"(*):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]:vcs:"
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
"(*)::filter check by package base:"
)
_shtab_ahriman_clean_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{--cache,--no-cache}"[clear directory with package caches]:cache:"
{--chroot,--no-chroot}"[clear build chroot]:chroot:"
{--manual,--no-manual}"[clear manually added packages queue]:manual:"
{--packages,--no-packages}"[clear directory with built packages]:packages:"
{--pacman,--no-pacman}"[clear directory with pacman local database cache]:pacman:"
)
_shtab_ahriman_config_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{--secure,--no-secure}"[hide passwords and secrets from output]: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]"
)
_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]:aur:"
{--dependencies,--no-dependencies}"[process missing package dependencies]:dependencies:"
{--local,--no-local}"[enable or disable checking of local packages for updates]:local:"
{--manual,--no-manual}"[include or exclude manual updates]:manual:"
{--vcs,--no-vcs}"[fetch actual version of VCS packages]:vcs:"
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
)
_shtab_ahriman_help_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
":show help message for specific command:"
)
_shtab_ahriman_help_commands_unsafe_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--command[instead of showing commands, just test command line for unsafe subcommand and return 0 in case if command is safe and 1 otherwise]:command:"
)
_shtab_ahriman_help_updates_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-e,--exit-code}"[return non-zero exit code if updates available]"
)
_shtab_ahriman_help_version_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_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]:makeflags_jobs:"
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
{--multilib,--no-multilib}"[add or do not multilib repository]:multilib:"
"--packager[packager name and email]:packager:"
"--repository[repository name]:repository:"
"--sign-key[sign key id]:sign_key:"
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
"--web-port[port of the web service]:web_port:"
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
)
_shtab_ahriman_key_import_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--key-server[key server for key import]:key_server:"
":PGP key to import from public server:"
)
_shtab_ahriman_package_add_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{--dependencies,--no-dependencies}"[process missing package dependencies]: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)"
"(*):package source (base name, path to local files, remote URL):"
)
_shtab_ahriman_package_remove_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"(*):package name or base:"
)
_shtab_ahriman_package_status_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--ahriman[get service status itself]"
{-e,--exit-code}"[return non-zero exit status if result is empty]"
{--info,--no-info}"[show additional package information]:info:"
{-s,--status}"[filter packages by status]:status:(unknown pending building failed success)"
"(*)::filter status by package base:"
)
_shtab_ahriman_package_status_remove_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"(*):remove specified packages from status page:"
)
_shtab_ahriman_package_status_update_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-s,--status}"[new package build status]:status:(unknown pending building failed success)"
"(*)::set status for specified packages. If no packages supplied, service status will be updated:"
)
_shtab_ahriman_package_update_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{--dependencies,--no-dependencies}"[process missing package dependencies]: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)"
"(*):package source (base name, path to local files, remote URL):"
)
_shtab_ahriman_patch_add_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
":package base:"
":PKGBUILD variable or function name. If variable is a function, it must end with ():"
":path to file which contains function or variable value. If not set, the value will be read from stdin:"
)
_shtab_ahriman_patch_list_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-e,--exit-code}"[return non-zero exit status if result is empty]"
"*"{-v,--variable}"[if set, show only patches for specified PKGBUILD variables]:variable:"
":package base:"
)
_shtab_ahriman_patch_remove_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"*"{-v,--variable}"[should be used for single-function patches in case if you wold like to remove only specified PKGBUILD variables. In case if not set, it will remove all patches related to the package]:variable:"
":package base:"
)
_shtab_ahriman_patch_set_add_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"*"{-t,--track}"[files which has to be tracked]:track:"
":path to directory with changed files for patch addition\/update:"
)
_shtab_ahriman_rebuild_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"*--depends-on[only rebuild packages that depend on specified packages]:depends_on:"
"--dry-run[just perform check for packages without rebuild process itself]"
"--from-database[read packages from database instead of filesystem. This feature in particular is required in case if you would like to restore repository from another repository instance. Note, however, that in order to restore packages you need to have original ahriman instance run with web service and have run repo-update at least once.]"
{-e,--exit-code}"[return non-zero exit status if result is empty]"
)
_shtab_ahriman_remove_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"(*):package name or base:"
)
_shtab_ahriman_remove_unknown_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--dry-run[just perform check for packages without removal]"
)
_shtab_ahriman_repo_backup_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
":path of the output archive:"
)
_shtab_ahriman_repo_check_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-e,--exit-code}"[return non-zero exit status if result is empty]"
{--vcs,--no-vcs}"[fetch actual version of VCS packages]:vcs:"
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
"(*)::filter check by package base:"
)
_shtab_ahriman_repo_clean_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{--cache,--no-cache}"[clear directory with package caches]:cache:"
{--chroot,--no-chroot}"[clear build chroot]:chroot:"
{--manual,--no-manual}"[clear manually added packages queue]:manual:"
{--packages,--no-packages}"[clear directory with built packages]:packages:"
{--pacman,--no-pacman}"[clear directory with pacman local database cache]:pacman:"
)
_shtab_ahriman_repo_config_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{--secure,--no-secure}"[hide passwords and secrets from output]: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]"
)
_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]:aur:"
{--dependencies,--no-dependencies}"[process missing package dependencies]:dependencies:"
{--local,--no-local}"[enable or disable checking of local packages for updates]:local:"
{--manual,--no-manual}"[include or exclude manual updates]:manual:"
{--vcs,--no-vcs}"[fetch actual version of VCS packages]:vcs:"
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
)
_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]:makeflags_jobs:"
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
{--multilib,--no-multilib}"[add or do not multilib repository]:multilib:"
"--packager[packager name and email]:packager:"
"--repository[repository name]:repository:"
"--sign-key[sign key id]:sign_key:"
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
"--web-port[port of the web service]:web_port:"
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
)
_shtab_ahriman_repo_rebuild_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"*--depends-on[only rebuild packages that depend on specified packages]:depends_on:"
"--dry-run[just perform check for packages without rebuild process itself]"
"--from-database[read packages from database instead of filesystem. This feature in particular is required in case if you would like to restore repository from another repository instance. Note, however, that in order to restore packages you need to have original ahriman instance run with web service and have run repo-update at least once.]"
{-e,--exit-code}"[return non-zero exit status if result is empty]"
)
_shtab_ahriman_repo_remove_unknown_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--dry-run[just perform check for packages without removal]"
)
_shtab_ahriman_repo_report_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_shtab_ahriman_repo_restore_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-o,--output}"[root path of the extracted files]:output:"
":path of the input archive:"
)
_shtab_ahriman_repo_setup_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--build-as-user[force makepkg user to the specific one]:build_as_user:"
"--build-command[build command prefix]:build_command:"
"--from-configuration[path to default devtools pacman configuration]:from_configuration:"
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores]:makeflags_jobs:"
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
{--multilib,--no-multilib}"[add or do not multilib repository]:multilib:"
"--packager[packager name and email]:packager:"
"--repository[repository name]:repository:"
"--sign-key[sign key id]:sign_key:"
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
"--web-port[port of the web service]:web_port:"
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
)
_shtab_ahriman_repo_sign_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"(*)::sign only specified packages:"
)
_shtab_ahriman_repo_status_update_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-s,--status}"[new status]:status:(unknown pending building failed success)"
)
_shtab_ahriman_repo_sync_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_shtab_ahriman_repo_tree_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_shtab_ahriman_repo_triggers_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"(*)::instead of running all triggers as set by configuration, just process specified ones in order of mention:"
)
_shtab_ahriman_repo_update_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{--aur,--no-aur}"[enable or disable checking for AUR updates]:aur:"
{--dependencies,--no-dependencies}"[process missing package dependencies]: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]:local:"
{--manual,--no-manual}"[include or exclude manual updates]:manual:"
{--vcs,--no-vcs}"[fetch actual version of VCS packages]:vcs:"
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
"(*)::filter check by package base:"
)
_shtab_ahriman_report_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_shtab_ahriman_search_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-e,--exit-code}"[return non-zero exit status if result is empty]"
{--info,--no-info}"[show additional package information]: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)"
"(*):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]:cache:"
{--chroot,--no-chroot}"[clear build chroot]:chroot:"
{--manual,--no-manual}"[clear manually added packages queue]:manual:"
{--packages,--no-packages}"[clear directory with built packages]:packages:"
{--pacman,--no-pacman}"[clear directory with pacman local database cache]:pacman:"
)
_shtab_ahriman_service_config_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{--secure,--no-secure}"[hide passwords and secrets from output]: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]"
)
_shtab_ahriman_service_key_import_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--key-server[key server for key import]:key_server:"
":PGP key to import from public server:"
)
_shtab_ahriman_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]:makeflags_jobs:"
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
{--multilib,--no-multilib}"[add or do not multilib repository]:multilib:"
"--packager[packager name and email]:packager:"
"--repository[repository name]:repository:"
"--sign-key[sign key id]:sign_key:"
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
"--web-port[port of the web service]:web_port:"
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
)
_shtab_ahriman_service_shell_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
":instead of dropping into shell, just execute the specified code:"
)
_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]:makeflags_jobs:"
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
{--multilib,--no-multilib}"[add or do not multilib repository]:multilib:"
"--packager[packager name and email]:packager:"
"--repository[repository name]:repository:"
"--sign-key[sign key id]:sign_key:"
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
"--web-port[port of the web service]:web_port:"
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
)
_shtab_ahriman_shell_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
":instead of dropping into shell, just execute the specified code:"
)
_shtab_ahriman_sign_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"(*)::sign only specified packages:"
)
_shtab_ahriman_status_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--ahriman[get service status itself]"
{-e,--exit-code}"[return non-zero exit status if result is empty]"
{--info,--no-info}"[show additional package information]:info:"
{-s,--status}"[filter packages by status]:status:(unknown pending building failed success)"
"(*)::filter status by package base:"
)
_shtab_ahriman_status_update_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-s,--status}"[new package build status]:status:(unknown pending building failed success)"
"(*)::set status for specified packages. If no packages supplied, service status will be updated:"
)
_shtab_ahriman_sync_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_shtab_ahriman_update_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{--aur,--no-aur}"[enable or disable checking for AUR updates]:aur:"
{--dependencies,--no-dependencies}"[process missing package dependencies]: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]:local:"
{--manual,--no-manual}"[include or exclude manual updates]:manual:"
{--vcs,--no-vcs}"[fetch actual version of VCS packages]:vcs:"
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
"(*)::filter check by package base:"
)
_shtab_ahriman_user_add_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-p,--password}"[user password. Blank password will be treated as empty password, which is in particular must be used for OAuth2 authorization type.]:password:"
{-r,--role}"[user access level]:role:(unauthorized read reporter full)"
{-s,--secure}"[set file permissions to user-only]"
":username for web service:"
)
_shtab_ahriman_user_list_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-e,--exit-code}"[return non-zero exit status if result is empty]"
{-r,--role}"[filter users by role]:role:(unauthorized read reporter full)"
":filter users by username:"
)
_shtab_ahriman_user_remove_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
":username for web service:"
)
_shtab_ahriman_version_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_shtab_ahriman_web_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_shtab_ahriman() {
local context state line curcontext="$curcontext" one_or_more='(-)*' remainder='(*)'
if ((${_shtab_ahriman_options[(I)${(q)one_or_more}*]} + ${_shtab_ahriman_options[(I)${(q)remainder}*]} == 0)); then # noqa: E501
_shtab_ahriman_options+=(': :_shtab_ahriman_commands' '*::: :->ahriman')
fi
_arguments -C $_shtab_ahriman_options
case $state in
ahriman)
words=($line[1] "${words[@]}")
(( CURRENT += 1 ))
curcontext="${curcontext%:*:*}:_shtab_ahriman-$line[1]:"
case $line[1] in
add) _arguments -C $_shtab_ahriman_add_options ;;
aur-search) _arguments -C $_shtab_ahriman_aur_search_options ;;
check) _arguments -C $_shtab_ahriman_check_options ;;
clean) _arguments -C $_shtab_ahriman_clean_options ;;
config) _arguments -C $_shtab_ahriman_config_options ;;
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 ;;
esac
esac
}
typeset -A opt_args
_shtab_ahriman "$@"

View File

@ -10,32 +10,22 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import datetime
import sys
from pathlib import Path
from unittest import mock
from ahriman.version import __version__
from ahriman import __version__
basedir = Path(__file__).resolve().parent.parent / "src"
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 -----------------------------------------------------
project = "ahriman"
copyright = "2021-2023, ahriman team"
copyright = f"2021-{datetime.date.today().year}, ahriman team"
author = "ahriman team"
# The full version, including alpha/beta/rc tags
@ -49,7 +39,9 @@ release = __version__
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.graphviz",
"sphinx.ext.napoleon",
"sphinx_rtd_theme",
"sphinxarg.ext",
]
@ -74,16 +66,23 @@ exclude_patterns = []
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "default" if on_rtd else "alabaster"
html_theme = "sphinx_rtd_theme"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = []
html_static_path = ["_static"]
html_logo = "_static/logo.svg"
add_module_names = False
modindex_common_prefix = ["ahriman.application.", "ahriman.core.", "ahriman.models.", "ahriman.web."]
modindex_common_prefix = [
"ahriman.application.",
"ahriman.core.",
"ahriman.models.",
"ahriman.web.",
]
# -- Extension configuration -------------------------------------------------
@ -92,6 +91,10 @@ autoclass_content = "both"
autodoc_member_order = "groupwise"
autodoc_mock_imports = ["cryptography", "pyalpm"]
autodoc_default_options = {
"no-undoc-members": True,
}
graphviz_output_format = "svg"

View File

@ -1,22 +1,75 @@
Configuration
=============
Some groups can be specified for each architecture separately. E.g. if there are ``build`` and ``build:x86_64`` groups it will use an option from ``build:x86_64`` for the ``x86_64`` architecture and ``build`` for any other (architecture specific group has higher priority). In case if both groups are presented, architecture specific options will be merged into global ones overriding them.
Some groups can be specified for each architecture and/or repository separately. E.g. if there are ``build`` and ``build:x86_64`` groups it will use an option from ``build:x86_64`` for the ``x86_64`` architecture and ``build`` for any other (architecture specific group has higher priority). In case if both groups are presented, architecture specific options will be merged into global ones overriding them. The order which will be used for option resolution is the following:
#. Repository and architecture specific, e.g. ``build:aur:x86_64``.
#. Repository specific, e.g. ``build:aur``.
#. Architecture specific, e.g. ``build:x86_64``.
#. Default section, e.g. ``build``.
There are two variable types which have been added to default ones, they are paths and lists. List values will be read in the same way as shell does:
* By default, it splits value by spaces excluding empty elements.
* In case if quotation mark (``"`` or ``'``) will be found, any spaces inside will be ignored.
* In order to use quotation mark inside value it is required to put it to another quotation mark, e.g. ``wor"'"d "with quote"`` will be parsed as ``["wor'd", "with quote"]`` and vice versa.
* Unclosed quotation mark is not allowed and will rise an exception.
* Unclosed quotation mark is not allowed and will raise an exception.
It is also possible to split list option between multiple declarations. To do so, append key name with ``[]`` (like PHP, sorry!), e.g.:
.. code-block:: ini
[section]
list[] = value1
list[] = value2
will lead to ``${section:list}`` value to be set to ``value1 value2``. The values will be set in order of appearance, meaning that values which appear in different include files will be set in alphabetical order of file names. In order to reset list values, set option to empty string, e.g.:
.. code-block:: ini
[section]
list[] = value1
list[] =
list[] = value2
list[] = value3
will set option ``${section:list}`` to ``value2 value3``. Alternatively, setting the original option (e.g. ``list`` in the example above) will also reset value, though the subsequent options with leading ``[]`` will append the previous value.
Path values, except for casting to ``pathlib.Path`` type, will be also expanded to absolute paths relative to the configuration path. E.g. if path is set to ``ahriman.ini.d/logging.ini`` and root configuration path is ``/etc/ahriman.ini``, the value will be expanded to ``/etc/ahriman.ini.d/logging.ini``. In order to disable path expand, use the full path, e.g. ``/etc/ahriman.ini.d/logging.ini``.
Configuration allows string interpolation from the same configuration file, e.g.:
.. code-block:: ini
[section]
key = ${another_key}
another_key = value
will read value for the ``key`` option from ``another_key`` in the same section. In case if the cross-section reference is required, the ``${section:another_key}`` notation must be used. It also allows string interpolation from environment variables, e.g.:
.. code-block:: ini
[section]
key = $SECRET
will try to read value from ``SECRET`` environment variable. In case if the required environment variable wasn't found, it will keep original value (i.e. ``$SECRET`` in the example). Dollar sign can be set as ``$$``. All those interpolations will be applied in succession and - expected to be - recursively, e.g. the following configuration:
.. code-block:: ini
[section1]
key = ${section2:key}
[section2]
key = ${home}
home = $HOME
will eventually lead ``key`` option in section ``section1`` to be set to the value of ``HOME`` environment variable (if available).
There is also additional subcommand which will allow to validate configuration and print found errors. In order to do so, run ``service-config-validate`` subcommand, e.g.:
.. code-block:: shell
ahriman -a x86_64 service-config-validate
ahriman service-config-validate
It will check current settings on common errors and compare configuration with known schema.
@ -25,38 +78,43 @@ It will check current settings on common errors and compare configuration with k
Base configuration settings.
* ``include`` - path to directory with configuration files overrides, string, required.
* ``database`` - path to SQLite database, string, required.
* ``apply_migrations`` - perform database migrations on the application start, boolean, optional, default ``yes``. Useful if you are using git version. Note, however, that this option must be changed only if you know what to do and going to handle migrations manually.
* ``database`` - path to the application SQLite database, string, required.
* ``include`` - path to directory with configuration files overrides, string, optional. Files will be read in alphabetical order.
* ``keep_last_logs`` - amount of build logs to be kept for each package, integer, optional ,default ``0``. Logs will be cleared at the end of each process.
* ``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.
* ``database`` - path to pacman system database cache, string, required.
* ``mirror`` - package database mirror used by pacman for syncronization, string, required. This option supports standard pacman substitutions with ``$arch`` and ``$repo``. Note that the mentioned mirror should contain all repositories which are set by ``alpm.repositories`` option.
* ``repositories`` - list of pacman repositories, space separated list of strings, required.
* ``root`` - root for alpm library, string, required.
* ``use_ahriman_cache`` - use local pacman package cache instead of system one, boolean, required. With this option enabled you might want to refresh database periodically (available as additional flag for some subcommands).
* ``mirror`` - package database mirror used by pacman for synchronization, string, required. This option supports standard pacman substitutions with ``$arch`` and ``$repo``. Note that the mentioned mirror should contain all repositories which are set by ``alpm.repositories`` option.
* ``repositories`` - list of pacman repositories, used for package search, space separated list of strings, required.
* ``root`` - root for alpm library, string, required. In the most cases it must point to the system root.
* ``sync_files_database`` - download files database from mirror, boolean, required.
* ``use_ahriman_cache`` - use local pacman package cache instead of system one, boolean, required. With this option enabled you might want to refresh database periodically (available as additional flag for some subcommands). If set to ``no``, databases must be synchronized manually.
``auth`` group
--------------
Base authorization settings. ``OAuth`` provider requires ``aioauth-client`` library to be installed.
* ``target`` - specifies authorization provider, string, optional, default ``disabled``. Allowed values are ``disabled``, ``configuration``, ``oauth``.
* ``target`` - specifies authorization provider, string, optional, default ``disabled``. Allowed values are ``disabled``, ``configuration``, ``oauth``, ``pam``.
* ``allow_read_only`` - allow requesting status APIs without authorization, boolean, required.
* ``client_id`` - OAuth2 application client ID, string, required in case if ``oauth`` is used.
* ``client_secret`` - OAuth2 application client secret key, string, required in case if ``oauth`` is used.
* ``cookie_secret_key`` - secret key which will be used for cookies encryption, string, optional. It must be 32 url-safe base64-encoded bytes and can be generated as following ``base64.urlsafe_b64encode(os.urandom(32)).decode("utf8")``. If not set, it will be generated automatically; note, however, that in this case, all sessions will be automatically expired during restart.
* ``max_age`` - parameter which controls both cookie expiration and token expiration inside the service, integer, optional, default is 7 days.
* ``cookie_secret_key`` - secret key which will be used for cookies encryption, string, optional. It must be 32 bytes URL-safe base64-encoded and can be generated as following ``base64.urlsafe_b64encode(os.urandom(32)).decode("utf8")``. If not set, it will be generated automatically; note, however, that in this case, all sessions will be automatically invalidated during the service restart.
* ``full_access_group`` - name of the secondary group (e.g. ``wheel``) to be used as admin group in the service, string, required in case if ``pam`` is used.
* ``max_age`` - parameter which controls both cookie expiration and token expiration inside the service in seconds, integer, optional, default is 7 days.
* ``oauth_icon`` - OAuth2 login button icon, string, optional, default is ``google``. Must be valid `Bootstrap icon <https://icons.getbootstrap.com/>`__ name.
* ``oauth_provider`` - OAuth2 provider class name as is in ``aioauth-client`` (e.g. ``GoogleClient``, ``GithubClient`` etc), string, required in case if ``oauth`` is used.
* ``oauth_scopes`` - scopes list for OAuth2 provider, which will allow retrieving user email (which is used for checking user permissions), e.g. ``https://www.googleapis.com/auth/userinfo.email`` for ``GoogleClient`` or ``user:email`` for ``GithubClient``, space separated list of strings, required in case if ``oauth`` is used.
* ``salt`` - password hash salt, string, required in case if authorization enabled (automatically generated by ``user-add`` subcommand).
* ``permit_root_login`` - allow login as root user, boolean, optional, default ``no``.
* ``salt`` - additional password hash salt, string, optional.
Authorized users are stored inside internal database, if any of external provides are used the password field for non-service users must be empty.
Authorized users are stored inside internal database, if any of external providers (e.g. ``oauth``) are used, the password field for non-service users must be empty.
``build:*`` groups
------------------
@ -66,17 +124,20 @@ Build related configuration. Group name can refer to architecture, e.g. ``build:
* ``archbuild_flags`` - additional flags passed to ``archbuild`` command, space separated list of strings, optional.
* ``build_command`` - default build command, string, required.
* ``ignore_packages`` - list packages to ignore during a regular update (manual update will still work), space separated list of strings, optional.
* ``include_debug_packages`` - distribute debug packages, boolean, optional, default ``yes``.
* ``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.
* ``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``.
* ``scan_paths`` - paths to be used for implicit dependencies scan, space separated list of strings, optional. If any of those paths is matched against the path, it will be added to the allowed list.
* ``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 definition.
* ``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, integer, optional, default is 7 days.
* ``workers`` - list of worker nodes addresses used for build process, space separated list of strings, optional. Each worker address must be valid and reachable URL, e.g. ``https://10.0.0.1:8080``. If none set, the build process will be run on the current node. There is also special trigger which loads this value based on the list of the discovered nodes.
``repository`` group
--------------------
Base repository settings.
* ``name`` - repository name, string, required.
* ``root`` - root path for application, string, required.
``sign:*`` groups
@ -86,36 +147,83 @@ 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
``status`` group
----------------
Web server settings. If any of ``host``/``port`` is not set, web integration will be disabled. Group name can refer to architecture, e.g. ``web:x86_64`` can be used for x86_64 architecture specific settings. This feature requires ``aiohttp`` libraries to be installed.
Reporting to web service related settings. In most cases there is fallback to web section settings.
* ``enabled`` - enable reporting to web service, boolean, optional, default ``yes`` for backward compatibility.
* ``address`` - remote web service address with protocol, string, optional. In case of websocket, the ``http+unix`` scheme and URL encoded address (e.g. ``%2Fvar%2Flib%2Fahriman`` for ``/var/lib/ahriman``) must be used, e.g. ``http+unix://%2Fvar%2Flib%2Fahriman%2Fsocket``. In case if none set, it will be guessed from ``web`` section.
* ``password`` - password to authorize in web service in order to update service status, string, required in case if authorization enabled.
* ``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.
* ``timeout`` - HTTP request timeout in seconds, integer, optional, default is ``30``.
* ``username`` - username to authorize in web service in order to update service status, string, required in case if authorization enabled.
``web`` group
-------------
Web server settings. This feature requires ``aiohttp`` libraries to be installed.
* ``address`` - optional address in form ``proto://host:port`` (``port`` can be omitted in case of default ``proto`` ports), will be used instead of ``http://{host}:{port}`` in case if set, string, optional. This option is required in case if ``OAuth`` provider is used.
* ``debug`` - enable debug toolbar, boolean, optional, default ``no``.
* ``debug_check_host`` - check hosts to access debug toolbar, boolean, optional, default ``no``.
* ``debug_allowed_hosts`` - allowed hosts to get access to debug toolbar, space separated list of string, optional.
* ``enable_archive_upload`` - allow to upload packages via HTTP (i.e. call of ``/api/v1/service/upload`` uri), boolean, optional, default ``no``.
* ``host`` - host to bind, string, optional.
* ``index_url`` - full url of the repository index page, string, optional.
* ``password`` - password to authorize in web service in order to update service status, string, required in case if authorization enabled.
* ``port`` - port to bind, int, optional.
* ``index_url`` - full URL of the repository index page, string, optional.
* ``max_body_size`` - max body size in bytes to be validated for archive upload, integer, optional. If not set, validation will be disabled.
* ``port`` - port to bind, integer, optional.
* ``service_only`` - disable status routes (including logs), boolean, optional, default ``no``.
* ``static_path`` - path to directory with static files, string, required.
* ``templates`` - path to templates directory, string, required.
* ``templates`` - path to templates directories, space separated list of paths, required.
* ``unix_socket`` - path to the listening unix socket, string, optional. If set, server will create the socket on the specified address which can (and will) be used by application. Note, that unlike usual host/port configuration, unix socket allows to perform requests without authorization.
* ``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.
* ``wait_timeout`` - wait timeout in seconds, maximum amount of time to be waited before lock will be free, integer, optional.
``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
^^^^^^^^^^^^^^^^^^^^^^^^
* ``type`` - type of the generator, string, optional, must be set to ``keyring-generator`` if exists.
* ``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 user keys from database 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
^^^^^^^^^^^^^^^^^^^^^^^^^^^
* ``type`` - type of the generator, string, optional, must be set to ``mirrorlist-generator`` if exists.
* ``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
---------------------
Remote git source synchronization settings. Unlike ``Upload`` triggers those triggers are used for PKGBUILD synchronization - fetch from remote repository PKGBUILDs before updating process.
Remote git source synchronization settings. Unlike ``upload`` triggers those triggers are used for PKGBUILD synchronization - fetch from remote repository PKGBUILDs before updating process.
It supports authorization; to do so you'd need to prefix the url with authorization part, e.g. ``https://key:token@github.com/arcan1s/ahriman.git``. It is highly recommended to use application tokens instead of your user authorization details. Alternatively, you can use any other option supported by git, e.g.:
It supports authorization; to do so you'd need to prefix the URL with authorization part, e.g. ``https://key:token@github.com/arcan1s/ahriman.git``. It is highly recommended to use application tokens instead of your user authorization details. Alternatively, you can use any other option supported by git, e.g.:
* by SSH key: generate SSH key as ``ahriman`` user and put public part of it to the repository keys.
* by git credentials helper: consult with the `related man page <https://git-scm.com/docs/gitcredentials>`_.
* by git credentials helper: consult with the `related man page <https://git-scm.com/docs/gitcredentials>`__.
Available options are:
@ -124,7 +232,7 @@ Available options are:
Remote pull trigger
^^^^^^^^^^^^^^^^^^^
* ``pull_url`` - url of the remote repository from which PKGBUILDs can be pulled before build process, string, required.
* ``pull_url`` - URL of the remote repository from which PKGBUILDs can be pulled before build process, string, required.
* ``pull_branch`` - branch of the remote repository from which PKGBUILDs can be pulled before build process, string, optional, default is ``master``.
``remote-push`` group
@ -132,10 +240,10 @@ Remote pull trigger
Remote git source synchronization settings. Same as remote pull triggers those triggers are used for PKGBUILD synchronization - push updated PKGBUILDs to the remote repository after build process.
It supports authorization; to do so you'd need to prefix the url with authorization part, e.g. ``https://key:token@github.com/arcan1s/ahriman.git``. It is highly recommended to use application tokens instead of your user authorization details. Alternatively, you can use any other option supported by git, e.g.:
It supports authorization; to do so you'd need to prefix the URL with authorization part, e.g. ``https://key:token@github.com/arcan1s/ahriman.git``. It is highly recommended to use application tokens instead of your user authorization details. Alternatively, you can use any other option supported by git, e.g.:
* by SSH key: generate SSH key as ``ahriman`` user and put public part of it to the repository keys.
* by git credentials helper: consult with the `related man page <https://git-scm.com/docs/gitcredentials>`_.
* by git credentials helper: consult with the `related man page <https://git-scm.com/docs/gitcredentials>`__.
Available options are:
@ -144,8 +252,9 @@ Available options are:
Remote push trigger
^^^^^^^^^^^^^^^^^^^
* ``commit_author`` - git commit author, string, optional. In case if not set, the git will generate author for you. Note, however, that in this case it will disclosure your hostname.
* ``push_url`` - url of the remote repository to which PKGBUILDs should be pushed after build process, string, required.
* ``commit_email`` - git commit email, string, optional, default is ``ahriman@localhost``.
* ``commit_user`` - git commit user, string, optional, default is ``ahriman``.
* ``push_url`` - URL of the remote repository to which PKGBUILDs should be pushed after build process, string, required.
* ``push_branch`` - branch of the remote repository to which PKGBUILDs should be pushed after build process, string, optional, default is ``master``.
``report`` group
@ -175,17 +284,19 @@ Section name must be either ``console`` (plus optional architecture name, e.g. `
Section name must be either ``email`` (plus optional architecture name, e.g. ``email:x86_64``) or random name with ``type`` set.
* ``type`` - type of the report, string, optional, must be set to ``email`` if exists.
* ``full_template_path`` - path to Jinja2 template for full package description index, string, optional.
* ``homepage`` - link to homepage, string, optional.
* ``host`` - SMTP host for sending emails, string, required.
* ``link_path`` - prefix for HTML links, string, required.
* ``no_empty_report`` - skip report generation for empty packages list, boolean, optional, default ``yes``.
* ``password`` - SMTP password to authenticate, string, optional.
* ``port`` - SMTP port for sending emails, int, required.
* ``port`` - SMTP port for sending emails, integer, required.
* ``receivers`` - SMTP receiver addresses, space separated list of strings, required.
* ``rss_url`` - link to RSS feed, string, optional.
* ``sender`` - SMTP sender address, string, required.
* ``ssl`` - SSL mode for SMTP connection, one of ``ssl``, ``starttls``, ``disabled``, optional, default ``disabled``.
* ``template_path`` - path to Jinja2 template, string, required.
* ``template`` - Jinja2 template name, string, required.
* ``template_full`` - Jinja2 template name for full package description index, string, optional.
* ``templates`` - path to templates directories, space separated list of paths, required.
* ``user`` - SMTP user to authenticate, string, optional.
``html`` type
@ -196,8 +307,35 @@ Section name must be either ``html`` (plus optional architecture name, e.g. ``ht
* ``type`` - type of the report, string, optional, must be set to ``html`` if exists.
* ``homepage`` - link to homepage, string, optional.
* ``link_path`` - prefix for HTML links, string, required.
* ``path`` - path to html report file, string, required.
* ``template_path`` - path to Jinja2 template, string, required.
* ``path`` - path to HTML report file, string, required.
* ``rss_url`` - link to RSS feed, string, optional.
* ``template`` - Jinja2 template name, string, required.
* ``templates`` - path to templates directories, space separated list of paths, required.
``remote-call`` type
^^^^^^^^^^^^^^^^^^^^
Section name must be either ``remote-call`` (plus optional architecture name, e.g. ``remote-call:x86_64``) or random name with ``type`` set.
* ``type`` - type of the report, string, optional, must be set to ``remote-call`` if exists.
* ``aur`` - check for AUR packages updates, boolean, optional, default ``no``.
* ``local`` - check for local packages updates, boolean, optional, default ``no``.
* ``manual`` - update manually built packages, boolean, optional, default ``no``.
* ``wait_timeout`` - maximum amount of time in seconds to be waited before remote process will be terminated, integer, optional, default ``-1``.
``rss`` type
^^^^^^^^^^^^
Section name must be either ``rss`` (plus optional architecture name, e.g. ``rss:x86_64``) or random name with ``type`` set.
* ``type`` - type of the report, string, optional, must be set to ``rss`` if exists.
* ``homepage`` - link to homepage, string, optional.
* ``link_path`` - prefix for HTML links, string, required.
* ``max_entries`` - maximal amount of entries to be included to the report, negative means no limit, integer, optional, default ``-1``.
* ``path`` - path to generated RSS file, string, required.
* ``rss_url`` - link to RSS feed, string, optional.
* ``template`` - Jinja2 template name, string, required.
* ``templates`` - path to templates directories, space separated list of paths, required.
``telegram`` type
^^^^^^^^^^^^^^^^^
@ -209,9 +347,11 @@ Section name must be either ``telegram`` (plus optional architecture name, e.g.
* ``chat_id`` - telegram chat id, either string with ``@`` or integer value, required.
* ``homepage`` - link to homepage, string, optional.
* ``link_path`` - prefix for HTML links, string, required.
* ``template_path`` - path to Jinja2 template, string, required.
* ``rss_url`` - link to RSS feed, string, optional.
* ``template`` - Jinja2 template name, string, required.
* ``template_type`` - ``parse_mode`` to be passed to telegram API, one of ``MarkdownV2``, ``HTML``, ``Markdown``, string, optional, default ``HTML``.
* ``timeout`` - HTTP request timeout in seconds, int, optional, default is ``30``.
* ``templates`` - path to templates directories, space separated list of paths, required.
* ``timeout`` - HTTP request timeout in seconds, integer, optional, default is ``30``.
``upload`` group
----------------
@ -229,20 +369,29 @@ Type will be read from several sources:
``github`` type
^^^^^^^^^^^^^^^
This feature requires Github key creation (see below). Section name must be either ``github`` (plus optional architecture name, e.g. ``github:x86_64``) or random name with ``type`` set.
This feature requires GitHub key creation (see below). Section name must be either ``github`` (plus optional architecture name, e.g. ``github:x86_64``) or random name with ``type`` set.
* ``type`` - type of the upload, string, optional, must be set to ``github`` if exists.
* ``owner`` - Github repository owner, string, required.
* ``password`` - created Github API key. In order to create it do the following:
* ``owner`` - GitHub repository owner, string, required.
* ``password`` - created GitHub API key. In order to create it do the following:
#. Go to `settings page <https://github.com/settings/profile>`_.
#. Switch to `developers settings <https://github.com/settings/apps>`_.
#. Switch to `personal access tokens <https://github.com/settings/tokens>`_.
#. Go to `settings page <https://github.com/settings/profile>`__.
#. Switch to `developers settings <https://github.com/settings/apps>`__.
#. Switch to `personal access tokens <https://github.com/settings/tokens>`__.
#. Generate new token. Required scope is ``public_repo`` (or ``repo`` for private repository support).
* ``repository`` - Github repository name, string, required. Repository must be created before any action and must have active branch (e.g. with readme).
* ``timeout`` - HTTP request timeout in seconds, int, optional, default is ``30``.
* ``username`` - Github authorization user, string, required. Basically the same as ``owner``.
* ``repository`` - GitHub repository name, string, required. Repository must be created before any action and must have active branch (e.g. with readme).
* ``timeout`` - HTTP request timeout in seconds, integer, optional, default is ``30``.
* ``use_full_release_name`` - if set to ``yes``, the release will contain both repository name and architecture, and only architecture otherwise, boolean, optional, default ``no`` (legacy behavior).
* ``username`` - GitHub authorization user, string, required. Basically the same as ``owner``.
``remote-service`` type
^^^^^^^^^^^^^^^^^^^^^^^
Section name must be either ``remote-service`` (plus optional architecture name, e.g. ``remote-service:x86_64``) or random name with ``type`` set.
* ``type`` - type of the report, string, optional, must be set to ``remote-service`` if exists.
* ``timeout`` - HTTP request timeout in seconds, integer, optional, default is ``30``.
``rsync`` type
^^^^^^^^^^^^^^
@ -251,16 +400,26 @@ Requires ``rsync`` package to be installed. Do not forget to configure ssh for u
* ``type`` - type of the upload, string, optional, must be set to ``rsync`` if exists.
* ``command`` - rsync command to run, space separated list of string, required.
* ``remote`` - remote server to rsync (e.g. ``1.2.3.4:path/to/sync``), string, required.
* ``remote`` - remote server to rsync (e.g. ``ahriman@10.0.0.1:/srv/repo``), string, required.
``s3`` type
^^^^^^^^^^^
Requires ``boto3`` library to be installed. Section name must be either ``s3`` (plus optional architecture name, e.g. ``s3:x86_64``) or random name with ``type`` set.
* ``type`` - type of the upload, string, optional, must be set to ``github`` if exists.
* ``type`` - type of the upload, string, optional, must be set to ``s3`` if exists.
* ``access_key`` - AWS access key ID, string, required.
* ``bucket`` - bucket name (e.g. ``bucket``), string, required.
* ``chunk_size`` - chunk size for calculating entity tags, int, optional, default 8 * 1024 * 1024.
* ``chunk_size`` - chunk size for calculating entity tags, integer, optional, default 8 * 1024 * 1024.
* ``object_path`` - path prefix for stored objects, string, optional. If none set, the prefix as in repository tree will be used.
* ``region`` - bucket region (e.g. ``eu-central-1``), string, required.
* ``secret_key`` - AWS secret access key, string, required.
* ``secret_key`` - AWS secret access key, string, required.
``worker`` group
----------------
This section controls settings for ``ahriman.core.distributed.WorkerTrigger`` plugin.
* ``address`` - address of the instance, string, required. Must be reachable for the master instance.
* ``identifier`` - unique identifier of the instance, string, optional.
* ``time_to_live`` - amount of time which remote worker will be considered alive in seconds, integer, optional, default is ``60``. The ping interval will be set automatically equal this value divided by 4.

View File

@ -1,996 +0,0 @@
FAQ
===
General topics
--------------
What is the purpose of the project
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This project has been created in order to maintain self-hosted Arch Linux user repository without manual intervention - checking for updates and building packages.
How to install ahriman
^^^^^^^^^^^^^^^^^^^^^^
TL;DR
.. code-block:: shell
yay -S ahriman
ahriman -a x86_64 service-setup --packager "ahriman bot <ahriman@example.com>" --repository "repository"
systemctl enable --now ahriman@x86_64.timer
Long answer
"""""""""""
The idea is to install the package as usual, create working directory tree, create configuration for ``sudo`` and ``devtools``. Detailed description of the setup instruction can be found :doc:`here <setup>`.
How to validate settings
^^^^^^^^^^^^^^^^^^^^^^^^
There is special command which can be used in order to validate current configuration:
.. code-block:: shell
ahriman -a x86_64 service-config-validate --exit-code
This command will print found errors, based on `cerberus <https://docs.python-cerberus.org/>`_, e.g.:
.. code-block:: shell
auth
ssalt: unknown field
target: none or more than one rule validate
oneof definition 0: unallowed value mapping
oneof definition 1: field 'salt' is required
oneof definition 2: unallowed value mapping
oneof definition 2: field 'salt' is required
oneof definition 2: field 'client_id' is required
oneof definition 2: field 'client_secret' is required
gitremote
pull_url: unknown field
If an additional flag ``--exit-code`` is supplied, the application will return non-zero exit code, which can be used partially in scripts.
What does "architecture specific" mean / How to configure for different architectures
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Some sections can be configured per architecture. The service will merge architecture specific values into common settings. In order to specify settings for specific architecture you must point it in section name.
For example, the section
.. code-block:: ini
[build]
build_command = extra-x86_64-build
states that default build command is ``extra-x86_64-build``. But if there is section
.. code-block:: ini
[build:i686]
build_command = extra-i686-build
the ``extra-i686-build`` command will be used for ``i686`` architecture.
How to generate build reports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Normally you probably like to generate only one report for the specific type, e.g. only one email report. In order to do it you will need to have the following configuration:
.. code-block:: ini
[report]
target = email
[email]
...
or in case of multiple architectures and *different* reporting settings:
.. code-block:: ini
[report]
target = email
[email:i686]
...
[email:x86_64]
...
But for some cases you would like to have multiple different reports with the same type (e.g. sending different templates to different addresses). For these cases you will need to specify section name in target and type in section, e.g. the following configuration can be used:
.. code-block:: ini
[report]
target = email_1 email_2
[email_1]
type = email
...
[email_2]
type = email
...
How do I add new package
^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: shell
sudo -u ahriman ahriman package-add ahriman --now
``--now`` flag is totally optional and just run ``repo-update`` subcommand after the registering the new package, Thus the extended flow is the following:
.. code-block:: shell
sudo -u ahriman ahriman package-add ahriman
sudo -u ahriman ahriman repo-update
How to build package from local PKGBUILD
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TL;DR
.. code-block:: shell
sudo -u ahriman ahriman package-add /path/to/local/directory/with/PKGBUILD --now
Before using this command you will need to create local directory, put ``PKGBUILD`` there and generate ``.SRCINFO`` by using ``makepkg --printsrcinfo > .SRCINFO`` command. These packages will be stored locally and *will be ignored* during automatic update; in order to update the package you will need to run ``package-add`` command again.
How to fetch PKGBUILDs from remote repository
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For that purpose you could use ``RemotePullTrigger`` trigger. To do so you will need to configure trigger as following:
.. code-block:: ini
[remote-pull]
target = gitremote
[gitremote]
pull_url = https://github.com/username/repository
During the next application run it will fetch repository from the specified url and will try to find packages there which can be used as local sources.
How to push updated PKGBUILDs to remote repository
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For that purpose you'd need to use another trigger called ``RemotePushTrigger``. Configure trigger as following:
.. code-block:: ini
[remote-push]
target = gitremote
[gitremote]
push_url = https://github.com/username/repository
Unlike ``RemotePullTrigger`` trigger, the ``RemotePushTrigger`` more likely will require authorization. It is highly recommended to use application tokens for that instead of using your password (e.g. for Github you can generate tokens `here <https://github.com/settings/tokens>`_ with scope ``public_repo``). Authorization can be supplied by using authorization part of the url, e.g. ``https://key:token@github.com/username/repository``.
How to change PKGBUILDs before build
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Well it is supported also. The recommended way is to patch specific function, e.g. by running
.. code-block:: shell
sudo -u ahriman ahriman patch-add ahriman version
This command will prompt for new value of the PKGBUILD variable ``version``. You can also write it to file and read from it:
.. code-block:: shell
sudo -u ahriman ahriman patch-add ahriman version version.patch
Alternatively you can create full-diff patches, which are calculated by using ``git diff`` from current PKGBUILD master branch:
#.
Clone sources from AUR.
#.
Make changes you would like to (e.g. edit ``PKGBUILD``, add external patches).
#.
Run command
.. code-block:: shell
sudo -u ahriman ahriman patch-set-add /path/to/local/directory/with/PKGBUILD
The last command will calculate diff from current tree to the ``HEAD`` and will store it locally. Patches will be applied on any package actions (e.g. it can be used for dependency management).
How to build package from official repository
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
So it is the same as adding any other package, but due to restrictions you must specify source explicitly, e.g.:
.. code-block:: shell
sudo -u ahriman ahriman package-add pacman -s repository
This feature is heavily depends on local pacman cache. In order to use this feature it is recommended to either run ``pacman -Sy`` before the interaction or configure timer for this.
Package build fails because it cannot validate PGP signature of source files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TL;DR
.. code-block:: shell
sudo -u ahriman ahriman service-key-import ...
How to update VCS packages
^^^^^^^^^^^^^^^^^^^^^^^^^^
Normally the service handles VCS packages correctly, however it requires additional dependencies:
.. code-block:: shell
pacman -S breezy darcs mercurial subversion
How to remove package
^^^^^^^^^^^^^^^^^^^^^
.. code-block:: shell
sudo -u ahriman ahriman package-remove ahriman
Also, there is command ``repo-remove-unknown`` which checks packages in AUR and local storage and removes ones which have been removed.
Remove commands also remove any package files (patches, caches etc).
How to sign repository
^^^^^^^^^^^^^^^^^^^^^^
Repository sign feature is available in several configurations. The recommended way is just to sign repository database file by single key instead of trying to sign each package. However, the steps are pretty same, just configuration is a bit differ. For more details about options kindly refer to :doc:`configuration reference <configuration>`.
#.
First you would need to create the key on your local machine:
.. code-block:: shell
gpg --full-generate-key
This command will prompt you for several questions. Most of them may be left default, but you will need to fill real name and email address with some data. Because at the moment the service doesn't support passphrases, it must be left blank.
#.
The command above will generate key and print its hash, something like ``8BE91E5A773FB48AC05CC1EDBED105AED6246B39``. Copy it.
#.
Export your private key by using the hash above:
.. code-block:: shell
gpg --export-secret-keys -a 8BE91E5A773FB48AC05CC1EDBED105AED6246B39 > repository-key.gpg
#.
Copy the specified key to the build machine (i.e. where the service is running).
#.
Import the specified key to the service user:
.. code-block:: shell
sudo -u ahriman gpg --import repository-key.gpg
Don't forget to remove the key from filesystem after import.
#.
Change trust level to ``ultimate``:
.. code-block:: shell
sudo -u ahriman gpg --edit-key 8BE91E5A773FB48AC05CC1EDBED105AED6246B39
The command above will drop you into gpg shell, in which you will need to type ``trust``, choose ``5 = I trust ultimately``, confirm and exit ``quit``.
#.
Proceed with service configuration according to the :doc:`configuration <configuration>`:
.. code-block:: ini
[sign]
target = repository
key = 8BE91E5A773FB48AC05CC1EDBED105AED6246B39
How to rebuild packages after library update
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TL;DR
.. code-block:: shell
sudo -u ahriman ahriman repo-rebuild --depends-on python
You can even rebuild the whole repository (which is particular useful in case if you would like to change packager) if you do not supply ``--depends-on`` option.
However, note that you do not need to rebuild repository in case if you just changed signing option, just use ``repo-sign`` command instead.
How to install built packages
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Add the following lines to your ``pacman.conf``:
.. code-block:: ini
[repository]
Server = file:///var/lib/ahriman/repository/x86_64
(You might need to add ``SigLevel`` option according to the pacman documentation.)
How to serve repository
^^^^^^^^^^^^^^^^^^^^^^^
Easy. For example, nginx configuration (without SSL) will look like:
.. code-block::
server {
listen 80;
server_name repo.example.com;
location / {
autoindex on;
root /var/lib/ahriman/repository;
}
}
Example of the status page configuration is the following (status service is using 8080 port):
.. code-block::
server {
listen 80;
server_name builds.example.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarder-Proto $scheme;
proxy_pass http://127.0.0.1:8080;
}
}
Docker image
------------
We provide official images which can be found under ``arcan1s/ahriman`` repository. Docker image is being updated on each commit to master as well as on each version. If you would like to use last (probably unstable) build you can use ``edge`` tag or ``latest`` for any tagged versions; otherwise you can use any version tag available.
The default action (in case if no arguments provided) is ``repo-update``. Basically the idea is to run container, e.g.:
.. code-block:: shell
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
``--privileged`` flag is required to make mount possible inside container. In order to make data available outside of container, you would need to mount local (parent) directory inside container by using ``-v /path/to/local/repo:/var/lib/ahriman`` argument, where ``/path/to/local/repo`` is a path to repository on local machine. In addition, you can pass own configuration overrides by using the same ``-v`` flag, e.g.:
.. code-block:: shell
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman -v /path/to/overrides/overrides.ini:/etc/ahriman.ini.d/10-overrides.ini arcan1s/ahriman:latest
The action can be specified during run, e.g.:
.. code-block:: shell
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest package-add ahriman --now
For more details please refer to docker FAQ.
Environment variables
^^^^^^^^^^^^^^^^^^^^^
The following environment variables are supported:
* ``AHRIMAN_ARCHITECTURE`` - architecture of the repository, default is ``x86_64``.
* ``AHRIMAN_DEBUG`` - if set all commands will be logged to console.
* ``AHRIMAN_FORCE_ROOT`` - force run ahriman as root instead of guessing by subcommand.
* ``AHRIMAN_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_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.
* ``AHRIMAN_REPOSITORY`` - repository name, default is ``aur-clone``.
* ``AHRIMAN_REPOSITORY_ROOT`` - repository root. Because of filesystem rights it is required to override default repository root. By default, it uses ``ahriman`` directory inside ahriman's home, which can be passed as mount volume.
* ``AHRIMAN_UNIX_SOCKET`` - full path to unix socket which is used by web server, default is empty. Note that more likely you would like to put it inside ``AHRIMAN_REPOSITORY_ROOT`` directory (e.g. ``/var/lib/ahriman/ahriman/ahriman-web.sock``) or to ``/tmp``.
* ``AHRIMAN_USER`` - ahriman user, usually must not be overwritten, default is ``ahriman``.
* ``AHRIMAN_VALIDATE_CONFIGURATION`` - if set validate service configuration
You can pass any of these variables by using ``-e`` argument, e.g.:
.. code-block:: shell
docker run --privileged -e AHRIMAN_PORT=8080 -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
Daemon service
^^^^^^^^^^^^^^
There is special ``repo-daemon`` subcommand which emulates systemd timer and will perform repository update periodically:
.. code-block:: shell
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest repo-daemon
This command uses same rules as ``repo-update``, thus, e.g. requires ``--privileged`` flag.
Web service setup
^^^^^^^^^^^^^^^^^
Well for that you would need to have web container instance running forever; it can be achieved by the following command:
.. code-block:: shell
docker run --privileged -p 8080:8080 -e AHRIMAN_PORT=8080 -e AHRIMAN_UNIX_SOCKET=/var/lib/ahriman/ahriman/ahriman-web.sock -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
Note about ``AHRIMAN_PORT`` environment variable which is required in order to enable web service. An additional port bind by ``-p 8080:8080`` is required to pass docker port outside of container.
The ``AHRIMAN_UNIX_SOCKET`` variable is not required, however, highly recommended as it can be used for interprocess communications. If you set this variable you would like to be sure that this path is available outside of container if you are going to use multiple docker instances.
If you are using ``AHRIMAN_UNIX_SOCKET`` variable, for every next container run it has to be passed also, e.g.:
.. code-block:: shell
docker run --privileged -e AHRIMAN_UNIX_SOCKET=/var/lib/ahriman/ahriman/ahriman-web.sock -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
Otherwise, you would need to pass ``AHRIMAN_PORT`` and mount container network to the host system (``--net=host``), e.g.:
.. code-block:: shell
docker run --privileged --net=host -e AHRIMAN_PORT=8080 -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
Non-x86_64 architecture setup
-----------------------------
The following section describes how to setup ahriman with architecture different from x86_64, as example i686. For most cases you have base repository available, e.g. archlinux32 repositories for i686 architecture; in case if base repository is not available, steps are a bit different, however, idea remains the same.
Physical server setup
^^^^^^^^^^^^^^^^^^^^^
In this example we are going to use files and packages which are provided by official repositories of the used architecture. Note, that versions might be different, thus you need to find correct versions on the distribution web site, e.g. `archlinux32 packages <https://www.archlinux32.org/packages/>`_.
#.
First, considering having base Arch Linux system, we need to install keyring for the specified repositories:
.. code-block:: shell
wget http://pool.mirror.archlinux32.org/i686/core/archlinux32-keyring-20220927-1.0-any.pkg.tar.zst
pacman -U archlinux32-keyring-20220927-1.0-any.pkg.tar.zst
#.
In order to run ``devtools`` scripts for custom architecture they also need specific ``makepkg`` configuration, it can be retrieved by installing the ``devtools`` package of the distribution:
.. code-block:: shell
wget http://pool.mirror.archlinux32.org/i686/extra/devtools-20221208-1.0-any.pkg.tar.zst
pacman -U devtools-20221208-1.0-any.pkg.tar.zst
Alternatively, you can create your own ``makepkg`` configuration and save it as ``/usr/share/devtools/makepkg-i686.conf``.
#.
Setup repository as usual:
.. code-block:: shell
ahriman -a i686 service-setup --mirror 'http://de.mirror.archlinux32.org/$arch/$repo'--no-multilib ...
In addition to usual options, you need to specify the following options:
* ``--mirror`` - link to the mirrors which will be used instead of official repositories.
* ``--no-multilib`` - in the example we are using i686 architecture for which multilib repository doesn't exist.
Docker container setup
^^^^^^^^^^^^^^^^^^^^^^
There are two possible ways to achieve same setup, by using docker container. The first one is just mount required files inside container and run it as usual (with specific environment variables). Another one is to create own container based on official one:
#.
Clone official container as base:
.. code-block:: dockerfile
FROM arcan1s/ahriman:latest
#.
Init pacman keys. This command is required in order to populate distribution keys:
.. code-block:: dockerfile
RUN pacman-key --init
#.
Install packages as it was described above:
.. code-block:: dockerfile
RUN pacman --noconfirm -Sy wget
RUN wget http://pool.mirror.archlinux32.org/i686/extra/devtools-20221208-1.0-any.pkg.tar.zst && pacman --noconfirm -U devtools-20221208-1.0-any.pkg.tar.zst
RUN wget http://pool.mirror.archlinux32.org/i686/core/archlinux32-keyring-20220927-1.0-any.pkg.tar.zst && pacman --noconfirm -U archlinux32-keyring-20220927-1.0-any.pkg.tar.zst
#.
At that point you should have full ``Dockerfile`` like:
.. code-block:: dockerfile
FROM arcan1s/ahriman:latest
RUN pacman-key --init
RUN pacman --noconfirm -Sy wget
RUN wget http://pool.mirror.archlinux32.org/i686/extra/devtools-20221208-1.0-any.pkg.tar.zst && pacman --noconfirm -U devtools-20221208-1.0-any.pkg.tar.zst
RUN wget http://pool.mirror.archlinux32.org/i686/core/archlinux32-keyring-20220927-1.0-any.pkg.tar.zst && pacman --noconfirm -U archlinux32-keyring-20220927-1.0-any.pkg.tar.zst
#.
After that you can build you own container, e.g.:
.. code-block:: shell
docker build --tag ahriman-i686:latest
#.
Now you can run locally built container as usual with passing environment variables for setup command:
.. code-block:: shell
docker run --privileged -p 8080:8080 -e AHRIMAN_ARCHITECTURE=i686 -e AHRIMAN_PACMAN_MIRROR='http://de.mirror.archlinux32.org/$arch/$repo' -e AHRIMAN_MULTILIB= ahriman-i686:latest
Remote synchronization
----------------------
How to sync repository to another server
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are several choices:
#.
Easy and cheap, just share your local files through the internet, e.g. for ``nginx``:
.. code-block::
server {
location /x86_64 {
root /var/lib/ahriman/repository/x86_64;
autoindex on;
}
}
#.
You can also upload your packages using ``rsync`` to any available server. In order to use it you would need to configure ahriman first:
.. code-block:: ini
[upload]
target = rsync
[rsync]
remote = 192.168.0.1:/srv/repo
After that just add ``/srv/repo`` to the ``pacman.conf`` as usual. You can also upload to S3 (e.g. ``Server = https://s3.eu-central-1.amazonaws.com/repository/x86_64``) or to Github (e.g. ``Server = https://github.com/ahriman/repository/releases/download/x86_64``).
How to sync to S3
^^^^^^^^^^^^^^^^^
#.
Install dependencies:
.. code-block:: shell
pacman -S python-boto3
#.
Create a bucket.
#.
Create user with write access to the bucket:
.. code-block::
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListObjectsInBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::repository"
]
},
{
"Sid": "AllObjectActions",
"Effect": "Allow",
"Action": "s3:*Object",
"Resource": [
"arn:aws:s3:::repository/*"
]
}
]
}
#.
Create an API key for the user and store it.
#.
Configure the service as following:
.. code-block:: ini
[upload]
target = s3
[s3]
access_key = ...
bucket = repository
region = eu-central-1
secret_key = ...
How to sync to Github releases
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#.
Create a repository.
#.
`Create API key <https://github.com/settings/tokens>`_ with scope ``public_repo``.
#.
Configure the service as following:
.. code-block:: ini
[upload]
target = github
[github]
owner = ahriman
password = ...
repository = repository
username = ahriman
Reporting
---------
How to report by email
^^^^^^^^^^^^^^^^^^^^^^
#.
Install dependencies:
.. code-block:: shell
yay -S python-jinja
#.
Configure the service:
.. code-block:: ini
[report]
target = email
[email]
host = smtp.example.com
link_path = http://example.com/x86_64
password = ...
port = 465
receivers = me@example.com
sender = me@example.com
user = me@example.com
How to generate index page for S3
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#.
Install dependencies:
.. code-block:: shell
yay -S python-jinja
#.
Configure the service:
.. code-block:: ini
[report]
target = html
[html]
path = /var/lib/ahriman/repository/x86_64/index.html
link_path = http://example.com/x86_64
After these steps ``index.html`` file will be automatically synced to S3
How to post build report to telegram
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#.
It still requires additional dependencies:
.. code-block:: shell
yay -S 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>`_.
#.
Optionally (if you want to post message in chat):
#. Create telegram channel.
#. Invite your bot into the channel.
#. Make your channel public
#.
Get chat id if you want to use by numerical id or just use id prefixed with ``@`` (e.g. ``@ahriman``). If you are not using chat the chat id is your user id. If you don't want to make channel public you can use `this guide <https://stackoverflow.com/a/33862907>`_.
#.
Configure the service:
.. code-block:: ini
[report]
target = telegram
[telegram]
api_key = aaAAbbBBccCC
chat_id = @ahriman
link_path = http://example.com/x86_64
``api_key`` is the one sent by `@BotFather <https://t.me/botfather>`_, ``chat_id`` is the value retrieved from previous step.
If you did everything fine you should receive the message with the next update. Quick credentials check can be done by using the following command:
.. code-block:: shell
curl 'https://api.telegram.org/bot${CHAT_ID}/sendMessage?chat_id=${API_KEY}&text=hello'
(replace ``${CHAT_ID}`` and ``${API_KEY}`` with the values from configuration).
Web service
-----------
How to setup web service
^^^^^^^^^^^^^^^^^^^^^^^^
#.
Install dependencies:
.. code-block:: shell
yay -S python-aiohttp python-aiohttp-jinja2
#.
Configure service:
.. code-block:: ini
[web]
port = 8080
#.
Start the web service ``systemctl enable --now ahriman-web@x86_64``.
How to enable basic authorization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#.
Install dependencies 😊:
.. code-block:: shell
yay -S python-aiohttp-security python-aiohttp-session python-cryptography
#.
Configure the service to enable authorization:
.. code-block:: ini
[auth]
target = configuration
#.
In order to provide access for reporting from application instances you can (recommended way) use unix sockets by configuring the following (note, that it requires ``python-requests-unixsocket`` package to be installed):
.. code-block:: ini
[web]
unix_socket = /var/lib/ahriman/ahriman-web.sock
This socket path must be available for web service instance and must be available for application instances (e.g. in case if you are using docker container, see above, you need to be sure that the socket is passed to the root filesystem).
By the way, unix socket variable will be automatically set in case if ``--web-unix-socket`` argument is supplied to the ``setup`` subcommand.
Alternatively, you need to create user for the service:
.. code-block:: shell
sudo -u ahriman ahriman user-add -r full api
This command will ask for the password, just type it in stdin; *do not* leave the field blank, user will not be able to authorize, and finally configure the application:
.. code-block:: ini
[web]
username = api
password = pa55w0rd
#.
Create end-user with password:
.. code-block:: shell
sudo -u ahriman ahriman user-add -r full my-first-user
#.
Restart web service ``systemctl restart ahriman-web@x86_64``.
How to enable OAuth authorization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#.
Create OAuth web application, download its ``client_id`` and ``client_secret``.
#.
Guess what? Install dependencies:
.. code-block:: shell
yay -S python-aiohttp-security python-aiohttp-session python-cryptography python-aioauth-client
#.
Configure the service:
.. code-block:: ini
[auth]
target = oauth
client_id = ...
client_secret = ...
[web]
address = https://example.com
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:
.. code-block:: shell
sudo -u ahriman ahriman user-add --as-service -r full api
#.
Create end-user:
.. code-block:: shell
sudo -u ahriman ahriman user-add -r full my-first-user
When it will ask for the password leave it blank.
#.
Restart web service ``systemctl restart ahriman-web@x86_64``.
How to implement own interface
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You can write your own interface by using API which is provided by the web service. Full autogenerated API documentation is available at ``http://localhost:8080/api-docs``.
Backup and restore
------------------
The service provides several commands aim to do easy repository backup and restore. If you would like to move repository from the server ``server1.example.com`` to another ``server2.example.com`` you have to perform the following steps:
#.
On the source server ``server1.example.com`` run ``repo-backup`` command, e.g.:
.. code-block:: shell
ahriman repo-backup /tmp/repo.tar.gz
This command will pack all configuration files together with database file into the archive specified as command line argument (i.e. ``/tmp/repo.tar.gz``). In addition it will also archive ``cache`` directory (the one which contains local clones used by e.g. local packages) and ``.gnupg`` of the ``ahriman`` user.
#.
Copy created archive from source server ``server1.example.com`` to target ``server2.example.com``.
#.
Install package as usual on the target server ``server2.example.com`` if you didn't yet.
#.
Extract archive e.g. by using subcommand:
.. code-block:: shell
ahriman repo-restore /tmp/repo.tar.gz
An additional argument ``-o``/``--output`` can be used to specify extraction root (``/`` by default).
#.
Rebuild repository:
.. code-block:: shell
sudo -u ahriman ahriman repo-rebuild --from-database
Other topics
------------
How does it differ from %another-manager%?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Short answer - I do not know. Also for some references credits to `Alad <https://github.com/AladW>`_, he `did <https://wiki.archlinux.org/title/User:Alad/Local_repo_tools>`_ really good investigation of existing alternatives.
`arch-repo-manager <https://github.com/Martchus/arch-repo-manager>`_
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Looks actually pretty good, in case if I would find it, I would probably didn't start this project, most of features (like web interface or additional helpers) are already implemented or planned to be. However, this project seems to be at early alpha stage (as for Nov 2022), written in C++ (not pro or con) and misses code documentation.
`archrepo2 <https://github.com/lilydjwg/archrepo2>`_
""""""""""""""""""""""""""""""""""""""""""""""""""""
Don't know, haven't tried it. But it lacks of documentation at least.
* ``ahriman`` has web interface.
* ``archrepo2`` doesn't have synchronization and reporting.
* ``archrepo2`` actively uses direct shell calls and ``yaourt`` components.
* ``archrepo2`` has constantly running process instead of timer process (it is not pro or con).
`repoctl <https://github.com/cassava/repoctl>`_
"""""""""""""""""""""""""""""""""""""""""""""""
* ``ahriman`` has web interface.
* ``repoctl`` does not have reporting feature.
* ``repoctl`` does not support local packages and patches.
* Some actions are not fully automated in ``repoctl`` (e.g. package update still requires manual intervention for the build itself).
* ``repoctl`` has better AUR interaction features. With colors!
* ``repoctl`` has much easier configuration and even completion.
* ``repoctl`` is able to store old packages.
* Ability to host repository from same command in ``repoctl`` vs external services (e.g. nginx) in ``ahriman``.
`repo-scripts <https://github.com/arcan1s/repo-scripts>`_
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Though originally I've created ahriman by trying to improve the project, it still lacks a lot of features:
* ``ahriman`` has web interface.
* ``ahriman`` has better reporting with template support.
* ``ahriman`` has more synchronization features (there was only ``rsync`` based).
* ``ahriman`` supports local packages and patches.
* ``repo-scripts`` doesn't have dependency management.
...and so on. ``repo-scripts`` also has bad architecture and bad quality code and uses out-of-dated ``yaourt`` and ``package-query``.
`toolbox <https://github.com/chaotic-aur/toolbox>`_
"""""""""""""""""""""""""""""""""""""""""""""""""""
It is automation tools for ``repoctl`` mentioned above. Except for using shell it looks pretty cool and also offers some additional features like patches, remote synchronization (isn't it?) and reporting.
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.:
.. code-block:: shell
sed -i 's/handlers = syslog_handler/handlers = console_handler/g' /etc/ahriman.ini.d/logging.ini
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).
Html customization
^^^^^^^^^^^^^^^^^^
It is possible to customize html templates. In order to do so, create files somewhere (refer to Jinja2 documentation and the service source code for available parameters) and put ``template_path`` to configuration pointing to this directory.
I did not find my question
^^^^^^^^^^^^^^^^^^^^^^^^^^
`Create an issue <https://github.com/arcan1s/ahriman/issues>`_ with type **Question**.

35
docs/faq/backup.rst Normal file
View File

@ -0,0 +1,35 @@
Backup and restore
------------------
The service provides several commands aim to do easy repository backup and restore. If you would like to move repository from the server ``server1.example.com`` to another ``server2.example.com`` you have to perform the following steps:
#.
On the source server ``server1.example.com`` run ``repo-backup`` command, e.g.:
.. code-block:: shell
ahriman repo-backup /tmp/repo.tar.gz
This command will pack all configuration files together with database file into the archive specified as command line argument (i.e. ``/tmp/repo.tar.gz``). In addition it will also archive ``cache`` directory (the one which contains local clones used by e.g. local packages) and ``.gnupg`` of the ``ahriman`` user.
#.
Copy created archive from source server ``server1.example.com`` to target ``server2.example.com``.
#.
Install package as usual on the target server ``server2.example.com`` if you didn't yet.
#.
Extract archive e.g. by using subcommand:
.. code-block:: shell
ahriman repo-restore /tmp/repo.tar.gz
An additional argument ``-o``/``--output`` can be used to specify extraction root (``/`` by default).
#.
Rebuild repository:
.. code-block:: shell
sudo -u ahriman ahriman repo-rebuild --from-database

326
docs/faq/distributed.rst Normal file
View File

@ -0,0 +1,326 @@
Distributed builds
------------------
The service allows to run build on multiple machines and collect packages on main node. There are several ways to achieve it, this section describes officially supported methods.
Remote synchronization and remote server call
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This setup requires at least two instances of the service:
#. Web service (with opt-in authorization enabled), later will be referenced as **master** node.
#. Application instances responsible for build, later will be referenced as **worker** nodes.
In this example the following settings are assumed:
* Repository architecture is ``x86_64``.
* Master node address is ``master.example.com``.
Master node configuration
"""""""""""""""""""""""""
The only requirements for the master node is that API must be available for worker nodes to call (e.g. port must be exposed to internet, or local network in case of VPN, etc) and file upload must be enabled:
.. code-block:: ini
[web]
enable_archive_upload = yes
In addition, the following settings are recommended for the master node:
*
As it has been mentioned above, it is recommended to enable authentication (see :doc:`How to enable basic authorization <web>`) and create system user which will be used later. Later this user (if any) will be referenced as ``worker-user``.
*
In order to be able to spawn multiple processes at the same time, wait timeout must be configured:
.. code-block:: ini
[web]
wait_timeout = 0
Worker nodes configuration
""""""""""""""""""""""""""
#.
First of all, in this setup you need to split your repository into chunks manually, e.g. if you have repository on master node with packages ``A``, ``B`` and ``C``, you need to split them between all available workers, as example:
* Worker #1: ``A``.
* Worker #2: ``B`` and ``C``.
Hint: ``repo-tree`` subcommand provides ``--partitions`` argument.
#.
Each worker must be configured to upload files to master node:
.. code-block:: ini
[upload]
target = remote-service
[remote-service]
#.
Worker must be configured to access web on master node:
.. code-block:: ini
[status]
address = https://master.example.com
username = worker-user
password = very-secure-password
As it has been mentioned above, ``${status:address}`` must be available for workers. In case if unix socket is used, it can be passed in the same option as usual. Optional ``${status:username}``/``${status:password}`` can be supplied in case if authentication was enabled on master node.
#.
Each worker must call master node on success:
.. code-block:: ini
[report]
target = remote-call
[remote-call]
manual = yes
After success synchronization (see above), the built packages will be put into directory, from which they will be read during manual update, thus ``${remote-call:manual}`` flag is required.
#.
Change order of trigger runs. This step is required, because by default the report trigger is called before the upload trigger and we would like to achieve the opposite:
.. code-block:: ini
[build]
triggers = ahriman.core.gitremote.RemotePullTrigger ahriman.core.upload.UploadTrigger ahriman.core.report.ReportTrigger ahriman.core.gitremote.RemotePushTrigger
In addition, the following settings are recommended for workers:
*
You might want to wait until report trigger will be completed; in this case the following option must be set:
.. code-block:: ini
[remote-call]
wait_timeout = 0
Dependency management
"""""""""""""""""""""
By default worker nodes don't know anything about master nodes packages, thus it will try to build each dependency by its own. However, using ``AHRIMAN_REPOSITORY_SERVER`` docker variable (or ``--server`` flag for setup command), it is possible to specify address of the master node for devtools configuration.
Repository and packages signing
"""""""""""""""""""""""""""""""
You can sign packages on worker nodes and then signatures will be synced to master node. In order to do so, you need to configure worker node as following, e.g.:
.. code-block:: ini
[sign]
target = package
key = 8BE91E5A773FB48AC05CC1EDBED105AED6246B39
Note, however, that in this case, signatures will not be validated on master node and just will be copied to repository tree.
If you would like to sign only database files (aka repository sign), it has to be configured only on master node as usual, e.g.:
.. code-block:: ini
[sign]
target = repository
key = 8BE91E5A773FB48AC05CC1EDBED105AED6246B39
Double node minimal docker example
""""""""""""""""""""""""""""""""""
Master node config (``master.ini``) as:
.. code-block:: ini
[auth]
target = configuration
[web]
enable_archive_upload = yes
wait_timeout = 0
Command to run master node:
.. code-block:: shell
docker run --privileged -p 8080:8080 -e AHRIMAN_PORT=8080 -v master.ini:/etc/ahriman.ini.d/overrides.ini arcan1s/ahriman:latest web
The user ``worker-user`` has been created additionally. Worker node config (``worker.ini``) as:
.. code-block:: ini
[status]
address = http://172.17.0.1:8080
username = worker-user
password = very-secure-password
[upload]
target = remote-service
[remote-service]
[report]
target = remote-call
[remote-call]
manual = yes
wait_timeout = 0
[build]
triggers = ahriman.core.gitremote.RemotePullTrigger ahriman.core.upload.UploadTrigger ahriman.core.report.ReportTrigger ahriman.core.gitremote.RemotePushTrigger
The address above (``http://172.17.0.1:8080``) is somewhat available for worker container.
Command to run worker node:
.. code-block:: shell
docker run --privileged -v worker.ini:/etc/ahriman.ini.d/overrides.ini -it arcan1s/ahriman:latest package-add ahriman --now
The command above will successfully build ``ahriman`` package, upload it on master node and, finally, will update master node repository.
Check proof-of-concept setup `here <https://github.com/arcan1s/ahriman/tree/master/recipes/distributed-manual>`__.
Addition of new package and repository update
"""""""""""""""""""""""""""""""""""""""""""""
Just run on worker command as usual, the built packages will be automatically uploaded to master node. Note that automatic update process must be disabled on master node.
Package removal
"""""""""""""""
This action must be done in two steps:
#. Remove package on worker.
#. Remove package on master node.
Delegate builds to remote workers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This setup heavily uses upload feature described above and, in addition, also delegates build process automatically to build machines. Same as above, there must be at least two instances available (**master** and **worker**), however, all **worker** nodes must be run in the web service mode.
Master node configuration
"""""""""""""""""""""""""
In addition to the configuration above, the worker list must be defined in configuration file (``${build:workers}`` option), i.e.:
.. code-block:: ini
[build]
workers = https://worker1.example.com https://worker2.example.com
[web]
enable_archive_upload = yes
wait_timeout = 0
In the example above, ``https://worker1.example.com`` and ``https://worker2.example.com`` are remote **worker** node addresses available for **master** node.
In case if authentication is required (which is recommended way to setup it), it can be set by using ``status`` section as usual.
Worker nodes configuration
""""""""""""""""""""""""""
It is required to point to the master node repository, otherwise internal dependencies will not be handled correctly. In order to do so, the ``--server`` argument (or ``AHRIMAN_REPOSITORY_SERVER`` environment variable for docker images) can be used.
Also, in case if authentication is enabled, the same user with the same password must be created for all workers.
It is also recommended to set ``${web:wait_timeout}`` to infinite in case of multiple conflicting runs and ``${web:service_only}`` to ``yes`` in order to disable status endpoints.
Other settings are the same as mentioned above.
Triple node minimal docker example
""""""""""""""""""""""""""""""""""
In this example, all instances are run on the same machine with address ``172.17.0.1`` with ports available outside of container. Master node config (``master.ini``) as:
.. code-block:: ini
[auth]
target = configuration
[status]
username = builder-user
password = very-secure-password
[build]
workers = http://172.17.0.1:8081 http://172.17.0.1:8082
[web]
enable_archive_upload = yes
wait_timeout = 0
Command to run master node:
.. code-block:: shell
docker run --privileged -p 8080:8080 -e AHRIMAN_PORT=8080 -v master.ini:/etc/ahriman.ini.d/overrides.ini arcan1s/ahriman:latest web
Worker nodes (applicable for all workers) config (``worker.ini``) as:
.. code-block:: ini
[auth]
target = configuration
[status]
address = http://172.17.0.1:8080
username = builder-user
password = very-secure-password
[upload]
target = remote-service
[remote-service]
[report]
target = remote-call
[remote-call]
manual = yes
wait_timeout = 0
[web]
service_only = yes
[build]
triggers = ahriman.core.upload.UploadTrigger ahriman.core.report.ReportTrigger
Command to run worker nodes (considering there will be two workers, one is on ``8081`` port and other is on ``8082``):
.. code-block:: shell
docker run --privileged -p 8081:8081 -e AHRIMAN_PORT=8081 -v worker.ini:/etc/ahriman.ini.d/overrides.ini arcan1s/ahriman:latest web
docker run --privileged -p 8082:8082 -e AHRIMAN_PORT=8082 -v worker.ini:/etc/ahriman.ini.d/overrides.ini arcan1s/ahriman:latest web
Unlike the previous setup, it doesn't require to mount repository root for **worker** nodes, because they don't use it anyway.
Check proof-of-concept setup `here <https://github.com/arcan1s/ahriman/tree/master/recipes/distributed>`__.
Addition of new package, package removal, repository update
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
In all scenarios, update process must be run only on **master** node. Unlike the manually distributed packages described above, automatic update must be enabled only for **master** node.
Automatic worker nodes discovery
""""""""""""""""""""""""""""""""
Instead of setting ``${build:workers}`` option explicitly it is also possible to configure services to load worker list dynamically. To do so, the ``ahriman.core.distributed.WorkerLoaderTrigger`` and ``ahriman.core.distributed.WorkerTrigger`` must be used for **master** and **worker** nodes respectively. See recipes for more details.
Those triggers have to be installed as a separate package:
.. code-block:: shell
yay -S ahriman-triggers
Known limitations
"""""""""""""""""
* Workers don't support local packages. However, it is possible to build custom packages by providing sources by using ``ahriman.core.gitremote.RemotePullTrigger`` trigger.
* No dynamic nodes discovery. In case if one of worker nodes is unavailable, the build process will fail.
* No pkgrel bump on conflicts.
* The identical user must be created for all workers. However, the **master** node user can be different from this one.

137
docs/faq/docker.rst Normal file
View File

@ -0,0 +1,137 @@
Docker image
------------
We provide official images which can be found under:
* docker registry ``arcan1s/ahriman``;
* ghcr.io registry ``ghcr.io/arcan1s/ahriman``.
These images are totally identical.
Docker image is being updated on each commit to master as well as on each version. If you would like to use last (probably unstable) build you can use ``edge`` tag or ``latest`` for any tagged versions; otherwise you can use any version tag available.
The default action (in case if no arguments provided) is ``repo-update``. Basically the idea is to run container, e.g.:
.. code-block:: shell
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
In order to make data available outside of container, you would need to mount local (parent) directory inside container by using ``-v /path/to/local/repo:/var/lib/ahriman`` argument, where ``/path/to/local/repo`` is a path to repository on local machine. In addition, you can pass own configuration overrides by using the same ``-v`` flag, e.g.:
.. code-block:: shell
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman -v /path/to/overrides/overrides.ini:/etc/ahriman.ini.d/10-overrides.ini arcan1s/ahriman:latest
The action can be specified during run, e.g.:
.. code-block:: shell
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest package-add ahriman --now
For more details please refer to the docker FAQ.
Privileged and non-privileged container
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Examples here suggest using ``--privileged`` flag which is required for the devtools and is involved in two types of operations: tmpfs mount and cgroup manipulation. Whereas it is the easiest way to operate, it might be not really secure. The other way to make devtools working is to grant required capabilities, which can be achieved by using flags:
* ``--cap-add=SYS_ADMIN``, which grants permissions to operate with tmpfs for ``systemd-nspawn``.
* ``-v /sys/fs/cgroup:/sys/fs/cgroup`` which allows access to cgroup manipulation.
Thus, there are two possible ways to run the container:
.. code-block:: shell
docker run --privileged arcan1s/ahriman:latest
and
.. code-block:: shell
docker run --cap-add=SYS_ADMIN -v /sys/fs/cgroup:/sys/fs/cgroup arcan1s/ahriman:latest
but for the simplicity this FAQ will always use ``--privileged`` flag.
Environment variables
^^^^^^^^^^^^^^^^^^^^^
The following environment variables are supported:
* ``AHRIMAN_ARCHITECTURE`` - architecture of the repository, default is ``x86_64``.
* ``AHRIMAN_DEBUG`` - if set all commands will be logged to console.
* ``AHRIMAN_FORCE_ROOT`` - force run ahriman as root instead of guessing by subcommand.
* ``AHRIMAN_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`` 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.
* ``AHRIMAN_POSTSETUP_COMMAND`` - if set, the command which will be called (as root) after the setup command, but before any other actions.
* ``AHRIMAN_PRESETUP_COMMAND`` - if set, the command which will be called (as root) right before the setup command.
* ``AHRIMAN_REPOSITORY`` - repository name, default is ``aur``.
* ``AHRIMAN_REPOSITORY_SERVER`` - optional override for the repository URL. Useful if you would like to download packages from remote instead of local filesystem.
* ``AHRIMAN_REPOSITORY_ROOT`` - repository root. Because of filesystem rights it is required to override default repository root. By default, it uses ``ahriman`` directory inside ahriman's home, which can be passed as mount volume.
* ``AHRIMAN_UNIX_SOCKET`` - full path to unix socket which is used by web server, default is empty. Note that more likely you would like to put it inside ``AHRIMAN_REPOSITORY_ROOT`` directory (e.g. ``/var/lib/ahriman/ahriman/ahriman-web.sock``) or to ``/run/ahriman``.
* ``AHRIMAN_USER`` - ahriman user, usually must not be overwritten, default is ``ahriman``.
* ``AHRIMAN_VALIDATE_CONFIGURATION`` - if set (default) validate service configuration.
You can pass any of these variables by using ``-e`` argument, e.g.:
.. code-block:: shell
docker run --privileged -e AHRIMAN_PORT=8080 -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
Daemon service
^^^^^^^^^^^^^^
There is special ``repo-daemon`` subcommand which emulates systemd timer and will perform repository update periodically:
.. code-block:: shell
docker run --privileged -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest repo-daemon
This command uses same rules as ``repo-update``, thus, e.g. requires ``--privileged`` flag. Check also `examples <https://github.com/arcan1s/ahriman/tree/master/recipes/daemon>`__.
Web service setup
^^^^^^^^^^^^^^^^^
For that you would need to have web container instance running forever; it can be achieved by the following command:
.. code-block:: shell
docker run --privileged -p 8080:8080 -e AHRIMAN_PORT=8080 -e AHRIMAN_UNIX_SOCKET=/var/lib/ahriman/ahriman/ahriman-web.sock -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
Note about ``AHRIMAN_PORT`` environment variable which is required in order to enable web service. An additional port bind by ``-p 8080:8080`` is required to pass docker port outside of container.
The ``AHRIMAN_UNIX_SOCKET`` variable is not required, however, highly recommended as it can be used for interprocess communications. If you set this variable you would like to be sure that this path is available outside of container if you are going to use multiple docker instances.
If you are using ``AHRIMAN_UNIX_SOCKET`` variable, for every next container run it has to be passed also, e.g.:
.. code-block:: shell
docker run --privileged -e AHRIMAN_UNIX_SOCKET=/var/lib/ahriman/ahriman/ahriman-web.sock -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
Otherwise, you would need to pass ``AHRIMAN_PORT`` and mount container network to the host system (``--net=host``), e.g.:
.. code-block:: shell
docker run --privileged --net=host -e AHRIMAN_PORT=8080 -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
Simple server with authentication can be found in `examples <https://github.com/arcan1s/ahriman/tree/master/recipes/web>`__ too.
Multi-repository web service
""""""""""""""""""""""""""""
Idea is pretty same as to just run web service. However, it is required to run setup commands for each repository, except for one which is specified by ``AHRIMAN_REPOSITORY`` and ``AHRIMAN_ARCHITECTURE`` variables.
In order to create configuration for additional repositories, the ``AHRIMAN_POSTSETUP_COMMAND`` variable should be used, e.g.:
.. code-block:: shell
docker run --privileged -p 8080:8080 -e AHRIMAN_PORT=8080 -e AHRIMAN_UNIX_SOCKET=/var/lib/ahriman/ahriman/ahriman-web.sock -e AHRIMAN_POSTSETUP_COMMAND="ahriman --architecture x86_64 --repository aur-v2 service-setup --build-as-user ahriman --packager 'ahriman bot <ahriman@example.com>'" -v /path/to/local/repo:/var/lib/ahriman arcan1s/ahriman:latest
The command above will also create configuration for the repository named ``aur-v2``.
Note, however, that the command above is only required in case if the service is going to be used to run subprocesses. Otherwise, everything else (web interface, status, etc) will be handled as usual.
Configuration `example <https://github.com/arcan1s/ahriman/tree/master/recipes/multirepo>`__.

12
docs/faq/examples.rst Normal file
View File

@ -0,0 +1,12 @@
Use cases
---------
There is a collection of some specific recipes which can be found in `the repository <https://github.com/arcan1s/ahriman/tree/master/recipes>`__.
Most of them can be run (``AHRIMAN_PASSWORD`` environment variable is required in the most setups) as simple as:
.. code-block:: shell
AHRIMAN_PASSWORD=demo docker compose up
Note, however, they are just an examples of specific configuration for specific cases and they are never intended to be used as is in real environment.

425
docs/faq/general.rst Normal file
View File

@ -0,0 +1,425 @@
General topics
--------------
What is the purpose of the project
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This project has been created in order to maintain self-hosted Arch Linux user repository without manual intervention - checking for updates and building packages.
How to install ahriman
^^^^^^^^^^^^^^^^^^^^^^
TL;DR
.. code-block:: shell
yay -S ahriman-core
ahriman -a x86_64 -r aur service-setup --packager "ahriman bot <ahriman@example.com>"
systemctl enable --now ahriman@x86_64-aur.timer
Long answer
"""""""""""
The idea is to install the package as usual, create working directory tree, create configuration for ``sudo`` and ``devtools``. Detailed description of the setup instruction can be found :doc:`here </setup>`.
Run as daemon
"""""""""""""
The alternative way (though not recommended) is to run service instead of timer:
.. code-block:: shell
systemctl enable --now ahriman-daemon@x86_64-aur
How to validate settings
^^^^^^^^^^^^^^^^^^^^^^^^
There is special command which can be used in order to validate current configuration:
.. code-block:: shell
ahriman service-config-validate --exit-code
This command will print found errors, based on `cerberus <https://docs.python-cerberus.org/>`__, e.g.:
.. code-block:: shell
auth
ssalt: unknown field
target: none or more than one rule validate
oneof definition 0: unallowed value mapping
oneof definition 1: field 'salt' is required
oneof definition 2: unallowed value mapping
oneof definition 2: field 'salt' is required
oneof definition 2: field 'client_id' is required
oneof definition 2: field 'client_secret' is required
gitremote
pull_url: unknown field
If an additional flag ``--exit-code`` is supplied, the application will return non-zero exit code, which can be used partially in scripts.
What does "architecture specific" mean / How to configure for different architectures
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Some sections can be configured per architecture. The service will merge architecture specific values into common settings. In order to specify settings for specific architecture you must point it in section name.
For example, the section
.. code-block:: ini
[build]
build_command = extra-x86_64-build
states that default build command is ``extra-x86_64-build``. But if there is section
.. code-block:: ini
[build:i686]
build_command = extra-i686-build
the ``extra-i686-build`` command will be used for ``i686`` architecture. You can also override settings for different repositories and architectures; in this case section names will be ``build:aur`` (repository name only) and ``build:aur:i686`` (both repository name and architecture).
How to generate build reports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Normally you would probably like to generate only one report for the specific type, e.g. only one email report. In order to do so you will need to have the following configuration:
.. code-block:: ini
[report]
target = email
[email]
...
or in case of multiple architectures and *different* reporting settings:
.. code-block:: ini
[report]
target = email
[email:i686]
...
[email:x86_64]
...
But for some cases you would like to have multiple different reports with the same type (e.g. sending different templates to different addresses). For these cases you will need to specify section name in target and type in section, e.g. the following configuration can be used:
.. code-block:: ini
[report]
target = email_1 email_2
[email_1]
type = email
...
[email_2]
type = email
...
How to add new package
^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: shell
sudo -u ahriman ahriman package-add ahriman --now
``--now`` flag is totally optional and just run ``repo-update`` subcommand after the registering the new package. Thus the extended flow is the following:
.. code-block:: shell
sudo -u ahriman ahriman package-add ahriman
sudo -u ahriman ahriman repo-update
How to build package from local PKGBUILD
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TL;DR
.. code-block:: shell
sudo -u ahriman ahriman package-add /path/to/local/directory/with/PKGBUILD --now
Before using this command you will need to create local directory and put ``PKGBUILD`` there. These packages will be stored locally and *will be ignored* during automatic update; in order to update the package you will need to run ``package-add`` command again.
How to copy package from another repository
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
It is possible to copy package and its metadata between local repositories, optionally removing the source archive, e.g.:
.. code-block:: shell
sudo -u ahriman ahriman -r target-repository package-copy source-repository ahriman
This feature in particular useful if for managing multiple repositories like ``[testing]`` and ``[extra]``.
How to fetch PKGBUILDs from remote repository
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For that purpose you could use ``RemotePullTrigger`` trigger. To do so you will need to configure trigger as following:
.. code-block:: ini
[remote-pull]
target = gitremote
[gitremote]
pull_url = https://github.com/username/repository
During the next application run it will fetch repository from the specified URL and will try to find packages there which can be used as local sources.
This feature can be also used to build packages which are not listed in AUR, the example of the feature use can be found `here <https://github.com/arcan1s/ahriman/tree/master/recipes/pull>`__.
How to push updated PKGBUILDs to remote repository
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For that purpose you'd need to use another trigger called ``RemotePushTrigger``. Configure trigger as following:
.. code-block:: ini
[remote-push]
target = gitremote
[gitremote]
push_url = https://github.com/username/repository
Unlike ``RemotePullTrigger`` trigger, the ``RemotePushTrigger`` more likely will require authorization. It is highly recommended to use application tokens for that instead of using your password (e.g. for GitHub you can generate tokens `here <https://github.com/settings/tokens>`__ with scope ``public_repo``). Authorization can be supplied by using authorization part of the URL, e.g. ``https://key:token@github.com/username/repository``.
How to change PKGBUILDs before build
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Well it is supported also. The recommended way is to patch specific function, e.g. by running
.. code-block:: shell
sudo -u ahriman ahriman patch-add ahriman version
This command will prompt for new value of the PKGBUILD variable ``version``. You can also write it to file and read from it:
.. code-block:: shell
sudo -u ahriman ahriman patch-add ahriman version version.patch
The command also supports arrays, but in this case you need to specify full array, e.g.
.. code-block:: shell
sudo -u ahriman ahriman patch-add ahriman depends
Post new function or variable value below. Press Ctrl-D to finish:
(python python-aiohttp)
^D
will set depends PKGBUILD variable (exactly) to array ``["python", "python-aiohttp"]``.
Alternatively you can create full-diff patches, which are calculated by using ``git diff`` from current PKGBUILD master branch:
#.
Clone sources from AUR.
#.
Make changes you would like to (e.g. edit ``PKGBUILD``, add external patches).
#.
Run command
.. code-block:: shell
sudo -u ahriman ahriman patch-set-add /path/to/local/directory/with/PKGBUILD
The last command will calculate diff from current tree to the ``HEAD`` and will store it locally. Patches will be applied on any package actions (e.g. it can be used for dependency management).
It is also possible to create simple patch during package addition, e.g.:
.. code-block:: shell
sudo -u ahriman ahriman package-add ahriman --variable PKGEXT=.pkg.tar.xz
The ``--variable`` argument accepts variables in shell like format: quotation and lists are supported as usual, but functions are not. This feature is useful in particular in order to override specific makepkg variables during build.
How to build package from official repository
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
It is the same as adding any other package, but due to restrictions you must specify source explicitly, e.g.:
.. code-block:: shell
sudo -u ahriman ahriman package-add pacman --source repository
This feature is heavily depends on local pacman cache. In order to use this feature it is recommended to either run ``pacman -Sy`` before the interaction or use internal application cache with ``--refresh`` flag.
Package build fails because it cannot validate PGP signature of source files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TL;DR
.. code-block:: shell
sudo -u ahriman ahriman service-key-import ...
How to update VCS packages
^^^^^^^^^^^^^^^^^^^^^^^^^^
Normally the service handles VCS packages correctly. The version is updated in clean chroot, no additional actions are required.
How to review changes before build
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In this scenario, the update process must be separated into several stages. First, it is required to check updates:
.. code-block:: shell
sudo -u ahriman ahriman repo-check
During the check process, the service will generate changes from the last known commit and will send it to remote service. In order to verify source files changes, the web interface or special subcommand can be used:
.. code-block:: shell
ahriman package-changes ahriman
After validation, the operator can run update process with approved list of packages, e.g.:
.. code-block:: shell
sudo -u ahriman ahriman repo-update ahriman
How to remove package
^^^^^^^^^^^^^^^^^^^^^
.. code-block:: shell
sudo -u ahriman ahriman package-remove ahriman
Also, there is command ``repo-remove-unknown`` which checks packages in AUR and local storage and removes ones which have been removed.
Remove commands also remove any package files (patches, caches etc).
How to sign repository
^^^^^^^^^^^^^^^^^^^^^^
Repository sign feature is available in several configurations. The recommended way is just to sign repository database file by single key instead of trying to sign each package. However, the steps are pretty same, just configuration is a bit different. For more details about options kindly refer to :doc:`configuration reference </configuration>`.
#.
First you would need to create the key on your local machine:
.. code-block:: shell
gpg --full-generate-key
This command will prompt you for several questions. Most of them may be left default, but you will need to fill real name and email address with some data. Because at the moment the service doesn't support passphrases, it must be left blank.
#.
The command above will generate key and print its fingerprint, something like ``8BE91E5A773FB48AC05CC1EDBED105AED6246B39``. Copy it.
#.
Export your private key by using the fingerprint above:
.. code-block:: shell
gpg --export-secret-keys -a 8BE91E5A773FB48AC05CC1EDBED105AED6246B39 > repository-key.gpg
#.
Copy the specified key to the build machine (i.e. where the service is running).
#.
Import the specified key to the service user:
.. code-block:: shell
sudo -u ahriman gpg --import repository-key.gpg
Don't forget to remove the key from filesystem after import.
#.
Change trust level to ``ultimate``:
.. code-block:: shell
sudo -u ahriman gpg --edit-key 8BE91E5A773FB48AC05CC1EDBED105AED6246B39
The command above will drop you into gpg shell, in which you will need to type ``trust``, choose ``5 = I trust ultimately``, confirm and exit ``quit``.
#.
Proceed with service configuration according to the :doc:`configuration </configuration>`:
.. code-block:: ini
[sign]
target = repository
key = 8BE91E5A773FB48AC05CC1EDBED105AED6246B39
How to rebuild packages after library update
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TL;DR
.. code-block:: shell
sudo -u ahriman ahriman repo-rebuild --depends-on python
You can even rebuild the whole repository (which is particular useful in case if you would like to change packager) if you do not supply ``--depends-on`` option. This action will automatically increment ``pkgrel`` value; in case if you don't want to, the ``--no-increment`` option has to be supplied.
However, note that you do not need to rebuild repository in case if you just changed signing option, just use ``repo-sign`` command instead.
Automated broken dependencies detection
"""""""""""""""""""""""""""""""""""""""
After the success build the application extracts all linked libraries and used directories and stores them in database. During the check process, the application extracts pacman databases and checks if file names have been changed (e.g. new python release caused ``/usr/lib/python3.x`` directory renaming to ``/usr/lib/python3.y`` or soname for a linked library has been changed). In case if broken dependencies have been detected, the package will be added to the rebuild queue.
In order to disable this check completely, the ``--no-check-files`` flag can be used.
In addition, there is possibility to control paths which will be used for checking, by using option ``${build:scan_paths}``, which supports regular expressions. Leaving ``${build:scan_paths}`` blank will effectively disable any check too.
How to install built packages
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Add the following lines to your ``pacman.conf``:
.. code-block:: ini
[repository]
Server = file:///var/lib/ahriman/repository/$repo/$arch
(You might need to add ``SigLevel`` option according to the pacman documentation.)
How to serve repository
^^^^^^^^^^^^^^^^^^^^^^^
Easy. For example, nginx configuration (without SSL) will look like:
.. code-block::
server {
listen 80;
server_name repo.example.com;
location / {
autoindex on;
root /var/lib/ahriman/repository;
}
}
Example of the status page configuration is the following (status service is using 8080 port):
.. code-block::
server {
listen 80;
server_name builds.example.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarder-Proto $scheme;
proxy_pass http://127.0.0.1:8080;
}
}
Some more examples can be found in configuration `recipes <https://github.com/arcan1s/ahriman/tree/master/recipes>`__.

17
docs/faq/index.rst Normal file
View File

@ -0,0 +1,17 @@
FAQ
===
.. toctree::
:maxdepth: 2
general
docker
non-x86_64-setup
synchronization
reporting
distributed
maintenance-packages
web
backup
examples
misc

View File

@ -0,0 +1,79 @@
Maintenance packages
--------------------
Those features require extensions package to be installed before, e.g.:
.. code-block:: shell
yay -S ahriman-triggers
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-keyring --source local --now
where ``aur`` 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-mirrorlist --source local --now
where ``aur`` is your repository name.

107
docs/faq/misc.rst Normal file
View File

@ -0,0 +1,107 @@
Other topics
------------
How does it differ from %another-manager%?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Short answer - I do not know. Also for some references credits to `Alad <https://github.com/AladW>`__, he `did <https://wiki.archlinux.org/title/User:Alad/Local_repo_tools>`__ really good investigation of existing alternatives.
`arch-repo-manager <https://github.com/Martchus/arch-repo-manager>`__
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Looks actually pretty good, in case if I would find it, I would probably didn't start this project; the most of features (like web interface or additional helpers) are already implemented or planned to be. However, this project seems to be at early alpha stage (as for Nov 2022), written in C++ (not pro or con) and misses documentation.
`archrepo2 <https://github.com/lilydjwg/archrepo2>`__
"""""""""""""""""""""""""""""""""""""""""""""""""""""
Don't know, haven't tried it. But it lacks of documentation at least.
* ``ahriman`` has web interface.
* ``archrepo2`` doesn't have synchronization and reporting.
* ``archrepo2`` actively uses direct shell calls and ``yaourt`` components.
* ``archrepo2`` has constantly running process instead of timer process (it is not pro or con).
`repoctl <https://github.com/cassava/repoctl>`__
""""""""""""""""""""""""""""""""""""""""""""""""
* ``ahriman`` has web interface.
* ``repoctl`` does not have reporting feature.
* ``repoctl`` does not support local packages and patches.
* Some actions are not fully automated in ``repoctl`` (e.g. package update still requires manual intervention for the build itself).
* ``repoctl`` has better AUR interaction features. With colors!
* ``repoctl`` has much easier configuration and even completion.
* ``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>`__
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Though originally I've created ahriman by trying to improve the project, it still lacks a lot of features:
* ``ahriman`` has web interface.
* ``ahriman`` has better reporting with template support.
* ``ahriman`` has more synchronization features (there was only ``rsync`` based).
* ``ahriman`` supports local packages and patches.
* ``repo-scripts`` doesn't have dependency management.
...and so on. ``repo-scripts`` also has bad architecture and bad quality code and uses out-of-dated ``yaourt`` and ``package-query``.
`toolbox <https://github.com/chaotic-aur/toolbox>`__
""""""""""""""""""""""""""""""""""""""""""""""""""""
It is automation tools for ``repoctl`` mentioned above. Except for using shell it looks pretty cool and also offers some additional features like patches, remote synchronization (isn't it?) and reporting.
`AURCache <https://github.com/Lukas-Heiligenbrunner/AURCache>`__
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
That's really cool project if you are looking for simple service to build AUR packages. It provides very informative dashboard and easy to configure and use. However, it doesn't provide direct way to control build process (e.g. it is neither trivial to build packages for architectures which are not supported by default nor to change build flags).
Also this application relies on docker setup (e.g. builders are only available as special docker containers). In addition, it uses ``paru`` to build packages instead of ``devtools``.
How to check service logs
^^^^^^^^^^^^^^^^^^^^^^^^^
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
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).
Html customization
^^^^^^^^^^^^^^^^^^
It is possible to customize html templates. In order to do so, create files somewhere (refer to Jinja2 documentation and the service source code for available parameters) and prepend ``templates`` with value pointing to this directory.
In addition, default html templates supports style customization out-of-box. In order to customize style, just put file named ``user-style.jinja2`` to the templates directory.
Web API extension
^^^^^^^^^^^^^^^^^
The application loads web views dynamically, so it is possible relatively easy extend its API. In order to do so:
#. Create view class which is derived from ``ahriman.web.views.base.BaseView`` class.
#. Create implementation for this class.
#. Put file into ``ahriman.web.views`` package.
#. Restart application.
For more details about implementation and possibilities, kindly refer to module documentation and source code and `aiohttp documentation <https://docs.aiohttp.org/en/stable/>`__.
I did not find my question
^^^^^^^^^^^^^^^^^^^^^^^^^^
`Create an issue <https://github.com/arcan1s/ahriman/issues>`__ with type **Question**.

View File

@ -0,0 +1,99 @@
Non-x86_64 architecture setup
-----------------------------
The following section describes how to setup ahriman with architecture different from x86_64, as example i686. For most cases you have base repository available, e.g. archlinux32 repositories for i686 architecture; in case if base repository is not available, steps are a bit different, however, idea remains the same.
The example of setup with docker compose can be found `here <https://github.com/arcan1s/ahriman/tree/master/recipes/i686>`__.
Physical server setup
^^^^^^^^^^^^^^^^^^^^^
In this example we are going to use files and packages which are provided by official repositories of the used architecture. Note, that versions might be different, thus you need to find correct versions on the distribution web site, e.g. `archlinux32 packages <https://www.archlinux32.org/packages/>`__.
#.
First, considering having base Arch Linux system, we need to install keyring for the specified repositories, e.g.:
.. code-block:: shell
wget https://pool.mirror.archlinux32.org/i686/core/archlinux32-keyring-20230705-1.0-any.pkg.tar.zst
pacman -U archlinux32-keyring-20230705-1.0-any.pkg.tar.zst
#.
In order to run ``devtools`` scripts for custom architecture they also need specific ``makepkg`` configuration, it can be retrieved by installing the ``devtools`` package of the distribution, e.g.:
.. code-block:: shell
wget https://pool.mirror.archlinux32.org/i686/extra/devtools-20221208-1.2-any.pkg.tar.zst
pacman -U devtools-20221208-1.2-any.pkg.tar.zst
Alternatively, you can create your own ``makepkg`` configuration and save it as ``/usr/share/devtools/makepkg.conf.d/i686.conf``.
#.
Setup repository as usual:
.. code-block:: shell
ahriman -a i686 service-setup --mirror 'https://de.mirror.archlinux32.org/$arch/$repo'--no-multilib ...
In addition to usual options, you need to specify the following options:
* ``--mirror`` - link to the mirrors which will be used instead of official repositories.
* ``--no-multilib`` - in the example we are using i686 architecture for which multilib repository doesn't exist.
#.
That's all Folks!
Docker container setup
^^^^^^^^^^^^^^^^^^^^^^
There are two possible ways to achieve same setup, by using docker container. The first one is just mount required files inside container and run it as usual (with specific environment variables). Another one is to create own container based on official one:
#.
Clone official container as base:
.. code-block:: dockerfile
FROM arcan1s/ahriman:latest
#.
Init pacman keys. This command is required in order to populate distribution keys:
.. code-block:: dockerfile
RUN pacman-key --init
#.
Install packages as it was described above:
.. code-block:: dockerfile
RUN pacman --noconfirm -Sy wget
RUN wget https://pool.mirror.archlinux32.org/i686/extra/devtools-20221208-1.2-any.pkg.tar.zst && pacman --noconfirm -U devtools-20221208-1.2-any.pkg.tar.zst
RUN wget https://pool.mirror.archlinux32.org/i686/core/archlinux32-keyring-20230705-1.0-any.pkg.tar.zst && pacman --noconfirm -U archlinux32-keyring-20230705-1.0-any.pkg.tar.zst
#.
At that point you should have full ``Dockerfile`` like:
.. code-block:: dockerfile
FROM arcan1s/ahriman:latest
RUN pacman-key --init
RUN pacman --noconfirm -Sy wget
RUN wget https://pool.mirror.archlinux32.org/i686/extra/devtools-20221208-1.2-any.pkg.tar.zst && pacman --noconfirm -U devtools-20221208-1.2-any.pkg.tar.zst
RUN wget https://pool.mirror.archlinux32.org/i686/core/archlinux32-keyring-20230705-1.0-any.pkg.tar.zst && pacman --noconfirm -U archlinux32-keyring-20230705-1.0-any.pkg.tar.zst
#.
After that you can build you own container, e.g.:
.. code-block:: shell
docker build --tag ahriman-i686:latest
#.
Now you can run locally built container as usual with passing environment variables for setup command:
.. code-block:: shell
docker run --privileged -p 8080:8080 -e AHRIMAN_ARCHITECTURE=i686 -e AHRIMAN_PACMAN_MIRROR='https://de.mirror.archlinux32.org/$arch/$repo' -e AHRIMAN_MULTILIB= ahriman-i686:latest

119
docs/faq/reporting.rst Normal file
View File

@ -0,0 +1,119 @@
Reporting
---------
How to report by email
^^^^^^^^^^^^^^^^^^^^^^
#.
Install dependencies:
.. code-block:: shell
yay -S --asdeps python-jinja
#.
Configure the service:
.. code-block:: ini
[report]
target = email
[email]
host = smtp.example.com
link_path = http://example.com/aur/x86_64
password = ...
port = 465
receivers = me@example.com
sender = me@example.com
user = me@example.com
How to generate index page
^^^^^^^^^^^^^^^^^^^^^^^^^^
#.
Install dependencies:
.. code-block:: shell
yay -S --asdeps python-jinja
#.
Configure the service:
.. code-block:: ini
[report]
target = html
[html]
path = ${repository:root}/repository/aur/x86_64/index.html
link_path = http://example.com/aur/x86_64
Having this configuration, the generated ``index.html`` will be also automatically synced to remote services (e.g. S3).
How to generate RSS feed for index page
"""""""""""""""""""""""""""""""""""""""
In addition to previous steps, the following configuration is required:
.. code-block:: ini
[report]
target = html rss
[html]
rss_url = ${html:link_path}/rss.xml
[rss]
link_path = ${html:link_path}
path = ${repository:root}/repository/ahriman-demo/x86_64/rss.xml
rss_url = ${html:link_path}/rss.xml
With the appended configuration, the service fill also generate ``rss.xml``, link it to generated ``index.html`` and put it together.
How to post build report to telegram
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#.
It still requires additional dependencies:
.. code-block:: shell
yay -S --asdeps python-jinja
#.
Register bot in telegram. You can do it by starting chat with `@BotFather <https://t.me/botfather>`__. For more details please refer to `official documentation <https://core.telegram.org/bots>`__.
#.
Optionally (if you want to post message in chat):
#. Create telegram channel.
#. Invite your bot into the channel.
#. Make your channel public
#.
Get chat id if you want to use by numerical id or just use id prefixed with ``@`` (e.g. ``@ahriman``). If you are not using chat the chat id is your user id. If you don't want to make channel public you can use `this guide <https://stackoverflow.com/a/33862907>`__.
#.
Configure the service:
.. code-block:: ini
[report]
target = telegram
[telegram]
api_key = aaAAbbBBccCC
chat_id = @ahriman
link_path = http://example.com/aur/x86_64
``${api_key}`` is the one sent by `@BotFather <https://t.me/botfather>`__, ``${chat_id}`` is the value retrieved from previous step.
If you did everything fine you should receive the message with the next update. Quick credentials check can be done by using the following command:
.. code-block:: shell
curl 'https://api.telegram.org/bot${api_key}/sendMessage?chat_id=${chat_id}&text=hello'
(replace ``${chat_id}`` and ``${api_key}`` with the values from configuration).

View File

@ -0,0 +1,131 @@
Remote synchronization
----------------------
How to sync repository to another server
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are several choices:
#.
Easy and cheap, just share your local files through the internet, e.g. for ``nginx``:
.. code-block::
server {
location / {
autoindex on;
root /var/lib/ahriman/repository/;
}
}
#.
You can also upload your packages using ``rsync`` to any available server. In order to use it you would need to configure ahriman first:
.. code-block:: ini
[upload]
target = rsync
[rsync]
remote = 192.168.0.1:/srv/repo
After that just add ``/srv/repo`` to the ``pacman.conf`` as usual. You can also upload to S3 (``Server = https://s3.eu-central-1.amazonaws.com/repository/aur/x86_64``) or to GitHub (``Server = https://github.com/ahriman/repository/releases/download/aur-x86_64``).
How to sync to S3
^^^^^^^^^^^^^^^^^
#.
Install dependencies:
.. code-block:: shell
pacman -S python-boto3
#.
Create a bucket (e.g. ``repository``).
#.
Create an user with write access to the bucket:
.. code-block::
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListObjectsInBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::repository"
]
},
{
"Sid": "AllObjectActions",
"Effect": "Allow",
"Action": "s3:*Object",
"Resource": [
"arn:aws:s3:::repository/*"
]
}
]
}
#.
Create an API key for the user and store it.
#.
Configure the service as following:
.. code-block:: ini
[upload]
target = s3
[s3]
access_key = ...
bucket = repository
region = eu-central-1
secret_key = ...
S3 with SSL
"""""""""""
In order to configure S3 on custom domain with SSL (and some other features, like redirects), the CloudFront should be used.
#. Configure S3 as described above.
#. In bucket properties, enable static website hosting with hosting type "Host a static website".
#. Go to AWS Certificate Manager and create public certificate on your domain. Validate domain as suggested.
#. Go to CloudFront and create distribution. The following settings are required:
* Origin domain choose S3 bucket.
* Tick use website endpoint.
* Disable caching.
* Select issued certificate.
#. Point DNS record to CloudFront address.
How to sync to GitHub releases
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#.
Create a repository.
#.
`Create API key <https://github.com/settings/tokens>`__ with scope ``public_repo``.
#.
Configure the service as following:
.. code-block:: ini
[upload]
target = github
[github]
owner = ahriman
password = ...
repository = repository
username = ahriman

145
docs/faq/web.rst Normal file
View File

@ -0,0 +1,145 @@
Web service
-----------
How to setup web service
^^^^^^^^^^^^^^^^^^^^^^^^
#.
Install web service:
.. code-block:: shell
yay -S ahriman-web
#.
Configure service:
.. code-block:: ini
[web]
port = 8080
#.
Start the web service ``systemctl enable --now ahriman-web``.
How to enable basic authorization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#.
Install dependencies 😊:
.. code-block:: shell
yay -S --asdeps python-aiohttp-security python-aiohttp-session python-cryptography
#.
Configure the service to enable authorization:
.. code-block:: ini
[auth]
target = configuration
salt = somerandomstring
The ``${auth:salt}`` parameter is optional, but recommended, and can be set to any (random) string.
#.
In order to provide access for reporting from application instances you can (the recommended way) use unix sockets by the following configuration (note, that it requires ``python-requests-unixsocket2`` package to be installed):
.. code-block:: ini
[web]
unix_socket = /run/ahriman/ahriman-web.sock
This socket path must be available for web service instance and must be available for all application instances (e.g. in case if you are using docker container - see above - you need to make sure that the socket is passed to the root filesystem).
By the way, unix socket variable will be automatically set in case if ``--web-unix-socket`` argument is supplied to the ``service-setup`` subcommand.
Alternatively, you need to create user for the service:
.. code-block:: shell
sudo -u ahriman ahriman user-add -r full api
This command will ask for the password, just type it in stdin; **do not** leave the field blank, user will not be able to authorize, and finally configure the application:
.. code-block:: ini
[status]
username = api
password = pa55w0rd
#.
Create end-user with password:
.. code-block:: shell
sudo -u ahriman ahriman user-add -r full my-first-user
#.
Restart web service ``systemctl restart ahriman-web``.
Using PAM authentication
""""""""""""""""""""""""
There is also ability to allow system users to log in. To do so, the following configuration have to be set:
.. code-block:: ini
[auth]
target = pam
full_access_group = wheel
With this setup, every user (except root) will be able to log in by using system password. If user belongs to the ``wheel`` group, the full access will be automatically granted. It is also possible to manually add, block user or change user rights via usual user management process.
How to enable OAuth authorization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#.
Create OAuth web application, download its ``${auth:client_id}`` and ``${auth:client_secret}``.
#.
Guess what? Install dependencies:
.. code-block:: shell
yay -S --asdeps python-aiohttp-security python-aiohttp-session python-cryptography python-aioauth-client
#.
Configure the service:
.. code-block:: ini
[auth]
target = oauth
client_id = ...
client_secret = ...
[web]
address = https://example.com
Configure ``${auth:oauth_provider}`` and ``${auth: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.
#.
If you are not going to use unix socket, you also need to create service user (remember to set ``${auth:salt}`` option before if required):
.. code-block:: shell
sudo -u ahriman ahriman user-add --as-service -r full api
#.
Create end-user:
.. code-block:: shell
sudo -u ahriman ahriman user-add -r full my-first-user
When it will ask for the password leave it blank.
#.
Restart web service ``systemctl restart ahriman-web``.
How to implement own interface
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You can write your own interface by using API which is provided by the web service. Full autogenerated API documentation is available at ``http://localhost:8080/api-docs``.

View File

@ -1,27 +1,28 @@
Welcome to ahriman's documentation!
===================================
Wrapper for managing custom repository inspired by `repo-scripts <https://github.com/arcan1s/repo-scripts>`_.
Wrapper for managing custom repository inspired by `repo-scripts <https://github.com/arcan1s/repo-scripts>`__.
Features
--------
* Install-configure-forget manager for the very own repository.
* Multi-architecture support.
* Multi architecture and repository support.
* Dependency manager.
* 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).
* Triggers for repository updates, e.g. synchronization to remote services (rsync, s3 and github) and report generation (email, html, telegram).
* Various rebuild options with ability to automatically bump package version.
* 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.
Live demos
----------
* `Build status page <https://ahriman-demo.arcanis.me>`_. You can login as ``demo`` user by using ``demo`` password. Note, however, you will not be able to run tasks. `HTTP API documentation <https://ahriman-demo.arcanis.me/api-docs>`_ is also available.
* `Repository index <http://repo.arcanis.me/x86_64/index.html>`_.
* `Telegram feed <https://t.me/arcanisrepo>`_.
* `Build status page <https://ahriman-demo.arcanis.me>`__. You can login as ``demo`` user by using ``demo`` password. Note, however, you will not be able to run tasks. `HTTP API documentation <https://ahriman-demo.arcanis.me/api-docs>`__ is also available.
* `Repository index <https://repo.arcanis.me/x86_64/index.html>`__.
* `Telegram feed <https://t.me/arcanisrepo>`__.
Contents
--------
@ -32,8 +33,9 @@ Contents
setup
configuration
command-line
faq
faq/index
migrations/index
architecture
advanced-usage
advanced-usage/index
triggers
modules

View File

@ -0,0 +1,46 @@
To 2.12.0
---------
This release includes paths migration. Unlike usual case, no automatic migration is performed because it might break user configuration. The following noticeable changes have been made:
* Path to pre-built packages now includes repository name, i.e. it has been changed from ``/var/lib/ahriman/packages/x86_64`` to ``/var/lib/ahriman/packages/aur/x86_64``.
* Path to pacman databases now includes repository name too, it has been changed from ``/var/lib/ahriman/pacman/x86_64`` to ``/var/lib/ahriman/pacman/aur/x86_64``.
* Path to repository itself also includes repository name, from ``/var/lib/ahriman/repository/x86_64`` to ``/var/lib/ahriman/repository/aur/x86_64``.
In order to migrate to the new filesystem tree the following actions are required:
#.
Stop and disable all services, e.g. timer and web service:
.. code-block:: shell
sudo systemctl disable --now ahriman@x86_64.timer
sudo systemctl disable --now ahriman-web@x86_64
#.
Create directory tree. It can be done by running ``ahriman service-tree-migrate`` subcommand. It performs copying between the old repository tree and the new one. Alternatively directories can be copied by hands.
#.
Edit configuration in case if anything is pointing to the old path, e.g. HTML report generation, in the way in which it will point to the directory inside repository specific one, e.g. ``/var/lib/ahriman/repository/x86_64`` to ``/var/lib/ahriman/repository/aur/x86_64``.
#.
Run setup command (i.e. ``ahriman service-setup``) again with the same arguments as used before. This step can be done manually by editing devtools pacman configuration (``/usr/share/devtools/pacman.conf.d/ahriman-x86_64.conf`` by default) replacing ``Server`` with path to the repository, e.g.:
.. code-block:: ini
[aur]
SigLevel = Optional TrustAll
Server = file:///var/lib/ahriman/repository/aur/x86_64
In case of manual interventions make sure to remove architecture reference from ``web`` sections (if any) to avoid ambiguity.
#.
Make sure to update remote synchronization services if any. Almost all of them rely on current repository tree by default, so it is required to setup either redirects or configure to synchronize to the old locations (e.g. ``object_path`` option for S3 synchronization).
#.
Enable and start services again. Unit template parameter should include both repository architecture and name, dash separated, e.g. ``x86_64-aur``, where ``x86_64`` is the repository architecture and ``aur`` is the repository name:
.. code-block:: shell
sudo systemctl enable --now ahriman@x86_64-aur.timer
sudo systemctl enable --now ahriman-web

View File

@ -0,0 +1,16 @@
To 2.16.0
---------
This release replaces ``passlib`` dependency with ``bcrypt``.
The reason behind this change is that python developers have deprecated and scheduled for removal ``crypt`` module, which is used by ``passlib``. (By the way, they recommend to use ``passlib`` as a replacement.) Unfortunately, it appears that ``passlib`` is unmaintained (see `the issue <https://foss.heptapod.net/python-libs/passlib/-/issues/187>`__), so the only solution is to migrate to another library.
Because passwords are stored as hashes, it is near to impossible to shadow change passwords in database, the manual intervention is required if:
#. Authentication is used.
#. Notification provider is ``configuration`` or a user with explicitly set password exists.
Manual steps might look as:
#. Get list of users with their roles ``ahriman user-list``.
#. For each user run update command, i.e. ``ahriman user-add <username> -R <role>``. Type password when it will be requested.

11
docs/migrations/2.9.0.rst Normal file
View File

@ -0,0 +1,11 @@
To 2.9.0
--------
This release includes major upgrade for the newest devtools and archlinux repository structure. In order to upgrade package need to:
#. Upgrade to the latest major release of python (3.11) (required by other changes).
#. Upgrade devtools to the latest release.
#. Backup local settings, ``/etc/ahriman.ini.d/00-setup-overrides.ini`` by default.
#. Run setup command (i.e. ``ahriman service-setup``) again with the same arguments as used before. This step can be done manually by moving ``devtools`` configuration (something like ``/usr/share/devtools/pacman-ahriman*.conf``) to new location ``/usr/share/devtools/pacman.conf.d/`` under name ``ahriman.conf``. After that make sure to remove any ``community`` mentions from configurations (e.g. ``/usr/share/devtools/pacman.conf.d/ahriman.conf``, ``/etc/ahriman.ini``) if there were any. The only thing which will change is ``devtools`` configuration.
#. Remove build chroot as it is incompatible, e.g. ``sudo ahriman service-clean --chroot``.
#. Run ``sudo -u ahriman ahriman update --no-aur --no-local --no-manual -yy`` in order to update local databases.

14
docs/migrations/index.rst Normal file
View File

@ -0,0 +1,14 @@
Manual migrations
=================
Normally the most of migrations are handled automatically after application start, however, some upgrades require manual interventions; this document describes them.
Upgrades to breakpoints
-----------------------
.. toctree::
:maxdepth: 2
2.9.0
2.12.0
2.16.0

View File

@ -2,7 +2,7 @@ Initial setup
=============
#.
Install package as usual.
Install package(s) as usual. At least, ``ahriman-core`` package is required; other features can be installed separately. Alternatively, it is possible to install meta-package, which includes everything.
#.
Change settings if required, see :doc:`configuration reference <configuration>` for more details.
#.
@ -10,45 +10,48 @@ Initial setup
.. code-block:: shell
sudo ahriman -a x86_64 service-setup ...
sudo ahriman -a x86_64 -r aur service-setup ...
``service-setup`` literally does the following steps:
.. admonition:: Details
:collapsible: closed
#.
Create ``/var/lib/ahriman/.makepkg.conf`` with ``makepkg.conf`` overrides if required (at least you might want to set ``PACKAGER``):
``service-setup`` literally does the following steps:
.. code-block:: shell
#.
Create ``/var/lib/ahriman/.makepkg.conf`` with ``makepkg.conf`` overrides if required (at least you might want to set ``PACKAGER``):
echo 'PACKAGER="John Doe <john@doe.com>"' | sudo -u ahriman tee -a /var/lib/ahriman/.makepkg.conf
.. code-block:: shell
#.
Configure build tools (it is required for correct dependency management system):
echo 'PACKAGER="ahriman bot <ahriman@example.com>"' | sudo -u ahriman tee -a /var/lib/ahriman/.makepkg.conf
#.
#.
Configure build tools (it is required for correct dependency management system):
#.
Create build command (you can choose any name for command, basically it should be ``{name}-{arch}-build``):
.. code-block:: shell
ln -s /usr/bin/archbuild /usr/local/bin/ahriman-x86_64-build
ln -s /usr/bin/archbuild /usr/local/bin/aur-x86_64-build
#.
Create configuration file (same as previous ``{name}.conf``):
.. code-block:: shell
cp /usr/share/devtools/pacman.conf.d/{extra,ahriman}.conf
cp /usr/share/devtools/pacman.conf.d/{extra,aur}.conf
#.
Change configuration file, add your own repository, add multilib repository etc:
.. 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.conf.d/ahriman.conf
echo '[multilib]' | tee -a /usr/share/devtools/pacman.conf.d/aur-x86_64.conf
echo 'Include = /etc/pacman.d/mirrorlist' | tee -a /usr/share/devtools/pacman.conf.d/aur-x86_64.conf
echo '[aur-clone]' | 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
echo '[aur]' | tee -a /usr/share/devtools/pacman.conf.d/aur-x86_64.conf
echo 'SigLevel = Optional TrustAll' | tee -a /usr/share/devtools/pacman.conf.d/aur-x86_64.conf
echo 'Server = file:///var/lib/ahriman/repository/$repo/$arch' | tee -a /usr/share/devtools/pacman.conf.d/aur-x86_64.conf
#.
Set ``build_command`` option to point to your command:
@ -56,38 +59,38 @@ Initial setup
.. code-block:: shell
echo '[build]' | tee -a /etc/ahriman.ini.d/build.ini
echo 'build_command = ahriman-x86_64-build' | tee -a /etc/ahriman.ini.d/build.ini
echo 'build_command = aur-x86_64-build' | tee -a /etc/ahriman.ini.d/build.ini
#.
Configure ``/etc/sudoers.d/ahriman`` to allow running command without a password:
.. 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 'Cmnd_Alias CARCHBUILD_CMD = /usr/local/bin/aur-x86_64-build *' | 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.
This command supports several arguments, kindly refer to its help message.
#.
Start and enable ``ahriman@.timer`` via ``systemctl``:
.. code-block:: shell
systemctl enable --now ahriman@x86_64.timer
systemctl enable --now ahriman@x86_64-aur.timer
#.
Start and enable status page:
.. code-block:: shell
systemctl enable --now ahriman-web@x86_64
systemctl enable --now ahriman-web
#.
Add packages by using ``ahriman package-add {package}`` command:
.. code-block:: shell
sudo -u ahriman ahriman -a x86_64 package-add ahriman --now --refresh
sudo -u ahriman ahriman package-add ahriman --now --refresh
The ``--refresh`` flag is required in order to handle local database update.

View File

@ -1,7 +1,7 @@
Triggers
========
The package provides ability to write custom extensions which will be run on (the most) actions, e.g. after updates. By default ahriman provides three types of extensions - reporting, files uploading and PKGBUILD syncronization. Each extension must derive from the ``ahriman.core.triggers.Trigger`` class and should implement at least one of the abstract methods:
The package provides ability to write custom extensions which will be run on (the most) actions, e.g. after updates. By default ahriman provides three types of extensions - reporting, files uploading and PKGBUILD synchronization. Each extension must derive from the ``ahriman.core.triggers.Trigger`` class and should implement at least one of the abstract methods:
* ``on_result`` - trigger action which will be called after build process, the build result and the list of repository packages will be supplied as arguments.
* ``on_start`` - trigger action which will be called right before the start of the application process.
@ -14,6 +14,16 @@ Built-in triggers
For the configuration details and settings explanation kindly refer to the :doc:`documentation <configuration>`.
``ahriman.core.distributed.WorkerLoaderTrigger``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Special trigger to be used to load workers from database on the start of the application rather than configuration. If the option is already set, it will skip processing.
``ahriman.core.distributed.WorkerTrigger``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Another trigger for the distributed system, which registers itself as remote worker, calling remote service periodically.
``ahriman.core.gitremote.RemotePullTrigger``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -31,6 +41,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,9 +93,9 @@ 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``).
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``).
As it has been mentioned, our trigger must derive from specific class:
@ -85,8 +105,8 @@ As it has been mentioned, our trigger must derive from specific class:
class SlackReporter(Trigger):
def __init__(self, architecture, configuration):
Trigger.__init__(self, architecture, configuration)
def __init__(self, repository_id, configuration):
Trigger.__init__(self, repository_id, configuration)
self.slack_url = configuration.get("slack", "url")
self.channel = configuration.get("slack", "channel")
self.username = configuration.get("slack", "username")
@ -110,8 +130,8 @@ Obviously you can implement the specified method in class, but for guide purpose
class SlackReporter(Trigger):
def __init__(self, architecture, configuration):
Trigger.__init__(self, architecture, configuration)
def __init__(self, repository_id, configuration):
Trigger.__init__(self, repository_id, configuration)
self.slack_url = configuration.get("slack", "url")
self.channel = configuration.get("slack", "channel")
self.username = configuration.get("slack", "username")
@ -122,11 +142,11 @@ Obviously you can implement the specified method in class, but for guide purpose
Setup the trigger
^^^^^^^^^^^^^^^^^
First, put the trigger in any path it can be exported, e.g. by packing the resource into python package (which will lead to import path as ``package.slack_reporter.SlackReporter``) or just put file somewhere it can be accessed by application (e.g. ``/usr/local/lib/slack_reporter.py.SlackReporter``).
First, put the trigger in any path it can be exported, e.g. by packing the resource into python package (which will lead to import path as ``package.slack_reporter.SlackReporter``) or just put file somewhere it can be accessed by application (e.g. ``/usr/local/lib/slack_reporter.SlackReporter``).
After that run application as usual and receive notification in your slack channel.
Trigger configuration schema
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Triggers can expose their configuration schema. It can be achieved by implementing ``CONFIGURATION_SCHEMA`` class variable according to `cerberus <https://docs.python-cerberus.org/>`_ documentation. For more details and examples, please refer to built-in triggers implementations.
Triggers can expose their configuration schema. It can be achieved by implementing ``CONFIGURATION_SCHEMA`` class variable according to `cerberus <https://docs.python-cerberus.org/>`__ documentation. For more details and examples, please refer to built-in triggers implementations.

BIN
github-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -1,57 +1,89 @@
# Maintainer: Evgeniy Alekseev
pkgname='ahriman'
pkgver=2.9.0
pkgbase='ahriman'
pkgname=('ahriman' 'ahriman-core' 'ahriman-triggers' 'ahriman-web')
pkgver=2.17.1
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')
makedepends=('python-build' 'python-installer' 'python-wheel')
optdepends=('breezy: -bzr packages support'
'darcs: -darcs packages support'
'mercurial: -hg packages support'
'python-aioauth-client: web server with OAuth2 authorization'
'python-aiohttp: web server'
'python-aiohttp-apispec>=3.0.0: web server'
'python-aiohttp-cors: web server'
'python-aiohttp-debugtoolbar: web server with enabled debug panel'
'python-aiohttp-jinja2: web server'
'python-aiohttp-security: web server with authorization'
'python-aiohttp-session: web server with authorization'
'python-boto3: sync to s3'
'python-cryptography: web server with authorization'
'python-requests-unixsocket: client report to web server by unix socket'
'python-jinja: html report generation'
'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')
backup=('etc/ahriman.ini'
'etc/ahriman.ini.d/logging.ini')
url="https://ahriman.readthedocs.io/"
license=('GPL-3.0-or-later')
depends=('devtools>=1:1.0.0' 'git' 'pyalpm' 'python-bcrypt' 'python-inflection' 'python-pyelftools' 'python-requests')
makedepends=('python-build' 'python-flit' 'python-installer' 'python-wheel')
source=("https://github.com/arcan1s/ahriman/releases/download/$pkgver/$pkgbase-$pkgver.tar.gz"
"$pkgbase.sysusers"
"$pkgbase.tmpfiles")
build() {
cd "$pkgname"
cd "$pkgbase-$pkgver"
python -m build --wheel --no-isolation
python -m build --wheel --no-isolation
}
package() {
cd "$pkgname"
python -m installer --destdir="$pkgdir" "dist/$pkgname-$pkgver-py3-none-any.whl"
# python-installer actually thinks that you cannot just copy files to root
# thus we need to copy them manually
install -Dm644 "$pkgdir/usr/share/$pkgname/settings/ahriman.ini" "$pkgdir/etc/ahriman.ini"
install -Dm644 "$pkgdir/usr/share/$pkgname/settings/ahriman.ini.d/logging.ini" "$pkgdir/etc/ahriman.ini.d/logging.ini"
install -Dm644 "$srcdir/$pkgname.sysusers" "$pkgdir/usr/lib/sysusers.d/$pkgname.conf"
install -Dm644 "$srcdir/$pkgname.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/$pkgname.conf"
package_ahriman() {
pkgname='ahriman'
pkgdesc="ArcH linux ReposItory MANager (meta package)"
depends=("$pkgbase-core=$pkgver" "$pkgbase-triggers=$pkgver" "$pkgbase-web=$pkgver")
}
sha512sums=('112b0d8aac68e5330bbdd2b86a59c8a9af8ab7a7c636489623c8460bb90f1318585851edd2a97a8ce20e2d2ad93b847b522685df707c190aa39d23ab908fa8ef'
'53d37efec812afebf86281716259f9ea78a307b83897166c72777251c3eebcb587ecee375d907514781fb2a5c808cbb24ef9f3f244f12740155d0603bf213131'
'62b2eccc352d33853ef243c9cddd63663014aa97b87242f1b5bc5099a7dbd69ff3821f24ffc58e1b7f2387bd4e9e9712cc4c67f661b1724ad99cdf09b3717794')
package_ahriman-core() {
pkgname='ahriman-core'
optdepends=('ahriman-triggers: additional extensions for the application'
'ahriman-web: web server'
'ipython: an enhanced shell interpreter'
'python-boto3: sync to s3'
'python-cerberus: configuration validator'
'python-matplotlib: usage statistics chart'
'python-requests-unixsocket2: client report to web server by unix socket'
'python-jinja: html report generation'
'python-systemd: journal support'
'rsync: sync by using rsync')
install="$pkgbase.install"
backup=('etc/ahriman.ini'
'etc/ahriman.ini.d/logging.ini')
cd "$pkgbase-$pkgver"
python -m installer --destdir="$pkgdir" "dist/$pkgbase-$pkgver-py3-none-any.whl"
python subpackages.py "$pkgdir" "$pkgname"
# keep usr/share configs as reference and copy them to /etc
install -Dm644 "$pkgdir/usr/share/$pkgbase/settings/ahriman.ini" "$pkgdir/etc/ahriman.ini"
install -Dm644 "$pkgdir/usr/share/$pkgbase/settings/ahriman.ini.d/logging.ini" "$pkgdir/etc/ahriman.ini.d/logging.ini"
install -Dm644 "$srcdir/$pkgbase.sysusers" "$pkgdir/usr/lib/sysusers.d/$pkgbase.conf"
install -Dm644 "$srcdir/$pkgbase.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/$pkgbase.conf"
}
package_ahriman-triggers() {
pkgname='ahriman-triggers'
pkgdesc="ArcH linux ReposItory MANager, additional extensions"
depends=("$pkgbase-core=$pkgver")
backup=('etc/ahriman.ini.d/00-triggers.ini')
cd "$pkgbase-$pkgver"
python -m installer --destdir="$pkgdir" "dist/$pkgbase-$pkgver-py3-none-any.whl"
python subpackages.py "$pkgdir" "$pkgname"
install -Dm644 "$pkgdir/usr/share/$pkgbase/settings/ahriman.ini.d/00-triggers.ini" "$pkgdir/etc/ahriman.ini.d/00-triggers.ini"
}
package_ahriman-web() {
pkgname='ahriman-web'
pkgdesc="ArcH linux ReposItory MANager, web server"
depends=("$pkgbase-core=$pkgver" 'python-aiohttp-cors' 'python-aiohttp-jinja2')
optdepends=('python-aioauth-client: OAuth2 authorization support'
'python-aiohttp-apispec>=3.0.0: autogenerated API documentation'
'python-aiohttp-security: authorization support'
'python-aiohttp-session: authorization support'
'python-cryptography: authorization support')
backup=('etc/ahriman.ini.d/00-web.ini')
cd "$pkgbase-$pkgver"
python -m installer --destdir="$pkgdir" "dist/$pkgbase-$pkgver-py3-none-any.whl"
python subpackages.py "$pkgdir" "$pkgname"
install -Dm644 "$pkgdir/usr/share/$pkgbase/settings/ahriman.ini.d/00-web.ini" "$pkgdir/etc/ahriman.ini.d/00-web.ini"
}

View File

@ -0,0 +1,53 @@
post_upgrade() {
local breakpoints=(
2.9.0-1
2.12.0-1
2.16.0-1
)
for v in "${breakpoints[@]}"; do
if [[ $(vercmp "$v" "$2") -ne "-1" ]]; then
"_${v//[.-]/_}_changes"
fi
done
}
_2_9_0_1_changes() {
cat << EOF
It was found that there was an upgrade from old devtools package to the new one, which requires manual intervention:
* make sure that devtools are upgraded to the latest release;
* merge upstream configuration into local configuration (e.g. by using pacdiff);
* run setup command (i.e. ahriman service-setup) with the same arguments as did before;
* remove build chroot, e.g.: ahriman service-clean --chroot;
* update local databases: ahriman update --no-aur --no-local --no-manual -yy.
For more information kindly refer to migration notes https://ahriman.readthedocs.io/en/stable/migrations/2.9.0.html.
EOF
}
_2_12_0_1_changes() {
cat << EOF
Whereas old local tree is still supported it is highly recommended to migrate to the new one:
* stop and disable all services;
* run service-tree-migrate as ahriman user;
* edit local configuration to avoid pointing to the old paths;
* run setup command (i.e. ahriman service-setup) with the same arguments as did before;
* update remote services in order to support new paths (or setup redirects) if any;
* enable web and timer services again by using x86_64-aur suffix,
where x86_64 is the repository architecture and aur is the repository name.
For more information kindly refer to migration notes https://ahriman.readthedocs.io/en/stable/migrations/2.12.0.html.
EOF
}
_2_16_0_1_changes() {
cat << EOF
In order to prepare to python 3.13 the project now uses bcrypt instead of passlib for generating and validating
passwords, because the passlib seems to be unmaintained and will be broken since then. If you are using password
authentication, you'd need to generate passwords again.
For more information kindly refer to migration notes https://ahriman.readthedocs.io/en/stable/migrations/2.16.0.html.
EOF
}

View File

@ -1 +1 @@
u ahriman 643 "ArcH linux ReposItory MANager" /var/lib/ahriman
u ahriman 643 "ArcH linux ReposItory MANager" /var/lib/ahriman

View File

@ -1,2 +1,2 @@
d /var/lib/ahriman 0755 ahriman ahriman
d /var/log/ahriman 0755 ahriman ahriman
d /run/ahriman 0755 ahriman ahriman

View File

@ -1,3 +0,0 @@
#!/bin/sh
exec python -B -m ahriman.application.ahriman "$@"

View File

@ -0,0 +1,11 @@
[Unit]
Description=ArcH linux ReposItory MANager (%i)
[Service]
Type=simple
ExecStart=/usr/bin/ahriman --repository-id "%I" repo-daemon --refresh
User=ahriman
Group=ahriman
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,12 @@
[Unit]
Description=ArcH linux ReposItory MANager web server
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/ahriman web
User=ahriman
Group=ahriman
[Install]
WantedBy=multi-user.target

View File

@ -1,12 +0,0 @@
[Unit]
Description=ArcH linux ReposItory MANager web server (%I architecture)
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/ahriman --architecture %i web
User=ahriman
Group=ahriman
[Install]
WantedBy=multi-user.target

Some files were not shown because too many files have changed in this diff Show More