This repository has no description
1.9 kB
56 lines
1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 flake = "github:lassulus/superconfig";
9
10 # system.autoUpgrade switches to whatever the flake currently evaluates to,
11 # forwards or backwards. A machine deployed from an unpushed local checkout
12 # therefore gets reverted to the older remote HEAD on the next timer run.
13 # Refuse to move backwards in time: only upgrade to a revision committed
14 # after the running system was deployed. The deploy time is when its profile
15 # generation was created (/run/current-system's mtime if no generation points
16 # at it); the source's own lastModified is no use, since `clan machines
17 # update` builds from a path: flake, which has none.
18 guard = pkgs.writeShellApplication {
19 name = "autoupgrade-forward-only";
20 runtimeInputs = [
21 config.nix.package
22 pkgs.coreutils
23 pkgs.jq
24 ];
25 text = ''
26 system=$(readlink -f /run/current-system)
27 deployed=0
28 for link in /nix/var/nix/profiles/system-*-link; do
29 if [ "$(readlink -f "$link")" = "$system" ]; then
30 created=$(stat -c %Y "$link")
31 if [ "$created" -gt "$deployed" ]; then deployed=$created; fi
32 fi
33 done
34 if [ "$deployed" -eq 0 ]; then deployed=$(stat -c %Y /run/current-system); fi
35 if ! meta=$(nix flake metadata --refresh --json ${lib.escapeShellArg flake}); then
36 echo "autoupgrade: cannot reach ${flake}; letting nixos-upgrade report the error"
37 exit 0
38 fi
39 remote=$(jq -r '.lastModified // 0' <<<"$meta")
40 if [ "$remote" -gt "$deployed" ]; then
41 exit 0
42 fi
43 echo "autoupgrade: ${flake} is at $remote, running system was deployed at $deployed; skipping"
44 exit 1
45 '';
46 };
47in
48{
49 system.autoUpgrade = {
50 enable = true;
51 inherit flake;
52 randomizedDelaySec = "6h";
53 };
54
55 systemd.services.nixos-upgrade.serviceConfig.ExecCondition = lib.getExe guard;
56}