This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

superconfig / configs / autoupdate.nix
2.9 kB 79 lines
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 flake = "github:lassulus/superconfig"; 9 10 # The revision the guard checked; the upgrade is pinned to it, so the 11 # revision recorded afterwards is the one actually switched to. 12 revFile = "/run/nixos-upgrade/rev"; 13 14 # system.autoUpgrade switches to whatever the flake currently evaluates to, 15 # forwards or backwards. A machine deployed from an unpushed local checkout 16 # therefore gets reverted to the older remote HEAD on the next timer run. 17 # Refuse to move backwards in time: only upgrade to a revision committed 18 # after the running system was deployed. The deploy time is when its profile 19 # generation was created (/run/current-system's mtime if no generation points 20 # at it); the source's own lastModified is no use, since `clan machines 21 # update` builds from a path: flake, which has none. 22 guard = pkgs.writeShellApplication { 23 name = "autoupgrade-forward-only"; 24 runtimeInputs = [ 25 config.nix.package 26 pkgs.coreutils 27 pkgs.jq 28 ]; 29 text = '' 30 system=$(readlink -f /run/current-system) 31 deployed=0 32 for link in /nix/var/nix/profiles/system-*-link; do 33 if [ "$(readlink -f "$link")" = "$system" ]; then 34 created=$(stat -c %Y "$link") 35 if [ "$created" -gt "$deployed" ]; then deployed=$created; fi 36 fi 37 done 38 if [ "$deployed" -eq 0 ]; then deployed=$(stat -c %Y /run/current-system); fi 39 if ! meta=$(nix flake metadata --refresh --json ${lib.escapeShellArg flake}); then 40 echo "autoupgrade: cannot reach ${flake}; letting nixos-upgrade report the error" 41 exit 0 42 fi 43 remote=$(jq -r '.lastModified // 0' <<<"$meta") 44 if [ "$remote" -gt "$deployed" ]; then 45 jq -r .revision <<<"$meta" >${revFile} 46 exit 0 47 fi 48 echo "autoupgrade: ${flake} is at $remote, running system was deployed at $deployed; skipping" 49 exit 1 50 ''; 51 }; 52in 53{ 54 system.autoUpgrade = { 55 enable = true; 56 # Goes into the nixos-upgrade script unquoted, so the shell expands the 57 # pinned revision. Without a rev file (guard could not reach the flake) 58 # the ref stays unpinned and the recorded revision becomes unknown. 59 flake = "${flake}/$(cat ${revFile} 2>/dev/null)"; 60 randomizedDelaySec = "6h"; 61 }; 62 63 systemd.services.nixos-upgrade.serviceConfig = { 64 RuntimeDirectory = "nixos-upgrade"; 65 ExecCondition = lib.getExe guard; 66 # Only runs after a successful upgrade. Read by the monitoring agent. 67 ExecStartPost = lib.getExe ( 68 pkgs.writeShellApplication { 69 name = "autoupgrade-record-revision"; 70 runtimeInputs = [ pkgs.coreutils ]; 71 text = '' 72 rev=$(cat ${revFile} 2>/dev/null || echo unknown) 73 echo "$rev" >/var/lib/superconfig-revision.tmp 74 mv /var/lib/superconfig-revision.tmp /var/lib/superconfig-revision 75 ''; 76 } 77 ); 78 }; 79}