69 lines
2.7 KiB
Bash
Executable File
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
|