summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/default.nix3
-rw-r--r--nixos/doc/manual/configuration/modularity.xml2
-rw-r--r--nixos/doc/manual/configuration/network-manager.xml6
-rw-r--r--nixos/doc/manual/configuration/x-windows.xml8
-rw-r--r--nixos/doc/manual/configuration/xfce.xml42
-rw-r--r--nixos/doc/manual/development/replace-modules.xml75
-rw-r--r--nixos/doc/manual/development/writing-modules.xml1
-rw-r--r--nixos/doc/manual/installation/changing-config.xml2
-rw-r--r--nixos/doc/manual/release-notes/release-notes.xml1
-rw-r--r--nixos/doc/manual/release-notes/rl-1703.xml30
-rw-r--r--nixos/doc/manual/release-notes/rl-1709.xml55
-rw-r--r--nixos/lib/make-disk-image.nix53
-rw-r--r--nixos/lib/test-driver/Machine.pm3
-rw-r--r--nixos/maintainers/scripts/ec2/amazon-image.nix23
-rwxr-xr-xnixos/maintainers/scripts/ec2/create-amis.sh2
-rw-r--r--nixos/maintainers/scripts/openstack/nova-image.nix24
-rw-r--r--nixos/modules/config/fonts/fontconfig-ultimate.nix100
-rw-r--r--nixos/modules/config/fonts/fontconfig.nix120
-rw-r--r--nixos/modules/config/networking.nix5
-rw-r--r--nixos/modules/config/pulseaudio.nix2
-rw-r--r--nixos/modules/config/update-users-groups.pl2
-rw-r--r--nixos/modules/hardware/cpu/amd-microcode.nix3
-rw-r--r--nixos/modules/hardware/cpu/intel-microcode.nix3
-rw-r--r--nixos/modules/hardware/mcelog.nix37
-rw-r--r--nixos/modules/hardware/sensor/iio.nix30
-rw-r--r--nixos/modules/hardware/usb-wwan.nix26
-rw-r--r--nixos/modules/hardware/video/bumblebee.nix4
-rw-r--r--nixos/modules/hardware/video/capture/mwprocapture.nix61
-rw-r--r--nixos/modules/hardware/video/nvidia.nix4
-rw-r--r--nixos/modules/i18n/input-method/ibus.nix2
-rw-r--r--nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix4
-rw-r--r--nixos/modules/installer/cd-dvd/iso-image.nix2
-rw-r--r--nixos/modules/installer/scan/detected.nix2
-rw-r--r--nixos/modules/installer/scan/not-detected.nix2
-rw-r--r--nixos/modules/installer/tools/nix-fallback-paths.nix6
-rw-r--r--nixos/modules/installer/tools/nixos-generate-config.pl2
-rw-r--r--nixos/modules/installer/tools/nixos-rebuild.sh30
-rw-r--r--nixos/modules/misc/ids.nix2
-rw-r--r--nixos/modules/misc/locate.nix4
-rw-r--r--nixos/modules/misc/version.nix7
-rw-r--r--nixos/modules/module-list.nix10
-rw-r--r--nixos/modules/profiles/graphical.nix6
-rw-r--r--nixos/modules/programs/mtr.nix27
-rw-r--r--nixos/modules/programs/wireshark.nix42
-rw-r--r--nixos/modules/rename.nix13
-rw-r--r--nixos/modules/security/acme.nix2
-rw-r--r--nixos/modules/security/dhparams.nix90
-rw-r--r--nixos/modules/security/grsecurity.xml6
-rw-r--r--nixos/modules/security/pam.nix8
-rw-r--r--nixos/modules/security/polkit.nix2
-rw-r--r--nixos/modules/security/wrappers/default.nix30
-rw-r--r--nixos/modules/services/audio/mpd.nix19
-rw-r--r--nixos/modules/services/cluster/kubernetes.nix1
-rw-r--r--nixos/modules/services/continuous-integration/buildbot/master.nix29
-rw-r--r--nixos/modules/services/continuous-integration/buildbot/worker.nix16
-rw-r--r--nixos/modules/services/continuous-integration/jenkins/job-builder.nix26
-rw-r--r--nixos/modules/services/databases/neo4j.nix11
-rw-r--r--nixos/modules/services/databases/openldap.nix8
-rw-r--r--nixos/modules/services/databases/stanchion.nix10
-rw-r--r--nixos/modules/services/hardware/bluetooth.nix49
-rw-r--r--nixos/modules/services/logging/fluentd.nix1
-rw-r--r--nixos/modules/services/logging/graylog.nix23
-rw-r--r--nixos/modules/services/logging/logcheck.nix4
-rw-r--r--nixos/modules/services/mail/mlmmj.nix2
-rw-r--r--nixos/modules/services/misc/apache-kafka.nix14
-rw-r--r--nixos/modules/services/misc/nix-daemon.nix45
-rw-r--r--nixos/modules/services/misc/nixos-manual.nix14
-rw-r--r--nixos/modules/services/misc/octoprint.nix2
-rw-r--r--nixos/modules/services/misc/ssm-agent.nix1
-rw-r--r--nixos/modules/services/misc/taskserver/default.nix135
-rw-r--r--nixos/modules/services/misc/taskserver/doc.xml6
-rw-r--r--nixos/modules/services/misc/taskserver/helper-tool.py43
-rw-r--r--nixos/modules/services/monitoring/das_watchdog.nix2
-rw-r--r--nixos/modules/services/monitoring/munin.nix1
-rw-r--r--nixos/modules/services/monitoring/prometheus/default.nix1
-rw-r--r--nixos/modules/services/monitoring/prometheus/fritzbox-exporter.nix76
-rw-r--r--nixos/modules/services/monitoring/vnstat.nix2
-rw-r--r--nixos/modules/services/network-filesystems/samba.nix33
-rw-r--r--nixos/modules/services/network-filesystems/tahoe.nix4
-rw-r--r--nixos/modules/services/networking/btsync.nix1
-rw-r--r--nixos/modules/services/networking/ddclient.nix20
-rw-r--r--nixos/modules/services/networking/dhcpcd.nix4
-rw-r--r--nixos/modules/services/networking/dhcpd.nix7
-rw-r--r--nixos/modules/services/networking/dnscrypt-proxy.nix271
-rw-r--r--nixos/modules/services/networking/dnscrypt-proxy.xml12
-rw-r--r--nixos/modules/services/networking/networkmanager.nix19
-rw-r--r--nixos/modules/services/networking/nftables.nix125
-rw-r--r--nixos/modules/services/networking/openntpd.nix9
-rw-r--r--nixos/modules/services/networking/prosody.nix3
-rw-r--r--nixos/modules/services/networking/searx.nix4
-rw-r--r--nixos/modules/services/networking/tinc.nix4
-rw-r--r--nixos/modules/services/networking/znc.nix2
-rw-r--r--nixos/modules/services/scheduling/fcron.nix50
-rw-r--r--nixos/modules/services/security/physlock.nix14
-rw-r--r--nixos/modules/services/system/dbus-session-local.conf.in5
-rw-r--r--nixos/modules/services/system/dbus-system-local.conf.in6
-rw-r--r--nixos/modules/services/system/dbus.nix30
-rw-r--r--nixos/modules/services/ttys/kmscon.nix2
-rw-r--r--nixos/modules/services/web-apps/mattermost.nix1
-rw-r--r--nixos/modules/services/web-apps/pump.io-configure.js23
-rw-r--r--nixos/modules/services/web-apps/pump.io.nix220
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/wordpress.nix20
-rw-r--r--nixos/modules/services/web-servers/jboss/default.nix2
-rw-r--r--nixos/modules/services/web-servers/nginx/default.nix10
-rw-r--r--nixos/modules/services/web-servers/phpfpm/default.nix66
-rw-r--r--nixos/modules/services/web-servers/zope2.nix2
-rw-r--r--nixos/modules/services/x11/desktop-managers/default.nix4
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde5.nix255
-rw-r--r--nixos/modules/services/x11/desktop-managers/lumina.nix4
-rw-r--r--nixos/modules/services/x11/desktop-managers/plasma5.nix236
-rw-r--r--nixos/modules/services/x11/desktop-managers/xfce.nix15
-rw-r--r--nixos/modules/services/x11/display-managers/lightdm.nix4
-rw-r--r--nixos/modules/services/x11/display-managers/xpra.nix249
-rw-r--r--nixos/modules/services/x11/window-managers/herbstluftwm.nix23
-rw-r--r--nixos/modules/services/x11/xserver.nix14
-rw-r--r--nixos/modules/system/activation/activation-script.nix5
-rw-r--r--nixos/modules/system/activation/switch-to-configuration.pl6
-rw-r--r--nixos/modules/system/boot/kernel.nix2
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix15
-rw-r--r--nixos/modules/system/boot/loader/grub/install-grub.pl14
-rw-r--r--nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py23
-rw-r--r--nixos/modules/system/boot/luksroot.nix4
-rw-r--r--nixos/modules/system/boot/systemd.nix3
-rw-r--r--nixos/modules/tasks/filesystems.nix2
-rw-r--r--nixos/modules/tasks/filesystems/f2fs.nix2
-rw-r--r--nixos/modules/tasks/filesystems/zfs.nix63
-rw-r--r--nixos/modules/tasks/network-interfaces-scripted.nix37
-rw-r--r--nixos/modules/tasks/network-interfaces-systemd.nix2
-rw-r--r--nixos/modules/tasks/network-interfaces.nix173
-rw-r--r--nixos/modules/virtualisation/amazon-init.nix5
-rw-r--r--nixos/modules/virtualisation/ec2-amis.nix4
-rw-r--r--nixos/modules/virtualisation/ecs-agent.nix1
-rw-r--r--nixos/modules/virtualisation/google-compute-image.nix2
-rw-r--r--nixos/modules/virtualisation/libvirtd.nix18
-rw-r--r--nixos/modules/virtualisation/lxc.nix1
-rw-r--r--nixos/modules/virtualisation/nova-config.nix57
-rw-r--r--nixos/modules/virtualisation/nova-image.nix65
-rw-r--r--nixos/modules/virtualisation/openstack/glance.nix2
-rw-r--r--nixos/modules/virtualisation/qemu-vm.nix20
-rw-r--r--nixos/modules/virtualisation/virtualbox-guest.nix43
-rw-r--r--nixos/modules/virtualisation/xen-dom0.nix66
-rw-r--r--nixos/modules/virtualisation/xen-domU.nix5
-rw-r--r--nixos/release-combined.nix6
-rw-r--r--nixos/release.nix7
-rw-r--r--nixos/tests/buildbot.nix46
-rw-r--r--nixos/tests/cjdns.nix12
-rw-r--r--nixos/tests/containers-bridge.nix2
-rw-r--r--nixos/tests/containers-extra_veth.nix2
-rw-r--r--nixos/tests/containers-ipv6.nix2
-rw-r--r--nixos/tests/ec2.nix21
-rw-r--r--nixos/tests/ipv6.nix12
-rw-r--r--nixos/tests/leaps.nix3
-rw-r--r--nixos/tests/networking.nix28
-rw-r--r--nixos/tests/pgjwt.nix42
-rw-r--r--nixos/tests/phabricator.nix2
-rw-r--r--nixos/tests/plasma5.nix (renamed from nixos/tests/kde5.nix)5
-rw-r--r--nixos/tests/pump.io.nix19
-rw-r--r--nixos/tests/samba.nix5
-rw-r--r--nixos/tests/taskserver.nix129
-rw-r--r--nixos/tests/trac.nix2
-rw-r--r--nixos/tests/wordpress.nix12
161 files changed, 3054 insertions, 1283 deletions
diff --git a/nixos/default.nix b/nixos/default.nix
index 5f3e2ae081cc..0e45a1cd75e2 100644
--- a/nixos/default.nix
+++ b/nixos/default.nix
@@ -37,7 +37,4 @@ in
   vm = vmConfig.system.build.vm;
 
   vmWithBootLoader = vmWithBootLoaderConfig.system.build.vm;
-
-  # The following are used by nixos-rebuild.
-  nixFallback = pkgs.nixUnstable.out;
 }
diff --git a/nixos/doc/manual/configuration/modularity.xml b/nixos/doc/manual/configuration/modularity.xml
index 30da064ac579..5420c7f88385 100644
--- a/nixos/doc/manual/configuration/modularity.xml
+++ b/nixos/doc/manual/configuration/modularity.xml
@@ -37,7 +37,7 @@ latter might look like this:
 
 { services.xserver.enable = true;
   services.xserver.displayManager.sddm.enable = true;
-  services.xserver.desktopManager.kde5.enable = true;
+  services.xserver.desktopManager.plasma5.enable = true;
 }
 </programlisting>
 
diff --git a/nixos/doc/manual/configuration/network-manager.xml b/nixos/doc/manual/configuration/network-manager.xml
index dafbcfcb1e5b..b4808e74ff9d 100644
--- a/nixos/doc/manual/configuration/network-manager.xml
+++ b/nixos/doc/manual/configuration/network-manager.xml
@@ -27,7 +27,11 @@ users.extraUsers.youruser.extraGroups = [ "networkmanager" ];
 <para>NetworkManager is controlled using either <command>nmcli</command> or
 <command>nmtui</command> (curses-based terminal user interface). See their
 manual pages for details on their usage. Some desktop environments (GNOME, KDE)
-have their own configuration tools for NetworkManager.</para>
+have their own configuration tools for NetworkManager. On XFCE, there is no
+configuration tool for NetworkManager by default: by adding
+<code>networkmanagerapplet</code> to the list of system packages, the graphical
+applet will be installed and will launch automatically when XFCE is starting
+(and will show in the status tray).</para>
 
 <note><para><code>networking.networkmanager</code> and
 <code>networking.wireless</code> (WPA Supplicant) cannot be enabled at the same
diff --git a/nixos/doc/manual/configuration/x-windows.xml b/nixos/doc/manual/configuration/x-windows.xml
index 93d10d19b208..4a73695e0942 100644
--- a/nixos/doc/manual/configuration/x-windows.xml
+++ b/nixos/doc/manual/configuration/x-windows.xml
@@ -25,19 +25,23 @@ Otherwise, you can only log into a plain undecorated
 <command>xterm</command> window.  Thus you should pick one or more of
 the following lines:
 <programlisting>
-services.xserver.desktopManager.kde5.enable = true;
+services.xserver.desktopManager.plasma5.enable = true;
 services.xserver.desktopManager.xfce.enable = true;
+services.xserver.desktopManager.gnome3.enable = true;
 services.xserver.windowManager.xmonad.enable = true;
 services.xserver.windowManager.twm.enable = true;
 services.xserver.windowManager.icewm.enable = true;
+services.xserver.windowManager.i3.enable = true;
 </programlisting>
 </para>
 
 <para>NixOS’s default <emphasis>display manager</emphasis> (the
 program that provides a graphical login prompt and manages the X
-server) is SLiM.  You can select KDE’s <command>sddm</command> instead:
+server) is SLiM. You can select an alternative one by picking one
+of the following lines:
 <programlisting>
 services.xserver.displayManager.sddm.enable = true;
+services.xserver.displayManager.lightdm.enable = true;
 </programlisting>
 </para>
 
diff --git a/nixos/doc/manual/configuration/xfce.xml b/nixos/doc/manual/configuration/xfce.xml
index af6278e9c920..21c7a85e19cc 100644
--- a/nixos/doc/manual/configuration/xfce.xml
+++ b/nixos/doc/manual/configuration/xfce.xml
@@ -9,10 +9,10 @@
     <para>
         To enable the Xfce Desktop Environment, set
         <programlisting>
-            services.xserver.desktopManager = {
-                xfce.enable = true;
-                default = "xfce";
-            };
+services.xserver.desktopManager = {
+    xfce.enable = true;
+    default = "xfce";
+};
         </programlisting>
     </para>
 
@@ -20,13 +20,13 @@
         Optionally, <emphasis>compton</emphasis>
         can be enabled for nice graphical effects, some example settings:
         <programlisting>
-            services.compton = {
-              enable          = true;
-              fade            = true;
-              inactiveOpacity = "0.9";
-              shadow          = true;
-              fadeDelta       = 4;
-            };
+services.compton = {
+  enable          = true;
+  fade            = true;
+  inactiveOpacity = "0.9";
+  shadow          = true;
+  fadeDelta       = 4;
+};
         </programlisting>
     </para>
 
@@ -34,16 +34,16 @@
         Some Xfce programs are not installed automatically.
         To install them manually (system wide), put them into your
         <literal>environment.systemPackages</literal>.
-	</para>
+    </para>
 
     <para>
-		NixOS’s default <emphasis>display manager</emphasis>is SLiM.
-		(DM is the program that provides a graphical login prompt
-		 and manages the X server.)
-	   	You can, for example, select KDE’s
+        NixOS’s default <emphasis>display manager</emphasis> is SLiM.
+        (DM is the program that provides a graphical login prompt
+         and manages the X server.)
+        You can, for example, select KDE’s
         <command>sddm</command> instead:
         <programlisting>
-            services.xserver.displayManager.sddm.enable = true;
+services.xserver.displayManager.sddm.enable = true;
         </programlisting>
     </para>
 
@@ -55,7 +55,7 @@
             <emphasis>Thunar</emphasis>
             volume support, put
             <programlisting>
-                services.xserver.desktopManager.xfce.enable = true;
+services.xserver.desktopManager.xfce.enable = true;
             </programlisting>
             into your <emphasis>configuration.nix</emphasis>.
         </para>
@@ -84,10 +84,10 @@
             Thunar and/or the desktop takes time to show up.
 
             Thunar will spit out this kind of message on start
-            (look at journalctl --user -b).
+            (look at <command>journalctl --user -b</command>).
 
             <programlisting>
-                Thunar:2410): GVFS-RemoteVolumeMonitor-WARNING **: remote volume monitor with dbus name org.gtk.Private.UDisks2VolumeMonitor is not supported
+Thunar:2410): GVFS-RemoteVolumeMonitor-WARNING **: remote volume monitor with dbus name org.gtk.Private.UDisks2VolumeMonitor is not supported
             </programlisting>
 
             This is caused by some needed GNOME services not running.
@@ -95,7 +95,7 @@
             the Advanced tab of the Session and Startup settings panel.
             Alternatively, you can run this command to do the same thing.
             <programlisting>
-                $ xfconf-query -c xfce4-session -p /compat/LaunchGNOME -s true
+$ xfconf-query -c xfce4-session -p /compat/LaunchGNOME -s true
             </programlisting>
             A log-out and re-log will be needed for this to take effect.
         </para>
