Harden deployment, authentication, firewall and media storage failure paths

This commit is contained in:
rope 2026-09-14 11:50:22 +01:00
parent 64ede7bd05
commit 7145a35927
35 changed files with 2529 additions and 499 deletions

75
services/deployment.nix Normal file
View file

@ -0,0 +1,75 @@
# One protected activation path for manual, UI and nightly server deployments.
{ config, lib, pkgs, ... }:
let
worker = pkgs.writeShellApplication {
name = "fred-deploy-worker";
runtimeInputs = [
config.nix.package pkgs.systemd pkgs.iproute2 pkgs.iputils
pkgs.nftables pkgs.dig pkgs.curl
];
text = ''
export FRED_DEPLOY_RUNNER="$0"
exec ${pkgs.python3}/bin/python3 ${../scripts/deploy.py} "$@"
'';
};
command = pkgs.writeShellApplication {
name = "fred-deploy";
text = ''
if [ "''${1-}" = recover ]; then
shift
if [ -x /nix/var/nix/gcroots/fred-deploy/runner/bin/fred-deploy-worker ]; then
exec /nix/var/nix/gcroots/fred-deploy/runner/bin/fred-deploy-worker launch-recovery "$@"
fi
exec ${worker}/bin/fred-deploy-worker launch-recovery "$@"
fi
exec ${worker}/bin/fred-deploy-worker launch "$@"
'';
};
in {
config = lib.mkIf (config.networking.hostName == "FredOS-Mediaserver") {
environment.systemPackages = [ command ];
system.build.deploy = command;
systemd.services.nixos-upgrade = {
description = "Build, verify and commit the nightly server deployment";
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
restartIfChanged = false;
unitConfig.X-StopOnRemoval = false;
serviceConfig = {
Type = "oneshot";
ExecStart = "${command}/bin/fred-deploy --reboot";
TimeoutStartSec = "105min";
};
};
systemd.timers.nixos-upgrade = {
wantedBy = [ "timers.target" ];
timerConfig = { OnCalendar = "05:15"; Persistent = true; };
};
# Transient rollback timers do not survive reboot. Recover unfinished
# transactions from durable state using the pinned transaction runner.
systemd.services.fred-deploy-recover = {
description = "Recover an interrupted server deployment";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
before = [ "wan-watchdog.service" "nixos-upgrade.service" ];
restartIfChanged = false;
unitConfig.X-StopOnRemoval = false;
# A oneshot WantedBy=multi-user would hold up that target while the
# activation script waits for target start jobs: use exec so boot can
# finish while recovery holds the shared deployment lock.
serviceConfig = {
Type = "exec";
RuntimeMaxSec = "15min";
TimeoutStopSec = "10s";
};
script = ''
if [ -x /nix/var/nix/gcroots/fred-deploy/runner/bin/fred-deploy-worker ]; then
exec /nix/var/nix/gcroots/fred-deploy/runner/bin/fred-deploy-worker recover --boot
fi
exec ${worker}/bin/fred-deploy-worker recover --boot
'';
};
};
}