summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2015-10-30 15:47:37 +0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2015-10-30 15:47:37 +0100
commit81f6c62004a8ef711a8c23e8bdcf9f4bdf2c072d (patch)
tree00c48f56f3580ed330620d81e27542e8938ff4d7 /nixos
parentc232159feeb49c6b20bcacec291071eecdfecc66 (diff)
parente0596c96034978fe70d0295315fa4d584da9416c (diff)
downloadnixlib-81f6c62004a8ef711a8c23e8bdcf9f4bdf2c072d.tar
nixlib-81f6c62004a8ef711a8c23e8bdcf9f4bdf2c072d.tar.gz
nixlib-81f6c62004a8ef711a8c23e8bdcf9f4bdf2c072d.tar.bz2
nixlib-81f6c62004a8ef711a8c23e8bdcf9f4bdf2c072d.tar.lz
nixlib-81f6c62004a8ef711a8c23e8bdcf9f4bdf2c072d.tar.xz
nixlib-81f6c62004a8ef711a8c23e8bdcf9f4bdf2c072d.tar.zst
nixlib-81f6c62004a8ef711a8c23e8bdcf9f4bdf2c072d.zip
Merge remote-tracking branch 'origin/master' into systemd-219
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/installation/installing.xml4
-rw-r--r--nixos/lib/make-disk-image.nix3
-rw-r--r--nixos/modules/config/debug-info.nix46
-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.nix25
-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/module-list.nix10
-rw-r--r--nixos/modules/programs/bash/bash.nix14
-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.nix26
-rw-r--r--nixos/modules/services/databases/postgresql.nix2
-rw-r--r--nixos/modules/services/mail/opensmtpd.nix20
-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/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.nix16
-rw-r--r--nixos/modules/services/networking/supplicant.nix249
-rw-r--r--nixos/modules/services/scheduling/cron.nix2
-rw-r--r--nixos/modules/services/x11/desktop-managers/gnome3.nix1
-rw-r--r--nixos/modules/services/x11/display-managers/sddm.nix15
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix26
-rw-r--r--nixos/modules/system/boot/stage-1.nix2
-rw-r--r--nixos/modules/system/boot/systemd.nix7
-rw-r--r--nixos/modules/tasks/filesystems.nix2
-rw-r--r--nixos/modules/tasks/filesystems/nfs.nix2
-rw-r--r--nixos/modules/tasks/network-interfaces-scripted.nix14
-rw-r--r--nixos/modules/tasks/network-interfaces.nix194
-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/release-combined.nix2
-rw-r--r--nixos/tests/docker.nix2
-rw-r--r--nixos/tests/gnome3.nix2
45 files changed, 1012 insertions, 398 deletions
diff --git a/nixos/doc/manual/installation/installing.xml b/nixos/doc/manual/installation/installing.xml
index e40c15e8316d..6d734cd8caca 100644
--- a/nixos/doc/manual/installation/installing.xml
+++ b/nixos/doc/manual/installation/installing.xml
@@ -18,8 +18,8 @@
   <listitem><para>The NixOS manual is available on virtual console 8
   (press Alt+F8 to access).</para></listitem>
 
-  <listitem><para>Login as <literal>root</literal> and the empty
-  password.</para></listitem>
+  <listitem><para>You get logged in as <literal>root</literal>
+  (with empty password).</para></listitem>
 
   <listitem><para>If you downloaded the graphical ISO image, you can
   run <command>start display-manager</command> to start KDE.</para></listitem>
diff --git a/nixos/lib/make-disk-image.nix b/nixos/lib/make-disk-image.nix
index 79c5199cbec4..62728c8ac761 100644
--- a/nixos/lib/make-disk-image.nix
+++ b/nixos/lib/make-disk-image.nix
@@ -39,6 +39,7 @@ pkgs.vmTools.runInLinuxVM (
       exportReferencesGraph =
         [ "closure" config.system.build.toplevel ];
       inherit postVM;
+      memSize = 1024;
     }
     ''
       ${if partitioned then ''
@@ -109,7 +110,7 @@ pkgs.vmTools.runInLinuxVM (
       umount /mnt/proc /mnt/dev /mnt/sys
       umount /mnt
 
-      # Do an fsck to make sure resize2fs works.
+      # Do a fsck to make sure resize2fs works.
       fsck.${fsType} -f -y $rootDisk
     ''
 )
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/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 748ada99be69..e14e4cf13147 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,7 @@ in
     system.path = pkgs.buildEnv {
       name = "system-path";
       paths = config.environment.systemPackages;
-      inherit (config.environment) pathsToLink;
+      inherit (config.environment) pathsToLink outputsToLink;
       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 b2676b05a02c..e14653dc4eb0 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 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/module-list.nix b/nixos/modules/module-list.nix
index c890eac49910..77575867f873 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
@@ -264,6 +266,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 +343,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
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/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 95d2aecfac7d..7a118ac72071 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,9 +110,21 @@ 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;
 
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index bae088c6610e..06b9c3fbf4ca 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -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/mail/opensmtpd.nix b/nixos/modules/services/mail/opensmtpd.nix
index a3e50b422920..a1cfd84365a2 100644
--- a/nixos/modules/services/mail/opensmtpd.nix
+++ b/nixos/modules/services/mail/opensmtpd.nix
@@ -46,6 +46,17 @@ in {
           is left empty, the OpenSMTPD server will not start.
         '';
       };
+
+      procPackages = mkOption {
+        type = types.listOf types.path;
+        default = [];
+        description = ''
+          Packages to search for filters, tables, queues, and schedulers.
+
+          Add OpenSMTPD-extras here if you want to use the filters, etc. from
+          that package.
+        '';
+      };
     };
 
   };
