#!/bin/sh -eu
export PATH="/snap/bin/:${PATH}"

cleanup() {
    set +e
    incus delete build-distrobuilder-cache -f >/dev/null 2>&1

    exit 0
}
trap cleanup EXIT HUP INT TERM

ARCH="$1"
TARGET="$2"
DISTRO="jammy"

# Create the container
incus init "images:ubuntu/${DISTRO}/${ARCH}" build-distrobuilder-cache \
    -c security.privileged=true -c security.nesting=true
printf "lxc.cgroup2.devices.allow = b 259:* rw\nlxc.cgroup.devices.allow = b 259:* rw" | incus config set build-distrobuilder-cache raw.lxc -

# Setup loop devices
(
    incus config show build-distrobuilder-cache | sed "/devices:/d"
    cat << EOF
devices:
  loop-control:
    major: "10"
    minor: "237"
    path: /dev/loop-control
    type: unix-char
EOF

    for i in $(seq 0 64); do
        cat << EOF
  loop${i}:
    major: "7"
    minor: "${i}"
    path: /dev/loop${i}
    type: unix-block
EOF
    done
) | incus config edit build-distrobuilder-cache

# Start the container
incus start build-distrobuilder-cache

# Install distrobuilder
(
    cat << EOF
#!/bin/sh
set -eux

# Wait for network
while :; do
    ping -W1 -c1 linuxcontainers.org >/dev/null 2>&1 && break
    sleep 1
done

ARCHIVE="http://us.ports.ubuntu.com/ubuntu-ports"
if [ "${ARCH}" = "amd64" ] || [ "${ARCH}" = "i386" ]; then
    ARCHIVE="http://us.archive.ubuntu.com/ubuntu"
fi

# Workaround apparmor issues on older distributions.
umount -l /sys/devices/system/cpu || true

# Setup clean sources
echo force-unsafe-io >> /etc/dpkg/dpkg.cfg
cat > /etc/apt/apt.conf.d/60lxc-ci << EOL
APT::Get::Show-Versions "true";
Acquire::Languages "none";
EOL
cat > /etc/apt/sources.list << EOL
deb \${ARCHIVE} ${DISTRO} main universe
deb \${ARCHIVE} ${DISTRO}-updates main universe
deb \${ARCHIVE} ${DISTRO}-security main universe
EOL
apt-get update --yes

# Install dependencies
apt-get install --yes --no-install-recommends \
    btrfs-progs \
    build-essential \
    ca-certificates \
    curl \
    debootstrap \
    dirmngr \
    dosfstools \
    gcc \
    gdisk \
    git \
    gpg \
    gpg-agent \
    kpartx \
    libc6-dev \
    libncurses-dev \
    make \
    mawk \
    patch \
    python3 \
    qemu-utils \
    rsync \
    squashfs-tools \
    unzip \
    xz-utils \
    zstd
apt-get clean

# Install distrobuilder
curl -sL "https://go.dev/dl/go1.21.3.linux-\$(dpkg --print-architecture).tar.gz" | tar -zxv -C /usr/local/
export PATH=/usr/local/go/bin:\${PATH}
git clone https://github.com/lxc/distrobuilder --depth 1
cd distrobuilder
make
cp /root/go/bin/distrobuilder /usr/local/bin/
rm -Rf /root/distrobuilder /root/go /root/.cache

# All done
exit 0
EOF
) | incus exec build-distrobuilder-cache -- sh

incus stop build-distrobuilder-cache
incus export build-distrobuilder-cache "${TARGET}/build-distrobuilder-cache.tar.xz" --optimized-storage
incus delete -f build-distrobuilder-cache
