about summary refs log tree commit diff
path: root/nixos/modules
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/config/fonts/fontconfig-ultimate.nix100
-rw-r--r--nixos/modules/config/fonts/fontconfig.nix120
-rw-r--r--nixos/modules/config/pulseaudio.nix2
-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/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/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.nix3
-rw-r--r--nixos/modules/profiles/graphical.nix6
-rw-r--r--nixos/modules/rename.nix13
-rw-r--r--nixos/modules/security/grsecurity.xml6
-rw-r--r--nixos/modules/security/pam.nix8
-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/openldap.nix8
-rw-r--r--nixos/modules/services/logging/fluentd.nix1
-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/octoprint.nix2
-rw-r--r--nixos/modules/services/misc/ssm-agent.nix1
-rw-r--r--nixos/modules/services/monitoring/das_watchdog.nix2
-rw-r--r--nixos/modules/services/monitoring/prometheus/default.nix1
-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/dhcpd.nix7
-rw-r--r--nixos/modules/services/networking/dnscrypt-proxy.nix147
-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/searx.nix4
-rw-r--r--nixos/modules/services/scheduling/fcron.nix50
-rw-r--r--nixos/modules/services/ttys/kmscon.nix2
-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/nginx/default.nix10
-rw-r--r--nixos/modules/services/web-servers/phpfpm/default.nix66
-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.nix7
-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/xserver.nix14
-rw-r--r--nixos/modules/system/activation/switch-to-configuration.pl2
-rw-r--r--nixos/modules/system/boot/luksroot.nix4
-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.nix2
-rw-r--r--nixos/modules/tasks/network-interfaces.nix163
-rw-r--r--nixos/modules/virtualisation/amazon-init.nix5
-rw-r--r--nixos/modules/virtualisation/ecs-agent.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
68 files changed, 1622 insertions, 858 deletions
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/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/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/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/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 ee43e538f6d5..c9f1fad0d0e9 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -31,6 +31,7 @@
   ./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
@@ -428,6 +429,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
@@ -570,6 +572,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/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/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/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/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/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/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/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/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/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/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/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..beddaa076122 100644
--- a/nixos/modules/services/networking/dnscrypt-proxy.nix
+++ b/nixos/modules/services/networking/dnscrypt-proxy.nix
@@ -3,8 +3,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}";
@@ -121,7 +122,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 {
@@ -155,16 +156,60 @@ in
     };
   };
 
-  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" ]
+        ++ optional apparmorEnabled "apparmor.service";
+
+      requires = [ "dnscrypt-proxy.socket "]
+        ++ optional apparmorEnabled "apparmor.service";
+
+      serviceConfig = {
+        NonBlocking = "true";
+        ExecStart = "${pkgs.dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}";
+
+        User = "dnscrypt-proxy";
+
+        PrivateTmp = true;
+        PrivateDevices = true;
+        ProtectHome = true;
+      };
+    };
+    }
+
+    (mkIf apparmorEnabled {
+    security.apparmor.profiles = singleton (pkgs.writeText "apparmor-dnscrypt-proxy" ''
+      ${pkgs.dnscrypt-proxy}/bin/dnscrypt-proxy {
         /dev/null rw,
         /dev/urandom r,
 
@@ -180,6 +225,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 +235,82 @@ 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=download.dnscrypt.org
+        get="curl -fSs --resolve $domain:443:$(hostip -r 8.8.8.8 $domain | head -1)"
+        $get -o dnscrypt-resolvers.csv.tmp \
+          https://$domain/dnscrypt-proxy/dnscrypt-resolvers.csv
+        $get -o dnscrypt-resolvers.csv.minisig.tmp \
+          https://$domain/dnscrypt-proxy/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
+        [[ -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" ])
+  ];
 }
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/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/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/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/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/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/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 37523feb4140..9c42dc8781b9 100644
--- a/nixos/modules/services/x11/desktop-managers/xfce.nix
+++ b/nixos/modules/services/x11/desktop-managers/xfce.nix
@@ -47,6 +47,12 @@ in
         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.";
+      };
     };
 
   };
@@ -80,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
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/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/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl
index ca7932a3c5cd..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";
 
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/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 179300ef1667..3571e00d04ec 100644
--- a/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -220,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";
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index 42a1a5a2332d..6467259766ea 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -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 = { };
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/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/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";
     };
 
   };