#!/usr/bin/env bash
#
# Install Radicle CI with Ambient on a Debian host. Run this as root.
# Note that this is not suitable for upgrades, only initial installation.
#
# This script installs a Radicle node, the Radicle CI broker, and the Ambient
# CI engine. It also installs Caddy and other tooling needed. To access the CI
# reports, go to http://HOST, where `HOST` is the hostname. Note lack of TLS.
# The `radicle-ci-example` repository is cloned and this triggers CI to run.
#
# You will want to review the configuration files:
#
# * /home/ci/ci.yaml - the CI broker
# * /home/ci/radicle-ci-ambient.yaml - the Ambient adapter
# * /home/ci/.config/ambient/config.yaml - Ambient itself

set -euo pipefail

# Print log message.
log() {
	printf "LOG: $*\n"
}

# Print error message and terminate script.
die() {
	echo "$*" 1>&2
	exit 1
}

log Set up a temporary directory and its automatic removal.
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT

log Prevent packages from asking configuration questions when installed.
export DEBIAN_FRONTEND=noninteractive

log Install tools we will need.
if ! apt-get update -q >"$tmp/update.log" 2>&1; then
	cat "$tmp/update.log"
	exit 1
fi
if ! command -v chronic >/dev/null; then
	if ! apt-get install -y moreutils >"$tmp/moreutils" 2>&1; then
		cat "$tmp/moreutils"
		exit 1
	fi
fi
if ! command -v curl >/dev/null; then
	chronic apt-get install -y curl
fi
if ! command -v gpg >/dev/null; then
	chronic apt-get install -y gpg
fi
if ! command -v pstree >/dev/null; then
	chronic apt-get install -y psmisc
fi
if ! command -v unxz >/dev/null; then
	chronic apt-get install -y xz-utils
fi

log Set up the Radicle APT repository.
if ! dpkg -l radicle-archive-keyring 2>&1 | grep '^ii ' >/dev/null; then
	log Download current keyring package.
	cd "$tmp"
	curl -O -sL https://radicle.xyz/apt/radicle-archive-keyring.deb
	chronic dpkg -i radicle-archive-keyring.deb

	log Add to APT source lists.
	cat <<EOF | tee /etc/apt/sources.list.d/radicle_xyz_apt.list >/dev/null
deb [signed-by=/usr/share/radicle/radicle-archive-keyring.asc] https://radicle.xyz/apt release main                                                    
EOF

	log Install keyring package.
	chronic apt-get update
	chronic apt-get install -y radicle-archive-keyring
fi

log Install Radicle and CI software.
chronic apt-get install -y radicle radicle-ci-broker radicle-ci-ambient ambient-ci

log Create user for running CI. This user will also run the Radicle node.
if ! getent passwd ci >/dev/null; then
	chronic adduser --disabled-password --comment "Radicle CI" ci
fi

log Add CI user to kvm group.
chronic adduser ci kvm

log Configure Ambient.
install -d ~ci/.config/ambient -o ci -g ci
sudo -u ci tee ~ci/.config/ambient/config.yaml <<EOF >/dev/null
executor: /usr/bin/ambient-execute-plan
projects: ~/ambient-projects.yaml
artifacts_max_size: 1G
cache_max_size: 50G
uefi: true
qemu:
  cpus: 1
  memory: 1G
lint: false
EOF
sudo install -d -o ci -g ci /home/ci/adapter-logs
sudo -i -u ci ambient config >/dev/null

log Install Caddy.
chronic apt-get install -y caddy
tee /etc/caddy/Caddyfile <<EOF >/dev/null
:80 {
        root * /srv/http/
        file_server browse
}
EOF
install -d /srv/http -o ci -g ci
systemctl reload caddy

log Configure CI broker.
sudo -u ci tee ~ci/ci.yaml <<EOF >/dev/null
description: |
  <p>This is a Radicle CI node.
db: /home/ci/ci.db
report_dir: /srv/http
concurrent_adapters: 1
adapters:
  ambient:
    command: /bin/radicle-ci-ambient
    env:
      RADICLE_CI_AMBIENT: /home/ci/radicle-ci-ambient.yaml
triggers:
  - adapter: ambient
    filters:
      - !HasFile ".radicle/ambient.yaml"
EOF
sudo -i -u ci cib --log-level error --config ci.yaml config >/dev/null

log Configure Ambient adapter.
sudo -i -u ci tee ~ci/radicle-ci-ambient.yaml <<EOF >/dev/null
image: /home/ci/ambient.qcow2
logdir: /srv/http/ambient-log
log: /home/ci/adapter-logs
base_url: "http://$(hostname)/ambient-log"
EOF
install -d ~ci/.local/state/ambient-ci/projects -o ci -g ci

log Download virtual machine image for Ambient.
if ! [ -e ~ci/ambient.qcow2 ]; then
	chronic sudo -i -u ci curl -sOL https://files.liw.fi/ambient/ambient.qcow2.xz
	sudo -i -u ci unxz ambient.qcow2.xz
fi

log Set up Radicle node.
chronic sudo -i -u ci rad auth --alias "ci-$(hostname)" --stdin </dev/null

log Install systemd service unit for Radicle node.
cat <<EOF >/etc/systemd/system/radicle-node.service
[Unit]
Description=Radicle Node
After=network-online.target
Requires=network-online.target

[Service]
User=ci
Group=ci
ExecStart=/usr/bin/radicle-node --listen 0.0.0.0:8776 --force
KillMode=process
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
EOF

log Install systemd service unit for Radicle CI broker
cat <<EOF >/etc/systemd/system/radicle-ci-broker.service
[Unit]
Requires=radicle-node.service
After=radicle-node.service
Description=Radicle CI broker

[Service]
Type=simple
ExecStart=/bin/cib --log-level info --config /home/ci/ci.yaml process-events
KillMode=control-group
Restart=always
RestartSec=1
User=ci
Group=ci

[Install]
WantedBy=default.target
EOF

log Start Radicle CI via systemd.
systemctl daemon-reload
chronic systemctl enable radicle-node
chronic systemctl enable radicle-ci-broker
systemctl start radicle-ci-broker

log Seed the radicle-ci-example repository.
chronic sudo -i -u ci rad seed rad:z28U8KUBvVSMQc13NydX3LBDsdEdQ

log "OK"
