deploy-guard: block activation while users are online
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

- 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.
This commit is contained in:
2026-04-22 00:36:21 -04:00
parent ddac5e3f04
commit aef99e7365
11 changed files with 603 additions and 7 deletions

View File

@@ -372,7 +372,37 @@
profiles.system = {
sshUser = "root";
user = "root";
path = deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.muffin;
# Wrap deploy-rs.activate.nixos so the guard runs before
# switch-to-configuration. If the guard exits non-zero, deploy-rs's
# auto-rollback restores the previous profile. Bypass via
# DEPLOY_GUARD_BYPASS=1 or by pre-touching /run/deploy-guard-bypass.
path =
let
base = self.nixosConfigurations.muffin;
activate = deploy-rs.lib.${system}.activate;
bootloaderDefaultCleanup = nixpkgs-stable.lib.optionalString base.config.boot.loader.systemd-boot.enable "sed -i '/^default /d' ${base.config.boot.loader.efi.efiSysMountPoint}/loader/loader.conf";
in
(
activate.custom
// {
dryActivate = "$PROFILE/bin/switch-to-configuration dry-activate";
boot = "$PROFILE/bin/switch-to-configuration boot";
}
)
base.config.system.build.toplevel
''
# work around https://github.com/NixOS/nixpkgs/issues/73404
cd /tmp
# Halt deploys while users are actively using services.
# See modules/server-deploy-guard.nix.
"$PROFILE/sw/bin/deploy-guard-check"
$PROFILE/bin/switch-to-configuration switch
# https://github.com/serokell/deploy-rs/issues/31
${bootloaderDefaultCleanup}
'';
};
};