@@ -72,12 +83,19 @@ in {
       };
     };
 
-    systemd.services.opensmtpd = {
+    systemd.services.opensmtpd = let
+      procEnv = pkgs.buildEnv {
+        name = "opensmtpd-procs";
+        paths = [ opensmtpd ] ++ cfg.procPackages;
+        pathsToLink = [ "/libexec/opensmtpd" ];
+      };
+    in {
       wantedBy = [ "multi-user.target" ];
       wants = [ "network.target" ];
       after = [ "network.target" ];
       preStart = "mkdir -p /var/spool";
       serviceConfig.ExecStart = "${opensmtpd}/sbin/smtpd -d -f ${conf} ${args}";
+      environment.OPENSMTPD_PROC_PATH = "${procEnv}/libexec/opensmtpd";
     };
 
     environment.systemPackages = [ (pkgs.runCommand "opensmtpd-sendmail" {} ''
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/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 adbc6099c95a..1c824b6bbfc3 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -40,7 +40,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
         ))
@@ -71,11 +70,10 @@ let
     ${coreutils}/bin/rm -f $tmp $tmp.ns
   '';
 
-  # pre-up and pre-down hooks were added in NM 0.9.10, but we still use 0.9.0
   dispatcherTypesSubdirMap = {
     "basic" = "";
-    /*"pre-up" = "pre-up.d/";
-    "pre-down" = "pre-down.d/";*/
+    "pre-up" = "pre-up.d/";
+    "pre-down" = "pre-down.d/";
   };
 
 in {
@@ -207,10 +205,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/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/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/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix
index fdee5fbc6c5b..886a6c884013 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/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix
index c44383cc6117..4594155ea134 100644
--- a/nixos/modules/services/x11/display-managers/sddm.nix
+++ b/nixos/modules/services/x11/display-managers/sddm.nix
@@ -35,6 +35,8 @@ let
     SessionCommand=${dmcfg.session.script}
     SessionDir=${dmcfg.session.desktops}
     XauthPath=${pkgs.xorg.xauth}/bin/xauth
+
+    ${cfg.extraConfig}
   '';
 
 in
@@ -50,6 +52,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";
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/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index ace2d10ec9c1..fe34e8227289 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -206,7 +206,7 @@ let
       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 ];
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index 44871a459c18..0b7647093e0f 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -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/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 7af3160e2d42..2d6522a1bf9d 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -381,8 +381,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.
         '';
@@ -398,16 +398,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 = [];
@@ -688,6 +678,110 @@ in
       };
     };
 
