#!/bin/sh
# Build a single Debian package in a systemd machine container.
#
# Can be conrolled by env vars:
#
#   - SRC_DIR to specify the source directory containing the package source
#     and build.sh script.
#     Defaults to the current working directory.
#
#   - DEST_DIR to specify the output directory for the build artifacts.
#     Defaults to a random directory in $TMPDIR.
#
#   - MACHINE_NAME to specify the name of the systemd machine container.
#     Defaults to "debian-package-builder".

set -eu

sudo apt-get install \
    debootstrap \
    systemd-container \
    debian-archive-keyring

set +u
if [ -z "$DEST_DIR" ]; then
    DEST_DIR="$(mktemp -d --tmpdir)"
fi
set -u
echo "Using DEST_DIR: $DEST_DIR" >&2

set +u
SRC_DIR="${SRC_DIR:-"$(pwd)"}"
if [ -z "$SRC_DIR" ]; then
    SRC_DIR="$(pwd)"
fi
set -u
echo "Using SRC_DIR: $SRC_DIR" >&2

MACHINE_NAME="${MACHINE_NAME:-debian-package-builder}"
echo "Using MACHINE_NAME: $MACHINE_NAME" >&2
MACHINES_DIR='/var/lib/machines/'
MACHINE_DIR="$MACHINES_DIR/$MACHINE_NAME"
echo "Using MACHINE_DIR: $MACHINE_DIR" >&2

for arg in "$SRC_DIR" "$DEST_DIR" "$MACHINE_DIR"; do
    case "$arg" in
        ./*|../*|'')
            >&2 echo "Error: '$arg' is not an absolute path to a directory."
            exit 1
        ;;
        *) 
        ;;
    esac
done

echo "Bootstrapping container in ${MACHINE_DIR}" >&2
debootstrap \
    --include=ca-certificates,curl,jq,gpg \
    trixie \
    "${MACHINE_DIR}" \
    https://deb.debian.org/debian
systemd-nspawn \
    --quiet \
    --pipe \
    --machine="$MACHINE_NAME" \
    --directory="${MACHINE_DIR}" \
    --setenv=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
    --setenv=LANG=C.UTF-8 \
    --setenv=DEBIAN_FRONTEND=noninteractive \
    /bin/sh -c 'apt-get update && apt-get upgrade -y'
MACHINE_TAR="$(mktemp -d --tmpdir)/$MACHINE_NAME.tar"
tar -cf "$MACHINE_TAR" "$MACHINE_DIR"

PKG="$(basename "$SRC_DIR")"
# Triggering the package build.
TS=$(date -u +%Y%m%d-%H%M%S)
# TODO move this into repo when fully implemented
curl -o "$SRC_DIR/build-contained.sh" https://petur.ingi.dk/pipeline/build-contained.sh
set +e
systemd-nspawn \
    --quiet \
    --pipe \
    --machine="$MACHINE_NAME" \
    --directory="${MACHINE_DIR}" \
    --bind-ro="${SRC_DIR}:/mnt/src" \
    --bind="${DEST_DIR}:/mnt/dest" \
    --setenv=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
    --setenv=LANG=C.UTF-8 \
    --setenv=DEBIAN_FRONTEND=noninteractive \
    /bin/sh /mnt/src/build-contained.sh 2>&1
rc=$?
set -e

# Collecting build artifacts.
#shellcheck disable=SC2012
deb=$(ls "${DEST_DIR}"/*.deb 2>/dev/null | head -n1 || true)
if [ -z "$deb" ]; then
    echo "[!] build reported success but produced no .deb in ${DEST_DIR}" >&2
    exit 1
fi
echo "Finished building: $deb"

echo "Cleaning up machine container ${MACHINE_NAME}" >&2
rm -rf "$MACHINE_DIR"
tar -xf "$MACHINE_TAR" -C "$MACHINES_DIR"
echo "Finished restoring machine container ${MACHINE_NAME}" >&2
echo "Testing package installation in machine container ${MACHINE_NAME}" >&2
# TODO move into repo when implemented
curl -o "$SRC_DIR/test-contained.sh" https://petur.ingi.dk/pipeline/test-contained.sh
systemd-nspawn \
    --quiet \
    --pipe \
    --machine="$MACHINE_NAME" \
    --directory="${MACHINE_DIR}" \
    --bind-ro="${SRC_DIR}:/mnt/src" \
    --bind="${DEST_DIR}:/mnt/dest" \
    --setenv=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
    --setenv=LANG=C.UTF-8 \
    --setenv=DEBIAN_FRONTEND=noninteractive \
    /bin/sh /mnt/src/test-contained.sh 2>&1
rm -rf "$MACHINE_DIR"
# TODO move the build artifacts into a permanent location
rm -rf "$DEST_DIR"
