Files
werkregie/dashboard/packaging/werkregie-deploy-receive
claude-code 9fb408f68a
werkator build succeeded after 00:57
werkator/deploy build succeeded after 00:28
The deploy test runs the bundle's own launcher (#70)
Co-authored-by: claude-code <claude-code@javagil.de>
2026-10-14 14:55:56 +02:00

69 lines
2.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Usage: werkregie-deploy-receive < werkregie-dashboard-runtime-linux-x64.tar.gz
#
# Installs the runtime bundle on stdin as ~/opt/werkregie-dashboard and restarts the service with it.
# It is the forced command of Werkator's deploy key in ~/.ssh/authorized_keys of the server's user,
# so that the key can do nothing else; the human installs it once as ~/bin/werkregie-deploy-receive.
# The command the client asks for, in SSH_ORIGINAL_COMMAND, is ignored.
#
# It unpacks the bundle beside the running one and runs its launcher,
# so that a JRE that does not start on this host stops the deploy before the service does.
# Then it stops the service, keeps the running runtime as werkregie-dashboard.prev, swaps and starts it,
# and waits until the service answers with the new version; otherwise it puts the previous runtime back.
#
# The environment may override WERKREGIE_INSTALL_DIR (~/opt), WERKREGIE_CONFIG (~/.config/werkregie/dashboard.yml),
# WERKREGIE_UNIT (werkregie-dashboard), WERKREGIE_LAUNCHER_SECONDS (60) and WERKREGIE_WAIT_SECONDS (120).
set -euo pipefail
install_dir="${WERKREGIE_INSTALL_DIR:-$HOME/opt}"
config="${WERKREGIE_CONFIG:-$HOME/.config/werkregie/dashboard.yml}"
unit="${WERKREGIE_UNIT:-werkregie-dashboard}"
launcher_seconds="${WERKREGIE_LAUNCHER_SECONDS:-60}"
wait_seconds="${WERKREGIE_WAIT_SECONDS:-120}"
current="$install_dir/werkregie-dashboard"
new="$current.new"
prev="$current.prev"
rm -rf "$new"
mkdir -p "$new"
tar -xzf - -C "$new" --strip-components=1
# a launcher that ignores its argument would start the dashboard instead and never end
if ! version=$(timeout "$launcher_seconds" "$new/bin/werkregie-dashboard" version); then
echo "the launcher of the new runtime fails, the service stays as it is" >&2
rm -rf "$new"
exit 1
fi
[[ "$version" =~ ^[0-9]+(\.[0-9]+)+$ ]] || { echo "not a version: $version" >&2; rm -rf "$new"; exit 1; }
port=$(sed -n 's/^port:[[:space:]]*\([0-9][0-9]*\).*/\1/p' "$config" 2>/dev/null | head -1)
port="${port:-4747}"
answers() {
local deadline=$((SECONDS + wait_seconds))
while ((SECONDS < deadline)); do
curl -fsS --max-time 5 "http://127.0.0.1:$port/api/dashboard" 2>/dev/null | grep -q "\"version\":\"$1\"" && return 0
sleep 2
done
return 1
}
echo "installing $version"
systemctl --user stop "$unit"
rm -rf "$prev"
[[ ! -d "$current" ]] || mv "$current" "$prev"
mv "$new" "$current"
systemctl --user start "$unit"
if answers "$version"; then
echo "werkregie-dashboard $version runs"
exit 0
fi
echo "werkregie-dashboard $version does not answer within $wait_seconds s, the previous runtime comes back" >&2
systemctl --user stop "$unit"
if [[ -d "$prev" ]]; then
rm -rf "$current"
mv "$prev" "$current"
fi
systemctl --user start "$unit"
exit 1