{ config, lib, pkgs, ... }: let cfg = config.modules.frajulAutoUpgrade; flagFile = "/var/lib/frajul-auto-upgrade/flag"; lockFile = "/var/lib/frajul-auto-upgrade/lock"; lastStatusFile = "/var/lib/nixos-auto-upgrade/last-status"; in { options.modules.frajulAutoUpgrade = { enable = lib.mkEnableOption "NixOS auto-upgrade on boot"; user = lib.mkOption { type = lib.types.str; default = "root"; description = "User account to run the upgrade service as."; }; flakePath = lib.mkOption { type = lib.types.path; description = "The path to your flake"; }; }; config = lib.mkIf cfg.enable { # Ensure the flag directory exists systemd.tmpfiles.rules = [ "d /var/lib/frajul-auto-upgrade 0755 root root -" "f ${flagFile} 0766 root root -" "f ${lastStatusFile} 0644 root root -" ]; environment.systemPackages = [ (pkgs.writeShellScriptBin "frajul-auto-upgrade" '' #!/bin/sh FLAG_FILE="${flagFile}" LOCK_FILE="${lockFile}" LAST_STATUS_FILE="${lastStatusFile}" if [ ! -f "$FLAG_FILE" ] || [ "$(cat "$FLAG_FILE")" != "enabled" ]; then exit 0 fi if [ -f "$LOCK_FILE" ]; then echo "Already running" exit 1 fi echo $$ > "$LOCK_FILE" trap 'rm -f "$LOCK_FILE"' EXIT if nix flake update --flake "${cfg.flakePath}" && nixos-rebuild switch --flake "${cfg.flakePath}"; then echo "success" > "$LAST_STATUS_FILE" else echo "failure" > "$LAST_STATUS_FILE" fi '') (pkgs.writeShellScriptBin "frajul-auto-upgrade-status" '' #!/bin/sh FLAG_FILE="${flagFile}" LOCK_FILE="${lockFile}" LAST_STATUS_FILE="${lastStatusFile}" if [ -f "$LOCK_FILE" ]; then ICON=" " STATUS="running" elif [ -f "$FLAG_FILE" ] && [ "$(cat "$FLAG_FILE")" == "enabled" ]; then LAST="unknown" if [ -f "$LAST_STATUS_FILE" ]; then LAST=$(cat "$LAST_STATUS_FILE") fi if [ "$LAST" = "success" ]; then ICON="" elif [ "$LAST" = "failure" ]; then ICON="" else ICON="" fi STATUS="enabled (last: $LAST)" else ICON=" " STATUS="disabled" fi echo "{\"text\": \"$ICON\", \"tooltip\": \"NixOS Auto Update: $STATUS\"}" '') (pkgs.writeShellScriptBin "frajul-auto-upgrade-toggle" '' #!/bin/sh FLAG_FILE="${flagFile}" LOCK_FILE="${lockFile}" if [ ! -f "$FLAG_FILE" ] || [ "$(cat "$FLAG_FILE")" != "enabled" ]; then echo "enabled" > "$FLAG_FILE" else echo "disabled" > "$FLAG_FILE" if [ -f "$LOCK_FILE" ]; then kill -TERM "$(cat "$LOCK_FILE")" fi fi '') ]; systemd.services.frajul-auto-upgrade = { description = "Frajul's NixOS Auto Upgrade"; after = ["network-online.target"]; restartIfChanged = false; # Do not start service on nixos switch serviceConfig = { Type = "oneshot"; User = cfg.user; ExecStart = "/run/current-system/sw/bin/frajul-auto-upgrade"; }; }; systemd.timers.frajul-auto-upgrade = { description = "Run Frajul's NixOS Auto Upgrade at boot"; wantedBy = ["timers.target"]; timerConfig = { OnBootSec = "1min"; AccuracySec = "10s"; Unit = "frajul-auto-upgrade.service"; }; }; }; }