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/config/debug-info.nix46
-rw-r--r--nixos/modules/config/i18n.nix17
-rw-r--r--nixos/modules/config/power-management.nix1
-rw-r--r--nixos/modules/config/swap.nix167
-rw-r--r--nixos/modules/config/system-path.nix27
-rw-r--r--nixos/modules/config/users-groups.nix4
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix6
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix3
-rw-r--r--nixos/modules/installer/tools/auto-upgrade.nix2
-rw-r--r--nixos/modules/installer/tools/nixos-generate-config.pl20
-rw-r--r--nixos/modules/installer/tools/nixos-rebuild.sh2
-rw-r--r--nixos/modules/misc/ids.nix2
-rw-r--r--nixos/modules/module-list.nix15
-rw-r--r--nixos/modules/programs/bash/bash.nix14
-rw-r--r--nixos/modules/programs/environment.nix4
-rw-r--r--nixos/modules/programs/man.nix30
-rw-r--r--nixos/modules/rename.nix252
-rw-r--r--nixos/modules/services/continuous-integration/jenkins/default.nix31
-rw-r--r--nixos/modules/services/continuous-integration/jenkins/job-builder.nix155
-rw-r--r--nixos/modules/services/databases/postgresql.nix4
-rw-r--r--nixos/modules/services/hardware/actkbd.nix3
-rw-r--r--nixos/modules/services/hardware/tlp.nix24
-rw-r--r--nixos/modules/services/mail/postfix.nix41
-rw-r--r--nixos/modules/services/misc/autofs.nix45
-rw-r--r--nixos/modules/services/misc/calibre-server.nix63
-rw-r--r--nixos/modules/services/misc/ihaskell.nix6
-rw-r--r--nixos/modules/services/misc/nixos-manual.nix4
-rw-r--r--nixos/modules/services/misc/parsoid.nix2
-rw-r--r--nixos/modules/services/misc/synergy.nix2
-rw-r--r--nixos/modules/services/monitoring/bosun.nix10
-rw-r--r--nixos/modules/services/monitoring/grafana.nix2
-rw-r--r--nixos/modules/services/monitoring/teamviewer.nix1
-rw-r--r--nixos/modules/services/networking/asterisk.nix1
-rw-r--r--nixos/modules/services/networking/autossh.nix114
-rw-r--r--nixos/modules/services/networking/copy-com.nix3
-rw-r--r--nixos/modules/services/networking/networkmanager.nix31
-rw-r--r--nixos/modules/services/networking/quassel.nix13
-rw-r--r--nixos/modules/services/networking/supplicant.nix249
-rw-r--r--nixos/modules/services/networking/tlsdated.nix2
-rw-r--r--nixos/modules/services/networking/wakeonlan.nix2
-rw-r--r--nixos/modules/services/scheduling/cron.nix2
-rw-r--r--nixos/modules/services/web-servers/lighttpd/default.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/gnome3.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde5.nix135
-rw-r--r--nixos/modules/services/x11/display-managers/gdm.nix4
-rw-r--r--nixos/modules/services/x11/display-managers/sddm.nix90
-rw-r--r--nixos/modules/services/x11/redshift.nix12
-rw-r--r--nixos/modules/services/x11/window-managers/clfswm.nix31
-rw-r--r--nixos/modules/services/x11/window-managers/default.nix1
-rw-r--r--nixos/modules/services/x11/window-managers/xmonad.nix6
-rw-r--r--nixos/modules/system/boot/initrd-network.nix149
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix26
-rw-r--r--nixos/modules/system/boot/luksroot.nix26
-rw-r--r--nixos/modules/system/boot/stage-1-init.sh4
-rw-r--r--nixos/modules/system/boot/stage-1.nix14
-rw-r--r--nixos/modules/system/boot/systemd.nix9
-rw-r--r--nixos/modules/tasks/filesystems.nix2
-rw-r--r--nixos/modules/tasks/filesystems/nfs.nix2
-rw-r--r--nixos/modules/tasks/kbd.nix4
-rw-r--r--nixos/modules/tasks/network-interfaces-scripted.nix14
-rw-r--r--nixos/modules/tasks/network-interfaces.nix101
-rw-r--r--nixos/modules/virtualisation/docker.nix6
-rw-r--r--nixos/modules/virtualisation/nova-config.nix5
-rw-r--r--nixos/modules/virtualisation/nova-image.nix97
-rw-r--r--nixos/modules/virtualisation/virtualbox-host.nix3
65 files changed, 1607 insertions, 558 deletions
diff --git a/nixos/modules/config/debug-info.nix b/nixos/modules/config/debug-info.nix
new file mode 100644
index 000000000000..a096a9809cee
--- /dev/null
+++ b/nixos/modules/config/debug-info.nix
@@ -0,0 +1,46 @@
+{ config, lib, ... }:
+
+with lib;
+
+{
+
+  options = {
+
+    environment.enableDebugInfo = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Some NixOS packages provide debug symbols. However, these are
+        not included in the system closure by default to save disk
+        space. Enabling this option causes the debug symbols to appear
+        in <filename>/run/current-system/sw/lib/debug/.build-id</filename>,
+        where tools such as <command>gdb</command> can find them.
+        If you need debug symbols for a package that doesn't
+        provide them by default, you can enable them as follows:
+        <!-- FIXME: ugly, see #10721 -->
+        <programlisting>
+        nixpkgs.config.packageOverrides = pkgs: {
+          hello = overrideDerivation pkgs.hello (attrs: {
+            outputs = attrs.outputs or ["out"] ++ ["debug"];
+            buildInputs = attrs.buildInputs ++ [&lt;nixpkgs/pkgs/build-support/setup-hooks/separate-debug-info.sh>];
+          });
+        };
+        </programlisting>
+      '';
+    };
+
+  };
+
+
+  config = {
+
+    # FIXME: currently disabled because /lib is already in
+    # environment.pathsToLink, and we can't have both.
+    #environment.pathsToLink = [ "/lib/debug/.build-id" ];
+
+    environment.outputsToLink =
+      optional config.environment.enableDebugInfo "debug";
+
+  };
+
+}
diff --git a/nixos/modules/config/i18n.nix b/nixos/modules/config/i18n.nix
index f58e540a6e5c..b20fac6ad3e2 100644
--- a/nixos/modules/config/i18n.nix
+++ b/nixos/modules/config/i18n.nix
@@ -74,6 +74,23 @@ in
         '';
       };
 
+      consoleColors = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        example = [
+          "002b36" "dc322f" "859900" "b58900"
+          "268bd2" "d33682" "2aa198" "eee8d5"
+          "002b36" "cb4b16" "586e75" "657b83"
+          "839496" "6c71c4" "93a1a1" "fdf6e3"
+        ];
+        description = ''
+          The 16 colors palette used by the virtual consoles.
+          Leave empty to use the default colors.
+          Colors must be in hexadecimal format and listed in
+          order from color 0 to color 15.
+        '';
+      };
+
     };
 
   };
diff --git a/nixos/modules/config/power-management.nix b/nixos/modules/config/power-management.nix
index 32a7987617ad..dedc8a3f6793 100644
--- a/nixos/modules/config/power-management.nix
+++ b/nixos/modules/config/power-management.nix
@@ -98,6 +98,7 @@ in
         after = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ];
         script =
           ''
+            ${config.systemd.package}/bin/systemctl try-restart post-resume.target
             ${cfg.resumeCommands}
             ${cfg.powerUpCommands}
           '';
diff --git a/nixos/modules/config/swap.nix b/nixos/modules/config/swap.nix
index 1dc7ebb96aff..9a5d6a9fc333 100644
--- a/nixos/modules/config/swap.nix
+++ b/nixos/modules/config/swap.nix
@@ -3,6 +3,84 @@
 with utils;
 with lib;
 
+let
+
+  swapCfg = {config, options, ...}: {
+
+    options = {
+
+      device = mkOption {
+        example = "/dev/sda3";
+        type = types.str;
+        description = "Path of the device.";
+      };
+
+      label = mkOption {
+        example = "swap";
+        type = types.str;
+        description = ''
+          Label of the device.  Can be used instead of <varname>device</varname>.
+        '';
+      };
+
+      size = mkOption {
+        default = null;
+        example = 2048;
+        type = types.nullOr types.int;
+        description = ''
+          If this option is set, ‘device’ is interpreted as the
+          path of a swapfile that will be created automatically
+          with the indicated size (in megabytes) if it doesn't
+          exist.
+        '';
+      };
+
+      priority = mkOption {
+        default = null;
+        example = 2048;
+        type = types.nullOr types.int;
+        description = ''
+          Specify the priority of the swap device. Priority is a value between 0 and 32767.
+          Higher numbers indicate higher priority.
+          null lets the kernel choose a priority, which will show up as a negative value.
+        '';
+      };
+
+      randomEncryption = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          Encrypt swap device with a random key. This way you won't have a persistent swap device.
+
+          WARNING: Don't try to hibernate when you have at least one swap partition with
+          this option enabled! We have no way to set the partition into which hibernation image
+          is saved, so if your image ends up on an encrypted one you would lose it!
+        '';
+      };
+
+      deviceName = mkOption {
+        type = types.str;
+        internal = true;
+      };
+
+      realDevice = mkOption {
+        type = types.path;
+        internal = true;
+      };
+
+    };
+
+    config = rec {
+      device = mkIf options.label.isDefined
+        "/dev/disk/by-label/${config.label}";
+      deviceName = escapeSystemdPath config.device;
+      realDevice = if config.randomEncryption then "/dev/mapper/${deviceName}" else config.device;
+    };
+
+  };
+
+in
+
 {
 
   ###### interface
@@ -26,58 +104,7 @@ with lib;
         recommended.
       '';
 
-      type = types.listOf types.optionSet;
-
-      options = {config, options, ...}: {
-
-        options = {
-
-          device = mkOption {
-            example = "/dev/sda3";
-            type = types.str;
-            description = "Path of the device.";
-          };
-
-          label = mkOption {
-            example = "swap";
-            type = types.str;
-            description = ''
-              Label of the device.  Can be used instead of <varname>device</varname>.
-            '';
-          };
-
-          size = mkOption {
-            default = null;
-            example = 2048;
-            type = types.nullOr types.int;
-            description = ''
-              If this option is set, ‘device’ is interpreted as the
-              path of a swapfile that will be created automatically
-              with the indicated size (in megabytes) if it doesn't
-              exist.
-            '';
-          };
-
-          priority = mkOption {
-            default = null;
-            example = 2048;
-            type = types.nullOr types.int;
-            description = ''
-              Specify the priority of the swap device. Priority is a value between 0 and 32767.
-              Higher numbers indicate higher priority.
-              null lets the kernel choose a priority, which will show up as a negative value.
-            '';
-          };
-
-        };
-
-        config = {
-          device = mkIf options.label.isDefined
-            "/dev/disk/by-label/${config.label}";
-        };
-
-      };
-
+      type = types.listOf (types.submodule swapCfg);
     };
 
   };
@@ -95,27 +122,37 @@ with lib;
 
         createSwapDevice = sw:
           assert sw.device != "";
-          let device' = escapeSystemdPath sw.device; in
-          nameValuePair "mkswap-${escapeSystemdPath sw.device}"
-          { description = "Initialisation of Swapfile ${sw.device}";
-            wantedBy = [ "${device'}.swap" ];
-            before = [ "${device'}.swap" ];
-            path = [ pkgs.utillinux ];
+          let realDevice' = escapeSystemdPath sw.realDevice;
+          in nameValuePair "mkswap-${sw.deviceName}"
+          { description = "Initialisation of swap device ${sw.device}";
+            wantedBy = [ "${realDevice'}.swap" ];
+            before = [ "${realDevice'}.swap" ];
+            path = [ pkgs.utillinux ] ++ optional sw.randomEncryption pkgs.cryptsetup;
             script =
               ''
-                if [ ! -e "${sw.device}" ]; then
-                  fallocate -l ${toString sw.size}M "${sw.device}" ||
-                    dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size}
-                  chmod 0600 ${sw.device}
-                  mkswap ${sw.device}
-                fi
+                ${optionalString (sw.size != null) ''
+                  if [ ! -e "${sw.device}" ]; then
+                    fallocate -l ${toString sw.size}M "${sw.device}" ||
+                      dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size}
+                    chmod 0600 ${sw.device}
+                    ${optionalString (!sw.randomEncryption) "mkswap ${sw.realDevice}"}
+                  fi
+                ''}
+                ${optionalString sw.randomEncryption ''
+                  echo "secretkey" | cryptsetup luksFormat --batch-mode ${sw.device}
+                  echo "secretkey" | cryptsetup luksOpen ${sw.device} ${sw.deviceName}
+                  cryptsetup luksErase --batch-mode ${sw.device}
+                  mkswap ${sw.realDevice}
+                ''}
               '';
             unitConfig.RequiresMountsFor = [ "${dirOf sw.device}" ];
             unitConfig.DefaultDependencies = false; # needed to prevent a cycle
             serviceConfig.Type = "oneshot";
+            serviceConfig.RemainAfterExit = sw.randomEncryption;
+            serviceConfig.ExecStop = optionalString sw.randomEncryption "cryptsetup luksClose ${sw.deviceName}";
           };
 
-      in listToAttrs (map createSwapDevice (filter (sw: sw.size != null) config.swapDevices));
+      in listToAttrs (map createSwapDevice (filter (sw: sw.size != null || sw.randomEncryption) config.swapDevices));
 
   };
 
diff --git a/nixos/modules/config/system-path.nix b/nixos/modules/config/system-path.nix
index 26f4ba5fd706..da558a25d99b 100644
--- a/nixos/modules/config/system-path.nix
+++ b/nixos/modules/config/system-path.nix
@@ -7,12 +7,6 @@ with lib;
 
 let
 
-  extraManpages = pkgs.runCommand "extra-manpages" { buildInputs = [ pkgs.help2man ]; }
-    ''
-      mkdir -p $out/share/man/man1
-      help2man ${pkgs.gnutar}/bin/tar > $out/share/man/man1/tar.1
-    '';
-
   requiredPackages =
     [ config.nix.package
       pkgs.acl
@@ -34,7 +28,6 @@ let
       pkgs.xz
       pkgs.less
       pkgs.libcap
-      pkgs.man
       pkgs.nano
       pkgs.ncurses
       pkgs.netcat
@@ -47,7 +40,6 @@ let
       pkgs.time
       pkgs.texinfoInteractive
       pkgs.utillinux
-      extraManpages
     ];
 
 in
@@ -78,8 +70,16 @@ in
         # to work.
         default = [];
         example = ["/"];
-        description = "List of directories to be symlinked in `/run/current-system/sw'.";
+        description = "List of directories to be symlinked in <filename>/run/current-system/sw</filename>.";
+      };
+
+      outputsToLink = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        example = [ "doc" ];
+        description = "List of package outputs to be symlinked into <filename>/run/current-system/sw</filename>.";
       };
