{ config, lib, pkgs, ... }: with lib; let cfg = config.system.autoUpgradeWithPinch; in { options = { system.autoUpgradeWithPinch = { enable = mkOption { type = types.bool; default = false; description = '' Whether to periodically upgrade NixOS to the latest version. Presumes that /etc/nixos is a git repo with a remote and contains a pinch file called "channels". ''; }; dates = mkOption { default = "04:40"; type = types.str; description = '' Specification (in the format described by systemd.time 7) of the time at which the update will occur. ''; }; key = mkOption { type = types.path; description = '' GPG key that signs updates. Updates are only merged if the commit at the tip of the remote branch is signed with this key. ''; }; }; }; config = lib.mkIf cfg.enable { nixpkgs.overlays = [ (import ../overlays/keyedgit.nix) (import ../overlays/pinch.nix) (self: super: { auto-upgrade = super.writeShellScriptBin "auto-upgrade" '' flock /run/auto-upgrade-with-pinch ${super.writeShellScript "auto-upgrade-with-lock-held" '' set -e ( cd /etc/nixos ${self.keyedgit cfg.key}/bin/git pull --ff-only --verify-signatures ${self.pinch}/bin/pinch update channels ) ${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch --no-build-output ''} ''; }) ]; environment.systemPackages = [ pkgs.auto-upgrade ]; systemd.services.nixos-upgrade = { description = "NixOS Upgrade"; restartIfChanged = false; unitConfig.X-StopOnRemoval = false; serviceConfig.Type = "oneshot"; environment = config.nix.envVars // { inherit (config.environment.sessionVariables) NIX_PATH; HOME = "/root"; } // config.networking.proxy.envVars; path = with pkgs; [ config.nix.package.out coreutils git gitMinimal gnutar gzip xz.bin ]; script = '' set -e # Chill for awhile before applying updates. If applying an update # badly breaks things, we want a window in which an operator can # intervene either to fix the problem or disable automatic updates. sleep 2h ${pkgs.auto-upgrade}/bin/auto-upgrade ''; startAt = cfg.dates; }; }; }