{ config , lib , pkgs , ... }: let cfg = config.system.autoUpgrade; updateScript = pkgs.writeShellApplication { name = "update"; runtimeInputs = with pkgs; [ git nix ]; text = '' cd ${cfg.flake} git pull nix flake update --commit-lock-file ${lib.optionalString (cfg.extraCommands != null) "${cfg.extraCommands}"} git push ''; }; in { options.system.autoUpgrade = { # TODO: make sure system.autoUpgrade.flake is a local folder updateFlake = lib.mkOption { default = false; description = "Update lockfile of the flake."; example = true; }; extraCommands = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; description = "Extra commands to run during upgrade"; }; failureNotification = { enable = lib.mkOption { default = false; description = "Enable ntfy notification on upgrade failure."; example = true; }; ntfyUrlFile = lib.mkOption { type = lib.types.nullOr lib.types.path; description = "Environment file containing NTFY_URL"; example = "/etc/secrets/failureNotification.env"; }; }; }; config.systemd.services = lib.mkIf cfg.enable { nixos-upgrade.serviceConfig.ExecStartPre = lib.mkIf cfg.updateFlake (lib.getExe updateScript); nixos-upgrade-failure = lib.mkIf cfg.failureNotification.enable { path = with pkgs; [ "/run/wrappers" "/run/current-system/sw" curl ]; script = '' journalctl _SYSTEMD_INVOCATION_ID=`systemctl show --value -p InvocationID nixos-upgrade.service` > /tmp/upgrade-failure.txt curl -T /tmp/upgrade-failure.txt -H "Filename: failure-logs.txt" -H "Title: Nixos auto upgrade failed for $(hostname)" $NTFY_URL rm /tmp/upgrade-failure.txt ''; serviceConfig = { User = "root"; EnvironmentFile = cfg.failureNotification.ntfyUrlFile; }; }; nixos-upgrade.onFailure = lib.mkIf cfg.failureNotification.enable [ "nixos-upgrade-failure.service" ]; }; }