auto update

This commit is contained in:
Sam 2025-01-16 13:51:46 +00:00
parent 771e37650f
commit dcc9eaa74d
6 changed files with 215 additions and 2 deletions

98
bin/auto-update-nixos Executable file
View File

@ -0,0 +1,98 @@
#!/usr/bin/env bash
# Wrapper script for nixos-rebuild
# Configuration parameters
operation="switch" # The nixos-rebuild operation to use
hostname=$(/run/current-system/sw/bin/hostname) # The name of the host to build
flakeDir="${FLAKE_DIR}" # Path to the flake file (and optionally the hostname). Defaults to the FLAKE_DIR environment variable.
update=false # Whether to update flake.lock (false by default)
user=$(/run/current-system/sw/bin/whoami) # Which user account to use for git commands (defaults to whoever called the script)
remainingArgs="" # All remaining arguments that haven't yet been processed (will be passed to nixos-rebuild)
function usage() {
echo "nixos-rebuild Operations Script (NOS) updates your system and your flake.lock file by pulling the latest versions."
echo ""
echo "Running the script with no parameters performs the following operations:"
echo " 1. Pull the latest version of the config"
echo " 2. Update your flake.lock file"
echo " 3. Commit any changes back to the repository"
echo " 4. Run 'nixos-rebuild switch'."
echo ""
echo "Advanced usage: nixos-upgrade-script.sh [-o|--operation operation] [-f|--flake path-to-flake] [extra nixos-rebuild parameters]"
echo "Options:"
echo " -h, --help Show this help screen."
echo " -o, --operation The nixos-rebuild operation to perform."
echo " -f, --flake <path> The path to your flake.nix file (and optionally, the hostname to build)."
echo " -U, --update Update and commit flake.lock."
echo " -u, --user Which user account to run git commands under."
echo ""
exit 2
}
# Argument processing logic shamelessly stolen from https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash
POSITIONAL_ARGS=()
while [[ $# -gt 0 ]]; do
case "$1" in
--flake|-f)
flakeDir="$2"
shift
shift
;;
--update|--upgrade|-U)
update=true
shift
;;
--operation|-o)
operation="$2"
shift
shift
;;
--user|-u)
user="$2"
shift
shift
;;
--help|-h)
usage
exit 0
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift
;;
esac
done
remainingArgs=${POSITIONAL_ARGS[@]}
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
if [ -z "${flakeDir}" ]; then
echo "Flake directory not specified. Use '--flake <path>' or set \$FLAKE_DIR."
exit 1
fi
cd $flakeDir
echo "Pulling the latest version of the repository..."
/run/wrappers/bin/sudo -u $user git pull
if [ $update = true ]; then
echo "Updating flake.lock..."
/run/wrappers/bin/sudo -u $user nix flake update --commit-lock-file && /run/wrappers/bin/sudo -u $user git push
else
echo "Skipping 'nix flake update'..."
fi
options="--flake $flakeDir $remainingArgs --use-remote-sudo"
echo "Running this operation: nixos-rebuild $operation $options"
/run/wrappers/bin/sudo -u root /run/current-system/sw/bin/nixos-rebuild $operation $options
echo "Checking if reboot is necessary"
reboot=$(diff <(readlink /run/booted-system/{initrd,kernel,kernel-modules}) <(readlink /nix/var/nix/profiles/system/{initrd,kernel,kernel-modules}))
if [ -z "$reboot" ]; then
echo "No reboot necessary, exiting."
exit 0
else
echo "System requires a reboot. Rebooting now..."
reboot
fi

View File