+    networking.wlanInterfaces = mkOption {
+      default = { };
+      example = {
+        "wlan-station0" = {
+            device = "wlp6s0";
+        };
+        "wlan-adhoc0" = {
+            type = "ibss";
+            device = "wlp6s0";
+            mac = "02:00:00:00:00:01";
+        };
+        "wlan-p2p0" = {
+            device = "wlp6s0";
+            mac = "02:00:00:00:00:02";
+        };
+        "wlan-ap0" = {
+            device = "wlp6s0";
+            mac = "02:00:00:00:00:03";
+        };
+      };
+      description =
+        ''
+          Creating multiple WLAN interfaces on top of one physical WLAN device (NIC).
+
+          The name of the WLAN interface corresponds to the name of the attribute.
+          A NIC is referenced by the persistent device name of the WLAN interface that
+          <literal>udev</literal> assigns to a NIC by default.
+          If a NIC supports multiple WLAN interfaces, then the one NIC can be used as
+          <literal>device</literal> for multiple WLAN interfaces.
+          If a NIC is used for creating WLAN interfaces, then the default WLAN interface
+          with a persistent device name form <literal>udev</literal> is not created.
+          A WLAN interface with the persistent name assigned from <literal>udev</literal>
+          would have to be created explicitly.
+        '';
+
+      type = types.attrsOf types.optionSet;
+
+      options = {
+
+        device = mkOption {
+          type = types.string;
+          example = "wlp6s0";
+          description = "The name of the underlying hardware WLAN device as assigned by <literal>udev</literal>.";
+        };
+
+        type = mkOption {
+          type = types.string;
+          default = "managed";
+          example = "ibss";
+          description = ''
+            The type of the WLAN interface. The type has to be either <literal>managed</literal>,
+            <literal>ibss</literal>, <literal>monitor</literal>, <literal>mesh</literal> or <literal>wds</literal>.
+            Also, the type has to be supported by the underlying hardware of the device.
+          '';
+        };
+
+        meshID = mkOption {
+          type = types.nullOr types.string;
+          default = null;
+          description = "MeshID of interface with type <literal>mesh</literal>.";
+        };
+
+        flags = mkOption {
+          type = types.nullOr types.string;
+          default = null;
+          example = "control";
+          description = ''
+            Flags for interface of type <literal>monitor</literal>. The valid flags are:
+            none:     no special flags
+            fcsfail:  show frames with FCS errors
+            control:  show control frames
+            otherbss: show frames from other BSSes
+            cook:     use cooked mode
+            active:   use active mode (ACK incoming unicast packets)
+          '';
+        };
+
+        fourAddr = mkOption {
+          type = types.nullOr types.bool;
+          default = null;
+          description = "Whether to enable <literal>4-address mode</literal> with type <literal>managed</literal>.";
+        };
+
+        mac = mkOption {
+          type = types.nullOr types.str;
+          default = null;
+          example = "02:00:00:00:00:01";
+          description = ''
+            MAC address to use for the device. If <literal>null</literal>, then the MAC of the
+            underlying hardware WLAN device is used.
+
+            INFO: Locally administered MAC addresses are of the form:
+            <itemizedlist>
+            <listitem><para>x2:xx:xx:xx:xx:xx</para></listitem>
+            <listitem><para>x6:xx:xx:xx:xx:xx</para></listitem>
+            <listitem><para>xA:xx:xx:xx:xx:xx</para></listitem>
+            <listitem><para>xE:xx:xx:xx:xx:xx</para></listitem>
+            </itemizedlist>
+          '';
+        };
+
+      };
+    };
+
     networking.useDHCP = mkOption {
       type = types.bool;
       default = true;
@@ -844,6 +938,82 @@ in
 
     virtualisation.vswitch = mkIf (cfg.vswitches != { }) { enable = true; };
 
+    services.udev.packages = mkIf (cfg.wlanInterfaces != {}) [
+      (pkgs.writeTextFile {
+        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/release-combined.nix b/nixos/release-combined.nix
index a3948401d786..4dc221dba68b 100644
--- a/nixos/release-combined.nix
+++ b/nixos/release-combined.nix
@@ -51,7 +51,7 @@ in rec {
         (all nixos.tests.chromium)
         (all nixos.tests.firefox)
         (all nixos.tests.firewall)
-        (all nixos.tests.gnome3)
+        nixos.tests.gnome3.x86_64-linux # FIXME: i686-linux
         (all nixos.tests.installer.lvm)
         (all nixos.tests.installer.luksroot)
         (all nixos.tests.installer.separateBoot)
diff --git a/nixos/tests/docker.nix b/nixos/tests/docker.nix
index 034dcb04adfd..635a97e2ce09 100644
--- a/nixos/tests/docker.nix
+++ b/nixos/tests/docker.nix
@@ -11,6 +11,8 @@ import ./make-test.nix ({ pkgs, ...} : {
       { config, pkgs, ... }:
         {
           virtualisation.docker.enable = true;
+          # FIXME: The default "devicemapper" storageDriver fails in NixOS VM
+          # tests.
           virtualisation.docker.storageDriver = "overlay";
         };
     };
diff --git a/nixos/tests/gnome3.nix b/nixos/tests/gnome3.nix
index 7662efe1b350..714b35503706 100644
--- a/nixos/tests/gnome3.nix
+++ b/nixos/tests/gnome3.nix
@@ -28,7 +28,7 @@ import ./make-test.nix ({ pkgs, ...} : {
 
       $machine->succeed("su - alice -c 'DISPLAY=:0.0 gnome-terminal &'");
       $machine->waitForWindow(qr/Terminal/);
-      $machine->mustSucceed("timeout 60 bash -c 'journalctl -f|grep -m 1 \"GNOME Shell started\"'");
+      $machine->mustSucceed("timeout 900 bash -c 'journalctl -f|grep -m 1 \"GNOME Shell started\"'");
       $machine->sleep(10);
       $machine->screenshot("screen");
     '';