diff --git a/nixos/doc/manual/development/replace-modules.xml b/nixos/doc/manual/development/replace-modules.xml
new file mode 100644
index 000000000000..cc0539ec5109
--- /dev/null
+++ b/nixos/doc/manual/development/replace-modules.xml
@@ -0,0 +1,75 @@
+<section xmlns="http://docbook.org/ns/docbook"
+        xmlns:xlink="http://www.w3.org/1999/xlink"
+        xmlns:xi="http://www.w3.org/2001/XInclude"
+        version="5.0"
+        xml:id="sec-replace-modules">
+
+<title>Replace Modules</title>
+
+<para>Modules that are imported can also be disabled.  The option
+  declarations and config implementation of a disabled module will be
+  ignored, allowing another to take it's place.  This can be used to
+  import a set of modules from another channel while keeping the rest
+  of the system on a stable release.</para>
+<para><literal>disabledModules</literal> is a top level attribute like
+  <literal>imports</literal>, <literal>options</literal> and
+  <literal>config</literal>.  It contains a list of modules that will
+  be disabled. This can either be the full path to the module or a
+  string with the filename relative to the modules path
+  (eg. &lt;nixpkgs/nixos/modules&gt; for nixos).
+  </para>
+
+<para>This example will replace the existing postgresql module with
+  the version defined in the nixos-unstable channel while keeping the
+  rest of the modules and packages from the original nixos channel.
+  This only overrides the module definition, this won't use postgresql
+  from nixos-unstable unless explicitly configured to do so.</para>
+
+<programlisting>
+{ config, lib, pkgs, ... }:
+
+{
+  disabledModules = [ "services/databases/postgresql.nix" ];
+
+  imports =
+    [ # Use postgresql service from nixos-unstable channel.
+      # sudo nix-channel --add http://nixos.org/channels/nixos-unstable nixos-unstable
+      &lt;nixos-unstable/nixos/modules/services/databases/postgresql.nix&gt;
+    ];
+
+  services.postgresql.enable = true;
+}
+</programlisting>
+
+<para>This example shows how to define a custom module as a
+  replacement for an existing module. Importing this module will
+  disable the original module without having to know it's
+  implementation details.</para>
+
+<programlisting>
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.programs.man;
+in
+
+{
+  disabledModules = [ "services/programs/man.nix" ];
+
+  options = {
+    programs.man.enable = mkOption {
+      type = types.bool;
+      default = true;
+      description = "Whether to enable manual pages.";
+    };
+  };
+
+  config = mkIf cfg.enabled {
+    warnings = [ "disabled manpages for production deployments." ];
+  };
+}
+</programlisting>
+
+</section>
diff --git a/nixos/doc/manual/development/writing-modules.xml b/nixos/doc/manual/development/writing-modules.xml
index ef6920160e6d..5bdcad5ceb57 100644
--- a/nixos/doc/manual/development/writing-modules.xml
+++ b/nixos/doc/manual/development/writing-modules.xml
@@ -179,5 +179,6 @@ in {
 <xi:include href="option-types.xml" />
 <xi:include href="option-def.xml" />
 <xi:include href="meta-attributes.xml" />
+<xi:include href="replace-modules.xml" />
 
 </chapter>
diff --git a/nixos/doc/manual/installation/changing-config.xml b/nixos/doc/manual/installation/changing-config.xml
index 43b591a1cae9..75df307a1b7c 100644
--- a/nixos/doc/manual/installation/changing-config.xml
+++ b/nixos/doc/manual/installation/changing-config.xml
@@ -7,7 +7,7 @@
 
 <para>The file <filename>/etc/nixos/configuration.nix</filename>
 contains the current configuration of your machine.  Whenever you’ve
-changed something to that file, you should do
+<link linkend="ch-configuration">changed something</link> in that file, you should do
 
 <screen>
 # nixos-rebuild switch</screen>
diff --git a/nixos/doc/manual/release-notes/release-notes.xml b/nixos/doc/manual/release-notes/release-notes.xml
index 20d3f74f94b4..6065a86f60d8 100644
--- a/nixos/doc/manual/release-notes/release-notes.xml
+++ b/nixos/doc/manual/release-notes/release-notes.xml
@@ -9,6 +9,7 @@
 <para>This section lists the release notes for each stable version of NixOS
 and current unstable revision.</para>
 
+<xi:include href="rl-1709.xml" />
 <xi:include href="rl-1703.xml" />
 <xi:include href="rl-1609.xml" />
 <xi:include href="rl-1603.xml" />
diff --git a/nixos/doc/manual/release-notes/rl-1703.xml b/nixos/doc/manual/release-notes/rl-1703.xml
index 8f9694bad8bd..fda46217144c 100644
--- a/nixos/doc/manual/release-notes/rl-1703.xml
+++ b/nixos/doc/manual/release-notes/rl-1703.xml
@@ -30,6 +30,14 @@ has the following highlights: </para>
   <listitem>
     <para>PHP now defaults to PHP 7.1</para>
   </listitem>
+
+  <listitem>
+    <para>Packages in nixpkgs can be marked as insecure through listed
+    vulnerabilities. See the <link
+    xlink:href="https://nixos.org/nixpkgs/manual/#sec-allow-insecure">Nixpkgs
+    manual</link> for more information.</para>
+  </listitem>
+
 </itemizedlist>
 
 <para>The following new services were added since the last release:</para>
@@ -217,6 +225,18 @@ following incompatible changes:</para>
     </para>
   </listitem>
 
+  <listitem>
+    <para>
+    Iputils no longer provide ping6 and traceroute6. The functionality of
+    these tools have been integrated into ping and traceroute respectively. To
+    enforce an address family the new flags <literal>-4</literal> and
+    <literal>-6</literal> have been added. One notable incompatibility is that
+    specifying an interface (for link-local IPv6 for instance) is no longer done
+    with the <literal>-I</literal> flag, but by encoding the interface into the
+    address (<literal>ping fe80::1%eth0</literal>).
+    </para>
+  </listitem>
+
 </itemizedlist>
 
 
@@ -241,6 +261,16 @@ following incompatible changes:</para>
     </para>
   </listitem>
 
+  <listitem>
+    <para>
+      Python 2.7, 3.5 and 3.6 are now built deterministically and 3.4 mostly.
+      Minor modifications had to be made to the interpreters in order to generate
+      deterministic bytecode. This has security implications and is relevant for
+      those using Python in a <literal>nix-shell</literal>. See the Nixpkgs manual
+      for details.
+    </para>
+  </listitem>
+
 </itemizedlist>
 
 
diff --git a/nixos/doc/manual/release-notes/rl-1709.xml b/nixos/doc/manual/release-notes/rl-1709.xml
new file mode 100644
index 000000000000..3705fd468f61
--- /dev/null
+++ b/nixos/doc/manual/release-notes/rl-1709.xml
@@ -0,0 +1,55 @@
+<section xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         version="5.0"
+         xml:id="sec-release-17.09">
+
+<title>Release 17.09 (“Hummingbird”, 2017/09/??)</title>
+
+<para>In addition to numerous new and upgraded packages, this release
+has the following highlights: </para>
+
+<itemizedlist>
+  <listitem>
+    <para></para>
+  </listitem>
+
+</itemizedlist>
+
+<para>The following new services were added since the last release:</para>
+
+<itemizedlist>
+  <listitem>
+    <para></para>
+  </listitem>
+</itemizedlist>
+
+
+<para>When upgrading from a previous release, please be aware of the
+following incompatible changes:</para>
+
+<itemizedlist>
+  <listitem>
+    <para>
+    </para>
+  </listitem>
+</itemizedlist>
+
+
+<para>Other notable improvements:</para>
+
+<itemizedlist>
+
+  <listitem>
+    <para>
+      Modules can now be disabled by using <link
+      xlink:href="https://nixos.org/nixpkgs/manual/#sec-replace-modules">
+      disabledModules</link>, allowing another to take it's place.  This can be
+      used to import a set of modules from another channel while keeping the
+      rest of the system on a stable release.
+    </para>
+  </listitem>
+
+</itemizedlist>
+
+</section>
diff --git a/nixos/lib/make-disk-image.nix b/nixos/lib/make-disk-image.nix
index e279803f2ea0..8c5de22f30ff 100644
--- a/nixos/lib/make-disk-image.nix
+++ b/nixos/lib/make-disk-image.nix
@@ -7,6 +7,12 @@
 , # The size of the disk, in megabytes.
   diskSize
 
+  # The files and directories to be placed in the target file system.
+  # This is a list of attribute sets {source, target} where `source'
+  # is the file system object (regular file or directory) to be
+  # grafted in the file system at path `target'.
+, contents ? []
+
 , # Whether the disk should be partitioned (with a single partition
   # containing the root filesystem) or contain the root filesystem
   # directly.
@@ -45,7 +51,14 @@ pkgs.vmTools.runInLinuxVM (
           ${pkgs.vmTools.qemu}/bin/qemu-img create -f ${format} $diskImage "${toString diskSize}M"
           mv closure xchg/
         '';
-      buildInputs = [ pkgs.utillinux pkgs.perl pkgs.e2fsprogs pkgs.parted ];
+      buildInputs = with pkgs; [ utillinux perl e2fsprogs parted rsync ];
+
+      # I'm preserving the line below because I'm going to search for it across nixpkgs to consolidate
+      # image building logic. The comment right below this now appears in 4 different places in nixpkgs :)
+      # !!! should use XML.
+      sources = map (x: x.source) contents;
+      targets = map (x: x.target) contents;
+
       exportReferencesGraph =
         [ "closure" config.system.build.toplevel ];
       inherit postVM;
@@ -98,11 +111,45 @@ pkgs.vmTools.runInLinuxVM (
       # Remove /etc/machine-id so that each machine cloning this image will get its own id
       rm -f /mnt/etc/machine-id
 
+      # Copy arbitrary other files into the image
+      # Semi-shamelessly copied from make-etc.sh. I (@copumpkin) shall factor this stuff out as part of
+      # https://github.com/NixOS/nixpkgs/issues/23052.
+      set -f
+      sources_=($sources)
+      targets_=($targets)
+      set +f
+
+      for ((i = 0; i < ''${#targets_[@]}; i++)); do
+        source="''${sources_[$i]}"
+        target="''${targets_[$i]}"
+
+        if [[ "$source" =~ '*' ]]; then
+
+          # If the source name contains '*', perform globbing.
+          mkdir -p /mnt/$target
+          for fn in $source; do
+            rsync -a --no-o --no-g "$fn" /mnt/$target/
+          done
+
+        else
+
+          mkdir -p /mnt/$(dirname $target)
+          if ! [ -e /mnt/$target ]; then
+            rsync -a --no-o --no-g $source /mnt/$target
+          else
+            echo "duplicate entry $target -> $source"
+            exit 1
+          fi
+        fi
+      done
+
       umount /mnt
 
-      # Make sure resize2fs works
+      # Make sure resize2fs works. Note that resize2fs has stricter criteria for resizing than a normal
+      # mount, so the `-c 0` and `-i 0` don't affect it. Setting it to `now` doesn't produce deterministic
+      # output, of course, but we can fix that when/if we start making images deterministic.
       ${optionalString (fsType == "ext4") ''
-        tune2fs -c 0 -i 0 $rootDisk
+        tune2fs -T now -c 0 -i 0 $rootDisk
       ''}
     ''
 )
diff --git a/nixos/lib/test-driver/Machine.pm b/nixos/lib/test-driver/Machine.pm
index 85bc376f67fa..30664406b26d 100644
--- a/nixos/lib/test-driver/Machine.pm
+++ b/nixos/lib/test-driver/Machine.pm
@@ -607,7 +607,8 @@ sub waitForWindow {
 sub copyFileFromHost {
     my ($self, $from, $to) = @_;
     my $s = `cat $from` or die;
-    $self->mustSucceed("echo '$s' > $to"); # !!! escaping
+    $s =~ s/'/'\\''/g;
+    $self->mustSucceed("echo '$s' > $to");
 }
 
 
diff --git a/nixos/maintainers/scripts/ec2/amazon-image.nix b/nixos/maintainers/scripts/ec2/amazon-image.nix
index bfa4f4b3ca59..b4190df8335b 100644
--- a/nixos/maintainers/scripts/ec2/amazon-image.nix
+++ b/nixos/maintainers/scripts/ec2/amazon-image.nix
@@ -2,15 +2,34 @@
 
 with lib;
 
-{
+let
+  cfg = config.amazonImage;
+in {
 
   imports =
     [ ../../../modules/installer/cd-dvd/channel.nix
       ../../../modules/virtualisation/amazon-image.nix
     ];
 
-  system.build.amazonImage = import ../../../lib/make-disk-image.nix {
+  options.amazonImage = {
+    contents = mkOption {
+      example = literalExample ''
+        [ { source = pkgs.memtest86 + "/memtest.bin";
+            target = "boot/memtest.bin";
+          }
+        ]
+      '';
+      default = [];
+      description = ''
+        This option lists files to be copied to fixed locations in the
+        generated image. Glob patterns work.
+      '';
+    };
+  };
+
+  config.system.build.amazonImage = import ../../../lib/make-disk-image.nix {
     inherit lib config;
+    inherit (cfg) contents;
     pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package
     partitioned = config.ec2.hvm;
     diskSize = if config.ec2.hvm then 2048 else 8192;
diff --git a/nixos/maintainers/scripts/ec2/create-amis.sh b/nixos/maintainers/scripts/ec2/create-amis.sh
index 7cceac8cbf5a..1e397b0f1761 100755
--- a/nixos/maintainers/scripts/ec2/create-amis.sh
+++ b/nixos/maintainers/scripts/ec2/create-amis.sh
@@ -19,7 +19,7 @@ rm -f ec2-amis.nix
 
 types="hvm pv"
 stores="ebs s3"
-regions="eu-west-1 eu-west-2 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1"
+regions="eu-west-1 eu-west-2 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ca-central-1 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1"
 
 for type in $types; do
     link=$stateDir/$type
diff --git a/nixos/maintainers/scripts/openstack/nova-image.nix b/nixos/maintainers/scripts/openstack/nova-image.nix
new file mode 100644
index 000000000000..fa9cfb74bd6c
--- /dev/null
+++ b/nixos/maintainers/scripts/openstack/nova-image.nix
@@ -0,0 +1,24 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  imports =
+    [ ../../../modules/installer/cd-dvd/channel.nix
+      ../../../modules/virtualisation/nova-config.nix
+    ];
+
+  system.build.novaImage = import ../../../lib/make-disk-image.nix {
+    inherit lib config;
+    pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package
+    diskSize = 8192;
+    format = "qcow2";
+    configFile = pkgs.writeText "configuration.nix"
+      ''
+        {
+          imports = [ <nixpkgs/nixos/modules/virtualisation/nova-config.nix> ];
+        }
+      '';
+  };
+
+}
diff --git a/nixos/modules/config/fonts/fontconfig-ultimate.nix b/nixos/modules/config/fonts/fontconfig-ultimate.nix
index a3f52fbd9199..ed6429dda085 100644
--- a/nixos/modules/config/fonts/fontconfig-ultimate.nix
+++ b/nixos/modules/config/fonts/fontconfig-ultimate.nix
@@ -8,61 +8,6 @@ let fcBool = x: if x then "<bool>true</bool>" else "<bool>false</bool>";
 
     latestVersion  = pkgs.fontconfig.configVersion;
 
-    # fontconfig ultimate main configuration file
-    # priority 52
-    fontconfigUltimateConf = pkgs.writeText "fc-52-fontconfig-ultimate.conf" ''
-      <?xml version="1.0"?>
-      <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
-      <fontconfig>
-
-        ${optionalString (!cfg.allowBitmaps) ''
-        <!-- Reject bitmap fonts -->
-        <selectfont>
-          <rejectfont>
-            <pattern>
-              <patelt name="scalable"><bool>false</bool></patelt>
-            </pattern>
-          </rejectfont>
-        </selectfont>
-        ''}
-
-        ${optionalString cfg.allowType1 ''
-        <!-- Reject Type 1 fonts -->
-        <selectfont>
-          <rejectfont>
-            <pattern>
-              <patelt name="fontformat">
-                <string>Type 1</string>
-              </patelt>
-            </pattern>
-          </rejectfont>
-        </selectfont>
-        ''}
-
-        <!-- Use embedded bitmaps in fonts like Calibri? -->
-        <match target="font">
-          <edit name="embeddedbitmap" mode="assign">
-            ${fcBool cfg.useEmbeddedBitmaps}
-          </edit>
-        </match>
-
-        <!-- Force autohint always -->
-        <match target="font">
-          <edit name="force_autohint" mode="assign">
-            ${fcBool cfg.forceAutohint}
-          </edit>
-        </match>
-
-        <!-- Render some monospace TTF fonts as bitmaps -->
-        <match target="pattern">
-          <edit name="bitmap_monospace" mode="assign">
-            ${fcBool cfg.renderMonoTTFAsBitmap}
-          </edit>
-        </match>
-
-      </fontconfig>
-    '';
-
     # The configuration to be included in /etc/font/
     confPkg = pkgs.runCommand "font-ultimate-conf" {} ''
       support_folder=$out/etc/fonts/conf.d
@@ -71,12 +16,6 @@ let fcBool = x: if x then "<bool>true</bool>" else "<bool>false</bool>";
       mkdir -p $support_folder
       mkdir -p $latest_folder
 
-      # 52-fontconfig-ultimate.conf
-      ln -s ${fontconfigUltimateConf} \
-            $support_folder/52-fontconfig-ultimate.conf
-      ln -s ${fontconfigUltimateConf} \
-            $latest_folder/52-fontconfig-ultimate.conf
-
       # fontconfig ultimate substitutions
       ${optionalString (cfg.substitutions != "none") ''
       ln -s ${pkgs.fontconfig-ultimate}/etc/fonts/presets/${cfg.substitutions}/*.conf \
@@ -113,45 +52,6 @@ in
             '';
           };
 
-          allowBitmaps = mkOption {
-            type = types.bool;
-            default = true;
-            description = ''
-              Allow bitmap fonts. Set to <literal>false</literal> to ban all
-              bitmap fonts.
-            '';
-          };
-
-          allowType1 = mkOption {
-            type = types.bool;
-            default = false;
-            description = ''
-              Allow Type-1 fonts. Default is <literal>false</literal> because of
-              poor rendering.
-            '';
-          };
-
-          useEmbeddedBitmaps = mkOption {
-            type = types.bool;
-            default = false;
-            description = ''Use embedded bitmaps in fonts like Calibri.'';
-          };
-
-          forceAutohint = mkOption {
-            type = types.bool;
-            default = false;
-            description = ''
-              Force use of the TrueType Autohinter. Useful for debugging or
-              free-software purists.
-            '';
-          };
-
-          renderMonoTTFAsBitmap = mkOption {
-            type = types.bool;
-            default = false;
-            description = ''Render some monospace TTF fonts as bitmaps.'';
-          };
-
           substitutions = mkOption {
             type = types.nullOr (types.enum ["free" "combi" "ms"]);
             default = "free";
diff --git a/nixos/modules/config/fonts/fontconfig.nix b/nixos/modules/config/fonts/fontconfig.nix
index 52ad1e714fb9..5648b7b1d027 100644
--- a/nixos/modules/config/fonts/fontconfig.nix
+++ b/nixos/modules/config/fonts/fontconfig.nix
@@ -41,11 +41,11 @@ let cfg = config.fonts.fontconfig;
     # priority 0
     cacheConfSupport = makeCacheConf { version = supportVersion; };
     cacheConfLatest  = makeCacheConf {};
-    
+
     # generate the font cache setting file for a fontconfig version
     # use latest when no version is passed
     makeCacheConf = { version ? null }:
-      let 
+      let
         fcPackage = if builtins.isNull version
                     then "fontconfig"
                     else "fontconfig_${version}";
@@ -104,6 +104,13 @@ let cfg = config.fonts.fontconfig;
         </match>
         ''}
 
+        <!-- Force autohint always -->
+        <match target="font">
+          <edit name="force_autohint" mode="assign">
+            ${fcBool cfg.forceAutohint}
+          </edit>
+        </match>
+
       </fontconfig>
     '';
 
@@ -113,7 +120,7 @@ let cfg = config.fonts.fontconfig;
 
     # default fonts configuration file
     # priority 52
-    defaultFontsConf = 
+    defaultFontsConf =
       let genDefault = fonts: name:
         optionalString (fonts != []) ''
           <alias>
@@ -142,7 +149,61 @@ let cfg = config.fonts.fontconfig;
       </fontconfig>
     '';
 
-    # fontconfig configuration package 
+    # bitmap font options
+    # priority 53
+    rejectBitmaps = pkgs.writeText "fc-53-nixos-bitmaps.conf" ''
+      <?xml version="1.0"?>
+      <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+      <fontconfig>
+
+      ${optionalString (!cfg.allowBitmaps) ''
+      <!-- Reject bitmap fonts -->
+      <selectfont>
+        <rejectfont>
+          <pattern>
+            <patelt name="scalable"><bool>false</bool></patelt>
+          </pattern>
+        </rejectfont>
+      </selectfont>
+      ''}
+
+      <!-- Use embedded bitmaps in fonts like Calibri? -->
+      <match target="font">
+        <edit name="embeddedbitmap" mode="assign">
+          ${fcBool cfg.useEmbeddedBitmaps}
+        </edit>
+      </match>
+
+      <!-- Render some monospace TTF fonts as bitmaps -->
+      <match target="pattern">
+        <edit name="bitmap_monospace" mode="assign">
+          ${fcBool cfg.renderMonoTTFAsBitmap}
+        </edit>
+      </match>
+
+      </fontconfig>
+    '';
+
+    # reject Type 1 fonts
+    # priority 53
+    rejectType1 = pkgs.writeText "fc-53-nixos-reject-type1.conf" ''
+      <?xml version="1.0"?>
+      <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+      <fontconfig>
+
+      <!-- Reject Type 1 fonts -->
+      <selectfont>
+        <rejectfont>
+          <pattern>
+            <patelt name="fontformat"><string>Type 1</string></patelt>
+          </pattern>
+        </rejectfont>
+      </selectfont>
+
+      </fontconfig>
+    '';
+
+    # fontconfig configuration package
     confPkg = pkgs.runCommand "fontconfig-conf" {} ''
       support_folder=$out/etc/fonts
       latest_folder=$out/etc/fonts/${latestVersion}
@@ -166,7 +227,7 @@ let cfg = config.fonts.fontconfig;
 
       substitute ${latestPkg.out}/etc/fonts/conf.d/51-local.conf \
                  $latest_folder/conf.d/51-local.conf \
-                 --replace local.conf /etc/fonts/${latestVersion}/local.conf 
+                 --replace local.conf /etc/fonts/${latestVersion}/local.conf
 
       # 00-nixos-cache.conf
       ln -s ${cacheConfSupport} \
@@ -192,6 +253,16 @@ let cfg = config.fonts.fontconfig;
       # 52-nixos-default-fonts.conf
       ln -s ${defaultFontsConf} $support_folder/conf.d/52-nixos-default-fonts.conf
       ln -s ${defaultFontsConf} $latest_folder/conf.d/52-nixos-default-fonts.conf
+
+      # 53-nixos-bitmaps.conf
+      ln -s ${rejectBitmaps} $support_folder/conf.d/53-nixos-bitmaps.conf
+      ln -s ${rejectBitmaps} $latest_folder/conf.d/53-nixos-bitmaps.conf
+
+      ${optionalString (! cfg.allowType1) ''
+      # 53-nixos-reject-type1.conf
+      ln -s ${rejectType1} $support_folder/conf.d/53-nixos-reject-type1.conf
+      ln -s ${rejectType1} $latest_folder/conf.d/53-nixos-reject-type1.conf
+      ''}
     '';
 
     # Package with configuration files
@@ -349,6 +420,45 @@ in
           '';
         };
 
+        allowBitmaps = mkOption {
+          type = types.bool;
+          default = true;
+          description = ''
+            Allow bitmap fonts. Set to <literal>false</literal> to ban all
+            bitmap fonts.
+          '';
+        };
+
+        allowType1 = mkOption {
+          type = types.bool;
+          default = false;
+          description = ''
+            Allow Type-1 fonts. Default is <literal>false</literal> because of
+            poor rendering.
+          '';
+        };
+
+        useEmbeddedBitmaps = mkOption {
+          type = types.bool;
+          default = false;
+          description = ''Use embedded bitmaps in fonts like Calibri.'';
+        };
+
+        forceAutohint = mkOption {
+          type = types.bool;
+          default = false;
+          description = ''
+            Force use of the TrueType Autohinter. Useful for debugging or
+            free-software purists.
+          '';
+        };
+
+        renderMonoTTFAsBitmap = mkOption {
+          type = types.bool;
+          default = false;
+          description = ''Render some monospace TTF fonts as bitmaps.'';
+        };
+
       };
 
     };
diff --git a/nixos/modules/config/networking.nix b/nixos/modules/config/networking.nix
index 426aaa34885c..4431dfb40859 100644
--- a/nixos/modules/config/networking.nix
+++ b/nixos/modules/config/networking.nix
@@ -251,11 +251,6 @@ in
     # Install the proxy environment variables
     environment.sessionVariables = cfg.proxy.envVars;
 
-    # The ‘ip-up’ target is kept for backwards compatibility.
-    # New services should use systemd upstream targets:
-    # See https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/
-    systemd.targets.ip-up.description = "Services Requiring IP Connectivity (deprecated)";
-
     # This is needed when /etc/resolv.conf is being overriden by networkd
     # and other configurations. If the file is destroyed by an environment
     # activation then it must be rebuilt so that applications which interface
diff --git a/nixos/modules/config/pulseaudio.nix b/nixos/modules/config/pulseaudio.nix
index eee8db376c84..bf66994b5022 100644
--- a/nixos/modules/config/pulseaudio.nix
+++ b/nixos/modules/config/pulseaudio.nix
@@ -274,6 +274,8 @@ in {
           RestartSec = "500ms";
         };
       };
+
+      environment.variables.PULSE_COOKIE = "${stateDir}/.config/pulse/cookie";
     })
   ];
 
diff --git a/nixos/modules/config/update-users-groups.pl b/nixos/modules/config/update-users-groups.pl
index cbbe216e5a17..4ca8a83554ad 100644
--- a/nixos/modules/config/update-users-groups.pl
+++ b/nixos/modules/config/update-users-groups.pl
@@ -177,7 +177,7 @@ foreach my $u (@{$spec->{users}}) {
     }
 
     # Create a home directory.
-    if ($u->{createHome} && ! -e $u->{home}) {
+    if ($u->{createHome}) {
         make_path($u->{home}, { mode => 0700 }) if ! -e $u->{home};
         chown $u->{uid}, $u->{gid}, $u->{home};
     }
diff --git a/nixos/modules/hardware/cpu/amd-microcode.nix b/nixos/modules/hardware/cpu/amd-microcode.nix
index d44f01a49590..621c7066bfe1 100644
--- a/nixos/modules/hardware/cpu/amd-microcode.nix
+++ b/nixos/modules/hardware/cpu/amd-microcode.nix
@@ -22,7 +22,8 @@ with lib;
   ###### implementation
 
   config = mkIf config.hardware.cpu.amd.updateMicrocode {
-    boot.initrd.prepend = [ "${pkgs.microcodeAmd}/amd-ucode.img" ];
+    # Microcode updates must be the first item prepended in the initrd
+    boot.initrd.prepend = mkOrder 1 [ "${pkgs.microcodeAmd}/amd-ucode.img" ];
   };
 
 }
diff --git a/nixos/modules/hardware/cpu/intel-microcode.nix b/nixos/modules/hardware/cpu/intel-microcode.nix
index 89ae4f45806c..acce565fd808 100644
--- a/nixos/modules/hardware/cpu/intel-microcode.nix
+++ b/nixos/modules/hardware/cpu/intel-microcode.nix
@@ -22,7 +22,8 @@ with lib;
   ###### implementation
 
   config = mkIf config.hardware.cpu.intel.updateMicrocode {
-    boot.initrd.prepend = [ "${pkgs.microcodeIntel}/intel-ucode.img" ];
+    # Microcode updates must be the first item prepended in the initrd
+    boot.initrd.prepend = mkOrder 1 [ "${pkgs.microcodeIntel}/intel-ucode.img" ];
   };
 
 }
diff --git a/nixos/modules/hardware/mcelog.nix b/nixos/modules/hardware/mcelog.nix
new file mode 100644
index 000000000000..e4ac7d39053f
--- /dev/null
+++ b/nixos/modules/hardware/mcelog.nix
@@ -0,0 +1,37 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  meta.maintainers = [ maintainers.grahamc ];
+  options = {
+
+    hardware.mcelog = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Enable the Machine Check Exception logger.
+        '';
+      };
+    };
+
+  };
+
+  config = mkIf config.hardware.mcelog.enable {
+    systemd.services.mcelog = {
+      description = "Machine Check Exception Logging Daemon";
+      wantedBy = [ "multi-user.target" ];
+
+      serviceConfig = {
+        ExecStart = "${pkgs.mcelog}/bin/mcelog --daemon --foreground";
+        SuccessExitStatus = [ 0 15 ];
+
+        ProtectHome = true;
+        PrivateNetwork = true;
+        PrivateTmp = true;
+      };
+    };
+  };
+
+}
diff --git a/nixos/modules/hardware/sensor/iio.nix b/nixos/modules/hardware/sensor/iio.nix
new file mode 100644
index 000000000000..a8bc18800021
--- /dev/null
+++ b/nixos/modules/hardware/sensor/iio.nix
@@ -0,0 +1,30 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  ###### interface
+
+  options = {
+    hardware.sensor.iio = {
+      enable = mkOption {
+        description = "Enable this option to support IIO sensors.";
+        type = types.bool;
+        default = false;
+      };
+    };
+  };
+
+  ###### implementation
+
+  config = mkIf config.hardware.sensor.iio.enable {
+
+    boot.initrd.availableKernelModules = [ "hid-sensor-hub" ];
+
+    environment.systemPackages = with pkgs; [ iio-sensor-proxy ];
+
+    services.dbus.packages = with pkgs; [ iio-sensor-proxy ];
+    services.udev.packages = with pkgs; [ iio-sensor-proxy ];
+    systemd.packages = with pkgs; [ iio-sensor-proxy ];
+  };
+}
diff --git a/nixos/modules/hardware/usb-wwan.nix b/nixos/modules/hardware/usb-wwan.nix
new file mode 100644
index 000000000000..2d20421586a7
--- /dev/null
+++ b/nixos/modules/hardware/usb-wwan.nix
@@ -0,0 +1,26 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  ###### interface
+
+  options = {
+
+    hardware.usbWwan = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Enable this option to support USB WWAN adapters.
+        '';
+      };
+    };
+  };
+
+  ###### implementation
+
+  config = mkIf config.hardware.usbWwan.enable {
+    services.udev.packages = with pkgs; [ usb-modeswitch-data ];
+  };
+}
diff --git a/nixos/modules/hardware/video/bumblebee.nix b/nixos/modules/hardware/video/bumblebee.nix
index 3967137fcf8b..2278c7b40611 100644
--- a/nixos/modules/hardware/video/bumblebee.nix
+++ b/nixos/modules/hardware/video/bumblebee.nix
@@ -13,7 +13,7 @@ let
     useDisplayDevice = cfg.connectDisplay;
   };
 
-  useBbswitch = cfg.pmMethod == "bbswitch";
+  useBbswitch = cfg.pmMethod == "bbswitch" || cfg.pmMethod == "auto" && useNvidia;
 
   primus = pkgs.primus.override {
     inherit useNvidia;
@@ -65,7 +65,7 @@ in
 
       pmMethod = mkOption {
         default = "auto";
-        type = types.enum [ "auto" "bbswitch" "nouveau" "switcheroo" "none" ];
+        type = types.enum [ "auto" "bbswitch" "switcheroo" "none" ];
         description = ''
           Set preferred power management method for unused card.
         '';
diff --git a/nixos/modules/hardware/video/capture/mwprocapture.nix b/nixos/modules/hardware/video/capture/mwprocapture.nix
new file mode 100644
index 000000000000..aee15dcec6e5
--- /dev/null
+++ b/nixos/modules/hardware/video/capture/mwprocapture.nix
@@ -0,0 +1,61 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.hardware.mwProCapture;
+
+  kernelPackages = config.boot.kernelPackages;
+
+in
+
+{
+
+  options.hardware.mwProCapture.enable = mkEnableOption "Magewell Pro Capture family kernel module";
+
+  config = mkIf cfg.enable {
+
+    assertions = singleton {
+      assertion = versionAtLeast kernelPackages.kernel.version "3.2";
+      message = "Magewell Pro Capture family module is not supported for kernels older than 3.2";
+    };
+
+    boot.kernelModules = [ "ProCapture" ];
+
+    environment.systemPackages = [ kernelPackages.mwprocapture ];
+
+    boot.extraModulePackages = [ kernelPackages.mwprocapture ];
+
+    boot.extraModprobeConfig = ''
+      # Set the png picture to be displayed when no input signal is detected.
+      options ProCapture nosignal_file=${kernelPackages.mwprocapture}/res/NoSignal.png
+
+      # Set the png picture to be displayed when an unsupported input signal is detected.
+      options ProCapture unsupported_file=${kernelPackages.mwprocapture}/res/Unsupported.png
+
+      # Set the png picture to be displayed when an loking input signal is detected.
+      options ProCapture locking_file=${kernelPackages.mwprocapture}/res/Locking.png
+
+      # Message signaled interrupts switch
+      #options ProCapture disable_msi=0
+
+      # Set the debug level
+      #options ProCapture debug_level=0
+
+      # Force init switch eeprom
+      #options ProCapture init_switch_eeprom=0
+
+      # Min frame interval for VIDIOC_ENUM_FRAMEINTERVALS (default: 166666(100ns))
+      #options ProCapture enum_frameinterval_min=166666
+
+      # VIDIOC_ENUM_FRAMESIZES type (1: DISCRETE; 2: STEPWISE; otherwise: CONTINUOUS )
+      #options ProCapture enum_framesizes_type=0
+
+      # Parameters for internal usage
+      #options ProCapture internal_params=""
+    '';
+
+  };
+
+}
diff --git a/nixos/modules/hardware/video/nvidia.nix b/nixos/modules/hardware/video/nvidia.nix
index cf723d53269b..161ed9457af9 100644
--- a/nixos/modules/hardware/video/nvidia.nix
+++ b/nixos/modules/hardware/video/nvidia.nix
@@ -49,6 +49,10 @@ in
         Option "RandRRotation" "on"
       '';
 
+    environment.etc."nvidia/nvidia-application-profiles-rc" = mkIf nvidia_x11.useProfiles {
+      source = "${nvidia_x11.bin}/share/nvidia/nvidia-application-profiles-rc";
+    };
+
     hardware.opengl.package = nvidiaPackage nvidia_x11 pkgs;
     hardware.opengl.package32 = nvidiaPackage nvidia_libs32 pkgs_i686;
 
diff --git a/nixos/modules/i18n/input-method/ibus.nix b/nixos/modules/i18n/input-method/ibus.nix
index a5bbe6bcb559..f8e021f551e8 100644
--- a/nixos/modules/i18n/input-method/ibus.nix
+++ b/nixos/modules/i18n/input-method/ibus.nix
@@ -44,7 +44,7 @@ in
       panel = mkOption {
         type = with types; nullOr path;
         default = null;
-        example = literalExample "''${pkgs.kde5.plasma-desktop}/lib/libexec/kimpanel-ibus-panel";
+        example = literalExample "''${pkgs.plasma5.plasma-desktop}/lib/libexec/kimpanel-ibus-panel";
         description = "Replace the IBus panel with another panel.";
       };
     };
diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix
index c44dff3bb60d..63227d573495 100644
--- a/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix
+++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix
@@ -18,7 +18,7 @@ with lib;
       autoLogin = true;
     };
 
-    desktopManager.kde5 = {
+    desktopManager.plasma5 = {
       enable = true;
       enableQt4Support = false;
     };
@@ -66,7 +66,7 @@ with lib;
   in ''
     mkdir -p /root/Desktop
     ln -sfT ${desktopFile} /root/Desktop/nixos-manual.desktop
-    ln -sfT ${pkgs.kde5.konsole}/share/applications/org.kde.konsole.desktop /root/Desktop/org.kde.konsole.desktop
+    ln -sfT ${pkgs.konsole}/share/applications/org.kde.konsole.desktop /root/Desktop/org.kde.konsole.desktop
     ln -sfT ${pkgs.gparted}/share/applications/gparted.desktop /root/Desktop/gparted.desktop
   '';
 
diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix
index 93dba0d882b8..85163305c1ef 100644
--- a/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -280,7 +280,7 @@ in
         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" ];
+    boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "usb-storage" "uas" ];
 
     boot.blacklistedKernelModules = [ "nouveau" ];
 
diff --git a/nixos/modules/installer/scan/detected.nix b/nixos/modules/installer/scan/detected.nix
index f350cd986afa..e72c78532943 100644
--- a/nixos/modules/installer/scan/detected.nix
+++ b/nixos/modules/installer/scan/detected.nix
@@ -1,4 +1,4 @@
-# List all devices which are detected by nixos-hardware-scan.
+# List all devices which are detected by nixos-generate-config.
 # Common devices are enabled by default.
 { config, lib, pkgs, ... }:
 
diff --git a/nixos/modules/installer/scan/not-detected.nix b/nixos/modules/installer/scan/not-detected.nix
index b30c569ed2a7..e1a3052ba957 100644
--- a/nixos/modules/installer/scan/not-detected.nix
+++ b/nixos/modules/installer/scan/not-detected.nix
@@ -1,4 +1,4 @@
-# List all devices which are _not_ detected by nixos-hardware-scan.
+# List all devices which are _not_ detected by nixos-generate-config.
 # Common devices are enabled by default.
 { config, lib, pkgs, ... }:
 
diff --git a/nixos/modules/installer/tools/nix-fallback-paths.nix b/nixos/modules/installer/tools/nix-fallback-paths.nix
index d73d67ef4728..07623fd591de 100644
--- a/nixos/modules/installer/tools/nix-fallback-paths.nix
+++ b/nixos/modules/installer/tools/nix-fallback-paths.nix
@@ -1,5 +1,5 @@
 {
-  x86_64-linux = "/nix/store/qdkzm17csr24snk247a1s0c47ikq5sl6-nix-1.11.6";
-  i686-linux = "/nix/store/hiwp53747lxlniqy5wpbql5izjrs8z0z-nix-1.11.6";
-  x86_64-darwin = "/nix/store/hca2hqcvwncf23hiqyqgwbsdy8vvl9xv-nix-1.11.6";
+  x86_64-linux = "/nix/store/4ssykr786d0wp7y6m4xd4qwqs4nrry1z-nix-1.11.7";
+  i686-linux = "/nix/store/61ggxx2072y2g877m01asy0lsn7xpn06-nix-1.11.7";
+  x86_64-darwin = "/nix/store/pxf5ri5kdbfqkhd10sw4lpj8sn385ks5-nix-1.11.7";
 }
diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl
index b72db1f6f503..29b447912e70 100644
--- a/nixos/modules/installer/tools/nixos-generate-config.pl
+++ b/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -607,7 +607,7 @@ $bootLoaderConfig
 
   # Enable the KDE Desktop Environment.
   # services.xserver.displayManager.sddm.enable = true;
-  # services.xserver.desktopManager.kde5.enable = true;
+  # services.xserver.desktopManager.plasma5.enable = true;
 
   # Define a user account. Don't forget to set a password with ‘passwd’.
   # users.extraUsers.guest = {
diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh
index 4f73865dad6a..4b5e7b3230c8 100644
--- a/nixos/modules/installer/tools/nixos-rebuild.sh
+++ b/nixos/modules/installer/tools/nixos-rebuild.sh
@@ -278,24 +278,22 @@ if [ -n "$buildNix" ]; then
     echo "building Nix..." >&2
     nixDrv=
     if ! nixDrv="$(nix-instantiate '<nixpkgs/nixos>' --add-root $tmpDir/nix.drv --indirect -A config.nix.package.out "${extraBuildFlags[@]}")"; then
-        if ! nixDrv="$(nix-instantiate '<nixpkgs/nixos>' --add-root $tmpDir/nix.drv --indirect -A nixFallback "${extraBuildFlags[@]}")"; then
-            if ! nixDrv="$(nix-instantiate '<nixpkgs>' --add-root $tmpDir/nix.drv --indirect -A nix "${extraBuildFlags[@]}")"; then
-                nixStorePath="$(prebuiltNix "$(uname -m)")"
-                if ! nix-store -r $nixStorePath --add-root $tmpDir/nix --indirect \
-                    --option extra-binary-caches https://cache.nixos.org/; then
+        if ! nixDrv="$(nix-instantiate '<nixpkgs>' --add-root $tmpDir/nix.drv --indirect -A nix "${extraBuildFlags[@]}")"; then
+            nixStorePath="$(prebuiltNix "$(uname -m)")"
+            if ! nix-store -r $nixStorePath --add-root $tmpDir/nix --indirect \
+                --option extra-binary-caches https://cache.nixos.org/; then
+                echo "warning: don't know how to get latest Nix" >&2
+            fi
+            # Older version of nix-store -r don't support --add-root.
+            [ -e $tmpDir/nix ] || ln -sf $nixStorePath $tmpDir/nix
+            if [ -n "$buildHost" ]; then
+                remoteNixStorePath="$(prebuiltNix "$(buildHostCmd uname -m)")"
+                remoteNix="$remoteNixStorePath/bin"
+                if ! buildHostCmd nix-store -r $remoteNixStorePath \
+                  --option extra-binary-caches https://cache.nixos.org/ >/dev/null; then
+                    remoteNix=
                     echo "warning: don't know how to get latest Nix" >&2
                 fi
-                # Older version of nix-store -r don't support --add-root.
-                [ -e $tmpDir/nix ] || ln -sf $nixStorePath $tmpDir/nix
-                if [ -n "$buildHost" ]; then
-                    remoteNixStorePath="$(prebuiltNix "$(buildHostCmd uname -m)")"
-                    remoteNix="$remoteNixStorePath/bin"
-                    if ! buildHostCmd nix-store -r $remoteNixStorePath \
-                      --option extra-binary-caches https://cache.nixos.org/ >/dev/null; then
-                        remoteNix=
-                        echo "warning: don't know how to get latest Nix" >&2
-                    fi
-                fi
             fi
         fi
     fi
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index d51b29b99dae..feecee3225be 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -288,6 +288,7 @@
       kresd = 270;
       rpc = 271;
       geoip = 272;
+      fcron = 273;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
@@ -545,6 +546,7 @@
       kresd = 270;
       #rpc = 271; # unused
       #geoip = 272; # unused
+      fcron = 273;
 
       # 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/misc/locate.nix b/nixos/modules/misc/locate.nix
index 089f354f6119..6d9bc915ba03 100644
--- a/nixos/modules/misc/locate.nix
+++ b/nixos/modules/misc/locate.nix
@@ -104,13 +104,13 @@ in {
     users.extraGroups = mkIf isMLocate { mlocate = {}; };
 
     security.wrappers = mkIf isMLocate {
-      mlocate = {
+      locate = {
         group = "mlocate";
         owner = "root";
         permissions = "u+rx,g+x,o+x";
         setgid = true;
         setuid = false;
-        program = "locate";
+        source = "${cfg.locate}/bin/locate";
       };
     };
 
diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix
index 70cd3fb9766a..315c33a462c6 100644
--- a/nixos/modules/misc/version.nix
+++ b/nixos/modules/misc/version.nix
@@ -95,7 +95,7 @@ in
       nixosVersionSuffix = mkIf (pathIsDirectory gitRepo) (mkDefault (".git." + gitCommitId));
 
       # Note: code names must only increase in alphabetical order.
-      nixosCodeName = "Gorilla";
+      nixosCodeName = "Hummingbird";
     };
 
     # Generate /etc/os-release.  See
@@ -106,9 +106,12 @@ in
         NAME=NixOS
         ID=nixos
         VERSION="${config.system.nixosVersion} (${config.system.nixosCodeName})"
+        VERSION_CODENAME=${toLower config.system.nixosCodeName}
         VERSION_ID="${config.system.nixosVersion}"
         PRETTY_NAME="NixOS ${config.system.nixosVersion} (${config.system.nixosCodeName})"
-        HOME_URL="http://nixos.org/"
+        HOME_URL="https://nixos.org/"
+        SUPPORT_URL="https://nixos.org/nixos/support.html"
+        BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues"
       '';
 
   };
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 81597d91d89a..627807edb900 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -29,7 +29,9 @@
   ./hardware/ckb.nix
   ./hardware/cpu/amd-microcode.nix
   ./hardware/cpu/intel-microcode.nix
+  ./hardware/sensor/iio.nix
   ./hardware/ksm.nix
+  ./hardware/mcelog.nix
   ./hardware/network/b43.nix
   ./hardware/network/intel-2100bg.nix
   ./hardware/network/intel-2200bg.nix
@@ -38,9 +40,11 @@
   ./hardware/network/rtl8192c.nix
   ./hardware/opengl.nix
   ./hardware/pcmcia.nix
+  ./hardware/usb-wwan.nix
   ./hardware/video/amdgpu.nix
   ./hardware/video/amdgpu-pro.nix
   ./hardware/video/ati.nix
+  ./hardware/video/capture/mwprocapture.nix
   ./hardware/video/bumblebee.nix
   ./hardware/video/displaylink.nix
   ./hardware/video/nvidia.nix
@@ -80,6 +84,7 @@
   ./programs/light.nix
   ./programs/man.nix
   ./programs/mosh.nix
+  ./programs/mtr.nix
   ./programs/nano.nix
   ./programs/oblogout.nix
   ./programs/screen.nix
@@ -91,6 +96,7 @@
   ./programs/tmux.nix
   ./programs/venus.nix
   ./programs/vim.nix
+  ./programs/wireshark.nix
   ./programs/wvdial.nix
   ./programs/xfs_quota.nix
   ./programs/xonsh.nix
@@ -102,6 +108,7 @@
   ./security/audit.nix
   ./security/ca.nix
   ./security/chromium-suid-sandbox.nix
+  ./security/dhparams.nix
   ./security/duosec.nix
   ./security/grsecurity.nix
   ./security/hidepid.nix
@@ -322,6 +329,7 @@
   ./services/monitoring/prometheus/default.nix
   ./services/monitoring/prometheus/alertmanager.nix
   ./services/monitoring/prometheus/blackbox-exporter.nix
+  ./services/monitoring/prometheus/fritzbox-exporter.nix
   ./services/monitoring/prometheus/json-exporter.nix
   ./services/monitoring/prometheus/nginx-exporter.nix
   ./services/monitoring/prometheus/node-exporter.nix
@@ -422,6 +430,7 @@
   ./services/networking/namecoind.nix
   ./services/networking/nat.nix
   ./services/networking/networkmanager.nix
+  ./services/networking/nftables.nix
   ./services/networking/ngircd.nix
   ./services/networking/nix-serve.nix
   ./services/networking/nntp-proxy.nix
@@ -564,6 +573,7 @@
   ./services/x11/display-managers/lightdm.nix
   ./services/x11/display-managers/sddm.nix
   ./services/x11/display-managers/slim.nix
+  ./services/x11/display-managers/xpra.nix
   ./services/x11/hardware/libinput.nix
   ./services/x11/hardware/multitouch.nix
   ./services/x11/hardware/synaptics.nix
diff --git a/nixos/modules/profiles/graphical.nix b/nixos/modules/profiles/graphical.nix
index 73dd2d4bc9f7..e23375375188 100644
--- a/nixos/modules/profiles/graphical.nix
+++ b/nixos/modules/profiles/graphical.nix
@@ -1,5 +1,5 @@
-# This module defines a NixOS configuration that contains X11 and
-# KDE 4.  It's used by the graphical installation CD.
+# This module defines a NixOS configuration with the Plasma 5 desktop.
+# It's used by the graphical installation CD.
 
 { config, pkgs, ... }:
 
@@ -7,7 +7,7 @@
   services.xserver = {
     enable = true;
     displayManager.sddm.enable = true;
-    desktopManager.kde5.enable = true;
+    desktopManager.plasma5.enable = true;
     synaptics.enable = true; # for touchpad support on many laptops
   };
 
diff --git a/nixos/modules/programs/mtr.nix b/nixos/modules/programs/mtr.nix
new file mode 100644
index 000000000000..927fe68be875
--- /dev/null
+++ b/nixos/modules/programs/mtr.nix
@@ -0,0 +1,27 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.programs.mtr;
+in {
+  options = {
+    programs.mtr = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to add mtr to the global environment and configure a
+          setcap wrapper for it.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    security.wrappers.mtr = {
+      source = "${pkgs.mtr}/bin/mtr";
+      capabilities = "cap_net_raw+p";
+    };
+  };
+}
diff --git a/nixos/modules/programs/wireshark.nix b/nixos/modules/programs/wireshark.nix
new file mode 100644
index 000000000000..710d223b6f59
--- /dev/null
+++ b/nixos/modules/programs/wireshark.nix
@@ -0,0 +1,42 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.programs.wireshark;
+  wireshark = cfg.package;
+in {
+  options = {
+    programs.wireshark = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to add Wireshark to the global environment and configure a
+          setcap wrapper for 'dumpcap' for users in the 'wireshark' group.
+        '';
+      };
+      package = mkOption {
+        type = types.package;
+        default = pkgs.wireshark-cli;
+        defaultText = "pkgs.wireshark-cli";
+        description = ''
+          Which Wireshark package to install in the global environment.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ wireshark ];
+    users.extraGroups.wireshark = {};
+
+    security.wrappers.dumpcap = {
+      source = "${wireshark}/bin/dumpcap";
+      capabilities = "cap_net_raw+p";
+      owner = "root";
+      group = "wireshark";
+      permissions = "u+rx,g+x";
+    };
+  };
+}
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index ee68f8bff81a..af8b34b5e5cb 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -103,9 +103,6 @@ with lib;
     (mkRenamedOptionModule [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ])
     (mkRenamedOptionModule [ "services" "xserver" "desktopManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ])
 
-    # DNSCrypt-proxy
-    (mkRenamedOptionModule [ "services" "dnscrypt-proxy" "port" ] [ "services" "dnscrypt-proxy" "localPort" ])
-
     (mkRenamedOptionModule [ "services" "hostapd" "extraCfg" ] [ "services" "hostapd" "extraConfig" ])
 
     # Enlightenment
@@ -178,6 +175,16 @@ with lib;
     (mkRenamedOptionModule [ "services" "nfs" "lockdPort" ] [ "services" "nfs" "server" "lockdPort" ])
     (mkRenamedOptionModule [ "services" "nfs" "statdPort" ] [ "services" "nfs" "server" "statdPort" ])
 
+    # KDE Plasma 5
+    (mkRenamedOptionModule [ "services" "xserver" "desktopManager" "kde5" ] [ "services" "xserver" "desktopManager" "plasma5" ])
+
+    # Fontconfig
+    (mkRenamedOptionModule [ "config" "fonts" "fontconfig" "ultimate" "allowBitmaps" ] [ "config" "fonts" "fontconfig" "allowBitmaps" ])
+    (mkRenamedOptionModule [ "config" "fonts" "fontconfig" "ultimate" "allowType1" ] [ "config" "fonts" "fontconfig" "allowType1" ])
+    (mkRenamedOptionModule [ "config" "fonts" "fontconfig" "ultimate" "useEmbeddedBitmaps" ] [ "config" "fonts" "fontconfig" "useEmbeddedBitmaps" ])
+    (mkRenamedOptionModule [ "config" "fonts" "fontconfig" "ultimate" "forceAutohint" ] [ "config" "fonts" "fontconfig" "forceAutohint" ])
+    (mkRenamedOptionModule [ "config" "fonts" "fontconfig" "ultimate" "renderMonoTTFAsBitmap" ] [ "config" "fonts" "fontconfig" "renderMonoTTFAsBitmap" ])
+
     # Options that are obsolete and have no replacement.
     (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "")
     (mkRemovedOptionModule [ "programs" "bash" "enable" ] "")
diff --git a/nixos/modules/security/acme.nix b/nixos/modules/security/acme.nix
index 4e7c966a463a..78bd09441f83 100644
--- a/nixos/modules/security/acme.nix
+++ b/nixos/modules/security/acme.nix
@@ -129,7 +129,7 @@ in
 
       certs = mkOption {
         default = { };
-        type = with types; loaOf (submodule certOpts);
+        type = with types; attrsOf (submodule certOpts);
         description = ''
           Attribute set of certificates to get signed and renewed.
         '';
diff --git a/nixos/modules/security/dhparams.nix b/nixos/modules/security/dhparams.nix
new file mode 100644
index 000000000000..c16cd2fafef4
--- /dev/null
+++ b/nixos/modules/security/dhparams.nix
@@ -0,0 +1,90 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.security.dhparams;
+in
+{
+  options = {
+    security.dhparams = {
+      params = mkOption {
+        description =
+          ''
+            Diffie-Hellman parameters to generate.
+
+            The value is the size (in bits) of the DH params to generate. The
+            generated DH params path can be found in
+            <filename><replaceable>security.dhparams.path</replaceable>/<replaceable>name</replaceable>.pem</filename>.
+
+            Note: The name of the DH params is taken as being the name of the
+            service it serves: the params will be generated before the said
+            service is started.
+          '';
+        type = with types; attrsOf int;
+        default = {};
+        example = { nginx = 3072; };
+      };
+
+      path = mkOption {
+        description =
+          ''
+            Path to the directory in which Diffie-Hellman parameters will be
+            stored.
+          '';
+        type = types.str;
+        default = "/var/lib/dhparams";
+      };
+    };
+  };
+
+  config.systemd.services = {
+    dhparams-init = {
+      description = "Cleanup old Diffie-Hellman parameters";
+      wantedBy = [ "multi-user.target" ]; # Clean up even when no DH params is set
+      serviceConfig.Type = "oneshot";
+      script =
+        # Create directory
+        ''
+          if [ ! -d ${cfg.path} ]; then
+            mkdir -p ${cfg.path}
+          fi
+        '' +
+        # Remove old dhparams
+        ''
+          for file in ${cfg.path}/*; do
+            if [ ! -f "$file" ]; then
+              continue
+            fi
+        '' + concatStrings (mapAttrsToList (name: value:
+        ''
+            if [ "$file" == "${cfg.path}/${name}.pem" ] && \
+                ${pkgs.openssl}/bin/openssl dhparam -in "$file" -text | head -n 1 | grep "(${toString value} bit)" > /dev/null; then
+              continue
+            fi
+        ''
+        ) cfg.params) +
+        ''
+            rm $file
+          done
+
+          # TODO: Ideally this would be removing the *former* cfg.path, though this
+          # does not seem really important
+          rmdir -p --ignore-fail-on-non-empty ${cfg.path}
+        '';
+    };
+  } //
+    mapAttrs' (name: value: nameValuePair "dhparams-gen-${name}" {
+      description = "Generate Diffie-Hellman parameters for ${name} if they don't exist yet";
+      after = [ "dhparams-init.service" ];
+      before = [ "${name}.service" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig.Type = "oneshot";
+      script =
+        ''
+          mkdir -p ${cfg.path}
+          if [ ! -f ${cfg.path}/${name}.pem ]; then
+            ${pkgs.openssl}/bin/openssl dhparam -out ${cfg.path}/${name}.pem ${toString value}
+          fi
+        '';
+    }) cfg.params;
+}
diff --git a/nixos/modules/security/grsecurity.xml b/nixos/modules/security/grsecurity.xml
index ef0aab4a3f13..620e8f653f99 100644
--- a/nixos/modules/security/grsecurity.xml
+++ b/nixos/modules/security/grsecurity.xml
@@ -214,8 +214,8 @@
             GRKERNSEC_CONFIG_SERVER y
             GRKERNSEC_CONFIG_SECURITY y
           '';
-          };
-      }
+        };
+      };
     </programlisting>
   </para>
 
@@ -312,7 +312,7 @@
       Overflows in boot critical code (e.g., the root filesystem module) can
       render the system unbootable.  Work around by setting
       <programlisting>
-        boot.kernel.kernelParams = [ "pax_size_overflow_report_only" ];
+        boot.kernelParams = [ "pax_size_overflow_report_only" ];
       </programlisting>
     </para></listitem>
 
diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix
index b51c8b4996be..5632500df2e0 100644
--- a/nixos/modules/security/pam.nix
+++ b/nixos/modules/security/pam.nix
@@ -280,8 +280,8 @@ let
               ${optionalString cfg.pamMount
                 "auth optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
               ${optionalString cfg.enableKwallet
-                ("auth optional ${pkgs.kde5.kwallet-pam}/lib/security/pam_kwallet5.so" +
-                 " kwalletd=${pkgs.kde5.kwallet}/bin/kwalletd5")}
+                ("auth optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" +
+                 " kwalletd=${pkgs.libsForQt5.kwallet}/bin/kwalletd5")}
             '') + ''
           ${optionalString cfg.unixAuth
               "auth sufficient pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth try_first_pass"}
@@ -349,8 +349,8 @@ let
           ${optionalString (cfg.enableAppArmor && config.security.apparmor.enable)
               "session optional ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so order=user,group,default debug"}
           ${optionalString (cfg.enableKwallet)
-              ("session optional ${pkgs.kde5.kwallet-pam}/lib/security/pam_kwallet5.so" +
-               " kwalletd=${pkgs.kde5.kwallet}/bin/kwalletd5")}
+              ("session optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" +
+               " kwalletd=${pkgs.libsForQt5.kwallet}/bin/kwalletd5")}
         '');
     };
 
diff --git a/nixos/modules/security/polkit.nix b/nixos/modules/security/polkit.nix
index 419abb8b086d..8d9d53480630 100644
--- a/nixos/modules/security/polkit.nix
+++ b/nixos/modules/security/polkit.nix
@@ -84,7 +84,7 @@ in
     security.pam.services.polkit-1 = {};
 
     security.wrappers = {
-      pkexec.source = "${pkgs.polkit.out}/bin/pkexec";
+      pkexec.source = "${pkgs.polkit.bin}/bin/pkexec";
       "polkit-agent-helper-1".source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1";
     };
 
diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix
index 861ce225257d..65d875c3a375 100644
--- a/nixos/modules/security/wrappers/default.nix
+++ b/nixos/modules/security/wrappers/default.nix
@@ -3,6 +3,8 @@ let
 
   inherit (config.security) wrapperDir wrappers;
 
+  parentWrapperDir = dirOf wrapperDir;
+
   programs =
     (lib.mapAttrsToList
       (n: v: (if v ? "program" then v else v // {program=n;}))
@@ -15,8 +17,7 @@ let
     hardeningEnable = [ "pie" ];
     installPhase = ''
       mkdir -p $out/bin
-      parentWrapperDir=$(dirname ${wrapperDir})
-      gcc -Wall -O2 -DWRAPPER_DIR=\"$parentWrapperDir\" \
+      gcc -Wall -O2 -DWRAPPER_DIR=\"${parentWrapperDir}\" \
           -lcap-ng -lcap ${./wrapper.c} -o $out/bin/security-wrapper
     '';
   };
@@ -28,6 +29,7 @@ let
     , source
     , owner  ? "nobody"
     , group  ? "nogroup"
+    , permissions ? "u+rx,g+x,o+x"
     , ...
     }:
     assert (lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3");
@@ -45,7 +47,7 @@ let
       ${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" $wrapperDir/${program}
 
       # Set the executable bit
-      chmod u+rx,g+x,o+x $wrapperDir/${program}
+      chmod ${permissions} $wrapperDir/${program}
     '';
 
   ###### Activation script for the setuid wrappers
@@ -155,6 +157,11 @@ in
 
     security.wrappers.fusermount.source = "${pkgs.fuse}/bin/fusermount";
 
+    boot.specialFileSystems.${parentWrapperDir} = {
+      fsType = "tmpfs";
+      options = [ "nodev" ];
+    };
+
     # Make sure our wrapperDir exports to the PATH env variable when
     # initializing the shell
     environment.extraInit = ''
@@ -182,19 +189,15 @@ in
           # Remove the old /run/setuid-wrappers-dir path from the
           # system as well...
           #
-          # TDOO: this is only necessary for ugprades 16.09 => 17.x;
+          # TODO: this is only necessary for ugprades 16.09 => 17.x;
           # this conditional removal block needs to be removed after
           # the release.
           if [ -d /run/setuid-wrapper-dirs ]; then
             rm -rf /run/setuid-wrapper-dirs
           fi
 
-          # Get the "/run/wrappers" path, we want to place the tmpdirs
-          # for the wrappers there
-          parentWrapperDir="$(dirname ${wrapperDir})"
-
-          mkdir -p "$parentWrapperDir"
-          wrapperDir=$(mktemp --directory --tmpdir="$parentWrapperDir" wrappers.XXXXXXXXXX)
+          # We want to place the tmpdirs for the wrappers to the parent dir.
+          wrapperDir=$(mktemp --directory --tmpdir="${parentWrapperDir}" wrappers.XXXXXXXXXX)
           chmod a+rx $wrapperDir
 
           ${lib.concatStringsSep "\n" mkWrappedPrograms}
@@ -206,13 +209,6 @@ in
             ln --symbolic --force --no-dereference $wrapperDir ${wrapperDir}-tmp
             mv --no-target-directory ${wrapperDir}-tmp ${wrapperDir}
             rm --force --recursive $old
-          elif [ -d ${wrapperDir} ]; then
-            # Compatibility with old state, just remove the folder and symlink
-            rm -f ${wrapperDir}/*
-            # if it happens to be a tmpfs
-            ${pkgs.utillinux}/bin/umount ${wrapperDir} || true
-            rm -d ${wrapperDir}
-            ln -d --symbolic $wrapperDir ${wrapperDir}
           else
             # For initial setup
             ln --symbolic $wrapperDir ${wrapperDir}
diff --git a/nixos/modules/services/audio/mpd.nix b/nixos/modules/services/audio/mpd.nix
index a89215d73828..56af8fe152e0 100644
--- a/nixos/modules/services/audio/mpd.nix
+++ b/nixos/modules/services/audio/mpd.nix
@@ -4,6 +4,8 @@ with lib;
 
 let
 
+  name = "mpd";
+
   uid = config.ids.uids.mpd;
   gid = config.ids.gids.mpd;
   cfg = config.services.mpd;
@@ -54,13 +56,14 @@ in {
         description = ''
           Extra directives added to to the end of MPD's configuration file,
           mpd.conf. Basic configuration like file location and uid/gid
-          is added automatically to the beginning of the file.
+          is added automatically to the beginning of the file. For available
+          options see <literal>man 5 mpd.conf</literal>'.
         '';
       };
 
       dataDir = mkOption {
         type = types.path;
-        default = "/var/lib/mpd";
+        default = "/var/lib/${name}";
         description = ''
           The directory where MPD stores its state, tag cache,
           playlists etc.
@@ -69,13 +72,13 @@ in {
 
       user = mkOption {
         type = types.str;
-        default = "mpd";
+        default = name;
         description = "User account under which MPD runs.";
       };
 
       group = mkOption {
         type = types.str;
-        default = "mpd";
+        default = name;
         description = "Group account under which MPD runs.";
       };
 
@@ -131,17 +134,17 @@ in {
       };
     };
 
-    users.extraUsers = optionalAttrs (cfg.user == "mpd") (singleton {
+    users.extraUsers = optionalAttrs (cfg.user == name) (singleton {
       inherit uid;
-      name = "mpd";
+      inherit name;
       group = cfg.group;
       extraGroups = [ "audio" ];
       description = "Music Player Daemon user";
       home = "${cfg.dataDir}";
     });
 
-    users.extraGroups = optionalAttrs (cfg.group == "mpd") (singleton {
-      name = "mpd";
+    users.extraGroups = optionalAttrs (cfg.group == name) (singleton {
+      inherit name;
       gid = gid;
     });
   };
diff --git a/nixos/modules/services/cluster/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix
index a82802c32662..9ccc7295019a 100644
--- a/nixos/modules/services/cluster/kubernetes.nix
+++ b/nixos/modules/services/cluster/kubernetes.nix
@@ -76,6 +76,7 @@ in {
       description = "Kubernetes package to use.";
       type = types.package;
       default = pkgs.kubernetes;
+      defaultText = "pkgs.kubernetes";
     };
 
     verbose = mkOption {
diff --git a/nixos/modules/services/continuous-integration/buildbot/master.nix b/nixos/modules/services/continuous-integration/buildbot/master.nix
index 512e09eb8041..533751734fa5 100644
--- a/nixos/modules/services/continuous-integration/buildbot/master.nix
+++ b/nixos/modules/services/continuous-integration/buildbot/master.nix
@@ -28,7 +28,7 @@ let
 
     ${cfg.extraConfig}
   ''
-  else pkgs.writeText "master.cfg" cfg.masterCfg;
+  else cfg.masterCfg;
 
 in {
   options = {
@@ -66,13 +66,10 @@ in {
       };
 
       masterCfg = mkOption {
-        type = types.str;
-        description = ''
-          Optionally pass raw master.cfg file as string.
-          Other options in this configuration will be ignored.
-        '';
+        type = types.nullOr types.path;
+        description = "Optionally pass master.cfg path. Other options in this configuration will be ignored.";
         default = null;
-        example = "BuildmasterConfig = c = {}";
+        example = "/etc/nixos/buildbot/master.cfg";
       };
 
       schedulers = mkOption {
@@ -88,7 +85,7 @@ in {
         type = types.listOf types.str;
         description = "List of Builders.";
         default = [
-          "util.BuilderConfig(name='runtests',workernames=['default-worker'],factory=factory)"
+          "util.BuilderConfig(name='runtests',workernames=['example-worker'],factory=factory)"
         ];
       };
 
@@ -121,7 +118,7 @@ in {
 
       extraGroups = mkOption {
         type = types.listOf types.str;
-        default = [ "nixbld" ];
+        default = [];
         description = "List of extra groups that the buildbot user should be a part of.";
       };
 
@@ -183,16 +180,14 @@ in {
       package = mkOption {
         type = types.package;
         default = pkgs.buildbot-ui;
-        description = ''
-          Package to use for buildbot.
-          <literal>buildbot-full</literal> is required in order to use local workers.
-        '';
-        example = pkgs.buildbot-full;
+        defaultText = "pkgs.buildbot-ui";
+        description = "Package to use for buildbot.";
+        example = literalExample "pkgs.buildbot-full";
       };
 
       packages = mkOption {
         default = [ ];
-        example = [ pkgs.git ];
+        example = literalExample "[ pkgs.git ]";
         type = types.listOf types.package;
         description = "Packages to add to PATH for the buildbot process.";
       };
@@ -222,11 +217,11 @@ in {
       path = cfg.packages;
 
       serviceConfig = {
-        Type = "forking";
+        Type = "simple";
         User = cfg.user;
         Group = cfg.group;
         WorkingDirectory = cfg.home;
-        ExecStart = "${cfg.package}/bin/buildbot start ${cfg.buildbotDir}";
+        ExecStart = "${cfg.package}/bin/buildbot start --nodaemon ${cfg.buildbotDir}";
       };
 
       preStart = ''
diff --git a/nixos/modules/services/continuous-integration/buildbot/worker.nix b/nixos/modules/services/continuous-integration/buildbot/worker.nix
index 430fd4e53f1c..e4ee4dd861ef 100644
--- a/nixos/modules/services/continuous-integration/buildbot/worker.nix
+++ b/nixos/modules/services/continuous-integration/buildbot/worker.nix
@@ -31,7 +31,7 @@ in {
 
       extraGroups = mkOption {
         type = types.listOf types.str;
-        default = [ "nixbld" ];
+        default = [];
         description = "List of extra groups that the Buildbot Worker user should be a part of.";
       };
 
@@ -68,13 +68,14 @@ in {
       package = mkOption {
         type = types.package;
         default = pkgs.buildbot-worker;
+        defaultText = "pkgs.buildbot-worker";
         description = "Package to use for buildbot worker.";
-        example = pkgs.buildbot-worker;
+        example = literalExample "pkgs.buildbot-worker";
       };
 
       packages = mkOption {
         default = [ ];
-        example = [ pkgs.git ];
+        example = literalExample "[ pkgs.git ]";
         type = types.listOf types.package;
         description = "Packages to add to PATH for the buildbot process.";
       };
@@ -100,24 +101,21 @@ in {
 
     systemd.services.buildbot-worker = {
       description = "Buildbot Worker.";
-      after = [ "network.target" ];
+      after = [ "network.target" "buildbot-master.service" ];
       wantedBy = [ "multi-user.target" ];
-      wants = [ "buildbot-master.service" ];
       path = cfg.packages;
 
       preStart = ''
-        # NOTE: ensure master has time to start in case running on localhost
-        ${pkgs.coreutils}/bin/sleep 4
         ${pkgs.coreutils}/bin/mkdir -vp ${cfg.buildbotDir}
         ${cfg.package}/bin/buildbot-worker create-worker ${cfg.buildbotDir} ${cfg.masterUrl} ${cfg.workerUser} ${cfg.workerPass}
       '';
 
       serviceConfig = {
-        Type = "forking";
+        Type = "simple";
         User = cfg.user;
         Group = cfg.group;
         WorkingDirectory = cfg.home;
-        ExecStart = "${cfg.package}/bin/buildbot-worker start ${cfg.buildbotDir}";
+        ExecStart = "${cfg.package}/bin/buildbot-worker start --nodaemon ${cfg.buildbotDir}";
       };
 
     };
diff --git a/nixos/modules/services/continuous-integration/jenkins/job-builder.nix b/nixos/modules/services/continuous-integration/jenkins/job-builder.nix
index 7b1fe6269fe9..861b46a2d642 100644
--- a/nixos/modules/services/continuous-integration/jenkins/job-builder.nix
+++ b/nixos/modules/services/continuous-integration/jenkins/job-builder.nix
@@ -29,6 +29,22 @@ in {
         '';
       };
 
+      accessUser = mkOption {
+        default = "";
+        type = types.str;
+        description = ''
+          User id in Jenkins used to reload config.
+        '';
+      };
+
+      accessToken = mkOption {
+        default = "";
+        type = types.str;
+        description = ''
+          User token in Jenkins used to reload config.
+        '';
+      };
+
       yamlJobs = mkOption {
         default = "";
         type = types.lines;
@@ -110,6 +126,11 @@ in {
           # Stamp file is placed in $JENKINS_HOME/jobs/$JOB_NAME/ to indicate
           # ownership. Enables tracking and removal of stale jobs.
           ownerStamp = ".config-xml-managed-by-nixos-jenkins-job-builder";
+          reloadScript = ''
+            echo "Asking Jenkins to reload config"
+            CRUMB=$(curl -s 'http://${cfg.accessUser}:${cfg.accessToken}@${jenkinsCfg.listenAddress}:${toString jenkinsCfg.port}${jenkinsCfg.prefix}/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
+            curl --silent -X POST -H "$CRUMB" http://${cfg.accessUser}:${cfg.accessToken}@${jenkinsCfg.listenAddress}:${toString jenkinsCfg.port}${jenkinsCfg.prefix}/reload
+          '';
         in
           ''
             rm -rf ${jobBuilderOutputDir}
@@ -142,10 +163,7 @@ in {
                 echo "Deleting stale job \"$jobname\""
                 rm -rf "$jobdir"
             done
-
-            echo "Asking Jenkins to reload config"
-            curl --silent -X POST http://${jenkinsCfg.listenAddress}:${toString jenkinsCfg.port}${jenkinsCfg.prefix}/reload
-          '';
+          '' + (if cfg.accessUser != "" then reloadScript else "");
       serviceConfig = {
         User = jenkinsCfg.user;
         RuntimeDirectory = "jenkins-job-builder";
diff --git a/nixos/modules/services/databases/neo4j.nix b/nixos/modules/services/databases/neo4j.nix
index 7b51f1af6899..cbba9c2a691c 100644
--- a/nixos/modules/services/databases/neo4j.nix
+++ b/nixos/modules/services/databases/neo4j.nix
@@ -30,9 +30,16 @@ let
   '';
 
   wrapperConfig = pkgs.writeText "neo4j-wrapper.conf" ''
+    # Default JVM parameters from neo4j.conf
+    dbms.jvm.additional=-XX:+UseG1GC
+    dbms.jvm.additional=-XX:-OmitStackTraceInFastThrow
+    dbms.jvm.additional=-XX:+AlwaysPreTouch
+    dbms.jvm.additional=-XX:+UnlockExperimentalVMOptions
+    dbms.jvm.additional=-XX:+TrustFinalNonStaticFields
+    dbms.jvm.additional=-XX:+DisableExplicitGC
+    dbms.jvm.additional=-Djdk.tls.ephemeralDHKeySize=2048
+
     dbms.jvm.additional=-Dunsupported.dbms.udc.source=tarball
-    dbms.jvm.additional=-XX:+UseConcMarkSweepGC
-    dbms.jvm.additional=-XX:+CMSClassUnloadingEnabled
   '';
 
 in {
diff --git a/nixos/modules/services/databases/openldap.nix b/nixos/modules/services/databases/openldap.nix
index b8e6c0cec3dc..d76859bf3eb6 100644
--- a/nixos/modules/services/databases/openldap.nix
+++ b/nixos/modules/services/databases/openldap.nix
@@ -68,10 +68,10 @@ in
         ";
         example = literalExample ''
             '''
-            include ${pkgs.openldap.out}/etc/openldap/schema/core.schema
-            include ${pkgs.openldap.out}/etc/openldap/schema/cosine.schema
-            include ${pkgs.openldap.out}/etc/openldap/schema/inetorgperson.schema
-            include ${pkgs.openldap.out}/etc/openldap/schema/nis.schema
+            include ${pkgs.openldap.out}/etc/schema/core.schema
+            include ${pkgs.openldap.out}/etc/schema/cosine.schema
+            include ${pkgs.openldap.out}/etc/schema/inetorgperson.schema
+            include ${pkgs.openldap.out}/etc/schema/nis.schema
 
             database bdb 
             suffix dc=example,dc=org 
diff --git a/nixos/modules/services/databases/stanchion.nix b/nixos/modules/services/databases/stanchion.nix
index f2dbb78b5c4b..a4597cac3cd6 100644
--- a/nixos/modules/services/databases/stanchion.nix
+++ b/nixos/modules/services/databases/stanchion.nix
@@ -76,14 +76,6 @@ in
         '';
       };
 
-      stanchionSsl = mkOption {
-        type = types.bool;
-        default = true;
-        description = ''
-          Tell stanchion to use SSL.
-        '';
-      };
-
       distributedCookie = mkOption {
         type = types.str;
         default = "riak";
@@ -148,8 +140,6 @@ in
 
       distributed_cookie = ${cfg.distributedCookie}
 
-      stanchion_ssl=${if cfg.stanchionSsl then "on" else "off"}
-
       ${cfg.extraConfig}
     '';
 
diff --git a/nixos/modules/services/hardware/bluetooth.nix b/nixos/modules/services/hardware/bluetooth.nix
index de0d48032113..71b3a93a2e0d 100644
--- a/nixos/modules/services/hardware/bluetooth.nix
+++ b/nixos/modules/services/hardware/bluetooth.nix
@@ -1,8 +1,11 @@
 { config, lib, pkgs, ... }:
 
 with lib;
+
 let
   bluez-bluetooth = pkgs.bluez;
+  cfg = config.hardware.bluetooth;
+
 in
 
 {
@@ -11,33 +14,53 @@ in
 
   options = {
 
-    hardware.bluetooth.enable = mkOption {
-      type = types.bool;
-      default = false;
-      description = "Whether to enable support for Bluetooth.";
+    hardware.bluetooth.enable = mkEnableOption "support for Bluetooth.";
+
+    hardware.bluetooth.powerOnBoot = mkOption {
+      type    = types.bool;
+      default = true;
+      description = "Whether to power up the default Bluetooth controller on boot.";
     };
 
   };
 
   ###### implementation
 
-  config = mkIf config.hardware.bluetooth.enable {
+  config = mkIf cfg.enable {
 
     environment.systemPackages = [ bluez-bluetooth pkgs.openobex pkgs.obexftp ];
 
     services.udev.packages = [ bluez-bluetooth ];
-
     services.dbus.packages = [ bluez-bluetooth ];
+    systemd.packages       = [ bluez-bluetooth ];
+
+    services.udev.extraRules = optionalString cfg.powerOnBoot ''
+      ACTION=="add", KERNEL=="hci[0-9]*", ENV{SYSTEMD_WANTS}="bluetooth-power@%k.service"
+    '';
+
+    systemd.services = {
+      bluetooth = {
+        wantedBy = [ "bluetooth.target" ];
+        aliases  = [ "dbus-org.bluez.service" ];
+      };
+
+      "bluetooth-power@" = mkIf cfg.powerOnBoot {
+        description = "Power up bluetooth controller";
+        after = [
+          "bluetooth.service"
+          "suspend.target"
+          "sys-subsystem-bluetooth-devices-%i.device"
+        ];
+        wantedBy = [ "suspend.target" ];
+
+        serviceConfig.Type      = "oneshot";
+        serviceConfig.ExecStart = "${pkgs.bluez.out}/bin/hciconfig %i up";
+      };
 
-    systemd.packages = [ bluez-bluetooth ];
-
-    systemd.services.bluetooth = {
-      wantedBy = [ "bluetooth.target" ];
-      aliases = [ "dbus-org.bluez.service" ];
     };
 
-    systemd.user.services.obex = {
-      aliases = [ "dbus-org.bluez.obex.service" ];
+    systemd.user.services = {
+      obex.aliases = [ "dbus-org.bluez.obex.service" ];
     };
 
   };
diff --git a/nixos/modules/services/logging/fluentd.nix b/nixos/modules/services/logging/fluentd.nix
index e56a9a4e9afb..9fbec2457371 100644
--- a/nixos/modules/services/logging/fluentd.nix
+++ b/nixos/modules/services/logging/fluentd.nix
@@ -25,6 +25,7 @@ in {
       package = mkOption {
         type = types.path;
         default = pkgs.fluentd;
+        defaultText = "pkgs.fluentd";
         description = "The fluentd package to use.";
       };
     };
diff --git a/nixos/modules/services/logging/graylog.nix b/nixos/modules/services/logging/graylog.nix
index a7785decd19a..95283096662e 100644
--- a/nixos/modules/services/logging/graylog.nix
+++ b/nixos/modules/services/logging/graylog.nix
@@ -17,9 +17,16 @@ let
     elasticsearch_discovery_zen_ping_unicast_hosts = ${cfg.elasticsearchDiscoveryZenPingUnicastHosts}
     message_journal_dir = ${cfg.messageJournalDir}
     mongodb_uri = ${cfg.mongodbUri}
+    plugin_dir = /var/lib/graylog/plugins
 
     ${cfg.extraConfig}
   '';
+
+  glPlugins = pkgs.buildEnv {
+    name = "graylog-plugins";
+    paths = cfg.plugins;
+  };
+
 in
 
 {
@@ -121,6 +128,12 @@ in
         description = "Any other configuration options you might want to add";
       };
 
+      plugins = mkOption {
+        description = "Extra graylog plugins";
+        default = [ ];
+        type = types.listOf types.package;
+      };
+
     };
   };
 
@@ -146,6 +159,16 @@ in
       path = [ pkgs.openjdk8 pkgs.which pkgs.procps ];
       preStart = ''
         mkdir -p /var/lib/graylog -m 755
+
+        rm -rf /var/lib/graylog/plugins || true
+        mkdir -p /var/lib/graylog/plugins -m 755
+
+        for declarativeplugin in `ls ${glPlugins}/bin/`; do
+          ln -sf ${glPlugins}/bin/$declarativeplugin /var/lib/graylog/plugins/$declarativeplugin
+        done
+        for includedplugin in `ls ${cfg.package}/plugin/`; do
+          ln -s ${cfg.package}/plugin/$includedplugin /var/lib/graylog/plugins/$includedplugin || true
+        done
         chown -R ${cfg.user} /var/lib/graylog
 
         mkdir -p ${cfg.messageJournalDir} -m 755
diff --git a/nixos/modules/services/logging/logcheck.nix b/nixos/modules/services/logging/logcheck.nix
index 72925b95cae4..2a8ac414720b 100644
--- a/nixos/modules/services/logging/logcheck.nix
+++ b/nixos/modules/services/logging/logcheck.nix
@@ -184,7 +184,7 @@ in
         description = ''
           This option defines extra ignore rules.
         '';
-        type = with types; loaOf (submodule ignoreOptions);
+        type = with types; attrsOf (submodule ignoreOptions);
       };
 
       ignoreCron = mkOption {
@@ -192,7 +192,7 @@ in
         description = ''
           This option defines extra ignore rules for cronjobs.
         '';
-        type = with types; loaOf (submodule ignoreCronOptions);
+        type = with types; attrsOf (submodule ignoreCronOptions);
       };
 
       extraGroups = mkOption {
diff --git a/nixos/modules/services/mail/mlmmj.nix b/nixos/modules/services/mail/mlmmj.nix
index e2b37522cb16..4a01745eb8b6 100644
--- a/nixos/modules/services/mail/mlmmj.nix
+++ b/nixos/modules/services/mail/mlmmj.nix
@@ -18,7 +18,7 @@ let
   footer = domain: list: "To unsubscribe send a mail to ${list}+unsubscribe@${domain}";
   createList = d: l: ''
     ${pkgs.coreutils}/bin/mkdir -p ${listCtl d l}
-    echo ${listAddress d l} > ${listCtl d l}/listadress
+    echo ${listAddress d l} > ${listCtl d l}/listaddress
     echo "${lib.concatStringsSep "\n" (customHeaders d l)}" > ${listCtl d l}/customheaders
     echo ${footer d l} > ${listCtl d l}/footer
     echo ${subjectPrefix l} > ${listCtl d l}/prefix
diff --git a/nixos/modules/services/misc/apache-kafka.nix b/nixos/modules/services/misc/apache-kafka.nix
index cff053396885..82fa1cc2e7e5 100644
--- a/nixos/modules/services/misc/apache-kafka.nix
+++ b/nixos/modules/services/misc/apache-kafka.nix
@@ -19,13 +19,8 @@ let
         ${toString cfg.extraProperties}
       '';
 
-  configDir = pkgs.buildEnv {
-    name = "apache-kafka-conf";
-    paths = [
-      (pkgs.writeTextDir "server.properties" serverProperties)
-      (pkgs.writeTextDir "log4j.properties" cfg.log4jProperties)
-    ];
-  };
+  serverConfig = pkgs.writeText "server.properties" serverProperties;
+  logConfig = pkgs.writeText "log4j.properties" cfg.log4jProperties;
 
 in {
 
@@ -143,10 +138,11 @@ in {
       serviceConfig = {
         ExecStart = ''
           ${pkgs.jre}/bin/java \
-            -cp "${cfg.package}/libs/*:${configDir}" \
+            -cp "${cfg.package}/libs/*" \
+            -Dlog4j.configuration=file:${logConfig} \
             ${toString cfg.jvmOptions} \
             kafka.Kafka \
-            ${configDir}/server.properties
+            ${serverConfig}
         '';
         User = "apache-kafka";
         PermissionsStartOnly = true;
diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix
index 7101cadfeed2..5088c4e60691 100644
--- a/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixos/modules/services/misc/nix-daemon.nix
@@ -8,6 +8,8 @@ let
 
   nix = cfg.package.out;
 
+  isNix112 = versionAtLeast (getVersion nix) "1.12pre4997";
+
   makeNixBuildUser = nr:
     { name = "nixbld${toString nr}";
       description = "Nix build user ${toString nr}";
@@ -162,22 +164,23 @@ in
       buildMachines = mkOption {
         type = types.listOf types.attrs;
         default = [];
-        example = [
-          { hostName = "voila.labs.cs.uu.nl";
-            sshUser = "nix";
-            sshKey = "/root/.ssh/id_buildfarm";
-            system = "powerpc-darwin";
-            maxJobs = 1;
-          }
-          { hostName = "linux64.example.org";
-            sshUser = "buildfarm";
-            sshKey = "/root/.ssh/id_buildfarm";
-            system = "x86_64-linux";
-            maxJobs = 2;
-            supportedFeatures = [ "kvm" ];
-            mandatoryFeatures = [ "perf" ];
-          }
-        ];
+        example = literalExample ''
+          [ { hostName = "voila.labs.cs.uu.nl";
+              sshUser = "nix";
+              sshKey = "/root/.ssh/id_buildfarm";
+              system = "powerpc-darwin";
+              maxJobs = 1;
+            }
+            { hostName = "linux64.example.org";
+              sshUser = "buildfarm";
+              sshKey = "/root/.ssh/id_buildfarm";
+              system = "x86_64-linux";
+              maxJobs = 2;
+              supportedFeatures = [ "kvm" ];
+              mandatoryFeatures = [ "perf" ];
+            }
+          ]
+        '';
         description = ''
           This option lists the machines to be used if distributed
           builds are enabled (see
@@ -380,7 +383,9 @@ in
 
     nix.envVars =
       { NIX_CONF_DIR = "/etc/nix";
+      }
 
+      // optionalAttrs (!isNix112) {
         # Enable the copy-from-other-stores substituter, which allows
         # builds to be sped up by copying build results from remote
         # Nix stores.  To do this, mount the remote file system on a
@@ -389,9 +394,11 @@ in
       }
 
       // optionalAttrs cfg.distributedBuilds {
-        NIX_BUILD_HOOK = "${nix}/libexec/nix/build-remote.pl";
-        NIX_REMOTE_SYSTEMS = "/etc/nix/machines";
-        NIX_CURRENT_LOAD = "/run/nix/current-load";
+        NIX_BUILD_HOOK =
+          if isNix112 then
+            "${nix}/libexec/nix/build-remote"
+          else
+            "${nix}/libexec/nix/build-remote.pl";
       };
 
     # Set up the environment variables for running Nix.
diff --git a/nixos/modules/services/misc/nixos-manual.nix b/nixos/modules/services/misc/nixos-manual.nix
index 306ee346523d..622607f3b32d 100644
--- a/nixos/modules/services/misc/nixos-manual.nix
+++ b/nixos/modules/services/misc/nixos-manual.nix
@@ -41,7 +41,7 @@ let
 
   entry = "${manual.manual}/share/doc/nixos/index.html";
 
-  help = pkgs.writeScriptBin "nixos-help"
+  helpScript = pkgs.writeScriptBin "nixos-help"
     ''
       #! ${pkgs.stdenv.shell} -e
       browser="$BROWSER"
@@ -58,6 +58,15 @@ let
       exec "$browser" ${entry}
     '';
 
+  desktopItem = pkgs.makeDesktopItem {
+    name = "nixos-manual";
+    desktopName = "NixOS Manual";
+    genericName = "View NixOS documentation in a web browser";
+    # TODO: find a better icon (Nix logo + help overlay?)
+    icon = "system-help";
+    exec = "${helpScript}/bin/nixos-help";
+    categories = "System";
+  };
 in
 
 {
@@ -105,7 +114,8 @@ in
     system.build.manual = manual;
 
     environment.systemPackages =
-      [ manual.manual help ]
+      [ manual.manual helpScript ]
+      ++ optional config.services.xserver.enable desktopItem
       ++ optional config.programs.man.enable manual.manpages;
 
     boot.extraTTYs = mkIf cfg.showManual ["tty${toString cfg.ttyNumber}"];
diff --git a/nixos/modules/services/misc/octoprint.nix b/nixos/modules/services/misc/octoprint.nix
index c2b3f63be7d4..8faad46a49f1 100644
--- a/nixos/modules/services/misc/octoprint.nix
+++ b/nixos/modules/services/misc/octoprint.nix
@@ -7,7 +7,7 @@ let
   cfg = config.services.octoprint;
 
   baseConfig = {
-    plugins.cura.cura_engine = "${pkgs.curaengine}/bin/CuraEngine";
+    plugins.cura.cura_engine = "${pkgs.curaengine_stable}/bin/CuraEngine";
     server.host = cfg.host;
     server.port = cfg.port;
     webcam.ffmpeg = "${pkgs.ffmpeg.bin}/bin/ffmpeg";
diff --git a/nixos/modules/services/misc/ssm-agent.nix b/nixos/modules/services/misc/ssm-agent.nix
index b04959a9686a..c1e1f0903539 100644
--- a/nixos/modules/services/misc/ssm-agent.nix
+++ b/nixos/modules/services/misc/ssm-agent.nix
@@ -23,6 +23,7 @@ in {
       type = types.path;
       description = "The SSM agent package to use";
       default = pkgs.ssm-agent;
+      defaultText = "pkgs.ssm-agent";
     };
   };
 
diff --git a/nixos/modules/services/misc/taskserver/default.nix b/nixos/modules/services/misc/taskserver/default.nix
index d28c5dc7af85..826f463bbd75 100644
--- a/nixos/modules/services/misc/taskserver/default.nix
+++ b/nixos/modules/services/misc/taskserver/default.nix
@@ -94,44 +94,6 @@ let
     in flatten (mapAttrsToList mkSublist attrs);
   in all isNull (findPkiDefinitions [] manualPkiOptions);
 
-  configFile = pkgs.writeText "taskdrc" (''
-    # systemd related
-    daemon = false
-    log = -
-
-    # logging
-    ${mkConfLine "debug" cfg.debug}
-    ${mkConfLine "ip.log" cfg.ipLog}
-
-    # general
-    ${mkConfLine "ciphers" cfg.ciphers}
-    ${mkConfLine "confirmation" cfg.confirmation}
-    ${mkConfLine "extensions" cfg.extensions}
-    ${mkConfLine "queue.size" cfg.queueSize}
-    ${mkConfLine "request.limit" cfg.requestLimit}
-
-    # client
-    ${mkConfLine "client.allow" cfg.allowedClientIDs}
-    ${mkConfLine "client.deny" cfg.disallowedClientIDs}
-
-    # server
-    server = ${cfg.listenHost}:${toString cfg.listenPort}
-    ${mkConfLine "trust" cfg.trust}
-
-    # PKI options
-    ${if needToCreateCA then ''
-      ca.cert = ${cfg.dataDir}/keys/ca.cert
-      server.cert = ${cfg.dataDir}/keys/server.cert
-      server.key = ${cfg.dataDir}/keys/server.key
-      server.crl = ${cfg.dataDir}/keys/server.crl
-    '' else ''
-      ca.cert = ${cfg.pki.manual.ca.cert}
-      server.cert = ${cfg.pki.manual.server.cert}
-      server.key = ${cfg.pki.manual.server.key}
-      server.crl = ${cfg.pki.manual.server.crl}
-    ''}
-  '' + cfg.extraConfig);
-
   orgOptions = { name, ... }: {
     options.users = mkOption {
       type = types.uniq (types.listOf types.str);
@@ -154,9 +116,8 @@ let
 
   certtool = "${pkgs.gnutls.bin}/bin/certtool";
 
-  nixos-taskserver = pkgs.pythonPackages.buildPythonPackage {
+  nixos-taskserver = pkgs.pythonPackages.buildPythonApplication {
     name = "nixos-taskserver";
-    namePrefix = "";
 
     src = pkgs.runCommand "nixos-taskserver-src" {} ''
       mkdir -p "$out"
@@ -167,6 +128,7 @@ let
         certBits = cfg.pki.auto.bits;
         clientExpiration = cfg.pki.auto.expiration.client;
         crlExpiration = cfg.pki.auto.expiration.crl;
+        isAutoConfig = if needToCreateCA then "True" else "False";
       }}" > "$out/main.py"
       cat > "$out/setup.py" <<EOF
       from setuptools import setup
@@ -365,20 +327,57 @@ in {
       pki.manual = manualPkiOptions;
       pki.auto = autoPkiOptions;
 
-      extraConfig = mkOption {
-        type = types.lines;
-        default = "";
-        example = "client.cert = /tmp/debugging.cert";
+      config = mkOption {
+        type = types.attrs;
+        example.client.cert = "/tmp/debugging.cert";
         description = ''
-          Extra lines to append to the taskdrc configuration file.
+          Configuration options to pass to Taskserver.
+
+          The options here are the same as described in <citerefentry>
+            <refentrytitle>taskdrc</refentrytitle>
+            <manvolnum>5</manvolnum>
+          </citerefentry>, but with one difference:
+
+          The <literal>server</literal> option is
+          <literal>server.listen</literal> here, because the
+          <literal>server</literal> option would collide with other options
+          like <literal>server.cert</literal> and we would run in a type error
+          (attribute set versus string).
+
+          Nix types like integers or booleans are automatically converted to
+          the right values Taskserver would expect.
         '';
+        apply = let
+          mkKey = path: if path == ["server" "listen"] then "server"
+                        else concatStringsSep "." path;
+          recurse = path: attrs: let
+            mapper = name: val: let
+              newPath = path ++ [ name ];
+              scalar = if val == true then "true"
+                       else if val == false then "false"
+                       else toString val;
+            in if isAttrs val then recurse newPath val
+               else [ "${mkKey newPath}=${scalar}" ];
+          in concatLists (mapAttrsToList mapper attrs);
+        in recurse [];
       };
     };
   };
 
+  imports = [
+    (mkRemovedOptionModule ["services" "taskserver" "extraConfig"] ''
+      This option was removed in favor of `services.taskserver.config` with
+      different semantics (it's now a list of attributes instead of lines).
+
+      Please look up the documentation of `services.taskserver.config' to get
+      more information about the new way to pass additional configuration
+      options.
+    '')
+  ];
+
   config = mkMerge [
     (mkIf cfg.enable {
-      environment.systemPackages = [ pkgs.taskserver nixos-taskserver ];
+      environment.systemPackages = [ nixos-taskserver ];
 
       users.users = optional (cfg.user == "taskd") {
         name = "taskd";
@@ -392,6 +391,44 @@ in {
         gid = config.ids.gids.taskd;
       };
 
+      services.taskserver.config = {
+        # systemd related
+        daemon = false;
+        log = "-";
+
+        # logging
+        debug = cfg.debug;
+        ip.log = cfg.ipLog;
+
+        # general
+        ciphers = cfg.ciphers;
+        confirmation = cfg.confirmation;
+        extensions = cfg.extensions;
+        queue.size = cfg.queueSize;
+        request.limit = cfg.requestLimit;
+
+        # client
+        client.allow = cfg.allowedClientIDs;
+        client.deny = cfg.disallowedClientIDs;
+
+        # server
+        trust = cfg.trust;
+        server = {
+          listen = "${cfg.listenHost}:${toString cfg.listenPort}";
+        } // (if needToCreateCA then {
+          cert = "${cfg.dataDir}/keys/server.cert";
+          key = "${cfg.dataDir}/keys/server.key";
+          crl = "${cfg.dataDir}/keys/server.crl";
+        } else {
+          cert = "${cfg.pki.manual.server.cert}";
+          key = "${cfg.pki.manual.server.key}";
+          crl = "${cfg.pki.manual.server.crl}";
+        });
+
+        ca.cert = if needToCreateCA then "${cfg.dataDir}/keys/ca.cert"
+                  else "${cfg.pki.manual.ca.cert}";
+      };
+
       systemd.services.taskserver-init = {
         wantedBy = [ "taskserver.service" ];
         before = [ "taskserver.service" ];
@@ -404,7 +441,6 @@ in {
 
         script = ''
           ${taskd} init
-          echo "include ${configFile}" > "${cfg.dataDir}/config"
           touch "${cfg.dataDir}/.is_initialized"
         '';
 
@@ -436,7 +472,10 @@ in {
         in "${helperTool} process-json '${jsonFile}'";
 
         serviceConfig = {
-          ExecStart = "@${taskd} taskd server";
+          ExecStart = let
+            mkCfgFlag = flag: escapeShellArg "--${flag}";
+            cfgFlags = concatMapStringsSep " " mkCfgFlag cfg.config;
+          in "@${taskd} taskd server ${cfgFlags}";
           ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
           Restart = "on-failure";
           PermissionsStartOnly = true;
diff --git a/nixos/modules/services/misc/taskserver/doc.xml b/nixos/modules/services/misc/taskserver/doc.xml
index 48591129264a..6d4d2a9b488c 100644
--- a/nixos/modules/services/misc/taskserver/doc.xml
+++ b/nixos/modules/services/misc/taskserver/doc.xml
@@ -136,9 +136,9 @@ $ ssh server nixos-taskserver user export my-company alice | sh
 
     <para>
       If you set any options within
-      <option>service.taskserver.pki.manual.*</option>, the automatic user and
-      CA management by the <command>nixos-taskserver</command> is disabled and
-      you need to create certificates and keys by yourself.
+      <option>service.taskserver.pki.manual.*</option>,
+      <command>nixos-taskserver</command> won't issue certificates, but you can
+      still use it for adding or removing user accounts.
     </para>
   </section>
 </chapter>
diff --git a/nixos/modules/services/misc/taskserver/helper-tool.py b/nixos/modules/services/misc/taskserver/helper-tool.py
index 03e7cdf8987a..b97bc1df74f7 100644
--- a/nixos/modules/services/misc/taskserver/helper-tool.py
+++ b/nixos/modules/services/misc/taskserver/helper-tool.py
@@ -13,6 +13,7 @@ from tempfile import NamedTemporaryFile
 
 import click
 
+IS_AUTO_CONFIG = @isAutoConfig@ # NOQA
 CERTTOOL_COMMAND = "@certtool@"
 CERT_BITS = "@certBits@"
 CLIENT_EXPIRATION = "@clientExpiration@"
@@ -149,6 +150,12 @@ def create_template(contents):
 
 
 def generate_key(org, user):
+    if not IS_AUTO_CONFIG:
+        msg = "Automatic PKI handling is disabled, you need to " \
+              "manually issue a client certificate for user {}.\n"
+        sys.stderr.write(msg.format(user))
+        return
+
     basedir = os.path.join(TASKD_DATA_DIR, "keys", org, user)
     if os.path.exists(basedir):
         raise OSError("Keyfile directory for {} already exists.".format(user))
@@ -243,26 +250,32 @@ class User(object):
         self.key = key
 
     def export(self):
-        pubcert = getkey(self.__org, self.name, "public.cert")
-        privkey = getkey(self.__org, self.name, "private.key")
-        cacert = getkey("ca.cert")
-
-        keydir = "${TASKDATA:-$HOME/.task}/keys"
-
         credentials = '/'.join([self.__org, self.name, self.key])
         allow_unquoted = string.ascii_letters + string.digits + "/-_."
         if not all((c in allow_unquoted) for c in credentials):
             credentials = "'" + credentials.replace("'", r"'\''") + "'"
 
-        script = [
-            "umask 0077",
-            'mkdir -p "{}"'.format(keydir),
-            mktaskkey("certificate", os.path.join(keydir, "public.cert"),
-                      pubcert),
-            mktaskkey("key", os.path.join(keydir, "private.key"), privkey),
-            mktaskkey("ca", os.path.join(keydir, "ca.cert"), cacert),
+        script = []
+
+        if IS_AUTO_CONFIG:
+            pubcert = getkey(self.__org, self.name, "public.cert")
+            privkey = getkey(self.__org, self.name, "private.key")
+            cacert = getkey("ca.cert")
+
+            keydir = "${TASKDATA:-$HOME/.task}/keys"
+
+            script += [
+                "umask 0077",
+                'mkdir -p "{}"'.format(keydir),
+                mktaskkey("certificate", os.path.join(keydir, "public.cert"),
+                          pubcert),
+                mktaskkey("key", os.path.join(keydir, "private.key"), privkey),
+                mktaskkey("ca", os.path.join(keydir, "ca.cert"), cacert)
+            ]
+
+        script.append(
             "task config taskd.credentials -- {}".format(credentials)
-        ]
+        )
 
         return "\n".join(script) + "\n"
 
@@ -526,7 +539,7 @@ def export_user(organisation, user):
     userobj = organisation.get_user(user)
     if userobj is None:
         msg = "User {} doesn't exist in organisation {}."
-        sys.exit(msg.format(userobj.name, organisation.name))
+        sys.exit(msg.format(user, organisation.name))
 
     sys.stdout.write(userobj.export())
 
diff --git a/nixos/modules/services/monitoring/das_watchdog.nix b/nixos/modules/services/monitoring/das_watchdog.nix
index 6e2653836d5e..88ca3a9227d2 100644
--- a/nixos/modules/services/monitoring/das_watchdog.nix
+++ b/nixos/modules/services/monitoring/das_watchdog.nix
@@ -25,7 +25,7 @@ in {
       wantedBy = [ "multi-user.target" ];
       serviceConfig = {
         User = "root";
-        Type = "oneshot";
+        Type = "simple";
         ExecStart = "${das_watchdog}/bin/das_watchdog";
         RemainAfterExit = true;
       };
diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix
index 6d2ce5383687..364f18e7543d 100644
--- a/nixos/modules/services/monitoring/munin.nix
+++ b/nixos/modules/services/monitoring/munin.nix
@@ -76,6 +76,7 @@ let
       # wrapped plugins by makeWrapper being with dots
       ignore_file ^\.
 
+      allow ^::1$
       allow ^127\.0\.0\.1$
 
       ${nodeCfg.extraConfig}
diff --git a/nixos/modules/services/monitoring/prometheus/default.nix b/nixos/modules/services/monitoring/prometheus/default.nix
index a07445ce167c..cf9deccbffe2 100644
--- a/nixos/modules/services/monitoring/prometheus/default.nix
+++ b/nixos/modules/services/monitoring/prometheus/default.nix
@@ -134,6 +134,7 @@ let
           };
         });
         default = null;
+        apply = x: if x == null then null else _filter x;
         description = ''
           Optional http login credentials for metrics scraping.
         '';
diff --git a/nixos/modules/services/monitoring/prometheus/fritzbox-exporter.nix b/nixos/modules/services/monitoring/prometheus/fritzbox-exporter.nix
new file mode 100644
index 000000000000..6da39b6519cb
--- /dev/null
+++ b/nixos/modules/services/monitoring/prometheus/fritzbox-exporter.nix
@@ -0,0 +1,76 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.services.prometheus.fritzboxExporter;
+in {
+  options = {
+    services.prometheus.fritzboxExporter = {
+      enable = mkEnableOption "prometheus fritzbox exporter";
+
+      port = mkOption {
+        type = types.int;
+        default = 9133;
+        description = ''
+          Port to listen on.
+        '';
+      };
+
+      gatewayAddress = mkOption {
+        type = types.str;
+        default = "fritz.box";
+        description = ''
+          The hostname or IP of the FRITZ!Box.
+        '';
+      };
+
+      gatewayPort = mkOption {
+        type = types.int;
+        default = 49000;
+        description = ''
+          The port of the FRITZ!Box UPnP service.
+        '';
+      };
+
+      extraFlags = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        description = ''
+          Extra commandline options when launching the fritzbox exporter.
+        '';
+      };
+
+      openFirewall = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Open port in firewall for incoming connections.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
+
+    systemd.services.prometheus-fritzbox-exporter = {
+      description = "Prometheus exporter for FRITZ!Box via UPnP";
+      unitConfig.Documentation = "https://github.com/ndecker/fritzbox_exporter";
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        User = "nobody";
+        Restart = "always";
+        PrivateTmp = true;
+        WorkingDirectory = /tmp;
+        ExecStart = ''
+          ${pkgs.prometheus-fritzbox-exporter}/bin/fritzbox_exporter \
+            -listen-address :${toString cfg.port} \
+            -gateway-address ${cfg.gatewayAddress} \
+            -gateway-port ${toString cfg.gatewayPort} \
+            ${concatStringsSep " \\\n  " cfg.extraFlags}
+        '';
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/monitoring/vnstat.nix b/nixos/modules/services/monitoring/vnstat.nix
index f6be7c7fd34a..ca56e4a7b958 100644
--- a/nixos/modules/services/monitoring/vnstat.nix
+++ b/nixos/modules/services/monitoring/vnstat.nix
@@ -32,7 +32,7 @@ in {
       preStart = "chmod 755 /var/lib/vnstat";
       serviceConfig = {
         ExecStart = "${pkgs.vnstat}/bin/vnstatd -n";
-        ExecReload = "kill -HUP $MAINPID";
+        ExecReload = "${pkgs.procps}/bin/kill -HUP $MAINPID";
         ProtectHome = true;
         PrivateDevices = true;
         PrivateTmp = true;
diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix
index 09a11585bc92..6ae5292fc303 100644
--- a/nixos/modules/services/network-filesystems/samba.nix
+++ b/nixos/modules/services/network-filesystems/samba.nix
@@ -91,6 +91,26 @@ in
         '';
       };
 
+      enableNmbd = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether to enable Samba's nmbd, which replies to NetBIOS over IP name
+          service requests. It also participates in the browsing protocols
+          which make up the Windows "Network Neighborhood" view.
+        '';
+      };
+
+      enableWinbindd = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether to enable Samba's winbindd, which provides a number of services
+          to the Name Service Switch capability found in most modern C libraries,
+          to arbitrary applications via PAM and ntlm_auth and to Samba itself.
+        '';
+      };
+
       package = mkOption {
         type = types.package;
         default = pkgs.samba;
@@ -185,7 +205,12 @@ in
   ###### implementation
 
   config = mkMerge
-    [ { # Always provide a smb.conf to shut up programs like smbclient and smbspool.
+    [ { assertions =
+          [ { assertion = cfg.nsswins -> cfg.enableWinbindd;
+              message   = "If samba.nsswins is enabled, then samba.enableWinbindd must also be enabled";
+            }
+          ];
+        # Always provide a smb.conf to shut up programs like smbclient and smbspool.
         environment.etc = singleton
           { source =
               if cfg.enable then configFile
@@ -194,7 +219,7 @@ in
           };
       }
 
-      (mkIf config.services.samba.enable {
+      (mkIf cfg.enable {
 
         system.nssModules = optional cfg.nsswins samba;
 
@@ -207,9 +232,9 @@ in
           };
 
           services = {
-            "samba-nmbd" = daemonService "nmbd" "-F";
             "samba-smbd" = daemonService "smbd" "-F";
-            "samba-winbindd" = daemonService "winbindd" "-F";
+            "samba-nmbd" = mkIf cfg.enableNmbd (daemonService "nmbd" "-F");
+            "samba-winbindd" = mkIf cfg.enableWinbindd (daemonService "winbindd" "-F");
             "samba-setup" = {
               description = "Samba Setup Task";
               script = setupScript;
diff --git a/nixos/modules/services/network-filesystems/tahoe.nix b/nixos/modules/services/network-filesystems/tahoe.nix
index f63f641d00be..3d78ac096a2b 100644
--- a/nixos/modules/services/network-filesystems/tahoe.nix
+++ b/nixos/modules/services/network-filesystems/tahoe.nix
@@ -8,7 +8,7 @@ in
     options.services.tahoe = {
       introducers = mkOption {
         default = {};
-        type = with types; loaOf (submodule {
+        type = with types; attrsOf (submodule {
           options = {
             nickname = mkOption {
               type = types.str;
@@ -49,7 +49,7 @@ in
       };
       nodes = mkOption {
         default = {};
-        type = with types; loaOf (submodule {
+        type = with types; attrsOf (submodule {
           options = {
             nickname = mkOption {
               type = types.str;
diff --git a/nixos/modules/services/networking/btsync.nix b/nixos/modules/services/networking/btsync.nix
index 572a7387316b..92e9fa7be419 100644
--- a/nixos/modules/services/networking/btsync.nix
+++ b/nixos/modules/services/networking/btsync.nix
@@ -208,7 +208,6 @@ in
       storagePath = mkOption {
         type = types.path;
         default = "/var/lib/btsync/";
-        example = "/var/lib/btsync/";
         description = ''
           Where BitTorrent Sync will store it's database files (containing
           things like username info and licenses). Generally, you should not
diff --git a/nixos/modules/services/networking/ddclient.nix b/nixos/modules/services/networking/ddclient.nix
index 5928203368d2..28c96a9baefc 100644
--- a/nixos/modules/services/networking/ddclient.nix
+++ b/nixos/modules/services/networking/ddclient.nix
@@ -7,7 +7,7 @@ let
 
   stateDir = "/var/spool/ddclient";
   ddclientUser = "ddclient";
-  ddclientFlags = "-foreground -verbose -noquiet -file ${config.services.ddclient.configFile}";
+  ddclientFlags = "-foreground -file ${config.services.ddclient.configFile}";
   ddclientPIDFile = "${stateDir}/ddclient.pid";
 
 in
@@ -102,6 +102,22 @@ in
           Method to determine the IP address to send to the dynamic DNS provider.
         '';
       };
+
+      verbose = mkOption {
+        default = true;
+        type = bool;
+        description = ''
+          Print verbose information.
+        '';
+      };
+
+      quiet = mkOption {
+        default = false;
+        type = bool;
+        description = ''
+          Print no messages for unnecessary updates.
+        '';
+      };
     };
   };
 
@@ -136,6 +152,8 @@ in
           lib.optionalString (server != "") "server=${server}"}
         ssl=${if config.services.ddclient.ssl then "yes" else "no"}
         wildcard=YES
+        quiet=${if config.services.ddclient.quiet then "yes" else "no"}
+        verbose=${if config.services.ddclient.verbose then "yes" else "no"}
         ${config.services.ddclient.domain}
         ${config.services.ddclient.extraConfig}
       '';
diff --git a/nixos/modules/services/networking/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix
index 87c0aa50a1ff..7eeceb7407c6 100644
--- a/nixos/modules/services/networking/dhcpcd.nix
+++ b/nixos/modules/services/networking/dhcpcd.nix
@@ -157,7 +157,7 @@ in
     systemd.services.dhcpcd =
       { description = "DHCP Client";
 
-        wantedBy = [ "multi-user.target" ];
+        wantedBy = [ "network-online.target" ];
         after = [ "network.target" ];
         wants = [ "network.target" ];
 
@@ -173,7 +173,7 @@ in
         serviceConfig =
           { Type = "forking";
             PIDFile = "/run/dhcpcd.pid";
-            ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --quiet ${optionalString cfg.persistent "--persistent"} --config ${dhcpcdConf}";
+            ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd -w --quiet ${optionalString cfg.persistent "--persistent"} --config ${dhcpcdConf}";
             ExecReload = "${dhcpcd}/sbin/dhcpcd --rebind";
             Restart = "always";
           };
diff --git a/nixos/modules/services/networking/dhcpd.nix b/nixos/modules/services/networking/dhcpd.nix
index 86bcaa96f345..2eac6dfec5b7 100644
--- a/nixos/modules/services/networking/dhcpd.nix
+++ b/nixos/modules/services/networking/dhcpd.nix
@@ -60,8 +60,9 @@ let
     };
   };
 
-  machineOpts = {...}: {
-    config = {
+  machineOpts = { ... }: {
+
+    options = {
 
       hostName = mkOption {
         type = types.str;
@@ -156,7 +157,7 @@ let
     };
 
     machines = mkOption {
-      type = types.listOf (types.submodule machineOpts);
+      type = with types; listOf (submodule machineOpts);
       default = [];
       example = [
         { hostName = "foo";
diff --git a/nixos/modules/services/networking/dnscrypt-proxy.nix b/nixos/modules/services/networking/dnscrypt-proxy.nix
index 462039803f80..d382fa8c9cb2 100644
--- a/nixos/modules/services/networking/dnscrypt-proxy.nix
+++ b/nixos/modules/services/networking/dnscrypt-proxy.nix
@@ -2,12 +2,9 @@
 with lib;
 
 let
-  apparmorEnabled = config.security.apparmor.enable;
-  dnscrypt-proxy = pkgs.dnscrypt-proxy;
   cfg = config.services.dnscrypt-proxy;
-  stateDirectory = "/var/lib/dnscrypt-proxy";
 
-  localAddress = "${cfg.localAddress}:${toString cfg.localPort}";
+  stateDirectory = "/var/lib/dnscrypt-proxy";
 
   # The minisign public key used to sign the upstream resolver list.
   # This is somewhat more flexible than preloading the key as an
@@ -17,31 +14,33 @@ let
     sha256 = "18lnp8qr6ghfc2sd46nn1rhcpr324fqlvgsp4zaigw396cd7vnnh";
   };
 
-  # Internal flag indicating whether the upstream resolver list is used
-  useUpstreamResolverList = cfg.resolverList == null && cfg.customResolver == null;
-
-  resolverList =
-    if (cfg.resolverList != null)
-      then cfg.resolverList
-      else "${stateDirectory}/dnscrypt-resolvers.csv";
-
-  resolverArgs = if (cfg.customResolver != null)
-    then
-      [ "--resolver-address=${cfg.customResolver.address}:${toString cfg.customResolver.port}"
-        "--provider-name=${cfg.customResolver.name}"
-        "--provider-key=${cfg.customResolver.key}"
-      ]
-    else
-      [ "--resolvers-list=${resolverList}"
-        "--resolver-name=${cfg.resolverName}"
-      ];
-
-  # The final command line arguments passed to the daemon
+  # Internal flag indicating whether the upstream resolver list is used.
+  useUpstreamResolverList = cfg.customResolver == null;
+
+  # The final local address.
+  localAddress = "${cfg.localAddress}:${toString cfg.localPort}";
+
+  # The final resolvers list path.
+  resolverList = "${stateDirectory}/dnscrypt-resolvers.csv";
+
+  # Build daemon command line
+
+  resolverArgs =
+    if (cfg.customResolver == null)
+      then
+        [ "-L ${resolverList}"
+          "-R ${cfg.resolverName}"
+        ]
+      else with cfg.customResolver;
+        [ "-N ${name}"
+          "-k ${key}"
+          "-r ${address}:${toString port}"
+        ];
+
   daemonArgs =
-    [ "--local-address=${localAddress}" ]
-    ++ optional cfg.tcpOnly "--tcp-only"
-    ++ optional cfg.ephemeralKeys "-E"
-    ++ resolverArgs;
+       [ "-a ${localAddress}" ]
+    ++ resolverArgs
+    ++ cfg.extraArgs;
 in
 
 {
@@ -51,6 +50,9 @@ in
   };
 
   options = {
+    # Before adding another option, consider whether it could
+    # equally well be passed via extraArgs.
+
     services.dnscrypt-proxy = {
       enable = mkOption {
         default = false;
@@ -83,19 +85,11 @@ in
         default = "dnscrypt.eu-nl";
         type = types.nullOr types.str;
         description = ''
-          The name of the upstream DNSCrypt resolver to use, taken from
-          <filename>${resolverList}</filename>.  The default resolver is
-          located in Holland, supports DNS security extensions, and
-          <emphasis>claims</emphasis> to not keep logs.
-        '';
-      };
-
-      resolverList = mkOption {
-        default = null;
-        type = types.nullOr types.path;
-        description = ''
-          List of DNSCrypt resolvers.  The default is to use the list of
-          public resolvers provided by upstream.
+          The name of the DNSCrypt resolver to use, taken from
+          <filename>${resolverList}</filename>.  The default
+          resolver is located in Holland, supports DNS security
+          extensions, and <emphasis>claims</emphasis> to not
+          keep logs.
         '';
       };
 
@@ -121,7 +115,7 @@ in
           name = mkOption {
             type = types.str;
             description = "Fully qualified domain name";
-            example = "2.dnscrypt-cert.opendns.com";
+            example = "2.dnscrypt-cert.example.com";
           };
 
           key = mkOption {
@@ -132,39 +126,72 @@ in
         }; }));
       };
 
-      tcpOnly = mkOption {
-        default = false;
-        type = types.bool;
-        description = ''
-          Force sending encrypted DNS queries to the upstream resolver over
-          TCP instead of UDP (on port 443). Use only if the UDP port is blocked.
-        '';
-      };
-
-      ephemeralKeys = mkOption {
-        default = false;
-        type = types.bool;
+      extraArgs = mkOption {
+        default = [];
+        type = types.listOf types.str;
         description = ''
-          Compute a new key pair for every query.  Enabling this option
-          increases CPU usage, but makes it more difficult for the upstream
-          resolver to track your usage of their service across IP addresses.
-          The default is to re-use the public key pair for all queries, making
-          tracking trivial.
+          Additional command-line arguments passed verbatim to the daemon.
+          See <citerefentry><refentrytitle>dnscrypt-proxy</refentrytitle>
+          <manvolnum>8</manvolnum></citerefentry> for details.
         '';
+        example = [ "-X libdcplugin_example_cache.so,--min-ttl=60" ];
       };
     };
   };
 
-  config = mkIf cfg.enable {
-
+  config = mkIf cfg.enable (mkMerge [{
     assertions = [
       { assertion = (cfg.customResolver != null) || (cfg.resolverName != null);
         message   = "please configure upstream DNSCrypt resolver";
       }
     ];
 
-    security.apparmor.profiles = optional apparmorEnabled (pkgs.writeText "apparmor-dnscrypt-proxy" ''
-      ${dnscrypt-proxy}/bin/dnscrypt-proxy {
+    users.users.dnscrypt-proxy = {
+      description = "dnscrypt-proxy daemon user";
+      isSystemUser = true;
+      group = "dnscrypt-proxy";
+    };
+    users.groups.dnscrypt-proxy = {};
+
+    systemd.sockets.dnscrypt-proxy = {
+      description = "dnscrypt-proxy listening socket";
+      documentation = [ "man:dnscrypt-proxy(8)" ];
+
+      wantedBy = [ "sockets.target" ];
+
+      socketConfig = {
+        ListenStream = localAddress;
+        ListenDatagram = localAddress;
+      };
+    };
+
+    systemd.services.dnscrypt-proxy = {
+      description = "dnscrypt-proxy daemon";
+      documentation = [ "man:dnscrypt-proxy(8)" ];
+
+      before = [ "nss-lookup.target" ];
+      after = [ "network.target" ];
+      requires = [ "dnscrypt-proxy.socket "];
+
+      serviceConfig = {
+        NonBlocking = "true";
+        ExecStart = "${pkgs.dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}";
+        ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+
+        User = "dnscrypt-proxy";
+
+        PrivateTmp = true;
+        PrivateDevices = true;
+        ProtectHome = true;
+      };
+    };
+    }
+
+    (mkIf config.security.apparmor.enable {
+    systemd.services.dnscrypt-proxy.after = [ "apparmor.service" ];
+
+    security.apparmor.profiles = singleton (pkgs.writeText "apparmor-dnscrypt-proxy" ''
+      ${pkgs.dnscrypt-proxy}/bin/dnscrypt-proxy {
         /dev/null rw,
         /dev/urandom r,
 
@@ -180,6 +207,8 @@ in
         network inet dgram,
         network inet6 dgram,
 
+        ${getLib pkgs.dnscrypt-proxy}/lib/dnscrypt-proxy/libdcplugin*.so mr,
+
         ${getLib pkgs.gcc.cc}/lib/libssp.so.* mr,
         ${getLib pkgs.libsodium}/lib/libsodium.so.* mr,
         ${getLib pkgs.systemd}/lib/libsystemd.so.* mr,
@@ -188,102 +217,104 @@ in
         ${getLib pkgs.libgpgerror}/lib/libgpg-error.so.* mr,
         ${getLib pkgs.libcap}/lib/libcap.so.* mr,
         ${getLib pkgs.lz4}/lib/liblz4.so.* mr,
-        ${getLib pkgs.attr}/lib/libattr.so.* mr,
+        ${getLib pkgs.attr}/lib/libattr.so.* mr, # */
 
         ${resolverList} r,
       }
     '');
+    })
 
-    users.users.dnscrypt-proxy = {
-      description = "dnscrypt-proxy daemon user";
-      isSystemUser = true;
-      group = "dnscrypt-proxy";
-    };
-    users.groups.dnscrypt-proxy = {};
-
-    systemd.services.init-dnscrypt-proxy-statedir = optionalAttrs useUpstreamResolverList {
+    (mkIf useUpstreamResolverList {
+    systemd.services.init-dnscrypt-proxy-statedir = {
       description = "Initialize dnscrypt-proxy state directory";
+
+      wantedBy = [ "dnscrypt-proxy.service" ];
+      before = [ "dnscrypt-proxy.service" ];
+
       script = ''
         mkdir -pv ${stateDirectory}
         chown -c dnscrypt-proxy:dnscrypt-proxy ${stateDirectory}
-        cp --preserve=timestamps -uv \
+        cp -uv \
           ${pkgs.dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv \
           ${stateDirectory}
       '';
+
       serviceConfig = {
         Type = "oneshot";
         RemainAfterExit = true;
       };
     };
 
-    systemd.services.update-dnscrypt-resolvers = optionalAttrs useUpstreamResolverList {
+    systemd.services.update-dnscrypt-resolvers = {
       description = "Update list of DNSCrypt resolvers";
 
       requires = [ "init-dnscrypt-proxy-statedir.service" ];
       after = [ "init-dnscrypt-proxy-statedir.service" ];
 
-      path = with pkgs; [ curl minisign ];
+      path = with pkgs; [ curl diffutils dnscrypt-proxy minisign ];
       script = ''
         cd ${stateDirectory}
-        curl -fSsL -o dnscrypt-resolvers.csv.tmp \
-          https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-resolvers.csv
-        curl -fSsL -o dnscrypt-resolvers.csv.minisig.tmp \
-          https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-resolvers.csv.minisig
+        domain=raw.githubusercontent.com
+        get="curl -fSs --resolve $domain:443:$(hostip -r 8.8.8.8 $domain | head -1)"
+        $get -o dnscrypt-resolvers.csv.tmp \
+          https://$domain/jedisct1/dnscrypt-proxy/master/dnscrypt-resolvers.csv
+        $get -o dnscrypt-resolvers.csv.minisig.tmp \
+          https://$domain/jedisct1/dnscrypt-proxy/master/dnscrypt-resolvers.csv.minisig
         mv dnscrypt-resolvers.csv.minisig{.tmp,}
-        minisign -q -V -p ${upstreamResolverListPubKey} \
-          -m dnscrypt-resolvers.csv.tmp -x dnscrypt-resolvers.csv.minisig
+        if ! minisign -q -V -p ${upstreamResolverListPubKey} \
+          -m dnscrypt-resolvers.csv.tmp -x dnscrypt-resolvers.csv.minisig ; then
+          echo "failed to verify resolver list!" >&2
+          exit 1
+        fi
+        [[ -f dnscrypt-resolvers.csv ]] && mv dnscrypt-resolvers.csv{,.old}
         mv dnscrypt-resolvers.csv{.tmp,}
+        if cmp dnscrypt-resolvers.csv{,.old} ; then
+          echo "no change"
+        else
+          echo "resolver list updated"
+        fi
       '';
 
       serviceConfig = {
         PrivateTmp = true;
         PrivateDevices = true;
         ProtectHome = true;
-        ProtectSystem = true;
+        ProtectSystem = "strict";
+        ReadWritePaths = "${dirOf stateDirectory} ${stateDirectory}";
+        SystemCallFilter = "~@mount";
       };
     };
 
-    systemd.timers.update-dnscrypt-resolvers = optionalAttrs useUpstreamResolverList {
+    systemd.timers.update-dnscrypt-resolvers = {
+      wantedBy = [ "timers.target" ];
       timerConfig = {
         OnBootSec = "5min";
         OnUnitActiveSec = "6h";
       };
-      wantedBy = [ "timers.target" ];
-    };
-
-    systemd.sockets.dnscrypt-proxy = {
-      description = "dnscrypt-proxy listening socket";
-      socketConfig = {
-        ListenStream = localAddress;
-        ListenDatagram = localAddress;
-      };
-      wantedBy = [ "sockets.target" ];
     };
-
-    systemd.services.dnscrypt-proxy = {
-      description = "dnscrypt-proxy daemon";
-
-      before = [ "nss-lookup.target" ];
-
-      after = [ "network.target" ]
-        ++ optional apparmorEnabled "apparmor.service"
-        ++ optional useUpstreamResolverList "init-dnscrypt-proxy-statedir.service";
-
-      requires = [ "dnscrypt-proxy.socket "]
-        ++ optional apparmorEnabled "apparmor.service"
-        ++ optional useUpstreamResolverList "init-dnscrypt-proxy-statedir.service";
-
-      serviceConfig = {
-        Type = "simple";
-        NonBlocking = "true";
-        ExecStart = "${dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}";
-
-        User = "dnscrypt-proxy";
-
-        PrivateTmp = true;
-        PrivateDevices = true;
-        ProtectHome = true;
-      };
-    };
-  };
+    })
+    ]);
+
+  imports = [
+    (mkRenamedOptionModule [ "services" "dnscrypt-proxy" "port" ] [ "services" "dnscrypt-proxy" "localPort" ])
+
+    (mkChangedOptionModule
+      [ "services" "dnscrypt-proxy" "tcpOnly" ]
+      [ "services" "dnscrypt-proxy" "extraArgs" ]
+      (config:
+        let val = getAttrFromPath [ "services" "dnscrypt-proxy" "tcpOnly" ] config; in
+        optional val "-T"))
+
+    (mkChangedOptionModule
+      [ "services" "dnscrypt-proxy" "ephemeralKeys" ]
+      [ "services" "dnscrypt-proxy" "extraArgs" ]
+      (config:
+        let val = getAttrFromPath [ "services" "dnscrypt-proxy" "ephemeralKeys" ] config; in
+        optional val "-E"))
+
+    (mkRemovedOptionModule [ "services" "dnscrypt-proxy" "resolverList" ] ''
+      The current resolver listing from upstream is always used
+      unless a custom resolver is specified.
+    '')
+  ];
 }
diff --git a/nixos/modules/services/networking/dnscrypt-proxy.xml b/nixos/modules/services/networking/dnscrypt-proxy.xml
index 982961833ad2..555c6df4d551 100644
--- a/nixos/modules/services/networking/dnscrypt-proxy.xml
+++ b/nixos/modules/services/networking/dnscrypt-proxy.xml
@@ -31,15 +31,12 @@
 
   </sect1>
 
-  <sect1><title>As a forwarder for a caching DNS client</title>
+  <sect1><title>As a forwarder for another DNS client</title>
 
   <para>
-    By default, DNSCrypt proxy acts as a transparent proxy for the
-    system stub resolver. Because the client does not cache lookups, this
-    setup can significantly slow down e.g., web browsing. The recommended
-    configuration is to run DNSCrypt proxy as a forwarder for a caching DNS
-    client. To achieve this, change the default proxy listening port to
-    a non-standard value and point the caching client to it:
+    To run the DNSCrypt proxy client as a forwarder for another
+    DNS client, change the default proxy listening port to a
+    non-standard value and point the other client to it:
     <programlisting>
       services.dnscrypt-proxy.localPort = 43;
     </programlisting>
@@ -60,7 +57,6 @@
   <para>
     <programlisting>
       {
-        networking.nameservers = [ "127.0.0.1" ];
         services.unbound.enable = true;
         services.unbound.forwardAddresses = [ "127.0.0.1@43" ];
       }
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index c11d4434c206..7255ffc5af4b 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -24,6 +24,8 @@ let
 
     [connection]
     ipv6.ip6-privacy=2
+    ethernet.cloned-mac-address=${cfg.ethernet.macAddress}
+    wifi.cloned-mac-address=${cfg.wifi.macAddress}
   '';
 
   /*
@@ -73,6 +75,19 @@ let
     "pre-down" = "pre-down.d/";
   };
 
+  macAddressOpt = mkOption {
+    type = types.either types.str (types.enum ["permanent" "preserve" "random" "stable"]);
+    default = "preserve";
+    example = "00:11:22:33:44:55";
+    description = ''
+      "XX:XX:XX:XX:XX:XX": MAC address of the interface.
+      <literal>permanent</literal>: use the permanent MAC address of the device.
+      <literal>preserve</literal>: don’t change the MAC address of the device upon activation.
+      <literal>random</literal>: generate a randomized value upon each connect.
+      <literal>stable</literal>: generate a stable, hashed MAC address.
+    '';
+  };
+
 in {
 
   ###### interface
@@ -140,6 +155,9 @@ in {
         '';
       };
 
+      ethernet.macAddress = macAddressOpt;
+      wifi.macAddress = macAddressOpt;
+
       dispatcherScripts = mkOption {
         type = types.listOf (types.submodule {
           options = {
@@ -229,6 +247,7 @@ in {
 
     systemd.services."network-manager" = {
       wantedBy = [ "network.target" ];
+      restartTriggers = [ configFile ];
 
       preStart = ''
         mkdir -m 700 -p /etc/NetworkManager/system-connections
diff --git a/nixos/modules/services/networking/nftables.nix b/nixos/modules/services/networking/nftables.nix
new file mode 100644
index 000000000000..029c3df89932
--- /dev/null
+++ b/nixos/modules/services/networking/nftables.nix
@@ -0,0 +1,125 @@
+{ config, pkgs, lib, ... }:
+with lib;
+let
+  cfg = config.networking.nftables;
+in
+{
+  ###### interface
+
+  options = {
+    networking.nftables.enable = mkOption {
+      type = types.bool;
+      default = false;
+      description =
+        ''
+          Whether to enable nftables.  nftables is a Linux-based packet
+          filtering framework intended to replace frameworks like iptables.
+
+          This conflicts with the standard networking firewall, so make sure to
+          disable it before using nftables.
+        '';
+    };
+    networking.nftables.ruleset = mkOption {
+      type = types.lines;
+      example = ''
+        # Check out https://wiki.nftables.org/ for better documentation.
+        # Table for both IPv4 and IPv6.
+        table inet filter {
+          # Block all incomming connections traffic except SSH and "ping".
+          chain input {
+            type filter hook input priority 0;
+
+            # accept any localhost traffic
+            iifname lo accept
+
+            # accept traffic originated from us
+            ct state {established, related} accept
+
+            # ICMP
+            # routers may also want: mld-listener-query, nd-router-solicit
+            ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
+            ip protocol icmp icmp type { destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept
+
+            # allow "ping"
+            ip6 nexthdr icmp icmpv6 type echo-request accept
+            ip protocol icmp icmp type echo-request accept
+
+            # accept SSH connections (required for a server)
+            tcp dport 22 accept
+
+            # count and drop any other traffic
+            counter drop
+          }
+
+          # Allow all outgoing connections.
+          chain output {
+            type filter hook output priority 0;
+            accept
+          }
+
+          chain forward {
+            type filter hook forward priority 0;
+            accept
+          }
+        }
+      '';
+      description =
+        ''
+          The ruleset to be used with nftables.  Should be in a format that
+          can be loaded using "/bin/nft -f".  The ruleset is updated atomically.
+        '';
+    };
+    networking.nftables.rulesetFile = mkOption {
+      type = types.path;
+      default = pkgs.writeTextFile {
+        name = "nftables-rules";
+        text = cfg.ruleset;
+      };
+      description =
+        ''
+          The ruleset file to be used with nftables.  Should be in a format that
+          can be loaded using "nft -f".  The ruleset is updated atomically.
+        '';
+    };
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+    assertions = [{
+      assertion = config.networking.firewall.enable == false;
+      message = "You can not use nftables with services.networking.firewall.";
+    }];
+    boot.blacklistedKernelModules = [ "ip_tables" ];
+    environment.systemPackages = [ pkgs.nftables ];
+    systemd.services.nftables = {
+      description = "nftables firewall";
+      before = [ "network-pre.target" ];
+      wants = [ "network-pre.target" ];
+      wantedBy = [ "multi-user.target" ];
+      reloadIfChanged = true;
+      serviceConfig = let
+        rulesScript = pkgs.writeScript "nftables-rules" ''
+          #! ${pkgs.nftables}/bin/nft -f
+          flush ruleset
+          include "${cfg.rulesetFile}"
+        '';
+        checkScript = pkgs.writeScript "nftables-check" ''
+          #! ${pkgs.stdenv.shell} -e
+          if $(${pkgs.kmod}/bin/lsmod | grep -q ip_tables); then
+            echo "Unload ip_tables before using nftables!" 1>&2
+            exit 1
+          else
+            ${rulesScript}
+          fi
+        '';
+      in {
+        Type = "oneshot";
+        RemainAfterExit = true;
+        ExecStart = checkScript;
+        ExecReload = checkScript;
+        ExecStop = "${pkgs.nftables}/bin/nft flush ruleset";
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/networking/openntpd.nix b/nixos/modules/services/networking/openntpd.nix
index 13a1b5258ce0..4bb9da54fe09 100644
--- a/nixos/modules/services/networking/openntpd.nix
+++ b/nixos/modules/services/networking/openntpd.nix
@@ -11,6 +11,9 @@ let
     ${concatStringsSep "\n" (map (s: "server ${s}") cfg.servers)}
     ${cfg.extraConfig}
   '';
+
+  pidFile = "/run/openntpd.pid";
+
 in
 {
   ###### interface
@@ -67,7 +70,11 @@ in
       wants = [ "network-online.target" "time-sync.target" ];
       before = [ "time-sync.target" ];
       after = [ "dnsmasq.service" "bind.service" "network-online.target" ];
-      serviceConfig.ExecStart = "${package}/sbin/ntpd -d -f ${cfgFile} ${cfg.extraOptions}";
+      serviceConfig = {
+        ExecStart = "${package}/sbin/ntpd -f ${cfgFile} -p ${pidFile} ${cfg.extraOptions}";
+        Type = "forking";
+        PIDFile = pidFile;
+      };
     };
   };
 }
diff --git a/nixos/modules/services/networking/prosody.nix b/nixos/modules/services/networking/prosody.nix
index 5682b506344c..feaa007de15e 100644
--- a/nixos/modules/services/networking/prosody.nix
+++ b/nixos/modules/services/networking/prosody.nix
@@ -265,7 +265,8 @@ in
     systemd.services.prosody = {
 
       description = "Prosody XMPP server";
-      after = [ "network.target" ];
+      after = [ "network-online.target" ];
+      wants = [ "network-online.target" ];
       wantedBy = [ "multi-user.target" ];
       serviceConfig = {
         User = "prosody";
diff --git a/nixos/modules/services/networking/searx.nix b/nixos/modules/services/networking/searx.nix
index b852e4e6dc86..3520c6d3f7da 100644
--- a/nixos/modules/services/networking/searx.nix
+++ b/nixos/modules/services/networking/searx.nix
@@ -19,6 +19,7 @@ in
     services.searx = {
 
       enable = mkOption {
+        type = types.bool;
         default = false;
         description = "
           Whether to enable the Searx server. See https://github.com/asciimoo/searx
@@ -26,6 +27,7 @@ in
       };
 
       configFile = mkOption {
+        type = types.path;
         default = "";
         description = "
           The path of the Searx server configuration file. If no file
@@ -35,7 +37,9 @@ in
       };
 
       package = mkOption {
+        type = types.package;
         default = pkgs.pythonPackages.searx;
+        defaultText = "pkgs.pythonPackages.searx";
         description = "searx package to use.";
       };
 
diff --git a/nixos/modules/services/networking/tinc.nix b/nixos/modules/services/networking/tinc.nix
index f8e68fda7fc2..6cb40185274d 100644
--- a/nixos/modules/services/networking/tinc.nix
+++ b/nixos/modules/services/networking/tinc.nix
@@ -18,7 +18,7 @@ in
 
       networks = mkOption {
         default = { };
-        type = with types; loaOf (submodule {
+        type = with types; attrsOf (submodule {
           options = {
 
             extraConfig = mkOption {
@@ -59,7 +59,7 @@ in
 
             hosts = mkOption {
               default = { };
-              type = types.loaOf types.lines;
+              type = types.attrsOf types.lines;
               description = ''
                 The name of the host in the network as well as the configuration for that host.
                 This name should only contain alphanumerics and underscores.
diff --git a/nixos/modules/services/networking/znc.nix b/nixos/modules/services/networking/znc.nix
index 76ba78ff366f..0d41e3ea92ce 100644
--- a/nixos/modules/services/networking/znc.nix
+++ b/nixos/modules/services/networking/znc.nix
@@ -208,7 +208,7 @@ in
 
         networks = mkOption {
           default = { };
-          type = with types; loaOf (submodule networkOpts);
+          type = with types; attrsOf (submodule networkOpts);
           description = ''
             IRC networks to connect the user to.
           '';
diff --git a/nixos/modules/services/scheduling/fcron.nix b/nixos/modules/services/scheduling/fcron.nix
index e4ada2768715..bd1ecb40969b 100644
--- a/nixos/modules/services/scheduling/fcron.nix
+++ b/nixos/modules/services/scheduling/fcron.nix
@@ -23,7 +23,8 @@ let
   allowdeny = target: users:
     { source = pkgs.writeText "fcron.${target}" (concatStringsSep "\n" users);
       target = "fcron.${target}";
-      mode = "600"; # fcron has some security issues.. So I guess this is most safe
+      mode = "644";
+      gid = config.ids.gids.fcron;
     };
 
 in
@@ -89,7 +90,7 @@ in
       [ (allowdeny "allow" (cfg.allow))
         (allowdeny "deny" cfg.deny)
         # see man 5 fcron.conf
-        { source = pkgs.writeText "fcon.conf" ''
+        { source = pkgs.writeText "fcron.conf" ''
             fcrontabs   =       /var/spool/fcron
             pidfile     =       /var/run/fcron.pid
             fifofile    =       /var/run/fcron.fifo
@@ -97,16 +98,40 @@ in
             fcrondeny   =       /etc/fcron.deny
             shell       =       /bin/sh
             sendmail    =       /run/wrappers/bin/sendmail
-            editor      =       /run/current-system/sw/bin/vi
+            editor      =       ${pkgs.vim}/bin/vim
           '';
           target = "fcron.conf";
-          mode = "0600"; # max allowed is 644
+          gid = config.ids.gids.fcron;
+          mode = "0644";
         }
       ];
 
     environment.systemPackages = [ pkgs.fcron ];
-
-    security.wrappers.fcrontab.source = "${pkgs.fcron.out}/bin/fcrontab";
+    users.extraUsers.fcron = {
+      uid = config.ids.uids.fcron;
+      home = "/var/spool/fcron";
+      group = "fcron";
+    };
+    users.groups.fcron.gid = config.ids.gids.fcron;
+
+    security.wrappers = {
+      fcrontab = {
+        source = "${pkgs.fcron}/bin/fcrontab";
+        owner = "fcron";
+        group = "fcron";
+        setgid = true;
+      };
+      fcrondyn = {
+        source = "${pkgs.fcron}/bin/fcrondyn";
+        owner = "fcron";
+        group = "fcron";
+        setgid = true;
+      };
+      fcronsighup = {
+        source = "${pkgs.fcron}/bin/fcronsighup";
+        group = "fcron";
+      };
+    };
     systemd.services.fcron = {
       description = "fcron daemon";
       after = [ "local-fs.target" ];
@@ -118,14 +143,17 @@ in
       };
 
       preStart = ''
-        ${pkgs.coreutils}/bin/mkdir -m 0700 -p /var/spool/fcron
+        ${pkgs.coreutils}/bin/mkdir -m 0770 -p /var/spool/fcron
+        ${pkgs.coreutils}/bin/chown -R fcron:fcron /var/spool/fcron
         # load system crontab file
-        ${pkgs.fcron}/bin/fcrontab -u systab ${pkgs.writeText "systab" cfg.systab}
+        set -x
+        #${pkgs.fcron}/bin/fcrontab -u systab ${pkgs.writeText "systab" cfg.systab}
       '';
 
-      serviceConfig.Type = "forking";
-
-      script = "${pkgs.fcron}/sbin/fcron -m ${toString cfg.maxSerialJobs} ${queuelen}";
+      serviceConfig = {
+        Type = "forking";
+        ExecStart = "${pkgs.fcron}/sbin/fcron -m ${toString cfg.maxSerialJobs} ${queuelen}";
+      };
     };
   };
 }
diff --git a/nixos/modules/services/security/physlock.nix b/nixos/modules/services/security/physlock.nix
index 34d0be3b1beb..0881483967c6 100644
--- a/nixos/modules/services/security/physlock.nix
+++ b/nixos/modules/services/security/physlock.nix
@@ -26,17 +26,7 @@ in
           This will switch to a new virtual terminal, turn off console
           switching and disable SysRq mechanism (when
           <option>services.physlock.disableSysRq</option> is set)
-          until the root or <option>services.physlock.user</option>
-          password is given.
-        '';
-      };
-
-      user = mkOption {
-        type = types.nullOr types.str;
-        default = null;
-        description = ''
-          User whose password will be used to unlock the screen on par
-          with the root password.
+          until the root or user password is given.
         '';
       };
 
@@ -105,7 +95,7 @@ in
               ++ cfg.lockOn.extraTargets;
       serviceConfig.Type = "forking";
       script = ''
-        ${pkgs.physlock}/bin/physlock -d${optionalString cfg.disableSysRq "s"}${optionalString (cfg.user != null) " -u ${cfg.user}"}
+        ${pkgs.physlock}/bin/physlock -d${optionalString cfg.disableSysRq "s"}
       '';
     };
 
diff --git a/nixos/modules/services/system/dbus-session-local.conf.in b/nixos/modules/services/system/dbus-session-local.conf.in
deleted file mode 100644
index 5fd6f80a3539..000000000000
--- a/nixos/modules/services/system/dbus-session-local.conf.in
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-<busconfig>
-  @extra@
-</busconfig>
diff --git a/nixos/modules/services/system/dbus-system-local.conf.in b/nixos/modules/services/system/dbus-system-local.conf.in
deleted file mode 100644
index edbb476f585a..000000000000
--- a/nixos/modules/services/system/dbus-system-local.conf.in
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-<busconfig>
-  <servicehelper>@servicehelper@</servicehelper>
-  @extra@
-</busconfig>
diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix
index 33bc890a78c8..643bec188142 100644
--- a/nixos/modules/services/system/dbus.nix
+++ b/nixos/modules/services/system/dbus.nix
@@ -10,32 +10,10 @@ let
 
   homeDir = "/run/dbus";
 
-  systemExtraxml = concatStrings (flip concatMap cfg.packages (d: [
-    "<servicedir>${d}/share/dbus-1/system-services</servicedir>"
-    "<includedir>${d}/etc/dbus-1/system.d</includedir>"
-  ]));
-
-  sessionExtraxml = concatStrings (flip concatMap cfg.packages (d: [
-    "<servicedir>${d}/share/dbus-1/services</servicedir>"
-    "<includedir>${d}/etc/dbus-1/session.d</includedir>"
-  ]));
-
-  configDir = pkgs.runCommand "dbus-conf"
-    { preferLocalBuild = true;
-      allowSubstitutes = false;
-    }
-    ''
-      mkdir -p $out
-
-      sed '${./dbus-system-local.conf.in}' \
-        -e 's,@servicehelper@,${config.security.wrapperDir}/dbus-daemon-launch-helper,g' \
-        -e 's,@extra@,${systemExtraxml},' \
-        > "$out/system-local.conf"
-
-      sed '${./dbus-session-local.conf.in}' \
-        -e 's,@extra@,${sessionExtraxml},' \
-        > "$out/session-local.conf"
-    '';
+  configDir = pkgs.makeDBusConf {
+    suidHelper = "${config.security.wrapperDir}/dbus-daemon-launch-helper";
+    serviceDirectories = cfg.packages;
+  };
 
 in
 
diff --git a/nixos/modules/services/ttys/kmscon.nix b/nixos/modules/services/ttys/kmscon.nix
index ba25f9128445..8bad42927e3f 100644
--- a/nixos/modules/services/ttys/kmscon.nix
+++ b/nixos/modules/services/ttys/kmscon.nix
@@ -76,7 +76,7 @@ in {
           ln -s ${config.systemd.units."kmsconvt@.service".unit}/kmsconvt@.service $out/autovt@.service
         '';
 
-    systemd.services.systemd-vconsole-setup.restartIfChanged = false;
+    systemd.services.systemd-vconsole-setup.enable = false;
 
     services.kmscon.extraConfig = mkIf cfg.hwRender ''
       drm
diff --git a/nixos/modules/services/web-apps/mattermost.nix b/nixos/modules/services/web-apps/mattermost.nix
index bf3a8eed6004..8e6baf6a17e3 100644
--- a/nixos/modules/services/web-apps/mattermost.nix
+++ b/nixos/modules/services/web-apps/mattermost.nix
@@ -202,6 +202,7 @@ in
           ExecStart = "${pkgs.mattermost}/bin/mattermost-platform";
           WorkingDirectory = "${cfg.statePath}";
           PrivateTmp = true;
+          JoinsNamespaceOf = mkIf cfg.localDatabaseCreate "postgresql.service";
           Restart = "always";
           RestartSec = "10";
           LimitNOFILE = "49152";
diff --git a/nixos/modules/services/web-apps/pump.io-configure.js b/nixos/modules/services/web-apps/pump.io-configure.js
new file mode 100644
index 000000000000..1fbf346a34c4
--- /dev/null
+++ b/nixos/modules/services/web-apps/pump.io-configure.js
@@ -0,0 +1,23 @@
+var fs = require('fs');
+
+var opts = JSON.parse(fs.readFileSync("/dev/stdin").toString());
+var config = opts.config;
+
+var readSecret = function(filename) {
+  return fs.readFileSync(filename).toString().trim();
+};
+
+if (opts.secretFile) {
+  config.secret = readSecret(opts.secretFile);
+}
+if (opts.dbPasswordFile) {
+  config.params.dbpass = readSecret(opts.dbPasswordFile);
+}
+if (opts.smtpPasswordFile) {
+  config.smtppass = readSecret(opts.smtpPasswordFile);
+}
+if (opts.spamClientSecretFile) {
+  config.spamclientsecret = readSecret(opts.opts.spamClientSecretFile);
+}
+
+fs.writeFileSync(opts.outputFile, JSON.stringify(config));
diff --git a/nixos/modules/services/web-apps/pump.io.nix b/nixos/modules/services/web-apps/pump.io.nix
index b7c64bc6940b..27ae68516367 100644
--- a/nixos/modules/services/web-apps/pump.io.nix
+++ b/nixos/modules/services/web-apps/pump.io.nix
@@ -5,71 +5,74 @@ with lib;
 let
   cfg = config.services.pumpio;
   dataDir = "/var/lib/pump.io";
+  runDir = "/run/pump.io";
   user = "pumpio";
 
+  optionalSet = condition: value: if condition then value else {};
+
+  configScript = ./pump.io-configure.js;
   configOptions = {
-    driver = if cfg.driver == "disk" then null else cfg.driver;
-    params = ({ } //
-    (if cfg.driver == "disk" then {
-      dir = dataDir;
-     } else { }) //
-    (if cfg.driver == "mongodb" || cfg.driver == "redis" then {
-       host = cfg.dbHost;
-       port = cfg.dbPort;
-       dbname = cfg.dbName;
-       dbuser = cfg.dbUser;
-       dbpass = cfg.dbPassword;
-     } else { }) //
-    (if cfg.driver == "memcached" then {
-       host = cfg.dbHost;
-       port = cfg.dbPort;
-     } else { }) //
-     cfg.driverParams);
-
-    secret = cfg.secret;
-
-    address = cfg.address;
-    port = cfg.port;
-
-    noweb = false;
-    urlPort = cfg.urlPort;
-    hostname = cfg.hostname;
-    favicon = cfg.favicon;
-
-    site = cfg.site;
-    owner = cfg.owner;
-    ownerURL = cfg.ownerURL;
-
-    key = cfg.sslKey;
-    cert = cfg.sslCert;
-    bounce = false;
-
-    spamhost = cfg.spamHost;
-    spamclientid = cfg.spamClientId;
-    spamclientsecret = cfg.spamClientSecret;
-
-    requireEmail = cfg.requireEmail;
-    smtpserver = cfg.smtpHost;
-    smtpport = cfg.smtpPort;
-    smtpuser = cfg.smtpUser;
-    smtppass = cfg.smtpPassword;
-    smtpusessl = cfg.smtpUseSSL;
-    smtpfrom = cfg.smtpFrom;
-
-    nologger = false;
-    uploaddir =  "${dataDir}/uploads";
-    debugClient = false;
-    firehose = cfg.firehose;
-    disableRegistration = cfg.disableRegistration;
-  } //
-  (if cfg.port < 1024 then {
-    serverUser = user;  # have pump.io listen then drop privileges
-   } else { }) //
-  cfg.extraConfig;
-
-in
-
-{
+    outputFile = "${runDir}/config.json";
+    config =
+      (optionalSet (cfg.driver != "disk") {
+        driver = cfg.driver;
+      }) //
+      {
+        params = (optionalSet (cfg.driver == "disk") { dir = dataDir; }) //
+                 (optionalSet (cfg.driver == "mongodb" || cfg.driver == "redis") {
+                   host = cfg.dbHost;
+                   port = cfg.dbPort;
+                   dbname = cfg.dbName;
+                   dbuser = cfg.dbUser;
+                   dbpass = cfg.dbPassword;
+                 }) //
+                 (optionalSet (cfg.driver == "memcached") {
+                   host = cfg.dbHost;
+                   port = cfg.dbPort;
+                 }) // cfg.driverParams;
+        secret = cfg.secret;
+
+        address = cfg.address;
+        port = cfg.port;
+
+        noweb = false;
+        urlPort = cfg.urlPort;
+        hostname = cfg.hostname;
+        favicon = cfg.favicon;
+
+        site = cfg.site;
+        owner = cfg.owner;
+        ownerURL = cfg.ownerURL;
+
+        key = cfg.sslKey;
+        cert = cfg.sslCert;
+        bounce = false;
+
+        spamhost = cfg.spamHost;
+        spamclientid = cfg.spamClientId;
+        spamclientsecret = cfg.spamClientSecret;
+
+        requireEmail = cfg.requireEmail;
+        smtpserver = cfg.smtpHost;
+        smtpport = cfg.smtpPort;
+        smtpuser = cfg.smtpUser;
+        smtppass = cfg.smtpPassword;
+        smtpusessl = cfg.smtpUseSSL;
+        smtpfrom = cfg.smtpFrom;
+
+        nologger = false;
+        enableUploads = cfg.enableUploads;
+        datadir = dataDir;
+        debugClient = false;
+        firehose = cfg.firehose;
+        disableRegistration = cfg.disableRegistration;
+
+        inherit (cfg) secretFile dbPasswordFile smtpPasswordFile spamClientSecretFile;
+      } //
+      (optionalSet (cfg.port < 1024) {
+        serverUser = user;  # have pump.io listen then drop privileges
+      }) // cfg.extraConfig;
+}; in {
   options = {
 
     services.pumpio = {
@@ -77,7 +80,8 @@ in
       enable = mkEnableOption "Pump.io social streams server";
 
       secret = mkOption {
-        type = types.str;
+        type = types.nullOr types.str;
+        default = null;
         example = "my dog has fleas";
         description = ''
           A session-generating secret, server-wide password.  Warning:
@@ -85,6 +89,16 @@ in
         '';
       };
 
+      secretFile = mkOption {
+        type = types.nullOr types.path;
+        default = null;
+        example = "/run/keys/pump.io-secret";
+        description = ''
+          A file containing the session-generating secret,
+          server-wide password.
+        '';
+      };
+
       site = mkOption {
         type = types.str;
         example = "Awesome Sauce";
@@ -125,7 +139,7 @@ in
 
       hostname = mkOption {
         type = types.nullOr types.str;
-        default = null;
+        default = "localhost";
         description = ''
           The hostname of the server, used for generating
           URLs. Defaults to "localhost" which doesn't do much for you.
@@ -152,6 +166,15 @@ in
         '';
       };
 
+      enableUploads = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          If you want to disable file uploads, set this to false. Uploaded files will be stored
+          in ${dataDir}/uploads.
+        '';
+      };
+
       sslKey = mkOption {
         type = types.path;
         example = "${dataDir}/myserver.key";
@@ -253,6 +276,15 @@ in
         '';
       };
 
+      dbPasswordFile = mkOption {
+        type = types.nullOr types.path;
+        default = null;
+        example = "/run/keys/pump.io-dbpassword";
+        description = ''
+          A file containing the password corresponding to dbUser.
+        '';
+      };
+
       smtpHost = mkOption {
         type = types.nullOr types.str;
         default = null;
@@ -291,6 +323,17 @@ in
         '';
       };
 
+      smtpPasswordFile = mkOption {
+        type = types.nullOr types.path;
+        default = null;
+        example = "/run/keys/pump.io-smtppassword";
+        description = ''
+          A file containing the password used to connect to SMTP
+          server. Might not be necessary for some servers.
+        '';
+      };
+
+
       smtpUseSSL = mkOption {
         type = types.bool;
         default = false;
@@ -332,24 +375,55 @@ in
           stored in cleartext in the Nix store!
         '';
       };
+      spamClientSecretFile = mkOption {
+        type = types.nullOr types.path;
+        default = null;
+        example = "/run/keys/pump.io-spamclientsecret";
+        description = ''
+          A file containing the OAuth key for the spam server.
+        '';
+      };
     };
 
   };
 
   config = mkIf cfg.enable {
+    warnings = let warn = k: optional (cfg.${k} != null)
+                 "config.services.pumpio.${k} is insecure. Use ${k}File instead.";
+               in concatMap warn [ "secret" "dbPassword" "smtpPassword" "spamClientSecret" ];
+
+    assertions = [
+      { assertion = !(isNull cfg.secret && isNull cfg.secretFile);
+        message = "pump.io needs a secretFile configured";
+      }
+    ];
+
     systemd.services."pump.io" =
-      { description = "pump.io social network stream server";
+      { description = "Pump.io - stream server that does most of what people really want from a social network";
         after = [ "network.target" ];
         wantedBy = [ "multi-user.target" ];
-        serviceConfig.ExecStart = "${pkgs.pumpio}/bin/pump -c /etc/pump.io.json";
-        serviceConfig.User = if cfg.port < 1024 then "root" else user;
-        serviceConfig.Group = user;
-      };
 
-      environment.etc."pump.io.json" = {
-        mode = "0440";
-        gid = config.ids.gids.pumpio;
-        text = builtins.toJSON configOptions;
+        preStart = ''
+          mkdir -p ${dataDir}/uploads
+          mkdir -p ${runDir}
+          chown pumpio:pumpio ${dataDir}/uploads ${runDir}
+          chmod 770 ${dataDir}/uploads ${runDir}
+
+          ${pkgs.nodejs}/bin/node ${configScript} <<EOF
+          ${builtins.toJSON configOptions}
+          EOF
+
+          chgrp pumpio ${configOptions.outputFile}
+          chmod 640 ${configOptions.outputFile}
+        '';
+
+        serviceConfig = {
+          ExecStart = "${pkgs.pumpio}/bin/pump -c ${configOptions.outputFile}";
+          PermissionsStartOnly = true;
+          User = if cfg.port < 1024 then "root" else user;
+          Group = user;
+        };
+        environment = { NODE_ENV = "production"; };
       };
 
       users.extraGroups.pumpio.gid = config.ids.gids.pumpio;
diff --git a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
index a5b6548d3c53..b94ec14308be 100644
--- a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
@@ -4,11 +4,6 @@
 with lib;
 
 let
-
-  # Upgrading? We have a test! nix-build ./nixos/tests/wordpress.nix
-  version = "4.7.2";
-  fullversion = "${version}";
-
   # Our bare-bones wp-config.php file using the above settings
   wordpressConfig = pkgs.writeText "wp-config.php" ''
     <?php
@@ -71,12 +66,7 @@ let
   # The wordpress package itself
   wordpressRoot = pkgs.stdenv.mkDerivation rec {
     name = "wordpress";
-    src = pkgs.fetchFromGitHub {
-      owner = "WordPress";
-      repo = "WordPress";
-      rev = "${fullversion}";
-      sha256 = "0vph12708drf8ww0xd05hpdvbyy7n5gj9ca598lhdhy2i1j6wy32";
-    };
+    src = config.package;
     installPhase = ''
       mkdir -p $out
       # copy all the wordpress files we downloaded
@@ -122,6 +112,14 @@ in
   enablePHP = true;
 
   options = {
+    package = mkOption {
+      type = types.path;
+      default = pkgs.wordpress;
+      description = ''
+        Path to the wordpress sources.
+        Upgrading? We have a test! nix-build ./nixos/tests/wordpress.nix
+      '';
+    };
     dbHost = mkOption {
       default = "localhost";
       description = "The location of the database server.";
diff --git a/nixos/modules/services/web-servers/jboss/default.nix b/nixos/modules/services/web-servers/jboss/default.nix
index 583fe56eb5e2..d28724281a83 100644
--- a/nixos/modules/services/web-servers/jboss/default.nix
+++ b/nixos/modules/services/web-servers/jboss/default.nix
@@ -25,7 +25,7 @@ in
 
       enable = mkOption {
         default = false;
-        description = "Whether to enable jboss";
+        description = "Whether to enable JBoss. WARNING : this package is outdated and is known to have vulnerabilities.";
       };
 
       tempDir = mkOption {
diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix
index 9e93e56b9c2c..6bc7192963d1 100644
--- a/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixos/modules/services/web-servers/nginx/default.nix
@@ -5,13 +5,16 @@ with lib;
 let
   cfg = config.services.nginx;
   virtualHosts = mapAttrs (vhostName: vhostConfig:
-    vhostConfig // {
+    let
       serverName = if vhostConfig.serverName != null
         then vhostConfig.serverName
         else vhostName;
+    in
+    vhostConfig // {
+      inherit serverName;
     } // (optionalAttrs vhostConfig.enableACME {
-      sslCertificate = "/var/lib/acme/${vhostName}/fullchain.pem";
-      sslCertificateKey = "/var/lib/acme/${vhostName}/key.pem";
+      sslCertificate = "/var/lib/acme/${serverName}/fullchain.pem";
+      sslCertificateKey = "/var/lib/acme/${serverName}/key.pem";
     })
   ) cfg.virtualHosts;
   enableIPv6 = config.networking.enableIPv6;
@@ -382,6 +385,7 @@ in
       description = "Nginx Web Server";
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
+      stopIfChanged = false;
       preStart =
         ''
         mkdir -p ${cfg.stateDir}/logs
diff --git a/nixos/modules/services/web-servers/phpfpm/default.nix b/nixos/modules/services/web-servers/phpfpm/default.nix
index ed537e7122a2..efb721c5773f 100644
--- a/nixos/modules/services/web-servers/phpfpm/default.nix
+++ b/nixos/modules/services/web-servers/phpfpm/default.nix
@@ -4,30 +4,35 @@ with lib;
 
 let
   cfg = config.services.phpfpm;
+  enabled = cfg.poolConfigs != {} || cfg.pools != {};
 
   stateDir = "/run/phpfpm";
 
+  poolConfigs = cfg.poolConfigs // mapAttrs mkPool cfg.pools;
+
   mkPool = n: p: ''
-    [${n}]
     listen = ${p.listen}
     ${p.extraConfig}
   '';
 
-  cfgFile = pkgs.writeText "phpfpm.conf" ''
+  fpmCfgFile = pool: poolConfig: pkgs.writeText "phpfpm-${pool}.conf" ''
     [global]
     error_log = syslog
     daemonize = no
     ${cfg.extraConfig}
 
-    ${concatStringsSep "\n" (mapAttrsToList mkPool cfg.pools)}
-
-    ${concatStringsSep "\n" (mapAttrsToList (n: v: "[${n}]\n${v}") cfg.poolConfigs)}
+    [${pool}]
+    ${poolConfig}
   '';
 
-  phpIni = pkgs.writeText "php.ini" ''
-    ${readFile "${cfg.phpPackage}/etc/php.ini"}
-
-    ${cfg.phpOptions}
+  phpIni = pkgs.runCommand "php.ini" {
+    inherit (cfg) phpPackage phpOptions;
+    nixDefaults = ''
+      sendmail_path = "/run/wrappers/bin/sendmail -t -i"
+    '';
+    passAsFile = [ "nixDefaults" "phpOptions" ];
+  } ''
+    cat $phpPackage/etc/php.ini $nixDefaultsPath $phpOptionsPath > $out
   '';
 
 in {
@@ -118,18 +123,41 @@ in {
     };
   };
 
-  config = mkIf (cfg.pools != {} || cfg.poolConfigs != {}) {
+  config = mkIf enabled {
+
+    systemd.slices.phpfpm = {
+      description = "PHP FastCGI Process manager pools slice";
+    };
 
-    systemd.services.phpfpm = {
+    systemd.targets.phpfpm = {
+      description = "PHP FastCGI Process manager pools target";
       wantedBy = [ "multi-user.target" ];
-      preStart = ''
-        mkdir -p "${stateDir}"
-      '';
-      serviceConfig = {
-        Type = "notify";
-        ExecStart = "${cfg.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${phpIni}";
-        ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID";
-      };
     };
+
+    systemd.services = flip mapAttrs' poolConfigs (pool: poolConfig:
+      nameValuePair "phpfpm-${pool}" {
+        description = "PHP FastCGI Process Manager service for pool ${pool}";
+        after = [ "network.target" ];
+        wantedBy = [ "phpfpm.target" ];
+        partOf = [ "phpfpm.target" ];
+        preStart = ''
+          mkdir -p ${stateDir}
+        '';
+        serviceConfig = let
+          cfgFile = fpmCfgFile pool poolConfig;
+        in {
+          Slice = "phpfpm.slice";
+          PrivateTmp = true;
+          PrivateDevices = true;
+          ProtectSystem = "full";
+          ProtectHome = true;
+          NoNewPrivileges = true;
+          RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
+          Type = "notify";
+          ExecStart = "${cfg.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${phpIni}";
+          ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID";
+        };
+      }
+   );
   };
 }
diff --git a/nixos/modules/services/web-servers/zope2.nix b/nixos/modules/services/web-servers/zope2.nix
index 8a453e015577..496e34db4a96 100644
--- a/nixos/modules/services/web-servers/zope2.nix
+++ b/nixos/modules/services/web-servers/zope2.nix
@@ -74,7 +74,7 @@ in
 
     services.zope2.instances = mkOption {
       default = {};
-      type = with types; loaOf (submodule zope2Opts);
+      type = with types; attrsOf (submodule zope2Opts);
       example = literalExample ''
         {
           plone01 = {
diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix
index 1f7a925ed054..af01f6acad18 100644
--- a/nixos/modules/services/x11/desktop-managers/default.nix
+++ b/nixos/modules/services/x11/desktop-managers/default.nix
@@ -16,9 +16,9 @@ in
 {
   # Note: the order in which desktop manager modules are imported here
   # determines the default: later modules (if enabled) are preferred.
-  # E.g., if KDE is enabled, it supersedes xterm.
+  # E.g., if Plasma 5 is enabled, it supersedes xterm.
   imports = [
-    ./none.nix ./xterm.nix ./xfce.nix ./kde5.nix ./lumina.nix
+    ./none.nix ./xterm.nix ./xfce.nix ./plasma5.nix ./lumina.nix
     ./lxqt.nix ./enlightenment.nix ./gnome3.nix ./kodi.nix
   ];
 
diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix
deleted file mode 100644
index 1b44b9e42c81..000000000000
--- a/nixos/modules/services/x11/desktop-managers/kde5.nix
+++ /dev/null
@@ -1,255 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
-
-  xcfg = config.services.xserver;
-  cfg = xcfg.desktopManager.kde5;
-  xorg = pkgs.xorg;
-
-  kde5 = pkgs.kde5;
-
-in
-
-{
-  options = {
-
-    services.xserver.desktopManager.kde5 = {
-      enable = mkOption {
-        type = types.bool;
-        default = false;
-        description = "Enable the Plasma 5 (KDE 5) desktop environment.";
-      };
-
-      enableQt4Support = mkOption {
-        type = types.bool;
-        default = true;
-        description = ''
-          Enable support for Qt 4-based applications. Particularly, install the
-          Qt 4 version of the Breeze theme and a default backend for Phonon.
-        '';
-      };
-
-      extraPackages = mkOption {
-        type = types.listOf types.package;
-        default = [];
-        description = ''
-          KDE packages that need to be installed system-wide.
-        '';
-      };
-
-    };
-
-  };
-
-
-  config = mkMerge [
-    (mkIf (cfg.extraPackages != []) {
-      environment.systemPackages = [ (kde5.kdeWrapper cfg.extraPackages) ];
-    })
-
-    (mkIf (xcfg.enable && cfg.enable) {
-      services.xserver.desktopManager.session = singleton {
-        name = "kde5";
-        bgSupport = true;
-        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 ''
-            ${getBin config.hardware.pulseaudio.package}/bin/pactl load-module module-device-manager "do_routing=1"
-          ''}
-
-          exec "${kde5.startkde}"
-        '';
-      };
-
-      security.wrappers = {
-        kcheckpass.source = "${kde5.plasma-workspace.out}/lib/libexec/kcheckpass";
-        "start_kdeinit".source = "${kde5.kinit.out}/lib/libexec/kf5/start_kdeinit";
-      };
-
-      environment.systemPackages =
-        [
-          kde5.frameworkintegration
-          kde5.kactivities
-          kde5.kauth
-          kde5.kcmutils
-          kde5.kconfig
-          kde5.kconfigwidgets
-          kde5.kcoreaddons
-          kde5.kdbusaddons
-          kde5.kdeclarative
-          kde5.kded
-          kde5.kdesu
-          kde5.kdnssd
-          kde5.kemoticons
-          kde5.kfilemetadata
-          kde5.kglobalaccel
-          kde5.kguiaddons
-          kde5.kiconthemes
-          kde5.kidletime
-          kde5.kimageformats
-          kde5.kinit
-          kde5.kio
-          kde5.kjobwidgets
-          kde5.knewstuff
-          kde5.knotifications
-          kde5.knotifyconfig
-          kde5.kpackage
-          kde5.kparts
-          kde5.kpeople
-          kde5.krunner
-          kde5.kservice
-          kde5.ktextwidgets
-          kde5.kwallet
-          kde5.kwallet-pam
-          kde5.kwalletmanager
-          kde5.kwayland
-          kde5.kwidgetsaddons
-          kde5.kxmlgui
-          kde5.kxmlrpcclient
-          kde5.plasma-framework
-          kde5.solid
-          kde5.sonnet
-          kde5.threadweaver
-
-          kde5.breeze-qt5
-          kde5.kactivitymanagerd
-          kde5.kde-cli-tools
-          kde5.kdecoration
-          kde5.kdeplasma-addons
-          kde5.kgamma5
-          kde5.khotkeys
-          kde5.kinfocenter
-          kde5.kmenuedit
-          kde5.kscreen
-          kde5.kscreenlocker
-          kde5.ksysguard
-          kde5.kwayland
-          kde5.kwin
-          kde5.kwrited
-          kde5.libkscreen
-          kde5.libksysguard
-          kde5.milou
-          kde5.plasma-integration
-          kde5.polkit-kde-agent
-          kde5.systemsettings
-
-          kde5.plasma-desktop
-          kde5.plasma-workspace
-          kde5.plasma-workspace-wallpapers
-
-          kde5.dolphin-plugins
-          kde5.ffmpegthumbs
-          kde5.kdegraphics-thumbnailers
-          kde5.kio-extras
-          kde5.print-manager
-
-          # Install Breeze icons if available
-          (kde5.breeze-icons or kde5.oxygen-icons5 or kde5.oxygen-icons)
-          pkgs.hicolor_icon_theme
-
-          kde5.kde-gtk-config kde5.breeze-gtk
-
-          pkgs.qt5.phonon-backend-gstreamer
-        ]
-
-        # Plasma 5.5 and later has a Breeze GTK theme.
-        # If it is not available, Orion is very similar to Breeze.
-        ++ lib.optional (!(lib.hasAttr "breeze-gtk" kde5)) pkgs.orion
-
-        # Install activity manager if available
-        ++ lib.optional (lib.hasAttr "kactivitymanagerd" kde5) kde5.kactivitymanagerd
-
-        # frameworkintegration was split with plasma-integration in Plasma 5.6
-        ++ lib.optional (lib.hasAttr "plasma-integration" kde5) kde5.plasma-integration
-
-        ++ lib.optionals cfg.enableQt4Support [ kde5.breeze-qt4 pkgs.phonon-backend-gstreamer ]
-
-        # Optional hardware support features
-        ++ lib.optional config.hardware.bluetooth.enable kde5.bluedevil
-        ++ lib.optional config.networking.networkmanager.enable kde5.plasma-nm
-        ++ lib.optional config.hardware.pulseaudio.enable kde5.plasma-pa
-        ++ lib.optional config.powerManagement.enable kde5.powerdevil
-        ++ lib.optional config.services.colord.enable pkgs.colord-kde
-        ++ lib.optionals config.services.samba.enable [ kde5.kdenetwork-filesharing pkgs.samba ];
-
-      services.xserver.desktopManager.kde5.extraPackages =
-        [
-          kde5.khelpcenter
-          kde5.oxygen
-
-          kde5.dolphin
-          kde5.konsole
-        ];
-
-      environment.pathsToLink = [ "/share" ];
-
-      environment.etc = singleton {
-        source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
-        target = "X11/xkb";
-      };
-
-      environment.variables =
-        {
-          # Enable GTK applications to load SVG icons
-          GST_PLUGIN_SYSTEM_PATH_1_0 =
-            lib.makeSearchPath "/lib/gstreamer-1.0"
-            (builtins.map (pkg: pkg.out) (with pkgs.gst_all_1; [
-              gstreamer
-              gst-plugins-base
-              gst-plugins-good
-              gst-plugins-ugly
-              gst-plugins-bad
-              gst-libav # for mp3 playback
-            ]));
-        }
-        // (if (lib.hasAttr "breeze-icons" kde5)
-            then { GDK_PIXBUF_MODULE_FILE = "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"; }
-            else { });
-
-      fonts.fonts = [ (kde5.oxygen-fonts or pkgs.noto-fonts) ];
-
-      programs.ssh.askPassword = "${kde5.ksshaskpass.out}/bin/ksshaskpass";
-
-      # Enable helpful DBus services.
-      services.udisks2.enable = true;
-      services.upower.enable = config.powerManagement.enable;
-      services.dbus.packages =
-        mkIf config.services.printing.enable [ pkgs.system-config-printer ];
-
-      # Extra UDEV rules used by Solid
-      services.udev.packages = [
-        pkgs.libmtp
-        pkgs.media-player-info
-      ];
-
-      services.xserver.displayManager.sddm = {
-        theme = "breeze";
-        themes = [
-          kde5.ecm # for the setup-hook
-          kde5.plasma-workspace
-          kde5.breeze-icons
-        ];
-      };
-
-      security.pam.services.kde = { allowNullPassword = true; };
-
-      # Doing these one by one seems silly, but we currently lack a better
-      # construct for handling common pam configs.
-      security.pam.services.gdm.enableKwallet = true;
-      security.pam.services.kdm.enableKwallet = true;
-      security.pam.services.lightdm.enableKwallet = true;
-      security.pam.services.sddm.enableKwallet = true;
-      security.pam.services.slim.enableKwallet = true;
-
-      # use kimpanel as the default IBus panel
-      i18n.inputMethod.ibus.panel =
-        lib.mkDefault
-        "${pkgs.kde5.plasma-desktop}/lib/libexec/kimpanel-ibus-panel";
-
-    })
-  ];
-
-}
diff --git a/nixos/modules/services/x11/desktop-managers/lumina.nix b/nixos/modules/services/x11/desktop-managers/lumina.nix
index f0b31a2acb01..ed5ad4a2a001 100644
--- a/nixos/modules/services/x11/desktop-managers/lumina.nix
+++ b/nixos/modules/services/x11/desktop-managers/lumina.nix
@@ -32,8 +32,8 @@ in
 
     environment.systemPackages = [
       pkgs.fluxbox
-      pkgs.kde5.kwindowsystem
-      pkgs.kde5.oxygen-icons5
+      pkgs.qt5.kwindowsystem
+      pkgs.qt5.oxygen-icons5
       pkgs.lumina
       pkgs.numlockx
       pkgs.qt5.qtsvg
diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix
new file mode 100644
index 000000000000..bc6e728169b4
--- /dev/null
+++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix
@@ -0,0 +1,236 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  xcfg = config.services.xserver;
+  cfg = xcfg.desktopManager.plasma5;
+
+  inherit (pkgs) kdeWrapper kdeApplications plasma5 libsForQt5 qt5 xorg;
+
+in
+
+{
+  options = {
+
+    services.xserver.desktopManager.plasma5 = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Enable the Plasma 5 (KDE 5) desktop environment.";
+      };
+
+      enableQt4Support = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Enable support for Qt 4-based applications. Particularly, install the
+          Qt 4 version of the Breeze theme and a default backend for Phonon.
+        '';
+      };
+
+      extraPackages = mkOption {
+        type = types.listOf types.package;
+        default = [];
+        description = ''
+          KDE packages that need to be installed system-wide.
+        '';
+      };
+
+    };
+
+  };
+
+
+  config = mkMerge [
+    (mkIf (cfg.extraPackages != []) {
+      environment.systemPackages = [ (kdeWrapper cfg.extraPackages) ];
+    })
+
+    (mkIf (xcfg.enable && cfg.enable) {
+      services.xserver.desktopManager.session = singleton {
+        name = "plasma5";
+        bgSupport = true;
+        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 ''
+            ${getBin config.hardware.pulseaudio.package}/bin/pactl load-module module-device-manager "do_routing=1"
+          ''}
+
+          exec "${plasma5.startkde}"
+        '';
+      };
+
+      security.wrappers = {
+        kcheckpass.source = "${plasma5.plasma-workspace.out}/lib/libexec/kcheckpass";
+        "start_kdeinit".source = "${pkgs.kinit.out}/lib/libexec/kf5/start_kdeinit";
+      };
+
+      environment.systemPackages = with pkgs; with qt5; with libsForQt5; with plasma5; with kdeApplications;
+        [
+          frameworkintegration
+          kactivities
+          kauth
+          kcmutils
+          kconfig
+          kconfigwidgets
+          kcoreaddons
+          kdbusaddons
+          kdeclarative
+          kded
+          kdesu
+          kdnssd
+          kemoticons
+          kfilemetadata
+          kglobalaccel
+          kguiaddons
+          kiconthemes
+          kidletime
+          kimageformats
+          kinit
+          kio
+          kjobwidgets
+          knewstuff
+          knotifications
+          knotifyconfig
+          kpackage
+          kparts
+          kpeople
+          krunner
+          kservice
+          ktextwidgets
+          kwallet
+          kwallet-pam
+          kwalletmanager
+          kwayland
+          kwidgetsaddons
+          kxmlgui
+          kxmlrpcclient
+          plasma-framework
+          solid
+          sonnet
+          threadweaver
+
+          breeze-qt5
+          kactivitymanagerd
+          kde-cli-tools
+          kdecoration
+          kdeplasma-addons
+          kgamma5
+          khotkeys
+          kinfocenter
+          kmenuedit
+          kscreen
+          kscreenlocker
+          ksysguard
+          kwayland
+          kwin
+          kwrited
+          libkscreen
+          libksysguard
+          milou
+          plasma-integration
+          polkit-kde-agent
+          systemsettings
+
+          plasma-desktop
+          plasma-workspace
+          plasma-workspace-wallpapers
+
+          dolphin-plugins
+          ffmpegthumbs
+          kdegraphics-thumbnailers
+          kio-extras
+          print-manager
+
+          breeze-icons
+          pkgs.hicolor_icon_theme
+
+          kde-gtk-config breeze-gtk
+
+          phonon-backend-gstreamer
+        ]
+
+        ++ lib.optionals cfg.enableQt4Support [ breeze-qt4 pkgs.phonon-backend-gstreamer ]
+
+        # Optional hardware support features
+        ++ lib.optional config.hardware.bluetooth.enable bluedevil
+        ++ lib.optional config.networking.networkmanager.enable plasma-nm
+        ++ lib.optional config.hardware.pulseaudio.enable plasma-pa
+        ++ lib.optional config.powerManagement.enable powerdevil
+        ++ lib.optional config.services.colord.enable colord-kde
+        ++ lib.optionals config.services.samba.enable [ kdenetwork-filesharing pkgs.samba ];
+
+      services.xserver.desktopManager.plasma5.extraPackages =
+        with kdeApplications; with plasma5;
+        [
+          khelpcenter
+          oxygen
+
+          dolphin
+          konsole
+        ];
+
+      environment.pathsToLink = [ "/share" ];
+
+      environment.etc = singleton {
+        source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
+        target = "X11/xkb";
+      };
+
+      environment.variables = {
+        # Enable GTK applications to load SVG icons
+        GDK_PIXBUF_MODULE_FILE = "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache";
+      };
+
+      fonts.fonts = with pkgs; [ noto-fonts hack-font ];
+      fonts.fontconfig.defaultFonts = {
+        monospace = [ "Hack" "Noto Mono" ];
+        sansSerif = [ "Noto Sans" ];
+        serif = [ "Noto Serif" ];
+      };
+
+      programs.ssh.askPassword = "${plasma5.ksshaskpass.out}/bin/ksshaskpass";
+
+      # Enable helpful DBus services.
+      services.udisks2.enable = true;
+      services.upower.enable = config.powerManagement.enable;
+      services.dbus.packages =
+        mkIf config.services.printing.enable [ pkgs.system-config-printer ];
+
+      # Extra UDEV rules used by Solid
+      services.udev.packages = [
+        pkgs.libmtp
+        pkgs.media-player-info
+      ];
+
+      services.xserver.displayManager.sddm = {
+        theme = "breeze";
+        themes = [
+          pkgs.extra-cmake-modules # for the setup-hook
+          plasma5.plasma-workspace
+          pkgs.breeze-icons
+        ];
+      };
+
+      security.pam.services.kde = { allowNullPassword = true; };
+
+      # Doing these one by one seems silly, but we currently lack a better
+      # construct for handling common pam configs.
+      security.pam.services.gdm.enableKwallet = true;
+      security.pam.services.kdm.enableKwallet = true;
+      security.pam.services.lightdm.enableKwallet = true;
+      security.pam.services.sddm.enableKwallet = true;
+      security.pam.services.slim.enableKwallet = true;
+
+      # use kimpanel as the default IBus panel
+      i18n.inputMethod.ibus.panel =
+        lib.mkDefault
+        "${plasma5.plasma-desktop}/lib/libexec/kimpanel-ibus-panel";
+
+    })
+  ];
+
+}
diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix
index 530468be5f96..9c42dc8781b9 100644
--- a/nixos/modules/services/x11/desktop-managers/xfce.nix
+++ b/nixos/modules/services/x11/desktop-managers/xfce.nix
@@ -41,6 +41,18 @@ in
           Shell commands executed just before XFCE is started.
         '';
       };
+
+      enableXfwm = mkOption {
+        type = types.bool;
+        default = true;
+        description = "Enable the XFWM (default) window manager.";
+      };
+
+      screenLock = mkOption {
+        type = types.enum [ "xscreensaver" "xlockmore" "slock" ];
+        default = "xlockmore";
+        description = "Application used by XFCE to lock the screen.";
+      };
     };
 
   };
@@ -74,6 +86,7 @@ in
         pkgs.tango-icon-theme
         pkgs.shared_mime_info
         pkgs.which # Needed by the xfce's xinitrc script.
+        pkgs."${cfg.screenLock}"
         pkgs.xfce.exo
         pkgs.xfce.gtk_xfce_engine
         pkgs.xfce.mousepad
@@ -87,7 +100,6 @@ in
         pkgs.xfce.xfce4volumed
         pkgs.xfce.xfce4-screenshooter
         pkgs.xfce.xfconf
-        pkgs.xfce.xfwm4
         # This supplies some "abstract" icons such as
         # "utilities-terminal" and "accessories-text-editor".
         pkgs.gnome3.defaultIconTheme
@@ -99,6 +111,7 @@ in
         pkgs.xfce.xfce4_appfinder
         pkgs.xfce.tumbler       # found via dbus
       ]
+      ++ optional cfg.enableXfwm pkgs.xfce.xfwm4
       ++ optional config.powerManagement.enable pkgs.xfce.xfce4_power_manager
       ++ optional config.networking.networkmanager.enable pkgs.networkmanagerapplet
       ++ optionals (!cfg.noDesktop)
diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix
index 4afef32aaa47..82b9a2fce5ab 100644
--- a/nixos/modules/services/x11/display-managers/lightdm.nix
+++ b/nixos/modules/services/x11/display-managers/lightdm.nix
@@ -46,15 +46,13 @@ let
       [Seat:*]
       xserver-command = ${xserverWrapper}
       session-wrapper = ${dmcfg.session.script}
-      ${optionalString (elem defaultSessionName dmcfg.session.names) ''
-        user-session = ${defaultSessionName}
-      ''}
       ${optionalString cfg.greeter.enable ''
         greeter-session = ${cfg.greeter.name}
       ''}
       ${optionalString cfg.autoLogin.enable ''
         autologin-user = ${cfg.autoLogin.user}
         autologin-user-timeout = ${toString cfg.autoLogin.timeout}
+        autologin-session = ${defaultSessionName}
       ''}
       ${cfg.extraSeatDefaults}
     '';
diff --git a/nixos/modules/services/x11/display-managers/xpra.nix b/nixos/modules/services/x11/display-managers/xpra.nix
new file mode 100644
index 000000000000..e60dd8765264
--- /dev/null
+++ b/nixos/modules/services/x11/display-managers/xpra.nix
@@ -0,0 +1,249 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.displayManager.xpra;
+  dmcfg = config.services.xserver.displayManager;
+
+in
+
+{
+  ###### interface
+
+  options = {
+    services.xserver.displayManager.xpra = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Whether to enable xpra as display manager.";
+      };
+
+      bindTcp = mkOption {
+        default = "127.0.0.1:10000";
+        example = "0.0.0.0:10000";
+        type = types.nullOr types.str;
+        description = "Bind xpra to TCP";
+      };
+
+      auth = mkOption {
+        type = types.str;
+        default = "pam";
+        example = "password:value=mysecret";
+        description = "Authentication to use when connecting to xpra";
+      };
+
+      pulseaudio = mkEnableOption "pulseaudio audio streaming.";
+    };
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+    services.xserver.videoDrivers = ["dummy"];
+
+    services.xserver.monitorSection = ''
+      HorizSync   1.0 - 2000.0
+      VertRefresh 1.0 - 200.0
+      #To add your own modes here, use a modeline calculator, like:
+      # cvt:
+      # http://www.x.org/archive/X11R7.5/doc/man/man1/cvt.1.html
+      # xtiming:
+      # http://xtiming.sourceforge.net/cgi-bin/xtiming.pl
+      # gtf:
+      # http://gtf.sourceforge.net/
+      #This can be used to get a specific DPI, but only for the default resolution:
+      #DisplaySize 508 317
+      #NOTE: the highest modes will not work without increasing the VideoRam
+      # for the dummy video card.
+      #Modeline "16000x15000" 300.00  16000 16408 18000 20000  15000 15003 15013 15016
+      #Modeline "15000x15000" 281.25  15000 15376 16872 18744  15000 15003 15013 15016
+      #Modeline "16384x8192" 167.75  16384 16800 18432 20480  8192 8195 8205 8208
+      #Modeline "15360x8640" 249.00 15360 15752 17280 19200 8640 8643 8648 8651
+      Modeline "8192x4096" 193.35 8192 8224 8952 8984 4096 4196 4200 4301
+      Modeline "7680x4320" 208.00 7680 7880 8640 9600 4320 4323 4328 4335
+      Modeline "6400x4096" 151.38 6400 6432 7000 7032 4096 4196 4200 4301
+      Modeline "6400x2560" 91.59 6400 6432 6776 6808 2560 2623 2626 2689
+      Modeline "6400x2160" 160.51 6400 6432 7040 7072 2160 2212 2216 2269
+      Modeline "5760x2160" 149.50 5760 5768 6320 6880 2160 2161 2164 2173
+      Modeline "5680x1440" 142.66 5680 5712 6248 6280 1440 1474 1478 1513
+      Modeline "5496x1200" 199.13 5496 5528 6280 6312 1200 1228 1233 1261
+      Modeline "5280x2560" 75.72 5280 5312 5592 5624 2560 2623 2626 2689
+      Modeline "5280x1920" 56.04 5280 5312 5520 5552 1920 1967 1969 2017
+      Modeline "5280x1200" 191.40 5280 5312 6032 6064 1200 1228 1233 1261
+      Modeline "5280x1080" 169.96 5280 5312 5952 5984 1080 1105 1110 1135
+      Modeline "5120x3200" 199.75 5120 5152 5904 5936 3200 3277 3283 3361
+      Modeline "5120x2560" 73.45 5120 5152 5424 5456 2560 2623 2626 2689
+      Modeline "5120x2880" 185.50 5120 5256 5760 6400 2880 2883 2888 2899
+      Modeline "4800x1200" 64.42 4800 4832 5072 5104 1200 1229 1231 1261
+      Modeline "4720x3840" 227.86 4720 4752 5616 5648 3840 3933 3940 4033
+      Modeline "4400x2560" 133.70 4400 4432 4936 4968 2560 2622 2627 2689
+      Modeline "4480x1440" 72.94 4480 4512 4784 4816 1440 1475 1478 1513
+      Modeline "4240x1440" 69.09 4240 4272 4528 4560 1440 1475 1478 1513
+      Modeline "4160x1440" 67.81 4160 4192 4448 4480 1440 1475 1478 1513
+      Modeline "4096x2304" 249.25 4096 4296 4720 5344 2304 2307 2312 2333
+      Modeline "4096x2160" 111.25 4096 4200 4608 5120 2160 2163 2173 2176
+      Modeline "4000x1660" 170.32 4000 4128 4536 5072 1660 1661 1664 1679
+      Modeline "4000x1440" 145.00 4000 4088 4488 4976 1440 1441 1444 1457
+      Modeline "3904x1440" 63.70 3904 3936 4176 4208 1440 1475 1478 1513
+      Modeline "3840x2880" 133.43 3840 3872 4376 4408 2880 2950 2955 3025
+      Modeline "3840x2560" 116.93 3840 3872 4312 4344 2560 2622 2627 2689
+      Modeline "3840x2160" 104.25 3840 3944 4320 4800 2160 2163 2168 2175
+      Modeline "3840x2048" 91.45 3840 3872 4216 4248 2048 2097 2101 2151
+      Modeline "3840x1200" 108.89 3840 3872 4280 4312 1200 1228 1232 1261
+      Modeline "3840x1080" 100.38 3840 3848 4216 4592 1080 1081 1084 1093
+      Modeline "3864x1050" 94.58 3864 3896 4248 4280 1050 1074 1078 1103
+      Modeline "3600x1200" 106.06 3600 3632 3984 4368 1200 1201 1204 1214
+      Modeline "3600x1080" 91.02 3600 3632 3976 4008 1080 1105 1109 1135
+      Modeline "3520x1196" 99.53 3520 3552 3928 3960 1196 1224 1228 1256
+      Modeline "3360x2560" 102.55 3360 3392 3776 3808 2560 2622 2627 2689
+      Modeline "3360x1050" 293.75 3360 3576 3928 4496 1050 1053 1063 1089
+      Modeline "3288x1080" 39.76 3288 3320 3464 3496 1080 1106 1108 1135
+      Modeline "3200x1800" 233.00 3200 3384 3720 4240  1800 1803 1808 1834
+      Modeline "3200x1080" 236.16 3200 3232 4128 4160 1080 1103 1112 1135
+      Modeline "3120x2560" 95.36 3120 3152 3512 3544 2560 2622 2627 2689
+      Modeline "3120x1050" 272.75 3120 3320 3648 4176 1050 1053 1063 1089
+      Modeline "3072x2560" 93.92 3072 3104 3456 3488 2560 2622 2627 2689
+      Modeline "3008x1692" 130.93 3008 3112 3416 3824 1692 1693 1696 1712
+      Modeline "3000x2560" 91.77 3000 3032 3376 3408 2560 2622 2627 2689
+      Modeline "2880x1620" 396.25 2880 3096 3408 3936 1620 1623 1628 1679
+      Modeline "2728x1680" 148.02 2728 2760 3320 3352 1680 1719 1726 1765
+      Modeline "2560x2240" 151.55 2560 2688 2952 3344 2240 2241 2244 2266
+      Modeline "2560x1600" 47.12 2560 2592 2768 2800 1600 1639 1642 1681
+      Modeline "2560x1440" 42.12 2560 2592 2752 2784 1440 1475 1478 1513
+      Modeline "2560x1400" 267.86 2560 2592 3608 3640 1400 1429 1441 1471
+      Modeline "2048x2048" 49.47 2048 2080 2264 2296 2048 2097 2101 2151
+      Modeline "2048x1536" 80.06 2048 2104 2312 2576 1536 1537 1540 1554
+      Modeline "2048x1152" 197.97 2048 2184 2408 2768 1152 1153 1156 1192
+      Modeline "2048x1152" 165.92 2048 2080 2704 2736 1152 1176 1186 1210
+      Modeline "1920x1440" 69.47 1920 1960 2152 2384 1440 1441 1444 1457
+      Modeline "1920x1200" 26.28 1920 1952 2048 2080 1200 1229 1231 1261
+      Modeline "1920x1080" 23.53 1920 1952 2040 2072 1080 1106 1108 1135
+      Modeline "1728x1520" 205.42 1728 1760 2536 2568 1520 1552 1564 1597
+      Modeline "1680x1050" 20.08 1680 1712 1784 1816 1050 1075 1077 1103
+      Modeline "1600x1200" 22.04 1600 1632 1712 1744 1200 1229 1231 1261
+      Modeline "1600x900" 33.92 1600 1632 1760 1792 900 921 924 946
+      Modeline "1440x900" 30.66 1440 1472 1584 1616 900 921 924 946
+      Modeline "1400x900" 103.50 1400 1480 1624 1848 900 903 913 934
+      ModeLine "1366x768" 72.00 1366 1414 1446 1494  768 771 777 803
+      Modeline "1360x768" 24.49 1360 1392 1480 1512 768 786 789 807
+      Modeline "1280x1024" 31.50 1280 1312 1424 1456 1024 1048 1052 1076
+      Modeline "1280x800" 24.15 1280 1312 1400 1432 800 819 822 841
+      Modeline "1280x768" 23.11 1280 1312 1392 1424 768 786 789 807
+      Modeline "1280x720" 59.42 1280 1312 1536 1568 720 735 741 757
+      Modeline "1024x768" 18.71 1024 1056 1120 1152 768 786 789 807
+      Modeline "1024x640" 41.98 1024 1056 1208 1240 640 653 659 673
+      Modeline "1024x576" 46.50 1024 1064 1160 1296  576 579 584 599
+      Modeline "768x1024" 19.50 768 800 872 904 1024 1048 1052 1076
+      Modeline "960x540" 40.75 960 992 1088 1216 540 543 548 562
+      Modeline "864x486"  32.50 864 888 968 1072 486 489 494 506
+      Modeline "720x405" 22.50 720 744 808 896  405 408 413 422
+      Modeline "640x360" 14.75 640 664 720 800 360 363 368 374
+      #common resolutions for android devices (both orientations):
+      Modeline "800x1280" 25.89 800 832 928 960 1280 1310 1315 1345
+      Modeline "1280x800" 24.15 1280 1312 1400 1432 800 819 822 841
+      Modeline "720x1280" 30.22 720 752 864 896 1280 1309 1315 1345
+      Modeline "1280x720" 27.41 1280 1312 1416 1448 720 737 740 757
+      Modeline "768x1024" 24.93 768 800 888 920 1024 1047 1052 1076
+      Modeline "1024x768" 23.77 1024 1056 1144 1176 768 785 789 807
+      Modeline "600x1024" 19.90 600 632 704 736 1024 1047 1052 1076
+      Modeline "1024x600" 18.26 1024 1056 1120 1152 600 614 617 631
+      Modeline "536x960" 16.74 536 568 624 656 960 982 986 1009
+      Modeline "960x536" 15.23 960 992 1048 1080 536 548 551 563
+      Modeline "600x800" 15.17 600 632 688 720 800 818 822 841
+      Modeline "800x600" 14.50 800 832 880 912 600 614 617 631
+      Modeline "480x854" 13.34 480 512 560 592 854 873 877 897
+      Modeline "848x480" 12.09 848 880 920 952 480 491 493 505
+      Modeline "480x800" 12.43 480 512 552 584 800 818 822 841
+      Modeline "800x480" 11.46 800 832 872 904 480 491 493 505
+      #resolutions for android devices (both orientations)
+      #minus the status bar
+      #38px status bar (and width rounded up)
+      Modeline "800x1242" 25.03 800 832 920 952 1242 1271 1275 1305
+      Modeline "1280x762" 22.93 1280 1312 1392 1424 762 780 783 801
+      Modeline "720x1242" 29.20 720 752 856 888 1242 1271 1276 1305
+      Modeline "1280x682" 25.85 1280 1312 1408 1440 682 698 701 717
+      Modeline "768x986" 23.90 768 800 888 920 986 1009 1013 1036
+      Modeline "1024x730" 22.50 1024 1056 1136 1168 730 747 750 767
+      Modeline "600x986" 19.07 600 632 704 736 986 1009 1013 1036
+      Modeline "1024x562" 17.03 1024 1056 1120 1152 562 575 578 591
+      Modeline "536x922" 16.01 536 568 624 656 922 943 947 969
+      Modeline "960x498" 14.09 960 992 1040 1072 498 509 511 523
+      Modeline "600x762" 14.39 600 632 680 712 762 779 783 801
+      Modeline "800x562" 13.52 800 832 880 912 562 575 578 591
+      Modeline "480x810" 12.59 480 512 552 584 810 828 832 851
+      Modeline "848x442" 11.09 848 880 920 952 442 452 454 465
+      Modeline "480x762" 11.79 480 512 552 584 762 779 783 801
+    '';
+
+    services.xserver.resolutions = [
+      {x="8192"; y="4096";}
+      {x="5120"; y="3200";}
+      {x="3840"; y="2880";}
+      {x="3840"; y="2560";}
+      {x="3840"; y="2048";}
+      {x="3840"; y="2160";}
+      {x="2048"; y="2048";}
+      {x="2560"; y="1600";}
+      {x="1920"; y="1440";}
+      {x="1920"; y="1200";}
+      {x="1920"; y="1080";}
+      {x="1600"; y="1200";}
+      {x="1680"; y="1050";}
+      {x="1600"; y="900";}
+      {x="1400"; y="1050";}
+      {x="1440"; y="900";}
+      {x="1280"; y="1024";}
+      {x="1366"; y="768";}
+      {x="1280"; y="800";}
+      {x="1024"; y="768";}
+      {x="1024"; y="600";}
+      {x="800"; y="600";}
+      {x="320"; y="200";}
+    ];
+
+    services.xserver.serverFlagsSection = ''
+      Option "DontVTSwitch" "true"
+      Option "PciForceNone" "true"
+      Option "AutoEnableDevices" "false"
+      Option "AutoAddDevices" "false"
+    '';
+
+    services.xserver.deviceSection = ''
+      VideoRam 192000
+    '';
+
+    services.xserver.displayManager.job = {
+      logsXsession = true;
+
+      execCmd = ''
+        ${optionalString (cfg.pulseaudio)
+          "export PULSE_COOKIE=/var/run/pulse/.config/pulse/cookie"}
+        exec ${pkgs.xpra}/bin/xpra start \
+          --daemon=off \
+          --log-dir=/var/log \
+          --log-file=xpra.log \
+          --opengl=on \
+          --clipboard=on \
+          --notifications=on \
+          --speaker=yes \
+          --mdns=no \
+          --pulseaudio=no \
+          ${optionalString (cfg.pulseaudio) "--sound-source=pulse"} \
+          --socket-dirs=/var/run/xpra \
+          --xvfb="xpra_Xdummy ${concatStringsSep " " dmcfg.xserverArgs}" \
+          ${optionalString (cfg.bindTcp != null) "--bind-tcp=${cfg.bindTcp}"} \
+          --auth=${cfg.auth}
+      '';
+    };
+
+    services.xserver.terminateOnReset = false;
+
+    environment.systemPackages = [pkgs.xpra];
+
+    virtualisation.virtualbox.guest.x11 = false;
+    hardware.pulseaudio.enable = mkDefault cfg.pulseaudio;
+    hardware.pulseaudio.systemWide = mkDefault cfg.pulseaudio;
+  };
+
+}
diff --git a/nixos/modules/services/x11/window-managers/herbstluftwm.nix b/nixos/modules/services/x11/window-managers/herbstluftwm.nix
index 829935fa432b..e3ea61cb9a6b 100644
--- a/nixos/modules/services/x11/window-managers/herbstluftwm.nix
+++ b/nixos/modules/services/x11/window-managers/herbstluftwm.nix
@@ -8,15 +8,30 @@ in
 
 {
   options = {
-    services.xserver.windowManager.herbstluftwm.enable = mkEnableOption "herbstluftwm";
+    services.xserver.windowManager.herbstluftwm = {
+      enable = mkEnableOption "herbstluftwm";
+
+      configFile = mkOption {
+        default     = null;
+        type        = with types; nullOr path;
+        description = ''
+          Path to the herbstluftwm configuration file.  If left at the
+          default value, $XDG_CONFIG_HOME/herbstluftwm/autostart will
+          be used.
+        '';
+      };
+    };
   };
 
   config = mkIf cfg.enable {
     services.xserver.windowManager.session = singleton {
       name = "herbstluftwm";
-      start = "
-        ${pkgs.herbstluftwm}/bin/herbstluftwm
-      ";
+      start =
+        let configFileClause = optionalString
+            (cfg.configFile != null)
+            ''-c "${cfg.configFile}"''
+            ;
+        in "${pkgs.herbstluftwm}/bin/herbstluftwm ${configFileClause}";
     };
     environment.systemPackages = [ pkgs.herbstluftwm ];
   };
diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix
index 7ac776571a01..8438e6dcc702 100644
--- a/nixos/modules/services/x11/xserver.nix
+++ b/nixos/modules/services/x11/xserver.nix
@@ -435,6 +435,14 @@ in
           by default.
         '';
       };
+
+      terminateOnReset = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether to terminate X upon server reset.
+        '';
+      };
     };
 
   };
@@ -550,8 +558,7 @@ in
       };
 
     services.xserver.displayManager.xserverArgs =
-      [ "-terminate"
-        "-config ${configFile}"
+      [ "-config ${configFile}"
         "-xkbdir" "${cfg.xkbDir}"
         # Log at the default verbosity level to stderr rather than /var/log/X.*.log.
         "-verbose" "3" "-logfile" "/dev/null"
@@ -560,7 +567,8 @@ in
         ++ optional (cfg.dpi     != null) "-dpi ${toString cfg.dpi}"
         ++ optional (!cfg.enableTCP) "-nolisten tcp"
         ++ optional (cfg.autoRepeatDelay != null) "-ardelay ${toString cfg.autoRepeatDelay}"
-        ++ optional (cfg.autoRepeatInterval != null) "-arinterval ${toString cfg.autoRepeatInterval}";
+        ++ optional (cfg.autoRepeatInterval != null) "-arinterval ${toString cfg.autoRepeatInterval}"
+        ++ optional cfg.terminateOnReset "-terminate";
 
     services.xserver.modules =
       concatLists (catAttrs "modules" cfg.drivers) ++
diff --git a/nixos/modules/system/activation/activation-script.nix b/nixos/modules/system/activation/activation-script.nix
index dcf105eb7844..c2ac731d433d 100644
--- a/nixos/modules/system/activation/activation-script.nix
+++ b/nixos/modules/system/activation/activation-script.nix
@@ -19,6 +19,7 @@ let
       glibc # needed for getent
       shadow
       nettools # needed for hostname
+      utillinux # needed for mount and mountpoint
     ];
 
 in
@@ -168,12 +169,12 @@ in
           local options="$3"
           local fsType="$4"
 
-          if ${pkgs.utillinux}/bin/mountpoint -q "$mountPoint"; then
+          if mountpoint -q "$mountPoint"; then
             local options="remount,$options"
           else
             mkdir -m 0755 -p "$mountPoint"
           fi
-          ${pkgs.utillinux}/bin/mount -t "$fsType" -o "$options" "$device" "$mountPoint"
+          mount -t "$fsType" -o "$options" "$device" "$mountPoint"
         }
         source ${config.system.build.earlyMountScript}
       '';
diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl
index 8747c1e3d4ac..88e7847cf8c8 100644
--- a/nixos/modules/system/activation/switch-to-configuration.pl
+++ b/nixos/modules/system/activation/switch-to-configuration.pl
@@ -41,7 +41,7 @@ if ($action eq "switch" || $action eq "boot") {
 }
 
 # Just in case the new configuration hangs the system, do a sync now.
-system("@coreutils@/bin/sync") unless ($ENV{"NIXOS_NO_SYNC"} // "") eq "1";
+system("@coreutils@/bin/sync", "-f", "/nix/store") unless ($ENV{"NIXOS_NO_SYNC"} // "") eq "1";
 
 exit 0 if $action eq "boot";
 
@@ -383,6 +383,10 @@ system("@systemd@/bin/systemctl", "reset-failed");
 # Make systemd reload its units.
 system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3;
 
+# Set the new tmpfiles
+print STDERR "setting up tmpfiles\n";
+system("@systemd@/bin/systemd-tmpfiles", "--create", "--remove", "--exclude-prefix=/dev") == 0 or $res = 3;
+
 # Reload units that need it. This includes remounting changed mount
 # units.
 if (scalar(keys %unitsToReload) > 0) {
diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix
index e751ff141f70..cf70a891c0ca 100644
--- a/nixos/modules/system/boot/kernel.nix
+++ b/nixos/modules/system/boot/kernel.nix
@@ -176,7 +176,7 @@ in
 
     boot.initrd.availableKernelModules =
       [ # Note: most of these (especially the SATA/PATA modules)
-        # shouldn't be included by default since nixos-hardware-scan
+        # shouldn't be included by default since nixos-generate-config
         # detects them, but I'm keeping them for now for backwards
         # compatibility.
 
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index 23b970186a39..5ab2d0775518 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -54,7 +54,7 @@ let
       inherit (efi) canTouchEfiVariables;
       inherit (cfg)
         version extraConfig extraPerEntryConfig extraEntries forceInstall useOSProber
-        extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels
+        extraEntriesBeforeNixOS extraPrepareConfig extraInitrd configurationLimit copyKernels
         default fsIdentifier efiSupport efiInstallAsRemovable gfxmodeEfi gfxmodeBios;
       path = (makeBinPath ([
         pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils pkgs.btrfs-progs
@@ -267,6 +267,19 @@ in
         '';
       };
 
+      extraInitrd = mkOption {
+        type = types.nullOr types.path;
+        default = null;
+        example = "/boot/extra_initrafms.gz";
+        description = ''
+          The path to a second initramfs to be supplied to the kernel.
+          This ramfs will not be copied to the store, so that it can
+          contain secrets such as LUKS keyfiles or ssh keys.
+          This implies that rolling back to a previous configuration
+          won't rollback the state of this file.
+        '';
+      };
+
       useOSProber = mkOption {
         default = false;
         type = types.bool;
diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl
index c9a51288747b..c7559cd634a2 100644
--- a/nixos/modules/system/boot/loader/grub/install-grub.pl
+++ b/nixos/modules/system/boot/loader/grub/install-grub.pl
@@ -49,6 +49,7 @@ my $extraPrepareConfig = get("extraPrepareConfig");
 my $extraPerEntryConfig = get("extraPerEntryConfig");
 my $extraEntries = get("extraEntries");
 my $extraEntriesBeforeNixOS = get("extraEntriesBeforeNixOS") eq "true";
+my $extraInitrd = get("extraInitrd");
 my $splashImage = get("splashImage");
 my $configurationLimit = int(get("configurationLimit"));
 my $copyKernels = get("copyKernels") eq "true";
@@ -226,6 +227,13 @@ my $grubStore;
 if ($copyKernels == 0) {
     $grubStore = GrubFs($storePath);
 }
+my $extraInitrdPath;
+if ($extraInitrd) {
+    if (! -f $extraInitrd) {
+        print STDERR "Warning: the specified extraInitrd " . $extraInitrd . " doesn't exist. Your system won't boot without it.\n";
+    }
+    $extraInitrdPath = GrubFs($extraInitrd);
+}
 
 # Generate the header.
 my $conf .= "# Automatically generated.  DO NOT EDIT THIS FILE!\n";
@@ -336,6 +344,9 @@ sub addEntry {
 
     my $kernel = copyToKernelsDir(Cwd::abs_path("$path/kernel"));
     my $initrd = copyToKernelsDir(Cwd::abs_path("$path/initrd"));
+    if ($extraInitrd) {
+        $initrd .= " " .$extraInitrdPath->path;
+    }
     my $xen = -e "$path/xen.gz" ? copyToKernelsDir(Cwd::abs_path("$path/xen.gz")) : undef;
 
     # FIXME: $confName
@@ -358,6 +369,9 @@ sub addEntry {
         if ($copyKernels == 0) {
             $conf .= $grubStore->search . "\n";
         }
+        if ($extraInitrd) {
+            $conf .= $extraInitrdPath->search . "\n";
+        }
         $conf .= "  $extraPerEntryConfig\n" if $extraPerEntryConfig;
         $conf .= "  multiboot $xen $xenParams\n" if $xen;
         $conf .= "  " . ($xen ? "module" : "linux") . " $kernel $kernelParams\n";
diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
index b91d64bb0a7f..04cf17c1b0b4 100644
--- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
+++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
@@ -101,11 +101,27 @@ def main():
     parser.add_argument('default_config', metavar='DEFAULT-CONFIG', help='The default NixOS config to boot')
     args = parser.parse_args()
 
+    try:
+        with open("/etc/machine-id") as machine_file:
+            machine_id = machine_file.readlines()[0]
+    except IOError as e:
+        if e.errno != errno.ENOENT:
+            raise
+        # Since systemd version 232 a machine ID is required and it might not
+        # be there on newly installed systems, so let's generate one so that
+        # bootctl can find it and we can also pass it to write_entry() later.
+        cmd = ["@systemd@/bin/systemd-machine-id-setup", "--print"]
+        machine_id = subprocess.check_output(cmd).rstrip()
+
     if os.getenv("NIXOS_INSTALL_GRUB") == "1":
         warnings.warn("NIXOS_INSTALL_GRUB env var deprecated, use NIXOS_INSTALL_BOOTLOADER", DeprecationWarning)
         os.environ["NIXOS_INSTALL_BOOTLOADER"] = "1"
 
     if os.getenv("NIXOS_INSTALL_BOOTLOADER") == "1":
+        # bootctl uses fopen() with modes "wxe" and fails if the file exists.
+        if os.path.exists("@efiSysMountPoint@/loader/loader.conf"):
+            os.unlink("@efiSysMountPoint@/loader/loader.conf")
+
         if "@canTouchEfiVariables@" == "1":
             subprocess.check_call(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "install"])
         else:
@@ -113,13 +129,6 @@ def main():
 
     mkdir_p("@efiSysMountPoint@/efi/nixos")
     mkdir_p("@efiSysMountPoint@/loader/entries")
-    try:
-        with open("/etc/machine-id") as machine_file:
-            machine_id = machine_file.readlines()[0]
-    except IOError as e:
-        if e.errno != errno.ENOENT:
-            raise
-        machine_id = None
 
     gens = get_generations("system")
     remove_old_entries(gens)
diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix
index 1f412fe2d8f2..8978b73749b7 100644
--- a/nixos/modules/system/boot/luksroot.nix
+++ b/nixos/modules/system/boot/luksroot.nix
@@ -434,8 +434,8 @@ in
       chmod +x $out/bin/cryptsetup-askpass
 
       ${optionalString luks.yubikeySupport ''
-        copy_bin_and_libs ${pkgs.ykpers}/bin/ykchalresp
-        copy_bin_and_libs ${pkgs.ykpers}/bin/ykinfo
+        copy_bin_and_libs ${pkgs.yubikey-personalization}/bin/ykchalresp
+        copy_bin_and_libs ${pkgs.yubikey-personalization}/bin/ykinfo
         copy_bin_and_libs ${pkgs.openssl.bin}/bin/openssl
 
         cc -O3 -I${pkgs.openssl.dev}/include -L${pkgs.openssl.out}/lib ${./pbkdf2-sha512.c} -o pbkdf2-sha512 -lcrypto
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index 904404e1e472..bff6739db616 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -329,7 +329,7 @@ let
           ${let env = cfg.globalEnvironment // def.environment;
             in concatMapStrings (n:
               let s = optionalString (env."${n}" != null)
-                "Environment=\"${n}=${env.${n}}\"\n";
+                "Environment=${builtins.toJSON "${n}=${env.${n}}"}\n";
               in if stringLength s >= 2048 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${name}.service’ is too long." else s) (attrNames env)}
           ${if def.reloadIfChanged then ''
             X-ReloadIfChanged=true
@@ -842,6 +842,7 @@ in
     systemd.services.systemd-journald.stopIfChanged = false;
     systemd.targets.local-fs.unitConfig.X-StopOnReconfiguration = true;
     systemd.targets.remote-fs.unitConfig.X-StopOnReconfiguration = true;
+    systemd.targets.network-online.wantedBy = [ "multi-user.target" ];
     systemd.services.systemd-binfmt.wants = [ "proc-sys-fs-binfmt_misc.automount" ];
 
     # Don't bother with certain units in containers.
diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix
index 8a4299113f2b..9f30eb611466 100644
--- a/nixos/modules/tasks/filesystems.nix
+++ b/nixos/modules/tasks/filesystems.nix
@@ -291,7 +291,7 @@ in
     # Sync mount options with systemd's src/core/mount-setup.c: mount_table.
     boot.specialFileSystems = {
       "/proc" = { fsType = "proc"; options = [ "nosuid" "noexec" "nodev" ]; };
-      "/run" = { fsType = "tmpfs"; options = [ "nodev" "strictatime" "mode=755" "size=${config.boot.runSize}" ]; };
+      "/run" = { fsType = "tmpfs"; options = [ "nosuid" "nodev" "strictatime" "mode=755" "size=${config.boot.runSize}" ]; };
       "/dev" = { fsType = "devtmpfs"; options = [ "nosuid" "strictatime" "mode=755" "size=${config.boot.devSize}" ]; };
       "/dev/shm" = { fsType = "tmpfs"; options = [ "nosuid" "nodev" "strictatime" "mode=1777" "size=${config.boot.devShmSize}" ]; };
       "/dev/pts" = { fsType = "devpts"; options = [ "nosuid" "noexec" "mode=620" "gid=${toString config.ids.gids.tty}" ]; };
diff --git a/nixos/modules/tasks/filesystems/f2fs.nix b/nixos/modules/tasks/filesystems/f2fs.nix
index 430ac630a885..d103ff1a57b5 100644
--- a/nixos/modules/tasks/filesystems/f2fs.nix
+++ b/nixos/modules/tasks/filesystems/f2fs.nix
@@ -10,7 +10,7 @@ in
 
     system.fsPackages = [ pkgs.f2fs-tools ];
 
-    boot.initrd.availableKernelModules = mkIf inInitrd [ "f2fs" ];
+    boot.initrd.availableKernelModules = mkIf inInitrd [ "f2fs" "crc32" ];
 
     boot.initrd.extraUtilsCommands = mkIf inInitrd ''
       copy_bin_and_libs ${pkgs.f2fs-tools}/sbin/fsck.f2fs
diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix
index 045cbeb7cff8..c8fa6c21a4f6 100644
--- a/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixos/modules/tasks/filesystems/zfs.nix
@@ -13,12 +13,14 @@ let
   cfgZfs = config.boot.zfs;
   cfgSnapshots = config.services.zfs.autoSnapshot;
   cfgSnapFlags = cfgSnapshots.flags;
+  cfgScrub = config.services.zfs.autoScrub;
 
   inInitrd = any (fs: fs == "zfs") config.boot.initrd.supportedFilesystems;
   inSystem = any (fs: fs == "zfs") config.boot.supportedFilesystems;
 
   enableAutoSnapshots = cfgSnapshots.enable;
-  enableZfs = inInitrd || inSystem || enableAutoSnapshots;
+  enableAutoScrub = cfgScrub.enable;
+  enableZfs = inInitrd || inSystem || enableAutoSnapshots || enableAutoScrub;
 
   kernel = config.boot.kernelPackages;
 
@@ -217,6 +219,37 @@ in
         '';
       };
     };
+
+    services.zfs.autoScrub = {
+      enable = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          Enables periodic scrubbing of ZFS pools.
+        '';
+      };
+
+      interval = mkOption {
+        default = "Sun, 02:00";
+        type = types.str;
+        example = "daily";
+        description = ''
+          Systemd calendar expression when to scrub ZFS pools. See
+          <citerefentry><refentrytitle>systemd.time</refentrytitle>
+          <manvolnum>5</manvolnum></citerefentry>.
+        '';
+      };
+
+      pools = mkOption {
+        default = [];
+        type = types.listOf types.str;
+        example = [ "tank" ];
+        description = ''
+          List of ZFS pools to periodically scrub. If empty, all pools
+          will be scrubbed.
+        '';
+      };
+    };
   };
 
   ###### implementation
@@ -282,7 +315,7 @@ in
         zfsSupport = true;
       };
 
-      environment.etc."zfs/zed.d".source = "${packages.zfsUser}/etc/zfs/zed.d/*";
+      environment.etc."zfs/zed.d".source = "${packages.zfsUser}/etc/zfs/zed.d/";
 
       system.fsPackages = [ packages.zfsUser ]; # XXX: needed? zfs doesn't have (need) a fsck
       environment.systemPackages = [ packages.zfsUser ]
@@ -391,5 +424,31 @@ in
                               };
                             }) snapshotNames);
     })
+
+    (mkIf enableAutoScrub {
+      systemd.services.zfs-scrub = {
+        description = "ZFS pools scrubbing";
+        after = [ "zfs-import.target" ];
+        serviceConfig = {
+          Type = "oneshot";
+        };
+        script = ''
+          ${packages.zfsUser}/bin/zpool scrub ${
+            if cfgScrub.pools != [] then
+              (concatStringsSep " " cfgScrub.pools)
+            else
+              "$(${packages.zfsUser}/bin/zpool list -H -o name)"
+            }
+        '';
+      };
+
+      systemd.timers.zfs-scrub = {
+        wantedBy = [ "timers.target" ];
+        timerConfig = {
+          OnCalendar = cfgScrub.interval;
+          Persistent = "yes";
+        };
+      };
+    })
   ];
 }
diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix
index d94d9db54ca5..3571e00d04ec 100644
--- a/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -60,21 +60,18 @@ let
       let
 
         deviceDependency = dev:
-          if (config.boot.isContainer == false)
-          then
-            # Trust udev when not in the container
-            optional (dev != null) (subsystemDevice dev)
-          else
-            # When in the container, check whether the interface is built from other definitions
-            if (hasAttr dev cfg.bridges) ||
-               (hasAttr dev cfg.bonds) ||
-               (hasAttr dev cfg.macvlans) ||
-               (hasAttr dev cfg.sits) ||
-               (hasAttr dev cfg.vlans) ||
-               (hasAttr dev cfg.vswitches) ||
-               (hasAttr dev cfg.wlanInterfaces)
-            then [ "${dev}-netdev.service" ]
-            else [];
+          # Use systemd service if we manage device creation, else
+          # trust udev when not in a container
+          if (hasAttr dev (filterAttrs (k: v: v.virtual) cfg.interfaces)) ||
+             (hasAttr dev cfg.bridges) ||
+             (hasAttr dev cfg.bonds) ||
+             (hasAttr dev cfg.macvlans) ||
+             (hasAttr dev cfg.sits) ||
+             (hasAttr dev cfg.vlans) ||
+             (hasAttr dev cfg.vswitches) ||
+             (hasAttr dev cfg.wlanInterfaces)
+          then [ "${dev}-netdev.service" ]
+          else optional (dev != null && !config.boot.isContainer) (subsystemDevice dev);
 
         networkLocalCommands = {
           after = [ "network-setup.service" ];
@@ -211,7 +208,7 @@ let
               user "${i.virtualOwner}"
             '';
             postStop = ''
-              ip link del ${i.name}
+              ip link del ${i.name} || true
             '';
           };
 
@@ -223,7 +220,7 @@ let
             wantedBy = [ "network-setup.service" (subsystemDevice n) ];
             bindsTo = deps ++ optional v.rstp "mstpd.service";
             partOf = [ "network-setup.service" ] ++ optional v.rstp "mstpd.service";
-            after = [ "network-pre.target" "mstpd.service" ] ++ deps
+            after = [ "network-pre.target" ] ++ deps ++ optional v.rstp "mstpd.service"
               ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces;
             before = [ "network-setup.service" (subsystemDevice n) ];
             serviceConfig.Type = "oneshot";
@@ -349,7 +346,7 @@ let
               ip link set "${n}" up
             '';
             postStop = ''
-              ip link delete "${n}"
+              ip link delete "${n}" || true
             '';
           });
 
@@ -377,7 +374,7 @@ let
               ip link set "${n}" up
             '';
             postStop = ''
-              ip link delete "${n}"
+              ip link delete "${n}" || true
             '';
           });
 
@@ -401,7 +398,7 @@ let
               ip link set "${n}" up
             '';
             postStop = ''
-              ip link delete "${n}"
+              ip link delete "${n}" || true
             '';
           });
 
diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix
index 736292400fd4..8b85ff0057f9 100644
--- a/nixos/modules/tasks/network-interfaces-systemd.nix
+++ b/nixos/modules/tasks/network-interfaces-systemd.nix
@@ -126,7 +126,7 @@ in
               ms    = trans (v: v + "ms");
               in {
                 Mode                       = simp "mode";
-                TransmitHashPolixy         = simp "xmit_hash_policy";
+                TransmitHashPolicy         = simp "xmit_hash_policy";
                 LACPTransmitRate           = simp "lacp_rate";
                 MIIMonitorSec              = ms "miimon";
                 UpDelaySec                 = ms "updelay";
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index 898207ef7a3c..6467259766ea 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -358,7 +358,7 @@ in
       default = null;
       example = {
         address = "131.211.84.1";
-        device = "enp3s0";
+        interface = "enp3s0";
       };
       type = types.nullOr (types.coercedTo types.str gatewayCoerce (types.submodule gatewayOpts));
       description = ''
@@ -371,7 +371,7 @@ in
       default = null;
       example = {
         address = "2001:4d0:1e04:895::1";
-        device = "enp3s0";
+        interface = "enp3s0";
       };
       type = types.nullOr (types.coercedTo types.str gatewayCoerce (types.submodule gatewayOpts));
       description = ''
@@ -560,101 +560,102 @@ in
 
     };
 
-    networking.bonds = mkOption {
-      default = { };
-      example = literalExample {
-        bond0 = {
-          interfaces = [ "eth0" "wlan0" ];
-          miimon = 100;
+    networking.bonds =
+      let
+        driverOptionsExample = {
+          miimon = "100";
           mode = "active-backup";
         };
-        fatpipe.interfaces = [ "enp4s0f0" "enp4s0f1" "enp5s0f0" "enp5s0f1" ];
-      };
-      description = ''
-        This option allows you to define bond devices that aggregate multiple,
-        underlying networking interfaces together. The value of this option is
-        an attribute set. Each attribute specifies a bond, with the attribute
-        name specifying the name of the bond's network interface
-      '';
+      in mkOption {
+        default = { };
+        example = literalExample {
+          bond0 = {
+            interfaces = [ "eth0" "wlan0" ];
+            driverOptions = driverOptionsExample;
+          };
+          anotherBond.interfaces = [ "enp4s0f0" "enp4s0f1" "enp5s0f0" "enp5s0f1" ];
+        };
+        description = ''
+          This option allows you to define bond devices that aggregate multiple,
+          underlying networking interfaces together. The value of this option is
+          an attribute set. Each attribute specifies a bond, with the attribute
+          name specifying the name of the bond's network interface
+        '';
 
-      type = with types; attrsOf (submodule {
+        type = with types; attrsOf (submodule {
 
-        options = {
+          options = {
 
-          interfaces = mkOption {
-            example = [ "enp4s0f0" "enp4s0f1" "wlan0" ];
-            type = types.listOf types.str;
-            description = "The interfaces to bond together";
-          };
+            interfaces = mkOption {
+              example = [ "enp4s0f0" "enp4s0f1" "wlan0" ];
+              type = types.listOf types.str;
+              description = "The interfaces to bond together";
+            };
+
+            driverOptions = mkOption {
+              type = types.attrsOf types.str;
+              default = {};
+              example = literalExample driverOptionsExample;
+              description = ''
+                Options for the bonding driver.
+                Documentation can be found in
+                <link xlink:href="https://www.kernel.org/doc/Documentation/networking/bonding.txt" />
+              '';
 
-          driverOptions = mkOption {
-            type = types.attrsOf types.str;
-            default = {};
-            example = literalExample {
-              interfaces = [ "eth0" "wlan0" ];
-              miimon = 100;
-              mode = "active-backup";
             };
-            description = ''
-              Options for the bonding driver.
-              Documentation can be found in
-              <link xlink:href="https://www.kernel.org/doc/Documentation/networking/bonding.txt" />
-            '';
 
-          };
+            lacp_rate = mkOption {
+              default = null;
+              example = "fast";
+              type = types.nullOr types.str;
+              description = ''
+                DEPRECATED, use `driverOptions`.
+                Option specifying the rate in which we'll ask our link partner
+                to transmit LACPDU packets in 802.3ad mode.
+              '';
+            };
 
-          lacp_rate = mkOption {
-            default = null;
-            example = "fast";
-            type = types.nullOr types.str;
-            description = ''
-              DEPRECATED, use `driverOptions`.
-              Option specifying the rate in which we'll ask our link partner
-              to transmit LACPDU packets in 802.3ad mode.
-            '';
-          };
+            miimon = mkOption {
+              default = null;
+              example = 100;
+              type = types.nullOr types.int;
+              description = ''
+                DEPRECATED, use `driverOptions`.
+                Miimon is the number of millisecond in between each round of polling
+                by the device driver for failed links. By default polling is not
+                enabled and the driver is trusted to properly detect and handle
+                failure scenarios.
+              '';
+            };
 
-          miimon = mkOption {
-            default = null;
-            example = 100;
-            type = types.nullOr types.int;
-            description = ''
-              DEPRECATED, use `driverOptions`.
-              Miimon is the number of millisecond in between each round of polling
-              by the device driver for failed links. By default polling is not
-              enabled and the driver is trusted to properly detect and handle
-              failure scenarios.
-            '';
-          };
+            mode = mkOption {
+              default = null;
+              example = "active-backup";
+              type = types.nullOr types.str;
+              description = ''
+                DEPRECATED, use `driverOptions`.
+                The mode which the bond will be running. The default mode for
+                the bonding driver is balance-rr, optimizing for throughput.
+                More information about valid modes can be found at
+                https://www.kernel.org/doc/Documentation/networking/bonding.txt
+              '';
+            };
 
-          mode = mkOption {
-            default = null;
-            example = "active-backup";
-            type = types.nullOr types.str;
-            description = ''
-              DEPRECATED, use `driverOptions`.
-              The mode which the bond will be running. The default mode for
-              the bonding driver is balance-rr, optimizing for throughput.
-              More information about valid modes can be found at
-              https://www.kernel.org/doc/Documentation/networking/bonding.txt
-            '';
-          };
+            xmit_hash_policy = mkOption {
+              default = null;
+              example = "layer2+3";
+              type = types.nullOr types.str;
+              description = ''
+                DEPRECATED, use `driverOptions`.
+                Selects the transmit hash policy to use for slave selection in
+                balance-xor, 802.3ad, and tlb modes.
+              '';
+            };
 
-          xmit_hash_policy = mkOption {
-            default = null;
-            example = "layer2+3";
-            type = types.nullOr types.str;
-            description = ''
-              DEPRECATED, use `driverOptions`.
-              Selects the transmit hash policy to use for slave selection in
-              balance-xor, 802.3ad, and tlb modes.
-            '';
           };
 
-        };
-
-      });
-    };
+        });
+      };
 
     networking.macvlans = mkOption {
       default = { };
@@ -960,14 +961,8 @@ in
         source  = "${pkgs.iputils.out}/bin/ping";
         capabilities = "cap_net_raw+p";
       };
-
-      ping6 = {
-        source  = "${pkgs.iputils.out}/bin/ping6";
-        capabilities = "cap_net_raw+p";
-      };
     } else {
       ping.source = "${pkgs.iputils.out}/bin/ping";
-      "ping6".source = "${pkgs.iputils.out}/bin/ping6";
     };
 
     # Set the host and domain names in the activation script.  Don't
diff --git a/nixos/modules/virtualisation/amazon-init.nix b/nixos/modules/virtualisation/amazon-init.nix
index 5797d9db4362..a7362423eb46 100644
--- a/nixos/modules/virtualisation/amazon-init.nix
+++ b/nixos/modules/virtualisation/amazon-init.nix
@@ -45,9 +45,8 @@ in {
     inherit script;
     description = "Reconfigure the system from EC2 userdata on startup";
 
-    wantedBy = [ "sshd.service" ];
-    before = [ "sshd.service" ];
-    after = [ "network-online.target" ];
+    wantedBy = [ "multi-user.target" ];
+    after = [ "multi-user.target" ];
     requires = [ "network-online.target" ];
  
     restartIfChanged = false;
diff --git a/nixos/modules/virtualisation/ec2-amis.nix b/nixos/modules/virtualisation/ec2-amis.nix
index 0753e2ce9948..d592a23c303f 100644
--- a/nixos/modules/virtualisation/ec2-amis.nix
+++ b/nixos/modules/virtualisation/ec2-amis.nix
@@ -156,6 +156,10 @@ let self = {
   "16.09".ap-southeast-2.hvm-s3 = "ami-87f4f0e4";
   "16.09".ap-southeast-2.pv-ebs = "ami-d8ede9bb";
   "16.09".ap-southeast-2.pv-s3 = "ami-a6ebefc5";
+  "16.09".ca-central-1.hvm-ebs = "ami-9f863bfb";
+  "16.09".ca-central-1.hvm-s3 = "ami-ea85388e";
+  "16.09".ca-central-1.pv-ebs = "ami-ce8a37aa";
+  "16.09".ca-central-1.pv-s3 = "ami-448a3720";
   "16.09".eu-central-1.hvm-ebs = "ami-1b884774";
   "16.09".eu-central-1.hvm-s3 = "ami-b08c43df";
   "16.09".eu-central-1.pv-ebs = "ami-888946e7";
diff --git a/nixos/modules/virtualisation/ecs-agent.nix b/nixos/modules/virtualisation/ecs-agent.nix
index 18e45e0b8457..fc51b159579e 100644
--- a/nixos/modules/virtualisation/ecs-agent.nix
+++ b/nixos/modules/virtualisation/ecs-agent.nix
@@ -12,6 +12,7 @@ in {
       type = types.path;
       description = "The ECS agent package to use";
       default = pkgs.ecs-agent;
+      defaultText = "pkgs.ecs-agent";
     };
 
     extra-environment = mkOption {
diff --git a/nixos/modules/virtualisation/google-compute-image.nix b/nixos/modules/virtualisation/google-compute-image.nix
index 0e6825c3f5da..556454c6b5f8 100644
--- a/nixos/modules/virtualisation/google-compute-image.nix
+++ b/nixos/modules/virtualisation/google-compute-image.nix
@@ -23,7 +23,7 @@ in
 
           postVM =
             ''
-              PATH=$PATH:${stdenv.lib.makeBinPath [ pkgs.gnutar pkgs.gzip ]}
+              PATH=$PATH:${pkgs.stdenv.lib.makeBinPath [ pkgs.gnutar pkgs.gzip ]}
               pushd $out
               mv $diskImageBase disk.raw
               tar -Szcf $diskImageBase.tar.gz disk.raw
diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix
index 5f669dee7545..101ea9a4f51b 100644
--- a/nixos/modules/virtualisation/libvirtd.nix
+++ b/nixos/modules/virtualisation/libvirtd.nix
@@ -13,6 +13,9 @@ let
     auth_unix_rw = "none"
     ${cfg.extraConfig}
   '';
+  qemuConfigFile = pkgs.writeText "qemu.conf" ''
+    ${cfg.qemuVerbatimConfig}
+  '';
 
 in {
 
@@ -48,6 +51,18 @@ in {
       '';
     };
 
+    virtualisation.libvirtd.qemuVerbatimConfig = mkOption {
+      type = types.lines;
+      default = ''
+        namespaces = []
+      '';
+      description = ''
+        Contents written to the qemu configuration file, qemu.conf.
+        Make sure to include a proper namespace configuration when
+        supplying custom configuration.
+      '';
+    };
+
     virtualisation.libvirtd.extraOptions = mkOption {
       type = types.listOf types.str;
       default = [ ];
@@ -119,6 +134,9 @@ in {
             cp -npd ${pkgs.libvirt}/var/lib/$i /var/lib/$i
         done
 
+        # Copy generated qemu config to libvirt directory
+        cp -f ${qemuConfigFile} /var/lib/libvirt/qemu.conf
+
         # libvirtd puts the full path of the emulator binary in the machine
         # config file. But this path can unfortunately be garbage collected
         # while still being used by the virtual machine. So update the
diff --git a/nixos/modules/virtualisation/lxc.nix b/nixos/modules/virtualisation/lxc.nix
index 6759ff0f2fe9..2310fe984325 100644
--- a/nixos/modules/virtualisation/lxc.nix
+++ b/nixos/modules/virtualisation/lxc.nix
@@ -71,6 +71,7 @@ in
     environment.etc."lxc/lxc.conf".text = cfg.systemConfig;
     environment.etc."lxc/lxc-usernet".text = cfg.usernetConfig;
     environment.etc."lxc/default.conf".text = cfg.defaultConfig;
+    systemd.tmpfiles.rules = [ "d /var/lib/lxc/rootfs 0755 root root -" ];
 
     security.apparmor.packages = [ pkgs.lxc ];
     security.apparmor.profiles = [ "${pkgs.lxc}/etc/apparmor.d/lxc-containers" ];
diff --git a/nixos/modules/virtualisation/nova-config.nix b/nixos/modules/virtualisation/nova-config.nix
new file mode 100644
index 000000000000..aac11ec8a178
--- /dev/null
+++ b/nixos/modules/virtualisation/nova-config.nix
@@ -0,0 +1,57 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  imports = [
+    ../profiles/qemu-guest.nix
+    ../profiles/headless.nix
+    ./grow-partition.nix
+  ];
+
+  config = {
+    fileSystems."/" = {
+      device = "/dev/disk/by-label/nixos";
+      autoResize = true;
+    };
+
+    virtualisation.growPartition = true;
+
+    boot.kernelParams = [ "console=ttyS0" ];
+    boot.loader.grub.device = "/dev/vda";
+    boot.loader.timeout = 0;
+
+    # Allow root logins
+    services.openssh.enable = true;
+    services.openssh.permitRootLogin = "prohibit-password";
+
+    # Put /tmp and /var on /ephemeral0, which has a lot more space.
+    # Unfortunately we can't do this with the `fileSystems' option
+    # because it has no support for creating the source of a bind
+    # mount.  Also, "move" /nix to /ephemeral0 by layering a unionfs-fuse
+    # mount on top of it so we have a lot more space for Nix operations.
+
+    /*
+    boot.initrd.postMountCommands =
+      ''
+        mkdir -m 1777 -p $targetRoot/ephemeral0/tmp
+        mkdir -m 1777 -p $targetRoot/tmp
+        mount --bind $targetRoot/ephemeral0/tmp $targetRoot/tmp
+
+        mkdir -m 755 -p $targetRoot/ephemeral0/var
+        mkdir -m 755 -p $targetRoot/var
+        mount --bind $targetRoot/ephemeral0/var $targetRoot/var
+
+        mkdir -p /unionfs-chroot/ro-nix
+        mount --rbind $targetRoot/nix /unionfs-chroot/ro-nix
+
+        mkdir -p /unionfs-chroot/rw-nix
+        mkdir -m 755 -p $targetRoot/ephemeral0/nix
+        mount --rbind $targetRoot/ephemeral0/nix /unionfs-chroot/rw-nix
+        unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot,max_files=32768 /rw-nix=RW:/ro-nix=RO $targetRoot/nix
+      '';
+
+      boot.initrd.supportedFilesystems = [ "unionfs-fuse" ];
+    */
+  };
+}
diff --git a/nixos/modules/virtualisation/nova-image.nix b/nixos/modules/virtualisation/nova-image.nix
deleted file mode 100644
index e253c77ebb4f..000000000000
--- a/nixos/modules/virtualisation/nova-image.nix
+++ /dev/null
@@ -1,65 +0,0 @@
-# Usage:
-# $ NIXOS_CONFIG=`pwd`/nixos/modules/virtualisation/nova-image.nix nix-build '<nixpkgs/nixos>' -A config.system.build.novaImage
-
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-{
-  system.build.novaImage = import ../../lib/make-disk-image.nix {
-    inherit pkgs lib config;
-    partitioned = true;
-    diskSize = 1 * 1024;
-    configFile = pkgs.writeText "configuration.nix"
-      ''
-        {
-          imports = [ <nixpkgs/nixos/modules/virtualisation/nova-image.nix> ];
-        }
-      '';
-  };
-
-  imports = [
-    ../profiles/qemu-guest.nix
-    ../profiles/headless.nix
-  ];
-
-  fileSystems."/".device = "/dev/disk/by-label/nixos";
-
-  boot.kernelParams = [ "console=ttyS0" ];
-  boot.loader.grub.device = "/dev/vda";
-  boot.loader.timeout = 0;
-
-  # Allow root logins
-  services.openssh.enable = true;
-  services.openssh.permitRootLogin = "prohibit-password";
-
-  # Put /tmp and /var on /ephemeral0, which has a lot more space.
-  # Unfortunately we can't do this with the `fileSystems' option
-  # because it has no support for creating the source of a bind
-  # mount.  Also, "move" /nix to /ephemeral0 by layering a unionfs-fuse
-  # mount on top of it so we have a lot more space for Nix operations.
-
-  /*
-  boot.initrd.postMountCommands =
-    ''
-      mkdir -m 1777 -p $targetRoot/ephemeral0/tmp
-      mkdir -m 1777 -p $targetRoot/tmp
-      mount --bind $targetRoot/ephemeral0/tmp $targetRoot/tmp
-
-      mkdir -m 755 -p $targetRoot/ephemeral0/var
-      mkdir -m 755 -p $targetRoot/var
-      mount --bind $targetRoot/ephemeral0/var $targetRoot/var
-
-      mkdir -p /unionfs-chroot/ro-nix
-      mount --rbind $targetRoot/nix /unionfs-chroot/ro-nix
-
-      mkdir -p /unionfs-chroot/rw-nix
-      mkdir -m 755 -p $targetRoot/ephemeral0/nix
-      mount --rbind $targetRoot/ephemeral0/nix /unionfs-chroot/rw-nix
-      unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot,max_files=32768 /rw-nix=RW:/ro-nix=RO $targetRoot/nix
-    '';
-
-    boot.initrd.supportedFilesystems = [ "unionfs-fuse" ];
-  */
-
-}
diff --git a/nixos/modules/virtualisation/openstack/glance.nix b/nixos/modules/virtualisation/openstack/glance.nix
index 4d85718e369c..7862409a65ec 100644
--- a/nixos/modules/virtualisation/openstack/glance.nix
+++ b/nixos/modules/virtualisation/openstack/glance.nix
@@ -43,7 +43,7 @@ in {
     package = mkOption {
       type = types.package;
       default = pkgs.glance;
-      example = literalExample "pkgs.glance";
+      defaultText = "pkgs.glance";
       description = ''
         Glance package to use.
       '';
diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix
index 56a05028b1d1..1933f11d1fff 100644
--- a/nixos/modules/virtualisation/qemu-vm.nix
+++ b/nixos/modules/virtualisation/qemu-vm.nix
@@ -136,15 +136,17 @@ let
                       else "-nographic -serial pty";
         }
         ''
-          # Create a /boot EFI partition with 40M
-          ${pkgs.gptfdisk}/bin/sgdisk -G /dev/vda
-          ${pkgs.gptfdisk}/bin/sgdisk -a 1 -n 1:34:2047 -c 1:"BIOS Boot Partition" -t 1:ef02 /dev/vda
-          ${pkgs.gptfdisk}/bin/sgdisk -a 512 -N 2 -c 2:"EFI System" -t 2:ef00 /dev/vda
-          ${pkgs.gptfdisk}/bin/sgdisk -A 1:set:1 /dev/vda
-          ${pkgs.gptfdisk}/bin/sgdisk -A 2:set:2 /dev/vda
-          ${pkgs.gptfdisk}/bin/sgdisk -h 2 /dev/vda
-          ${pkgs.gptfdisk}/bin/sgdisk -C /dev/vda
-          ${pkgs.utillinux}/bin/sfdisk /dev/vda -A 2
+          # Create a /boot EFI partition with 40M and arbitrary but fixed GUIDs for reproducibility
+          ${pkgs.gptfdisk}/bin/sgdisk \
+            --set-alignment=1 --new=1:34:2047 --change-name=1:BIOSBootPartition --typecode=1:ef02 \
+            --set-alignment=512 --largest-new=2 --change-name=2:EFISystem --typecode=2:ef00 \
+            --attributes=1:set:1 \
+            --attributes=2:set:2 \
+            --disk-guid=97FD5997-D90B-4AA3-8D16-C1723AEA73C1 \
+            --partition-guid=1:1C06F03B-704E-4657-B9CD-681A087A2FDC \
+            --partition-guid=2:970C694F-AFD0-4B99-B750-CDB7A329AB6F \
+            --hybrid 2 \
+            --recompute-chs /dev/vda
           . /sys/class/block/vda2/uevent
           mknod /dev/vda2 b $MAJOR $MINOR
           . /sys/class/block/vda/uevent
diff --git a/nixos/modules/virtualisation/virtualbox-guest.nix b/nixos/modules/virtualisation/virtualbox-guest.nix
index d253e9eab62b..5da4b7e3bafd 100644
--- a/nixos/modules/virtualisation/virtualbox-guest.nix
+++ b/nixos/modules/virtualisation/virtualbox-guest.nix
@@ -15,18 +15,27 @@ in
 
   ###### interface
 
-  options.virtualisation.virtualbox.guest.enable = mkOption {
-    default = false;
-    description = "Whether to enable the VirtualBox service and other guest additions.";
+  options.virtualisation.virtualbox.guest = {
+    enable = mkOption {
+      default = false;
+      type = types.bool;
+      description = "Whether to enable the VirtualBox service and other guest additions.";
+    };
+
+    x11 = mkOption {
+      default = true;
+      type = types.bool;
+      description = "Whether to enable x11 graphics";
+    };
   };
 
   ###### implementation
 
-  config = mkIf cfg.enable {
-    assertions = [ {
+  config = mkIf cfg.enable (mkMerge [{
+    assertions = [{
       assertion = pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64;
       message = "Virtualbox not currently supported on ${pkgs.stdenv.system}";
-    } ];
+    }];
 
     environment.systemPackages = [ kernel.virtualboxGuestAdditions ];
 
@@ -49,6 +58,16 @@ in
         serviceConfig.ExecStart = "@${kernel.virtualboxGuestAdditions}/bin/VBoxService VBoxService --foreground";
       };
 
+    services.udev.extraRules =
+      ''
+        # /dev/vboxuser is necessary for VBoxClient to work.  Maybe we
+        # should restrict this to logged-in users.
+        KERNEL=="vboxuser",  OWNER="root", GROUP="root", MODE="0666"
+
+        # Allow systemd dependencies on vboxguest.
+        SUBSYSTEM=="misc", KERNEL=="vboxguest", TAG+="systemd"
+      '';
+  } (mkIf cfg.x11 {
     services.xserver.videoDrivers = mkOverride 50 [ "virtualbox" "modesetting" ];
 
     services.xserver.config =
@@ -69,16 +88,6 @@ in
         PATH=${makeBinPath [ pkgs.gnugrep pkgs.which pkgs.xorg.xorgserver.out ]}:$PATH \
           ${kernel.virtualboxGuestAdditions}/bin/VBoxClient-all
       '';
-
-    services.udev.extraRules =
-      ''
-        # /dev/vboxuser is necessary for VBoxClient to work.  Maybe we
-        # should restrict this to logged-in users.
-        KERNEL=="vboxuser",  OWNER="root", GROUP="root", MODE="0666"
-
-        # Allow systemd dependencies on vboxguest.
-        SUBSYSTEM=="misc", KERNEL=="vboxguest", TAG+="systemd"
-      '';
-  };
+  })]);
 
 }
diff --git a/nixos/modules/virtualisation/xen-dom0.nix b/nixos/modules/virtualisation/xen-dom0.nix
index 67eef0ec1e4c..57487f704519 100644
--- a/nixos/modules/virtualisation/xen-dom0.nix
+++ b/nixos/modules/virtualisation/xen-dom0.nix
@@ -27,6 +27,36 @@ in
           '';
       };
 
+    virtualisation.xen.package = mkOption {
+      type = types.package;
+      default = pkgs.xen;
+      defaultText = "pkgs.xen";
+      example = literalExample "pkgs.xen-light";
+      description = ''
+        The package used for Xen binary.
+      '';
+    };
+
+    virtualisation.xen.qemu = mkOption {
+      type = types.path;
+      default = "${pkgs.xen}/lib/xen/bin/qemu-system-i386";
+      defaultText = "\${pkgs.xen}/lib/xen/bin/qemu-system-i386";
+      example = literalExample "''${pkgs.qemu_xen-light}/bin/qemu-system-i386";
+      description = ''
+        The qemu binary to use for Dom-0 backend.
+      '';
+    };
+
+    virtualisation.xen.qemu-package = mkOption {
+      type = types.package;
+      default = pkgs.xen;
+      defaultText = "pkgs.xen";
+      example = literalExample "pkgs.qemu_xen-light";
+      description = ''
+        The package with qemu binaries for xendomains.
+      '';
+    };
+
     virtualisation.xen.bootParams =
       mkOption {
         default = "";
@@ -106,9 +136,9 @@ in
       message = "Xen currently does not support EFI boot";
     } ];
 
-    virtualisation.xen.stored = mkDefault "${pkgs.xen}/bin/oxenstored";
+    virtualisation.xen.stored = mkDefault "${cfg.package}/bin/oxenstored";
 
-    environment.systemPackages = [ pkgs.xen ];
+    environment.systemPackages = [ cfg.package ];
 
     # Make sure Domain 0 gets the required configuration
     #boot.kernelPackages = pkgs.boot.kernelPackages.override { features={xen_dom0=true;}; };
@@ -144,7 +174,7 @@ in
 
     system.extraSystemBuilderCmds =
       ''
-        ln -s ${pkgs.xen}/boot/xen.gz $out/xen.gz
+        ln -s ${cfg.package}/boot/xen.gz $out/xen.gz
         echo "${toString cfg.bootParams}" > $out/xen-params
       '';
 
@@ -180,19 +210,19 @@ in
 
 
     environment.etc =
-      [ { source = "${pkgs.xen}/etc/xen/xl.conf";
+      [ { source = "${cfg.package}/etc/xen/xl.conf";
           target = "xen/xl.conf";
         }
-        { source = "${pkgs.xen}/etc/xen/scripts";
+        { source = "${cfg.package}/etc/xen/scripts";
           target = "xen/scripts";
         }
-        { source = "${pkgs.xen}/etc/default/xendomains";
+        { source = "${cfg.package}/etc/default/xendomains";
           target = "default/xendomains";
         }
       ];
 
     # Xen provides udev rules.
-    services.udev.packages = [ pkgs.xen ];
+    services.udev.packages = [ cfg.package ];
 
     services.udev.path = [ pkgs.bridge-utils pkgs.iproute ];
 
@@ -217,7 +247,7 @@ in
         time=0
         timeout=30
         # Wait for xenstored to actually come up, timing out after 30 seconds
-        while [ $time -lt $timeout ] && ! `${pkgs.xen}/bin/xenstore-read -s / >/dev/null 2>&1` ; do
+        while [ $time -lt $timeout ] && ! `${cfg.package}/bin/xenstore-read -s / >/dev/null 2>&1` ; do
             time=$(($time+1))
             sleep 1
         done
@@ -228,8 +258,8 @@ in
             exit 1
         fi
 
-        ${pkgs.xen}/bin/xenstore-write "/local/domain/0/name" "Domain-0"
-        ${pkgs.xen}/bin/xenstore-write "/local/domain/0/domid" 0
+        ${cfg.package}/bin/xenstore-write "/local/domain/0/name" "Domain-0"
+        ${cfg.package}/bin/xenstore-write "/local/domain/0/domid" 0
         '';
     };
 
@@ -256,7 +286,7 @@ in
         '';
       serviceConfig = {
         ExecStart = ''
-          ${pkgs.xen}/bin/xenconsoled${optionalString cfg.trace " --log=all --log-dir=/var/log/xen"}
+          ${cfg.package}/bin/xenconsoled${optionalString cfg.trace " --log=all --log-dir=/var/log/xen"}
           '';
       };
     };
@@ -267,8 +297,8 @@ in
       wantedBy = [ "multi-user.target" ];
       after = [ "xen-console.service" ];
       serviceConfig.ExecStart = ''
-        ${pkgs.xen}/lib/xen/bin/qemu-system-i386 -xen-domid 0 -xen-attach -name dom0 -nographic -M xenpv \
-           -monitor /dev/null -serial /dev/null -parallel /dev/null
+        ${cfg.qemu} -xen-attach -xen-domid 0 -name dom0 -M xenpv \
+           -nographic -monitor /dev/null -serial /dev/null -parallel /dev/null
         '';
     };
 
@@ -277,7 +307,7 @@ in
       description = "Xen Watchdog Daemon";
       wantedBy = [ "multi-user.target" ];
       after = [ "xen-qemu.service" ];
-      serviceConfig.ExecStart = "${pkgs.xen}/bin/xenwatchdogd 30 15";
+      serviceConfig.ExecStart = "${cfg.package}/bin/xenwatchdogd 30 15";
       serviceConfig.Type = "forking";
       serviceConfig.RestartSec = "1";
       serviceConfig.Restart = "on-failure";
@@ -366,11 +396,11 @@ in
       before = [ "dhcpd.service" ];
       restartIfChanged = false;
       serviceConfig.RemainAfterExit = "yes";
-      path = [ pkgs.xen ];
-      environment.XENDOM_CONFIG = "${pkgs.xen}/etc/sysconfig/xendomains";
+      path = [ cfg.package cfg.qemu-package ];
+      environment.XENDOM_CONFIG = "${cfg.package}/etc/sysconfig/xendomains";
       preStart = "mkdir -p /var/lock/subsys -m 755";
-      serviceConfig.ExecStart = "${pkgs.xen}/etc/init.d/xendomains start";
-      serviceConfig.ExecStop = "${pkgs.xen}/etc/init.d/xendomains stop";
+      serviceConfig.ExecStart = "${cfg.package}/etc/init.d/xendomains start";
+      serviceConfig.ExecStop = "${cfg.package}/etc/init.d/xendomains stop";
     };
 
   };
diff --git a/nixos/modules/virtualisation/xen-domU.nix b/nixos/modules/virtualisation/xen-domU.nix
index 8dd0d1dbfd2c..b46002c10b54 100644
--- a/nixos/modules/virtualisation/xen-domU.nix
+++ b/nixos/modules/virtualisation/xen-domU.nix
@@ -3,11 +3,8 @@
 { config, pkgs, ... }:
 
 {
-  # We're being booted using pv-grub, which means that we need to
-  # generate a GRUB 1 menu without actually installing GRUB.
-  boot.loader.grub.version = 1;
+  boot.loader.grub.version = 2;
   boot.loader.grub.device = "nodev";
-  boot.loader.grub.extraPerEntryConfig = "root (hd0)";
 
   boot.initrd.kernelModules =
     [ "xen-blkfront" "xen-tpmfront" "xen-kbdfront" "xen-fbfront"
diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix
index 6c048e8a0aca..1953fd1a26a7 100644
--- a/nixos/release-combined.nix
+++ b/nixos/release-combined.nix
@@ -4,7 +4,7 @@
 
 { nixpkgs ? { outPath = ./..; revCount = 56789; shortRev = "gfedcba"; }
 , stableBranch ? false
-, supportedSystems ? [ "x86_64-linux" "i686-linux" ]
+, supportedSystems ? [ "x86_64-linux" "i686-linux" "aarch64-linux" ]
 }:
 
 let
@@ -68,11 +68,11 @@ in rec {
         (all nixos.tests.boot.uefiCdrom)
         (all nixos.tests.boot.uefiUsb)
         (all nixos.tests.boot-stage1)
-        (all nixos.tests.hibernate)
+        nixos.tests.hibernate.x86_64-linux # i686 is flaky, see #23107
         (all nixos.tests.ecryptfs)
         (all nixos.tests.ipv6)
         (all nixos.tests.i3wm)
-        (all nixos.tests.kde5)
+        (all nixos.tests.plasma5)
         #(all nixos.tests.lightdm)
         (all nixos.tests.login)
         (all nixos.tests.misc)
diff --git a/nixos/release.nix b/nixos/release.nix
index 0f93deddf263..0359d0907cca 100644
--- a/nixos/release.nix
+++ b/nixos/release.nix
@@ -1,6 +1,6 @@
 { nixpkgs ? { outPath = ./..; revCount = 56789; shortRev = "gfedcba"; }
 , stableBranch ? false
-, supportedSystems ? [ "x86_64-linux" "i686-linux" ]
+, supportedSystems ? [ "x86_64-linux" "i686-linux" "aarch64-linux" ]
 }:
 
 with import ../lib;
@@ -255,7 +255,7 @@ in rec {
   tests.influxdb = callTest tests/influxdb.nix {};
   tests.ipv6 = callTest tests/ipv6.nix {};
   tests.jenkins = callTest tests/jenkins.nix {};
-  tests.kde5 = callTest tests/kde5.nix {};
+  tests.plasma5 = callTest tests/plasma5.nix {};
   tests.keymap = callSubTests tests/keymap.nix {};
   tests.initrdNetwork = callTest tests/initrd-network.nix {};
   tests.keystone = callTest tests/keystone.nix {};
@@ -286,6 +286,7 @@ in rec {
   tests.pam-oath-login = callTest tests/pam-oath-login.nix {};
   #tests.panamax = hydraJob (import tests/panamax.nix { system = "x86_64-linux"; });
   tests.peerflix = callTest tests/peerflix.nix {};
+  tests.pgjwt = callTest tests/pgjwt.nix {};
   tests.postgresql = callTest tests/postgresql.nix {};
   tests.printing = callTest tests/printing.nix {};
   tests.proxy = callTest tests/proxy.nix {};
@@ -326,7 +327,7 @@ in rec {
     kde = makeClosure ({ pkgs, ... }:
       { services.xserver.enable = true;
         services.xserver.displayManager.sddm.enable = true;
-        services.xserver.desktopManager.kde5.enable = true;
+        services.xserver.desktopManager.plasma5.enable = true;
       });
 
     xfce = makeClosure ({ pkgs, ... }:
diff --git a/nixos/tests/buildbot.nix b/nixos/tests/buildbot.nix
new file mode 100644
index 000000000000..13a162e6c6e8
--- /dev/null
+++ b/nixos/tests/buildbot.nix
@@ -0,0 +1,46 @@
+# Test ensures buildbot master comes up correctly and workers can connect
+
+import ./make-test.nix ({ pkgs, ... } : {
+  name = "buildbot";
+
+  nodes = {
+    bbmaster = { config, pkgs, nodes, ... }: {
+      services.buildbot-master = {
+        enable = true;
+        factorySteps = [
+          "steps.Git(repourl='git://github.com/buildbot/pyflakes.git', mode='incremental')"
+          "steps.ShellCommand(command=['trial', 'pyflakes'])"
+        ];
+        changeSource = [
+          "changes.GitPoller('git://github.com/buildbot/pyflakes.git', workdir='gitpoller-workdir', branch='master', pollinterval=300)"
+        ];
+      };
+      networking.firewall.allowedTCPPorts = [ 8010 9989 ];
+    };
+
+    bbworker = { config, pkgs, ... }: {
+      services.buildbot-worker = {
+        enable = true;
+        masterUrl = "bbmaster:9989";
+      };
+    };
+  };
+
+  testScript = ''
+
+    $bbmaster->waitForUnit("network.target");
+    $bbworker->waitForUnit("network.target");
+
+    # Additional tests to be added
+    #$bbmaster->waitForUnit("buildbot-master.service");
+    #$bbmaster->waitUntilSucceeds("curl -s --head http://bbmaster:8010") =~ /200 OK/ or die;
+    #$bbworker->waitForUnit("buildbot-worker.service");
+    #$bbworker->waitUntilSucceeds("tail -10 /home/bbworker/worker/twistd.log") =~ /success/ or die;
+
+  '';
+
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ nand0p ];
+  };
+
+})
diff --git a/nixos/tests/cjdns.nix b/nixos/tests/cjdns.nix
index f32ec52dfc26..466663799241 100644
--- a/nixos/tests/cjdns.nix
+++ b/nixos/tests/cjdns.nix
@@ -109,14 +109,14 @@ import ./make-test.nix ({ pkgs, ...} : {
 
       # ping a few times each to let the routing table establish itself
 
-      $alice->succeed("ping6 -c 4 $carolIp6");
-      $bob->succeed("ping6 -c 4 $carolIp6");
+      $alice->succeed("ping -c 4 $carolIp6");
+      $bob->succeed("ping -c 4 $carolIp6");
 
-      $carol->succeed("ping6 -c 4 $aliceIp6");
-      $carol->succeed("ping6 -c 4 $bobIp6");
+      $carol->succeed("ping -c 4 $aliceIp6");
+      $carol->succeed("ping -c 4 $bobIp6");
 
-      $alice->succeed("ping6 -c 4 $bobIp6");
-      $bob->succeed("ping6 -c 4 $aliceIp6");
+      $alice->succeed("ping -c 4 $bobIp6");
+      $bob->succeed("ping -c 4 $aliceIp6");
 
       $alice->waitForUnit("httpd.service");
 
diff --git a/nixos/tests/containers-bridge.nix b/nixos/tests/containers-bridge.nix
index bb32d852a6f5..598abd22e61b 100644
--- a/nixos/tests/containers-bridge.nix
+++ b/nixos/tests/containers-bridge.nix
@@ -66,7 +66,7 @@ import ./make-test.nix ({ pkgs, ...} : {
       "${containerIp6}" =~ /([^\/]+)\/([0-9+])/;
       my $ip6 = $1;
       chomp $ip6;
-      $machine->succeed("ping6 -n -c 1 $ip6");
+      $machine->succeed("ping -n -c 1 $ip6");
       $machine->succeed("curl --fail http://[$ip6]/ > /dev/null");
 
       # Stop the container.
diff --git a/nixos/tests/containers-extra_veth.nix b/nixos/tests/containers-extra_veth.nix
index 2a54b1d961c8..6339c8c558b9 100644
--- a/nixos/tests/containers-extra_veth.nix
+++ b/nixos/tests/containers-extra_veth.nix
@@ -84,7 +84,7 @@ import ./make-test.nix ({ pkgs, ...} : {
 
       # Ping on main veth
       $machine->succeed("ping -n -c 1 192.168.0.100");
-      $machine->succeed("ping6 -n -c 1 fc00::2");
+      $machine->succeed("ping -n -c 1 fc00::2");
 
       # Ping on the first extra veth
       $machine->succeed("ping -n -c 1 192.168.1.100 >&2");
diff --git a/nixos/tests/containers-ipv6.nix b/nixos/tests/containers-ipv6.nix
index 320465ebb95b..f676ed122bb3 100644
--- a/nixos/tests/containers-ipv6.nix
+++ b/nixos/tests/containers-ipv6.nix
@@ -47,7 +47,7 @@ import ./make-test.nix ({ pkgs, ...} : {
       # multi-user.target, we should now be able to access it.
       my $ip = "${localIp}";
       chomp $ip;
-      $machine->succeed("ping6 -n -c 1 $ip");
+      $machine->succeed("ping -n -c 1 $ip");
       $machine->succeed("curl --fail http://[$ip]/ > /dev/null");
 
       # Stop the container.
diff --git a/nixos/tests/ec2.nix b/nixos/tests/ec2.nix
index e1f7143e3a95..4ec7e56cc6cb 100644
--- a/nixos/tests/ec2.nix
+++ b/nixos/tests/ec2.nix
@@ -25,8 +25,13 @@ let
           # access. Mostly copied from
           # modules/profiles/installation-device.nix.
           system.extraDependencies =
-            [ pkgs.stdenv pkgs.busybox pkgs.perlPackages.ArchiveCpio
-              pkgs.unionfs-fuse pkgs.mkinitcpio-nfs-utils
+            with pkgs; [
+              stdenv busybox perlPackages.ArchiveCpio unionfs-fuse mkinitcpio-nfs-utils
+
+              # These are used in the configure-from-userdata tests for EC2. Httpd and valgrind are requested
+              # directly by the configuration we set, and libxslt.bin is used indirectly as a build dependency
+              # of the derivation for dbus configuration files.
+              apacheHttpd valgrind.doc libxslt.bin
             ];
         }
       ];
@@ -137,6 +142,8 @@ in {
 
     # ### http://nixos.org/channels/nixos-unstable nixos
     userData = ''
+      { pkgs, ... }:
+
       {
         imports = [
           <nixpkgs/nixos/modules/virtualisation/amazon-image.nix>
@@ -146,12 +153,22 @@ in {
         environment.etc.testFile = {
           text = "whoa";
         };
+
+        services.httpd = {
+          enable = true;
+          adminAddr = "test@example.org";
+          documentRoot = "${pkgs.valgrind.doc}/share/doc/valgrind/html";
+        };
+        networking.firewall.allowedTCPPorts = [ 80 ];
       }
     '';
     script = ''
       $machine->start;
       $machine->waitForFile("/etc/testFile");
       $machine->succeed("cat /etc/testFile | grep -q 'whoa'");
+
+      $machine->waitForUnit("httpd.service");
+      $machine->succeed("curl http://localhost | grep Valgrind");
     '';
   };
 }
diff --git a/nixos/tests/ipv6.nix b/nixos/tests/ipv6.nix
index 4e2e6379cad3..060f63216796 100644
--- a/nixos/tests/ipv6.nix
+++ b/nixos/tests/ipv6.nix
@@ -54,22 +54,22 @@ import ./make-test.nix ({ pkgs, ...} : {
       }
 
       subtest "loopback address", sub {
-          $client->succeed("ping6 -c 1 ::1 >&2");
-          $client->fail("ping6 -c 1 ::2 >&2");
+          $client->succeed("ping -c 1 ::1 >&2");
+          $client->fail("ping -c 1 ::2 >&2");
       };
 
       subtest "local link addressing", sub {
           my $clientIp = waitForAddress $client, "eth1", "link";
           my $serverIp = waitForAddress $server, "eth1", "link";
-          $client->succeed("ping6 -c 1 -I eth1 $clientIp >&2");
-          $client->succeed("ping6 -c 1 -I eth1 $serverIp >&2");
+          $client->succeed("ping -c 1 $clientIp%eth1 >&2");
+          $client->succeed("ping -c 1 $serverIp%eth1 >&2");
       };
 
       subtest "global addressing", sub {
           my $clientIp = waitForAddress $client, "eth1", "global";
           my $serverIp = waitForAddress $server, "eth1", "global";
-          $client->succeed("ping6 -c 1 $clientIp >&2");
-          $client->succeed("ping6 -c 1 $serverIp >&2");
+          $client->succeed("ping -c 1 $clientIp >&2");
+          $client->succeed("ping -c 1 $serverIp >&2");
           $client->succeed("curl --fail -g http://[$serverIp]");
           $client->fail("curl --fail -g http://[$clientIp]");
       };
diff --git a/nixos/tests/leaps.nix b/nixos/tests/leaps.nix
index 3c390e1a1691..6163fed56b6f 100644
--- a/nixos/tests/leaps.nix
+++ b/nixos/tests/leaps.nix
@@ -24,6 +24,7 @@ import ./make-test.nix ({ pkgs,  ... }:
     ''
       startAll;
       $server->waitForOpenPort(6666);
-      $client->succeed("curl http://server:6666/leaps/ | grep -i 'leaps'"); 
+      $client->waitForUnit("network.target");
+      $client->succeed("${pkgs.curl}/bin/curl http://server:6666/leaps/ | grep -i 'leaps'");
     '';
 })
diff --git a/nixos/tests/networking.nix b/nixos/tests/networking.nix
index 8b573869c157..6a7e628d8ef1 100644
--- a/nixos/tests/networking.nix
+++ b/nixos/tests/networking.nix
@@ -1,4 +1,6 @@
-{ system ? builtins.currentSystem, networkd }:
+{ system ? builtins.currentSystem
+# bool: whether to use networkd in the tests
+, networkd }:
 
 with import ../lib/testing.nix { inherit system; };
 with pkgs.lib;
@@ -166,24 +168,24 @@ let
           # Test vlan 1
           $client->waitUntilSucceeds("ping -c 1 192.168.1.1");
           $client->waitUntilSucceeds("ping -c 1 192.168.1.2");
-          $client->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:1::1");
-          $client->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:1::2");
+          $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1");
+          $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::2");
 
           $router->waitUntilSucceeds("ping -c 1 192.168.1.1");
           $router->waitUntilSucceeds("ping -c 1 192.168.1.2");
-          $router->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:1::1");
-          $router->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:1::2");
+          $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1");
+          $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::2");
 
           # Test vlan 2
           $client->waitUntilSucceeds("ping -c 1 192.168.2.1");
           $client->waitUntilSucceeds("ping -c 1 192.168.2.2");
-          $client->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:2::1");
-          $client->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:2::2");
+          $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::1");
+          $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::2");
 
           $router->waitUntilSucceeds("ping -c 1 192.168.2.1");
           $router->waitUntilSucceeds("ping -c 1 192.168.2.2");
-          $router->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:2::1");
-          $router->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:2::2");
+          $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::1");
+          $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::2");
         '';
     };
     dhcpOneIf = {
@@ -390,11 +392,11 @@ let
           $client2->succeed("ip addr >&2");
 
           # Test ipv6
-          $client1->waitUntilSucceeds("ping6 -c 1 fc00::1");
-          $client1->waitUntilSucceeds("ping6 -c 1 fc00::2");
+          $client1->waitUntilSucceeds("ping -c 1 fc00::1");
+          $client1->waitUntilSucceeds("ping -c 1 fc00::2");
 
-          $client2->waitUntilSucceeds("ping6 -c 1 fc00::1");
-          $client2->waitUntilSucceeds("ping6 -c 1 fc00::2");
+          $client2->waitUntilSucceeds("ping -c 1 fc00::1");
+          $client2->waitUntilSucceeds("ping -c 1 fc00::2");
         '';
     };
     vlan = let
diff --git a/nixos/tests/pgjwt.nix b/nixos/tests/pgjwt.nix
new file mode 100644
index 000000000000..2cf2963ae316
--- /dev/null
+++ b/nixos/tests/pgjwt.nix
@@ -0,0 +1,42 @@
+import ./make-test.nix ({ pkgs, ...} : 
+let
+  test = pkgs.writeText "test.sql" ''
+    CREATE EXTENSION pgcrypto;
+    CREATE EXTENSION pgjwt;
+    select sign('{"sub":"1234567890","name":"John Doe","admin":true}', 'secret');
+    select * from verify('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ', 'secret');
+  '';
+in
+{
+  name = "pgjwt";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ spinus ];
+  };
+
+  nodes = {
+    master =
+      { pkgs, config, ... }:
+
+      {
+        services.postgresql = let mypg = pkgs.postgresql95; in {
+            enable = true;
+            package = mypg;
+            extraPlugins =[pkgs.pgjwt];
+            initialScript =  pkgs.writeText "postgresql-init.sql"
+          ''
+          CREATE ROLE postgres WITH superuser login createdb;
+          '';
+          };
+      };
+  };
+
+  testScript = ''
+    startAll;
+    $master->waitForUnit("postgresql");
+    $master->succeed("timeout 10 bash -c 'while ! psql postgres -c \"SELECT 1;\";do sleep 1;done;'");
+    $master->succeed("cat ${test} | psql postgres");
+    # I can't make original test working :[
+    # $master->succeed("${pkgs.perlPackages.TAPParserSourceHandlerpgTAP}/bin/pg_prove -d postgres ${pkgs.pgjwt.src}/test.sql");
+
+  '';
+})
diff --git a/nixos/tests/phabricator.nix b/nixos/tests/phabricator.nix
index 85faafd56899..fdc39393faea 100644
--- a/nixos/tests/phabricator.nix
+++ b/nixos/tests/phabricator.nix
@@ -54,7 +54,7 @@ import ./make-test.nix ({ pkgs, ... }: {
     client =
       { config, pkgs, ... }:
       { imports = [ ./common/x11.nix ];
-        services.xserver.desktopManager.kde5.enable = true;
+        services.xserver.desktopManager.plasma5.enable = true;
       };
   };
 
diff --git a/nixos/tests/kde5.nix b/nixos/tests/plasma5.nix
index 2b61d6f3f0a1..ca787e9c7b9b 100644
--- a/nixos/tests/kde5.nix
+++ b/nixos/tests/plasma5.nix
@@ -1,7 +1,7 @@
 import ./make-test.nix ({ pkgs, ...} :
 
 {
-  name = "kde5";
+  name = "plasma5";
   meta = with pkgs.stdenv.lib.maintainers; {
     maintainers = [ ttuegel ];
   };
@@ -17,7 +17,8 @@ import ./make-test.nix ({ pkgs, ...} :
         user = "alice";
       };
     };
-    services.xserver.desktopManager.kde5.enable = true;
+    services.xserver.desktopManager.plasma5.enable = true;
+    services.xserver.desktopManager.default = "plasma5";
     virtualisation.writableStore = false; # FIXME
   };
 
diff --git a/nixos/tests/pump.io.nix b/nixos/tests/pump.io.nix
index 18da52b5134b..0991ed3fce1f 100644
--- a/nixos/tests/pump.io.nix
+++ b/nixos/tests/pump.io.nix
@@ -51,16 +51,6 @@ import ./make-test.nix ({ pkgs, ...} : let
     Vd5WD2HJhLb9u0UxVp9vfWIUDgydopV5ZmWCQ5YvNepb1w==
     -----END CERTIFICATE-----
   '';
-
-  makePump = { opts ? { } }:
-    {
-      enable = true;
-      sslCert = pkgs.writeText "snakeoil.cert" snakeOilCert;
-      sslKey = pkgs.writeText "snakeoil.pem" snakeOilKey;
-      secret = "test";
-      site = "test";
-    } // opts;
-
 in {
   name = "pumpio";
   meta = with pkgs.stdenv.lib.maintainers; {
@@ -72,9 +62,14 @@ in {
       { config, pkgs, ... }:
         {
           services = {
-           pumpio = makePump { opts = {
+           pumpio = {
              port = 443;
-           }; };
+             enable = true;
+             sslCert = pkgs.writeText "snakeoil.cert" snakeOilCert;
+             sslKey = pkgs.writeText "snakeoil.pem" snakeOilKey;
+             secretFile = pkgs.writeText "secretFile" "test123";
+             site = "test";
+           };
            mongodb.enable = true;
            mongodb.extraConfig = ''
              storage.journal.enabled: false
diff --git a/nixos/tests/samba.nix b/nixos/tests/samba.nix
index d6658ef0400b..e446284fc0ef 100644
--- a/nixos/tests/samba.nix
+++ b/nixos/tests/samba.nix
@@ -37,12 +37,11 @@ import ./make-test.nix ({ pkgs, ... }:
   testScript =
     ''
       $server->start;
-      $server->waitForUnit("samba-smbd");
-      $server->waitForUnit("samba-nmbd");
+      $server->waitForUnit("samba.target");
       $server->succeed("mkdir -p /public; echo bar > /public/foo");
 
       $client->start;
-      $client->waitForUnit("network.target");
+      $client->waitForUnit("remote-fs.target");
       $client->succeed("[[ \$(cat /public/foo) = bar ]]");
     '';
 })
diff --git a/nixos/tests/taskserver.nix b/nixos/tests/taskserver.nix
index d770b20a7757..cdccb11d8887 100644
--- a/nixos/tests/taskserver.nix
+++ b/nixos/tests/taskserver.nix
@@ -1,4 +1,62 @@
-import ./make-test.nix {
+import ./make-test.nix ({ pkgs, ... }: let
+  snakeOil = pkgs.runCommand "snakeoil-certs" {
+    outputs = [ "out" "cacert" "cert" "key" "crl" ];
+    buildInputs = [ pkgs.gnutls.bin ];
+    caTemplate = pkgs.writeText "snakeoil-ca.template" ''
+      cn = server
+      expiration_days = -1
+      cert_signing_key
+      ca
+    '';
+    certTemplate = pkgs.writeText "snakeoil-cert.template" ''
+      cn = server
+      expiration_days = -1
+      tls_www_server
+      encryption_key
+      signing_key
+    '';
+    crlTemplate = pkgs.writeText "snakeoil-crl.template" ''
+      expiration_days = -1
+    '';
+    userCertTemplace = pkgs.writeText "snakoil-user-cert.template" ''
+      organization = snakeoil
+      cn = server
+      expiration_days = -1
+      tls_www_client
+      encryption_key
+      signing_key
+    '';
+  } ''
+    certtool -p --bits 4096 --outfile ca.key
+    certtool -s --template "$caTemplate" --load-privkey ca.key \
+                --outfile "$cacert"
+    certtool -p --bits 4096 --outfile "$key"
+    certtool -c --template "$certTemplate" \
+                --load-ca-privkey ca.key \
+                --load-ca-certificate "$cacert" \
+                --load-privkey "$key" \
+                --outfile "$cert"
+    certtool --generate-crl --template "$crlTemplate" \
+                            --load-ca-privkey ca.key \
+                            --load-ca-certificate "$cacert" \
+                            --outfile "$crl"
+
+    mkdir "$out"
+
+    # Stripping key information before the actual PEM-encoded values is solely
+    # to make test output a bit less verbose when copying the client key to the
+    # actual client.
+    certtool -p --bits 4096 | sed -n \
+      -e '/^----* *BEGIN/,/^----* *END/p' > "$out/alice.key"
+
+    certtool -c --template "$userCertTemplace" \
+                --load-privkey "$out/alice.key" \
+                --load-ca-privkey ca.key \
+                --load-ca-certificate "$cacert" \
+                --outfile "$out/alice.cert"
+  '';
+
+in {
   name = "taskserver";
 
   nodes = rec {
@@ -12,6 +70,23 @@ import ./make-test.nix {
       };
     };
 
+    # New generation of the server with manual config
+    newServer = { lib, nodes, ... }: {
+      imports = [ server ];
+      services.taskserver.pki.manual = {
+        ca.cert = snakeOil.cacert;
+        server.cert = snakeOil.cert;
+        server.key = snakeOil.key;
+        server.crl = snakeOil.crl;
+      };
+      # This is to avoid assigning a different network address to the new
+      # generation.
+      networking = lib.mapAttrs (lib.const lib.mkForce) {
+        inherit (nodes.server.config.networking)
+          hostName interfaces primaryIPAddress extraHosts;
+      };
+    };
+
     client1 = { pkgs, ... }: {
       environment.systemPackages = [ pkgs.taskwarrior pkgs.gnutls ];
       users.users.alice.isNormalUser = true;
@@ -26,6 +101,8 @@ import ./make-test.nix {
   testScript = { nodes, ... }: let
     cfg = nodes.server.config.services.taskserver;
     portStr = toString cfg.listenPort;
+    newServerSystem = nodes.newServer.config.system.build.toplevel;
+    switchToNewServer = "${newServerSystem}/bin/switch-to-configuration test";
   in ''
     sub su ($$) {
       my ($user, $cmd) = @_;
@@ -33,8 +110,8 @@ import ./make-test.nix {
       return "su - $user -c '$esc'";
     }
 
-    sub setupClientsFor ($$) {
-      my ($org, $user) = @_;
+    sub setupClientsFor ($$;$) {
+      my ($org, $user, $extraInit) = @_;
 
       for my $client ($client1, $client2) {
         $client->nest("initialize client for user $user", sub {
@@ -58,6 +135,8 @@ import ./make-test.nix {
             }
           });
 
+          eval { &$extraInit($client, $org, $user) };
+
           $client->succeed(su $user,
             "task config taskd.server server:${portStr} >&2"
           );
@@ -104,7 +183,10 @@ import ./make-test.nix {
       return su $user, $cmd;
     }
 
-    startAll;
+    # Explicitly start the VMs so that we don't accidentally start newServer
+    $server->start;
+    $client1->start;
+    $client2->start;
 
     $server->waitForUnit("taskserver.service");
 
@@ -162,5 +244,42 @@ import ./make-test.nix {
       restartServer;
       testSync "bar";
     };
+
+    subtest "check manual configuration", sub {
+      $server->succeed('${switchToNewServer} >&2');
+      $server->waitForUnit("taskserver.service");
+      $server->waitForOpenPort(${portStr});
+
+      $server->succeed(
+        "nixos-taskserver org add manualOrg",
+        "nixos-taskserver user add manualOrg alice"
+      );
+
+      setupClientsFor "manualOrg", "alice", sub {
+        my ($client, $org, $user) = @_;
+        my $cfgpath = "/home/$user/.task";
+
+        $client->copyFileFromHost("${snakeOil.cacert}", "$cfgpath/ca.cert");
+        for my $file ('alice.key', 'alice.cert') {
+          $client->copyFileFromHost("${snakeOil}/$file", "$cfgpath/$file");
+        }
+
+        for my $file ("$user.key", "$user.cert") {
+          $client->copyFileFromHost(
+            "${snakeOil}/$file", "$cfgpath/$file"
+          );
+        }
+        $client->copyFileFromHost(
+          "${snakeOil.cacert}", "$cfgpath/ca.cert"
+        );
+        $client->succeed(
+          (su "alice", "task config taskd.ca $cfgpath/ca.cert"),
+          (su "alice", "task config taskd.key $cfgpath/$user.key"),
+          (su $user, "task config taskd.certificate $cfgpath/$user.cert")
+        );
+      };
+
+      testSync "alice";
+    };
   '';
-}
+})
diff --git a/nixos/tests/trac.nix b/nixos/tests/trac.nix
index 0d56c564e182..d426bbde68d2 100644
--- a/nixos/tests/trac.nix
+++ b/nixos/tests/trac.nix
@@ -45,7 +45,7 @@ import ./make-test.nix ({ pkgs, ... }: {
     client =
       { config, pkgs, ... }:
       { imports = [ ./common/x11.nix ];
-        services.xserver.desktopManager.kde5.enable = true;
+        services.xserver.desktopManager.plasma5.enable = true;
       };
   };
 
diff --git a/nixos/tests/wordpress.nix b/nixos/tests/wordpress.nix
index afee1f7f6dd4..c51306a8c7a0 100644
--- a/nixos/tests/wordpress.nix
+++ b/nixos/tests/wordpress.nix
@@ -10,14 +10,10 @@ import ./make-test.nix ({ pkgs, ... }:
     { web =
         { config, pkgs, ... }:
         {
-          services.mysql.enable = true;
-          services.mysql.package = pkgs.mysql;
-          services.mysql.initialScript = pkgs.writeText "start.sql" ''
-            CREATE DATABASE wordpress;
-	    CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'wordpress';
-            GRANT ALL on wordpress.* TO 'wordpress'@'localhost';
-          '';
-
+          services.mysql = {
+            enable = true;
+            package = pkgs.mysql;
+          };
           services.httpd = {
             enable = true;
             logPerVirtualHost = true;