From 0cc35e70e31c66b36357e949e1568dff6c03715c Mon Sep 17 00:00:00 2001 From: Evgenii Alekseev Date: Fri, 15 Nov 2024 16:54:04 +0200 Subject: [PATCH] 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 --- docker/Dockerfile | 159 ++++++++++++++++++++++------------ docker/install-aur-package.sh | 4 + 2 files changed, 106 insertions(+), 57 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 312eaddc..fe0e87ad 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,77 @@ -FROM archlinux:base +# 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" @@ -23,73 +96,45 @@ ENV AHRIMAN_VALIDATE_CONFIGURATION="yes" ## update pacman.conf with multilib RUN echo "[multilib]" >> "/etc/pacman.conf" && \ echo "Include = /etc/pacman.d/mirrorlist" >> "/etc/pacman.conf" -## refresh packages, install sudo and install packages for building -RUN pacman -Syu --noconfirm sudo && \ - pacman -S --noconfirm --asdeps fakeroot python-tox -## 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 +## 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 \ + --assume-installed python-aiohttp-apispec=3.0.0 \ + ahriman 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-wheel \ - && \ - pacman -S --noconfirm --asdeps \ - git \ - python-aiohttp \ + python-aioauth-client \ + python-aiohttp-apispec-git \ + python-aiohttp-security \ + python-aiohttp-session \ python-boto3 \ python-cerberus \ python-cryptography \ - python-jinja \ python-systemd \ + python-requests-unixsocket2 \ 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 + sudo -## 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" - -# 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 && \ - runuser -u build -- makepkg --packagelist | grep -v -- -debug- | pacman -U --noconfirm --nodeps - && \ - cd / && rm -r "/home/build/ahriman" - -# cleanup unused -RUN find "/var/cache/pacman/pkg" -type f -delete -RUN pacman -Qdtq | pacman -Rscn --noconfirm - +## 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" ENTRYPOINT ["entrypoint"] # default command diff --git a/docker/install-aur-package.sh b/docker/install-aur-package.sh index 433bdfcc..85d24ed0 100755 --- a/docker/install-aur-package.sh +++ b/docker/install-aur-package.sh @@ -4,8 +4,12 @@ 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" + # 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"