From 56bc3161d71995b31dd418e5b2d6b65467d310ec Mon Sep 17 00:00:00 2001 From: moons Date: Thu, 3 Sep 2026 23:26:45 +0900 Subject: [PATCH] nix builder --- hosts/nix-builder/fleet-automation.nix | 82 ++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 hosts/nix-builder/fleet-automation.nix diff --git a/hosts/nix-builder/fleet-automation.nix b/hosts/nix-builder/fleet-automation.nix new file mode 100644 index 0000000..ae4bc5d --- /dev/null +++ b/hosts/nix-builder/fleet-automation.nix @@ -0,0 +1,82 @@ +{ + config, + pkgs, + primaryUser, + ... +}: + +let + homeDirectory = "/home/${primaryUser}"; + fleetDirectory = "${homeDirectory}/srv/nix-fleet"; + stateDirectory = "/var/lib/nix-fleet"; + sourceDirectory = "${stateDirectory}/source"; + + git = "${pkgs.git}/bin/git"; + nix = "${config.nix.package}/bin/nix"; + rsync = "${pkgs.rsync}/bin/rsync"; + + cleanCheckoutConditions = [ + "${git} -C ${fleetDirectory} diff --quiet" + "${git} -C ${fleetDirectory} diff --cached --quiet" + ]; +in +{ + systemd.services.nix-fleet-converge = { + description = "Update inputs, build the fleet, and deploy changed hosts"; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + + environment = { + HOME = homeDirectory; + NIX_CONFIG = '' + accept-flake-config = true + max-jobs = 4 + cores = 3 + ''; + }; + + serviceConfig = { + Type = "oneshot"; + User = primaryUser; + Restart = "on-failure"; + RestartSec = "5min"; + StateDirectory = "nix-fleet"; + StateDirectoryMode = "0750"; + WorkingDirectory = stateDirectory; + UMask = "0077"; + ExecCondition = cleanCheckoutConditions; + + # Work in a disposable copy so updating the dotfiles lock never dirties + # the operator's nix-fleet checkout. + ExecStart = [ + "${git} -C ${fleetDirectory} pull --ff-only" + "${rsync} --archive --delete --exclude=.git/ --exclude=.direnv/ --exclude=result --exclude=result-* ${fleetDirectory}/ ${sourceDirectory}/" + "${nix} flake update --flake ${sourceDirectory} dotfiles" + "${nix} run ${sourceDirectory}#converge -- ${sourceDirectory} ${stateDirectory}" + ]; + }; + }; + + systemd.timers.nix-fleet-converge = { + description = "Periodically converge the NixOS fleet"; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = "2min"; + OnUnitInactiveSec = "5min"; + RandomizedDelaySec = "30s"; + Persistent = true; + Unit = "nix-fleet-converge.service"; + }; + }; + + # Only an actual successful deployment touches gc-request. This starts the + # builder's root nh-clean unit; remote host stores are never cleaned here. + systemd.paths.nix-fleet-gc = { + description = "Garbage-collect superseded fleet builds on nix-builder"; + wantedBy = [ "multi-user.target" ]; + pathConfig = { + PathChanged = "${stateDirectory}/gc-request"; + Unit = "nh-clean.service"; + }; + }; +}