+
     };
 
     system = {
@@ -103,9 +103,7 @@ in
       [ "/bin"
         "/etc/xdg"
         "/info"
-        "/lib" # FIXME: remove
-        #"/lib/debug/.build-id" # enables GDB to find separated debug info
-        "/man"
+        "/lib" # FIXME: remove and update debug-info.nix
         "/sbin"
         "/share/applications"
         "/share/desktop-directories"
@@ -113,7 +111,6 @@ in
         "/share/emacs"
         "/share/icons"
         "/share/info"
-        "/share/man"
         "/share/menus"
         "/share/mime"
         "/share/nano"
@@ -126,7 +123,8 @@ in
     system.path = pkgs.buildEnv {
       name = "system-path";
       paths = let
-        #outputs TODO: make it user-customizable?
+      inherit (config.environment) pathsToLink outputsToLink;
+        #outputs TODO: some code already merged by Eelco? make it user-customizable?
         pkgOutputFun = pkg: lib.filter (p: p!=null) [
           (pkg.bin or (pkg.out or pkg))
           (pkg.man or null)
@@ -134,7 +132,6 @@ in
           (pkg.doc or null)
         ];
         in lib.concatMap pkgOutputFun config.environment.systemPackages;
-      inherit (config.environment) pathsToLink;
       ignoreCollisions = true;
       # !!! Hacky, should modularise.
       postBuild =
diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix
index adc014eed415..485926fb1dd0 100644
--- a/nixos/modules/config/users-groups.nix
+++ b/nixos/modules/config/users-groups.nix
@@ -550,4 +550,8 @@ in {
 
   };
 
+  imports =
+    [ (mkAliasOptionModule [ "users" "extraUsers" ] [ "users" "users" ])
+      (mkAliasOptionModule [ "users" "extraGroups" ] [ "users" "groups" ])
+    ];
 }
diff --git a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
index 0ca57a4635f4..15e22fb50d48 100644
--- a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
@@ -22,13 +22,9 @@ in
   boot.loader.grub.enable = false;
   boot.loader.generic-extlinux-compatible.enable = true;
 
-  # FIXME: change this to linuxPackages_latest once v4.2 is out
-  boot.kernelPackages = pkgs.linuxPackages_testing;
+  boot.kernelPackages = pkgs.linuxPackages_latest;
   boot.kernelParams = ["console=ttyS0,115200n8" "console=ttyAMA0,115200n8" "console=tty0"];
 
-  # FIXME: fix manual evaluation on ARM
-  services.nixosManual.enable = lib.mkOverride 0 false;
-
   # FIXME: this probably should be in installation-device.nix
   users.extraUsers.root.initialHashedPassword = "";
 
diff --git a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
index 199a252ad2b5..e7163f10a3c3 100644
--- a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
@@ -27,9 +27,6 @@ in
 
   boot.kernelPackages = pkgs.linuxPackages_rpi;
 
-  # FIXME: fix manual evaluation on ARM
-  services.nixosManual.enable = lib.mkOverride 0 false;
-
   # FIXME: this probably should be in installation-device.nix
   users.extraUsers.root.initialHashedPassword = "";
 
diff --git a/nixos/modules/installer/tools/auto-upgrade.nix b/nixos/modules/installer/tools/auto-upgrade.nix
index dd8663a12db8..1fa9282b909e 100644
--- a/nixos/modules/installer/tools/auto-upgrade.nix
+++ b/nixos/modules/installer/tools/auto-upgrade.nix
@@ -70,7 +70,7 @@ let cfg = config.system.autoUpgrade; in
       path = [ pkgs.gnutar pkgs.xz.bin config.nix.package ];
 
       script = ''
-        ${config.system.build.nixos-rebuild}/bin/nixos-rebuild test ${toString cfg.flags}
+        ${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch ${toString cfg.flags}
       '';
 
       startAt = mkIf cfg.enable "04:40";
diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl
index 39ef4c51ba10..c590c4cde3f0 100644
--- a/nixos/modules/installer/tools/nixos-generate-config.pl
+++ b/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -152,6 +152,22 @@ sub pciCheck {
         push @kernelModules, "wl";
      }
 
+    # broadcom FullMac driver
+    # list taken from
+    # https://wireless.wiki.kernel.org/en/users/Drivers/brcm80211#brcmfmac
+    if ($vendor eq "0x14e4" &&
+        ($device eq "0x43a3" || $device eq "0x43df" || $device eq "0x43ec" ||
+         $device eq "0x43d3" || $device eq "0x43d9" || $device eq "0x43e9" ||
+         $device eq "0x43ba" || $device eq "0x43bb" || $device eq "0x43bc" ||
+         $device eq "0xaa52" || $device eq "0x43ca" || $device eq "0x43cb" ||
+         $device eq "0x43cc" || $device eq "0x43c3" || $device eq "0x43c4" ||
+         $device eq "0x43c5"
+        ) )
+    {
+        # we need e.g. brcmfmac43602-pcie.bin
+        push @imports, "<nixos/modules/hardware/network/broadcom-43xx.nix>";
+    }
+
     # Can't rely on $module here, since the module may not be loaded
     # due to missing firmware.  Ideally we would check modules.pcimap
     # here.
@@ -217,8 +233,8 @@ foreach my $path (glob "/sys/bus/usb/devices/*") {
 }
 
 
-# Add the modules for all block devices.
-foreach my $path (glob "/sys/class/block/*") {
+# Add the modules for all block and MMC devices.
+foreach my $path (glob "/sys/class/{block,mmc_host}/*") {
     my $module;
     if (-e "$path/device/driver/module") {
         $module = basename `readlink -f $path/device/driver/module`;
diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh
index af19004cbddb..6792690b4c3b 100644
--- a/nixos/modules/installer/tools/nixos-rebuild.sh
+++ b/nixos/modules/installer/tools/nixos-rebuild.sh
@@ -235,7 +235,7 @@ fi
 # default and/or activate it now.
 if [ "$action" = switch -o "$action" = boot -o "$action" = test -o "$action" = dry-activate ]; then
     if ! $pathToConfig/bin/switch-to-configuration "$action"; then
-        echo "warning: error(s) occured while switching to the new configuration" >&2
+        echo "warning: error(s) occurred while switching to the new configuration" >&2
         exit 1
     fi
 fi
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index 0d2700a126f6..de9a318fdd24 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -234,6 +234,7 @@
       #lxd = 210; # unused
       kibana = 211;
       xtreemfs = 212;
+      calibre-server = 213;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
@@ -446,6 +447,7 @@
       lxd = 210; # unused
       #kibana = 211;
       xtreemfs = 212;
+      calibre-server = 213;
 
       # When adding a gid, make sure it doesn't match an existing
       # uid. Users and groups with the same name should have equal
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index c890eac49910..034ea933a7db 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -1,7 +1,8 @@
 [
+  ./config/debug-info.nix
   ./config/fonts/corefonts.nix
-  ./config/fonts/fontconfig.nix
   ./config/fonts/fontconfig-ultimate.nix
+  ./config/fonts/fontconfig.nix
   ./config/fonts/fontdir.nix
   ./config/fonts/fonts.nix
   ./config/fonts/ghostscript.nix
@@ -22,9 +23,9 @@
   ./config/system-environment.nix
   ./config/system-path.nix
   ./config/timezone.nix
-  ./config/vpnc.nix
   ./config/unix-odbc-drivers.nix
   ./config/users-groups.nix
+  ./config/vpnc.nix
   ./config/zram.nix
   ./hardware/all-firmware.nix
   ./hardware/cpu/amd-microcode.nix
@@ -61,9 +62,11 @@
   ./programs/command-not-found/command-not-found.nix
   ./programs/dconf.nix
   ./programs/environment.nix
+  ./programs/freetds.nix
   ./programs/ibus.nix
   ./programs/kbdlight.nix
   ./programs/light.nix
+  ./programs/man.nix
   ./programs/nano.nix
   ./programs/screen.nix
   ./programs/shadow.nix
@@ -73,7 +76,6 @@
   ./programs/uim.nix
   ./programs/venus.nix
   ./programs/wvdial.nix
-  ./programs/freetds.nix
   ./programs/xfs_quota.nix
   ./programs/zsh/zsh.nix
   ./rename.nix
@@ -116,6 +118,7 @@
   ./services/computing/slurm/slurm.nix
   ./services/continuous-integration/jenkins/default.nix
   ./services/continuous-integration/jenkins/slave.nix
+  ./services/continuous-integration/jenkins/job-builder.nix
   ./services/databases/4store-endpoint.nix
   ./services/databases/4store.nix
   ./services/databases/couchdb.nix
@@ -185,8 +188,9 @@
   ./services/mail/postfix.nix
   ./services/mail/spamassassin.nix
   ./services/misc/apache-kafka.nix
-  #./services/misc/autofs.nix
+  ./services/misc/autofs.nix
   ./services/misc/canto-daemon.nix
+  ./services/misc/calibre-server.nix
   ./services/misc/cpuminer-cryptonight.nix
   ./services/misc/cgminer.nix
   ./services/misc/confd.nix
@@ -264,6 +268,7 @@
   ./services/networking/atftpd.nix
   ./services/networking/avahi-daemon.nix
   ./services/networking/bind.nix
+  ./services/networking/autossh.nix
   ./services/networking/bird.nix
   ./services/networking/bitlbee.nix
   ./services/networking/btsync.nix
@@ -340,6 +345,7 @@
   ./services/networking/ssh/lshd.nix
   ./services/networking/ssh/sshd.nix
   ./services/networking/strongswan.nix
+  ./services/networking/supplicant.nix
   ./services/networking/supybot.nix
   ./services/networking/syncthing.nix
   ./services/networking/tcpcrypt.nix
@@ -435,6 +441,7 @@
   ./system/activation/top-level.nix
   ./system/boot/coredump.nix
   ./system/boot/emergency-mode.nix
+  ./system/boot/initrd-network.nix
   ./system/boot/kernel.nix
   ./system/boot/kexec.nix
   ./system/boot/loader/efi.nix
diff --git a/nixos/modules/programs/bash/bash.nix b/nixos/modules/programs/bash/bash.nix
index c5c0f9d01215..75efd5e29039 100644
--- a/nixos/modules/programs/bash/bash.nix
+++ b/nixos/modules/programs/bash/bash.nix
@@ -90,12 +90,14 @@ in
 
       promptInit = mkOption {
         default = ''
-          # Provide a nice prompt.
-          PROMPT_COLOR="1;31m"
-          let $UID && PROMPT_COLOR="1;32m"
-          PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] "
-          if test "$TERM" = "xterm"; then
-            PS1="\[\033]2;\h:\u:\w\007\]$PS1"
+          if test "$TERM" != "dumb"; then
+            # Provide a nice prompt.
+            PROMPT_COLOR="1;31m"
+            let $UID && PROMPT_COLOR="1;32m"
+            PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] "
+            if test "$TERM" = "xterm"; then
+              PS1="\[\033]2;\h:\u:\w\007\]$PS1"
+            fi
           fi
         '';
         description = ''
diff --git a/nixos/modules/programs/environment.nix b/nixos/modules/programs/environment.nix
index 52f6cc221119..a35b5cc9513e 100644
--- a/nixos/modules/programs/environment.nix
+++ b/nixos/modules/programs/environment.nix
@@ -38,9 +38,7 @@ in
         PERL5LIB = [ "/lib/perl5/site_perl" ];
         KDEDIRS = [ "" ];
         STRIGI_PLUGIN_PATH = [ "/lib/strigi/" ];
-        QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" "/lib/qt5/plugins" ];
-        QML_IMPORT_PATH = [ "/lib/qt5/imports" ];
-        QML2_IMPORT_PATH = [ "/lib/qt5/qml" ];
+        QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ];
         QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/plugins/" ];
         GTK_PATH = [ "/lib/gtk-2.0" "/lib/gtk-3.0" ];
         XDG_CONFIG_DIRS = [ "/etc/xdg" ];
diff --git a/nixos/modules/programs/man.nix b/nixos/modules/programs/man.nix
new file mode 100644
index 000000000000..b28506538049
--- /dev/null
+++ b/nixos/modules/programs/man.nix
@@ -0,0 +1,30 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+
+  options = {
+
+    programs.man.enable = mkOption {
+      type = types.bool;
+      default = true;
+      description = ''
+        Whether to enable manual pages and the <command>man</command> command.
+      '';
+    };
+
+  };
+
+
+  config = mkIf config.programs.man.enable {
+
+    environment.systemPackages = [ pkgs.man ];
+
+    environment.pathsToLink = [ "/share/man" ];
+
+    environment.outputsToLink = [ "man" ];
+
+  };
+
+}
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index 62be7dc6cae2..28ac1c3e888a 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -1,170 +1,88 @@
-{ config, lib, options, ... }:
+{ lib, ... }:
 
 with lib;
 
-let
-
-  alias = from: to: rename {
-    inherit from to;
-    name = "Alias";
-    use = id;
-    define = id;
-    visible = true;
-  };
-
-  # warn option was renamed
-  obsolete = from: to: rename {
-    inherit from to;
-    name = "Obsolete name";
-    use = x: builtins.trace "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'." x;
-    define = x: builtins.trace "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'." x;
-  };
-
-  # abort if deprecated option is used
-  deprecated = from: to: rename {
-    inherit from to;
-    name = "Deprecated name";
-    use = x: abort "Deprecated option `${showOption from}' is used. It was renamed to `${showOption to}'.";
-    define = x: abort "Deprecated option `${showOption from}' is used. It was renamed to `${showOption to}'.";
-  };
-
-  showOption = concatStringsSep ".";
-
-  zipModules = list:
-    zipAttrsWith (n: v:
-      if tail v != [] then
-        if all (o: isAttrs o && o ? _type) v then mkMerge v
-        else if n == "_type" then head v
-        else if n == "warnings" then concatLists v
-        else if n == "description" || n == "apply" then
-          abort "Cannot rename an option to multiple options."
-        else zipModules v
-      else head v
-    ) list;
-
-  rename = { from, to, name, use, define, visible ? false }:
-    let
-      setTo = setAttrByPath to;
-      setFrom = setAttrByPath from;
-      toOf = attrByPath to
-        (abort "Renaming error: option `${showOption to}' does not exists.");
-      fromOf = attrByPath from
-        (abort "Internal error: option `${showOption from}' should be declared.");
-    in
-      [ { options = setFrom (mkOption {
-            description = "${name} of <option>${showOption to}</option>.";
-            apply = x: use (toOf config);
-            inherit visible;
-          });
-
-          config = setTo (mkAliasAndWrapDefinitions define (fromOf options));
-        }
-      ];
-
-  obsolete' = option: singleton
-    { options = setAttrByPath option (mkOption {
-        default = null;
-        visible = false;
-      });
-      config.warnings = optional (getAttrFromPath option config != null)
-        "The option `${showOption option}' defined in your configuration no longer has any effect; please remove it.";
-    };
-
-in zipModules ([]
-
-++ obsolete [ "environment" "x11Packages" ] [ "environment" "systemPackages" ]
-++ obsolete [ "environment" "enableBashCompletion" ] [ "programs" "bash" "enableCompletion" ]
-++ obsolete [ "environment" "nix" ] [ "nix" "package" ]
-++ obsolete [ "fonts" "enableFontConfig" ] [ "fonts" "fontconfig" "enable" ]
-++ obsolete [ "fonts" "extraFonts" ] [ "fonts" "fonts" ]
-++ alias [ "users" "extraUsers" ] [ "users" "users" ]
-++ alias [ "users" "extraGroups" ] [ "users" "groups" ]
-
-++ obsolete [ "security" "extraSetuidPrograms" ] [ "security" "setuidPrograms" ]
-++ obsolete [ "networking" "enableWLAN" ] [ "networking" "wireless" "enable" ]
-++ obsolete [ "networking" "enableRT73Firmware" ] [ "networking" "enableRalinkFirmware" ]
-
-# FIXME: Remove these eventually.
-++ obsolete [ "boot" "systemd" "sockets" ] [ "systemd" "sockets" ]
-++ obsolete [ "boot" "systemd" "targets" ] [ "systemd" "targets" ]
-++ obsolete [ "boot" "systemd" "services" ] [ "systemd" "services" ]
-
-# Old Grub-related options.
-++ obsolete [ "boot" "copyKernels" ] [ "boot" "loader" "grub" "copyKernels" ]
-++ obsolete [ "boot" "extraGrubEntries" ] [ "boot" "loader" "grub" "extraEntries" ]
-++ obsolete [ "boot" "extraGrubEntriesBeforeNixos" ] [ "boot" "loader" "grub" "extraEntriesBeforeNixOS" ]
-++ obsolete [ "boot" "grubDevice" ] [ "boot" "loader" "grub" "device" ]
-++ obsolete [ "boot" "bootMount" ] [ "boot" "loader" "grub" "bootDevice" ]
-++ obsolete [ "boot" "grubSplashImage" ] [ "boot" "loader" "grub" "splashImage" ]
-
-++ obsolete [ "boot" "initrd" "extraKernelModules" ] [ "boot" "initrd" "kernelModules" ]
-++ obsolete [ "boot" "extraKernelParams" ] [ "boot" "kernelParams" ]
-
-# smartd
-++ obsolete [ "services" "smartd" "deviceOpts" ] [ "services" "smartd" "defaults" "monitored" ]
-
-# OpenSSH
-++ obsolete [ "services" "sshd" "ports" ] [ "services" "openssh" "ports" ]
-++ alias [ "services" "sshd" "enable" ] [ "services" "openssh" "enable" ]
-++ obsolete [ "services" "sshd" "allowSFTP" ] [ "services" "openssh" "allowSFTP" ]
-++ obsolete [ "services" "sshd" "forwardX11" ] [ "services" "openssh" "forwardX11" ]
-++ obsolete [ "services" "sshd" "gatewayPorts" ] [ "services" "openssh" "gatewayPorts" ]
-++ obsolete [ "services" "sshd" "permitRootLogin" ] [ "services" "openssh" "permitRootLogin" ]
-++ obsolete [ "services" "xserver" "startSSHAgent" ] [ "services" "xserver" "startOpenSSHAgent" ]
-++ obsolete [ "services" "xserver" "startOpenSSHAgent" ] [ "programs" "ssh" "startAgent" ]
-++ alias [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ]
-
-# VirtualBox
-++ obsolete [ "services" "virtualbox" "enable" ] [ "virtualisation" "virtualbox" "guest" "enable" ]
-++ obsolete [ "services" "virtualboxGuest" "enable" ] [ "virtualisation" "virtualbox" "guest" "enable" ]
-++ obsolete [ "programs" "virtualbox" "enable" ] [ "virtualisation" "virtualbox" "host" "enable" ]
-++ obsolete [ "programs" "virtualbox" "addNetworkInterface" ] [ "virtualisation" "virtualbox" "host" "addNetworkInterface" ]
-++ obsolete [ "programs" "virtualbox" "enableHardening" ] [ "virtualisation" "virtualbox" "host" "enableHardening" ]
-++ obsolete [ "services" "virtualboxHost" "enable" ] [ "virtualisation" "virtualbox" "host" "enable" ]
-++ obsolete [ "services" "virtualboxHost" "addNetworkInterface" ] [ "virtualisation" "virtualbox" "host" "addNetworkInterface" ]
-++ obsolete [ "services" "virtualboxHost" "enableHardening" ] [ "virtualisation" "virtualbox" "host" "enableHardening" ]
-
-# Tarsnap
-++ obsolete [ "services" "tarsnap" "config" ] [ "services" "tarsnap" "archives" ]
-
-# proxy
-++ obsolete [ "nix" "proxy" ] [ "networking" "proxy" "default" ]
-
-# KDE
-++ deprecated [ "kde" "extraPackages" ] [ "environment" "systemPackages" ]
-++ obsolete [ "environment" "kdePackages" ] [ "environment" "systemPackages" ]
-
-# Multiple efi bootloaders now
-++ obsolete [ "boot" "loader" "efi" "efibootmgr" "enable" ] [ "boot" "loader" "efi" "canTouchEfiVariables" ]
-
-# NixOS environment changes
-# !!! this hardcodes bash, could we detect from config which shell is actually used?
-++ obsolete [ "environment" "promptInit" ] [ "programs" "bash" "promptInit" ]
-
-++ obsolete [ "services" "xserver" "driSupport" ] [ "hardware" "opengl" "driSupport" ]
-++ obsolete [ "services" "xserver" "driSupport32Bit" ] [ "hardware" "opengl" "driSupport32Bit" ]
-++ obsolete [ "services" "xserver" "s3tcSupport" ] [ "hardware" "opengl" "s3tcSupport" ]
-++ obsolete [ "hardware" "opengl" "videoDrivers" ] [ "services" "xserver" "videoDrivers" ]
-
-++ obsolete [ "services" "mysql55" ] [ "services" "mysql" ]
-
-++ alias    [ "environment" "checkConfigurationOptions" ] [ "_module" "check" ]
-
-# XBMC
-++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]
-++ obsolete [ "services" "xserver" "desktopManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]
-
-# DNSCrypt-proxy
-++ obsolete [ "services" "dnscrypt-proxy" "port" ] [ "services" "dnscrypt-proxy" "localPort" ]
-
-# Options that are obsolete and have no replacement.
-++ obsolete' [ "boot" "loader" "grub" "bootDevice" ]
-++ obsolete' [ "boot" "initrd" "luks" "enable" ]
-++ obsolete' [ "programs" "bash" "enable" ]
-++ obsolete' [ "services" "samba" "defaultShare" ]
-++ obsolete' [ "services" "syslog-ng" "serviceName" ]
-++ obsolete' [ "services" "syslog-ng" "listenToJournal" ]
-++ obsolete' [ "ec2" "metadata" ]
-++ obsolete' [ "services" "openvpn" "enable" ]
-
-)
+{
+  imports = [
+    (mkRenamedOptionModule [ "environment" "x11Packages" ] [ "environment" "systemPackages" ])
+    (mkRenamedOptionModule [ "environment" "enableBashCompletion" ] [ "programs" "bash" "enableCompletion" ])
+    (mkRenamedOptionModule [ "environment" "nix" ] [ "nix" "package" ])
+    (mkRenamedOptionModule [ "fonts" "enableFontConfig" ] [ "fonts" "fontconfig" "enable" ])
+    (mkRenamedOptionModule [ "fonts" "extraFonts" ] [ "fonts" "fonts" ])
+
+    (mkRenamedOptionModule [ "security" "extraSetuidPrograms" ] [ "security" "setuidPrograms" ])
+    (mkRenamedOptionModule [ "networking" "enableWLAN" ] [ "networking" "wireless" "enable" ])
+    (mkRenamedOptionModule [ "networking" "enableRT73Firmware" ] [ "networking" "enableRalinkFirmware" ])
+
+    # Old Grub-related options.
+    (mkRenamedOptionModule [ "boot" "initrd" "extraKernelModules" ] [ "boot" "initrd" "kernelModules" ])
+    (mkRenamedOptionModule [ "boot" "extraKernelParams" ] [ "boot" "kernelParams" ])
+
+    # smartd
+    (mkRenamedOptionModule [ "services" "smartd" "deviceOpts" ] [ "services" "smartd" "defaults" "monitored" ])
+
+    # OpenSSH
+    (mkRenamedOptionModule [ "services" "sshd" "ports" ] [ "services" "openssh" "ports" ])
+    (mkAliasOptionModule [ "services" "sshd" "enable" ] [ "services" "openssh" "enable" ])
+    (mkRenamedOptionModule [ "services" "sshd" "allowSFTP" ] [ "services" "openssh" "allowSFTP" ])
+    (mkRenamedOptionModule [ "services" "sshd" "forwardX11" ] [ "services" "openssh" "forwardX11" ])
+    (mkRenamedOptionModule [ "services" "sshd" "gatewayPorts" ] [ "services" "openssh" "gatewayPorts" ])
+    (mkRenamedOptionModule [ "services" "sshd" "permitRootLogin" ] [ "services" "openssh" "permitRootLogin" ])
+    (mkRenamedOptionModule [ "services" "xserver" "startSSHAgent" ] [ "services" "xserver" "startOpenSSHAgent" ])
+    (mkRenamedOptionModule [ "services" "xserver" "startOpenSSHAgent" ] [ "programs" "ssh" "startAgent" ])
+    (mkAliasOptionModule [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ])
+
+    # VirtualBox
+    (mkRenamedOptionModule [ "services" "virtualbox" "enable" ] [ "virtualisation" "virtualbox" "guest" "enable" ])
+    (mkRenamedOptionModule [ "services" "virtualboxGuest" "enable" ] [ "virtualisation" "virtualbox" "guest" "enable" ])
+    (mkRenamedOptionModule [ "programs" "virtualbox" "enable" ] [ "virtualisation" "virtualbox" "host" "enable" ])
+    (mkRenamedOptionModule [ "programs" "virtualbox" "addNetworkInterface" ] [ "virtualisation" "virtualbox" "host" "addNetworkInterface" ])
+    (mkRenamedOptionModule [ "programs" "virtualbox" "enableHardening" ] [ "virtualisation" "virtualbox" "host" "enableHardening" ])
+    (mkRenamedOptionModule [ "services" "virtualboxHost" "enable" ] [ "virtualisation" "virtualbox" "host" "enable" ])
+    (mkRenamedOptionModule [ "services" "virtualboxHost" "addNetworkInterface" ] [ "virtualisation" "virtualbox" "host" "addNetworkInterface" ])
+    (mkRenamedOptionModule [ "services" "virtualboxHost" "enableHardening" ] [ "virtualisation" "virtualbox" "host" "enableHardening" ])
+
+    # Tarsnap
+    (mkRenamedOptionModule [ "services" "tarsnap" "config" ] [ "services" "tarsnap" "archives" ])
+
+    # proxy
+    (mkRenamedOptionModule [ "nix" "proxy" ] [ "networking" "proxy" "default" ])
+
+    # KDE
+    (mkRenamedOptionModule [ "kde" "extraPackages" ] [ "environment" "systemPackages" ])
+    (mkRenamedOptionModule [ "environment" "kdePackages" ] [ "environment" "systemPackages" ])
+
+    # Multiple efi bootloaders now
+    (mkRenamedOptionModule [ "boot" "loader" "efi" "efibootmgr" "enable" ] [ "boot" "loader" "efi" "canTouchEfiVariables" ])
+
+    # NixOS environment changes
+    # !!! this hardcodes bash, could we detect from config which shell is actually used?
+    (mkRenamedOptionModule [ "environment" "promptInit" ] [ "programs" "bash" "promptInit" ])
+
+    (mkRenamedOptionModule [ "services" "xserver" "driSupport" ] [ "hardware" "opengl" "driSupport" ])
+    (mkRenamedOptionModule [ "services" "xserver" "driSupport32Bit" ] [ "hardware" "opengl" "driSupport32Bit" ])
+    (mkRenamedOptionModule [ "services" "xserver" "s3tcSupport" ] [ "hardware" "opengl" "s3tcSupport" ])
+    (mkRenamedOptionModule [ "hardware" "opengl" "videoDrivers" ] [ "services" "xserver" "videoDrivers" ])
+
+    (mkRenamedOptionModule [ "services" "mysql55" ] [ "services" "mysql" ])
+
+    (mkAliasOptionModule [ "environment" "checkConfigurationOptions" ] [ "_module" "check" ])
+
+    # XBMC
+    (mkRenamedOptionModule [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ])
+    (mkRenamedOptionModule [ "services" "xserver" "desktopManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ])
+
+    # DNSCrypt-proxy
+    (mkRenamedOptionModule [ "services" "dnscrypt-proxy" "port" ] [ "services" "dnscrypt-proxy" "localPort" ])
+
+    # Options that are obsolete and have no replacement.
+    (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ])
+    (mkRemovedOptionModule [ "programs" "bash" "enable" ])
+    (mkRemovedOptionModule [ "services" "samba" "defaultShare" ])
+    (mkRemovedOptionModule [ "services" "syslog-ng" "serviceName" ])
+    (mkRemovedOptionModule [ "services" "syslog-ng" "listenToJournal" ])
+    (mkRemovedOptionModule [ "ec2" "metadata" ])
+    (mkRemovedOptionModule [ "services" "openvpn" "enable" ])
+
+  ];
+}
diff --git a/nixos/modules/services/continuous-integration/jenkins/default.nix b/nixos/modules/services/continuous-integration/jenkins/default.nix
index 31e585f211fe..0568b1af7d5c 100644
--- a/nixos/modules/services/continuous-integration/jenkins/default.nix
+++ b/nixos/modules/services/continuous-integration/jenkins/default.nix
@@ -65,11 +65,15 @@ in {
       };
 
       environment = mkOption {
-        default = { NIX_REMOTE = "daemon"; };
+        default = { };
         type = with types; attrsOf str;
         description = ''
           Additional environment variables to be passed to the jenkins process.
-          The environment will always include JENKINS_HOME.
+          As a base environment, jenkins receives NIX_PATH, SSL_CERT_FILE and
+          GIT_SSL_CAINFO from <option>environment.sessionVariables</option>,
+          NIX_REMOTE is set to "daemon" and JENKINS_HOME is set to
+          the value of <option>services.jenkins.home</option>. This option has
+          precedence and can be used to override those mentioned variables.
         '';
       };
 
@@ -106,12 +110,29 @@ in {
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
 
-      environment = {
-        JENKINS_HOME = cfg.home;
-      } // cfg.environment;
+      environment =
+        let
+          selectedSessionVars =
+            lib.filterAttrs (n: v: builtins.elem n
+                [ "NIX_PATH"
+                  "SSL_CERT_FILE"
+                  "GIT_SSL_CAINFO"
+                ])
+              config.environment.sessionVariables;
+        in
+          selectedSessionVars //
+          { JENKINS_HOME = cfg.home;
+            NIX_REMOTE = "daemon";
+          } //
+          cfg.environment;
 
       path = cfg.packages;
 
+      # Force .war (re)extraction, or else we might run stale Jenkins.
+      preStart = ''
+        rm -rf ${cfg.home}/war
+      '';
+
       script = ''
         ${pkgs.jdk}/bin/java -jar ${pkgs.jenkins} --httpPort=${toString cfg.port} ${concatStringsSep " " cfg.extraOptions}
       '';
diff --git a/nixos/modules/services/continuous-integration/jenkins/job-builder.nix b/nixos/modules/services/continuous-integration/jenkins/job-builder.nix
new file mode 100644
index 000000000000..ec15a6a3d706
--- /dev/null
+++ b/nixos/modules/services/continuous-integration/jenkins/job-builder.nix
@@ -0,0 +1,155 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  jenkinsCfg = config.services.jenkins;
+  cfg = config.services.jenkins.jobBuilder;
+
+in {
+  options = {
+    services.jenkins.jobBuilder = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether or not to enable the Jenkins Job Builder (JJB) service. It
+          allows defining jobs for Jenkins in a declarative manner.
+
+          Jobs managed through the Jenkins WebUI (or by other means) are left
+          unchanged.
+
+          Note that it really is declarative configuration; if you remove a
+          previously defined job, the corresponding job directory will be
+          deleted.
+
+          Please see the Jenkins Job Builder documentation for more info:
+          <link xlink:href="http://docs.openstack.org/infra/jenkins-job-builder/">
+          http://docs.openstack.org/infra/jenkins-job-builder/</link>
+        '';
+      };
+
+      yamlJobs = mkOption {
+        default = "";
+        type = types.lines;
+        example = ''
+          - job:
+              name: jenkins-job-test-1
+              builders:
+                - shell: echo 'Hello world!'
+        '';
+        description = ''
+          Job descriptions for Jenkins Job Builder in YAML format.
+        '';
+      };
+
+      jsonJobs = mkOption {
+        default = [ ];
+        type = types.listOf types.str;
+        example = literalExample ''
+          [
+            '''
+              [ { "job":
+                  { "name": "jenkins-job-test-2",
+                    "builders": [ "shell": "echo 'Hello world!'" ]
+                  }
+                }
+              ]
+            '''
+          ]
+        '';
+        description = ''
+          Job descriptions for Jenkins Job Builder in JSON format.
+        '';
+      };
+
+      nixJobs = mkOption {
+        default = [ ];
+        type = types.listOf types.attrs;
+        example = literalExample ''
+          [ { job =
+              { name = "jenkins-job-test-3";
+                builders = [
+                  { shell = "echo 'Hello world!'"; }
+                ];
+              };
+            }
+          ];
+        '';
+        description = ''
+          Job descriptions for Jenkins Job Builder in Nix format.
+
+          This is a trivial wrapper around jsonJobs, using builtins.toJSON
+          behind the scene.
+        '';
+      };
+    };
+  };
+
+  config = mkIf (jenkinsCfg.enable && cfg.enable) {
+    systemd.services.jenkins-job-builder = {
+      description = "Jenkins Job Builder Service";
+      # JJB can run either before or after jenkins. We chose after, so we can
+      # always use curl to notify (running) jenkins to reload its config.
+      after = [ "jenkins.service" ];
+      wantedBy = [ "multi-user.target" ];
+
+      path = with pkgs; [ jenkins-job-builder curl ];
+
+      # Q: Why manipulate files directly instead of using "jenkins-jobs upload [...]"?
+      # A: Because this module is for administering a local jenkins install,
+      #    and using local file copy allows us to not worry about
+      #    authentication.
+      script =
+        let
+          yamlJobsFile = builtins.toFile "jobs.yaml" cfg.yamlJobs;
+          jsonJobsFiles =
+            map (x: (builtins.toFile "jobs.json" x))
+              (cfg.jsonJobs ++ [(builtins.toJSON cfg.nixJobs)]);
+          jobBuilderOutputDir = "/run/jenkins-job-builder/output";
+          # Stamp file is placed in $JENKINS_HOME/jobs/$JOB_NAME/ to indicate
+          # ownership. Enables tracking and removal of stale jobs.
+          ownerStamp = ".config-xml-managed-by-nixos-jenkins-job-builder";
+        in
+          ''
+            rm -rf ${jobBuilderOutputDir}
+            cur_decl_jobs=/run/jenkins-job-builder/declarative-jobs
+            rm -f "$cur_decl_jobs"
+
+            # Create / update jobs
+            mkdir -p ${jobBuilderOutputDir}
+            for inputFile in ${yamlJobsFile} ${concatStringsSep " " jsonJobsFiles}; do
+                HOME="${jenkinsCfg.home}" "${pkgs.jenkins-job-builder}/bin/jenkins-jobs" --ignore-cache test -o "${jobBuilderOutputDir}" "$inputFile"
+            done
+
+            for file in "${jobBuilderOutputDir}/"*; do
+                test -f "$file" || continue
+                jobname="$(basename $file)"
+                jobdir="${jenkinsCfg.home}/jobs/$jobname"
+                echo "Creating / updating job \"$jobname\""
+                mkdir -p "$jobdir"
+                touch "$jobdir/${ownerStamp}"
+                cp "$file" "$jobdir/config.xml"
+                echo "$jobname" >> "$cur_decl_jobs"
+            done
+
+            # Remove stale jobs
+            for file in "${jenkinsCfg.home}"/jobs/*/${ownerStamp}; do
+                test -f "$file" || continue
+                jobdir="$(dirname $file)"
+                jobname="$(basename "$jobdir")"
+                grep --quiet --line-regexp "$jobname" "$cur_decl_jobs" 2>/dev/null && continue
+                echo "Deleting stale job \"$jobname\""
+                rm -rf "$jobdir"
+            done
+
+            echo "Asking Jenkins to reload config"
+            curl --silent -X POST http://localhost:${toString jenkinsCfg.port}/reload
+          '';
+      serviceConfig = {
+        User = jenkinsCfg.user;
+        RuntimeDirectory = "jenkins-job-builder";
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index bae088c6610e..16e3235eb2c8 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -119,7 +119,7 @@ in
       extraPlugins = mkOption {
         type = types.listOf types.path;
         default = [];
-        example = literalExample "pkgs.postgis";
+        example = literalExample "[ (pkgs.postgis.override { postgresql = pkgs.postgresql94; }).v_2_1_4 ]";
         description = ''
           When this list contains elements a new store path is created.
           PostgreSQL and the elments are symlinked into it. Then pg_config,
@@ -202,6 +202,8 @@ in
                   # For non-root operation.
                   initdb
                 fi
+                # See postStart!
+                touch "${cfg.dataDir}/.first_startup"
             fi
 
             ln -sfn "${configFile}" "${cfg.dataDir}/postgresql.conf"
diff --git a/nixos/modules/services/hardware/actkbd.nix b/nixos/modules/services/hardware/actkbd.nix
index 82de362c371b..b16a8f50a3d8 100644
--- a/nixos/modules/services/hardware/actkbd.nix
+++ b/nixos/modules/services/hardware/actkbd.nix
@@ -125,6 +125,9 @@ in
       };
     };
 
+    # For testing
+    environment.systemPackages = [ pkgs.actkbd ];
+
   };
 
 }
diff --git a/nixos/modules/services/hardware/tlp.nix b/nixos/modules/services/hardware/tlp.nix
index f221c82e2eda..23b6edcefd1a 100644
--- a/nixos/modules/services/hardware/tlp.nix
+++ b/nixos/modules/services/hardware/tlp.nix
@@ -6,9 +6,23 @@ let
 
 cfg = config.services.tlp;
 
-tlp = pkgs.tlp.override { kmod = config.system.sbin.modprobe; };
-
-confFile = pkgs.writeText "tlp" (builtins.readFile "${tlp}/etc/default/tlp" + cfg.extraConfig);
+enableRDW = config.networking.networkmanager.enable;
+
+tlp = pkgs.tlp.override {
+  inherit enableRDW;
+  kmod = config.system.sbin.modprobe;
+};
+
+# XXX: We can't use writeTextFile + readFile here because it triggers
+# TLP build to get the .drv (even on --dry-run).
+confFile = pkgs.runCommand "tlp"
+  { config = cfg.extraConfig;
+    passAsFile = [ "config" ];
+  }
+  ''
+    cat ${tlp}/etc/default/tlp > $out
+    cat $configPath >> $out
+  '';
 
 in
 
@@ -81,13 +95,15 @@ in
     environment.etc = [{ source = confFile;
                          target = "default/tlp";
                        }
-                      ] ++ optional tlp.enableRDW {
+                      ] ++ optional enableRDW {
                         source = "${tlp}/etc/NetworkManager/dispatcher.d/99tlp-rdw-nm";
                         target = "NetworkManager/dispatcher.d/99tlp-rdw-nm";
                       };
 
     environment.systemPackages = [ tlp ];
 
+    boot.kernelModules = [ "msr" ];
+
   };
 
 }
diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix
index e8beba4b3586..3a9e62a02052 100644
--- a/nixos/modules/services/mail/postfix.nix
+++ b/nixos/modules/services/mail/postfix.nix
@@ -11,6 +11,8 @@ let
 
   mainCf =
     ''
+      compatibility_level = 2
+
       queue_directory = /var/postfix/queue
       command_directory = ${pkgs.postfix}/sbin
       daemon_directory = ${pkgs.postfix}/libexec/postfix
@@ -31,10 +33,7 @@ let
           mynetworks_style = ${cfg.networksStyle}
         ''
       else
-        # Postfix default is subnet, but let's play safe
-        ''
-          mynetworks_style = host
-        '')
+        "")
     + optionalString (cfg.hostname != "") ''
       myhostname = ${cfg.hostname}
     ''
@@ -89,7 +88,7 @@ let
   masterCf = ''
     # ==========================================================================
     # service type  private unpriv  chroot  wakeup  maxproc command + args
-    #               (yes)   (yes)   (yes)   (never) (100)
+    #               (yes)   (yes)   (no)    (never) (100)
     # ==========================================================================
     smtp      inet  n       -       n       -       -       smtpd
     #submission inet n       -       n       -       -       smtpd
@@ -232,8 +231,7 @@ in
         default = null;
         example = ["localdomain"];
         description = "
-          List of domains we agree to relay to. Default is the same as
-          destination.
+          List of domains we agree to relay to. Default is empty.
         ";
       };
 
@@ -357,32 +355,29 @@ in
         }
       ];
 
-    jobs.postfix =
-      # I copy _lots_ of shipped configuration filed
-      # that can be left as is. I am afraid the exact
-      # will list slightly change in next Postfix
-      # release, so listing them all one-by-one in an
-      # accurate way is unlikely to be better.
+    systemd.services.postfix =
       { description = "Postfix mail server";
 
         wantedBy = [ "multi-user.target" ];
         after = [ "network.target" ];
 
-        daemonType = "fork";
+        serviceConfig = {
+          Type = "forking";
+          Restart = "always";
+          PIDFile = "/var/postfix/queue/pid/master.pid";
+        };
 
         preStart = ''
-          if ! [ -d /var/spool/postfix ]; then
-            ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue
-          fi
+          ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue
 
           ${pkgs.coreutils}/bin/chown -R ${user}:${group} /var/postfix
           ${pkgs.coreutils}/bin/chown -R ${user}:${setgidGroup} /var/postfix/queue
           ${pkgs.coreutils}/bin/chmod -R ug+rwX /var/postfix/queue
           ${pkgs.coreutils}/bin/chown root:root /var/spool/mail
           ${pkgs.coreutils}/bin/chmod a+rwxt /var/spool/mail
-          ${pkgs.coreutils}/bin/ln -sf /var/spool/mail /var/mail
+          ${pkgs.coreutils}/bin/ln -sf /var/spool/mail /var/
 
-          ln -sf "${pkgs.postfix}/etc/postfix/"* /var/postfix/conf
+          ln -sf ${pkgs.postfix}/etc/postfix/postfix-files /var/postfix/conf
 
           ln -sf ${aliasesFile} /var/postfix/conf/aliases
           ln -sf ${virtualFile} /var/postfix/conf/virtual
@@ -391,12 +386,18 @@ in
 
           ${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases
           ${pkgs.postfix}/sbin/postmap -c /var/postfix/conf /var/postfix/conf/virtual
+        '';
 
+        script = ''
           ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start
         '';
 
+        reload = ''
+          ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf reload
+        '';
+
         preStop = ''
-            ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop
+          ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop
         '';
 
       };
diff --git a/nixos/modules/services/misc/autofs.nix b/nixos/modules/services/misc/autofs.nix
index f4a1059d09f0..b4dae79cf8a9 100644
--- a/nixos/modules/services/misc/autofs.nix
+++ b/nixos/modules/services/misc/autofs.nix
@@ -71,48 +71,17 @@ in
 
   config = mkIf cfg.enable {
 
-    environment.etc = singleton
-      { target = "auto.master";
-        source = pkgs.writeText "auto.master" cfg.autoMaster;
-      };
-
     boot.kernelModules = [ "autofs4" ];
 
-    jobs.autofs =
+    systemd.services.autofs =
       { description = "Filesystem automounter";
+        wantedBy = [ "multi-user.target" ];
+        after = [ "network.target" ];
 
-        startOn = "started network-interfaces";
-        stopOn = "stopping network-interfaces";
-
-        path = [ pkgs.nfs-utils pkgs.sshfsFuse ];
-
-        preStop =
-          ''
-            set -e; while :; do pkill -TERM automount; sleep 1; done
-          '';
-
-        # automount doesn't clean up when receiving SIGKILL.
-        # umount -l should unmount the directories recursively when they are no longer used
-        # It does, but traces are left in /etc/mtab. So unmount recursively..
-        postStop =
-          ''
-          PATH=${pkgs.gnused}/bin:${pkgs.coreutils}/bin
-          exec &> /tmp/logss
-          # double quote for sed:
-          escapeSpaces(){ sed 's/ /\\\\040/g'; }
-          unescapeSpaces(){ sed 's/\\040/ /g'; }
-          sed -n 's@^\s*\(\([^\\ ]\|\\ \)*\)\s.*@\1@p' ${autoMaster} | sed 's/[\\]//' | while read mountPoint; do
-            sed -n "s@[^ ]\+\s\+\($(echo "$mountPoint"| escapeSpaces)[^ ]*\).*@\1@p" /proc/mounts | sort -r | unescapeSpaces| while read smountP; do
-              ${pkgs.utillinux}/bin/umount -l "$smountP" || true
-            done
-          done
-          '';
-
-        script =
-          ''
-            ${if cfg.debug then "exec &> /var/log/autofs" else ""}
-            exec ${pkgs.autofs5}/sbin/automount ${if cfg.debug then "-d" else ""} -f -t ${builtins.toString cfg.timeout} "${autoMaster}" ${if cfg.debug then "-l7" else ""}
-          '';
+        serviceConfig = {
+          ExecStart = "${pkgs.autofs5}/sbin/automount ${if cfg.debug then "-d" else ""} -f -t ${builtins.toString cfg.timeout} ${autoMaster} ${if cfg.debug then "-l7" else ""}";
+          ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+        };
       };
 
   };
diff --git a/nixos/modules/services/misc/calibre-server.nix b/nixos/modules/services/misc/calibre-server.nix
new file mode 100644
index 000000000000..a920aa22ccdf
--- /dev/null
+++ b/nixos/modules/services/misc/calibre-server.nix
@@ -0,0 +1,63 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.calibre-server;
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.calibre-server = {
+
+      enable = mkEnableOption "calibre-server";
+
+      libraryDir = mkOption {
+        description = ''
+          The directory where the Calibre library to serve is.
+          '';
+          type = types.path;
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    systemd.services.calibre-server =
+      {
+        description = "Calibre Server";
+        after = [ "network.target" ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          User = "calibre-server";
+          Restart = "always";
+          ExecStart = "${pkgs.calibre}/bin/calibre-server --with-library=${cfg.libraryDir}";
+        };
+
+      };
+
+    environment.systemPackages = [ pkgs.calibre ];
+
+    users.extraUsers.calibre-server = {
+        uid = config.ids.uids.calibre-server;
+        group = "calibre-server";
+      };
+
+    users.extraGroups.calibre-server = {
+        gid = config.ids.gids.calibre-server;
+      };
+
+  };
+
+}
diff --git a/nixos/modules/services/misc/ihaskell.nix b/nixos/modules/services/misc/ihaskell.nix
index 7f7f981de498..13c41466eab2 100644
--- a/nixos/modules/services/misc/ihaskell.nix
+++ b/nixos/modules/services/misc/ihaskell.nix
@@ -22,9 +22,9 @@ in
       };
 
       haskellPackages = mkOption {
-        default = pkgs.haskellngPackages;
-        defaultText = "pkgs.haskellngPackages";
-        example = literalExample "pkgs.haskell-ng.packages.ghc784";
+        default = pkgs.haskellPackages;
+        defaultText = "pkgs.haskellPackages";
+        example = literalExample "pkgs.haskell.packages.ghc784";
         description = ''
           haskellPackages used to build IHaskell and other packages.
           This can be used to change the GHC version used to build
diff --git a/nixos/modules/services/misc/nixos-manual.nix b/nixos/modules/services/misc/nixos-manual.nix
index c10d8197686f..7534eb0ae6a3 100644
--- a/nixos/modules/services/misc/nixos-manual.nix
+++ b/nixos/modules/services/misc/nixos-manual.nix
@@ -92,7 +92,9 @@ in
 
     system.build.manual = manual;
 
-    environment.systemPackages = [ manual.manpages manual.manual help ];
+    environment.systemPackages =
+      [ manual.manual help ]
+      ++ optional config.programs.man.enable manual.manpages;
 
     boot.extraTTYs = mkIf cfg.showManual ["tty${cfg.ttyNumber}"];
 
diff --git a/nixos/modules/services/misc/parsoid.nix b/nixos/modules/services/misc/parsoid.nix
index 0844190a5490..ea97d6e30e83 100644
--- a/nixos/modules/services/misc/parsoid.nix
+++ b/nixos/modules/services/misc/parsoid.nix
@@ -91,7 +91,7 @@ in
       wantedBy = [ "multi-user.target" ];
       after = [ "network.target" ];
       serviceConfig = {
-        ExecStart = "${pkgs.nodePackages.parsoid}/lib/node_modules/parsoid/api/server.js -c ${confFile} -n ${toString cfg.workers}";
+        ExecStart = "${pkgs.nodePackages_0_10.parsoid}/lib/node_modules/parsoid/api/server.js -c ${confFile} -n ${toString cfg.workers}";
       };
     };
 
diff --git a/nixos/modules/services/misc/synergy.nix b/nixos/modules/services/misc/synergy.nix
index 054df965347d..7e8eadbe5f37 100644
--- a/nixos/modules/services/misc/synergy.nix
+++ b/nixos/modules/services/misc/synergy.nix
@@ -89,6 +89,7 @@ in
         wantedBy = optional cfgC.autoStart "multi-user.target";
         path = [ pkgs.synergy ];
         serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergyc -f ${optionalString (cfgC.screenName != "") "-n ${cfgC.screenName}"} ${cfgC.serverAddress}'';
+        serviceConfig.Restart = "on-failure";
       };
     })
     (mkIf cfgS.enable {
@@ -98,6 +99,7 @@ in
         wantedBy = optional cfgS.autoStart "multi-user.target";
         path = [ pkgs.synergy ];
         serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} -f ${optionalString (cfgS.address != "") "-a ${cfgS.address}"} ${optionalString (cfgS.screenName != "") "-n ${cfgS.screenName}" }'';
+        serviceConfig.Restart = "on-failure";
       };
     })
   ];
diff --git a/nixos/modules/services/monitoring/bosun.nix b/nixos/modules/services/monitoring/bosun.nix
index 7e8dea4ec024..ebe4741f01bd 100644
--- a/nixos/modules/services/monitoring/bosun.nix
+++ b/nixos/modules/services/monitoring/bosun.nix
@@ -9,7 +9,7 @@ let
     tsdbHost = ${cfg.opentsdbHost}
     httpListen = ${cfg.listenAddress}
     stateFile = ${cfg.stateFile}
-    checkFrequency = 5m
+    checkFrequency = ${cfg.checkFrequency}
 
     ${cfg.extraConfig}
   '';
@@ -77,6 +77,14 @@ in {
         '';
       };
 
+      checkFrequency = mkOption {
+        type = types.str;
+        default = "5m";
+        description = ''
+          Bosun's check frequency
+        '';
+      };
+
       extraConfig = mkOption {
         type = types.string;
         default = "";
diff --git a/nixos/modules/services/monitoring/grafana.nix b/nixos/modules/services/monitoring/grafana.nix
index fa653565a67f..5302728eae91 100644
--- a/nixos/modules/services/monitoring/grafana.nix
+++ b/nixos/modules/services/monitoring/grafana.nix
@@ -318,7 +318,7 @@ in {
       wantedBy = ["multi-user.target"];
       after = ["networking.target"];
       serviceConfig = {
-        ExecStart = "${cfg.package-backend}/bin/grafana --config ${cfgFile} web";
+        ExecStart = "${cfg.package}/bin/grafana --config ${cfgFile} web";
         WorkingDirectory = cfg.dataDir;
         User = "grafana";
       };
diff --git a/nixos/modules/services/monitoring/teamviewer.nix b/nixos/modules/services/monitoring/teamviewer.nix
index beba5dcd1b06..533f1ea6644b 100644
--- a/nixos/modules/services/monitoring/teamviewer.nix
+++ b/nixos/modules/services/monitoring/teamviewer.nix
@@ -29,6 +29,7 @@ in
 
       wantedBy = [ "graphical.target" ];
       after = [ "NetworkManager-wait-online.service" "network.target" ];
+      preStart = "mkdir -pv /var/tmp/teamviewer10/{logs,config}";
 
       serviceConfig = {
         Type = "forking";
diff --git a/nixos/modules/services/networking/asterisk.nix b/nixos/modules/services/networking/asterisk.nix
index b079cb227303..13617a1b6c58 100644
--- a/nixos/modules/services/networking/asterisk.nix
+++ b/nixos/modules/services/networking/asterisk.nix
@@ -201,6 +201,7 @@ in
         for d in '${varlibdir}' '${spooldir}' '${logdir}'; do
           # TODO: Make exceptions for /var directories that likely should be updated
           if [ ! -e "$d" ]; then
+            mkdir -p "$d"
             cp --recursive ${pkgs.asterisk}/"$d" "$d"
             chown --recursive ${asteriskUser} "$d"
             find "$d" -type d | xargs chmod 0755
diff --git a/nixos/modules/services/networking/autossh.nix b/nixos/modules/services/networking/autossh.nix
new file mode 100644
index 000000000000..9ea17469870d
--- /dev/null
+++ b/nixos/modules/services/networking/autossh.nix
@@ -0,0 +1,114 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.autossh;
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.autossh = {
+
+      sessions = mkOption {
+        type = types.listOf (types.submodule {
+          options = {
+            name = mkOption {
+              type = types.string;
+              example = "socks-peer";
+              description = "Name of the local AutoSSH session";
+            };
+            user = mkOption {
+              type = types.string;
+              example = "bill";
+              description = "Name of the user the AutoSSH session should run as";
+            };
+            monitoringPort = mkOption {
+              type = types.int;
+              default = 0;
+              example = 20000;
+              description = ''
+                Port to be used by AutoSSH for peer monitoring. Note, that
+                AutoSSH also uses mport+1. Value of 0 disables the keep-alive
+                style monitoring
+              '';
+            };
+            extraArguments = mkOption {
+              type = types.string;
+              example = "-N -D4343 bill@socks.example.net";
+              description = ''
+                Arguments to be passed to AutoSSH and retransmitted to SSH
+                process. Some meaningful options include -N (don't run remote
+                command), -D (open SOCKS proxy on local port), -R (forward
+                remote port), -L (forward local port), -v (Enable debug). Check
+                ssh manual for the complete list.
+              '';
+            };
+          };
+        });
+
+        default = [];
+        description = ''
+          List of AutoSSH sessions to start as systemd services. Each service is
+          named 'autossh-{session.name}'.
+        '';
+
+        example = [
+          {
+            name="socks-peer";
+            user="bill";
+            monitoringPort = 20000;
+            extraArguments="-N -D4343 billremote@socks.host.net";
+          }
+        ];
+
+      };
+    };
+
+  };
+
+  ###### implementation
+
+  config = mkIf (cfg.sessions != []) {
+
+    systemd.services =
+
+      lib.fold ( s : acc : acc //
+        {
+          "autossh-${s.name}" =
+            let
+              mport = if s ? monitoringPort then s.monitoringPort else 0;
+            in
+            {
+              description = "AutoSSH session (" + s.name + ")";
+
+              after = [ "network.target" ];
+              wantedBy = [ "multi-user.target" ];
+
+              # To be able to start the service with no network connection
+              environment.AUTOSSH_GATETIME="0";
+
+              # How often AutoSSH checks the network, in seconds
+              environment.AUTOSSH_POLL="30";
+
+              serviceConfig = {
+                  User = "${s.user}";
+                  PermissionsStartOnly = true;
+                  # AutoSSH may exit with 0 code if the SSH session was
+                  # gracefully terminated by either local or remote side.
+                  Restart = "on-success";
+                  ExecStart = "${pkgs.autossh}/bin/autossh -M ${toString mport} ${s.extraArguments}";
+              };
+            };
+        }) {} cfg.sessions;
+
+    environment.systemPackages = [ pkgs.autossh ];
+
+  };
+}
diff --git a/nixos/modules/services/networking/copy-com.nix b/nixos/modules/services/networking/copy-com.nix
index 69a41ab97963..ee0d043d471b 100644
--- a/nixos/modules/services/networking/copy-com.nix
+++ b/nixos/modules/services/networking/copy-com.nix
@@ -39,7 +39,8 @@ in
 
     systemd.services."copy-com-${cfg.user}" = {
       description = "Copy.com client";
-      after = [ "network.target" "local-fs.target" ];
+      wants = [ "network-online.target" ];
+      after = [ "network-online.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 ""}";
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index 8370eca21e52..7df194fa419b 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -6,16 +6,18 @@ with lib;
 let
   cfg = config.networking.networkmanager;
 
-  stateDirs = "/var/lib/NetworkManager /var/lib/dhclient";
+  # /var/lib/misc is for dnsmasq.leases.
+  stateDirs = "/var/lib/NetworkManager /var/lib/dhclient /var/lib/misc";
 
   configFile = writeText "NetworkManager.conf" ''
     [main]
     plugins=keyfile
 
     [keyfile]
-    ${optionalString (config.networking.hostName != "") ''
-      hostname=${config.networking.hostName}
-    ''}
+    ${optionalString (config.networking.hostName != "")
+      ''hostname=${config.networking.hostName}''}
+    ${optionalString (cfg.unmanaged != [])
+      ''unmanaged-devices=${lib.concatStringsSep ";" cfg.unmanaged}''}
 
     [logging]
     level=WARN
@@ -40,7 +42,6 @@ let
     polkit.addRule(function(action, subject) {
       if (
         subject.isInGroup("networkmanager")
-        && subject.active
         && (action.id.indexOf("org.freedesktop.NetworkManager.") == 0
             || action.id.indexOf("org.freedesktop.ModemManager")  == 0
         ))
@@ -97,6 +98,16 @@ in {
         '';
       };
 
+      unmanaged = mkOption {
+        type = types.listOf types.string;
+        default = [];
+        description = ''
+          List of interfaces that will not be managed by NetworkManager.
+          Interface name can be specified here, but if you need more fidelity
+          see "Device List Format" in NetworkManager.conf man page.
+        '';
+      };
+
       # Ugly hack for using the correct gnome3 packageSet
       basePackages = mkOption {
         type = types.attrsOf types.path;
@@ -206,10 +217,16 @@ in {
 
     environment.systemPackages = cfg.packages;
 
-    users.extraGroups = singleton {
+    users.extraGroups = [{
       name = "networkmanager";
       gid = config.ids.gids.networkmanager;
-    };
+    }
+    {
+      name = "nm-openvpn";
+    }];
+    users.extraUsers = [{
+      name = "nm-openvpn";
+    }];
 
     systemd.packages = cfg.packages;
 
diff --git a/nixos/modules/services/networking/quassel.nix b/nixos/modules/services/networking/quassel.nix
index 005eb7bd7614..52c7ac8e6893 100644
--- a/nixos/modules/services/networking/quassel.nix
+++ b/nixos/modules/services/networking/quassel.nix
@@ -23,11 +23,11 @@ in
         '';
       };
 
-      interface = mkOption {
-        default = "127.0.0.1";
+      interfaces = mkOption {
+        default = [ "127.0.0.1" ];
         description = ''
-          The interface the Quassel daemon will be listening to.  If `127.0.0.1',
-          only clients on the local host can connect to it; if `0.0.0.0', clients
+          The interfaces the Quassel daemon will be listening to.  If `[ 127.0.0.1 ]',
+          only clients on the local host can connect to it; if `[ 0.0.0.0 ]', clients
           can access it from any network interface.
         '';
       };
@@ -78,7 +78,8 @@ in
       { description = "Quassel IRC client daemon";
 
         wantedBy = [ "multi-user.target" ];
-        after = [ "network.target" ];
+        after = [ "network.target" ] ++ optional config.services.postgresql.enable "postgresql.service"
+                                     ++ optional config.services.mysql.enable "mysql.service";
 
         preStart = ''
           mkdir -p ${cfg.dataDir}
@@ -87,7 +88,7 @@ in
 
         serviceConfig =
         {
-          ExecStart = "${quassel}/bin/quasselcore --listen=${cfg.interface} --port=${toString cfg.portNumber} --configdir=${cfg.dataDir}";
+          ExecStart = "${quassel}/bin/quasselcore --listen=${concatStringsSep '','' cfg.interfaces} --port=${toString cfg.portNumber} --configdir=${cfg.dataDir}";
           User = user;
           PermissionsStartOnly = true;
         };
diff --git a/nixos/modules/services/networking/supplicant.nix b/nixos/modules/services/networking/supplicant.nix
new file mode 100644
index 000000000000..502a0468787f
--- /dev/null
+++ b/nixos/modules/services/networking/supplicant.nix
@@ -0,0 +1,249 @@
+{ config, lib, utils, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.networking.supplicant;
+
+  # We must escape interfaces due to the systemd interpretation
+  subsystemDevice = interface:
+    "sys-subsystem-net-devices-${utils.escapeSystemdPath interface}.device";
+
+  serviceName = iface: "supplicant-${if (iface=="WLAN") then "wlan@" else (
+                                     if (iface=="LAN") then "lan@" else (
+                                     if (iface=="DBUS") then "dbus"
+                                     else (replaceChars [" "] ["-"] iface)))}";
+
+  # TODO: Use proper privilege separation for wpa_supplicant
+  supplicantService = iface: suppl:
+    let
+      deps = (if (iface=="WLAN"||iface=="LAN") then ["sys-subsystem-net-devices-%i.device"] else (
+             if (iface=="DBUS") then ["dbus.service"]
+             else (map subsystemDevice (splitString " " iface))))
+             ++ optional (suppl.bridge!="") (subsystemDevice suppl.bridge);
+
+      ifaceArg = concatStringsSep " -N " (map (i: "-i${i}") (splitString " " iface));
+      driverArg = optionalString (suppl.driver != null) "-D${suppl.driver}";
+      bridgeArg = optionalString (suppl.bridge!="") "-b${suppl.bridge}";
+      confFileArg = optionalString (suppl.configFile.path!=null) "-c${suppl.configFile.path}";
+      extraConfFile = pkgs.writeText "supplicant-extra-conf-${replaceChars [" "] ["-"] iface}" ''
+        ${optionalString suppl.userControlled.enable "ctrl_interface=DIR=${suppl.userControlled.socketDir} GROUP=${suppl.userControlled.group}"}
+        ${optionalString suppl.configFile.writable "update_config=1"}
+        ${suppl.extraConf}
+      '';
+    in
+      { description = "Supplicant ${iface}${optionalString (iface=="WLAN"||iface=="LAN") " %I"}";
+        wantedBy = [ "network.target" ];
+        bindsTo = deps;
+        after = deps;
+        before = [ "network.target" ];
+        # Receive restart event after resume
+        partOf = [ "post-resume.target" ];
+
+        path = [ pkgs.coreutils ];
+
+        preStart = ''
+          ${optionalString (suppl.configFile.path!=null) ''
+            touch -a ${suppl.configFile.path}
+            chmod 600 ${suppl.configFile.path}
+          ''}
+          ${optionalString suppl.userControlled.enable ''
+            if ! test -e ${suppl.userControlled.socketDir}; then
+                mkdir -m 0770 -p ${suppl.userControlled.socketDir}
+                chgrp ${suppl.userControlled.group} ${suppl.userControlled.socketDir}
+            fi
+
+            if test "$(stat --printf '%G' ${suppl.userControlled.socketDir})" != "${suppl.userControlled.group}"; then
+                echo "ERROR: bad ownership on ${suppl.userControlled.socketDir}" >&2
+                exit 1
+            fi
+          ''}
+        '';
+
+        serviceConfig.ExecStart = "${pkgs.wpa_supplicant}/bin/wpa_supplicant -s ${driverArg} ${confFileArg} -I${extraConfFile} ${bridgeArg} ${suppl.extraCmdArgs} ${if (iface=="WLAN"||iface=="LAN") then "-i%I" else (if (iface=="DBUS") then "-u" else ifaceArg)}";
+
+      };
+
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    networking.supplicant = mkOption {
+      type = types.attrsOf types.optionSet;
+
+      default = { };
+
+      example = {
+        "wlan0 wlan1" = {
+          configFile = "/etc/wpa_supplicant";
+          userControlled.group = "network";
+          extraConf = ''
+            ap_scan=1
+            p2p_disabled=1
+          '';
+          extraCmdArgs = "-u -W";
+          bridge = "br0";
+        };
+      };
+
+      description = ''
+        Interfaces for which to start <command>wpa_supplicant</command>.
+        The supplicant is used to scan for and associate with wireless networks,
+        or to authenticate with 802.1x capable network switches.
+
+        The value of this option is an attribute set. Each attribute configures a
+        <command>wpa_supplicant</command> service, where the attribute name specifies
+        the name of the interface that <command>wpa_supplicant</command> operates on.
+        The attribute name can be a space separated list of interfaces.
+        The attribute names <literal>WLAN</literal>, <literal>LAN</literal> and <literal>DBUS</literal>
+        have a special meaning. <literal>WLAN</literal> and <literal>LAN</literal> are
+        configurations for universal <command>wpa_supplicant</command> service that is
+        started for each WLAN interface or for each LAN interface, respectively.
+        <literal>DBUS</literal> defines a device-unrelated <command>wpa_supplicant</command>
+        service that can be accessed through <literal>D-Bus</literal>.
+      '';
+
+      options = {
+
+        configFile = {
+
+          path = mkOption {
+            type = types.path;
+            example = "/etc/wpa_supplicant.conf";
+            description = ''
+              External <literal>wpa_supplicant.conf</literal> configuration file.
+              The configuration options defined declaratively within <literal>networking.supplicant</literal> have
+              precedence over options defined in <literal>configFile</literal>.
+            '';
+          };
+
+          writable = mkOption {
+            type = types.bool;
+            default = false;
+            description = ''
+              Whether the configuration file at <literal>configFile.path</literal> should be written to by
+              <literal>wpa_supplicant</literal>.
+            '';
+          };
+
+        };
+
+        extraConf = mkOption {
+          type = types.lines;
+          default = "";
+          example = ''
+            ap_scan=1
+            device_name=My-NixOS-Device
+            device_type=1-0050F204-1
+            driver_param=use_p2p_group_interface=1
+            disable_scan_offload=1
+            p2p_listen_reg_class=81
+            p2p_listen_channel=1
+            p2p_oper_reg_class=81
+            p2p_oper_channel=1
+            manufacturer=NixOS
+            model_name=NixOS_Unstable
+            model_number=2015
+          '';
+          description = ''
+            Configuration options for <literal>wpa_supplicant.conf</literal>.
+            Options defined here have precedence over options in <literal>configFile</literal>.
+            NOTE: Do not write sensitive data into <literal>extraConf</literal> as it will
+            be world-readable in the <literal>nix-store</literal>. For sensitive information
+            use the <literal>configFile</literal> instead.
+          '';
+        };
+
+        extraCmdArgs = mkOption {
+          type = types.str;
+          default = "";
+          example = "-e/var/run/wpa_supplicant/entropy.bin";
+          description =
+            "Command line arguments to add when executing <literal>wpa_supplicant</literal>.";
+        };
+
+        driver = mkOption {
+          type = types.nullOr types.str;
+          default = "nl80211,wext";
+          description = "Force a specific wpa_supplicant driver.";
+        };
+
+        bridge = mkOption {
+          type = types.str;
+          default = "";
+          description = "Name of the bridge interface that wpa_supplicant should listen at.";
+        };
+
+        userControlled = {
+
+          enable = mkOption {
+            type = types.bool;
+            default = false;
+            description = ''
+              Allow normal users to control wpa_supplicant through wpa_gui or wpa_cli.
+              This is useful for laptop users that switch networks a lot and don't want
+              to depend on a large package such as NetworkManager just to pick nearby
+              access points.
+            '';
+          };
+
+          socketDir = mkOption {
+            type = types.str;
+            default = "/var/run/wpa_supplicant";
+            description = "Directory of sockets for controlling wpa_supplicant.";
+          };
+
+          group = mkOption {
+            type = types.str;
+            default = "wheel";
+            example = "network";
+            description = "Members of this group can control wpa_supplicant.";
+          };
+
+        };
+
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf (cfg != {}) {
+
+    environment.systemPackages =  [ pkgs.wpa_supplicant ];
+
+    services.dbus.packages = [ pkgs.wpa_supplicant ];
+
+    systemd.services = mapAttrs' (n: v: nameValuePair (serviceName n) (supplicantService n v)) cfg;
+
+    services.udev.packages = [
+      (pkgs.writeTextFile {
+        name = "99-zzz-60-supplicant.rules";
+        destination = "/etc/udev/rules.d/99-zzz-60-supplicant.rules";
+        text = ''
+          ${flip (concatMapStringsSep "\n") (filter (n: n!="WLAN" && n!="LAN" && n!="DBUS") (attrNames cfg)) (iface:
+            flip (concatMapStringsSep "\n") (splitString " " iface) (i: ''
+              ACTION=="add", SUBSYSTEM=="net", ENV{INTERFACE}=="${i}", TAG+="systemd", ENV{SYSTEMD_WANTS}+="supplicant-${replaceChars [" "] ["-"] iface}.service", TAG+="SUPPLICANT_ASSIGNED"''))}
+
+          ${optionalString (hasAttr "WLAN" cfg) ''
+            ACTION=="add", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", TAG!="SUPPLICANT_ASSIGNED", TAG+="systemd", PROGRAM="${pkgs.systemd}/bin/systemd-escape -p %E{INTERFACE}", ENV{SYSTEMD_WANTS}+="supplicant-wlan@$result.service"
+          ''}
+          ${optionalString (hasAttr "LAN" cfg) ''
+            ACTION=="add", SUBSYSTEM=="net", ENV{DEVTYPE}=="lan", TAG!="SUPPLICANT_ASSIGNED", TAG+="systemd", PROGRAM="${pkgs.systemd}/bin/systemd-escape -p %E{INTERFACE}", ENV{SYSTEMD_WANTS}+="supplicant-lan@$result.service"
+          ''}
+        '';
+      })];
+
+  };
+
+}
+
diff --git a/nixos/modules/services/networking/tlsdated.nix b/nixos/modules/services/networking/tlsdated.nix
index f2d0c9f35c9c..ff7d0178a81a 100644
--- a/nixos/modules/services/networking/tlsdated.nix
+++ b/nixos/modules/services/networking/tlsdated.nix
@@ -63,7 +63,7 @@ in
         });
         default = [
           {
-            host = "www.ptb.de";
+            host = "encrypted.google.com";
             port = 443;
             proxy = null;
           }
diff --git a/nixos/modules/services/networking/wakeonlan.nix b/nixos/modules/services/networking/wakeonlan.nix
index 11bb7e925255..ebfba263cd8f 100644
--- a/nixos/modules/services/networking/wakeonlan.nix
+++ b/nixos/modules/services/networking/wakeonlan.nix
@@ -40,7 +40,7 @@ in
       ];
       description = ''
         Interfaces where to enable Wake-On-LAN, and how. Two methods available:
-        "magickey" and "password". The password has the shape of six bytes
+        "magicpacket" and "password". The password has the shape of six bytes
         in hexadecimal separated by a colon each. For more information,
         check the ethtool manual.
       '';
diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix
index 02d80a77da50..1b5e83173e8f 100644
--- a/nixos/modules/services/scheduling/cron.nix
+++ b/nixos/modules/services/scheduling/cron.nix
@@ -100,7 +100,7 @@ in
       environment.systemPackages = [ cronNixosPkg ];
 
       environment.etc.crontab =
-        { source = pkgs.runCommand "crontabs" { inherit allFiles; }
+        { source = pkgs.runCommand "crontabs" { inherit allFiles; preferLocalBuild = true; }
             ''
               touch $out
               for i in $allFiles; do
diff --git a/nixos/modules/services/web-servers/lighttpd/default.nix b/nixos/modules/services/web-servers/lighttpd/default.nix
index 2c662c0aead9..171503db4eec 100644
--- a/nixos/modules/services/web-servers/lighttpd/default.nix
+++ b/nixos/modules/services/web-servers/lighttpd/default.nix
@@ -44,7 +44,6 @@ let
     "mod_flv_streaming"
     "mod_magnet"
     "mod_mysql_vhost"
-    "mod_rewrite"
     "mod_scgi"
     "mod_setenv"
     "mod_trigger_b4_dl"
diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix
index 0fc255c4d64c..e32d6669b046 100644
--- a/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -104,6 +104,7 @@ in {
 
     services.xserver.desktopManager.session = singleton
       { name = "gnome3";
+        bgSupport = true;
         start = ''
           # Set GTK_DATA_PREFIX so that GTK+ can find the themes
           export GTK_DATA_PREFIX=${config.system.path}
diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix
index 5061d59b7c7f..6fdd5b4fa36d 100644
--- a/nixos/modules/services/x11/desktop-managers/kde5.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde5.nix
@@ -8,38 +8,9 @@ let
   cfg = xcfg.desktopManager.kde5;
   xorg = pkgs.xorg;
 
-  phononBackends = {
-    gstreamer = [
-      pkgs.phonon_backend_gstreamer
-      pkgs.gst_all.gstreamer
-      pkgs.gst_all.gstPluginsBase
-      pkgs.gst_all.gstPluginsGood
-      pkgs.gst_all.gstPluginsUgly
-      pkgs.gst_all.gstPluginsBad
-      pkgs.gst_all.gstFfmpeg # for mp3 playback
-      pkgs.phonon_qt5_backend_gstreamer
-      pkgs.gst_all_1.gstreamer
-      pkgs.gst_all_1.gst-plugins-base
-      pkgs.gst_all_1.gst-plugins-good
-      pkgs.gst_all_1.gst-plugins-ugly
-      pkgs.gst_all_1.gst-plugins-bad
-      pkgs.gst_all_1.gst-libav # for mp3 playback
-    ];
-
-    vlc = [
-      pkgs.phonon_qt5_backend_vlc
-      pkgs.phonon_backend_vlc
-    ];
-  };
-
-  phononBackendPackages = flip concatMap cfg.phononBackends
-    (name: attrByPath [name] (throw "unknown phonon backend `${name}'") phononBackends);
-
   kf5 = pkgs.kf5_stable;
-
-  plasma5 = pkgs.plasma5_stable.override { inherit kf5; };
-
-  kdeApps = pkgs.kdeApps_stable.override { inherit kf5; };
+  plasma5 = pkgs.plasma5_stable;
+  kdeApps = pkgs.kdeApps_stable;
 
 in
 
@@ -53,14 +24,24 @@ in
         description = "Enable the Plasma 5 (KDE 5) desktop environment.";
       };
 
-      phononBackends = mkOption {
-        type = types.listOf types.str;
-        default = ["gstreamer"];
-        example = ["gstreamer" "vlc"];
-        description = ''
-          Phonon backends to use in KDE. Only the VLC and GStreamer backends are
-          available. The GStreamer backend is preferred by upstream.
-        '';
+      phonon = {
+
+        gstreamer = {
+          enable = mkOption {
+            type = types.bool;
+            default = true;
+            description = "Enable the GStreamer Phonon backend (recommended).";
+          };
+        };
+
+        vlc = {
+          enable = mkOption {
+            type = types.bool;
+            default = false;
+            description = "Enable the VLC Phonon backend.";
+          };
+        };
+
       };
 
     };
@@ -88,23 +69,77 @@ in
     };
 
     environment.systemPackages =
-      filter isDerivation (builtins.attrValues plasma5)
-      ++ filter isDerivation (builtins.attrValues kf5)
-      ++ [
+      [
         pkgs.qt4 # qtconfig is the only way to set Qt 4 theme
 
-        kdeApps.kde-baseapps
-        kdeApps.kde-base-artwork
-        kdeApps.kmix
+        kf5.frameworkintegration
+        kf5.kinit
+
+        plasma5.breeze
+        plasma5.kde-cli-tools
+        plasma5.kdeplasma-addons
+        plasma5.kgamma5
+        plasma5.khelpcenter
+        plasma5.khotkeys
+        plasma5.kinfocenter
+        plasma5.kmenuedit
+        plasma5.kscreen
+        plasma5.ksysguard
+        plasma5.kwayland
+        plasma5.kwin
+        plasma5.kwrited
+        plasma5.milou
+        plasma5.oxygen
+        plasma5.polkit-kde-agent
+        plasma5.systemsettings
+
+        plasma5.plasma-desktop
+        plasma5.plasma-workspace
+        plasma5.plasma-workspace-wallpapers
+
+        kdeApps.ark
+        kdeApps.dolphin
+        kdeApps.dolphin-plugins
+        kdeApps.ffmpegthumbs
+        kdeApps.gwenview
+        kdeApps.kate
+        kdeApps.kdegraphics-thumbnailers
         kdeApps.konsole
-        kdeApps.oxygen-icons
-
-        kdeApps.kde-runtime
+        kdeApps.okular
+        kdeApps.print-manager
 
+        kdeApps.oxygen-icons
         pkgs.hicolor_icon_theme
 
+        plasma5.kde-gtk-config
         pkgs.orion # GTK theme, nearly identical to Breeze
-      ] ++ phononBackendPackages;
+      ]
+      ++ lib.optional config.hardware.bluetooth.enable plasma5.bluedevil
+      ++ lib.optional config.networking.networkmanager.enable plasma5.plasma-nm
+      ++ lib.optional config.hardware.pulseaudio.enable plasma5.plasma-pa
+      ++ lib.optional config.powerManagement.enable plasma5.powerdevil
+      ++ lib.optionals cfg.phonon.gstreamer.enable
+        [
+          pkgs.phonon_backend_gstreamer
+          pkgs.gst_all.gstreamer
+          pkgs.gst_all.gstPluginsBase
+          pkgs.gst_all.gstPluginsGood
+          pkgs.gst_all.gstPluginsUgly
+          pkgs.gst_all.gstPluginsBad
+          pkgs.gst_all.gstFfmpeg # for mp3 playback
+          pkgs.phonon_qt5_backend_gstreamer
+          pkgs.gst_all_1.gstreamer
+          pkgs.gst_all_1.gst-plugins-base
+          pkgs.gst_all_1.gst-plugins-good
+          pkgs.gst_all_1.gst-plugins-ugly
+          pkgs.gst_all_1.gst-plugins-bad
+          pkgs.gst_all_1.gst-libav # for mp3 playback
+        ]
+      ++ lib.optionals cfg.phonon.vlc.enable
+        [
+          pkgs.phonon_qt5_backend_vlc
+          pkgs.phonon_backend_vlc
+        ];
 
     environment.pathsToLink = [ "/share" ];
 
@@ -114,7 +149,7 @@ in
     };
 
     environment.profileRelativeEnvVars =
-      mkIf (lib.elem "gstreamer" cfg.phononBackends)
+      mkIf cfg.phonon.gstreamer.enable
       {
         GST_PLUGIN_SYSTEM_PATH = [ "/lib/gstreamer-0.10" ];
         GST_PLUGIN_SYSTEM_PATH_1_0 = [ "/lib/gstreamer-1.0" ];
diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix
index c9a563768323..58eb6f050131 100644
--- a/nixos/modules/services/x11/display-managers/gdm.nix
+++ b/nixos/modules/services/x11/display-managers/gdm.nix
@@ -20,7 +20,9 @@ in
 
       enable = mkEnableOption ''
         GDM as the display manager.
-        <emphasis>GDM is very experimental and may render system unusable.</emphasis>
+        <emphasis>GDM in NixOS is not well-tested with desktops other
+        than GNOME, so use with caution, as it could render the
+        system unusable.</emphasis>
       '';
 
       debug = mkEnableOption ''
diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix
index 3f1d190ae66b..16a0d1b6d963 100644
--- a/nixos/modules/services/x11/display-managers/sddm.nix
+++ b/nixos/modules/services/x11/display-managers/sddm.nix
@@ -35,8 +35,23 @@ let
     SessionCommand=${dmcfg.session.script}
     SessionDir=${dmcfg.session.desktops}
     XauthPath=${pkgs.xorg.xauth}/bin/xauth
+
+    ${optionalString cfg.autoLogin.enable ''
+    [Autologin]
+    User=${cfg.autoLogin.user}
+    Session=${defaultSessionName}.desktop
+    Relogin=${if cfg.autoLogin.relogin then "true" else "false"}
+    ''}
+
+    ${cfg.extraConfig}
   '';
 
+  defaultSessionName =
+    let
+      dm = xcfg.desktopManager.default;
+      wm = xcfg.windowManager.default;
+    in dm + optionalString (wm != "none") (" + " + wm);
+
 in
 {
   options = {
@@ -50,6 +65,19 @@ in
         '';
       };
 
+      extraConfig = mkOption {
+        type = types.str;
+        default = "";
+        example = ''
+          [Autologin]
+          User=john
+          Session=plasma.desktop
+        '';
+        description = ''
+          Extra lines appended to the configuration of SDDM.
+        '';
+      };
+
       theme = mkOption {
         type = types.str;
         default = "maui";
@@ -57,12 +85,62 @@ in
           Greeter theme to use.
         '';
       };
+
+      autoLogin = mkOption {
+        default = {};
+        description = ''
+          Configuration for automatic login.
+        '';
+
+        type = types.submodule {
+	  options = {
+            enable = mkOption {
+              type = types.bool;
+              default = false;
+              description = ''
+                Automatically log in as the sepecified <option>autoLogin.user</option>.
+              '';
+            };
+
+            user = mkOption {
+              type = types.nullOr types.str;
+              default = null;
+              description = ''
+                User to be used for the autologin.
+              '';
+            };
+
+            relogin = mkOption {
+              type = types.bool;
+              default = false;
+              description = ''
+                If true automatic login will kick in again on session exit, otherwise it
+                will work only the first time.
+              '';
+            };
+	  };
+        };
+      };
+
     };
 
   };
 
   config = mkIf cfg.enable {
 
+    assertions = [
+      { assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null;
+        message = "SDDM auto-login requires services.xserver.displayManager.sddm.autoLogin.user to be set";
+      }
+      { assertion = cfg.autoLogin.enable -> elem defaultSessionName dmcfg.session.names;
+        message = ''
+          SDDM auto-login requires that services.xserver.desktopManager.default and
+	  services.xserver.windowMananger.default are set to valid values. The current
+	  default session: ${defaultSessionName} is not valid.
+	'';
+      }
+    ];
+
     services.xserver.displayManager.slim.enable = false;
 
     services.xserver.displayManager.job = {
@@ -93,6 +171,18 @@ in
         session  optional       pam_keyinit.so force revoke
         session  optional       pam_permit.so
       '';
+
+      sddm-autologin.text = ''
+        auth     requisite pam_nologin.so
+        auth     required  pam_succeed_if.so uid >= 1000 quiet
+        auth     required  pam_permit.so
+
+        account  include   sddm
+
+        password include   sddm
+
+        session  include   sddm
+      '';
     };
 
     users.extraUsers.sddm = {
diff --git a/nixos/modules/services/x11/redshift.nix b/nixos/modules/services/x11/redshift.nix
index ffae22d2d670..d40373ec2e55 100644
--- a/nixos/modules/services/x11/redshift.nix
+++ b/nixos/modules/services/x11/redshift.nix
@@ -22,14 +22,16 @@ in {
     latitude = mkOption {
       type = types.str;
       description = ''
-        Your current latitude.
+        Your current latitude, between
+        <literal>-90.0</literal> and <literal>90.0</literal>.
       '';
     };
 
     longitude = mkOption {
       type = types.str;
       description = ''
-        Your current longitude.
+        Your current longitude, between
+        between <literal>-180.0</literal> and <literal>180.0</literal>.
       '';
     };
 
@@ -38,14 +40,16 @@ in {
         type = types.int;
         default = 5500;
         description = ''
-          Colour temperature to use during the day.
+          Colour temperature to use during the day, between
+          <literal>1000</literal> and <literal>25000</literal> K.
         '';
       };
       night = mkOption {
         type = types.int;
         default = 3700;
         description = ''
-          Colour temperature to use at night.
+          Colour temperature to use at night, between
+          <literal>1000</literal> and <literal>25000</literal> K.
         '';
       };
     };
diff --git a/nixos/modules/services/x11/window-managers/clfswm.nix b/nixos/modules/services/x11/window-managers/clfswm.nix
new file mode 100644
index 000000000000..9d8eecb56c77
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/clfswm.nix
@@ -0,0 +1,31 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.clfswm;
+in
+
+{
+  options = {
+    services.xserver.windowManager.clfswm = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        example = true;
+        description = "Enable the clfswm tiling window manager.";
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "clfswm";
+      start = ''
+        ${pkgs.clfswm}/bin/clfswm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.clfswm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix
index 4751de07a15d..31f42f5ffb9f 100644
--- a/nixos/modules/services/x11/window-managers/default.nix
+++ b/nixos/modules/services/x11/window-managers/default.nix
@@ -10,6 +10,7 @@ in
   imports = [
     ./afterstep.nix
     ./bspwm.nix
+    ./clfswm.nix
     ./compiz.nix
     ./fluxbox.nix
     ./herbstluftwm.nix
diff --git a/nixos/modules/services/x11/window-managers/xmonad.nix b/nixos/modules/services/x11/window-managers/xmonad.nix
index c922ca7848d1..288800d514d3 100644
--- a/nixos/modules/services/x11/window-managers/xmonad.nix
+++ b/nixos/modules/services/x11/window-managers/xmonad.nix
@@ -20,9 +20,9 @@ in
       };
 
       haskellPackages = mkOption {
-        default = pkgs.haskellngPackages;
-        defaultText = "pkgs.haskellngPackages";
-        example = literalExample "pkgs.haskell-ng.packages.ghc784";
+        default = pkgs.haskellPackages;
+        defaultText = "pkgs.haskellPackages";
+        example = literalExample "pkgs.haskell.packages.ghc784";
         description = ''
           haskellPackages used to build Xmonad and other packages.
           This can be used to change the GHC version used to build
diff --git a/nixos/modules/system/boot/initrd-network.nix b/nixos/modules/system/boot/initrd-network.nix
new file mode 100644
index 000000000000..6c6e2fafad43
--- /dev/null
+++ b/nixos/modules/system/boot/initrd-network.nix
@@ -0,0 +1,149 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.boot.initrd.network;
+
+in
+{
+
+  options = {
+
+    boot.initrd.network.enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Add network connectivity support to initrd.
+
+        Network options are configured via <literal>ip</literal> kernel
+        option, according to the kernel documentation.
+      '';
+    };
+
+    boot.initrd.network.ssh.enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Start SSH service during initrd boot. It can be used to debug failing
+        boot on a remote server, enter pasphrase for an encrypted partition etc.
+        Service is killed when stage-1 boot is finished.
+      '';
+    };
+
+    boot.initrd.network.ssh.port = mkOption {
+      type = types.int;
+      default = 22;
+      description = ''
+        Port on which SSH initrd service should listen.
+      '';
+    };
+
+    boot.initrd.network.ssh.shell = mkOption {
+      type = types.str;
+      default = "/bin/ash";
+      description = ''
+        Login shell of the remote user. Can be used to limit actions user can do.
+      '';
+    };
+
+    boot.initrd.network.ssh.hostRSAKey = mkOption {
+      type = types.nullOr types.path;
+      default = null;
+      description = ''
+        RSA SSH private key file in the Dropbear format.
+
+        WARNING: This key is contained insecurely in the global Nix store. Do NOT
+        use your regular SSH host private keys for this purpose or you'll expose
+        them to regular users!
+      '';
+    };
+
+    boot.initrd.network.ssh.hostDSSKey = mkOption {
+      type = types.nullOr types.path;
+      default = null;
+      description = ''
+        DSS SSH private key file in the Dropbear format.
+
+        WARNING: This key is contained insecurely in the global Nix store. Do NOT
+        use your regular SSH host private keys for this purpose or you'll expose
+        them to regular users!
+      '';
+    };
+
+    boot.initrd.network.ssh.hostECDSAKey = mkOption {
+      type = types.nullOr types.path;
+      default = null;
+      description = ''
+        ECDSA SSH private key file in the Dropbear format.
+
+        WARNING: This key is contained insecurely in the global Nix store. Do NOT
+        use your regular SSH host private keys for this purpose or you'll expose
+        them to regular users!
+      '';
+    };
+
+    boot.initrd.network.ssh.authorizedKeys = mkOption {
+      type = types.listOf types.str;
+      default = config.users.extraUsers.root.openssh.authorizedKeys.keys;
+      description = ''
+        Authorized keys for the root user on initrd.
+      '';
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+
+    boot.initrd.kernelModules = [ "af_packet" ];
+
+    boot.initrd.extraUtilsCommands = ''
+      copy_bin_and_libs ${pkgs.mkinitcpio-nfs-utils}/bin/ipconfig
+    '' + optionalString cfg.ssh.enable ''
+      copy_bin_and_libs ${pkgs.dropbear}/bin/dropbear
+
+      cp -pv ${pkgs.glibc}/lib/libnss_files.so.* $out/lib
+    '';
+
+    boot.initrd.extraUtilsCommandsTest = optionalString cfg.ssh.enable ''
+      $out/bin/dropbear -V
+    '';
+
+    boot.initrd.postEarlyDeviceCommands = ''
+      # Search for interface definitions in command line
+      for o in $(cat /proc/cmdline); do
+        case $o in
+          ip=*)
+            ipconfig $o && hasNetwork=1
+            ;;
+        esac
+      done
+    '' + optionalString cfg.ssh.enable ''
+      if [ -n "$hasNetwork" ]; then
+        mkdir /dev/pts
+        mount -t devpts devpts /dev/pts
+
+        mkdir -p /etc
+        echo 'root:x:0:0:root:/root:${cfg.ssh.shell}' > /etc/passwd
+        echo '${cfg.ssh.shell}' > /etc/shells
+        echo 'passwd: files' > /etc/nsswitch.conf
+
+        mkdir -p /var/log
+        touch /var/log/lastlog
+
+        mkdir -p /etc/dropbear
+        ${optionalString (cfg.ssh.hostRSAKey != null) "ln -s ${cfg.ssh.hostRSAKey} /etc/dropbear/dropbear_rsa_host_key"}
+        ${optionalString (cfg.ssh.hostDSSKey != null) "ln -s ${cfg.ssh.hostDSSKey} /etc/dropbear/dropbear_dss_host_key"}
+        ${optionalString (cfg.ssh.hostECDSAKey != null) "ln -s ${cfg.ssh.hostECDSAKey} /etc/dropbear/dropbear_ecdsa_host_key"}
+
+        mkdir -p /root/.ssh
+        ${concatStrings (map (key: ''
+          echo -n ${escapeShellArg key} >> /root/.ssh/authorized_keys
+        '') cfg.ssh.authorizedKeys)}
+
+        dropbear -s -j -k -E -m -p ${toString cfg.ssh.port}
+      fi
+    '';
+
+  };
+}
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index 0b349749244f..5f09e937537f 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -378,6 +378,17 @@ in
         '';
       };
 
+      systemHasTPM = mkOption {
+        default = "";
+        example = "YES_TPM_is_activated";
+        type = types.string;
+        description = ''
+          Assertion that the target system has an activated TPM. It is a safety
+          check before allowing the activation of 'enableTrustedBoot'. TrustedBoot
+          WILL FAIL TO BOOT YOUR SYSTEM if no TPM is available.
+        '';
+      };
+
     };
 
   };
@@ -453,8 +464,8 @@ in
           message = "Trusted GRUB does not have ZFS support";
         }
         {
-          assertion = !cfg.enableTrustedBoot;
-          message = "Trusted GRUB can break your system. Remove assertion if you want to test trustedGRUB nevertheless.";
+          assertion = !cfg.enableTrustedBoot || cfg.systemHasTPM == "YES_TPM_is_activated";
+          message = "Trusted GRUB can break the system! Confirm that the system has an activated TPM by setting 'systemHasTPM'.";
         }
       ] ++ flip concatMap cfg.mirroredBoots (args: [
         {
@@ -477,4 +488,15 @@ in
 
   ];
 
+
+  imports =
+    [ (mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ])
+      (mkRenamedOptionModule [ "boot" "copyKernels" ] [ "boot" "loader" "grub" "copyKernels" ])
+      (mkRenamedOptionModule [ "boot" "extraGrubEntries" ] [ "boot" "loader" "grub" "extraEntries" ])
+      (mkRenamedOptionModule [ "boot" "extraGrubEntriesBeforeNixos" ] [ "boot" "loader" "grub" "extraEntriesBeforeNixOS" ])
+      (mkRenamedOptionModule [ "boot" "grubDevice" ] [ "boot" "loader" "grub" "device" ])
+      (mkRenamedOptionModule [ "boot" "bootMount" ] [ "boot" "loader" "grub" "bootDevice" ])
+      (mkRenamedOptionModule [ "boot" "grubSplashImage" ] [ "boot" "loader" "grub" "splashImage" ])
+    ];
+
 }
diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix
index 4a14ff1879c9..763703205630 100644
--- a/nixos/modules/system/boot/luksroot.nix
+++ b/nixos/modules/system/boot/luksroot.nix
@@ -32,9 +32,12 @@ let
     ''}
 
     open_normally() {
-        cryptsetup luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} \
+        echo luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} \
           ${optionalString (header != null) "--header=${header}"} \
-          ${optionalString (keyFile != null) "--key-file=${keyFile} ${optionalString (keyFileSize != null) "--keyfile-size=${toString keyFileSize}"}"}
+          ${optionalString (keyFile != null) "--key-file=${keyFile} ${optionalString (keyFileSize != null) "--keyfile-size=${toString keyFileSize}"}"} \
+          > /.luksopen_args
+        cryptsetup-askpass
+        rm /.luksopen_args
     }
 
     ${optionalString (luks.yubikeySupport && (yubikey != null)) ''
@@ -418,6 +421,18 @@ in
     boot.initrd.extraUtilsCommands = ''
       copy_bin_and_libs ${pkgs.cryptsetup}/bin/cryptsetup
 
+      cat > $out/bin/cryptsetup-askpass <<EOF
+      #!$out/bin/sh -e
+      if [ -e /.luksopen_args ]; then
+        cryptsetup \$(cat /.luksopen_args)
+        killall cryptsetup
+      else
+        echo "Passphrase is not requested now"
+        exit 1
+      fi
+      EOF
+      chmod +x $out/bin/cryptsetup-askpass
+
       ${optionalString luks.yubikeySupport ''
         copy_bin_and_libs ${pkgs.ykpers}/bin/ykchalresp
         copy_bin_and_libs ${pkgs.ykpers}/bin/ykinfo
@@ -432,6 +447,8 @@ in
 
         cat > $out/bin/openssl-wrap <<EOF
         #!$out/bin/sh
+        export OPENSSL_CONF=$out/etc/ssl/openssl.cnf
+        $out/bin/openssl "\$@"
         EOF
         chmod +x $out/bin/openssl-wrap
       ''}
@@ -442,11 +459,6 @@ in
       ${optionalString luks.yubikeySupport ''
         $out/bin/ykchalresp -V
         $out/bin/ykinfo -V
-        cat > $out/bin/openssl-wrap <<EOF
-        #!$out/bin/sh
-        export OPENSSL_CONF=$out/etc/ssl/openssl.cnf
-        $out/bin/openssl "\$@"
-        EOF
         $out/bin/openssl-wrap version
       ''}
     '';
diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh
index 51828c5c090b..2b5d547353f8 100644
--- a/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixos/modules/system/boot/stage-1-init.sh
@@ -149,6 +149,10 @@ udevadm trigger --action=add
 udevadm settle
 
 
+# Additional devices initialization.
+@postEarlyDeviceCommands@
+
+
 # Load boot-time keymap before any LVM/LUKS initialization
 @extraUtils@/bin/busybox loadkmap < "@busyboxKeymap@"
 
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index 0759b10c00a5..0bd5387a7c0f 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -104,7 +104,7 @@ let
       stripDirs "lib bin" "-s"
 
       # Run patchelf to make the programs refer to the copied libraries.
-      for i in $out/bin/* $out/lib/*; do if ! test -L $i; then nuke-refs $i; fi; done
+      for i in $out/bin/* $out/lib/*; do if ! test -L $i; then nuke-refs -e $out $i; fi; done
 
       for i in $out/bin/*; do
           if ! test -L $i; then
@@ -203,10 +203,10 @@ let
     inherit (config.boot) resumeDevice devSize runSize;
 
     inherit (config.boot.initrd) checkJournalingFS
-      preLVMCommands postDeviceCommands postMountCommands kernelModules;
+      postEarlyDeviceCommands preLVMCommands postDeviceCommands postMountCommands kernelModules;
 
     resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}")
-                    (filter (sd: sd ? label || hasPrefix "/dev/" sd.device) config.swapDevices);
+                    (filter (sd: (sd ? label || hasPrefix "/dev/" sd.device) && !sd.randomEncryption) config.swapDevices);
 
     fsInfo =
       let f = fs: [ fs.mountPoint (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fs.fsType fs.options ];
@@ -313,6 +313,14 @@ in
       '';
     };
 
+    boot.initrd.postEarlyDeviceCommands = mkOption {
+      default = "";
+      type = types.lines;
+      description = ''
+        Shell commands to be executed early after creation of device nodes.
+      '';
+    };
+
     boot.initrd.postMountCommands = mkOption {
       default = "";
       type = types.lines;
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index 34eda7247cdd..0b7647093e0f 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -100,7 +100,7 @@ let
       # Maintaining state across reboots.
       "systemd-random-seed.service"
       "systemd-backlight@.service"
-      "systemd-rfkill@.service"
+      "systemd-rfkill.service"
 
       # Hibernate / suspend.
       "hibernate.target"
@@ -770,4 +770,11 @@ in
 
   };
 
+  # FIXME: Remove these eventually.
+  imports =
+    [ (mkRenamedOptionModule [ "boot" "systemd" "sockets" ] [ "systemd" "sockets" ])
+      (mkRenamedOptionModule [ "boot" "systemd" "targets" ] [ "systemd" "targets" ])
+      (mkRenamedOptionModule [ "boot" "systemd" "services" ] [ "systemd" "services" ])
+    ];
+
 }
diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix
index 9dd250f140ce..dbe0c9c6e03a 100644
--- a/nixos/modules/tasks/filesystems.nix
+++ b/nixos/modules/tasks/filesystems.nix
@@ -174,7 +174,7 @@ in
 
         # Swap devices.
         ${flip concatMapStrings config.swapDevices (sw:
-            "${sw.device} none swap${prioOption sw.priority}\n"
+            "${sw.realDevice} none swap${prioOption sw.priority}\n"
         )}
       '';
 
diff --git a/nixos/modules/tasks/filesystems/nfs.nix b/nixos/modules/tasks/filesystems/nfs.nix
index 79de6556f251..e454eca3a0e5 100644
--- a/nixos/modules/tasks/filesystems/nfs.nix
+++ b/nixos/modules/tasks/filesystems/nfs.nix
@@ -90,7 +90,7 @@ in
         serviceConfig.Type = "forking";
         serviceConfig.ExecStart = ''
           @${pkgs.nfs-utils}/sbin/rpc.statd rpc.statd --no-notify \
-              ${if cfg.statdPort != null then "-p ${toString statdPort}" else ""}
+              ${if cfg.statdPort != null then "-p ${toString cfg.statdPort}" else ""}
         '';
         serviceConfig.Restart = "always";
       };
diff --git a/nixos/modules/tasks/kbd.nix b/nixos/modules/tasks/kbd.nix
index 69f004888f55..5969da7062b6 100644
--- a/nixos/modules/tasks/kbd.nix
+++ b/nixos/modules/tasks/kbd.nix
@@ -4,11 +4,13 @@ with lib;
 
 let
 
+  makeColor = n: value: "COLOR_${toString n}=${value}";
+
   vconsoleConf = pkgs.writeText "vconsole.conf"
     ''
       KEYMAP=${config.i18n.consoleKeyMap}
       FONT=${config.i18n.consoleFont}
-    '';
+    '' + concatImapStringsSep "\n" makeColor config.i18n.consoleColors;
 
 in
 
diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix
index d8b1592c36bb..80b7f718580e 100644
--- a/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -222,21 +222,15 @@ in
 
         createVswitchDevice = n: v: nameValuePair "${n}-netdev"
           (let
-            managedInterfaces = filter (x: hasAttr x cfg.interfaces) v.interfaces;
-            managedInterfaceServices = concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) managedInterfaces;
-            virtualInterfaces = filter (x: (hasAttr x cfg.interfaces) && cfg.interfaces.${x}.virtual) v.interfaces;
-            virtualInterfaceServices = concatMap (i: [ "${i}-netdev.service" ]) virtualInterfaces;
             deps = map subsystemDevice v.interfaces;
             ofRules = pkgs.writeText "vswitch-${n}-openFlowRules" v.openFlowRules;
           in
           { description = "Open vSwitch Interface ${n}";
-            wantedBy = [ "network.target" "vswitchd.service" (subsystemDevice n) ];
-            requires = optionals v.bindInterfaces (deps ++ managedInterfaceServices ++ virtualInterfaceServices);
-            requiredBy = optionals v.bindInterfaces (managedInterfaceServices ++ virtualInterfaceServices);
-            bindsTo = deps ++ [ "vswitchd.service" ];
+            wantedBy = [ "network.target" "vswitchd.service" ] ++ deps;
+            bindsTo =  [ "vswitchd.service" (subsystemDevice n) ] ++ deps;
             partOf = [ "vswitchd.service" ];
-            after = [ "network-pre.target" "vswitchd.service" ] ++ deps ++ managedInterfaceServices ++ virtualInterfaceServices;
-            before = [ "network-interfaces.target" (subsystemDevice n) ];
+            after = [ "network-pre.target" "vswitchd.service" ] ++ deps;
+            before = [ "network-interfaces.target" ];
             serviceConfig.Type = "oneshot";
             serviceConfig.RemainAfterExit = true;
             path = [ pkgs.iproute config.virtualisation.vswitch.package ];
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index 03e647b1b1e7..ee21d735f959 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -426,8 +426,8 @@ in
       description =
         ''
           This option allows you to define Open vSwitches that connect
-          physical networks together.  The value of this option is an
-          attribute set.  Each attribute specifies a vswitch, with the
+          physical networks together. The value of this option is an
+          attribute set. Each attribute specifies a vswitch, with the
           attribute name specifying the name of the vswitch's network
           interface.
         '';
@@ -443,16 +443,6 @@ in
             "The physical network interfaces connected by the vSwitch.";
         };
 
-        bindInterfaces = mkOption {
-          type = types.bool;
-          default = false;
-          description = ''
-            If true, then the interfaces of the vSwitch are brought 'up' and especially
-            also 'down' together with the vSwitch. That requires that every interfaces
-            is configured as a systemd network services.
-          '';
-        };
-
         controllers = mkOption {
           type = types.listOf types.str;
           default = [];
@@ -995,21 +985,78 @@ in
 
     services.udev.packages = mkIf (cfg.wlanInterfaces != {}) [
       (pkgs.writeTextFile {
-        name = "99-zzz-wlanInterfaces-last.rules";
-        destination = "/etc/udev/rules.d/99-zzz-wlanInterfaces-last.rules";
-        text = ''
-          # If persistent udev device name is not used for an interface, then do not
-          # call systemd for that udev device name and only execute the script that
-          # modifies or prepares the WLAN interfaces. All other commands that would
-          # otherwise be executed when the udev device is added, like, e.g., the calling
-          # of systemd-sysctl or the activation of wpa_supplicant is disabled when the
-          # persistend udev device name is not usef for an interface.
-          ${flip (concatMapStringsSep "\n") (attrNames wlanDeviceInterfaces) (device:
-          let script = wlanDeviceUdevScript device (wlanListDeviceFirst device wlanDeviceInterfaces."${device}"); in
-          if hasAttr device cfg.wlanInterfaces
-          then ''ACTION=="add", SUBSYSTEM=="net", NAME=="${device}", ENV{DEVTYPE}=="wlan", RUN+="${script}"''
-          else ''ACTION=="add", SUBSYSTEM=="net", NAME=="${device}", ENV{DEVTYPE}=="wlan", NAME="", TAG-="systemd", RUN:="${script}"'')}
-        '';
+        name = "99-zzz-40-wlanInterfaces.rules";
+        destination = "/etc/udev/rules.d/99-zzz-40-wlanInterfaces.rules";
+        text =
+          let
+            # Collect all interfaces that are defined for a device
+            # as device:interface key:value pairs.
+            wlanDeviceInterfaces =
+              let
+                allDevices = unique (mapAttrsToList (_: v: v.device) cfg.wlanInterfaces);
+                interfacesOfDevice = d: filterAttrs (_: v: v.device == d) cfg.wlanInterfaces;
+              in
+                genAttrs allDevices (d: interfacesOfDevice d);
+
+            # Convert device:interface key:value pairs into a list, and if it exists,
+            # place the interface which is named after the device at the beginning.
+            wlanListDeviceFirst = device: interfaces:
+              if hasAttr device interfaces
+              then mapAttrsToList (n: v: v//{_iName=n;}) (filterAttrs (n: _: n==device) interfaces) ++ mapAttrsToList (n: v: v//{_iName=n;}) (filterAttrs (n: _: n!=device) interfaces)
+              else mapAttrsToList (n: v: v // {_iName = n;}) interfaces;
+
+            # Udev script to execute for the default WLAN interface with the persistend udev name.
+            # The script creates the required, new WLAN interfaces interfaces and configures the
+            # existing, default interface.
+            curInterfaceScript = device: current: new: pkgs.writeScript "udev-run-script-wlan-interfaces-${device}.sh" ''
+              #!${pkgs.stdenv.shell}
+              # Change the wireless phy device to a predictable name.
+              ${pkgs.iw}/bin/iw phy `${pkgs.coreutils}/bin/cat /sys/class/net/$INTERFACE/phy80211/name` set name ${device}
+
+              # Add new WLAN interfaces
+              ${flip concatMapStrings new (i: ''
+              ${pkgs.iw}/bin/iw phy ${device} interface add ${i._iName} type managed
+              '')}
+
+              # Configure the current interface
+              ${pkgs.iw}/bin/iw dev ${device} set type ${current.type}
+              ${optionalString (current.type == "mesh" && current.meshID!=null) "${pkgs.iw}/bin/iw dev ${device} set meshid ${current.meshID}"}
+              ${optionalString (current.type == "monitor" && current.flags!=null) "${pkgs.iw}/bin/iw dev ${device} set monitor ${current.flags}"}
+              ${optionalString (current.type == "managed" && current.fourAddr!=null) "${pkgs.iw}/bin/iw dev ${device} set 4addr ${if current.fourAddr then "on" else "off"}"}
+              ${optionalString (current.mac != null) "${pkgs.iproute}/bin/ip link set dev ${device} address ${current.mac}"}
+            '';
+
+            # Udev script to execute for a new WLAN interface. The script configures the new WLAN interface.
+            newInterfaceScript = new: pkgs.writeScript "udev-run-script-wlan-interfaces-${new._iName}.sh" ''
+              #!${pkgs.stdenv.shell}
+              # Configure the new interface
+              ${pkgs.iw}/bin/iw dev ${new._iName} set type ${new.type}
+              ${optionalString (new.type == "mesh" && new.meshID!=null) "${pkgs.iw}/bin/iw dev ${device} set meshid ${new.meshID}"}
+              ${optionalString (new.type == "monitor" && new.flags!=null) "${pkgs.iw}/bin/iw dev ${device} set monitor ${new.flags}"}
+              ${optionalString (new.type == "managed" && new.fourAddr!=null) "${pkgs.iw}/bin/iw dev ${device} set 4addr ${if new.fourAddr then "on" else "off"}"}
+              ${optionalString (new.mac != null) "${pkgs.iproute}/bin/ip link set dev ${device} address ${new.mac}"}
+            '';
+
+            # Udev attributes for systemd to name the device and to create a .device target.
+            systemdAttrs = n: ''NAME:="${n}", ENV{INTERFACE}:="${n}", ENV{SYSTEMD_ALIAS}:="/sys/subsystem/net/devices/${n}", TAG+="systemd"'';
+          in
+          flip (concatMapStringsSep "\n") (attrNames wlanDeviceInterfaces) (device:
+            let
+              interfaces = wlanListDeviceFirst device wlanDeviceInterfaces."${device}";
+              curInterface = elemAt interfaces 0;
+              newInterfaces = drop 1 interfaces;
+            in ''
+            # It is important to have that rule first as overwriting the NAME attribute also prevents the
+            # next rules from matching.
+            ${flip (concatMapStringsSep "\n") (wlanListDeviceFirst device wlanDeviceInterfaces."${device}") (interface:
+            ''ACTION=="add", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", ENV{INTERFACE}=="${interface._iName}", ${systemdAttrs interface._iName}, RUN+="${newInterfaceScript interface}"'')}
+
+            # Add the required, new WLAN interfaces to the default WLAN interface with the
+            # persistent, default name as assigned by udev.
+            ACTION=="add", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", NAME=="${device}", ${systemdAttrs curInterface._iName}, RUN+="${curInterfaceScript device curInterface newInterfaces}"
+            # Generate the same systemd events for both 'add' and 'move' udev events.
+            ACTION=="move", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", NAME=="${device}", ${systemdAttrs curInterface._iName}
+          '');
       }) ];
 
   };
diff --git a/nixos/modules/virtualisation/docker.nix b/nixos/modules/virtualisation/docker.nix
index 0115b972e80d..0c642bf3b816 100644
--- a/nixos/modules/virtualisation/docker.nix
+++ b/nixos/modules/virtualisation/docker.nix
@@ -46,12 +46,10 @@ in
     storageDriver =
       mkOption {
         type = types.enum ["aufs" "btrfs" "devicemapper" "overlay" "zfs"];
+        default = "devicemapper";
         description =
           ''
             This option determines which Docker storage driver to use.
-            It is required but lacks a default value as its most
-            suitable value will depend the filesystems available on the
-            host.
           '';
       };
     extraOptions =
@@ -129,7 +127,7 @@ in
           LimitNPROC = 1048576;
         } // proxy_env;
 
-        path = [ pkgs.kmod ];
+        path = [ pkgs.kmod ] ++ (optional (cfg.storageDriver == "zfs") pkgs.zfs);
         environment.MODULE_DIR = "/run/current-system/kernel-modules/lib/modules";
 
         postStart = cfg.postStart;
diff --git a/nixos/modules/virtualisation/nova-config.nix b/nixos/modules/virtualisation/nova-config.nix
deleted file mode 100644
index f8239cdec519..000000000000
--- a/nixos/modules/virtualisation/nova-config.nix
+++ /dev/null
@@ -1,5 +0,0 @@
-{ config, pkgs, modulesPath, ... }:
-
-{
-  imports = [ "${modulesPath}/virtualisation/nova-image.nix" ];
-}
diff --git a/nixos/modules/virtualisation/nova-image.nix b/nixos/modules/virtualisation/nova-image.nix
index 20ec6b024e91..44c83aee2732 100644
--- a/nixos/modules/virtualisation/nova-image.nix
+++ b/nixos/modules/virtualisation/nova-image.nix
@@ -1,90 +1,45 @@
+# Usage:
+# $ NIXOS_CONFIG=`pwd`/nixos/modules/virtualisation/nova-image.nix nix-build '<nixpkgs/nixos>' -A config.system.build.novaImage
+
 { config, lib, pkgs, ... }:
 
 with lib;
 
 {
-  imports = [ ../profiles/qemu-guest.nix ../profiles/headless.nix ./ec2-data.nix ];
-
-  system.build.novaImage =
-    pkgs.vmTools.runInLinuxVM (
-      pkgs.runCommand "nova-image"
-        { preVM =
-            ''
-              mkdir $out
-              diskImage=$out/image
-              ${pkgs.vmTools.qemu}/bin/qemu-img create -f raw $diskImage "4G"
-              mv closure xchg/
-            '';
-          buildInputs = [ pkgs.utillinux pkgs.perl ];
-          exportReferencesGraph =
-            [ "closure" config.system.build.toplevel ];
+  system.build.novaImage = import ../../lib/make-disk-image.nix {
+    inherit pkgs lib config;
+    partitioned = true;
+    diskSize = 1 * 1024;
+    configFile = pkgs.writeText "configuration.nix"
+      ''
+        {
+          imports = [ <nixpkgs/nixos/modules/virtualisation/nova-image.nix> ];
         }
-        ''
-          # Create a single / partition.
-          ${pkgs.parted}/sbin/parted /dev/vda mklabel msdos
-          ${pkgs.parted}/sbin/parted /dev/vda -- mkpart primary ext2 1M -1s
-          . /sys/class/block/vda1/uevent
-          mknod /dev/vda1 b $MAJOR $MINOR
-
-          # Create an empty filesystem and mount it.
-          ${pkgs.e2fsprogs}/sbin/mkfs.ext3 -L nixos /dev/vda1
-          ${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1
-          mkdir /mnt
-          mount /dev/vda1 /mnt
-
-          # The initrd expects these directories to exist.
-          mkdir /mnt/dev /mnt/proc /mnt/sys
-          mount --bind /proc /mnt/proc
-          mount --bind /dev /mnt/dev
-          mount --bind /sys /mnt/sys
-
-          # Copy all paths in the closure to the filesystem.
-          storePaths=$(perl ${pkgs.pathsFromGraph} /tmp/xchg/closure)
-
-          mkdir -p /mnt/nix/store
-          ${pkgs.rsync}/bin/rsync -av $storePaths /mnt/nix/store/
-
-          # Register the paths in the Nix database.
-          printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \
-              chroot /mnt ${config.nix.package}/bin/nix-store --load-db --option build-users-group ""
-
-          # Create the system profile to allow nixos-rebuild to work.
-          chroot /mnt ${config.nix.package}/bin/nix-env --option build-users-group "" \
-              -p /nix/var/nix/profiles/system --set ${config.system.build.toplevel}
-
-          # `nixos-rebuild' requires an /etc/NIXOS.
-          mkdir -p /mnt/etc
-          touch /mnt/etc/NIXOS
-
-          # `switch-to-configuration' requires a /bin/sh
-          mkdir -p /mnt/bin
-          ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh
+      '';
+  };
 
-          # Install a configuration.nix.
-          mkdir -p /mnt/etc/nixos
-          cp ${./nova-config.nix} /mnt/etc/nixos/configuration.nix
-
-          # Generate the GRUB menu.
-          chroot /mnt ${config.system.build.toplevel}/bin/switch-to-configuration boot
-
-          umount /mnt/proc /mnt/dev /mnt/sys
-          umount /mnt
-        ''
-    );
+  imports = [
+    ../profiles/qemu-guest.nix
+    ../profiles/headless.nix
+    ./ec2-data.nix
+  ];
 
   fileSystems."/".device = "/dev/disk/by-label/nixos";
 
   boot.kernelParams = [ "console=ttyS0" ];
-
-  boot.loader.grub.version = 2;
   boot.loader.grub.device = "/dev/vda";
   boot.loader.grub.timeout = 0;
 
+  # Allow root logins
+  services.openssh.enable = true;
+  services.openssh.permitRootLogin = "without-password";
+
   # Put /tmp and /var on /ephemeral0, which has a lot more space.
   # Unfortunately we can't do this with the `fileSystems' option
   # because it has no support for creating the source of a bind
   # mount.  Also, "move" /nix to /ephemeral0 by layering a unionfs-fuse
   # mount on top of it so we have a lot more space for Nix operations.
+
   /*
   boot.initrd.postMountCommands =
     ''
@@ -106,10 +61,6 @@ with lib;
     '';
 
     boot.initrd.supportedFilesystems = [ "unionfs-fuse" ];
-    */
+  */
 
-  # Allow root logins only using the SSH key that the user specified
-  # at instance creation time.
-  services.openssh.enable = true;
-  services.openssh.permitRootLogin = "without-password";
 }
diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix
index 00486df5c4ba..5fb472ebfc32 100644
--- a/nixos/modules/virtualisation/virtualbox-host.nix
+++ b/nixos/modules/virtualisation/virtualbox-host.nix
@@ -111,5 +111,8 @@ in
       };
 
     networking.interfaces.vboxnet0.ip4 = [ { address = "192.168.56.1"; prefixLength = 24; } ];
+    # Make sure NetworkManager won't assume this interface being up
+    # means we have internet access.
+    networking.networkmanager.unmanaged = ["vboxnet0"];
   })]);
 }