summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorVladimír Čunát <vcunat@gmail.com>2016-02-14 08:33:51 +0100
committerVladimír Čunát <vcunat@gmail.com>2016-02-14 08:33:51 +0100
commitd039c879845ddcde6108203781e4b001c409e2c2 (patch)
tree1f9e2a99d95c8866ddbef81b4bfa6a49ce979451 /nixos
parent34922a3951a0ada7af4fe808250abaf5feb4e28e (diff)
parent6a036d9fca013265b4109ffcaf6df62efa010fa3 (diff)
downloadnixlib-d039c879845ddcde6108203781e4b001c409e2c2.tar
nixlib-d039c879845ddcde6108203781e4b001c409e2c2.tar.gz
nixlib-d039c879845ddcde6108203781e4b001c409e2c2.tar.bz2
nixlib-d039c879845ddcde6108203781e4b001c409e2c2.tar.lz
nixlib-d039c879845ddcde6108203781e4b001c409e2c2.tar.xz
nixlib-d039c879845ddcde6108203781e4b001c409e2c2.tar.zst
nixlib-d039c879845ddcde6108203781e4b001c409e2c2.zip
Merge branch 'master' into closure-size
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/configuration/config-file.xml2
-rw-r--r--nixos/doc/manual/default.nix15
-rw-r--r--nixos/doc/manual/man-nixos-generate-config.xml4
-rw-r--r--nixos/doc/manual/release-notes/rl-unstable.xml16
-rw-r--r--nixos/modules/config/zram.nix6
-rw-r--r--nixos/modules/hardware/video/webcam/facetimehd.nix45
-rw-r--r--nixos/modules/installer/cd-dvd/iso-image.nix8
-rw-r--r--nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix3
-rw-r--r--nixos/modules/installer/cd-dvd/system-tarball.nix2
-rw-r--r--nixos/modules/installer/tools/nixos-generate-config.pl4
-rw-r--r--nixos/modules/installer/tools/nixos-install.sh5
-rw-r--r--nixos/modules/installer/tools/nixos-rebuild.sh7
-rw-r--r--nixos/modules/module-list.nix9
-rw-r--r--nixos/modules/programs/ssh.nix3
-rw-r--r--nixos/modules/security/acme.nix4
-rw-r--r--nixos/modules/services/databases/postgresql.nix38
-rw-r--r--nixos/modules/services/hardware/acpid.nix174
-rw-r--r--nixos/modules/services/hardware/bluetooth.nix60
-rw-r--r--nixos/modules/services/hardware/udev.nix87
-rw-r--r--nixos/modules/services/logging/logstash.nix6
-rw-r--r--nixos/modules/services/mail/dovecot.nix1
-rw-r--r--nixos/modules/services/mail/dspam.nix5
-rw-r--r--nixos/modules/services/mail/opensmtpd.nix21
-rw-r--r--nixos/modules/services/mail/postfix.nix32
-rw-r--r--nixos/modules/services/mail/postsrsd.nix6
-rw-r--r--nixos/modules/services/misc/gitit.nix1
-rw-r--r--nixos/modules/services/misc/sundtek.nix2
-rw-r--r--nixos/modules/services/networking/connman.nix6
-rw-r--r--nixos/modules/services/networking/i2pd.nix300
-rw-r--r--nixos/modules/services/networking/ssh/sshd.nix13
-rw-r--r--nixos/modules/services/networking/tinc.nix12
-rw-r--r--nixos/modules/services/networking/unifi.nix2
-rw-r--r--nixos/modules/services/networking/wpa_supplicant.nix28
-rw-r--r--nixos/modules/services/search/elasticsearch.nix13
-rw-r--r--nixos/modules/services/search/kibana.nix65
-rw-r--r--nixos/modules/services/security/haka.nix156
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/mediawiki.nix4
-rw-r--r--nixos/modules/services/x11/desktop-managers/default.nix8
-rw-r--r--nixos/modules/services/x11/desktop-managers/gnome3.nix2
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde4.nix6
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde5.nix10
-rw-r--r--nixos/modules/services/x11/display-managers/default.nix3
-rw-r--r--nixos/modules/services/x11/display-managers/lightdm.nix2
-rw-r--r--nixos/modules/services/x11/hardware/synaptics.nix29
-rw-r--r--nixos/modules/services/x11/window-managers/i3.nix2
-rw-r--r--nixos/modules/system/activation/switch-to-configuration.pl2
-rw-r--r--nixos/modules/system/boot/initrd-network.nix178
-rw-r--r--nixos/modules/system/boot/initrd-ssh.nix124
-rw-r--r--nixos/modules/system/boot/kernel.nix3
-rw-r--r--nixos/modules/system/boot/loader/init-script/init-script-builder.sh9
-rw-r--r--nixos/modules/system/boot/stage-1-init.sh4
-rw-r--r--nixos/modules/system/boot/stage-1.nix20
-rw-r--r--nixos/modules/tasks/filesystems.nix18
-rw-r--r--nixos/modules/tasks/kbd.nix51
-rw-r--r--nixos/modules/tasks/network-interfaces-scripted.nix7
-rw-r--r--nixos/modules/tasks/network-interfaces.nix2
-rw-r--r--nixos/modules/virtualisation/amazon-image.nix29
-rw-r--r--nixos/modules/virtualisation/amazon-init.nix23
-rw-r--r--nixos/modules/virtualisation/azure-agent.nix9
-rw-r--r--nixos/modules/virtualisation/ec2-data.nix38
-rw-r--r--nixos/modules/virtualisation/qemu-vm.nix13
-rw-r--r--nixos/release.nix1
-rw-r--r--nixos/tests/chromium.nix4
-rw-r--r--nixos/tests/ec2.nix12
-rw-r--r--nixos/tests/haka.nix24
-rw-r--r--nixos/tests/initrd-network.nix22
-rw-r--r--nixos/tests/misc.nix2
-rw-r--r--nixos/tests/nfs.nix2
-rw-r--r--nixos/tests/simple.nix4
69 files changed, 1123 insertions, 705 deletions
diff --git a/nixos/doc/manual/configuration/config-file.xml b/nixos/doc/manual/configuration/config-file.xml
index b613c7f06cc8..9b240979273d 100644
--- a/nixos/doc/manual/configuration/config-file.xml
+++ b/nixos/doc/manual/configuration/config-file.xml
@@ -157,7 +157,7 @@ boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 60;
 fileSystems."/boot" =
   { device = "/dev/sda1";
     fsType = "ext4";
-    options = "rw,data=ordered,relatime";
+    options = [ "rw" "data=ordered" "relatime" ];
   };
 </programlisting>
       </para>
diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix
index c1f21a2f5da6..0f0809478339 100644
--- a/nixos/doc/manual/default.nix
+++ b/nixos/doc/manual/default.nix
@@ -17,7 +17,7 @@ let
 
   # Clean up declaration sites to not refer to the NixOS source tree.
   optionsList' = flip map optionsList (opt: opt // {
-    declarations = map (fn: stripAnyPrefixes fn) opt.declarations;
+    declarations = map stripAnyPrefixes opt.declarations;
   }
   // optionalAttrs (opt ? example) { example = substFunction opt.example; }
   // optionalAttrs (opt ? default) { default = substFunction opt.default; }
@@ -28,16 +28,9 @@ let
   # or else the build will fail.
   #
   # E.g. if some `options` came from modules in ${pkgs.customModules}/nix,
-  # you'd need to include `extraSources = [ "#{pkgs.customModules}" ]`
-  herePrefix = toString ../../..;
-  prefixesToStrip = [ herePrefix ] ++ extraSources;
-
-  stripAnyPrefixes = fn:
-    flip (flip fold fn) prefixesToStrip (fn: prefix:
-      if substring 0 (stringLength prefix) fn == prefix then
-        substring (stringLength prefix + 1) 1000 fn
-      else
-        fn);
+  # you'd need to include `extraSources = [ pkgs.customModules ]`
+  prefixesToStrip = map (p: "${toString p}/") ([ ../../.. ] ++ extraSources);
+  stripAnyPrefixes = flip (fold removePrefix) prefixesToStrip;
 
   # Convert the list of options into an XML file.
   optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList');
diff --git a/nixos/doc/manual/man-nixos-generate-config.xml b/nixos/doc/manual/man-nixos-generate-config.xml
index e4fba4a40a97..140642bc9c9c 100644
--- a/nixos/doc/manual/man-nixos-generate-config.xml
+++ b/nixos/doc/manual/man-nixos-generate-config.xml
@@ -165,13 +165,13 @@ look like this:
   fileSystems."/" =
     { device = "/dev/disk/by-label/nixos";
       fsType = "ext3";
-      options = "rw,data=ordered,relatime";
+      options = [ "rw" "data=ordered" "relatime" ];
     };
 
   fileSystems."/boot" =
     { device = "/dev/sda1";
       fsType = "ext3";
-      options = "rw,errors=continue,user_xattr,acl,barrier=1,data=writeback,relatime";
+      options = [ "rw" "errors=continue" "user_xattr" "acl" "barrier=1" "data=writeback" "relatime" ];
     };
 
   swapDevices =
diff --git a/nixos/doc/manual/release-notes/rl-unstable.xml b/nixos/doc/manual/release-notes/rl-unstable.xml
index ffde542d4e18..768b51d84a46 100644
--- a/nixos/doc/manual/release-notes/rl-unstable.xml
+++ b/nixos/doc/manual/release-notes/rl-unstable.xml
@@ -42,6 +42,7 @@ nixos.path = ./nixpkgs-unstable-2015-12-06/nixos;
   <itemizedlist>
     <listitem><para><literal>services/monitoring/longview.nix</literal></para></listitem>
     <listitem><para><literal>services/web-apps/pump.io.nix</literal></para></listitem>
+    <listitem><para><literal>services/security/haka.nix</literal></para></listitem>
   </itemizedlist>
 </para>
 
@@ -156,6 +157,21 @@ nginx.override {
   </listitem>
 
   <listitem>
+    <para>Filesystem options should now be configured as a list of strings, not
+    a comma-separated string. The old style will continue to work, but print a
+    warning, until the 16.09 release. An example of the new style:
+
+<programlisting>
+fileSystems."/example" = {
+  device = "/dev/sdc";
+  fsType = "btrfs";
+  options = [ "noatime" "compress=lzo" "space_cache" "autodefrag" ];
+};
+</programlisting>
+    </para>
+  </listitem>
+
+  <listitem>
     <para>CUPS, installed by <literal>services.printing</literal> module, now
     has its data directory in <filename>/var/lib/cups</filename>. Old
     configurations from <filename>/etc/cups</filename> are moved there
diff --git a/nixos/modules/config/zram.nix b/nixos/modules/config/zram.nix
index 22b74847f871..019932b04e8d 100644
--- a/nixos/modules/config/zram.nix
+++ b/nixos/modules/config/zram.nix
@@ -98,11 +98,9 @@ in
             script = ''
               set -u
               set -o pipefail
-
-              PATH=${pkgs.procps}/bin:${pkgs.gnugrep}/bin:${pkgs.gnused}/bin
-
+              
               # Calculate memory to use for zram
-              totalmem=$(free | grep -e "^Mem:" | sed -e 's/^Mem: *//' -e 's/  *.*//')
+              totalmem=$(${pkgs.gnugrep}/bin/grep 'MemTotal: ' /proc/meminfo | ${pkgs.gawk}/bin/awk '{print $2}')
               mem=$(((totalmem * ${toString cfg.memoryPercent} / 100 / ${toString cfg.numDevices}) * 1024))
 
               echo $mem > /sys/class/block/${dev}/disksize
diff --git a/nixos/modules/hardware/video/webcam/facetimehd.nix b/nixos/modules/hardware/video/webcam/facetimehd.nix
new file mode 100644
index 000000000000..b35709763b90
--- /dev/null
+++ b/nixos/modules/hardware/video/webcam/facetimehd.nix
@@ -0,0 +1,45 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.hardware.facetimehd;
+
+  kernelPackages = config.boot.kernelPackages;
+
+in
+
+{
+
+  options.hardware.facetimehd.enable = mkEnableOption "facetimehd kernel module";
+
+  config = mkIf cfg.enable {
+
+    assertions = singleton {
+      assertion = versionAtLeast kernelPackages.kernel.version "3.19";
+      message = "facetimehd is not supported for kernels older than 3.19";
+    };
+
+    boot.kernelModules = [ "facetimehd" ];
+
+    boot.blacklistedKernelModules = [ "bdc_pci" ];
+
+    boot.extraModulePackages = [ kernelPackages.facetimehd ];
+
+    hardware.firmware = [ pkgs.facetimehd-firmware ];
+
+    # unload module during suspend/hibernate as it crashes the whole system
+    powerManagement.powerDownCommands = ''
+      ${pkgs.module_init_tools}/bin/rmmod -f facetimehd
+    '';
+
+    # and load it back on resume
+    powerManagement.resumeCommands = ''
+      export MODULE_DIR=/run/current-system/kernel-modules/lib/modules
+      ${pkgs.module_init_tools}/bin/modprobe -v facetimehd
+    '';
+
+  };
+
+}
diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix
index 248b0f00283c..5702e2d9a1e5 100644
--- a/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -249,7 +249,7 @@ in
 
     fileSystems."/" =
       { fsType = "tmpfs";
-        options = "mode=0755";
+        options = [ "mode=0755" ];
       };
 
     # Note that /dev/root is a symlink to the actual root device
@@ -266,20 +266,20 @@ in
     fileSystems."/nix/.ro-store" =
       { fsType = "squashfs";
         device = "/iso/nix-store.squashfs";
-        options = "loop";
+        options = [ "loop" ];
         neededForBoot = true;
       };
 
     fileSystems."/nix/.rw-store" =
       { fsType = "tmpfs";
-        options = "mode=0755";
+        options = [ "mode=0755" ];
         neededForBoot = true;
       };
 
     fileSystems."/nix/store" =
       { fsType = "unionfs-fuse";
         device = "unionfs";
-        options = "allow_other,cow,nonempty,chroot=/mnt-root,max_files=32768,hide_meta_files,dirs=/nix/.rw-store=rw:/nix/.ro-store=ro";
+        options = [ "allow_other" "cow" "nonempty" "chroot=/mnt-root" "max_files=32768" "hide_meta_files" "dirs=/nix/.rw-store=rw:/nix/.ro-store=ro" ];
       };
 
     boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "usb-storage" ];
diff --git a/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix
index de0cc604bf3b..7badfcb8df22 100644
--- a/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix
+++ b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix
@@ -86,8 +86,7 @@ in
   system.boot.loader.kernelFile = "uImage";
 
   boot.initrd.availableKernelModules =
-    [ "mvsdio" "mmc_block" "reiserfs" "ext3" "ums-cypress" "rtc_mv"
-      "ext4" ];
+    [ "mvsdio" "reiserfs" "ext3" "ums-cypress" "rtc_mv" "ext4" ];
 
   boot.postBootCommands =
     ''
