From 41a3cdbedbf0a7e6ecf42bb5f1da869505f8ea1a Mon Sep 17 00:00:00 2001 From: Daniel Frank Date: Wed, 3 Jul 2019 22:31:48 +0200 Subject: [PATCH] allow automatic rebooting on kernel updates --- auto-upgrade.nix | 119 ++++++++++++++++++++++++++++++++++++++++++++++ configuration.nix | 3 ++ 2 files changed, 122 insertions(+) create mode 100644 auto-upgrade.nix diff --git a/auto-upgrade.nix b/auto-upgrade.nix new file mode 100644 index 0000000..64ad27f --- /dev/null +++ b/auto-upgrade.nix @@ -0,0 +1,119 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.system.autoUpgrade; in + +{ + + options = { + + system.autoUpgrade = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to periodically upgrade NixOS to the latest + version. If enabled, a systemd timer will run + nixos-rebuild switch --upgrade once a + day. + ''; + }; + + channel = mkOption { + type = types.nullOr types.str; + default = null; + example = https://nixos.org/channels/nixos-14.12-small; + description = '' + The URI of the NixOS channel to use for automatic + upgrades. By default, this is the channel set using + nix-channel (run nix-channel + --list to see the current value). + ''; + }; + + flags = mkOption { + type = types.listOf types.str; + default = []; + example = [ "-I" "stuff=/home/alice/nixos-stuff" "--option" "extra-binary-caches" "http://my-cache.example.org/" ]; + description = '' + Any additional flags passed to nixos-rebuild. + ''; + }; + + 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. + ''; + }; + + allowReboot = mkOption { + default = false; + type = types.bool; + description = '' + Shall the system be rebooted if the new configuration + uses a different kernel, kernel modules or initrd + than the booted system? + ''; + }; + + }; + + }; + + config = { + + system.autoUpgrade.flags = + [ "--no-build-output" ] + ++ (if cfg.channel == null + then [ "--upgrade" ] + else [ "-I" "nixpkgs=${cfg.channel}/nixexprs.tar.xz" ]); + + 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 = [ pkgs.gnutar pkgs.xz.bin pkgs.gitMinimal config.nix.package.out ]; + + script = '' + ${lib.optionalString cfg.allowReboot '' + set -euo pipefail + set -x + T=$(mktemp -d) + cd "$T" + ${config.system.build.nixos-rebuild}/bin/nixos-rebuild build ${toString cfg.flags} + booted="$(${pkgs.coreutils}/bin/readlink /run/booted-system/{initrd,kernel,kernel-modules})" + built="$(${pkgs.coreutils}/bin/readlink result/{initrd,kernel,kernel-modules})" + cd /tmp + rm -rf "$T" + if [ "$booted" = "$built" ]; then + ${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch ${toString cfg.flags} + else + ${config.system.build.nixos-rebuild}/bin/nixos-rebuild boot ${toString cfg.flags} + /run/current-system/sw/bin/shutdown -r +1 + fi + ''} + ${lib.optionalString (!cfg.allowReboot) "${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch ${toString cfg.flags}"} + ''; + + startAt = optional cfg.enable cfg.dates; + }; + + }; + +} diff --git a/configuration.nix b/configuration.nix index 31d11ed..edfc499 100644 --- a/configuration.nix +++ b/configuration.nix @@ -5,8 +5,10 @@ { config, pkgs, ... }: { + disabledModules = [ "tasks/auto-upgrade.nix" ]; imports = [ + ./auto-upgrade.nix ./hardware-configuration.nix ./sshusers.nix ./variables.nix @@ -51,6 +53,7 @@ # Automatic update each day at 04:40. Will not restart the system, so a reboot every now and then is a good idea. system.autoUpgrade.enable = true; + system.autoUpgrade.allowReboot = true; nix = { autoOptimiseStore = true; gc.automatic = true;