From 2b5e3d5b7be1b1155710ded90aac6b5ff1659e14 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Thu, 9 Jun 2022 21:08:13 +0200 Subject: [PATCH] docs: added in-depth build explanation --- docs/config.toml | 2 +- docs/content/other/builds-in-depth.md | 77 +++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/docs/config.toml b/docs/config.toml index 5c82044..f8e23cd 100644 --- a/docs/config.toml +++ b/docs/config.toml @@ -37,7 +37,7 @@ enableGitInfo = true url = "https://rustybever.be/man/vieter/vieter.1.html" weight = 20 [[menu.after]] - name = "Git" + name = "Vieter" url = "https://git.rustybever.be/vieter/vieter" weight = 30 [[menu.after]] diff --git a/docs/content/other/builds-in-depth.md b/docs/content/other/builds-in-depth.md index a6f0c21..a04acc4 100644 --- a/docs/content/other/builds-in-depth.md +++ b/docs/content/other/builds-in-depth.md @@ -2,3 +2,80 @@ For those interested, this page describes how the build system works internally. + +## Builder image + +Every cron daemon perodically creates a builder image that is then used as a +base for all builds. This is done to prevent build containers having to pull +down a bunch of updates when they update their system. + +The build container is created by running the following commands inside a +container started from the image defined in `base_image`: + +```sh +# Update repos & install required packages +pacman -Syu --needed --noconfirm base-devel git +# Add a non-root user to run makepkg +groupadd -g 1000 builder +useradd -mg builder builder +# Make sure they can use sudo without a password +echo 'builder ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers +# Create the directory for the builds & make it writeable for the +# build user +mkdir /build +chown -R builder:builder /build +``` + +This script updates the packages to their latest versions & creates a non-root +user to use when running `makepkg`. + +This script is base64-encoded & passed to the container as an environment +variable. The container's entrypoint is set to `/bin/sh -c` & its command +argument to `echo $BUILD_SCRIPT | base64 -d | /bin/sh -e`, with the +`BUILD_SCRIPT` environment variable containing the base64-encoded script. + +Once the container exits, a new Docker image is created from it. This image is +then used as the base for any builds. + +## Running builds + +Each build has its own Docker container, using the builder image as its base. +The same base64-based technique as above is used, just with a different script. +To make the build logs more clear, each command is appended by an echo command +printing the next command to stdout. + +Given the Git repository URL is `https://examplerepo.com` with branch `main`, +the URL of the Vieter server is `https://example.com` and `vieter` is the +repository we wish to publish to, we get the following script: + +```sh +echo -e '+ echo -e '\''[vieter]\\nServer = https://example.com/$repo/$arch\\nSigLevel = Optional'\'' >> /etc/pacman.conf' +echo -e '[vieter]\nServer = https://example.com/$repo/$arch\nSigLevel = Optional' >> /etc/pacman.conf +echo -e '+ pacman -Syu --needed --noconfirm' +pacman -Syu --needed --noconfirm +echo -e '+ su builder' +su builder +echo -e '+ git clone --single-branch --depth 1 --branch main https://examplerepo.com repo' +git clone --single-branch --depth 1 --branch main https://examplerepo.com repo +echo -e '+ cd repo' +cd repo +echo -e '+ makepkg --nobuild --syncdeps --needed --noconfirm' +makepkg --nobuild --syncdeps --needed --noconfirm +echo -e '+ source PKGBUILD' +source PKGBUILD +echo -e '+ curl -s --head --fail https://example.com/vieter/x86_64/$pkgname-$pkgver-$pkgrel && exit 0' +curl -s --head --fail https://example.com/vieter/x86_64/$pkgname-$pkgver-$pkgrel && exit 0 +echo -e '+ [ "$(id -u)" == 0 ] && exit 0' +[ "$(id -u)" == 0 ] && exit 0 +echo -e '+ MAKEFLAGS="-j$(nproc)" makepkg -s --noconfirm --needed && for pkg in $(ls -1 *.pkg*); do curl -XPOST -T "$pkg" -H "X-API-KEY: $API_KEY" https://example.com/vieter/publish; done' +MAKEFLAGS="-j$(nproc)" makepkg -s --noconfirm --needed && for pkg in $(ls -1 *.pkg*); do curl -XPOST -T "$pkg" -H "X-API-KEY: $API_KEY" https://example.com/vieter/publish; done +``` + +This script: + +1. Adds the target repository as a repository in the build container +2. Updates mirrors & packages +3. Clones the Git repository +4. Runs `makepkg` without building to calculate `pkgver` +5. Checks whether the package version is already present on the server +6. If not, run makepkg & publish any generated package archives to the server