about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorVladimír Čunát <vcunat@gmail.com>2016-02-17 10:06:31 +0100
committerVladimír Čunát <vcunat@gmail.com>2016-02-17 10:06:31 +0100
commite9520e81b375fca8bcf06b3f4c2dd3bb0b757be6 (patch)
tree7da1bda216c30520d864a266735c48988c2b2369 /nixos
parentee994dfae6e897ee4e7405e1624be43625086622 (diff)
parent2f3eae3a87eb4f9e330ac2c31611061c1ae8699f (diff)
downloadnixlib-e9520e81b375fca8bcf06b3f4c2dd3bb0b757be6.tar
nixlib-e9520e81b375fca8bcf06b3f4c2dd3bb0b757be6.tar.gz
nixlib-e9520e81b375fca8bcf06b3f4c2dd3bb0b757be6.tar.bz2
nixlib-e9520e81b375fca8bcf06b3f4c2dd3bb0b757be6.tar.lz
nixlib-e9520e81b375fca8bcf06b3f4c2dd3bb0b757be6.tar.xz
nixlib-e9520e81b375fca8bcf06b3f4c2dd3bb0b757be6.tar.zst
nixlib-e9520e81b375fca8bcf06b3f4c2dd3bb0b757be6.zip
Merge branch 'master' into staging
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/release-notes/rl-unstable.xml1
-rw-r--r--nixos/modules/hardware/all-firmware.nix2
-rw-r--r--nixos/modules/hardware/network/intel-2200bg.nix2
-rw-r--r--nixos/modules/hardware/video/webcam/facetimehd.nix45
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix2
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image.nix10
-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-install.sh5
-rw-r--r--nixos/modules/misc/ids.nix5
-rw-r--r--nixos/modules/module-list.nix4
-rw-r--r--nixos/modules/security/acme.nix4
-rw-r--r--nixos/modules/services/databases/postgresql.nix38
-rw-r--r--nixos/modules/services/hardware/bluetooth.nix60
-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.nix11
-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/cfdyndns.nix70
-rw-r--r--nixos/modules/services/misc/gammu-smsd.nix253
-rw-r--r--nixos/modules/services/misc/gitit.nix1
-rw-r--r--nixos/modules/services/networking/i2pd.nix300
-rw-r--r--nixos/modules/services/networking/pdnsd.nix93
-rw-r--r--nixos/modules/services/networking/tinc.nix12
-rw-r--r--nixos/modules/services/networking/unbound.nix44
-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/web-servers/apache-httpd/mediawiki.nix4
-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/boot/kernel.nix3
-rw-r--r--nixos/modules/system/boot/loader/init-script/init-script-builder.sh9
-rw-r--r--nixos/modules/tasks/kbd.nix51
-rw-r--r--nixos/modules/tasks/network-interfaces-scripted.nix7
-rw-r--r--nixos/modules/virtualisation/azure-agent.nix9
-rw-r--r--nixos/modules/virtualisation/qemu-vm.nix1
-rw-r--r--nixos/tests/simple.nix4
40 files changed, 893 insertions, 346 deletions
diff --git a/nixos/doc/manual/release-notes/rl-unstable.xml b/nixos/doc/manual/release-notes/rl-unstable.xml
index 768b51d84a46..c2d1563e0a5d 100644
--- a/nixos/doc/manual/release-notes/rl-unstable.xml
+++ b/nixos/doc/manual/release-notes/rl-unstable.xml
@@ -41,6 +41,7 @@ nixos.path = ./nixpkgs-unstable-2015-12-06/nixos;
 
   <itemizedlist>
     <listitem><para><literal>services/monitoring/longview.nix</literal></para></listitem>
+    <listitem><para><literal>services/networking/pdnsd.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>
diff --git a/nixos/modules/hardware/all-firmware.nix b/nixos/modules/hardware/all-firmware.nix
index 1a04baef1930..d0d481f72a40 100644
--- a/nixos/modules/hardware/all-firmware.nix
+++ b/nixos/modules/hardware/all-firmware.nix
@@ -22,7 +22,7 @@ with lib;
   ###### implementation
 
   config = mkIf config.hardware.enableAllFirmware {
-    hardware.firmware = [ pkgs.firmwareLinuxNonfree ];
+    hardware.firmware = [ pkgs.firmwareLinuxNonfree pkgs.intel2200BGFirmware ];
   };
 
 }
