Menu
Public repository / dad8e9b8a1147b0569aa29ed4a68b5731b7962aa
AkurAI-Build / deploy/service-deploy.sh
Latest change 3dc2e04327a45398df4d480fc24b78ea0f25fc75 - deploy: replace stale Docker service-deploy with systemd forge swap (scheduled restart, rollback) by Ólafur Búi Ólafsson
#!/bin/sh
# Replace the live AkurAI-Build forge binary (system unit akurai-build).
#
# Live layout (see `systemctl cat akurai-build`):
# binary $HOME/.local/lib/akurai-build/akurai (unit runs as the host user)
# health http://127.0.0.1:3210/api/health
#
# Steps: back up akurai -> akurai.prev, install target/release/akurai, restart,
# poll health up to 20s, restore akurai.prev and restart on failure.
#
# Self-restart: when run from the forge's own CI job (pass --scheduled, as
# .akurai.yml does), restarting the unit would kill this job mid-flight. In that
# case the swap/restart/health/rollback runs as a transient systemd unit
# started 5s later via `sudo systemd-run --on-active=5`; this script exits 0
# after scheduling, and the result is in `journalctl -u akurai-build-swap`.
# Requires passwordless sudo for systemctl/systemd-run/install. Note the forge
# unit sets NoNewPrivileges=true, which blocks sudo from inside CI jobs; until
# that is relaxed run this from a host shell: `sh deploy/service-deploy.sh`.
set -eu
host_home="${AKURAI_HOST_HOME:-$HOME}"
dest_dir="${AKURAI_BUILD_LIB:-$host_home/.local/lib/akurai-build}"
dest="$dest_dir/akurai"
unit=akurai-build
health=http://127.0.0.1:3210/api/health
swap() {
src="$1"
test -x "$src"
test -x "$dest"
sudo install -m 755 "$dest" "$dest.prev"
sudo install -m 755 "$src" "$dest.new"
sudo mv -f "$dest.new" "$dest"
sudo systemctl restart "$unit"
i=0
while [ "$i" -lt 20 ]; do
if curl -fsS -o /dev/null "$health"; then
echo "akurai-build healthy"
return 0
fi
i=$((i + 1))
sleep 1
done
echo "akurai-build unhealthy after 20s; rolling back" >&2
sudo install -m 755 "$dest.prev" "$dest"
sudo systemctl restart "$unit"
return 1
}
if [ "${1:-}" = "--swap" ]; then
swap "${2:?--swap requires a staged binary}"
exit $?
fi
test -x target/release/akurai
if [ "${1:-}" = "--scheduled" ]; then
# Stage binary and script outside the job workspace so they survive cleanup.
stage="$dest_dir/akurai.staged"
sudo install -m 755 target/release/akurai "$stage"
sudo install -m 755 deploy/service-deploy.sh "$dest_dir/service-deploy.sh"
sudo systemd-run --unit akurai-build-swap --collect --on-active=5 \
--uid="$(id -u)" --setenv=HOME="$host_home" \
/bin/sh "$dest_dir/service-deploy.sh" --swap "$stage"
echo "forge swap scheduled in 5s; check: journalctl -u akurai-build-swap"
exit 0
fi
swap target/release/akurai