1 { config, lib, pkgs, ... }:
4 cfg = config.system.autoUpgradeWithPinch;
5 auto-upgrade-script = pkgs.writeShellScript "auto-upgrade" ''
6 ${pkgs.utillinux}/bin/flock /run/auto-upgrade-with-pinch ${
7 pkgs.writeShellScript "auto-upgrade-with-lock-held" ''
20 if cfg.userEnvironment.enable then ''
21 /run/wrappers/bin/sudo -u ${escapeShellArg cfg.userEnvironment.user} "$@"
31 ${pkgs.keyedgit cfg.keys}/bin/git pull --ff-only --verify-signatures
32 ${pkgs.pinch}/bin/pinch update channels
36 in_tmpdir ${config.system.build.nixos-rebuild}/bin/nixos-rebuild build
37 as_user nix-build --no-out-link '<nixpkgs>' -A ${
38 escapeShellArg cfg.userEnvironment.package
42 ${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch
43 as_user nix-env -f '<nixpkgs>' -riA ${
44 escapeShellArg cfg.userEnvironment.package
51 system.autoUpgradeWithPinch = {
57 Whether to periodically upgrade NixOS to the latest version.
58 Presumes that /etc/nixos is a git repo with a remote and
59 contains a pinch file called "channels".
67 Specification (in the format described by
68 <citerefentry><refentrytitle>systemd.time</refentrytitle>
69 <manvolnum>7</manvolnum></citerefentry>) of the time at
70 which the update will occur.
77 File containing GPG keys that sign updates. Updates are only merged
78 if the commit at the tip of the remote branch is signed with one of
88 Whether to update a user-environment as well. This update is done
89 with nix-env -riA. Note the -r! I.e., ALL OTHER PACKAGES INSTALLED
90 WITH nix-env WILL BE DELETED!
92 This presumes that you have configured an "entire user environment"
94 https://nixos.wiki/wiki/FAQ#How_can_I_manage_software_with_nix-env_like_with_configuration.nix.3F
96 To check if you're set up for this, run "nix-env --query". If it
97 only lists one package, you're good to go.
104 The username of the user whose environment should be updated.
110 example = "nixos.userPackages";
112 The name of the single package that is the user's entire environment.
120 config = lib.mkIf cfg.enable {
122 security.sudo.extraRules = lib.mkAfter [{
123 groups = [ "users" ];
125 command = "${auto-upgrade-script}";
126 options = [ "NOPASSWD" "NOSETENV" ];
129 # NOSETENV above still allows through ~17 vars, including PATH. Block those
131 security.sudo.extraConfig = ''
132 Defaults!${auto-upgrade-script} !env_check
133 Defaults!${auto-upgrade-script} !env_keep
137 (import ../overlays/keyedgit.nix)
138 (import ../overlays/pinch.nix)
140 auto-upgrade = super.writeShellScriptBin "auto-upgrade" ''
141 /run/wrappers/bin/sudo ${auto-upgrade-script}
146 environment.systemPackages = [ pkgs.auto-upgrade ];
148 systemd.services.nixos-upgrade = {
149 description = "NixOS Upgrade";
150 restartIfChanged = false;
151 unitConfig.X-StopOnRemoval = false;
152 serviceConfig.Type = "oneshot";
153 environment = config.nix.envVars // {
154 inherit (config.environment.sessionVariables) NIX_PATH;
156 } // config.networking.proxy.envVars;
159 config.nix.package.out
171 # Chill for awhile before applying updates. If applying an update
172 # badly breaks things, we want a window in which an operator can
173 # intervene either to fix the problem or disable automatic updates.
176 # Wait until outside business hours
178 day_of_week=$(date +%u)
179 business_start=$(date -d 8:00 +%s)
180 business_end=$( date -d 17:00 +%s)
181 if (( day_of_week <= 5 && now > business_start && now < business_end ));then
182 delay=$((business_end - now))
183 echo "Waiting $delay seconds so we don't upgrade during business hours" >&2
187 ${auto-upgrade-script}
194 assertion = cfg.userEnvironment.enable -> cfg.enable;
196 "User environment upgrades cannot yet be enabled separately from system upgrades.";