# 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 ''; }; }; }