diff --git a/nixos/modules/installer/cd-dvd/system-tarball.nix b/nixos/modules/installer/cd-dvd/system-tarball.nix
index c24fe97fba46..90e9b98a4575 100644
--- a/nixos/modules/installer/cd-dvd/system-tarball.nix
+++ b/nixos/modules/installer/cd-dvd/system-tarball.nix
@@ -43,7 +43,7 @@ in
     # so that we don't need to know its device.
     fileSystems = [ ];
 
-    # boot.initrd.availableKernelModules = [ "mvsdio" "mmc_block" "reiserfs" "ext3" "ext4" ];
+    # boot.initrd.availableKernelModules = [ "mvsdio" "reiserfs" "ext3" "ext4" ];
 
     # boot.initrd.kernelModules = [ "rtc_mv" ];
 
diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl
index 2284eba07a2d..ec880e084726 100644
--- a/nixos/modules/installer/tools/nixos-generate-config.pl
+++ b/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -349,7 +349,7 @@ foreach my $fs (read_file("/proc/self/mountinfo")) {
   fileSystems.\"$mountPoint\" =
     { device = \"$base$path\";
       fsType = \"none\";
-      options = \"bind\";
+      options = \[ \"bind\" \];
     };
 
 EOF
@@ -409,7 +409,7 @@ EOF
 
     if (scalar @extraOptions > 0) {
       $fileSystems .= <<EOF;
-      options = \"${\join ",", uniq(@extraOptions)}\";
+      options = \[ ${\join " ", map { "\"" . $_ . "\"" } uniq(@extraOptions)} \];
 EOF
     }
 
diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh
index 4e10615f902f..c23d7e5b509d 100644
--- a/nixos/modules/installer/tools/nixos-install.sh
+++ b/nixos/modules/installer/tools/nixos-install.sh
@@ -73,11 +73,6 @@ if ! test -e "$mountPoint"; then
     exit 1
 fi
 
-if ! grep -F -q " $mountPoint " /proc/mounts; then
-    echo "$mountPoint doesn't appear to be a mount point"
-    exit 1
-fi
-
 
 # Mount some stuff in the target root directory.
 mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/etc $mountPoint/run $mountPoint/home
diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh
index 105d1cd16252..e0e79f63fab7 100644
--- a/nixos/modules/installer/tools/nixos-rebuild.sh
+++ b/nixos/modules/installer/tools/nixos-rebuild.sh
@@ -149,10 +149,11 @@ nixBuild() {
                 local j="$1"; shift 1
                 instArgs+=("$i" "$j")
                 ;;
-              -I)
-                # We don't want this in buildArgs
+              -I) # We don't want this in buildArgs
                 shift 1
                 ;;
+              --no-out-link) # We don't want this in buildArgs
+                ;;
               "<"*) # nix paths
                 instArgs+=("$i")
                 ;;
@@ -329,7 +330,7 @@ fi
 if [ -z "$rollback" ]; then
     echo "building the system configuration..." >&2
     if [ "$action" = switch -o "$action" = boot ]; then
-        pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A system "${extraBuildFlags[@]}")"
+        pathToConfig="$(nixBuild '<nixpkgs/nixos>' --no-out-link -A system "${extraBuildFlags[@]}")"
         copyToTarget "$pathToConfig"
         targetHostCmd nix-env -p "$profile" --set "$pathToConfig"
     elif [ "$action" = test -o "$action" = build -o "$action" = dry-build -o "$action" = dry-activate ]; then
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 2ff61877c23d..0011544988d6 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -42,6 +42,7 @@
   ./hardware/video/bumblebee.nix
   ./hardware/video/nvidia.nix
   ./hardware/video/ati.nix
+  ./hardware/video/webcam/facetimehd.nix
   ./installer/tools/auto-upgrade.nix
   ./installer/tools/nixos-checkout.nix
   ./installer/tools/tools.nix
@@ -395,6 +396,7 @@
   ./services/security/fprintd.nix
   ./services/security/fprot.nix
   ./services/security/frandom.nix
+  ./services/security/haka.nix
   ./services/security/haveged.nix
   ./services/security/hologram.nix
   ./services/security/munge.nix
@@ -460,10 +462,10 @@
   ./system/boot/coredump.nix
   ./system/boot/emergency-mode.nix
   ./system/boot/initrd-network.nix
+  ./system/boot/initrd-ssh.nix
   ./system/boot/kernel.nix
   ./system/boot/kexec.nix
   ./system/boot/loader/efi.nix
-  ./system/boot/loader/loader.nix
   ./system/boot/loader/generations-dir/generations-dir.nix
   ./system/boot/loader/generic-extlinux-compatible
   ./system/boot/loader/grub/grub.nix
@@ -471,15 +473,16 @@
   ./system/boot/loader/grub/memtest.nix
   ./system/boot/loader/gummiboot/gummiboot.nix
   ./system/boot/loader/init-script/init-script.nix
+  ./system/boot/loader/loader.nix
   ./system/boot/loader/raspberrypi/raspberrypi.nix
   ./system/boot/luksroot.nix
   ./system/boot/modprobe.nix
+  ./system/boot/networkd.nix
+  ./system/boot/resolved.nix
   ./system/boot/shutdown.nix
   ./system/boot/stage-1.nix
   ./system/boot/stage-2.nix
   ./system/boot/systemd.nix
-  ./system/boot/networkd.nix
-  ./system/boot/resolved.nix
   ./system/boot/timesyncd.nix
   ./system/boot/tmp.nix
   ./system/etc/etc.nix
diff --git a/nixos/modules/programs/ssh.nix b/nixos/modules/programs/ssh.nix
index 2da8ff738fbc..169c6a38e75b 100644
--- a/nixos/modules/programs/ssh.nix
+++ b/nixos/modules/programs/ssh.nix
@@ -186,6 +186,9 @@ in
 
         ForwardX11 ${if cfg.forwardX11 then "yes" else "no"}
 
+        # Allow DSA keys for now. (These were deprecated in OpenSSH 7.0.)
+        PubkeyAcceptedKeyTypes +ssh-dss
+
         ${cfg.extraConfig}
       '';
 
