Files
nixos/deploy.sh
Simon Gardling aef99e7365
Some checks failed
Build and Deploy / mreow (push) Successful in 51s
Build and Deploy / yarn (push) Successful in 47s
Build and Deploy / muffin (push) Failing after 1m9s
deploy-guard: block activation while users are online
- modules/server-deploy-guard.nix: extendable aggregator registered via
  services.deployGuard.checks.<name>.{description,command}. Installs
  deploy-guard-check with per-check timeout, pass/block reporting, JSON
  output, DEPLOY_GUARD_BYPASS / /run/deploy-guard-bypass (single-shot).
- services/jellyfin/jellyfin-deploy-guard.nix: curl+jq on /Sessions,
  blocks when any session carries NowPlayingItem; soft-fails when unreachable.
- services/minecraft-deploy-guard.nix: mcstatus SLP query on 25565, blocks
  when players.online > 0; soft-fails when unreachable.
- flake.nix: wrap deploy.nodes.muffin activation with activate.custom so
  deploy-guard-check runs before switch-to-configuration. Auto-rollback
  catches the failure. dryActivate/boot branches preserved.
- deploy.sh: SSH preflight for ./deploy.sh muffin with --force /
  DEPLOY_GUARD_FORCE=1 (touches remote bypass marker). Connectivity
  failure is soft; activation still enforces.
- tests/deploy-guard.nix: aggregator contract, bypass mechanics, timeout,
  JSON output.
2026-04-22 00:36:21 -04:00

65 lines
2.2 KiB
Bash
Executable File

#!/bin/sh
# Wrapper around nixos-rebuild and deploy-rs for the three hosts.
#
# Usage:
# ./deploy.sh # nixos-rebuild boot on current host (mreow/yarn)
# ./deploy.sh switch # apply immediately on current host
# ./deploy.sh test # apply without adding boot entry
# ./deploy.sh build # build only, no activation
# ./deploy.sh muffin # build + deploy to muffin via deploy-rs
# ./deploy.sh muffin --force # bypass the deploy guard (active-user check)
#
# muffin cannot be rebuilt locally from another host — this script only issues
# the remote deploy via deploy-rs when explicitly named.
#
# DEPLOY_GUARD_FORCE=1 is equivalent to passing --force.
set -eu
host="$(hostname -s)"
arg="${1:-boot}"
case "$arg" in
muffin)
shift # consume "muffin"
force=0
if [ "${DEPLOY_GUARD_FORCE:-0}" = "1" ]; then force=1; fi
if [ "${1:-}" = "--force" ]; then force=1; shift; fi
if [ "$force" = "1" ]; then
echo "deploy-guard: bypass requested; setting remote marker"
ssh -o BatchMode=yes -o ConnectTimeout=3 root@server-public \
'touch /run/deploy-guard-bypass' \
|| echo "deploy-guard: warning: could not write remote bypass marker" >&2
else
# Single SSH probe — if exit 255 it's a connectivity failure (skip
# preflight; the activation-time guard still enforces). Any other
# non-zero is the guard blocking the deploy.
output=$(ssh -o BatchMode=yes -o ConnectTimeout=5 \
root@server-public deploy-guard-check 2>&1) && rc=0 || rc=$?
if [ "$rc" -eq 255 ]; then
echo "deploy-guard: muffin unreachable for preflight;" \
"activation will still enforce" >&2
elif [ "$rc" -ne 0 ]; then
printf '%s\n' "$output"
echo >&2
echo "Blocked by deploy guard. Bypass: ./deploy.sh muffin --force" >&2
exit 1
elif [ -n "$output" ]; then
printf '%s\n' "$output"
fi
fi
exec nix run .#deploy -- .#muffin "$@"
;;
boot | switch | test | build)
exec nixos-rebuild "$arg" --flake ".#$host" --use-remote-sudo
;;
*)
echo "usage: $0 [muffin [--force] | boot | switch | test | build]" >&2
exit 2
;;
esac