]> git.scottworley.com Git - auto-upgrade-with-pinch/blob - modules/auto-upgrade.nix
Don't upgrade during business hours
[auto-upgrade-with-pinch] / modules / auto-upgrade.nix
1 { config, lib, pkgs, ... }:
2 with lib;
3 let cfg = config.system.autoUpgradeWithPinch;
4 in {
5 options = {
6 system.autoUpgradeWithPinch = {
7
8 enable = mkOption {
9 type = types.bool;
10 default = false;
11 description = ''
12 Whether to periodically upgrade NixOS to the latest version.
13 Presumes that /etc/nixos is a git repo with a remote and
14 contains a pinch file called "channels".
15 '';
16 };
17
18 dates = mkOption {
19 default = "04:40";
20 type = types.str;
21 description = ''
22 Specification (in the format described by
23 <citerefentry><refentrytitle>systemd.time</refentrytitle>
24 <manvolnum>7</manvolnum></citerefentry>) of the time at
25 which the update will occur.
26 '';
27 };
28
29 key = mkOption {
30 type = types.path;
31 description = ''
32 GPG key that signs updates. Updates are only merged if the commit
33 at the tip of the remote branch is signed with this key.
34 '';
35 };
36 };
37 };
38
39 config = lib.mkIf cfg.enable {
40 nixpkgs.overlays = [
41 (import ../overlays/keyedgit.nix)
42 (import ../overlays/pinch.nix)
43 (self: super: {
44 auto-upgrade = super.writeShellScriptBin "auto-upgrade" ''
45 flock /run/auto-upgrade-with-pinch ${super.writeShellScript "auto-upgrade-with-lock-held" ''
46 set -e
47 (
48 cd /etc/nixos
49 ${self.keyedgit cfg.key}/bin/git pull --ff-only --verify-signatures
50 ${self.pinch}/bin/pinch update channels
51 )
52
53 ${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch --no-build-output
54 ''}
55 '';
56 })
57 ];
58
59 environment.systemPackages = [ pkgs.auto-upgrade ];
60
61 systemd.services.nixos-upgrade = {
62 description = "NixOS Upgrade";
63 restartIfChanged = false;
64 unitConfig.X-StopOnRemoval = false;
65 serviceConfig.Type = "oneshot";
66 environment = config.nix.envVars // {
67 inherit (config.environment.sessionVariables) NIX_PATH;
68 HOME = "/root";
69 } // config.networking.proxy.envVars;
70
71 path = with pkgs; [
72 config.nix.package.out
73 coreutils
74 git
75 gitMinimal
76 gnutar
77 gzip
78 xz.bin
79 ];
80
81 script = ''
82 set -e
83
84 # Chill for awhile before applying updates. If applying an update
85 # badly breaks things, we want a window in which an operator can
86 # intervene either to fix the problem or disable automatic updates.
87 sleep 2h
88
89 # Wait until outside business hours
90 now=$(date +%s)
91 day_of_week=$(date +%u)
92 business_start=$(date -d 8:00 +%s)
93 business_end=$( date -d 17:00 +%s)
94 if (( day_of_week <= 5 && now > business_start && now < business_end ));then
95 delay=$((business_end - now))
96 echo "Waiting $delay seconds so we don't upgrade during business hours" >&2
97 sleep "$delay"
98 fi
99
100 ${pkgs.auto-upgrade}/bin/auto-upgrade
101 '';
102
103 startAt = cfg.dates;
104 };
105 };
106 }