1 { config, lib, pkgs, ... }:
4 cfg = config.system.autoUpgradeWithPinch;
5 auto-upgrade-script = pkgs.writeShellScript "auto-upgrade" ''
6 flock /run/auto-upgrade-with-pinch ${
7 pkgs.writeShellScript "auto-upgrade-with-lock-held" ''
11 ${pkgs.keyedgit cfg.key}/bin/git pull --ff-only --verify-signatures
12 ${pkgs.pinch}/bin/pinch update channels
15 ${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch --no-build-output
21 system.autoUpgradeWithPinch = {
27 Whether to periodically upgrade NixOS to the latest version.
28 Presumes that /etc/nixos is a git repo with a remote and
29 contains a pinch file called "channels".
37 Specification (in the format described by
38 <citerefentry><refentrytitle>systemd.time</refentrytitle>
39 <manvolnum>7</manvolnum></citerefentry>) of the time at
40 which the update will occur.
47 GPG key that signs updates. Updates are only merged if the commit
48 at the tip of the remote branch is signed with this key.
54 config = lib.mkIf cfg.enable {
56 security.sudo.extraRules = lib.mkAfter [{
59 command = "${auto-upgrade-script}";
60 options = [ "NOPASSWD" "NOSETENV" ];
63 # NOSETENV above still allows through ~17 vars, including PATH. Block those
65 security.sudo.extraConfig = ''
66 Defaults!${auto-upgrade-script} !env_check
67 Defaults!${auto-upgrade-script} !env_keep
71 (import ../overlays/keyedgit.nix)
72 (import ../overlays/pinch.nix)
74 auto-upgrade = super.writeShellScriptBin "auto-upgrade" ''
75 sudo ${auto-upgrade-script}
80 environment.systemPackages = [ pkgs.auto-upgrade ];
82 systemd.services.nixos-upgrade = {
83 description = "NixOS Upgrade";
84 restartIfChanged = false;
85 unitConfig.X-StopOnRemoval = false;
86 serviceConfig.Type = "oneshot";
87 environment = config.nix.envVars // {
88 inherit (config.environment.sessionVariables) NIX_PATH;
90 } // config.networking.proxy.envVars;
93 config.nix.package.out
105 # Chill for awhile before applying updates. If applying an update
106 # badly breaks things, we want a window in which an operator can
107 # intervene either to fix the problem or disable automatic updates.
110 # Wait until outside business hours
112 day_of_week=$(date +%u)
113 business_start=$(date -d 8:00 +%s)
114 business_end=$( date -d 17:00 +%s)
115 if (( day_of_week <= 5 && now > business_start && now < business_end ));then
116 delay=$((business_end - now))
117 echo "Waiting $delay seconds so we don't upgrade during business hours" >&2
121 ${auto-upgrade-script}