diff --git a/nixos/modules/security/acme.nix b/nixos/modules/security/acme.nix
index 15e5b49878f6..3d25e811e670 100644
--- a/nixos/modules/security/acme.nix
+++ b/nixos/modules/security/acme.nix
@@ -56,8 +56,8 @@ let
 
       plugins = mkOption {
         type = types.listOf (types.enum [
-          "cert.der" "cert.pem" "chain.der" "chain.pem" "external_pem.sh"
-          "fullchain.der" "fullchain.pem" "key.der" "key.pem" "account_key.json"
+          "cert.der" "cert.pem" "chain.pem" "external_pem.sh"
+          "fullchain.pem" "full.pem" "key.der" "key.pem" "account_key.json"
         ]);
         default = [ "fullchain.pem" "key.pem" "account_key.json" ];
         description = ''
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index c2045a5859c5..31ffe51c11ef 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -158,7 +158,7 @@ in
       # Note: when changing the default, make it conditional on
       # ‘system.stateVersion’ to maintain compatibility with existing
       # systems!
-      mkDefault pkgs.postgresql94;
+      mkDefault (if versionAtLeast config.system.stateVersion "16.03" then pkgs.postgresql95 else pkgs.postgresql94);
 
     services.postgresql.authentication = mkAfter
       ''
@@ -177,7 +177,7 @@ in
 
     users.extraGroups.postgres.gid = config.ids.gids.postgres;
 
-    environment.systemPackages = [postgresql];
+    environment.systemPackages = [ postgresql ];
 
     systemd.services.postgresql =
       { description = "PostgreSQL Server";
@@ -187,35 +187,37 @@ in
 
         environment.PGDATA = cfg.dataDir;
 
-        path = [ pkgs.su postgresql ];
+        path = [ postgresql ];
 
         preStart =
           ''
-            # Initialise the database.
+            # Create data directory.
             if ! test -e ${cfg.dataDir}/PG_VERSION; then
-                mkdir -m 0700 -p ${cfg.dataDir}
-                rm -f ${cfg.dataDir}/*.conf
-                if [ "$(id -u)" = 0 ]; then
-                  chown -R postgres ${cfg.dataDir}
-                  su -s ${pkgs.stdenv.shell} postgres -c 'initdb -U root'
-                else
-                  # For non-root operation.
-                  initdb
-                fi
-                # See postStart!
-                touch "${cfg.dataDir}/.first_startup"
+              mkdir -m 0700 -p ${cfg.dataDir}
+              rm -f ${cfg.dataDir}/*.conf
+              chown -R postgres:postgres ${cfg.dataDir}
             fi
+          ''; # */
 
+        script =
+          ''
+            # Initialise the database.
+            if ! test -e ${cfg.dataDir}/PG_VERSION; then
+              initdb -U root
+              # See postStart!
+              touch "${cfg.dataDir}/.first_startup"
+            fi
             ln -sfn "${configFile}" "${cfg.dataDir}/postgresql.conf"
             ${optionalString (cfg.recoveryConfig != null) ''
               ln -sfn "${pkgs.writeText "recovery.conf" cfg.recoveryConfig}" \
                 "${cfg.dataDir}/recovery.conf"
             ''}
-          ''; # */
+
+             exec postgres ${toString flags}
+          '';
 
         serviceConfig =
-          { ExecStart = "@${postgresql}/bin/postgres postgres ${toString flags}";
-            ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+          { ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
             User = "postgres";
             Group = "postgres";
             PermissionsStartOnly = true;
diff --git a/nixos/modules/services/hardware/acpid.nix b/nixos/modules/services/hardware/acpid.nix
index 48b2b6be09ed..bb17c8859d84 100644
--- a/nixos/modules/services/hardware/acpid.nix
+++ b/nixos/modules/services/hardware/acpid.nix
@@ -4,111 +4,38 @@ with lib;
 
 let
 
-  acpiConfDir = pkgs.runCommand "acpi-events" {}
-    ''
-      mkdir -p $out
-      ${
-        # Generate a configuration file for each event. (You can't have
-        # multiple events in one config file...)
-        let f = event:
-          ''
-            fn=$out/${event.name}
-            echo "event=${event.event}" > $fn
-            echo "action=${pkgs.writeScript "${event.name}.sh" event.action}" >> $fn
-          '';
-        in lib.concatMapStrings f events
-      }
-    '';
-
-  events = [powerEvent lidEvent acEvent muteEvent volumeDownEvent volumeUpEvent cdPlayEvent cdNextEvent cdPrevEvent];
-
-  # Called when the power button is pressed.
-  powerEvent =
-    { name = "power-button";
+  canonicalHandlers = {
+    powerEvent = {
       event = "button/power.*";
-      action =
-        ''
-          #! ${pkgs.bash}/bin/sh
-          ${config.services.acpid.powerEventCommands}
-        '';
+      action = config.services.acpid.powerEventCommands;
     };
 
-  # Called when the laptop lid is opened/closed.
-  lidEvent =
-    { name = "lid";
+    lidEvent = {
       event = "button/lid.*";
-      action =
-        ''
-          #! ${pkgs.bash}/bin/sh
-          ${config.services.acpid.lidEventCommands}
-        '';
+      action = config.services.acpid.lidEventCommands;
     };
 
-  # Called when the AC power is connected or disconnected.
-  acEvent =
-    { name = "ac-power";
+    acEvent = {
       event = "ac_adapter.*";
-      action =
-        ''
-          #! ${pkgs.bash}/bin/sh
-          ${config.services.acpid.acEventCommands}
-        '';
+      action = config.services.acpid.acEventCommands;
     };
-
-  muteEvent = {
-    name = "mute";
-    event = "button/mute.*";
-    action = ''
-      #! ${pkgs.bash}/bin/sh
-      ${config.services.acpid.muteCommands}
-    '';
-  };
-
-  volumeDownEvent = {
-    name = "volume-down";
-    event = "button/volumedown.*";
-    action = ''
-      #! ${pkgs.bash}/bin/sh
-      ${config.services.acpid.volumeDownEventCommands}
-    '';
   };
 
-  volumeUpEvent = {
-    name = "volume-up";
-    event = "button/volumeup.*";
-    action = ''
-      #! ${pkgs.bash}/bin/sh
-      ${config.services.acpid.volumeUpEventCommands}
-    '';
-  };
-
-  cdPlayEvent = {
-    name = "cd-play";
-    event = "cd/play.*";
-    action = ''
-      #! ${pkgs.bash}/bin/sh
-      ${config.services.acpid.cdPlayEventCommands}
-    '';
-  };
-
-  cdNextEvent = {
-    name = "cd-next";
-    event = "cd/next.*";
-    action = ''
-      #! ${pkgs.bash}/bin/sh
-      ${config.services.acpid.cdNextEventCommands}
-    '';
-  };
-
-  cdPrevEvent = {
-    name = "cd-prev";
-    event = "cd/prev.*";
-    action = ''
-      #! ${pkgs.bash}/bin/sh
-      ${config.services.acpid.cdPrevEventCommands}
+  acpiConfDir = pkgs.runCommand "acpi-events" {}
+    ''
+      mkdir -p $out
+      ${
+        # Generate a configuration file for each event. (You can't have
+        # multiple events in one config file...)
+        let f = name: handler:
+          ''
+            fn=$out/${name}
+            echo "event=${handler.event}" > $fn
+            echo "action=${pkgs.writeScript "${name}.sh" (concatStringsSep "\n" [ "#! ${pkgs.bash}/bin/sh" handler.action ])}" >> $fn
+          '';
+        in concatStringsSep "\n" (mapAttrsToList f (canonicalHandlers // config.services.acpid.handlers))
+      }
     '';
-  };
-
 
 in
 
@@ -126,58 +53,45 @@ in
         description = "Whether to enable the ACPI daemon.";
       };
 
-      powerEventCommands = mkOption {
-        type = types.lines;
-        default = "";
-        description = "Shell commands to execute on a button/power.* event.";
-      };
+      handlers = mkOption {
+        type = types.attrsOf (types.submodule {
+          options = {
+            event = mkOption {
+              type = types.str;
+              example = [ "button/power.*" "button/lid.*" "ac_adapter.*" "button/mute.*" "button/volumedown.*" "cd/play.*" "cd/next.*" ];
+              description = "Event type.";
+            };
 
-      lidEventCommands = mkOption {
-        type = types.lines;
-        default = "";
-        description = "Shell commands to execute on a button/lid.* event.";
-      };
+            action = mkOption {
+              type = types.lines;
+              description = "Shell commands to execute when the event is triggered.";
+            };
+          };
+        });
 
-      acEventCommands = mkOption {
-        type = types.lines;
-        default = "";
-        description = "Shell commands to execute on an ac_adapter.* event.";
-      };
-
-      muteCommands = mkOption {
-        type = types.lines;
-        default = "";
-        description = "Shell commands to execute on an button/mute.* event.";
-      };
+        description = "Event handlers.";
+        default = {};
+        example = { mute = { event = "button/mute.*"; action = "amixer set Master toggle"; }; };
 
-      volumeDownEventCommands = mkOption {
-        type = types.lines;
-        default = "";
-        description = "Shell commands to execute on an button/volumedown.* event.";
-      };
 
-      volumeUpEventCommands = mkOption {
-        type = types.lines;
-        default = "";
-        description = "Shell commands to execute on an button/volumeup.* event.";
       };
 
-      cdPlayEventCommands = mkOption {
+      powerEventCommands = mkOption {
         type = types.lines;
         default = "";
-        description = "Shell commands to execute on an cd/play.* event.";
+        description = "Shell commands to execute on a button/power.* event.";
       };
 
-      cdNextEventCommands = mkOption {
+      lidEventCommands = mkOption {
         type = types.lines;
         default = "";
-        description = "Shell commands to execute on an cd/next.* event.";
+        description = "Shell commands to execute on a button/lid.* event.";
       };
 
-      cdPrevEventCommands = mkOption {
+      acEventCommands = mkOption {
         type = types.lines;
         default = "";
-        description = "Shell commands to execute on an cd/prev.* event.";
+        description = "Shell commands to execute on an ac_adapter.* event.";
       };
 
     };
diff --git a/nixos/modules/services/hardware/bluetooth.nix b/nixos/modules/services/hardware/bluetooth.nix
index 68d0406e63bd..fc95c4910bf7 100644
--- a/nixos/modules/services/hardware/bluetooth.nix
+++ b/nixos/modules/services/hardware/bluetooth.nix
@@ -1,6 +1,43 @@
 { config, lib, pkgs, ... }:
 
 with lib;
+let
+    bluez-bluetooth = if config.services.xserver.desktopManager.kde4.enable then pkgs.bluez else pkgs.bluez5;
+
+    configBluez = {
+        description = "Bluetooth Service";
+        serviceConfig = {
+          Type = "dbus";
+          BusName = "org.bluez";
+          ExecStart = "${bluez-bluetooth}/sbin/bluetoothd -n";
+        };
+        wantedBy = [ "bluetooth.target" ];
+    };
+
+    configBluez5 =  {
+        description = "Bluetooth Service";
+        serviceConfig = {
+          Type = "dbus";
+          BusName = "org.bluez";
+          ExecStart = "${bluez-bluetooth}/sbin/bluetoothd -n";
+          NotifyAccess="main";
+          CapabilityBoundingSet="CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
+          LimitNPROC=1;
+        };
+        wantedBy = [ "bluetooth.target" ];
+    };
+
+    obexConfig = {
+        description = "Bluetooth OBEX service";
+        serviceConfig = {
+          Type = "dbus";
+          BusName = "org.bluez.obex";
+          ExecStart = "${bluez-bluetooth}/sbin/obexd";
+        };
+    };
+
+    bluezConfig = if config.services.xserver.desktopManager.kde4.enable then configBluez else configBluez5;
+in
 
 {
 
@@ -16,26 +53,15 @@ with lib;
 
   };
 
-
   ###### implementation
-
+  
   config = mkIf config.hardware.bluetooth.enable {
 
-    environment.systemPackages = [ pkgs.bluez pkgs.openobex pkgs.obexftp ];
-
-    services.udev.packages = [ pkgs.bluez ];
-
-    services.dbus.packages = [ pkgs.bluez ];
-
-    systemd.services."dbus-org.bluez" = {
-      description = "Bluetooth Service";
-      serviceConfig = {
-        Type = "dbus";
-        BusName = "org.bluez";
-        ExecStart = "${pkgs.bluez}/sbin/bluetoothd -n";
-      };
-      wantedBy = [ "bluetooth.target" ];
-    };
+    environment.systemPackages = [ bluez-bluetooth pkgs.openobex pkgs.obexftp ];
+    services.udev.packages = [ bluez-bluetooth ];
+    services.dbus.packages = [ bluez-bluetooth ];
+    systemd.services."dbus-org.bluez" = bluezConfig;
+    systemd.services."dbus-org.bluez.obex" = obexConfig;
 
   };
 
diff --git a/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix
index 107e1012b88d..369a50bd6a85 100644
--- a/nixos/modules/services/hardware/udev.nix
+++ b/nixos/modules/services/hardware/udev.nix
@@ -16,6 +16,12 @@ let
     destination = "/etc/udev/rules.d/10-local.rules";
   };
 
+  extraHwdbFile = pkgs.writeTextFile {
+    name = "extra-hwdb-file";
+    text = cfg.extraHwdb;
+    destination = "/etc/udev/hwdb.d/10-local.hwdb";
+  };
+
   nixosRules = ''
     # Miscellaneous devices.
     KERNEL=="kvm",                  MODE="0666"
@@ -55,7 +61,9 @@ let
           --replace \"/sbin/modprobe \"${config.system.sbin.modprobe}/sbin/modprobe \
           --replace \"/sbin/mdadm \"${pkgs.mdadm}/sbin/mdadm \
           --replace \"/sbin/blkid \"${pkgs.utillinux}/sbin/blkid \
-          --replace \"/bin/mount \"${pkgs.utillinux}/bin/mount
+          --replace \"/bin/mount \"${pkgs.utillinux}/bin/mount \
+          --replace /usr/bin/readlink ${pkgs.coreutils}/bin/readlink \
+          --replace /usr/bin/basename ${pkgs.coreutils}/bin/basename
       done
 
       echo -n "Checking that all programs called by relative paths in udev rules exist in ${udev}/lib/udev... "
@@ -86,10 +94,30 @@ let
       done
       echo "OK"
 
-      echo "Consider fixing the following udev rules:"
-      for i in ${toString cfg.packages}; do
-        grep -l '\(RUN+\|IMPORT{program}\)="\(/usr\)\?/s\?bin' $i/*/udev/rules.d/* || true
-      done
+      filesToFixup="$(for i in "$out"/*; do
+        grep -l '\B\(/usr\)\?/s\?bin' "$i" || :
+      done)"
+
+      if [ -n "$filesToFixup" ]; then
+        echo "Consider fixing the following udev rules:"
+        echo "$filesToFixup" | while read localFile; do
+          remoteFile="origin unknown"
+          for i in ${toString cfg.packages}; do
+            for j in "$i"/*/udev/rules.d/*; do
+              [ -e "$out/$(basename "$j")" ] || continue
+              [ "$(basename "$j")" = "$(basename "$localFile")" ] || continue
+              remoteFile="originally from $j"
+              break 2
+            done
+          done
+          refs="$(
+            grep -o '\B\(/usr\)\?/s\?bin/[^ "]\+' "$localFile" \
+              | sed -e ':r;N;''${s/\n/ and /;br};s/\n/, /g;br'
+          )"
+          echo "$localFile ($remoteFile) contains references to $refs."
+        done
+        exit 1
+      fi
 
       ${optionalString config.networking.usePredictableInterfaceNames ''
         cp ${./80-net-setup-link.rules} $out/80-net-setup-link.rules
@@ -104,6 +132,27 @@ let
     ''; # */
   };
 
+  hwdbBin = stdenv.mkDerivation {
+    name = "hwdb.bin";
+
+    preferLocalBuild = true;
+    allowSubstitutes = false;
+
+    buildCommand = ''
+      mkdir -p etc/udev/hwdb.d
+      for i in ${toString ([udev] ++ cfg.packages)}; do
+        echo "Adding hwdb files for package $i"
+        for j in $i/{etc,lib}/udev/hwdb.d/*; do
+          ln -s $j etc/udev/hwdb.d/$(basename $j)
+        done
+      done
+
+      echo "Generating hwdb database..."
+      ${udev}/bin/udevadm hwdb --update --root=$(pwd)
+      mv etc/udev/hwdb.bin $out
+    '';
+  };
+
   # Udev has a 512-character limit for ENV{PATH}, so create a symlink
   # tree to work around this.
   udevPath = pkgs.buildEnv {
@@ -168,6 +217,21 @@ in
         '';
       };
 
+      extraHwdb = mkOption {
+        default = "";
+        example = ''
+          evdev:input:b0003v05AFp8277*
+            KEYBOARD_KEY_70039=leftalt
+            KEYBOARD_KEY_700e2=leftctrl
+        '';
+        type = types.lines;
+        description = ''
+          Additional <command>hwdb</command> files. They'll be written
+          into file <filename>10-local.hwdb</filename>. Thus they are
+          read before all other files.
+        '';
+      };
+
     };
 
     hardware.firmware = mkOption {
@@ -216,7 +280,7 @@ in
 
     services.udev.extraRules = nixosRules;
 
-    services.udev.packages = [ extraUdevRules ];
+    services.udev.packages = [ extraUdevRules extraHwdbFile ];
 
     services.udev.path = [ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.utillinux udev ];
 
@@ -224,6 +288,9 @@ in
       [ { source = udevRules;
           target = "udev/rules.d";
         }
+        { source = hwdbBin;
+          target = "udev/hwdb.bin";
+        }
       ];
 
     system.requiredKernelConfig = with config.lib.kernelConfig; [
@@ -241,13 +308,6 @@ in
           echo "" > /proc/sys/kernel/hotplug
         fi
 
-        # Regenerate the hardware database /var/lib/udev/hwdb.bin
-        # whenever systemd changes.
-        if [ ! -e /var/lib/udev/prev-systemd -o "$(readlink /var/lib/udev/prev-systemd)" != ${config.systemd.package} ]; then
-          echo "regenerating udev hardware database..."
-          ${config.systemd.package}/bin/udevadm hwdb --update && ln -sfn ${config.systemd.package} /var/lib/udev/prev-systemd
-        fi
-
         # Allow the kernel to find our firmware.
         if [ -e /sys/module/firmware_class/parameters/path ]; then
           echo -n "${config.hardware.firmware}/lib/firmware" > /sys/module/firmware_class/parameters/path
@@ -256,6 +316,7 @@ in
 
     systemd.services.systemd-udevd =
       { environment.MODULE_DIR = "/run/booted-system/kernel-modules/lib/modules";
+        restartTriggers = cfg.packages;
       };
 
   };
diff --git a/nixos/modules/services/logging/logstash.nix b/nixos/modules/services/logging/logstash.nix
index e019e6c3f237..d27456e59e88 100644
--- a/nixos/modules/services/logging/logstash.nix
+++ b/nixos/modules/services/logging/logstash.nix
@@ -85,7 +85,7 @@ in
         type = types.lines;
         default = ''stdin { type => "example" }'';
         description = "Logstash input configuration.";
-        example = ''
+        example = literalExample ''
           # Read from journal
           pipe {
             command => "''${pkgs.systemd}/bin/journalctl -f -o json"
@@ -98,7 +98,7 @@ in
         type = types.lines;
         default = ''noop {}'';
         description = "logstash filter configuration.";
-        example = ''
+        example = literalExample ''
           if [type] == "syslog" {
             # Keep only relevant systemd fields
             # http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html
@@ -114,7 +114,7 @@ in
 
       outputConfig = mkOption {
         type = types.lines;
-        default = ''stdout { debug => true debug_format => "json"}'';
+        default = literalExample ''stdout { debug => true debug_format => "json"}'';
         description = "Logstash output configuration.";
         example = ''
           redis { host => "localhost" data_type => "list" key => "logstash" codec => json }
diff --git a/nixos/modules/services/mail/dovecot.nix b/nixos/modules/services/mail/dovecot.nix
index 11e8b26c75ef..333a03315bca 100644
--- a/nixos/modules/services/mail/dovecot.nix
+++ b/nixos/modules/services/mail/dovecot.nix
@@ -13,6 +13,7 @@ let
     ''
       base_dir = ${baseDir}
       protocols = ${concatStringsSep " " cfg.protocols}
+      sendmail_path = /var/setuid-wrappers/sendmail
     ''
 
     (if isNull cfg.sslServerCert then ''
diff --git a/nixos/modules/services/mail/dspam.nix b/nixos/modules/services/mail/dspam.nix
index 10352ba6abcc..2d8aebe20575 100644
--- a/nixos/modules/services/mail/dspam.nix
+++ b/nixos/modules/services/mail/dspam.nix
@@ -109,6 +109,9 @@ in {
           Group = cfg.group;
           RuntimeDirectory = optional (cfg.domainSocket == defaultSock) "dspam";
           PermissionsStartOnly = true;
+          # DSPAM segfaults on just about every error
+          Restart = "on-failure";
+          RestartSec = "1s";
         };
 
         preStart = ''
@@ -136,7 +139,7 @@ in {
         restartTriggers = [ cfgfile ];
 
         serviceConfig = {
-          ExecStart = "${dspam}/bin/dspam_maintenance";
+          ExecStart = "${dspam}/bin/dspam_maintenance --verbose";
           Type = "oneshot";
           User = cfg.user;
           Group = cfg.group;
diff --git a/nixos/modules/services/mail/opensmtpd.nix b/nixos/modules/services/mail/opensmtpd.nix
index a1cfd84365a2..42a1244cde57 100644
--- a/nixos/modules/services/mail/opensmtpd.nix
+++ b/nixos/modules/services/mail/opensmtpd.nix
@@ -9,6 +9,11 @@ let
   conf = writeText "smtpd.conf" cfg.serverConfiguration;
   args = concatStringsSep " " cfg.extraServerArgs;
 
+  sendmail = pkgs.runCommand "opensmtpd-sendmail" {} ''
+    mkdir -p $out/bin
+    ln -s ${opensmtpd}/sbin/smtpctl $out/bin/sendmail
+  '';
+
 in {
 
   ###### interface
@@ -23,6 +28,15 @@ in {
         description = "Whether to enable the OpenSMTPD server.";
       };
 
+      addSendmailToSystemPath = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether to add OpenSMTPD's sendmail binary to the
+          system path or not.
+        '';
+      };
+
       extraServerArgs = mkOption {
         type = types.listOf types.str;
         default = [];
@@ -64,7 +78,7 @@ in {
 
   ###### implementation
 
-  config = mkIf config.services.opensmtpd.enable {
+  config = mkIf cfg.enable {
     users.extraGroups = {
       smtpd.gid = config.ids.gids.smtpd;
       smtpq.gid = config.ids.gids.smtpq;
@@ -98,9 +112,6 @@ in {
       environment.OPENSMTPD_PROC_PATH = "${procEnv}/libexec/opensmtpd";
     };
 
-    environment.systemPackages = [ (pkgs.runCommand "opensmtpd-sendmail" {} ''
-      mkdir -p $out/bin
-      ln -s ${opensmtpd}/sbin/smtpctl $out/bin/sendmail
-    '') ];
+    environment.systemPackages = mkIf cfg.addSendmailToSystemPath [ sendmail ];
   };
 }
diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix
index f2d8189de6ef..404cdf0f564b 100644
--- a/nixos/modules/services/mail/postfix.nix
+++ b/nixos/modules/services/mail/postfix.nix
@@ -13,6 +13,18 @@ let
   haveTransport = cfg.transport != "";
   haveVirtual = cfg.virtual != "";
 
+  clientAccess =
+    if (cfg.dnsBlacklistOverrides != "")
+    then [ "check_client_access hash:/etc/postfix/client_access" ]
+    else [];
+
+  dnsBl =
+    if (cfg.dnsBlacklists != [])
+    then [ (concatStringsSep ", " (map (s: "reject_rbl_client " + s) cfg.dnsBlacklists)) ]
+    else [];
+
+  clientRestrictions = concatStringsSep ", " (clientAccess ++ dnsBl);
+
   mainCf =
     ''
       compatibility_level = 2
@@ -104,6 +116,9 @@ let
     + optionalString haveVirtual ''
       virtual_alias_maps = hash:/etc/postfix/virtual
     ''
+    + optionalString (cfg.dnsBlacklists != []) ''
+      smtpd_client_restrictions = ${clientRestrictions}
+    ''
     + cfg.extraConfig;
 
   masterCf = ''
@@ -161,6 +176,7 @@ let
 
   aliasesFile = pkgs.writeText "postfix-aliases" aliases;
   virtualFile = pkgs.writeText "postfix-virtual" cfg.virtual;
+  checkClientAccessFile = pkgs.writeText "postfix-check-client-access" cfg.dnsBlacklistOverrides;
   mainCfFile = pkgs.writeText "postfix-main.cf" mainCf;
   masterCfFile = pkgs.writeText "postfix-master.cf" masterCf;
   transportFile = pkgs.writeText "postfix-transport" cfg.transport;
@@ -366,6 +382,17 @@ in
         ";
       };
 
+      dnsBlacklists = mkOption {
+        default = [];
+        type = with types; listOf string;
+        description = "dns blacklist servers to use with smtpd_client_restrictions";
+      };
+
+      dnsBlacklistOverrides = mkOption {
+        default = "";
+        description = "contents of check_client_access for overriding dnsBlacklists";
+      };
+
       extraMasterConf = mkOption {
         type = types.lines;
         default = "";
@@ -461,7 +488,7 @@ in
             rm -rf /var/lib/postfix/conf
             mkdir -p /var/lib/postfix/conf
             chmod 0755 /var/lib/postfix/conf
-            ln -sf ${pkgs.postfix}/etc/postfix/postfix-files
+            ln -sf ${pkgs.postfix}/etc/postfix/postfix-files /var/lib/postfix/conf/postfix-files
             ln -sf ${mainCfFile} /var/lib/postfix/conf/main.cf
             ln -sf ${masterCfFile} /var/lib/postfix/conf/master.cf
 
@@ -494,6 +521,9 @@ in
     (mkIf haveVirtual {
       services.postfix.mapFiles."virtual" = virtualFile;
     })
+    (mkIf (cfg.dnsBlacklists != []) {
+      services.postfix.mapFiles."client_access" = checkClientAccessFile;
+    })
   ]);
 
 }
diff --git a/nixos/modules/services/mail/postsrsd.nix b/nixos/modules/services/mail/postsrsd.nix
index 36a0f8218d88..68a4c1012064 100644
--- a/nixos/modules/services/mail/postsrsd.nix
+++ b/nixos/modules/services/mail/postsrsd.nix
@@ -95,7 +95,11 @@ in {
       preStart = ''
         if [ ! -e "${cfg.secretsFile}" ]; then
           echo "WARNING: secrets file not found, autogenerating!"
-          mkdir -p -m750 "$(dirname "${cfg.secretsFile}")"
+          DIR="$(dirname "${cfg.secretsFile}")"
+          if [ ! -d "$DIR" ]; then
+            mkdir -p -m750 "$DIR"
+            chown "${cfg.user}:${cfg.group}" "$DIR"
+          fi
           dd if=/dev/random bs=18 count=1 | base64 > "${cfg.secretsFile}"
           chmod 600 "${cfg.secretsFile}"
         fi
diff --git a/nixos/modules/services/misc/gitit.nix b/nixos/modules/services/misc/gitit.nix
index ab4d385ba165..befd8c628f16 100644
--- a/nixos/modules/services/misc/gitit.nix
+++ b/nixos/modules/services/misc/gitit.nix
@@ -35,7 +35,6 @@ let
       };
 
       haskellPackages = mkOption {
-        type = types.attrsOf types.package;
         default = pkgs.haskellPackages;
         defaultText = "pkgs.haskellPackages";
         example = literalExample "pkgs.haskell.packages.ghc784";
diff --git a/nixos/modules/services/misc/sundtek.nix b/nixos/modules/services/misc/sundtek.nix
index 8438ef79904f..e3234518c940 100644
--- a/nixos/modules/services/misc/sundtek.nix
+++ b/nixos/modules/services/misc/sundtek.nix
@@ -23,7 +23,7 @@ in
         Type = "oneshot";
         ExecStart = ''
           ${pkgs.sundtek}/bin/mediasrv -d -v -p ${pkgs.sundtek}/bin ;\
-          ${pkgs.sundtek}/bin/mediaclient --start=5 --wait-for-devices
+          ${pkgs.sundtek}/bin/mediaclient --start --wait-for-devices
           '';
         ExecStop = "${pkgs.sundtek}/bin/mediaclient --shutdown";
         RemainAfterExit = true;
diff --git a/nixos/modules/services/networking/connman.nix b/nixos/modules/services/networking/connman.nix
index deb1cbfc1858..3fecfbb13a04 100644
--- a/nixos/modules/services/networking/connman.nix
+++ b/nixos/modules/services/networking/connman.nix
@@ -53,13 +53,13 @@ in {
   config = mkIf cfg.enable {
 
     assertions = [{
-      assertion = config.networking.useDHCP == false;
+      assertion = !config.networking.useDHCP;
       message = "You can not use services.networking.connman with services.networking.useDHCP";
     }{
-      assertion = config.networking.wireless.enable == true;
+      assertion = config.networking.wireless.enable;
       message = "You must use services.networking.connman with services.networking.wireless";
     }{
-      assertion = config.networking.networkmanager.enable == false;
+      assertion = !config.networking.networkmanager.enable;
       message = "You can not use services.networking.connman with services.networking.networkmanager";
     }];
 
diff --git a/nixos/modules/services/networking/i2pd.nix b/nixos/modules/services/networking/i2pd.nix
index c467402dbcf6..c32b935cf940 100644
--- a/nixos/modules/services/networking/i2pd.nix
+++ b/nixos/modules/services/networking/i2pd.nix
@@ -12,21 +12,69 @@ let
 
   toOneZero = b: if b then "1" else "0";
 
+  mkEndpointOpt = name: addr: port: {
+    name = mkOption {
+      type = types.str;
+      default = name;
+      description = "The endpoint name.";
+    };
+    address = mkOption {
+      type = types.str;
+      default = addr;
+      description = "Bind address for ${name} endpoint. Default: " + addr;
+    };
+    port = mkOption {
+      type = types.int;
+      default = port;
+      description = "Bind port for ${name} endoint. Default: " + toString port;
+    };
+  };
+
+  commonTunOpts = let
+    i2cpOpts = {
+      length = mkOption {
+        type = types.int;
+        description = "Guaranteed minimum hops.";
+        default = 3;
+      };
+      quantity = mkOption {
+        type = types.int;
+        description = "Number of simultaneous tunnels.";
+        default = 5;
+      };
+    };
+  in name: {
+    outbound = i2cpOpts;
+    inbound = i2cpOpts;
+    crypto.tagsToSend = mkOption {
+      type = types.int;
+      description = "Number of ElGamal/AES tags to send.";
+      default = 40;
+    };
+   destination = mkOption {
+      type = types.str;
+      description = "Remote endpoint, I2P hostname or b32.i2p address.";
+    };
+    keys = mkOption {
+      type = types.str;
+      default = name + "-keys.dat";
+      description = "Keyset used for tunnel identity.";
+    };
+  } // mkEndpointOpt name "127.0.0.1" 0;
+
   i2pdConf = pkgs.writeText "i2pd.conf" ''
-      v6 = ${toOneZero cfg.enableIPv6}
-      unreachable = ${toOneZero cfg.unreachable}
+      ipv6 = ${toOneZero cfg.enableIPv6}
+      notransit = ${toOneZero cfg.notransit}
       floodfill = ${toOneZero cfg.floodfill}
       ${if isNull cfg.port then "" else "port = ${toString cfg.port}"}
-      httpproxyport = ${toString cfg.proxy.httpPort}
-      socksproxyport = ${toString cfg.proxy.socksPort}
-      ircaddress = ${cfg.irc.host}
-      ircport = ${toString cfg.irc.port}
-      ircdest = ${cfg.irc.dest}
-      irckeys = ${cfg.irc.keyFile}
-      eepport = ${toString cfg.eep.port}
-      ${if isNull cfg.sam.port then "" else "--samport=${toString cfg.sam.port}"}
-      eephost = ${cfg.eep.host}
-      eepkeys = ${cfg.eep.keyFile}
+      ${flip concatMapStrings
+        (collect (proto: proto ? port && proto ? address && proto ? name) cfg.proto)
+        (proto: let portStr = toString proto.port; in ''
+      [${proto.name}]
+      address = ${proto.address}
+      port = ${toString proto.port}
+      '')
+      }
   '';
 
   i2pdTunnelConf = pkgs.writeText "i2pd-tunnels.conf" ''
@@ -39,10 +87,15 @@ let
   keys = ${tun.keys}
   address = ${tun.address}
   port = ${toString tun.port}
+  inbound.length = ${toString tun.inbound.length}
+  outbound.length = ${toString tun.outbound.length}
+  inbound.quantity = ${toString tun.inbound.quantity}
+  outbound.quantity = ${toString tun.outbound.quantity}
+  crypto.tagsToSend = ${toString tun.crypto.tagsToSend}
   '')
   }
   ${flip concatMapStrings
-    (collect (tun: tun ? port && tun ? host) cfg.outTunnels)
+    (collect (tun: tun ? port && tun ? host) cfg.inTunnels)
     (tun: let portStr = toString tun.port; in ''
   [${tun.name}]
   type = server
@@ -59,10 +112,10 @@ let
   i2pdSh = pkgs.writeScriptBin "i2pd" ''
     #!/bin/sh
     ${if isNull cfg.extIp then extip else ""}
-    ${pkgs.i2pd}/bin/i2pd --log=1 --daemon=0 --service=0 \
+    ${pkgs.i2pd}/bin/i2pd --log=1 \
       --host=${if isNull cfg.extIp then "$EXTIP" else cfg.extIp} \
       --conf=${i2pdConf} \
-      --tunnelscfg=${i2pdTunnelConf}
+      --tunconf=${i2pdTunnelConf}
   '';
 
 in
@@ -91,11 +144,11 @@ in
         '';
       };
 
-      unreachable = mkOption {
+      notransit = mkOption {
         type = types.bool;
         default = false;
         description = ''
-          If the router is declared to be unreachable and needs introduction nodes.
+          Tells the router to not accept transit tunnels during startup.
         '';
       };
 
@@ -111,7 +164,7 @@ in
         type = with types; nullOr int;
         default = null;
         description = ''
-	        I2P listen port. If no one is given the router will pick between 9111 and 30777.
+          I2P listen port. If no one is given the router will pick between 9111 and 30777.
         '';
       };
 
@@ -123,184 +176,53 @@ in
         '';
       };
 
-      http = {
-        port = mkOption {
-          type = types.int;
-          default = 7070;
-          description = ''
-            HTTP listen port.
-          '';
-        };
-      };
-
-      proxy = {
-        httpPort = mkOption {
-          type = types.int;
-          default = 4446;
-          description = ''
-            HTTP proxy listen port.
-          '';
-        };
-        socksPort = mkOption {
-          type = types.int;
-          default = 4447;
-          description = ''
-            SOCKS proxy listen port.
-          '';
-        };
-      };
-
-      irc = {
-        host = mkOption {
-          type = types.str;
-          default = "127.0.0.1";
-          description = ''
-            Address to forward incoming traffic to. 127.0.0.1 by default.
-          '';
-        };
-        dest = mkOption {
-          type = types.str;
-          default = "irc.postman.i2p";
-          description = ''
-            Destination I2P tunnel endpoint address of IRC server. irc.postman.i2p by default.
-          '';
-        };
-        port = mkOption {
-          type = types.int;
-          default = 6668;
-          description = ''
-            Local IRC tunnel endoint port to listen on. 6668 by default.
-          '';
-        };
-        keyFile = mkOption {
-          type = types.str;
-          default = "privKeys.dat";
-          description = ''
-            File name containing destination keys. privKeys.dat by default.
-          '';
-        };
-      };
-
-      eep = {
-        host = mkOption {
-          type = types.str;
-          default = "127.0.0.1";
-          description = ''
-            Address to forward incoming traffic to. 127.0.0.1 by default.
-          '';
-        };
-        port = mkOption {
-          type = types.int;
-          default = 80;
-          description = ''
-            Port to forward incoming traffic to. 80 by default.
-          '';
-        };
-        keyFile = mkOption {
-          type = types.str;
-          default = "privKeys.dat";
-          description = ''
-            File name containing destination keys. privKeys.dat by default.
-          '';
-        };
-      };
-
-      sam = {
-        port = mkOption {
-          type = with types; nullOr int;
-          default = null;
-          description = ''
-            Local SAM tunnel endpoint. Usually 7656. SAM is disabled if not specified.
-          '';
-        };
-      };
+      proto.http = mkEndpointOpt "http" "127.0.0.1" 7070;
+      proto.sam = mkEndpointOpt "sam" "127.0.0.1" 7656;
+      proto.bob = mkEndpointOpt "bob" "127.0.0.1" 2827;
+      proto.i2pControl = mkEndpointOpt "i2pcontrol" "127.0.0.1" 7650;
+      proto.httpProxy = mkEndpointOpt "httpproxy" "127.0.0.1" 4446;
+      proto.socksProxy = mkEndpointOpt "socksproxy" "127.0.0.1" 4447;
 
       outTunnels = mkOption {
         default = {};
-	      type = with types; loaOf optionSet;
-	      description = ''
-	      '';
-	      options = [ ({ name, config, ... }: {
-
-	        options = {
-	          name = mkOption {
-	            type = types.str;
-	            description = "The name of the tunnel.";
-	          };
-	          destination = mkOption {
-	            type = types.str;
-	            description = "Remote endpoint, I2P hostname or b32.i2p address.";
-	          };
-	          keys = mkOption {
-	            type = types.str;
-	            default = name + "-keys.dat";
-	            description = "Keyset used for tunnel identity.";
-	          };
-	          address = mkOption {
-	            type = types.str;
-	            default = "127.0.0.1";
-	            description = "Local bind address for tunnel.";
-	          };
-	          port = mkOption {
-	            type = types.int;
-	            default = 0;
-	            description = "Local tunnel listen port.";
-	          };
-	        };
-
-	        config = {
-	          name = mkDefault name;
-	        };
-
-	      }) ];
+        type = with types; loaOf optionSet;
+        description = ''
+          Connect to someone as a client and establish a local accept endpoint
+        '';
+        options = [ ({ name, config, ... }: {
+          options = commonTunOpts name;
+          config = {
+            name = mkDefault name;
+          };
+        }) ];
       };
 
       inTunnels = mkOption {
         default = {};
-	      type = with types; loaOf optionSet;
-	      description = ''
-	      '';
-	      options = [ ({ name, config, ... }: {
-
-	        options = {
-
-	          name = mkOption {
-	            type = types.str;
-	            description = "The name of the tunnel.";
-	          };
-	          keys = mkOption {
-	            type = types.path;
-	            default = name + "-keys.dat";
-	            description = "Keyset used for tunnel identity.";
-	          };
-	          address = mkOption {
-	            type = types.str;
-	            default = "127.0.0.1";
-	            description = "Local service IP address.";
-	          };
-	          port = mkOption {
-	            type = types.int;
-	            default = 0;
-	            description = "Local tunnel listen port.";
-	          };
-	          inPort = mkOption {
-	            type = types.int;
-	            default = 0;
-	            description = "I2P service port. Default to the tunnel's listen port.";
-	          };
-	          accessList = mkOption {
-	            type = with types; listOf str;
-	            default = [];
-	            description = "I2P nodes that are allowed to connect to this service.";
-	          };
-
-	        };
-
-	        config = {
-	          name = mkDefault name;
-	        };
-
-	      }) ];
+        type = with types; loaOf optionSet;
+        description = ''
+          Serve something on I2P network at port and delegate requests to address inPort.
+        '';
+        options = [ ({ name, config, ... }: {
+
+          options = {
+            inPort = mkOption {
+              type = types.int;
+              default = 0;
+              description = "Service port. Default to the tunnel's listen port.";
+            };
+            accessList = mkOption {
+              type = with types; listOf str;
+              default = [];
+              description = "I2P nodes that are allowed to connect to this service.";
+            };
+          } // commonTunOpts name;
+
+          config = {
+            name = mkDefault name;
+          };
+
+        }) ];
       };
     };
   };
diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix
index 5baea4bc6aea..ba3efc8c0c2a 100644
--- a/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixos/modules/services/networking/ssh/sshd.nix
@@ -52,6 +52,8 @@ let
     ));
   in listToAttrs (map mkAuthKeyFile usersWithKeys);
 
+  supportOldHostKeys = !versionAtLeast config.system.stateVersion "15.07";
+
 in
 
 {
@@ -177,7 +179,7 @@ in
         default =
           [ { type = "rsa"; bits = 4096; path = "/etc/ssh/ssh_host_rsa_key"; }
             { type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
-          ] ++ optionals (!versionAtLeast config.system.stateVersion "15.07")
+          ] ++ optionals supportOldHostKeys
           [ { type = "dsa"; path = "/etc/ssh/ssh_host_dsa_key"; }
             { type = "ecdsa"; bits = 521; path = "/etc/ssh/ssh_host_ecdsa_key"; }
           ];
@@ -347,6 +349,15 @@ in
         ${flip concatMapStrings cfg.hostKeys (k: ''
           HostKey ${k.path}
         '')}
+
+        # Allow DSA client keys for now. (These were deprecated
+        # in OpenSSH 7.0.)
+        PubkeyAcceptedKeyTypes +ssh-dss
+
+        # Re-enable DSA host keys for now.
+        ${optionalString supportOldHostKeys ''
+          HostKeyAlgorithms +ssh-dss
+        ''}
       '';
 
     assertions = [{ assertion = if cfg.forwardX11 then cfgc.setXAuthLocation else true;
diff --git a/nixos/modules/services/networking/tinc.nix b/nixos/modules/services/networking/tinc.nix
index 34f4f6b37b60..9330e6c92ba8 100644
--- a/nixos/modules/services/networking/tinc.nix
+++ b/nixos/modules/services/networking/tinc.nix
@@ -95,6 +95,16 @@ in
             '';
           };
 
+          chroot = mkOption {
+            default = true;
+            type = types.bool;
+            description = ''
+              Change process root directory to the directory where the config file is located (/etc/tinc/netname/), for added security.
+              The chroot is performed after all the initialization is done, after writing pid files and opening network sockets.
+
+              Note that tinc can't run scripts anymore (such as tinc-down or host-up), unless it is setup to be runnable inside chroot environment.
+            '';
+          };
         };
       };
     };
@@ -166,7 +176,7 @@ in
           fi
         '';
         script = ''
-          tincd -D -U tinc.${network} -n ${network} --pidfile /run/tinc.${network}.pid -d ${toString data.debugLevel}
+          tincd -D -U tinc.${network} -n ${network} ${optionalString (data.chroot) "-R"} --pidfile /run/tinc.${network}.pid -d ${toString data.debugLevel}
         '';
       })
     );
diff --git a/nixos/modules/services/networking/unifi.nix b/nixos/modules/services/networking/unifi.nix
index be8f12ecd32d..4dc0cd96904c 100644
--- a/nixos/modules/services/networking/unifi.nix
+++ b/nixos/modules/services/networking/unifi.nix
@@ -61,6 +61,8 @@ in
       partOf = systemdMountPoints;
       bindsTo = systemdMountPoints;
       unitConfig.RequiresMountsFor = stateDir;
+      # This a HACK to fix missing dependencies of dynamic libs extracted from jars
+      environment.LD_LIBRARY_PATH = with pkgs.stdenv; "${cc.cc}/lib";
 
       preStart = ''
         # Ensure privacy of state
diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix
index 1b655af6c82d..1558c5832892 100644
--- a/nixos/modules/services/networking/wpa_supplicant.nix
+++ b/nixos/modules/services/networking/wpa_supplicant.nix
@@ -8,11 +8,15 @@ let
     ${optionalString cfg.userControlled.enable ''
       ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=${cfg.userControlled.group}
       update_config=1''}
-    ${concatStringsSep "\n" (mapAttrsToList (ssid: networkConfig: ''
+    ${concatStringsSep "\n" (mapAttrsToList (ssid: networkConfig: let
+      psk = if networkConfig.psk != null
+        then ''"${networkConfig.psk}"''
+        else networkConfig.pskRaw;
+    in ''
       network={
         ssid="${ssid}"
-        ${optionalString (networkConfig.psk != null) ''psk="${networkConfig.psk}"''}
-        ${optionalString (networkConfig.psk == null) ''key_mgmt=NONE''}
+        ${optionalString (psk != null) ''psk=${psk}''}
+        ${optionalString (psk == null) ''key_mgmt=NONE''}
       }
     '') cfg.networks)}
   '' else "/etc/wpa_supplicant.conf";
@@ -49,6 +53,19 @@ in {
 
                 Be aware that these will be written to the nix store
                 in plaintext!
+
+                Mutually exclusive with <varname>pskRaw</varname>.
+              '';
+            };
+
+            pskRaw = mkOption {
+              type = types.nullOr types.str;
+              default = null;
+              description = ''
+                The network's pre-shared key in hex defaulting
+                to being a network without any authentication.
+
+                Mutually exclusive with <varname>psk</varname>.
               '';
             };
           };
@@ -95,6 +112,11 @@ in {
 
   config = mkMerge [
     (mkIf cfg.enable {
+      assertions = flip mapAttrsToList cfg.networks (name: cfg: {
+        assertion = cfg.psk == null || cfg.pskRaw == null;
+        message = ''networking.wireless."${name}".psk and networking.wireless."${name}".pskRaw are mutually exclusive'';
+      });
+
       environment.systemPackages =  [ pkgs.wpa_supplicant ];
 
       services.dbus.packages = [ pkgs.wpa_supplicant ];
diff --git a/nixos/modules/services/search/elasticsearch.nix b/nixos/modules/services/search/elasticsearch.nix
index 478ebcfb9664..c51a42b8e9c1 100644
--- a/nixos/modules/services/search/elasticsearch.nix
+++ b/nixos/modules/services/search/elasticsearch.nix
@@ -9,6 +9,8 @@ let
     network.host: ${cfg.listenAddress}
     network.port: ${toString cfg.port}
     network.tcp.port: ${toString cfg.tcp_port}
+    # TODO: find a way to enable security manager
+    security.manager.enabled: false
     cluster.name: ${cfg.cluster_name}
     ${cfg.extraConf}
   '';
@@ -39,8 +41,8 @@ in {
 
     package = mkOption {
       description = "Elasticsearch package to use.";
-      default = pkgs.elasticsearch;
-      defaultText = "pkgs.elasticsearch";
+      default = pkgs.elasticsearch2;
+      defaultText = "pkgs.elasticsearch2";
       type = types.package;
     };
 
@@ -129,7 +131,9 @@ in {
       wantedBy = [ "multi-user.target" ];
       after = [ "network-interfaces.target" ];
       path = [ pkgs.inetutils ];
-      environment = { ES_HOME = cfg.dataDir; };
+      environment = {
+        ES_HOME = cfg.dataDir;
+      };
       serviceConfig = {
         ExecStart = "${cfg.package}/bin/elasticsearch -Des.path.conf=${configDir} ${toString cfg.extraCmdLineOptions}";
         User = "elasticsearch";
@@ -137,10 +141,11 @@ in {
       };
       preStart = ''
         mkdir -m 0700 -p ${cfg.dataDir}
-        if [ "$(id -u)" = 0 ]; then chown -R elasticsearch ${cfg.dataDir}; fi
 
         # Install plugins
         ln -sfT ${esPlugins}/plugins ${cfg.dataDir}/plugins
+        ln -sfT ${cfg.package}/lib ${cfg.dataDir}/lib
+        if [ "$(id -u)" = 0 ]; then chown -R elasticsearch ${cfg.dataDir}; fi
       '';
       postStart = mkBefore ''
         until ${pkgs.curl.bin}/bin/curl -s -o /dev/null ${cfg.listenAddress}:${toString cfg.port}; do
diff --git a/nixos/modules/services/search/kibana.nix b/nixos/modules/services/search/kibana.nix
index 4263ed22a8db..033b8139d341 100644
--- a/nixos/modules/services/search/kibana.nix
+++ b/nixos/modules/services/search/kibana.nix
@@ -7,37 +7,33 @@ let
 
   cfgFile = pkgs.writeText "kibana.json" (builtins.toJSON (
     (filterAttrsRecursive (n: v: v != null) ({
-      server = {
-        host = cfg.listenAddress;
-        port = cfg.port;
-        ssl = {
-          cert = cfg.cert;
-          key = cfg.key;
-        };
-      };
-
-      kibana = {
-        index = cfg.index;
-        defaultAppId = cfg.defaultAppId;
-      };
-
-      elasticsearch = {
-        url = cfg.elasticsearch.url;
-        username = cfg.elasticsearch.username;
-        password = cfg.elasticsearch.password;
-        ssl = {
-          cert = cfg.elasticsearch.cert;
-          key = cfg.elasticsearch.key;
-          ca = cfg.elasticsearch.ca;
-        };
-      };
-
-      logging = {
-        verbose = cfg.logLevel == "verbose";
-        quiet = cfg.logLevel == "quiet";
-        silent = cfg.logLevel == "silent";
-        dest = "stdout";
-      };
+      host = cfg.listenAddress;
+      port = cfg.port;
+      ssl_cert_file = cfg.cert;
+      ssl_key_file = cfg.key;
+
+      kibana_index = cfg.index;
+      default_app_id = cfg.defaultAppId;
+
+      elasticsearch_url = cfg.elasticsearch.url;
+      kibana_elasticsearch_username = cfg.elasticsearch.username;
+      kibana_elasticsearch_password = cfg.elasticsearch.password;
+      kibana_elasticsearch_cert = cfg.elasticsearch.cert;
+      kibana_elasticsearch_key = cfg.elasticsearch.key;
+      ca = cfg.elasticsearch.ca;
+
+      bundled_plugin_ids = [
+        "plugins/dashboard/index"
+        "plugins/discover/index"
+        "plugins/doc/index"
+        "plugins/kibana/index"
+        "plugins/markdown_vis/index"
+        "plugins/metric_vis/index"
+        "plugins/settings/index"
+        "plugins/table_vis/index"
+        "plugins/vis_types/index"
+        "plugins/visualize/index"
+      ];
     } // cfg.extraConf)
   )));
 in {
@@ -118,12 +114,6 @@ in {
       };
     };
 
-    logLevel = mkOption {
-      description = "Kibana log level";
-      default = "normal";
-      type = types.enum ["verbose" "normal" "silent" "quiet"];
-    };
-
     package = mkOption {
       description = "Kibana package to use";
       default = pkgs.kibana;
@@ -149,6 +139,7 @@ in {
       description = "Kibana Service";
       wantedBy = [ "multi-user.target" ];
       after = [ "network-interfaces.target" "elasticsearch.service" ];
+      environment = { BABEL_CACHE_PATH = "${cfg.dataDir}/.babelcache.json"; };
       serviceConfig = {
         ExecStart = "${cfg.package}/bin/kibana --config ${cfgFile}";
         User = "kibana";
diff --git a/nixos/modules/services/security/haka.nix b/nixos/modules/services/security/haka.nix
new file mode 100644
index 000000000000..4f2bdd29cc49
--- /dev/null
+++ b/nixos/modules/services/security/haka.nix
@@ -0,0 +1,156 @@
+# This module defines global configuration for Haka.
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.haka;
+
+  haka = cfg.package;
+
+  hakaConf = pkgs.writeText "haka.conf"
+  ''
+    [general]
+    configuration = ${if lib.strings.hasPrefix "/" cfg.configFile
+      then "${cfg.configFile}"
+      else "${haka}/share/haka/sample/${cfg.configFile}"}
+    ${optionalString (builtins.lessThan 0 cfg.threads) "thread = ${cfg.threads}"}
+
+    [packet]
+    ${optionalString cfg.pcap ''module = "packet/pcap"''}
+    ${optionalString cfg.nfqueue ''module = "packet/nqueue"''}
+    ${optionalString cfg.dump.enable ''dump = "yes"''}
+    ${optionalString cfg.dump.enable ''dump_input = "${cfg.dump.input}"''}
+    ${optionalString cfg.dump.enable ''dump_output = "${cfg.dump.output}"''}
+
+    interfaces = "${lib.strings.concatStringsSep "," cfg.interfaces}"
+
+    [log]
+    # Select the log module
+    module = "log/syslog"
+
+    # Set the default logging level
+    #level = "info,packet=debug"
+
+    [alert]
+    # Select the alert module
+    module = "alert/syslog"
+
+    # Disable alert on standard output
+    #alert_on_stdout = no
+
+    # alert/file module option
+    #file = "/dev/null"
+  '';
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.haka = {
+
+      enable = mkEnableOption "Haka";
+
+      package = mkOption {
+        default = pkgs.haka;
+        type = types.package;
+        description = "
+          Which Haka derivation to use.
+        ";
+      };
+
+      configFile = mkOption {
+        default = "empty.lua";
+        example = "/srv/haka/myfilter.lua";
+        type = types.string;
+        description = ''
+          Specify which configuration file Haka uses.
+          It can be absolute path or a path relative to the sample directory of
+          the haka git repo.
+        '';
+      };
+
+      interfaces = mkOption {
+        default = [ "eth0" ];
+        example = [ "any" ];
+        type = with types; listOf string;
+        description = ''
+          Specify which interface(s) Haka listens to.
+          Use 'any' to listen to all interfaces.
+        '';
+      };
+
+      threads = mkOption {
+        default = 0;
+        example = 4;
+        type = types.int;
+        description = ''
+          The number of threads that will be used.
+          All system threads are used by default.
+        '';
+      };
+
+      pcap = mkOption {
+        default = true;
+        example = false;
+        type = types.bool;
+        description = "Whether to enable pcap";
+      };
+
+      nfqueue = mkEnableOption "nfqueue";
+
+      dump.enable = mkEnableOption "dump";
+      dump.input  = mkOption {
+        default = "/tmp/input.pcap";
+        example = "/path/to/file.pcap";
+        type = types.path;
+        description = "Path to file where incoming packets are dumped";
+      };
+
+      dump.output  = mkOption {
+        default = "/tmp/output.pcap";
+        example = "/path/to/file.pcap";
+        type = types.path;
+        description = "Path to file where outgoing packets are dumped";
+      };
+    };
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    assertions = [
+      { assertion = cfg.pcap != cfg.nfqueue;
+        message = "either pcap or nfqueue can be enabled, not both.";
+      }
+      { assertion = cfg.nfqueue -> !dump.enable;
+        message = "dump can only be used with nfqueue.";
+      }
+      { assertion = cfg.interfaces != [];
+        message = "at least one interface must be specified.";
+      }];
+
+
+    environment.systemPackages = [ haka ];
+
+    systemd.services.haka = {
+      description = "Haka";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network.target" ];
+      serviceConfig = {
+        ExecStart = "${haka}/bin/haka -c ${hakaConf}";
+        ExecStop = "${haka}/bin/hakactl stop";
+        User = "root";
+        Type = "forking";
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix b/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix
index 52d8c89baff2..0fe8d1a89cf3 100644
--- a/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix
@@ -83,11 +83,11 @@ let
 
   # Unpack Mediawiki and put the config file in its root directory.
   mediawikiRoot = pkgs.stdenv.mkDerivation rec {
-    name= "mediawiki-1.23.9";
+    name= "mediawiki-1.23.13";
 
     src = pkgs.fetchurl {
       url = "http://download.wikimedia.org/mediawiki/1.23/${name}.tar.gz";
-      sha256 = "1l7k4g0pgz92yvrfr52w26x740s4362v0gc95pk0i30vn2sp5bql";
+      sha256 = "168wpf53n4ksj2g5q5r0hxapx6238dvsfng5ff9ixk6axsn0j5d0";
     };
 
     skins = config.skins;
diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix
index 998bcd354c53..3e91450a39d2 100644
--- a/nixos/modules/services/x11/desktop-managers/default.nix
+++ b/nixos/modules/services/x11/desktop-managers/default.nix
@@ -64,7 +64,13 @@ in
           else if any (w: w.name == defaultDM) cfg.session.list then
             defaultDM
           else
-            throw "Default desktop manager ($(defaultDM)) not found.";
+            throw ''
+              Default desktop manager (${defaultDM}) not found.
+              Probably you want to change
+                services.xserver.desktopManager.default = "${defaultDM}";
+              to one of
+                ${concatMapStringsSep "\n  " (w: "services.xserver.desktopManager.default = \"${w.name}\";") cfg.session.list}
+            '';
       };
 
     };
diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix
index 55d7fd80cf97..6cb4f3acba8d 100644
--- a/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -64,7 +64,7 @@ in {
     environment.gnome3.packageSet = mkOption {
       type = types.nullOr types.package;
       default = null;
-      example = literalExample "pkgs.gnome3_16";
+      example = literalExample "pkgs.gnome3_18";
       description = "Which GNOME 3 package set to use.";
       apply = p: if p == null then pkgs.gnome3 else p;
     };
diff --git a/nixos/modules/services/x11/desktop-managers/kde4.nix b/nixos/modules/services/x11/desktop-managers/kde4.nix
index 29cca248cde3..80e408be4923 100644
--- a/nixos/modules/services/x11/desktop-managers/kde4.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde4.nix
@@ -108,6 +108,12 @@ in
                 sed -e '/nix\\store\|nix\/store/ d' -i $HOME/.config/Trolltech.conf
             fi
 
+            # Load PulseAudio module for routing support.
+            # See http://colin.guthr.ie/2009/10/so-how-does-the-kde-pulseaudio-support-work-anyway/
+            ${optionalString config.hardware.pulseaudio.enable ''
+              ${config.hardware.pulseaudio.package}/bin/pactl load-module module-device-manager "do_routing=1"
+            ''}
+
             # Start KDE.
             exec ${kde_workspace}/bin/startkde
           '';
diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix
index 4b238938d927..62e483ae7061 100644
--- a/nixos/modules/services/x11/desktop-managers/kde5.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde5.nix
@@ -55,7 +55,15 @@ in
     services.xserver.desktopManager.session = singleton {
       name = "kde5";
       bgSupport = true;
-      start = ''exec startkde;'';
+      start = ''
+        # Load PulseAudio module for routing support.
+        # See http://colin.guthr.ie/2009/10/so-how-does-the-kde-pulseaudio-support-work-anyway/
+        ${optionalString config.hardware.pulseaudio.enable ''
+          ${config.hardware.pulseaudio.package}/bin/pactl load-module module-device-manager "do_routing=1"
+        ''}
+
+        exec startkde
+      '';
     };
 
     security.setuidOwners = singleton {
diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix
index 3437d8f38930..b93e7db46003 100644
--- a/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixos/modules/services/x11/display-managers/default.nix
@@ -83,9 +83,6 @@ let
 
         # Publish access credentials in the root window.
         ${config.hardware.pulseaudio.package.out}/bin/pactl load-module module-x11-publish "display=$DISPLAY"
-
-        # Keep track of devices.  Mostly useful for Phonon/KDE.
-        ${config.hardware.pulseaudio.package.out}/bin/pactl load-module module-device-manager "do_routing=1"
       ''}
 
       # Tell systemd about our $DISPLAY. This is needed by the
diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix
index 9460395f86d6..3949bf01a316 100644
--- a/nixos/modules/services/x11/display-managers/lightdm.nix
+++ b/nixos/modules/services/x11/display-managers/lightdm.nix
@@ -86,7 +86,7 @@ in
       };
 
       background = mkOption {
-        type = types.path;
+        type = types.str;
         description = ''
           The background image or color to use.
         '';
diff --git a/nixos/modules/services/x11/hardware/synaptics.nix b/nixos/modules/services/x11/hardware/synaptics.nix
index e50ed08a218a..2981e7545e81 100644
--- a/nixos/modules/services/x11/hardware/synaptics.nix
+++ b/nixos/modules/services/x11/hardware/synaptics.nix
@@ -62,6 +62,13 @@ in {
         description = "Cursor speed factor for highest-speed finger motion.";
       };
 
+      scrollDelta = mkOption {
+        type = types.nullOr types.int;
+        default = null;
+        example = 75;
+        description = "Move distance of the finger for a scroll event.";
+      };
+
       twoFingerScroll = mkOption {
         type = types.bool;
         default = false;
@@ -122,6 +129,20 @@ in {
         description = "Whether to enable palm detection (hardware support required)";
       };
 
+      palmMinWidth = mkOption {
+        type = types.nullOr types.int;
+        default = null;
+        example = 5;
+        description = "Minimum finger width at which touch is considered a palm";
+      };
+
+      palmMinZ = mkOption {
+        type = types.nullOr types.int;
+        default = null;
+        example = 20;
+        description = "Minimum finger pressure at which touch is considered a palm";
+      };
+
       horizontalScroll = mkOption {
         type = types.bool;
         default = true;
@@ -174,8 +195,12 @@ in {
           Option "HorizTwoFingerScroll" "${if cfg.horizTwoFingerScroll then "1" else "0"}"
           Option "VertEdgeScroll" "${if cfg.vertEdgeScroll then "1" else "0"}"
           Option "HorizEdgeScroll" "${if cfg.horizEdgeScroll then "1" else "0"}"
-          ${if cfg.palmDetect then ''Option "PalmDetect" "1"'' else ""}
-          ${if cfg.horizontalScroll then "" else ''Option "HorizScrollDelta" "0"''}
+          ${optionalString cfg.palmDetect ''Option "PalmDetect" "1"''}
+          ${optionalString (cfg.palmMinWidth != null) ''Option "PalmMinWidth" "${toString cfg.palmMinWidth}"''}
+          ${optionalString (cfg.palmMinZ != null) ''Option "PalmMinZ" "${toString cfg.palmMinZ}"''}
+          ${optionalString (cfg.scrollDelta != null) ''Option "VertScrollDelta" "${toString cfg.scrollDelta}"''}
+          ${if !cfg.horizontalScroll then ''Option "HorizScrollDelta" "0"''
+            else (optionalString (cfg.scrollDelta != null) ''Option "HorizScrollDelta" "${toString cfg.scrollDelta}"'')}
           ${cfg.additionalOptions}
         EndSection
       '';
diff --git a/nixos/modules/services/x11/window-managers/i3.nix b/nixos/modules/services/x11/window-managers/i3.nix
index d43dacb1be6b..2e2e10cc33b0 100644
--- a/nixos/modules/services/x11/window-managers/i3.nix
+++ b/nixos/modules/services/x11/window-managers/i3.nix
@@ -34,6 +34,6 @@ in
         '';
       }];
     };
-    environment.systemPackages = with pkgs; [ i3 i3status dmenu ];
+    environment.systemPackages = with pkgs; [ i3 ];
   };
 }
diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl
index 655fbab2a843..d9048427801f 100644
--- a/nixos/modules/system/activation/switch-to-configuration.pl
+++ b/nixos/modules/system/activation/switch-to-configuration.pl
@@ -323,7 +323,7 @@ foreach my $device (keys %$prevSwaps) {
 
 
 # Should we have systemd re-exec itself?
-my $prevSystemd = abs_path("/proc/1/exe") or die;
+my $prevSystemd = abs_path("/proc/1/exe") // "/unknown";
 my $newSystemd = abs_path("@systemd@/lib/systemd/systemd") or die;
 my $restartSystemd = $prevSystemd ne $newSystemd;
 
diff --git a/nixos/modules/system/boot/initrd-network.nix b/nixos/modules/system/boot/initrd-network.nix
index d01222243f5d..6e226c190609 100644
--- a/nixos/modules/system/boot/initrd-network.nix
+++ b/nixos/modules/system/boot/initrd-network.nix
@@ -3,9 +3,28 @@
 with lib;
 
 let
+
   cfg = config.boot.initrd.network;
 
+  udhcpcScript = pkgs.writeScript "udhcp-script"
+    ''
+      #! /bin/sh
+      if [ "$1" = bound ]; then
+        ip address add "$ip/$mask" dev "$interface"
+        if [ -n "$router" ]; then
+          ip route add default via "$router" dev "$interface"
+        fi
+        if [ -n "$dns" ]; then
+          rm -f /etc/resolv.conf
+          for i in $dns; do
+            echo "nameserver $dns" >> /etc/resolv.conf
+          done
+        fi
+      fi
+    '';
+
 in
+
 {
 
   options = {
@@ -14,82 +33,25 @@ in
       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.
+        Add network connectivity support to initrd. The network may be
+        configured using the <literal>ip</literal> kernel parameter,
+        as described in <link
+        xlink:href="https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt">the
+        kernel documentation</link>.  Otherwise, if
+        <option>networking.useDHCP</option> is enabled, an IP address
+        is acquired using DHCP.
       '';
     };
 
-    boot.initrd.network.ssh.hostRSAKey = mkOption {
-      type = types.nullOr types.path;
-      default = null;
+    boot.initrd.network.postCommands = mkOption {
+      default = "";
+      type = types.lines;
       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!
+        Shell commands to be executed after stage 1 of the
+        boot has initialised the network.
       '';
     };
 
-    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.
-      '';
-    };
 
   };
 
@@ -99,51 +61,43 @@ in
 
     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.out}/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
-    '';
+    boot.initrd.preLVMCommands = mkBefore (
+      # Search for interface definitions in command line.
+      ''
+        for o in $(cat /proc/cmdline); do
+          case $o in
+            ip=*)
+              ipconfig $o && hasNetwork=1
+              ;;
+          esac
+        done
+      ''
+
+      # Otherwise, use DHCP.
+      + optionalString config.networking.useDHCP ''
+        if [ -z "$hasNetwork" ]; then
+
+          # Bring up all interfaces.
+          for iface in $(cd /sys/class/net && ls); do
+            echo "bringing up network interface $iface..."
+            ip link set "$iface" up
+          done
+
+          # Acquire a DHCP lease.
+          echo "acquiring IP address via DHCP..."
+          udhcpc --quit --now --script ${udhcpcScript} && hasNetwork=1
+        fi
+      ''
+
+      + ''
+        if [ -n "$hasNetwork" ]; then
+          echo "networking is up!"
+          ${cfg.postCommands}
+        fi
+      '');
 
   };
+
 }
diff --git a/nixos/modules/system/boot/initrd-ssh.nix b/nixos/modules/system/boot/initrd-ssh.nix
new file mode 100644
index 000000000000..4cdc81541955
--- /dev/null
+++ b/nixos/modules/system/boot/initrd-ssh.nix
@@ -0,0 +1,124 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.boot.initrd.network.ssh;
+
+in
+
+{
+
+  options = {
+
+    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 (config.boot.initrd.network.enable && cfg.enable) {
+
+    boot.initrd.extraUtilsCommands = ''
+      copy_bin_and_libs ${pkgs.dropbear}/bin/dropbear
+      cp -pv ${pkgs.glibc}/lib/libnss_files.so.* $out/lib
+    '';
+
+    boot.initrd.extraUtilsCommandsTest = ''
+      $out/bin/dropbear -V
+    '';
+
+    boot.initrd.network.postCommands = ''
+      mkdir /dev/pts
+      mount -t devpts devpts /dev/pts
+
+      echo '${cfg.shell}' > /etc/shells
+      echo 'root:x:0:0:root:/root:${cfg.shell}' > /etc/passwd
+      echo 'passwd: files' > /etc/nsswitch.conf
+
+      mkdir -p /var/log
+      touch /var/log/lastlog
+
+      mkdir -p /etc/dropbear
+      ${optionalString (cfg.hostRSAKey != null) "ln -s ${cfg.hostRSAKey} /etc/dropbear/dropbear_rsa_host_key"}
+      ${optionalString (cfg.hostDSSKey != null) "ln -s ${cfg.hostDSSKey} /etc/dropbear/dropbear_dss_host_key"}
+      ${optionalString (cfg.hostECDSAKey != null) "ln -s ${cfg.hostECDSAKey} /etc/dropbear/dropbear_ecdsa_host_key"}
+
+      mkdir -p /root/.ssh
+      ${concatStrings (map (key: ''
+        echo -n ${escapeShellArg key} >> /root/.ssh/authorized_keys
+      '') cfg.authorizedKeys)}
+
+      dropbear -s -j -k -E -m -p ${toString cfg.port}
+    '';
+
+  };
+
+}
diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix
index 6bc046d02611..a6bbca9b30bb 100644
--- a/nixos/modules/system/boot/kernel.nix
+++ b/nixos/modules/system/boot/kernel.nix
@@ -184,6 +184,9 @@ in
         "ide_disk"
         "ide_generic"
 
+        # SD cards and internal eMMC drives.
+        "mmc_block"
+
         # Support USB keyboards, in case the boot fails and we only have
         # a USB keyboard.
         "uhci_hcd"
diff --git a/nixos/modules/system/boot/loader/init-script/init-script-builder.sh b/nixos/modules/system/boot/loader/init-script/init-script-builder.sh
index 502b3b63af2f..08d4ab14c9ca 100644
--- a/nixos/modules/system/boot/loader/init-script/init-script-builder.sh
+++ b/nixos/modules/system/boot/loader/init-script/init-script-builder.sh
@@ -80,8 +80,13 @@ for generation in $(
     | sort -n -r); do
     link=/nix/var/nix/profiles/system-$generation-link
     date=$(stat --printf="%y\n" $link | sed 's/\..*//')
-    kernelVersion=$(cd $(dirname $(readlink -f $link/kernel))/lib/modules && echo *)
-    addEntry "NixOS - Configuration $generation ($date - $kernelVersion)" $link "$generation ($date)"
+    if [ -d $link/kernel ]; then
+      kernelVersion=$(cd $(dirname $(readlink -f $link/kernel))/lib/modules && echo *)
+      suffix="($date - $kernelVersion)"
+    else
+      suffix="($date)"
+    fi
+    addEntry "NixOS - Configuration $generation $suffix" $link "$generation ($date)"
 done
 
 mv $tmpOther $targetOther
diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh
index 7fb368e8c44f..95df0ace1ca4 100644
--- a/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixos/modules/system/boot/stage-1-init.sh
@@ -150,10 +150,6 @@ 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 81418bdf1c15..3367fedc2865 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -66,10 +66,6 @@ let
         copy_bin_and_libs $BIN
       done
 
-      # Copy modprobe.
-      copy_bin_and_libs ${pkgs.kmod}/bin/kmod
-      ln -sf kmod $out/bin/modprobe
-
       # Copy resize2fs if needed.
       ${optionalString (any (fs: fs.autoResize) (attrValues config.fileSystems)) ''
         # We need mke2fs in the initrd.
@@ -161,7 +157,9 @@ let
             --replace /sbin/blkid ${extraUtils}/bin/blkid \
             --replace ${pkgs.lvm2}/sbin ${extraUtils}/bin \
             --replace /sbin/mdadm ${extraUtils}/bin/mdadm \
-            --replace /bin/sh ${extraUtils}/bin/sh
+            --replace /bin/sh ${extraUtils}/bin/sh \
+            --replace /usr/bin/readlink ${extraUtils}/bin/readlink \
+            --replace /usr/bin/basename ${extraUtils}/bin/basename
       done
 
       # Work around a bug in QEMU, which doesn't implement the "READ
@@ -203,13 +201,13 @@ let
     inherit (config.boot) resumeDevice devSize runSize;
 
     inherit (config.boot.initrd) checkJournalingFS
-      preLVMCommands preDeviceCommands postEarlyDeviceCommands postDeviceCommands postMountCommands kernelModules;
+      preLVMCommands preDeviceCommands 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) && !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 ];
+      let f = fs: [ fs.mountPoint (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fs.fsType (builtins.concatStringsSep "," fs.options) ];
       in pkgs.writeText "initrd-fsinfo" (concatStringsSep "\n" (concatMap f fileSystems));
 
     setHostId = optionalString (config.networking.hostId != null) ''
@@ -322,14 +320,6 @@ 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/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix
index d0dd7670157e..4d1466db22d0 100644
--- a/nixos/modules/tasks/filesystems.nix
+++ b/nixos/modules/tasks/filesystems.nix
@@ -41,11 +41,15 @@ let
       };
 
       options = mkOption {
-        default = "defaults";
-        example = "data=journal";
-        type = types.commas; # FIXME: should be a list
+        default = [ "defaults" ];
+        example = [ "data=journal" ];
         description = "Options used to mount the file system.";
-      };
+      } // (if versionAtLeast lib.nixpkgsVersion "16.09" then {
+        type = types.listOf types.str;
+      } else {
+        type = types.either types.commas (types.listOf types.str);
+        apply = x: if isList x then x else lib.strings.splitString "," (builtins.trace "warning: passing a comma-separated string for filesystem options is deprecated; use a list of strings instead. This will become a hard error in 16.09." x);
+      });
 
       autoFormat = mkOption {
         default = false;
@@ -112,7 +116,7 @@ in
         "/data" = {
           device = "/dev/hda2";
           fsType = "ext3";
-          options = "data=journal";
+          options = [ "data=journal" ];
         };
         "/bigdisk".label = "bigdisk";
       };
@@ -127,7 +131,7 @@ in
         <command>mount</command>; defaults to
         <literal>"auto"</literal>), and <literal>options</literal>
         (the mount options passed to <command>mount</command> using the
-        <option>-o</option> flag; defaults to <literal>"defaults"</literal>).
+        <option>-o</option> flag; defaults to <literal>[ "defaults" ]</literal>).
 
         Instead of specifying <literal>device</literal>, you can also
         specify a volume label (<literal>label</literal>) for file
@@ -177,7 +181,7 @@ in
              else throw "No device specified for mount point ‘${fs.mountPoint}’.")
             + " " + fs.mountPoint
             + " " + fs.fsType
-            + " " + fs.options
+            + " " + builtins.concatStringsSep "," fs.options
             + " 0"
             + " " + (if skipCheck fs then "0" else
                      if fs.mountPoint == "/" then "1" else "2")
diff --git a/nixos/modules/tasks/kbd.nix b/nixos/modules/tasks/kbd.nix
index e1574fa68ad9..02721bb3bea2 100644
--- a/nixos/modules/tasks/kbd.nix
+++ b/nixos/modules/tasks/kbd.nix
@@ -12,6 +12,8 @@ let
     FONT=${config.i18n.consoleFont}
     ${colors}
   '';
+
+  setVconsole = !config.boot.isContainer;
 in
 
 {
@@ -41,26 +43,33 @@ in
 
   ###### implementation
 
-  config = {
-
-    environment.systemPackages = [ pkgs.kbd ];
-
-    # Let systemd-vconsole-setup.service do the work of setting up the
-    # virtual consoles.  FIXME: trigger a restart of
-    # systemd-vconsole-setup.service if /etc/vconsole.conf changes.
-    environment.etc."vconsole.conf".source = vconsoleConf;
-
-    # This is identical to the systemd-vconsole-setup.service unit
-    # shipped with systemd, except that it uses /dev/tty1 instead of
-    # /dev/tty0 to prevent putting the X server in non-raw mode, and
-    # it has a restart trigger.
-    systemd.services."systemd-vconsole-setup" =
-      { wantedBy = [ "multi-user.target" ];
-        before = [ "display-manager.service" ];
-        after = [ "systemd-udev-settle.service" ];
-        restartTriggers = [ vconsoleConf ];
-      };
-
-  };
+  config = mkMerge [
+    (mkIf (!setVconsole) {
+      systemd.services."systemd-vconsole-setup".enable = false;
+    })
+
+    (mkIf setVconsole {
+      environment.systemPackages = [ pkgs.kbd ];
+
+      # Let systemd-vconsole-setup.service do the work of setting up the
+      # virtual consoles.  FIXME: trigger a restart of
+      # systemd-vconsole-setup.service if /etc/vconsole.conf changes.
+      environment.etc = [ {
+        target = "vconsole.conf";
+        source = vconsoleConf;
+      } ];
+
+      # This is identical to the systemd-vconsole-setup.service unit
+      # shipped with systemd, except that it uses /dev/tty1 instead of
+      # /dev/tty0 to prevent putting the X server in non-raw mode, and
+      # it has a restart trigger.
+      systemd.services."systemd-vconsole-setup" =
+        { wantedBy = [ "multi-user.target" ];
+          before = [ "display-manager.service" ];
+          after = [ "systemd-udev-settle.service" ];
+          restartTriggers = [ vconsoleConf ];
+        };
+    })
+  ];
 
 }
diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix
index f07e7baeb119..c960e401f9b1 100644
--- a/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -144,15 +144,12 @@ in
                   fi
                   ${config.systemd.package}/bin/systemctl start ip-up.target
                 '';
-            preStop =
-              ''
-                echo "releasing configured ip's..."
-              '' + flip concatMapStrings (ips) (ip:
+            preStop = flip concatMapStrings (ips) (ip:
                 let
                   address = "${ip.address}/${toString ip.prefixLength}";
                 in
                 ''
-                  echo -n "Deleting ${address}..."
+                  echo -n "deleting ${address}..."
                   ip addr del "${address}" dev "${i.name}" >/dev/null 2>&1 || echo -n " Failed"
                   echo ""
                 '');
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index e72c0f8956ed..503d3813611f 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -927,7 +927,7 @@ in
         pkgs.nettools
         pkgs.openresolv
       ]
-      ++ optionals (!config.boot.isContainer) [
+      ++ optionals config.networking.wireless.enable [
         pkgs.wirelesstools # FIXME: obsolete?
         pkgs.iw
         pkgs.rfkill
diff --git a/nixos/modules/virtualisation/amazon-image.nix b/nixos/modules/virtualisation/amazon-image.nix
index 7ccc9df740e5..a895f66db8ef 100644
--- a/nixos/modules/virtualisation/amazon-image.nix
+++ b/nixos/modules/virtualisation/amazon-image.nix
@@ -20,8 +20,7 @@ let cfg = config.ec2; in
       autoResize = true;
     };
 
-    boot.initrd.kernelModules = [ "xen-blkfront" ];
-    boot.kernelModules = [ "xen-netfront" ];
+    boot.initrd.kernelModules = [ "xen-blkfront" "xen-netfront" ];
     boot.kernelParams = mkIf cfg.hvm [ "console=ttyS0" ];
 
     # Prevent the nouveau kernel module from being loaded, as it
@@ -44,6 +43,8 @@ let cfg = config.ec2; in
         kill -9 -1
       '';
 
+    boot.initrd.network.enable = true;
+
     # Mount all formatted ephemeral disks and activate all swap devices.
     # We cannot do this with the ‘fileSystems’ and ‘swapDevices’ options
     # because the set of devices is dependent on the instance type
@@ -55,6 +56,28 @@ let cfg = config.ec2; in
     # Nix operations.
     boot.initrd.postMountCommands =
       ''
+        metaDir=$targetRoot/etc/ec2-metadata
+        mkdir -m 0755 -p "$metaDir"
+
+        echo "getting EC2 instance metadata..."
+
+        if ! [ -e "$metaDir/ami-manifest-path" ]; then
+          wget -q -O "$metaDir/ami-manifest-path" http://169.254.169.254/1.0/meta-data/ami-manifest-path
+        fi
+
+        if ! [ -e "$metaDir/user-data" ]; then
+          wget -q -O "$metaDir/user-data" http://169.254.169.254/1.0/user-data
+          chmod 600 "$metaDir/user-data"
+        fi
+
+        if ! [ -e "$metaDir/hostname" ]; then
+          wget -q -O "$metaDir/hostname" http://169.254.169.254/1.0/meta-data/hostname
+        fi
+
+        if ! [ -e "$metaDir/public-keys-0-openssh-key" ]; then
+          wget -q -O "$metaDir/public-keys-0-openssh-key" http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key
+        fi
+
         diskNr=0
         diskForUnionfs=
         for device in /dev/xvd[abcde]*; do
@@ -81,7 +104,7 @@ let cfg = config.ec2; in
             mkdir -m 1777 -p $targetRoot/$diskForUnionfs/root/tmp $targetRoot/tmp
             mount --bind $targetRoot/$diskForUnionfs/root/tmp $targetRoot/tmp
 
-            if [ ! -e $targetRoot/.ebs ]; then
+            if [ "$(cat "$metaDir/ami-manifest-path")" != "(unknown)" ]; then
                 mkdir -m 755 -p $targetRoot/$diskForUnionfs/root/var $targetRoot/var
                 mount --bind $targetRoot/$diskForUnionfs/root/var $targetRoot/var
 
diff --git a/nixos/modules/virtualisation/amazon-init.nix b/nixos/modules/virtualisation/amazon-init.nix
index 96cd57e6db5d..886552f33c2c 100644
--- a/nixos/modules/virtualisation/amazon-init.nix
+++ b/nixos/modules/virtualisation/amazon-init.nix
@@ -4,18 +4,17 @@
 
 let
   bootScript = pkgs.writeScript "bootscript.sh" ''
-    #!${pkgs.stdenv.shell} -eux
+    #!${pkgs.stdenv.shell} -eu
 
-    echo "attempting to fetch configuration from user-data..."
+    echo "attempting to fetch configuration from EC2 user data..."
 
-    export PATH=${config.nix.package}/bin:${pkgs.wget}/bin:${pkgs.systemd}/bin:${pkgs.gnugrep}/bin:${pkgs.gnused}/bin:${config.system.build.nixos-rebuild}/bin:$PATH
+    export PATH=${config.nix.package}/bin:${pkgs.systemd}/bin:${pkgs.gnugrep}/bin:${pkgs.gnused}/bin:${config.system.build.nixos-rebuild}/bin:$PATH
     export NIX_PATH=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels
 
-    userData="$(mktemp)"
-    wget -q --wait=1 --tries=0 --retry-connrefused -O - http://169.254.169.254/2011-01-01/user-data > "$userData"
+    userData=/etc/ec2-metadata/user-data
+
+    if [ -s "$userData" ]; then
 
-    if [[ $? -eq 0 ]]; then
-      echo "user-data fetched"
       # If the user-data looks like it could be a nix expression,
       # copy it over. Also, look for a magic three-hash comment and set
       # that as the channel.
@@ -30,17 +29,17 @@ let
           nix-channel --update
         fi
 
-        echo "setting configuration"
+        echo "setting configuration from EC2 user data"
         cp "$userData" /etc/nixos/configuration.nix
       else
-        echo "user-data does not appear to be a nix expression; ignoring"
+        echo "user data does not appear to be a Nix expression; ignoring"
+        exit
       fi
     else
-      echo "failed to fetch user-data"
+      echo "no user data is available"
+      exit
     fi
 
-    type -f nixos-rebuild
-
     nixos-rebuild switch
   '';
 in {
diff --git a/nixos/modules/virtualisation/azure-agent.nix b/nixos/modules/virtualisation/azure-agent.nix
index ef4e3e1e48d4..96418d61ff85 100644
--- a/nixos/modules/virtualisation/azure-agent.nix
+++ b/nixos/modules/virtualisation/azure-agent.nix
@@ -8,10 +8,11 @@ let
 
   waagent = with pkgs; stdenv.mkDerivation rec {
     name = "waagent-2.0";
-    src = pkgs.fetchgit {
-      url = https://github.com/Phreedom/WALinuxAgent.git;
-      rev = "9dba81c7b1239c7971ec96e405e403c7cd224e6b";
-      sha256 = "0khxk3ns3z37v26f2qj6m3m698a0vqpc9bxg5p7fyr3xza5gzwhs";
+    src = pkgs.fetchFromGitHub {
+      owner = "phreedom";
+      repo = "WALinuxAgent";
+      rev = "1d31fe8cbc7f842993eed9b33a3d3f5410c364e3";
+      sha256 = "1s53pfmy3azp0rmympmnphyq96sr9jy07pbsfza6mdzpalx1ripl";
     };
     buildInputs = [ makeWrapper python pythonPackages.wrapPython ];
     runtimeDeps = [ findutils gnugrep gawk coreutils openssl openssh
diff --git a/nixos/modules/virtualisation/ec2-data.nix b/nixos/modules/virtualisation/ec2-data.nix
index 383750520ab7..bee262612680 100644
--- a/nixos/modules/virtualisation/ec2-data.nix
+++ b/nixos/modules/virtualisation/ec2-data.nix
@@ -1,6 +1,6 @@
-# This module defines a systemd service that obtains the SSH key and
-# host name of virtual machines running on Amazon EC2, Eucalyptus and
-# OpenStack Compute (Nova).
+# This module defines a systemd service that sets the SSH host key and
+# authorized client key and host name of virtual machines running on
+# Amazon EC2, Eucalyptus and OpenStack Compute (Nova).
 
 { config, lib, pkgs, ... }:
 
@@ -9,55 +9,49 @@ with lib;
 {
   config = {
 
-    systemd.services.fetch-ec2-data =
-      { description = "Fetch EC2 Data";
+    systemd.services.apply-ec2-data =
+      { description = "Apply EC2 Data";
 
         wantedBy = [ "multi-user.target" "sshd.service" ];
         before = [ "sshd.service" ];
-        wants = [ "ip-up.target" ];
-        after = [ "ip-up.target" ];
 
-        path = [ pkgs.wget pkgs.iproute ];
+        path = [ pkgs.iproute ];
 
         script =
           ''
-            wget="wget -q --retry-connrefused -O -"
-
             ${optionalString (config.networking.hostName == "") ''
               echo "setting host name..."
-              ${pkgs.nettools}/bin/hostname $($wget http://169.254.169.254/1.0/meta-data/hostname)
+              if [ -s /etc/ec2-metadata/hostname ]; then
+                  ${pkgs.nettools}/bin/hostname $(cat /etc/ec2-metadata/hostname)
+              fi
             ''}
 
-            # Don't download the SSH key if it has already been injected
-            # into the image (a Nova feature).
             if ! [ -e /root/.ssh/authorized_keys ]; then
                 echo "obtaining SSH key..."
                 mkdir -m 0700 -p /root/.ssh
-                $wget http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key > /root/key.pub
-                if [ $? -eq 0 -a -e /root/key.pub ]; then
-                    cat /root/key.pub >> /root/.ssh/authorized_keys
+                if [ -s /etc/ec2-metadata/public-keys-0-openssh-key ]; then
+                    cat /etc/ec2-metadata/public-keys-0-openssh-key >> /root/.ssh/authorized_keys
                     echo "new key added to authorized_keys"
                     chmod 600 /root/.ssh/authorized_keys
-                    rm -f /root/key.pub
                 fi
             fi
 
             # Extract the intended SSH host key for this machine from
             # the supplied user data, if available.  Otherwise sshd will
             # generate one normally.
-            $wget http://169.254.169.254/2011-01-01/user-data > /root/user-data || true
+            userData=/etc/ec2-metadata/user-data
 
             mkdir -m 0755 -p /etc/ssh
 
-            key="$(sed 's/|/\n/g; s/SSH_HOST_DSA_KEY://; t; d' /root/user-data)"
-            key_pub="$(sed 's/SSH_HOST_DSA_KEY_PUB://; t; d' /root/user-data)"
+            key="$(sed 's/|/\n/g; s/SSH_HOST_DSA_KEY://; t; d' $userData)"
+            key_pub="$(sed 's/SSH_HOST_DSA_KEY_PUB://; t; d' $userData)"
             if [ -n "$key" -a -n "$key_pub" -a ! -e /etc/ssh/ssh_host_dsa_key ]; then
                 (umask 077; echo "$key" > /etc/ssh/ssh_host_dsa_key)
                 echo "$key_pub" > /etc/ssh/ssh_host_dsa_key.pub
             fi
 
-            key="$(sed 's/|/\n/g; s/SSH_HOST_ED25519_KEY://; t; d' /root/user-data)"
-            key_pub="$(sed 's/SSH_HOST_ED25519_KEY_PUB://; t; d' /root/user-data)"
+            key="$(sed 's/|/\n/g; s/SSH_HOST_ED25519_KEY://; t; d' $userData)"
+            key_pub="$(sed 's/SSH_HOST_ED25519_KEY_PUB://; t; d' $userData)"
             if [ -n "$key" -a -n "$key_pub" -a ! -e /etc/ssh/ssh_host_ed25519_key ]; then
                 (umask 077; echo "$key" > /etc/ssh/ssh_host_ed25519_key)
                 echo "$key_pub" > /etc/ssh/ssh_host_ed25519_key.pub
diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix
index 82b58aa67a3d..7dfbc38efee6 100644
--- a/nixos/modules/virtualisation/qemu-vm.nix
+++ b/nixos/modules/virtualisation/qemu-vm.nix
@@ -110,6 +110,7 @@ let
 
   # Generate a hard disk image containing a /boot partition and GRUB
   # in the MBR.  Used when the `useBootLoader' option is set.
+  # FIXME: use nixos/lib/make-disk-image.nix.
   bootDisk =
     pkgs.vmTools.runInLinuxVM (
       pkgs.runCommand "nixos-boot-disk"
@@ -427,38 +428,38 @@ in
         ${if cfg.writableStore then "/nix/.ro-store" else "/nix/store"} =
           { device = "store";
             fsType = "9p";
-            options = "trans=virtio,version=9p2000.L,cache=loose";
+            options = [ "trans=virtio" "version=9p2000.L" "cache=loose" ];
             neededForBoot = true;
           };
         "/tmp/xchg" =
           { device = "xchg";
             fsType = "9p";
-            options = "trans=virtio,version=9p2000.L,cache=loose";
+            options = [ "trans=virtio" "version=9p2000.L" "cache=loose" ];
             neededForBoot = true;
           };
         "/tmp/shared" =
           { device = "shared";
             fsType = "9p";
-            options = "trans=virtio,version=9p2000.L";
+            options = [ "trans=virtio" "version=9p2000.L" ];
             neededForBoot = true;
           };
       } // optionalAttrs cfg.writableStore
       { "/nix/store" =
           { fsType = "unionfs-fuse";
             device = "unionfs";
-            options = "allow_other,cow,nonempty,chroot=/mnt-root,max_files=32768,hide_meta_files,dirs=/nix/.rw-store=rw:/nix/.ro-store=ro";
+            options = [ "allow_other" "cow" "nonempty" "chroot=/mnt-root" "max_files=32768" "hide_meta_files" "dirs=/nix/.rw-store=rw:/nix/.ro-store=ro" ];
           };
       } // optionalAttrs (cfg.writableStore && cfg.writableStoreUseTmpfs)
       { "/nix/.rw-store" =
           { fsType = "tmpfs";
-            options = "mode=0755";
+            options = [ "mode=0755" ];
             neededForBoot = true;
           };
       } // optionalAttrs cfg.useBootLoader
       { "/boot" =
           { device = "/dev/vdb2";
             fsType = "vfat";
-            options = "ro";
+            options = [ "ro" ];
             noCheck = true; # fsck fails on a r/o filesystem
           };
       });
diff --git a/nixos/release.nix b/nixos/release.nix
index 9c15b1ea0746..d9f3e46b27c0 100644
--- a/nixos/release.nix
+++ b/nixos/release.nix
@@ -248,6 +248,7 @@ in rec {
   tests.ipv6 = callTest tests/ipv6.nix {};
   tests.jenkins = callTest tests/jenkins.nix {};
   tests.kde4 = callTest tests/kde4.nix {};
+  tests.initrdNetwork = callTest tests/initrd-network.nix {};
   tests.kubernetes = hydraJob (import tests/kubernetes.nix { system = "x86_64-linux"; });
   tests.latestKernel.login = callTest tests/login.nix { latestKernel = true; };
   #tests.lightdm = callTest tests/lightdm.nix {};
diff --git a/nixos/tests/chromium.nix b/nixos/tests/chromium.nix
index 1d1e12d0ee39..6c61087760dd 100644
--- a/nixos/tests/chromium.nix
+++ b/nixos/tests/chromium.nix
@@ -2,8 +2,8 @@ import ./make-test.nix (
 { pkgs
 , channelMap ? {
     stable = pkgs.chromium;
-    beta   = pkgs.chromiumBeta;
-    dev    = pkgs.chromiumDev;
+    #beta   = pkgs.chromiumBeta;
+    #dev    = pkgs.chromiumDev;
   }
 , ...
 }: rec {
diff --git a/nixos/tests/ec2.nix b/nixos/tests/ec2.nix
index 1925ab37419a..0a95d6cfeff4 100644
--- a/nixos/tests/ec2.nix
+++ b/nixos/tests/ec2.nix
@@ -10,9 +10,10 @@ let
       inherit system;
       modules = [
         ../maintainers/scripts/ec2/amazon-image.nix
-        ../../nixos/modules/testing/test-instrumentation.nix
-        { boot.initrd.kernelModules = [ "virtio" "virtio_blk" "virtio_pci" "virtio_ring" ];
-          ec2.hvm = true;
+        ../modules/testing/test-instrumentation.nix
+        ../modules/profiles/minimal.nix
+        ../modules/profiles/qemu-guest.nix
+        { ec2.hvm = true;
 
           # Hack to make the partition resizing work in QEMU.
           boot.initrd.postDeviceCommands = mkBefore
@@ -33,6 +34,7 @@ let
           ln -s ${pkgs.writeText "userData" userData} $out/2011-01-01/user-data
           mkdir -p $out/1.0/meta-data
           echo "${hostname}" > $out/1.0/meta-data/hostname
+          echo "(unknown)" > $out/1.0/meta-data/ami-manifest-path
         '' + optionalString (sshPublicKey != null) ''
           mkdir -p $out/1.0/meta-data/public-keys/0
           ln -s ${pkgs.writeText "sshPublicKey" sshPublicKey} $out/1.0/meta-data/public-keys/0/openssh-key
@@ -56,7 +58,7 @@ let
           # again when it deletes link-local addresses.) Ideally we'd
           # turn off the DHCP server, but qemu does not have an option
           # to do that.
-          my $startCommand = "qemu-kvm -m 768 -net nic -net 'user,net=169.0.0.0/8,guestfwd=tcp:169.254.169.254:80-cmd:${pkgs.micro-httpd}/bin/micro_httpd ${metaData}'";
+          my $startCommand = "qemu-kvm -m 768 -net nic,vlan=0,model=virtio -net 'user,vlan=0,net=169.0.0.0/8,guestfwd=tcp:169.254.169.254:80-cmd:${pkgs.micro-httpd}/bin/micro_httpd ${metaData}'";
           $startCommand .= " -drive file=$diskImage,if=virtio,werror=report";
           $startCommand .= " \$QEMU_OPTS";
 
@@ -92,6 +94,8 @@ in {
       $machine->waitForFile("/root/user-data");
       $machine->waitForUnit("sshd.service");
 
+      $machine->succeed("grep unknown /etc/ec2-metadata/ami-manifest-path");
+
       # We have no keys configured on the client side yet, so this should fail
       $machine->fail("ssh -o BatchMode=yes localhost exit");
 
diff --git a/nixos/tests/haka.nix b/nixos/tests/haka.nix
new file mode 100644
index 000000000000..40548f34690f
--- /dev/null
+++ b/nixos/tests/haka.nix
@@ -0,0 +1,24 @@
+# This test runs haka and probes it with hakactl
+
+import ./make-test.nix ({ pkgs, ...} : {
+  name = "haka";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ tvestelind ];
+  };
+
+  nodes = {
+    haka =
+      { config, pkgs, ... }:
+        {
+          services.haka.enable = true;
+        };
+    };
+
+  testScript = ''
+    startAll;
+
+    $haka->waitForUnit("haka.service");
+    $haka->succeed("hakactl status");
+    $haka->succeed("hakactl stop");
+  '';
+})
diff --git a/nixos/tests/initrd-network.nix b/nixos/tests/initrd-network.nix
new file mode 100644
index 000000000000..db9f572d3c2f
--- /dev/null
+++ b/nixos/tests/initrd-network.nix
@@ -0,0 +1,22 @@
+import ./make-test.nix ({ pkgs, ...} : {
+  name = "initrd-network";
+
+  meta.maintainers = [ pkgs.stdenv.lib.maintainers.eelco ];
+
+  machine = { config, pkgs, ... }: {
+    imports = [ ../modules/profiles/minimal.nix ];
+    boot.initrd.network.enable = true;
+    boot.initrd.network.postCommands =
+      ''
+        ip addr | grep 10.0.2.15 || exit 1
+        ping -c1 10.0.2.2 || exit 1
+      '';
+  };
+
+  testScript =
+    ''
+      startAll;
+      $machine->waitForUnit("multi-user.target");
+      $machine->succeed("ip link >&2");
+    '';
+})
diff --git a/nixos/tests/misc.nix b/nixos/tests/misc.nix
index 6297452df95e..73af0cfad21f 100644
--- a/nixos/tests/misc.nix
+++ b/nixos/tests/misc.nix
@@ -16,7 +16,7 @@ import ./make-test.nix ({ pkgs, ...} : {
       systemd.tmpfiles.rules = [ "d /tmp 1777 root root 10d" ];
       fileSystems = mkVMOverride { "/tmp2" =
         { fsType = "tmpfs";
-          options = "mode=1777,noauto";
+          options = [ "mode=1777" "noauto" ];
         };
       };
       systemd.automounts = singleton
diff --git a/nixos/tests/nfs.nix b/nixos/tests/nfs.nix
index 24f6e0f2ed95..36cd6a395779 100644
--- a/nixos/tests/nfs.nix
+++ b/nixos/tests/nfs.nix
@@ -8,7 +8,7 @@ let
         [ { mountPoint = "/data";
             device = "server:/data";
             fsType = "nfs";
-            options = "vers=${toString version}";
+            options = [ "vers=${toString version}" ];
           }
         ];
       networking.firewall.enable = false; # FIXME: only open statd
diff --git a/nixos/tests/simple.nix b/nixos/tests/simple.nix
index 287712be316d..04d624adcfe9 100644
--- a/nixos/tests/simple.nix
+++ b/nixos/tests/simple.nix
@@ -4,7 +4,9 @@ import ./make-test.nix ({ pkgs, ...} : {
     maintainers = [ eelco ];
   };
 
-  machine = { config, pkgs, ... }: { };
+  machine = { config, pkgs, ... }: {
+    imports = [ ../modules/profiles/minimal.nix ];
+  };
 
   testScript =
     ''