#!/bin/bash -e
[ "$1" = "-h" ] || [ "$1" = "--help" ] && echo "Setup a working openQA installation in a systemd-nspawn container" && exit

if [ "$(id -ru)" != "0" ]; then
    echo "$0 must be run as root"
    exit 1
fi

set -euo pipefail
# Enable -x only here to show above error message cleanly
set -x

CONTAINER_NAME="openqa1"
CONTAINER_PATH="/var/lib/machines/${CONTAINER_NAME}"

systemd_run_params=(-q -M "$CONTAINER_NAME")
if systemd-run --help | grep '\-P'; then
    systemd_run_params+=(-P)
else
    echo "Your version of systemd-run does not support the '-P' parameter,
piped output from the container will not be available here"
fi

ARCH="${ARCH:=$(arch)}"
if [ "$ARCH" = "x86_64" ]; then
    DEFAULT_REPO="${DEFAULT_REPO:="http://download.opensuse.org/tumbleweed/repo/oss/"}"
else
    DEFAULT_REPO="${DEFAULT_REPO:="http://download.opensuse.org/ports/$ARCH/tumbleweed/repo/oss/"}"
fi

PKGS_TO_INSTALL="aaa_base systemd shadow zypper openSUSE-release vim iproute2 iputils openQA-single-instance sudo net-tools curl wget ca-certificates-mozilla qemu-arm qemu-ppc qemu-x86 openQA-bootstrap"

zypper -n install systemd-container
mkdir -p /var/lib/machines/

cat > /etc/systemd/system/systemd-nspawn-openqa@.service << EOF
[Unit]
Description=Container %i
Documentation=man:systemd-nspawn(1)
PartOf=machines.target
Before=machines.target
After=network.target systemd-resolved.service
RequiresMountsFor=/var/lib/machines

[Service]
ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --bind /dev/kvm --settings=override --machine=%i
KillMode=mixed
Type=notify
RestartForceExitStatus=133
SuccessExitStatus=133
Slice=machine.slice
Delegate=yes
TasksMax=16384

DevicePolicy=closed
DeviceAllow=/dev/net/tun rwm
DeviceAllow=char-pts rw

# nspawn itself needs access to /dev/loop-control and /dev/loop, to
# implement the --image= option. Add these here, too.
DeviceAllow=/dev/loop-control rw
DeviceAllow=/dev/kvm rw
DeviceAllow=block-loop rw
DeviceAllow=block-blkext rw

[Install]
WantedBy=machines.target
EOF

if [ ! -d $CONTAINER_PATH ]; then
    mkdir -p $CONTAINER_PATH
    zypper -n --root $CONTAINER_PATH addrepo "$DEFAULT_REPO" defaultrepo
    zypper -n --root $CONTAINER_PATH --gpg-auto-import-keys refresh
    # There are non-fatal errors when zyppering inside chroot, so ignoring errors on the next line
    # Allow command line options without quotes
    # shellcheck disable=SC2086
    zypper -n --root $CONTAINER_PATH install --no-recommends -ly $PKGS_TO_INSTALL || test $? = 107
else
    echo Container path $CONTAINER_PATH already exists, stopping here. Please clean manually and rerun.
    exit 1
fi

systemctl daemon-reload
systemctl start systemd-nspawn-openqa@$CONTAINER_NAME
# ensure that the container is really running
# ignore expected errors about 'Failed to create bus connection: Protocol error' and restarting error
while ! timeout -s9 2 systemd-run -qPM $CONTAINER_NAME /bin/bash -c whoami /dev/null 2>&1; do
    systemctl restart systemd-nspawn-openqa@$CONTAINER_NAME.service || true
    sleep 3
done
systemd-run "${systemd_run_params[@]}" /bin/bash -c 'update-ca-certificates'
systemd-run "${systemd_run_params[@]}" /bin/bash -c '/usr/share/openqa/script/openqa-bootstrap'

echo -e "$(
    tput setaf 2
    tput bold
)Your openQA container has been created. Run 'systemd-run -tM $CONTAINER_NAME /bin/bash' to get a shell in the container$(tput sgr0)"
