mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 07:17:17 +00:00
* 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
327 lines
11 KiB
ReStructuredText
327 lines
11 KiB
ReStructuredText
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.
|