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;