diff --git a/nixos/modules/hardware/network/intel-2200bg.nix b/nixos/modules/hardware/network/intel-2200bg.nix
index 1b70057d135b..17b973474c93 100644
--- a/nixos/modules/hardware/network/intel-2200bg.nix
+++ b/nixos/modules/hardware/network/intel-2200bg.nix
@@ -23,7 +23,7 @@
 
   config = lib.mkIf config.networking.enableIntel2200BGFirmware {
 
-    hardware.enableAllFirmware = true;
+    hardware.firmware = [ pkgs.intel2200BGFirmware ];
 
   };
 
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/sd-image-armv7l-multiplatform.nix b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
index 15e22fb50d48..957a8ff9ce6d 100644
--- a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
@@ -23,7 +23,7 @@ in
   boot.loader.generic-extlinux-compatible.enable = true;
 
   boot.kernelPackages = pkgs.linuxPackages_latest;
-  boot.kernelParams = ["console=ttyS0,115200n8" "console=ttyAMA0,115200n8" "console=tty0"];
+  boot.kernelParams = ["console=ttyS0,115200n8" "console=ttymxc0,115200n8" "console=ttyAMA0,115200n8" "console=tty0"];
 
   # FIXME: this probably should be in installation-device.nix
   users.extraUsers.root.initialHashedPassword = "";
