summary refs log tree commit diff
path: root/nixos/modules
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/installer/cd-dvd/iso-image.nix14
-rw-r--r--nixos/modules/installer/tools/nixos-generate-config.pl3
-rw-r--r--nixos/modules/installer/tools/tools.nix1
-rw-r--r--nixos/modules/misc/version.nix26
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/databases/postgresql.nix7
-rw-r--r--nixos/modules/services/mail/dovecot.nix7
-rw-r--r--nixos/modules/services/misc/gitit.nix11
-rw-r--r--nixos/modules/services/misc/nix-daemon.nix2
-rw-r--r--nixos/modules/services/networking/copy-com.nix106
-rw-r--r--nixos/modules/services/networking/firewall.nix14
-rw-r--r--nixos/modules/services/networking/heyefi.nix82
-rw-r--r--nixos/modules/services/networking/ssh/sshd.nix15
-rw-r--r--nixos/modules/services/scheduling/cron.nix65
-rw-r--r--nixos/modules/services/x11/desktop-managers/gnome3.nix2
-rw-r--r--nixos/modules/services/x11/desktop-managers/xfce.nix2
-rw-r--r--nixos/modules/services/x11/redshift.nix10
-rw-r--r--nixos/modules/services/x11/window-managers/icewm.nix17
-rw-r--r--nixos/modules/services/x11/window-managers/oroborus.nix25
-rw-r--r--nixos/modules/system/boot/kernel.nix5
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix42
-rw-r--r--nixos/modules/system/boot/loader/grub/install-grub.pl13
22 files changed, 315 insertions, 155 deletions
diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix
index c9abff2ecfc0..fa9cc6fa20b9 100644
--- a/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -30,8 +30,7 @@ let
   #   * COM32 entries (chainload, reboot, poweroff) are not recognized. They
   #     result in incorrect boot entries.
 
-  baseIsolinuxCfg =
-    ''
+  baseIsolinuxCfg = ''
     SERIAL 0 38400
     TIMEOUT ${builtins.toString syslinuxTimeout}
     UI vesamenu.c32
@@ -44,7 +43,7 @@ let
     LINUX /boot/bzImage
     APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
     INITRD /boot/initrd
-    '';
+  '';
 
   isolinuxMemtest86Entry = ''
     LABEL memtest
@@ -55,12 +54,12 @@ let
 
   isolinuxCfg = baseIsolinuxCfg + (optionalString config.boot.loader.grub.memtest86.enable isolinuxMemtest86Entry);
 
-  # The efi boot image
+  # The EFI boot image.
   efiDir = pkgs.runCommand "efi-directory" {} ''
     mkdir -p $out/EFI/boot
     cp -v ${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi $out/EFI/boot/boot${targetArch}.efi
     mkdir -p $out/loader/entries
-    echo "title NixOS LiveCD" > $out/loader/entries/nixos-livecd.conf
+    echo "title NixOS Live CD" > $out/loader/entries/nixos-livecd.conf
     echo "linux /boot/bzImage" >> $out/loader/entries/nixos-livecd.conf
     echo "initrd /boot/initrd" >> $out/loader/entries/nixos-livecd.conf
     echo "options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" >> $out/loader/entries/nixos-livecd.conf
@@ -218,6 +217,8 @@ in
     system.boot.loader.kernelFile = "bzImage";
     environment.systemPackages = [ pkgs.grub2 pkgs.grub2_efi pkgs.syslinux ];
 
+    boot.consoleLogLevel = mkDefault 7;
+
     # In stage 1 of the boot, mount the CD as the root FS by label so
     # that we don't need to know its device.  We pass the label of the
     # root filesystem on the kernel command line, rather than in
@@ -229,6 +230,7 @@ in
     boot.kernelParams =
       [ "root=LABEL=${config.isoImage.volumeID}"
         "boot.shell_on_fail"
+        "nomodeset"
       ];
 
     fileSystems."/" =
@@ -268,6 +270,8 @@ in
 
     boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "usb-storage" ];
 
+    boot.blacklistedKernelModules = [ "nouveau" ];
+
     boot.initrd.kernelModules = [ "loop" ];
 
     # Closures to be copied to the Nix store on the CD, namely the init
diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl
index 187ea7635eb5..9010478662cc 100644
--- a/nixos/modules/installer/tools/nixos-generate-config.pl
+++ b/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -544,6 +544,9 @@ $bootLoaderConfig
   #   uid = 1000;
   # };
 
+  # The NixOS release to be compatible with for stateful data such as databases.
+  system.stateVersion = "@nixosRelease@";
+
 }
 EOF
     } else {
diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix
index 99a74b6d59ed..61744c39d601 100644
--- a/nixos/modules/installer/tools/tools.nix
+++ b/nixos/modules/installer/tools/tools.nix
@@ -40,6 +40,7 @@ let
     src = ./nixos-generate-config.pl;
     path = [ pkgs.btrfsProgs ];
     perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl";
+    inherit (config.system) nixosRelease;
   };
 
   nixos-option = makeProg {
diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix
index 5afdcf214f27..8a52df42dd80 100644
--- a/nixos/modules/misc/version.nix
+++ b/nixos/modules/misc/version.nix
@@ -6,12 +6,35 @@ with lib;
 
   options = {
 
+    system.stateVersion = mkOption {
+      type = types.str;
+      default = config.system.nixosRelease;
+      description = ''
+        Every once in a while, a new NixOS release may change
+        configuration defaults in a way incompatible with stateful
+        data. For instance, if the default version of PostgreSQL
+        changes, the new version will probably be unable to read your
+        existing databases. To prevent such breakage, you can set the
+        value of this option to the NixOS release with which you want
+        to be compatible. The effect is that NixOS will option
+        defaults corresponding to the specified release (such as using
+        an older version of PostgreSQL).
+      '';
+    };
+
     system.nixosVersion = mkOption {
       internal = true;
       type = types.str;
       description = "NixOS version.";
     };
 
+    system.nixosRelease = mkOption {
+      internal = true;
+      type = types.str;
+      default = readFile "${toString pkgs.path}/.version";
+      description = "NixOS release.";
+    };
+
     system.nixosVersionSuffix = mkOption {
       internal = true;
       type = types.str;
@@ -41,8 +64,7 @@ with lib;
 
   config = {
 
-    system.nixosVersion =
-      mkDefault (readFile "${toString pkgs.path}/.version" + config.system.nixosVersionSuffix);
+    system.nixosVersion = mkDefault (config.system.nixosRelease + config.system.nixosVersionSuffix);
 
     system.nixosVersionSuffix =
       let suffixFile = "${toString pkgs.path}/.version-suffix"; in
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 7e2c42f2b8c1..c56e6a82e831 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -288,6 +288,7 @@
   ./services/networking/gogoclient.nix
   ./services/networking/gvpe.nix
   ./services/networking/haproxy.nix
+  ./services/networking/heyefi.nix
   ./services/networking/hostapd.nix
   ./services/networking/i2pd.nix
   ./services/networking/i2p.nix
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index 97927055ce37..bae088c6610e 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -154,6 +154,12 @@ in
 
   config = mkIf config.services.postgresql.enable {
 
+    services.postgresql.package =
+      # Note: when changing the default, make it conditional on
+      # ‘system.stateVersion’ to maintain compatibility with existing
+      # systems!
+      mkDefault pkgs.postgresql94;
+
     services.postgresql.authentication = mkAfter
       ''
         # Generated file; do not edit!
@@ -207,6 +213,7 @@ in
 
         serviceConfig =
           { ExecStart = "@${postgresql}/bin/postgres postgres ${toString flags}";
+            ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
             User = "postgres";
             Group = "postgres";
             PermissionsStartOnly = true;
diff --git a/nixos/modules/services/mail/dovecot.nix b/nixos/modules/services/mail/dovecot.nix
index 50ff1b38db12..fca0d2a7f616 100644
--- a/nixos/modules/services/mail/dovecot.nix
+++ b/nixos/modules/services/mail/dovecot.nix
@@ -10,7 +10,7 @@ let
     ''
       base_dir = /var/run/dovecot2/
 
-      protocols = ${optionalString cfg.enableImap "imap"} ${optionalString cfg.enablePop3 "pop3"}
+      protocols = ${optionalString cfg.enableImap "imap"} ${optionalString cfg.enablePop3 "pop3"} ${optionalString cfg.enableLmtp "lmtp"}
     ''
     + (if cfg.sslServerCert!="" then
     ''
@@ -70,6 +70,11 @@ in
         description = "Start the IMAP listener (when Dovecot is enabled).";
       };
 
+      enableLmtp = mkOption {
+        default = false;
+        description = "Start the LMTP listener (when Dovecot is enabled).";
+      };
+
       user = mkOption {
         default = "dovecot2";
         description = "Dovecot user name.";
diff --git a/nixos/modules/services/misc/gitit.nix b/nixos/modules/services/misc/gitit.nix
index 56e735d7356b..72b706ddc5ae 100644
--- a/nixos/modules/services/misc/gitit.nix
+++ b/nixos/modules/services/misc/gitit.nix
@@ -40,7 +40,6 @@ let
       };
 
       haskellPackages = mkOption {
-        default = pkgs.haskellPackages;
         defaultText = "pkgs.haskellPackages";
         example = literalExample "pkgs.haskell.packages.ghc784";
         description = "haskellPackages used to build gitit and plugins.";
@@ -143,7 +142,6 @@ let
 
       staticDir = mkOption {
         type = types.path;
-        default = gititShared + "/data/static";
         description = ''
           Specifies the path of the static directory (containing javascript,
           css, and images).  If it does not exist, gitit will create it and
@@ -214,7 +212,6 @@ let
 
       templatesDir = mkOption {
         type = types.path;
-        default = gititShared + "/data/templates";
         description = ''
           Specifies the path of the directory containing page templates.  If it
           does not exist, gitit will create it with default templates.  Users
@@ -296,7 +293,6 @@ let
 
       plugins = mkOption {
         type = types.path;
-        default = gititShared + "/plugins/Dot.hs";
         description = ''
           Specifies a list of plugins to load.  Plugins may be specified either
           by their path or by their module name.  If the plugin name starts
@@ -608,6 +604,13 @@ in
 
   config = mkIf cfg.enable {
 
+    services.gitit = {
+      haskellPackages = mkDefault pkgs.haskellPackages;
+      staticDir = gititShared + "/data/static";
+      templatesDir = gititShared + "/data/templates";
+      plugins = gititShared + "/plugins/Dot.hs";
+    };
+
     users.extraUsers.gitit = {
       group = config.users.extraGroups.gitit.name;
       description = "Gitit user";
diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix
index b5a8a7df9fca..49286f512bb9 100644
--- a/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixos/modules/services/misc/nix-daemon.nix
@@ -254,7 +254,7 @@ in
 
       requireSignedBinaryCaches = mkOption {
         type = types.bool;
-        default = false;
+        default = true;
         description = ''
           If enabled, Nix will only download binaries from binary
           caches if they are cryptographically signed with any of the
diff --git a/nixos/modules/services/networking/copy-com.nix b/nixos/modules/services/networking/copy-com.nix
index 36bd29109b8a..69a41ab97963 100644
--- a/nixos/modules/services/networking/copy-com.nix
+++ b/nixos/modules/services/networking/copy-com.nix
@@ -1,53 +1,53 @@
-{ config, lib, pkgs, ... }:

-

-with lib;

-

-let

-  

-  cfg = config.services.copy-com;

-

-in 

-

-{

-  options = {

-

-    services.copy-com = {

-	  

-	  enable = mkOption {

-          default = false;

-          description = "

-            Enable the copy.com client.

-

-            The first time copy.com is run, it needs to be configured. Before enabling run 

-            copy_console manually.

-          ";

-      };

-

-      user = mkOption {

-        description = "The user for which copy should run.";

-      };

-

-      debug = mkOption {

-        default = false;

-        description = "Output more.";

-      };

-	  };

-  };

-

-  config = mkIf cfg.enable {

-    environment.systemPackages = [ pkgs.postfix ];

-

-    systemd.services."copy-com-${cfg.user}" = {

-      description = "Copy.com Client";

-      after = [ "network.target" "local-fs.target" ];

-      wantedBy = [ "multi-user.target" ];

-      serviceConfig = {

-        ExecStart = "${pkgs.copy-com}/bin/copy_console ${if cfg.debug then "-consoleOutput -debugToConsole=dirwatch,path-watch,csm_path,csm -debug -console" else ""}";

-        User = "${cfg.user}";

-      };

-

-    };

-  };

-

-}

-

+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.copy-com;
+
+in
+
+{
+  options = {
+
+    services.copy-com = {
+
+	  enable = mkOption {
+          default = false;
+          description = "
+            Enable the Copy.com client.
+            NOTE: before enabling the client for the first time, it must be
+            configured by first running CopyConsole (command line) or CopyAgent
+            (graphical) as the appropriate user.
+          ";
+      };
+
+      user = mkOption {
+        description = "The user for which the Copy.com client should be run.";
+      };
+
+      debug = mkOption {
+        default = false;
+        description = "Output more (debugging) messages to the console.";
+      };
+	  };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ pkgs.postfix ];
+
+    systemd.services."copy-com-${cfg.user}" = {
+      description = "Copy.com client";
+      after = [ "network.target" "local-fs.target" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        ExecStart = "${pkgs.copy-com}/bin/CopyConsole ${if cfg.debug then "-consoleOutput -debugToConsole=dirwatch,path-watch,csm_path,csm -debug -console" else ""}";
+        User = "${cfg.user}";
+      };
+
+    };
+  };
+
+}
+
diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix
index 40681f5b957a..a61f0250ef8b 100644
--- a/nixos/modules/services/networking/firewall.nix
+++ b/nixos/modules/services/networking/firewall.nix
@@ -420,6 +420,16 @@ in
         '';
     };
 
+    networking.firewall.extraPackages = mkOption {
+      default = [ ];
+      example = [ pkgs.ipset ];
+      description =
+        ''
+          Additional packages to be included in the environment of the system
+          as well as the path of networking.firewall.extraCommands.
+        '';
+    };
+
     networking.firewall.extraStopCommands = mkOption {
       type = types.lines;
       default = "";
@@ -443,7 +453,7 @@ in
 
     networking.firewall.trustedInterfaces = [ "lo" ];
 
-    environment.systemPackages = [ pkgs.iptables pkgs.ipset ];
+    environment.systemPackages = [ pkgs.iptables ] ++ cfg.extraPackages;
 
     boot.kernelModules = map (x: "nf_conntrack_${x}") cfg.connectionTrackingModules;
     boot.extraModprobeConfig = optionalString (!cfg.autoLoadConntrackHelpers) ''
@@ -462,7 +472,7 @@ in
       before = [ "network-pre.target" ];
       after = [ "systemd-modules-load.service" ];
 
-      path = [ pkgs.iptables pkgs.ipset ];
+      path = [ pkgs.iptables ] ++ cfg.extraPackages;
 
       # FIXME: this module may also try to load kernel modules, but
       # containers don't have CAP_SYS_MODULE. So the host system had
diff --git a/nixos/modules/services/networking/heyefi.nix b/nixos/modules/services/networking/heyefi.nix
new file mode 100644
index 000000000000..fc2b5a848578
--- /dev/null
+++ b/nixos/modules/services/networking/heyefi.nix
@@ -0,0 +1,82 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.heyefi;
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.heyefi = {
+
+      enable = mkEnableOption "heyefi";
+
+      cardMacaddress = mkOption {
+        default = "";
+        description = ''
+          An Eye-Fi card MAC address.
+          '';
+      };
+
+      uploadKey = mkOption {
+        default = "";
+        description = ''
+          An Eye-Fi card's upload key.
+          '';
+      };
+
+      uploadDir = mkOption {
+        example = "/home/username/pictures";
+        description = ''
+          The directory to upload the files to.
+          '';
+      };
+
+      user = mkOption {
+        default = "root";
+        description = ''
+          heyefi will be run under this user (user must exist,
+          this can be your user name).
+        '';
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    systemd.services.heyefi =
+      {
+        description = "heyefi service";
+        after = [ "network.target" ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          User = "${cfg.user}";
+          Restart = "always";
+          ExecStart = "${pkgs.heyefi}/bin/heyefi";
+        };
+
+      };
+
+    environment.etc."heyefi/heyefi.config".text =
+      ''
+        # /etc/heyefi/heyefi.conf: DO NOT EDIT -- this file has been generated automatically.
+        cards = [["${config.services.heyefi.cardMacaddress}","${config.services.heyefi.uploadKey}"]]
+        upload_dir = "${toString config.services.heyefi.uploadDir}"
+      '';
+
+    environment.systemPackages = [ pkgs.heyefi ];
+
+  };
+
+}
diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix
index 4be2b5fe0c0c..1c428ceddfd2 100644
--- a/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixos/modules/services/networking/ssh/sshd.nix
@@ -184,16 +184,11 @@ in
       hostKeys = mkOption {
         type = types.listOf types.attrs;
         default =
-          [ { path = "/etc/ssh/ssh_host_dsa_key";
-              type = "dsa";
-            }
-            { path = "/etc/ssh/ssh_host_ecdsa_key";
-              type = "ecdsa";
-              bits = 521;
-            }
-            { path = "/etc/ssh/ssh_host_ed25519_key";
-              type = "ed25519";
-            }
+          [ { type = "rsa"; bits = 4096; path = "/etc/ssh/ssh_host_rsa_key"; }
+            { type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
+          ] ++ optionals (!versionAtLeast config.system.stateVersion "15.07")
+          [ { type = "dsa"; path = "/etc/ssh/ssh_host_dsa_key"; }
+            { type = "ecdsa"; bits = 521; path = "/etc/ssh/ssh_host_ecdsa_key"; }
           ];
         description = ''
           NixOS can automatically generate SSH host keys.  This option
diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix
index 1f42086dc1ec..02d80a77da50 100644
--- a/nixos/modules/services/scheduling/cron.nix
+++ b/nixos/modules/services/scheduling/cron.nix
@@ -4,8 +4,6 @@ with lib;
 
 let
 
-  inherit (config.services) jobsTags;
-
   # Put all the system cronjobs together.
   systemCronJobsFile = pkgs.writeText "system-crontab"
     ''
@@ -25,9 +23,9 @@ let
     sendmailPath = "/var/setuid-wrappers/sendmail";
   };
 
-  allFiles = map (f: "\"${f}\"") (
-    [ "${systemCronJobsFile}" ] ++ config.services.cron.cronFiles
-  );
+  allFiles =
+    optional (config.services.cron.systemCronJobs != []) systemCronJobsFile
+    ++ config.services.cron.cronFiles;
 
 in
 
@@ -91,36 +89,49 @@ in
 
   ###### implementation
 
-  config = mkIf (config.services.cron.enable && allFiles != []) {
+  config = mkMerge [
 
-    security.setuidPrograms = [ "crontab" ];
+    { services.cron.enable = mkDefault (allFiles != []); }
 
-    environment.systemPackages = [ cronNixosPkg ];
+    (mkIf (config.services.cron.enable) {
 
-    systemd.services.cron =
-      { description = "Cron Daemon";
+      security.setuidPrograms = [ "crontab" ];
 
-        wantedBy = [ "multi-user.target" ];
+      environment.systemPackages = [ cronNixosPkg ];
 
-        preStart =
-          ''
-            rm -f /etc/crontab
-            cat ${toString allFiles} > /etc/crontab
-            chmod 0600 /etc/crontab
+      environment.etc.crontab =
+        { source = pkgs.runCommand "crontabs" { inherit allFiles; }
+            ''
+              touch $out
+              for i in $allFiles; do
+                cat "$i" >> $out
+              done
+            '';
+          mode = "0600"; # Cron requires this.
+        };
 
-            mkdir -m 710 -p /var/cron
+      systemd.services.cron =
+        { description = "Cron Daemon";
 
-            # By default, allow all users to create a crontab.  This
-            # is denoted by the existence of an empty cron.deny file.
-            if ! test -e /var/cron/cron.allow -o -e /var/cron/cron.deny; then
-                touch /var/cron/cron.deny
-            fi
-          '';
+          wantedBy = [ "multi-user.target" ];
 
-        restartTriggers = [ config.environment.etc.localtime.source ];
-        serviceConfig.ExecStart = "${cronNixosPkg}/bin/cron -n";
-      };
+          preStart =
+            ''
+              mkdir -m 710 -p /var/cron
 
-  };
+              # By default, allow all users to create a crontab.  This
+              # is denoted by the existence of an empty cron.deny file.
+              if ! test -e /var/cron/cron.allow -o -e /var/cron/cron.deny; then
+                  touch /var/cron/cron.deny
+              fi
+            '';
+
+          restartTriggers = [ config.environment.etc.localtime.source ];
+          serviceConfig.ExecStart = "${cronNixosPkg}/bin/cron -n";
+        };
+
+    })
+
+  ];
 
 }
diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix
index cf6d2cab3492..01ab086b0925 100644
--- a/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -40,7 +40,7 @@ in {
       example = literalExample "[ pkgs.gnome3.gpaste ]";
       description = "Additional list of packages to be added to the session search path.
                      Useful for gnome shell extensions or gsettings-conditionated autostart.";
-      apply = list: list ++ [ gnome3.gnome_shell ]; 
+      apply = list: list ++ [ gnome3.gnome_shell gnome3.gnome-shell-extensions ];
     };
 
     environment.gnome3.packageSet = mkOption {
diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix
index fce5bf11f053..88eefa13de35 100644
--- a/nixos/modules/services/x11/desktop-managers/xfce.nix
+++ b/nixos/modules/services/x11/desktop-managers/xfce.nix
@@ -62,7 +62,7 @@ in
         pkgs.xfce.xfwm4
         # This supplies some "abstract" icons such as
         # "utilities-terminal" and "accessories-text-editor".
-        pkgs.gnome.gnomeicontheme
+        pkgs.gnome3.defaultIconTheme
         pkgs.desktop_file_utils
         pkgs.xfce.libxfce4ui
         pkgs.xfce.garcon
diff --git a/nixos/modules/services/x11/redshift.nix b/nixos/modules/services/x11/redshift.nix
index 99d19f6ab151..4f39e05f0f8d 100644
--- a/nixos/modules/services/x11/redshift.nix
+++ b/nixos/modules/services/x11/redshift.nix
@@ -47,6 +47,13 @@ in {
         type = types.str;
       };
     };
+
+    services.redshift.extraOptions = mkOption {
+      type = types.listOf types.str;
+      default = [];
+      example = [ "-v" "-m randr" ];
+      description = "Additional command-line arguments to pass to the redshift(1) command";
+    };
   };
 
   config = mkIf cfg.enable {
@@ -59,7 +66,8 @@ in {
         ${pkgs.redshift}/bin/redshift \
           -l ${cfg.latitude}:${cfg.longitude} \
           -t ${toString cfg.temperature.day}:${toString cfg.temperature.night} \
-          -b ${toString cfg.brightness.day}:${toString cfg.brightness.night}
+          -b ${toString cfg.brightness.day}:${toString cfg.brightness.night} \
+          ${lib.strings.concatStringsSep " " cfg.extraOptions}
       '';
       environment = { DISPLAY = ":0"; };
       serviceConfig.Restart = "always";
diff --git a/nixos/modules/services/x11/window-managers/icewm.nix b/nixos/modules/services/x11/window-managers/icewm.nix
index 36028da453a5..9a3e80221890 100644
--- a/nixos/modules/services/x11/window-managers/icewm.nix
+++ b/nixos/modules/services/x11/window-managers/icewm.nix
@@ -3,29 +3,16 @@
 with lib;
 
 let
-
   cfg = config.services.xserver.windowManager.icewm;
-
 in
-
 {
-
   ###### interface
-
   options = {
-
-    services.xserver.windowManager.icewm.enable = mkOption {
-      default = false;
-      description = "Enable the IceWM window manager.";
-    };
-
+    services.xserver.windowManager.icewm.enable = mkEnableOption "oroborus";
   };
 
-
   ###### implementation
-
   config = mkIf cfg.enable {
-
     services.xserver.windowManager.session = singleton
       { name = "icewm";
         start =
@@ -36,7 +23,5 @@ in
       };
 
     environment.systemPackages = [ pkgs.icewm ];
-
   };
-
 }
diff --git a/nixos/modules/services/x11/window-managers/oroborus.nix b/nixos/modules/services/x11/window-managers/oroborus.nix
new file mode 100644
index 000000000000..bd7e3396864b
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/oroborus.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.oroborus;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.oroborus.enable = mkEnableOption "oroborus";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "oroborus";
+      start = ''
+        ${pkgs.oroborus}/bin/oroborus &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.oroborus ];
+  };
+}
diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix
index 63a095be6311..ae868219aa42 100644
--- a/nixos/modules/system/boot/kernel.nix
+++ b/nixos/modules/system/boot/kernel.nix
@@ -49,9 +49,8 @@ in
       type = types.int;
       default = 4;
       description = ''
-        The kernel console log level.  Only log messages with a
-        priority numerically less than this will appear on the
-        console.
+        The kernel console log level.  Log messages with a priority
+        numerically less than this will not appear on the console.
       '';
     };
 
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index c7cf712e3c2b..0b349749244f 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -10,7 +10,7 @@ let
 
   realGrub = if cfg.version == 1 then pkgs.grub
     else if cfg.zfsSupport then pkgs.grub2.override { zfsSupport = true; }
-    else if cfg.enableTrustedboot then pkgs.trustedGrub
+    else if cfg.enableTrustedBoot then pkgs.trustedGrub
            else pkgs.grub2;
 
   grub =
@@ -112,7 +112,7 @@ in
         description = ''
           The devices on which the boot loader, GRUB, will be
           installed. Can be used instead of <literal>device</literal> to
-          install grub into multiple devices (e.g., if as softraid arrays holding /boot).
+          install GRUB onto multiple devices.
         '';
       };
 
@@ -135,8 +135,8 @@ in
             example = "/boot1";
             type = types.str;
             description = ''
-              The path to the boot directory where grub will be written. Generally
-              this boot parth should double as an efi path.
+              The path to the boot directory where GRUB will be written. Generally
+              this boot path should double as an EFI path.
             '';
           };
 
@@ -166,7 +166,7 @@ in
             example = [ "/dev/sda" "/dev/sdb" ];
             type = types.listOf types.str;
             description = ''
-              The path to the devices which will have the grub mbr written.
+              The path to the devices which will have the GRUB MBR written.
               Note these are typically device paths and not paths to partitions.
             '';
           };
@@ -197,7 +197,7 @@ in
         type = types.lines;
         description = ''
           Additional bash commands to be run at the script that
-          prepares the grub menu entries.
+          prepares the GRUB menu entries.
         '';
       };
 
@@ -276,7 +276,7 @@ in
         example = "1024x768";
         type = types.str;
         description = ''
-          The gfxmode to pass to grub when loading a graphical boot interface under efi.
+          The gfxmode to pass to GRUB when loading a graphical boot interface under EFI.
         '';
       };
 
@@ -285,7 +285,7 @@ in
         example = "auto";
         type = types.str;
         description = ''
-          The gfxmode to pass to grub when loading a graphical boot interface under bios.
+          The gfxmode to pass to GRUB when loading a graphical boot interface under BIOS.
         '';
       };
 
@@ -330,10 +330,10 @@ in
         type = types.addCheck types.str
           (type: type == "uuid" || type == "label" || type == "provided");
         description = ''
-          Determines how grub will identify devices when generating the
+          Determines how GRUB will identify devices when generating the
           configuration file. A value of uuid / label signifies that grub
           will always resolve the uuid or label of the device before using
-          it in the configuration. A value of provided means that grub will
+          it in the configuration. A value of provided means that GRUB will
           use the device name as show in <command>df</command> or
           <command>mount</command>. Note, zfs zpools / datasets are ignored
           and will always be mounted using their labels.
@@ -344,7 +344,7 @@ in
         default = false;
         type = types.bool;
         description = ''
-          Whether grub should be build against libzfs.
+          Whether GRUB should be build against libzfs.
           ZFS support is only available for GRUB v2.
           This option is ignored for GRUB v1.
         '';
@@ -354,7 +354,7 @@ in
         default = false;
         type = types.bool;
         description = ''
-          Whether grub should be build with EFI support.
+          Whether GRUB should be build with EFI support.
           EFI support is only available for GRUB v2.
           This option is ignored for GRUB v1.
         '';
@@ -364,16 +364,16 @@ in
         default = false;
         type = types.bool;
         description = ''
-          Enable support for encrypted partitions. Grub should automatically
+          Enable support for encrypted partitions. GRUB should automatically
           unlock the correct encrypted partition and look for filesystems.
         '';
       };
 
-      enableTrustedboot = mkOption {
+      enableTrustedBoot = mkOption {
         default = false;
         type = types.bool;
         description = ''
-          Enable trusted boot. Grub will measure all critical components during
+          Enable trusted boot. GRUB will measure all critical components during
           the boot process to offer TCG (TPM) support.
         '';
       };
@@ -429,7 +429,7 @@ in
       assertions = [
         {
           assertion = !cfg.zfsSupport || cfg.version == 2;
-          message = "Only grub version 2 provides zfs support";
+          message = "Only GRUB version 2 provides ZFS support";
         }
         {
           assertion = cfg.mirroredBoots != [ ];
@@ -441,19 +441,19 @@ in
           message = "You cannot have duplicated devices in mirroredBoots";
         }
         {
-          assertion = !cfg.enableTrustedboot || cfg.version == 2;
+          assertion = !cfg.enableTrustedBoot || cfg.version == 2;
           message = "Trusted GRUB is only available for GRUB 2";
         }
         {
-          assertion = !cfg.efiSupport || !cfg.enableTrustedboot;
+          assertion = !cfg.efiSupport || !cfg.enableTrustedBoot;
           message = "Trusted GRUB does not have EFI support";
         }
         {
-          assertion = !cfg.zfsSupport || !cfg.enableTrustedboot;
+          assertion = !cfg.zfsSupport || !cfg.enableTrustedBoot;
           message = "Trusted GRUB does not have ZFS support";
         }
         {
-          assertion = !cfg.enableTrustedboot;
+          assertion = !cfg.enableTrustedBoot;
           message = "Trusted GRUB can break your system. Remove assertion if you want to test trustedGRUB nevertheless.";
         }
       ] ++ flip concatMap cfg.mirroredBoots (args: [
@@ -471,7 +471,7 @@ in
         }
       ] ++ flip map args.devices (device: {
         assertion = device == "nodev" || hasPrefix "/" device;
-        message = "Grub devices must be absolute paths, not ${dev} in ${args.path}";
+        message = "GRUB devices must be absolute paths, not ${dev} in ${args.path}";
       }));
     })
 
diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl
index 34bff727b73a..af39e50ff72d 100644
--- a/nixos/modules/system/boot/loader/grub/install-grub.pl
+++ b/nixos/modules/system/boot/loader/grub/install-grub.pl
@@ -237,6 +237,7 @@ else {
         $conf .= "
             " . $grubStore->search;
     }
+    # FIXME: should use grub-mkconfig.
     $conf .= "
         " . $grubBoot->search . "
         if [ -s \$prefix/grubenv ]; then
@@ -245,14 +246,12 @@ else {
 
         # ‘grub-reboot’ sets a one-time saved entry, which we process here and
         # then delete.
-        if [ \"\${saved_entry}\" ]; then
-          # The next line *has* to look exactly like this, otherwise KDM's
-          # reboot feature won't work properly with GRUB 2.
+        if [ \"\${next_entry}\" ]; then
+          # FIXME: KDM expects the next line to be present.
           set default=\"\${saved_entry}\"
-          set saved_entry=
-          set prev_saved_entry=
-          save_env saved_entry
-          save_env prev_saved_entry
+          set default=\"\${next_entry}\"
+          set next_entry=
+          save_env next_entry
           set timeout=1
         else
           set default=$defaultEntry