From b78565281e21f951c141a56e9f9674eb88d788b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20N=C3=BCtzi?= Date: Tue, 2 Apr 2024 20:36:24 +0200 Subject: [PATCH] feat: Refactor setup script into function calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The setup script has been broken up into function calls to improve readability and further maintenance. Also its beneficial for other derivations with different base OS. Signed-off-by: Gabriel Nützi --- root/setup.sh | 243 +++++++++++++++++++++++++++++++------------------- 1 file changed, 153 insertions(+), 90 deletions(-) diff --git a/root/setup.sh b/root/setup.sh index 99201ff..70710e3 100644 --- a/root/setup.sh +++ b/root/setup.sh @@ -1,3 +1,5 @@ +#!/usr/bin/env bash +# # This script is intended to be run during container-image build. Any # other usage outside this context is likely to cause harm. # @@ -19,39 +21,61 @@ set -eo pipefail -for varname in PRUNE_INTERVAL RUNNER_VERSION TARGETARCH; do - if [[ -z "${!varname}" ]]; then - echo "Error: \$$varname must be non-empty." +function die() { + echo -n '!! ERROR:' >&2 + printf " %s\n" "$@" >&2 + exit 1 +} + +function check_vars() { + for varname in PRUNE_INTERVAL RUNNER_VERSION TARGETARCH; do + if [[ -z "${!varname}" ]]; then + die "Env. variable '$varname' must be non-empty." + fi + done +} + +function main() { + # Show what's happening to make debugging easier + set -x + + # Make image smaller by not installing docs. + dnf=(dnf --setopt=tsflags=nodocs -y) + + install_packages + setup_user + setup_service_podman + setup_service_runner + setup_gitlab_config + + finalize_ownership +} + +function install_packages() { + readarray xpackages < <(grep -vE '^(# )+' :65539` -echo -e "podman:1:999\npodman:1002:64536" | tee /etc/subuid >/etc/subgid -# Host volume mount necessary for nested-podman to use overlayfs2 for container & volume storage. -mkdir -p /home/podman/.local/share/containers -# Nested-container's local container-cache volume mount, recommended by gitlab-runner docs. -mkdir -p /cache -# Both the gitlab-runner and podman need access to the cache directory / volume mount. -chown podman:runner /cache + # Separate users for services to increase process isolation. + # The 'podman' user's socket service writes /home/runner/podman.socket + # Prevent copying of skel since it can interfere with the gitlab-runner + mkdir -p /home/podman /home/runner + useradd -M -u 1000 -g podman -G runner podman + useradd -M -u 1001 -g runner runner -# Setup persistent 'podman' user services to start & run without a login. -mkdir -p /var/lib/systemd/linger -touch /var/lib/systemd/linger/podman -# Setup 'podman' socket and a container-storage pruning service for 'podman' user. -mkdir -p /home/podman/.config/systemd/user/{sockets.target.wants,default.target.wants} -cd /home/podman/.config/systemd/user/ -ln -s $PWD/podman.socket ./sockets.target.wants/ # Added from Containerfile -ln -s $PWD/prune.timer ./default.target.wants/ # also from Containerfile -# Substitute value from --build-arg if specified, otherwise use default from Containerfile. -sed -i -e "s/@@@PRUNE_INTERVAL@@@/$PRUNE_INTERVAL/" ./prune.timer -# Containerfile ADD instruction does not properly set ownership/permissions. -chown -R 1000:1000 /home/podman -chmod 700 /home/podman + # Allow only podman in `/home/podman`. + chmod 700 /home/podman + # Allow 'podman' user to create socket file under `/home/runner`. + chmod 770 /home/runner -# Setup persistent 'runner' user services to start & run without a login. -touch /var/lib/systemd/linger/runner -mkdir -p /home/runner/.config/systemd/user/default.target.wants -cd /home/runner/.config/systemd/user/ -# Does not depend on podman.socket file availablility, will retry if not present. -ln -s $PWD/runner.service ./default.target.wants/ -# gitlab-runner will create side-car '.runner_system_id' file next to 'config.toml' -# on first startup. Ensure access is allowed. Also link to future config file -# presented as a container-secret. -mkdir -p /home/runner/.gitlab-runner -ln -s /var/run/secrets/config.toml /home/runner/.gitlab-runner/config.toml -# Containerfile ADD instruction does not properly set ownership/permissions. -chown -R runner:runner /home/runner -chmod -R 700 /home/runner/.gitlab-runner + # Set permissions. + chown -R runner:runner /home/runner + chown -R podman:podman /home/podman + + # Overwrite defaults, only user 'podman' permitted to have a user-namespace + # Split the namespaced ID's around the containers root (ID 0), podman (ID 1000), and + # runner (ID 1001) such that the user-namespace of any nested containers cannot + # read or write any files owned by these users (and/or hijack nested container processes). + # N/B: The range-end (999+64536) ensures a total of 65535 IDs are available for nested-containers. + # This requires the host provide a sufficiently large range, i.e. `pipglr::65539` + echo -e "podman:1:999\npodman:1002:64536" | tee /etc/subuid >/etc/subgid +} + +function setup_volumes() { + # Host volume mount necessary for nested-podman to use overlayfs2 for container & volume storage. + mkdir -p /home/podman/.local/share/containers + + # Nested-container's local container-cache volume mount, recommended by gitlab-runner docs. + mkdir -p /cache + + # Both the gitlab-runner and podman need access to the cache directory / volume mount. + chown podman:runner /cache +} + +function setup_service_podman() { + # Setup persistent 'podman' user services to start & run without a login. + mkdir -p /var/lib/systemd/linger + touch /var/lib/systemd/linger/podman + + # Setup 'podman' socket and a container-storage pruning service for 'podman' user. + mkdir -p /home/podman/.config/systemd/user/{sockets.target.wants,default.target.wants} + + cd /home/podman/.config/systemd/user/ + ln -s "$(pwd)/podman.socket" ./sockets.target.wants/ # Added from Containerfile + ln -s "$(pwd)/prune.timer" ./default.target.wants/ # also from Containerfile + + # Substitute value from --build-arg if specified, otherwise use default from Containerfile. + sed -i -e "s/@@@PRUNE_INTERVAL@@@/$PRUNE_INTERVAL/" ./prune.timer +} + +function setup_service_runner() { + # Setup persistent 'runner' user services to start & run without a login. + touch /var/lib/systemd/linger/runner + + # Setup persistent 'runner' user services to start & run without a login. + mkdir -p /home/runner/.config/systemd/user/default.target.wants + + cd /home/runner/.config/systemd/user/ + # Does not depend on podman.socket file availability, will retry if not present. + ln -s "$(pwd)/runner.service" ./default.target.wants/ +} + +function setup_gitlab_config() { + # gitlab-runner will create side-car '.runner_system_id' file next to 'config.toml' + # on first startup. Ensure access is allowed. Also link to future config file + # presented as a container-secret. + mkdir -p /home/runner/.gitlab-runner + ln -s /var/run/secrets/config.toml /home/runner/.gitlab-runner/config.toml + + chmod -R 700 /home/runner/.gitlab-runner +} + +function finalize_ownership() { + # Adjust ownership to all files created after `setup_user`. + # and also to the `ADD` instruction in the `Containerfile`. + chown -R runner:runner /home/runner + chown -R podman:podman /home/podman +} + +check_vars +main