diff --git a/nixos/modules/installer/cd-dvd/sd-image.nix b/nixos/modules/installer/cd-dvd/sd-image.nix
index 12b4f3045614..9eba542d8c91 100644
--- a/nixos/modules/installer/cd-dvd/sd-image.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image.nix
@@ -30,7 +30,7 @@ in
 
     bootSize = mkOption {
       type = types.int;
-      default = 128;
+      default = 120;
       description = ''
         Size of the /boot partition, in megabytes.
       '';
@@ -66,10 +66,10 @@ in
       buildInputs = with pkgs; [ dosfstools e2fsprogs mtools libfaketime utillinux ];
 
       buildCommand = ''
-        # Create the image file sized to fit /boot and /, plus 4M of slack
+        # Create the image file sized to fit /boot and /, plus 20M of slack
         rootSizeBlocks=$(du -B 512 --apparent-size ${rootfsImage} | awk '{ print $1 }')
         bootSizeBlocks=$((${toString config.sdImage.bootSize} * 1024 * 1024 / 512))
-        imageSize=$((rootSizeBlocks * 512 + bootSizeBlocks * 512 + 4096 * 1024))
+        imageSize=$((rootSizeBlocks * 512 + bootSizeBlocks * 512 + 20 * 1024 * 1024))
         truncate -s $imageSize $out
 
         # type=b is 'W95 FAT32', type=83 is 'Linux'.
@@ -77,8 +77,8 @@ in
             label: dos
             label-id: 0x2178694e
 
-            start=1M, size=$bootSizeBlocks, type=b, bootable
-            type=83
+            start=8M, size=$bootSizeBlocks, type=b, bootable
+            start=${toString (8 + config.sdImage.bootSize)}M, type=83
         EOF
 
         # Copy the rootfs into the SD image
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-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/misc/ids.nix b/nixos/modules/misc/ids.nix
index 064b4cbc4b33..19da804c13f3 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -248,6 +248,9 @@
       matrix-synapse = 224;
       rspamd = 225;
       rmilter = 226;
+      cfdyndns = 227;
+      gammu-smsd = 228;
+      pdnsd = 229;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
@@ -473,6 +476,8 @@
       matrix-synapse = 224;
       rspamd = 225;
       rmilter = 226;
+      cfdyndns = 227;
+      pdnsd = 229;
 
       # When adding a gid, make sure it doesn't match an existing
       # uid. Users and groups with the same name should have equal
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index f0b90d3d8c80..8254cdd6f5eb 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
@@ -200,6 +201,7 @@
   ./services/misc/bepasty.nix
   ./services/misc/canto-daemon.nix
   ./services/misc/calibre-server.nix
+  ./services/misc/cfdyndns.nix
   ./services/misc/cpuminer-cryptonight.nix
   ./services/misc/cgminer.nix
   ./services/misc/confd.nix
@@ -210,6 +212,7 @@
   ./services/misc/etcd.nix
   ./services/misc/felix.nix
   ./services/misc/folding-at-home.nix
+  ./services/misc/gammu-smsd.nix
   #./services/misc/gitit.nix
   ./services/misc/gitlab.nix
   ./services/misc/gitolite.nix
@@ -339,6 +342,7 @@
   ./services/networking/openntpd.nix
   ./services/networking/openvpn.nix
   ./services/networking/ostinato.nix
+  ./services/networking/pdnsd.nix
   ./services/networking/polipo.nix
   ./services/networking/prayer.nix
   ./services/networking/privoxy.nix
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/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/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..46e6f216b21e 100644
--- a/nixos/modules/services/mail/dspam.nix
+++ b/nixos/modules/services/mail/dspam.nix
@@ -19,7 +19,10 @@ let
     SystemLog on
     UserLog on
 
-    ${optionalString (cfg.domainSocket != null) ''ServerDomainSocketPath "${cfg.domainSocket}"''}
+    ${optionalString (cfg.domainSocket != null) ''
+      ServerDomainSocketPath "${cfg.domainSocket}"
+      ClientHost "${cfg.domainSocket}"
+    ''}
 
     ${cfg.extraConfig}
   '';
@@ -108,7 +111,11 @@ in {
           User = cfg.user;
           Group = cfg.group;
           RuntimeDirectory = optional (cfg.domainSocket == defaultSock) "dspam";
+          RuntimeDirectoryMode = optional (cfg.domainSocket == defaultSock) "0750";
           PermissionsStartOnly = true;
+          # DSPAM segfaults on just about every error
+          Restart = "on-failure";
+          RestartSec = "1s";
         };
 
         preStart = ''
@@ -136,7 +143,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/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/cfdyndns.nix b/nixos/modules/services/misc/cfdyndns.nix
new file mode 100644
index 000000000000..69a33d0b8c1b
--- /dev/null
+++ b/nixos/modules/services/misc/cfdyndns.nix
@@ -0,0 +1,70 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.services.cfdyndns;
+in
+{
+  options = {
+    services.cfdyndns = {
+      enable = mkEnableOption "Cloudflare Dynamic DNS Client";
+
+      email = mkOption {
+        type = types.str;
+        description = ''
+          The email address to use to authenticate to CloudFlare.
+        '';
+      };
+
+      apikey = mkOption {
+        type = types.str;
+        description = ''
+          The API Key to use to authenticate to CloudFlare.
+        '';
+      };
+
+      records = mkOption {
+        default = [];
+        example = [ "host.tld" ];
+        type = types.listOf types.str;
+        description = ''
+          The records to update in CloudFlare.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.cfdyndns = {
+      description = "CloudFlare Dynamic DNS Client";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      startAt = "5 minutes";
+      serviceConfig = {
+        Type = "simple";
+        User = config.ids.uids.cfdyndns;
+        Group = config.ids.gids.cfdyndns;
+        ExecStart = "/bin/sh -c '${pkgs.cfdyndns}/bin/cfdyndns'";
+      };
+      environment = {
+        CLOUDFLARE_EMAIL="${cfg.email}";
+        CLOUDFLARE_APIKEY="${cfg.apikey}";
+        CLOUDFLARE_RECORDS="${concatStringsSep "," cfg.records}";
+      };
+    };
+
+    users.extraUsers = {
+      cfdyndns = {
+        group = "cfdyndns";
+        uid = config.ids.uids.cfdyndns;
+      };
+    };
+
+    users.extraGroups = {
+      cfdyndns = {
+        gid = config.ids.gids.cfdyndns;
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/misc/gammu-smsd.nix b/nixos/modules/services/misc/gammu-smsd.nix
new file mode 100644
index 000000000000..91047ead4364
--- /dev/null
+++ b/nixos/modules/services/misc/gammu-smsd.nix
@@ -0,0 +1,253 @@
+{ pkgs, lib, config, ... }:
+
+with lib;
+let
+  cfg = config.services.gammu-smsd;
+
+  configFile = pkgs.writeText "gammu-smsd.conf" ''
+    [gammu]
+    Device = ${cfg.device.path}
+    Connection = ${cfg.device.connection}
+    SynchronizeTime = ${if cfg.device.synchronizeTime then "yes" else "no"}
+    LogFormat = ${cfg.log.format}
+    ${if (cfg.device.pin != null) then "PIN = ${cfg.device.pin}" else ""}
+    ${cfg.extraConfig.gammu}
+
+
+    [smsd]
+    LogFile = ${cfg.log.file}
+    Service = ${cfg.backend.service}
+
+    ${optionalString (cfg.backend.service == "files") ''
+      InboxPath = ${cfg.backend.files.inboxPath}
+      OutboxPath = ${cfg.backend.files.outboxPath}
+      SentSMSPath = ${cfg.backend.files.sentSMSPath}
+      ErrorSMSPath = ${cfg.backend.files.errorSMSPath}
+    ''}
+
+    ${optionalString (cfg.backend.service == "sql" && cfg.backend.sql.driver == "sqlite") ''
+      Driver = ${cfg.backend.sql.driver}
+      DBDir = ${cfg.backend.sql.database}
+    ''}
+
+    ${optionalString (cfg.backend.service == "sql" && cfg.backend.sql.driver == "native_pgsql") (
+      with cfg.backend; ''
+        Driver = ${sql.driver}
+        ${if (sql.database!= null) then "Database = ${sql.database}" else ""}
+        ${if (sql.host != null) then "Host = ${sql.host}" else ""}
+        ${if (sql.user != null) then "User = ${sql.user}" else ""}
+        ${if (sql.password != null) then "Password = ${sql.password}" else ""}
+      '')}
+
+    ${cfg.extraConfig.smsd}
+  '';
+
+  initDBDir = "share/doc/gammu/examples/sql";
+
+  gammuPackage = with cfg.backend; (pkgs.gammu.override {
+    dbiSupport = (service == "sql" && sql.driver == "sqlite");
+    postgresSupport = (service == "sql" && sql.driver == "native_pgsql");
+  });
+
+in {
+  options = {
+    services.gammu-smsd = {
+
+      enable = mkEnableOption "gammu-smsd daemon";
+
+      user = mkOption {
+        type = types.str;
+        default = "smsd";
+        description = "User that has access to the device";
+      };
+
+      device = {
+        path = mkOption {
+          type = types.path;
+          description = "Device node or address of the phone";
+          example = "/dev/ttyUSB2";
+        };
+
+        group = mkOption {
+          type = types.str;
+          default = "root";
+          description = "Owner group of the device";
+          example = "dialout";
+        };
+
+        connection = mkOption {
+          type = types.str;
+          default = "at";
+          description = "Protocol which will be used to talk to the phone";
+        };
+
+        synchronizeTime = mkOption {
+          type = types.bool;
+          default = true;
+          description = "Whether to set time from computer to the phone during starting connection";
+        };
+
+        pin = mkOption {
+          type = types.nullOr types.str;
+          default = null;
+          description = "PIN code for the simcard";
+        };
+      };
+
+
+      log = {
+        file = mkOption {
+          type = types.str;
+          default = "syslog";
+          description = "Path to file where information about communication will be stored";
+        };
+
+        format = mkOption {
+          type = types.enum [ "nothing" "text" "textall" "textalldate" "errors" "errorsdate" "binary" ];
+          default = "errors";
+          description = "Determines what will be logged to the LogFile";
+        };
+      };
+
+
+      extraConfig = {
+        gammu = mkOption {
+          type = types.lines;
+          default = "";
+          description = "Extra config lines to be added into [gammu] section";
+        };
+
+
+        smsd = mkOption {
+          type = types.lines;
+          default = "";
+          description = "Extra config lines to be added into [smsd] section";
+        };
+      };
+
+
+      backend = {
+        service = mkOption {
+          type = types.enum [ "null" "files" "sql" ];
+          default = "null";
+          description = "Service to use to store sms data.";
+        };
+
+        files = {
+          inboxPath = mkOption {
+            type = types.path;
+            default = "/var/spool/sms/inbox/";
+            description = "Where the received SMSes are stored";
+          };
+
+          outboxPath = mkOption {
+            type = types.path;
+            default = "/var/spool/sms/outbox/";
+            description = "Where SMSes to be sent should be placed";
+          };
+
+          sentSMSPath = mkOption {
+            type = types.path;
+            default = "/var/spool/sms/sent/";
+            description = "Where the transmitted SMSes are placed";
+          };
+
+          errorSMSPath = mkOption {
+            type = types.path;
+            default = "/var/spool/sms/error/";
+            description = "Where SMSes with error in transmission is placed";
+          };
+        };
+
+        sql = {
+          driver = mkOption {
+            type = types.enum [ "native_mysql" "native_pgsql" "odbc" "dbi" ];
+            description = "DB driver to use";
+          };
+
+          sqlDialect = mkOption {
+            type = types.nullOr types.str;
+            default = null;
+            description = "SQL dialect to use (odbc driver only)";
+          };
+
+          database = mkOption {
+            type = types.str;
+            default = null;
+            description = "Database name to store sms data";
+          };
+
+          host = mkOption {
+            type = types.str;
+            default = "localhost";
+            description = "Database server address";
+          };
+
+          user = mkOption {
+            type = types.nullOr types.str;
+            default = null;
+            description = "User name used for connection to the database";
+          };
+
+          password = mkOption {
+            type = types.nullOr types.str;
+            default = null;
+            description = "User password used for connetion to the database";
+          };
+        };
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    users.extraUsers.${cfg.user} = {
+      description = "gammu-smsd user";
+      uid = config.ids.uids.gammu-smsd;
+      extraGroups = [ "${cfg.device.group}" ];
+    };
+
+    environment.systemPackages = with cfg.backend; [ gammuPackage ]
+    ++ optionals (service == "sql" && sql.driver == "sqlite")  [ pkgs.sqlite ];
+
+    systemd.services.gammu-smsd = {
+      description = "gammu-smsd daemon";
+
+      wantedBy = [ "multi-user.target" ];
+
+      wants = with cfg.backend; [ ]
+      ++ optionals (service == "sql" && sql.driver == "native_pgsql") [ "postgresql.service" ];
+
+      preStart = with cfg.backend;
+
+        optionalString (service == "files") (with files; ''
+          mkdir -m 755 -p ${inboxPath} ${outboxPath} ${sentSMSPath} ${errorSMSPath}
+          chown ${cfg.user} -R ${inboxPath}
+          chown ${cfg.user} -R ${outboxPath}
+          chown ${cfg.user} -R ${sentSMSPath}
+          chown ${cfg.user} -R ${errorSMSPath}
+        '')
+      + optionalString (service == "sql" && sql.driver == "sqlite") ''
+         cat "${gammuPackage}/${initDBDir}/sqlite.sql" \
+         | ${pkgs.sqlite}/bin/sqlite3 ${sql.database}
+        ''
+      + (let execPsql = extraArgs: concatStringsSep " " [
+          (optionalString (sql.password != null) "PGPASSWORD=${sql.password}")
+          "${config.services.postgresql.package}/bin/psql"
+          (optionalString (sql.host != null) "-h ${sql.host}")
+          (optionalString (sql.user != null) "-U ${sql.user}")
+          "$extraArgs"
+          "${sql.database}"
+        ]; in optionalString (service == "sql" && sql.driver == "native_pgsql") ''
+         echo '\i '"${gammuPackage}/${initDBDir}/pgsql.sql" | ${execPsql ""}
+       '');
+
+      serviceConfig = {
+        User = "${cfg.user}";
+        Group = "${cfg.device.group}";
+        PermissionsStartOnly = true;
+        ExecStart = "${gammuPackage}/bin/gammu-smsd -c ${configFile}";
+      };
+
+    };
+  };
+}
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/networking/i2pd.nix b/nixos/modules/services/networking/i2pd.nix
index af9424ecfeaf..e73316a9b1e8 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/pdnsd.nix b/nixos/modules/services/networking/pdnsd.nix
new file mode 100644
index 000000000000..f4467b818958
--- /dev/null
+++ b/nixos/modules/services/networking/pdnsd.nix
@@ -0,0 +1,93 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.services.pdnsd;
+  pdnsd = pkgs.pdnsd;
+  pdnsdUser = "pdnsd";
+  pdnsdGroup = "pdnsd";
+  pdnsdConf = pkgs.writeText "pdnsd.conf"
+    ''
+      global {
+        run_as=${pdnsdUser};
+        cache_dir="${cfg.cacheDir}";
+        ${cfg.globalConfig}
+      }
+
+      server {
+        ${cfg.serverConfig}
+      }
+      ${cfg.extraConfig}
+    '';
+in
+
+{ options =
+    { services.pdnsd =
+        { enable = mkEnableOption "pdnsd";
+
+          cacheDir = mkOption {
+            type = types.str;
+            default = "/var/cache/pdnsd";
+            description = "Directory holding the pdnsd cache";
+          };
+
+          globalConfig = mkOption {
+            type = types.lines;
+            default = "";
+            description = ''
+              Global configuration that should be added to the global directory
+              of <literal>pdnsd.conf</literal>.
+            '';
+          };
+
+          serverConfig = mkOption {
+            type = types.lines;
+            default = "";
+            description = ''
+              Server configuration that should be added to the server directory
+              of <literal>pdnsd.conf</literal>.
+            '';
+          };
+
+          extraConfig = mkOption {
+            type = types.lines;
+            default = "";
+            description = ''
+              Extra configuration directives that should be added to
+              <literal>pdnsd.conf</literal>.
+            '';
+          };
+        };
+    };
+
+  config = mkIf cfg.enable {
+    users.extraUsers = singleton {
+      name = pdnsdUser;
+      uid = config.ids.uids.pdnsd;
+      group = pdnsdGroup;
+      description = "pdnsd user";
+    };
+
+    users.extraGroups = singleton {
+      name = pdnsdGroup;
+      gid = config.ids.gids.pdnsd;
+    };
+
+    systemd.services.pdnsd =
+      { wantedBy = [ "multi-user.target" ];
+        after = [ "network.target" ];
+        preStart =
+          ''
+            mkdir -p "${cfg.cacheDir}"
+            touch "${cfg.cacheDir}/pdnsd.cache"
+            chown -R ${pdnsdUser}:${pdnsdGroup} "${cfg.cacheDir}"
+          '';
+        description = "pdnsd";
+        serviceConfig =
+          {
+            ExecStart = "${pdnsd}/bin/pdnsd -c ${pdnsdConf}";
+          };
+      };
+  };
+}
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/unbound.nix b/nixos/modules/services/networking/unbound.nix
index 73b10c1d5611..e154aed0843a 100644
--- a/nixos/modules/services/networking/unbound.nix
+++ b/nixos/modules/services/networking/unbound.nix
@@ -16,6 +16,11 @@ let
     "forward-zone:\n  name: .\n" +
     concatMapStrings (x: "  forward-addr: ${x}\n") cfg.forwardAddresses;
 
+  rootTrustAnchorFile = "${stateDir}/root.key";
+
+  trustAnchor = optionalString cfg.enableRootTrustAnchor
+    "auto-trust-anchor-file: ${rootTrustAnchorFile}";
+
   confFile = pkgs.writeText "unbound.conf" ''
     server:
       directory: "${stateDir}"
@@ -24,6 +29,7 @@ let
       pidfile: ""
       ${interfaces}
       ${access}
+      ${trustAnchor}
     ${cfg.extraConfig}
     ${forward}
   '';
@@ -38,28 +44,39 @@ in
     services.unbound = {
 
       enable = mkOption {
-	default = false;
-	description = "Whether to enable the Unbound domain name server.";
+        default = false;
+        type = types.bool;
+        description = "Whether to enable the Unbound domain name server.";
       };
 
       allowedAccess = mkOption {
-	default = ["127.0.0.0/24"];
-	description = "What networks are allowed to use unbound as a resolver.";
+        default = ["127.0.0.0/24"];
+        type = types.listOf types.str;
+        description = "What networks are allowed to use unbound as a resolver.";
       };
 
       interfaces = mkOption {
-	default = [ "127.0.0.1" "::1" ];
-	description = "What addresses the server should listen on.";
+        default = [ "127.0.0.1" "::1" ];
+        type = types.listOf types.str;
+        description = "What addresses the server should listen on.";
       };
 
       forwardAddresses = mkOption {
-	default = [ ];
-	description = "What servers to forward queries to.";
+        default = [ ];
+        type = types.listOf types.str;
+        description = "What servers to forward queries to.";
+      };
+
+      enableRootTrustAnchor = mkOption {
+        default = true;
+        type = types.bool;
+        description = "Use and update root trust anchor for DNSSEC validation.";
       };
 
       extraConfig = mkOption {
-	default = "";
-	description = "Extra lines of unbound config.";
+        default = "";
+        type = types.str;
+        description = "Extra lines of unbound config.";
       };
 
     };
@@ -88,9 +105,10 @@ in
 
       preStart = ''
         mkdir -m 0755 -p ${stateDir}/dev/
-	cp ${confFile} ${stateDir}/unbound.conf
-	chown unbound ${stateDir}
-	touch ${stateDir}/dev/random
+        cp ${confFile} ${stateDir}/unbound.conf
+        ${pkgs.unbound}/bin/unbound-anchor -a ${rootTrustAnchorFile}
+        chown unbound ${stateDir} ${rootTrustAnchorFile}
+        touch ${stateDir}/dev/random
         ${pkgs.utillinux}/bin/mount --bind -n /dev/random ${stateDir}/dev/random
       '';
 
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 356cfd409ad4..31332489a784 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/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/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/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/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/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/virtualisation/azure-agent.nix b/nixos/modules/virtualisation/azure-agent.nix
index e657cc519396..4fbc8fd3511c 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/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix
index 6e0dc065387a..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"
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 =
     ''