@ -129,6 +129,7 @@
inherit specialArgs;
modules = [
./hosts/citadel
home-manager.nixosModules.home-manager
{
home-manager.extraSpecialArgs = specialArgs;

View File

@ -4,6 +4,7 @@
pkgs,
config,
configVars,
outputs,
...
}: let
# Disko setup
@ -60,6 +61,9 @@ in {
# This machine is used for remote building
../common/optional/distributed-builds/remote-builder-machine.nix
# ../../modules/nixos
outputs.nixosModules.nixosAutoUpgrade
];
boot = {
@ -84,6 +88,15 @@ in {
}
];
system.services.nixosAutoUpgrade = {
enable = true;
persistent = true;
pushUpdates = true;
configDir = "/etc/nixos";
onCalendar = "daily";
user = "sam";
};
services = {
libinput.touchpad.accelSpeed = "0.5";
xserver = {
@ -99,7 +112,7 @@ in {
# ${pkgs.xorg.xmodmap}/bin/xmodmap -e "keycode 46 = l L Right L"
# '';
};
# enable oom killer when system ram drops below 5% free
# enable oom killer when system ram drops below 5% free
earlyoom = {
enable = true;
freeMemThreshold = 5; # <%5 free

View File

@ -47,9 +47,17 @@ in
pkgs.rsync
pkgs.curl
pkgs.just
pkgs.git
pkgs.vim
];
programs.git = {
enable = true;
package = pkgs.git;
config = {
# need to set /etc/nixos as safe directory to enable root to interact with non-root nix config repo
safe = {directory = ["/etc/nixos"]; };
};
};
system.stateVersion = "24.05";
}

View File

@ -0,0 +1,4 @@
{
nixosAutoUpgrade = import ./nixosAutoUpgrade.nix;
}

View File

@ -0,0 +1,89 @@
# Run automatic updates. Replaces system.nixosAutoUpgrade.
{ config, lib, pkgs, ... }:
let
cfg = config.system.services.nixosAutoUpgrade;
auto-update-nixos = pkgs.writeShellScriptBin "auto-update-nixos" (
builtins.readFile ../../bin/auto-update-nixos
);
in
{
options = {
system.services.nixosAutoUpgrade = {
enable = lib.mkEnableOption "Enables automatic system updates.";
configDir = lib.mkOption {
type = lib.types.str;
description = "Path where your NixOS configuration files are stored.";
};
extraFlags = lib.mkOption {
type = lib.types.str;
description = "Extra flags to pass to nixos-rebuild.";
default = "";
};
onCalendar = lib.mkOption {
default = "daily";
type = lib.types.str;
description = "How frequently to run updates. See systemd.timer(5) and systemd.time(7) for configuration details.";
};
operation = lib.mkOption {
type = lib.types.enum [
"boot"
"switch"
"test"
];
default = "switch";
description = "Which `nixos-rebuild` operation to perform. Defaults to `switch`.";
};
persistent = lib.mkOption {
default = true;
type = lib.types.bool;
description = "If true, the time when the service unit was last triggered is stored on disk. When the timer is activated, the service unit is triggered immediately if it would have been triggered at least once during the time when the timer was inactive. This is useful to catch up on missed runs of the service when the system was powered down.";
};
pushUpdates = lib.mkEnableOption "Updates the flake.lock file and pushes it back to the repo.";
user = lib.mkOption {
type = lib.types.str;
description = "The user who owns the configDir.";
};
};
};
config = lib.mkIf cfg.enable {
# Assert that system.nixosAutoUpgrade is not also enabled
assertions = [
{
assertion = !config.system.autoUpgrade.enable;
message = "The system.nixosAutoUpgrade option conflicts with this module.";
}
];
# Pull and apply updates.
systemd = {
services."nixos-upgrade" = {
serviceConfig = {
Type = "oneshot";
User = "root";
};
path = ["/run/current-system/sw"];
unitConfig.RequiresMountsFor = cfg.configDir;
script = lib.strings.concatStrings [
"${auto-update-nixos}/bin/auto-update-nixos --operation ${cfg.operation} "
(lib.mkIf (cfg.configDir != "") "--flake ${cfg.configDir} ").content
(lib.mkIf (cfg.user != "") "--user ${cfg.user} ").content
(lib.mkIf (cfg.pushUpdates) "--update ").content
(lib.mkIf (cfg.extraFlags != "") cfg.extraFlags).content
];
};
timers."nixos-upgrade" = {
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = cfg.onCalendar;
Persistent = cfg.persistent;
Unit = "nixos-upgrade.service";
RandomizedDelaySec = "30m";
};
};
};
};
}