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.key}/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 GPG key that signs updates. Updates are only merged if the commit
78 at the tip of the remote branch is signed with this key.
87 Whether to update a user-environment as well. This update is done
88 with nix-env -riA. Note the -r! I.e., ALL OTHER PACKAGES INSTALLED
89 WITH nix-env WILL BE DELETED!
91 This presumes that you have configured an "entire user environment"
93 https://nixos.wiki/wiki/FAQ#How_can_I_manage_software_with_nix-env_like_with_configuration.nix.3F
95 To check if you're set up for this, run "nix-env --query". If it
96 only lists one package, you're good to go.
103 The username of the user whose environment should be updated.
109 example = "nixos.userPackages";
111 The name of the single package that is the user's entire environment.
119 config = lib.mkIf cfg.enable {
121 security.sudo.extraRules = lib.mkAfter [{
122 groups = [ "users" ];
124 command = "${auto-upgrade-script}";
125 options = [ "NOPASSWD" "NOSETENV" ];
128 # NOSETENV above still allows through ~17 vars, including PATH. Block those
130 security.sudo.extraConfig = ''
131 Defaults!${auto-upgrade-script} !env_check
132 Defaults!${auto-upgrade-script} !env_keep
136 (import ../overlays/keyedgit.nix)
137 (import ../overlays/pinch.nix)
139 auto-upgrade = super.writeShellScriptBin "auto-upgrade" ''
140 /run/wrappers/bin/sudo ${auto-upgrade-script}
145 environment.systemPackages = [ pkgs.auto-upgrade ];
147 systemd.services.nixos-upgrade = {
148 description = "NixOS Upgrade";
149 restartIfChanged = false;
150 unitConfig.X-StopOnRemoval = false;
151 serviceConfig.Type = "oneshot";
152 environment = config.nix.envVars // {
153 inherit (config.environment.sessionVariables) NIX_PATH;
155 } // config.networking.proxy.envVars;
158 config.nix.package.out
170 # Chill for awhile before applying updates. If applying an update
171 # badly breaks things, we want a window in which an operator can
172 # intervene either to fix the problem or disable automatic updates.
175 # Wait until outside business hours
177 day_of_week=$(date +%u)
178 business_start=$(date -d 8:00 +%s)
179 business_end=$( date -d 17:00 +%s)
180 if (( day_of_week <= 5 && now > business_start && now < business_end ));then
181 delay=$((business_end - now))
182 echo "Waiting $delay seconds so we don't upgrade during business hours" >&2
186 ${auto-upgrade-script}
193 assertion = cfg.userEnvironment.enable -> cfg.enable;
195 "User environment upgrades cannot yet be enabled separately from system upgrades.";