about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/man-nixos-rebuild.xml53
-rw-r--r--nixos/doc/manual/release-notes/rl-1903.xml6
-rw-r--r--nixos/lib/build-vms.nix2
-rw-r--r--nixos/lib/make-disk-image.nix2
-rw-r--r--nixos/lib/make-ext4-fs.nix61
-rw-r--r--nixos/lib/make-squashfs.nix5
-rw-r--r--nixos/lib/test-driver/Logger.pm3
-rw-r--r--nixos/lib/test-driver/Machine.pm6
-rw-r--r--nixos/lib/testing.nix4
-rw-r--r--nixos/modules/config/users-groups.nix4
-rw-r--r--nixos/modules/hardware/all-firmware.nix2
-rw-r--r--nixos/modules/installer/cd-dvd/channel.nix2
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-aarch64.nix9
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix9
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix9
-rw-r--r--nixos/modules/installer/tools/nix-fallback-paths.nix8
-rw-r--r--nixos/modules/installer/tools/nixos-rebuild.sh4
-rw-r--r--nixos/modules/installer/tools/tools.nix2
-rw-r--r--nixos/modules/misc/nixpkgs.nix4
-rw-r--r--nixos/modules/misc/version.nix1
-rw-r--r--nixos/modules/module-list.nix2
-rw-r--r--nixos/modules/profiles/hardened.nix9
-rw-r--r--nixos/modules/profiles/headless.nix1
-rw-r--r--nixos/modules/profiles/minimal.nix2
-rw-r--r--nixos/modules/programs/command-not-found/command-not-found.nix2
-rw-r--r--nixos/modules/programs/nano.nix5
-rw-r--r--nixos/modules/programs/sway.nix13
-rw-r--r--nixos/modules/programs/way-cooler.nix2
-rw-r--r--nixos/modules/programs/xss-lock.nix3
-rw-r--r--nixos/modules/services/backup/borgbackup.nix3
-rw-r--r--nixos/modules/services/databases/cassandra.nix22
-rw-r--r--nixos/modules/services/desktops/gnome3/gnome-keyring.nix2
-rw-r--r--nixos/modules/services/hardware/lirc.nix6
-rw-r--r--nixos/modules/services/hardware/tlp.nix2
-rw-r--r--nixos/modules/services/hardware/vdr.nix14
-rw-r--r--nixos/modules/services/misc/gitea.nix17
-rw-r--r--nixos/modules/services/misc/nzbget.nix23
-rw-r--r--nixos/modules/services/misc/sonarr.nix60
-rw-r--r--nixos/modules/services/monitoring/datadog-agent.nix2
-rw-r--r--nixos/modules/services/monitoring/prometheus/exporters.nix1
-rw-r--r--nixos/modules/services/monitoring/prometheus/exporters/bind.nix55
-rw-r--r--nixos/modules/services/network-filesystems/glusterfs.nix1
-rw-r--r--nixos/modules/services/networking/nsd.nix12
-rw-r--r--nixos/modules/services/networking/shairport-sync.nix2
-rw-r--r--nixos/modules/services/networking/ssh/sshd.nix5
-rw-r--r--nixos/modules/services/search/elasticsearch-curator.nix5
-rw-r--r--nixos/modules/services/system/kerberos.nix64
-rw-r--r--nixos/modules/services/system/kerberos/default.nix80
-rw-r--r--nixos/modules/services/system/kerberos/heimdal.nix68
-rw-r--r--nixos/modules/services/system/kerberos/mit.nix68
-rw-r--r--nixos/modules/services/web-apps/atlassian/confluence.nix2
-rw-r--r--nixos/modules/services/web-apps/atlassian/crowd.nix5
-rw-r--r--nixos/modules/services/web-apps/atlassian/jira.nix2
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/wordpress.nix8
-rw-r--r--nixos/modules/services/web-servers/lighttpd/collectd.nix2
-rw-r--r--nixos/modules/services/x11/desktop-managers/gnome3.nix15
-rw-r--r--nixos/modules/services/x11/desktop-managers/lxqt.nix11
-rw-r--r--nixos/modules/services/x11/desktop-managers/mate.nix10
-rw-r--r--nixos/modules/services/x11/display-managers/default.nix4
-rw-r--r--nixos/modules/services/x11/urxvtd.nix28
-rw-r--r--nixos/modules/system/boot/initrd-network.nix3
-rw-r--r--nixos/modules/system/boot/initrd-ssh.nix1
-rw-r--r--nixos/modules/system/boot/loader/generations-dir/generations-dir.nix4
-rw-r--r--nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix2
-rw-r--r--nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix4
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix2
-rw-r--r--nixos/modules/system/boot/loader/init-script/init-script.nix4
-rw-r--r--nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix4
-rw-r--r--nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix9
-rw-r--r--nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix2
-rw-r--r--nixos/modules/system/boot/luksroot.nix2
-rw-r--r--nixos/modules/system/boot/stage-1-init.sh4
-rw-r--r--nixos/modules/system/boot/stage-1.nix4
-rw-r--r--nixos/modules/system/boot/systemd.nix1
-rw-r--r--nixos/modules/system/etc/etc.nix2
-rw-r--r--nixos/modules/tasks/cpu-freq.nix74
-rw-r--r--nixos/modules/tasks/filesystems/f2fs.nix6
-rw-r--r--nixos/modules/testing/service-runner.nix2
-rw-r--r--nixos/modules/virtualisation/container-config.nix1
-rw-r--r--nixos/modules/virtualisation/containers.nix2
-rw-r--r--nixos/tests/all-tests.nix3
-rw-r--r--nixos/tests/containers-extra_veth.nix1
-rw-r--r--nixos/tests/docker-tools.nix1
-rw-r--r--nixos/tests/gitea.nix2
-rw-r--r--nixos/tests/hardened.nix9
-rw-r--r--nixos/tests/kerberos/default.nix7
-rw-r--r--nixos/tests/kerberos/heimdal.nix53
-rw-r--r--nixos/tests/kerberos/mit.nix45
-rw-r--r--nixos/tests/nexus.nix2
-rw-r--r--nixos/tests/prometheus-exporters.nix19
-rw-r--r--nixos/tests/xss-lock.nix3
91 files changed, 800 insertions, 312 deletions
diff --git a/nixos/doc/manual/man-nixos-rebuild.xml b/nixos/doc/manual/man-nixos-rebuild.xml
index 551a65f5e96b..b6a247286d4b 100644
--- a/nixos/doc/manual/man-nixos-rebuild.xml
+++ b/nixos/doc/manual/man-nixos-rebuild.xml
@@ -13,35 +13,35 @@
  </refnamediv>
  <refsynopsisdiv>
   <cmdsynopsis>
-   <command>nixos-rebuild</command><group choice='req'> 
+   <command>nixos-rebuild</command><group choice='req'>
    <arg choice='plain'>
     <option>switch</option>
    </arg>
-    
+
    <arg choice='plain'>
     <option>boot</option>
    </arg>
-    
+
    <arg choice='plain'>
     <option>test</option>
    </arg>
-    
+
    <arg choice='plain'>
     <option>build</option>
    </arg>
-    
+
    <arg choice='plain'>
     <option>dry-build</option>
    </arg>
-    
+
    <arg choice='plain'>
     <option>dry-activate</option>
    </arg>
-    
+
    <arg choice='plain'>
     <option>build-vm</option>
    </arg>
-    
+
    <arg choice='plain'>
     <option>build-vm-with-bootloader</option>
    </arg>
@@ -50,29 +50,33 @@
    <arg>
     <option>--upgrade</option>
    </arg>
-    
+
    <arg>
     <option>--install-bootloader</option>
    </arg>
-    
+
    <arg>
     <option>--no-build-nix</option>
    </arg>
-    
+
    <arg>
     <option>--fast</option>
    </arg>
-    
+
    <arg>
     <option>--rollback</option>
    </arg>
+   <arg>
+     <option>--builders</option>
+     <replaceable>builder-spec</replaceable>
+   </arg>
    <sbr />
    <arg>
-    <group choice='req'> 
+    <group choice='req'>
     <arg choice='plain'>
      <option>--profile-name</option>
     </arg>
-     
+
     <arg choice='plain'>
      <option>-p</option>
     </arg>
@@ -316,6 +320,27 @@ $ ./result/bin/run-*-vm
     </listitem>
    </varlistentry>
    <varlistentry>
+     <term>
+       <option>--builders</option>
+       <replaceable>builder-spec</replaceable>
+     </term>
+     <listitem>
+       <para>
+         Allow ad-hoc remote builders for building the new system.
+         This requires the user executing <command>nixos-rebuild</command> (usually
+         root) to be configured as a trusted user in the Nix daemon. This can be
+         achieved by using the <literal>nix.trustedUsers</literal> NixOS option.
+         Examples values for that option are described in the
+		 <literal>Remote builds chapter</literal> in the Nix manual,
+         (i.e. <command>--builders "ssh://bigbrother x86_64-linux"</command>).
+         By specifying an empty string existing builders specified in
+         <filename>/etc/nix/machines</filename> can be ignored:
+         <command>--builders ""</command> for example when they are not
+         reachable due to network connectivity.
+       </para>
+     </listitem>
+   </varlistentry>
+   <varlistentry>
     <term>
      <option>--profile-name</option>
     </term>
diff --git a/nixos/doc/manual/release-notes/rl-1903.xml b/nixos/doc/manual/release-notes/rl-1903.xml
index c823d8fcf264..89d9f48aedd3 100644
--- a/nixos/doc/manual/release-notes/rl-1903.xml
+++ b/nixos/doc/manual/release-notes/rl-1903.xml
@@ -370,6 +370,12 @@
    </listitem>
    <listitem>
     <para>
+     <literal>composableDerivation</literal> along with supporting library functions
+     has been removed.
+    </para>
+   </listitem>
+   <listitem>
+    <para>
      The deprecated <literal>truecrypt</literal> package has been removed
      and <literal>truecrypt</literal> attribute is now an alias for
      <literal>veracrypt</literal>. VeraCrypt is backward-compatible with
diff --git a/nixos/lib/build-vms.nix b/nixos/lib/build-vms.nix
index 024f4414ebeb..a5580f4712eb 100644
--- a/nixos/lib/build-vms.nix
+++ b/nixos/lib/build-vms.nix
@@ -83,6 +83,8 @@ rec {
                     (m': let config = (getAttr m' nodes).config; in
                       optionalString (config.networking.primaryIPAddress != "")
                         ("${config.networking.primaryIPAddress} " +
+                         optionalString (config.networking.domain != null)
+                           "${config.networking.hostName}.${config.networking.domain} " +
                          "${config.networking.hostName}\n"));
 
                   virtualisation.qemu.options =
diff --git a/nixos/lib/make-disk-image.nix b/nixos/lib/make-disk-image.nix
index bf32a36895c5..6fec322f9095 100644
--- a/nixos/lib/make-disk-image.nix
+++ b/nixos/lib/make-disk-image.nix
@@ -84,7 +84,7 @@ let format' = format; in let
   # FIXME: merge with channel.nix / make-channel.nix.
   channelSources = pkgs.runCommand "nixos-${config.system.nixos.version}" {} ''
     mkdir -p $out
-    cp -prd ${nixpkgs} $out/nixos
+    cp -prd ${nixpkgs.outPath} $out/nixos
     chmod -R u+w $out/nixos
     if [ ! -e $out/nixos/nixpkgs ]; then
       ln -s . $out/nixos/nixpkgs
diff --git a/nixos/lib/make-ext4-fs.nix b/nixos/lib/make-ext4-fs.nix
index 694142a5123a..47c6374c81ad 100644
--- a/nixos/lib/make-ext4-fs.nix
+++ b/nixos/lib/make-ext4-fs.nix
@@ -9,6 +9,7 @@
 , e2fsprogs
 , libfaketime
 , perl
+, lkl
 }:
 
 let
@@ -18,16 +19,13 @@ in
 pkgs.stdenv.mkDerivation {
   name = "ext4-fs.img";
 
-  nativeBuildInputs = [e2fsprogs.bin libfaketime perl];
+  nativeBuildInputs = [e2fsprogs.bin libfaketime perl lkl];
 
   buildCommand =
     ''
       # Add the closures of the top-level store objects.
       storePaths=$(cat ${sdClosureInfo}/store-paths)
 
-      # Also include a manifest of the closures in a format suitable for nix-store --load-db.
-      cp ${sdClosureInfo}/registration nix-path-registration
-
       # Make a crude approximation of the size of the target image.
       # If the script starts failing, increase the fudge factors here.
       numInodes=$(find $storePaths | wc -l)
@@ -38,55 +36,16 @@ pkgs.stdenv.mkDerivation {
       truncate -s $bytes $out
       faketime -f "1970-01-01 00:00:01" mkfs.ext4 -L ${volumeLabel} -U ${uuid} $out
 
-      # Populate the image contents by piping a bunch of commands to the `debugfs` tool from e2fsprogs.
-      # For example, to copy /nix/store/abcd...efg-coreutils-8.23/bin/sleep:
-      #   cd /nix/store/abcd...efg-coreutils-8.23/bin
-      #   write /nix/store/abcd...efg-coreutils-8.23/bin/sleep sleep
-      #   sif sleep mode 040555
-      #   sif sleep gid 30000
-      # In particular, debugfs doesn't handle absolute target paths; you have to 'cd' in the virtual
-      # filesystem first. Likewise the intermediate directories must already exist (using `find`
-      # handles that for us). And when setting the file's permissions, the inode type flags (__S_IFDIR,
-      # __S_IFREG) need to be set as well.
-      (
-        echo write nix-path-registration nix-path-registration
-        echo mkdir nix
-        echo cd /nix
-        echo mkdir store
-
-        # XXX: This explodes in exciting ways if anything in /nix/store has a space in it.
-        find $storePaths -printf '%y %f %h %m\n'| while read -r type file dir perms; do
-          # echo "TYPE=$type DIR=$dir FILE=$file PERMS=$perms" >&2
-
-          echo "cd $dir"
-          case $type in
-            d)
-              echo "mkdir $file"
-              echo sif $file mode $((040000 | 0$perms)) # magic constant is __S_IFDIR
-              ;;
-            f)
-              echo "write $dir/$file $file"
-              echo sif $file mode $((0100000 | 0$perms)) # magic constant is __S_IFREG
-              ;;
-            l)
-              echo "symlink $file $(readlink "$dir/$file")"
-              ;;
-            *)
-              echo "Unknown entry: $type $dir $file $perms" >&2
-              exit 1
-              ;;
-          esac
+      # Also include a manifest of the closures in a format suitable for nix-store --load-db.
+      cp ${sdClosureInfo}/registration nix-path-registration
+      cptofs -t ext4 -i $out nix-path-registration /
 
-          echo sif $file gid 30000 # chgrp to nixbld
-        done
-      ) | faketime -f "1970-01-01 00:00:01" debugfs -w $out -f /dev/stdin > errorlog 2>&1
+      # Create nix/store before copying paths
+      faketime -f "1970-01-01 00:00:01" mkdir -p nix/store
+      cptofs -t ext4 -i $out nix /
 
-      # The debugfs tool doesn't terminate on error nor exit with a non-zero status. Check manually.
-      if egrep -q 'Could not allocate|File not found' errorlog; then
-        cat errorlog
-        echo "--- Failed to create EXT4 image of $bytes bytes (numInodes=$numInodes, numDataBlocks=$numDataBlocks) ---"
-        return 1
-      fi
+      echo "copying store paths to image..."
+      cptofs -t ext4 -i $out $storePaths /nix/store/
 
       # I have ended up with corrupted images sometimes, I suspect that happens when the build machine's disk gets full during the build.
       if ! fsck.ext4 -n -f $out; then
diff --git a/nixos/lib/make-squashfs.nix b/nixos/lib/make-squashfs.nix
index 7ab84e47f53b..ee76c9c5bf24 100644
--- a/nixos/lib/make-squashfs.nix
+++ b/nixos/lib/make-squashfs.nix
@@ -3,6 +3,9 @@
 , # The root directory of the squashfs filesystem is filled with the
   # closures of the Nix store paths listed here.
   storeContents ? []
+, # Compression parameters.
+  # For zstd compression you can use "zstd -Xcompression-level 6".
+  comp ? "xz -Xdict-size 100%"
 }:
 
 stdenv.mkDerivation {
@@ -20,6 +23,6 @@ stdenv.mkDerivation {
 
       # Generate the squashfs image.
       mksquashfs nix-path-registration $(cat $closureInfo/store-paths) $out \
-        -keep-as-directory -all-root -b 1048576 -comp xz -Xdict-size 100%
+        -keep-as-directory -all-root -b 1048576 -comp ${comp}
     '';
 }
diff --git a/nixos/lib/test-driver/Logger.pm b/nixos/lib/test-driver/Logger.pm
index 3fe5ef67c144..080310ea34e0 100644
--- a/nixos/lib/test-driver/Logger.pm
+++ b/nixos/lib/test-driver/Logger.pm
@@ -4,6 +4,7 @@ use strict;
 use Thread::Queue;
 use XML::Writer;
 use Encode qw(decode encode);
+use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
 
 sub new {
     my ($class) = @_;
@@ -46,10 +47,12 @@ sub nest {
     print STDERR maybePrefix("$msg\n", $attrs);
     $self->{log}->startTag("nest");
     $self->{log}->dataElement("head", $msg, %{$attrs});
+    my $now = clock_gettime(CLOCK_MONOTONIC);
     $self->drainLogQueue();
     eval { &$coderef };
     my $res = $@;
     $self->drainLogQueue();
+    $self->log(sprintf("(%.2f seconds)", clock_gettime(CLOCK_MONOTONIC) - $now));
     $self->{log}->endTag("nest");
     die $@ if $@;
 }
diff --git a/nixos/lib/test-driver/Machine.pm b/nixos/lib/test-driver/Machine.pm
index a00fe25c2b8e..c95bc548e04f 100644
--- a/nixos/lib/test-driver/Machine.pm
+++ b/nixos/lib/test-driver/Machine.pm
@@ -10,6 +10,7 @@ use Cwd;
 use File::Basename;
 use File::Path qw(make_path);
 use File::Slurp;
+use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
 
 
 my $showGraphics = defined $ENV{'DISPLAY'};
@@ -249,12 +250,15 @@ sub connect {
 
         $self->start;
 
+        my $now = clock_gettime(CLOCK_MONOTONIC);
         local $SIG{ALRM} = sub { die "timed out waiting for the VM to connect\n"; };
-        alarm 300;
+        alarm 600;
         readline $self->{socket} or die "the VM quit before connecting\n";
         alarm 0;
 
         $self->log("connected to guest root shell");
+        # We're interested in tracking how close we are to `alarm`.
+        $self->log(sprintf("(connecting took %.2f seconds)", clock_gettime(CLOCK_MONOTONIC) - $now));
         $self->{connected} = 1;
 
     });
diff --git a/nixos/lib/testing.nix b/nixos/lib/testing.nix
index c0b4041d7e30..e68563ef48d2 100644
--- a/nixos/lib/testing.nix
+++ b/nixos/lib/testing.nix
@@ -34,14 +34,14 @@ in rec {
         cp ${./test-driver/test-driver.pl} $out/bin/nixos-test-driver
         chmod u+x $out/bin/nixos-test-driver
 
-        libDir=$out/lib/perl5/site_perl
+        libDir=$out/${perl.libPrefix}
         mkdir -p $libDir
         cp ${./test-driver/Machine.pm} $libDir/Machine.pm
         cp ${./test-driver/Logger.pm} $libDir/Logger.pm
 
         wrapProgram $out/bin/nixos-test-driver \
           --prefix PATH : "${lib.makeBinPath [ qemu_test vde2 netpbm coreutils ]}" \
-          --prefix PERL5LIB : "${with perlPackages; lib.makePerlPath [ TermReadLineGnu XMLWriter IOTty FileSlurp ]}:$out/lib/perl5/site_perl"
+          --prefix PERL5LIB : "${with perlPackages; makePerlPath [ TermReadLineGnu XMLWriter IOTty FileSlurp ]}:$out/${perl.libPrefix}"
       '';
   };
 
diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix
index 137ee243813d..c3f228c9bcc4 100644
--- a/nixos/modules/config/users-groups.nix
+++ b/nixos/modules/config/users-groups.nix
@@ -534,8 +534,8 @@ in {
         install -m 0755 -d /home
 
         ${pkgs.perl}/bin/perl -w \
-          -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl \
-          -I${pkgs.perlPackages.JSON}/lib/perl5/site_perl \
+          -I${pkgs.perlPackages.FileSlurp}/${pkgs.perl.libPrefix} \
+          -I${pkgs.perlPackages.JSON}/${pkgs.perl.libPrefix} \
           ${./update-users-groups.pl} ${spec}
       '';
 
diff --git a/nixos/modules/hardware/all-firmware.nix b/nixos/modules/hardware/all-firmware.nix
index e978ec6b40ad..69cc22aaa34b 100644
--- a/nixos/modules/hardware/all-firmware.nix
+++ b/nixos/modules/hardware/all-firmware.nix
@@ -38,7 +38,7 @@ in {
         firmwareLinuxNonfree
         intel2200BGFirmware
         rtl8192su-firmware
-      ] ++ optional (pkgs.stdenv.isAarch32 || pkgs.stdenv.isAarch64) raspberrypiWirelessFirmware
+      ] ++ optional (pkgs.stdenv.hostPlatform.isAarch32 || pkgs.stdenv.hostPlatform.isAarch64) raspberrypiWirelessFirmware
         ++ optionals (versionOlder config.boot.kernelPackages.kernel.version "4.13") [
         rtl8723bs-firmware
       ];
diff --git a/nixos/modules/installer/cd-dvd/channel.nix b/nixos/modules/installer/cd-dvd/channel.nix
index 01cfe8a02e10..e946c4abc576 100644
--- a/nixos/modules/installer/cd-dvd/channel.nix
+++ b/nixos/modules/installer/cd-dvd/channel.nix
@@ -16,7 +16,7 @@ let
     { }
     ''
       mkdir -p $out
-      cp -prd ${nixpkgs} $out/nixos
+      cp -prd ${nixpkgs.outPath} $out/nixos
       chmod -R u+w $out/nixos
       if [ ! -e $out/nixos/nixpkgs ]; then
         ln -s . $out/nixos/nixpkgs
diff --git a/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix b/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix
index 2db71eb20c5d..5f7194e92a36 100644
--- a/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix
@@ -5,7 +5,7 @@
 let
   extlinux-conf-builder =
     import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix {
-      inherit pkgs;
+      pkgs = pkgs.buildPackages;
     };
 in
 {
@@ -15,13 +15,6 @@ in
     ./sd-image.nix
   ];
 
-  assertions = lib.singleton {
-    assertion = pkgs.stdenv.hostPlatform.system == "aarch64-linux"
-      && pkgs.stdenv.hostPlatform.system == pkgs.stdenv.buildPlatform.system;
-    message = "sd-image-aarch64.nix can be only built natively on Aarch64 / ARM64; " +
-      "it cannot be cross compiled";
-  };
-
   boot.loader.grub.enable = false;
   boot.loader.generic-extlinux-compatible.enable = true;
 
diff --git a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
index 695c79ca1707..71448f74c361 100644
--- a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
@@ -5,7 +5,7 @@
 let
   extlinux-conf-builder =
     import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix {
-      inherit pkgs;
+      pkgs = pkgs.buildPackages;
     };
 in
 {
@@ -15,13 +15,6 @@ in
     ./sd-image.nix
   ];
 
-  assertions = lib.singleton {
-    assertion = pkgs.stdenv.hostPlatform.system == "armv7l-linux"
-      && pkgs.stdenv.hostPlatform.system == pkgs.stdenv.buildPlatform.system;
-    message = "sd-image-armv7l-multiplatform.nix can be only built natively on ARMv7; " +
-      "it cannot be cross compiled";
-  };
-
   boot.loader.grub.enable = false;
   boot.loader.generic-extlinux-compatible.enable = true;
 
diff --git a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
index e395b265d15e..96e06670694e 100644
--- a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
@@ -5,7 +5,7 @@
 let
   extlinux-conf-builder =
     import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix {
-      inherit pkgs;
+      pkgs = pkgs.buildPackages;
     };
 in
 {
@@ -15,13 +15,6 @@ in
     ./sd-image.nix
   ];
 
-  assertions = lib.singleton {
-    assertion = pkgs.stdenv.hostPlatform.system == "armv6l-linux"
-      && pkgs.stdenv.hostPlatform.system == pkgs.stdenv.buildPlatform.system;
-    message = "sd-image-raspberrypi.nix can be only built natively on ARMv6; " +
-      "it cannot be cross compiled";
-  };
-
   boot.loader.grub.enable = false;
   boot.loader.generic-extlinux-compatible.enable = true;
 
diff --git a/nixos/modules/installer/tools/nix-fallback-paths.nix b/nixos/modules/installer/tools/nix-fallback-paths.nix
index 1cfc8ff8612e..5d431df4b114 100644
--- a/nixos/modules/installer/tools/nix-fallback-paths.nix
+++ b/nixos/modules/installer/tools/nix-fallback-paths.nix
@@ -1,6 +1,6 @@
 {
-  x86_64-linux = "/nix/store/cdcia67siabmj6li7vyffgv2cry86fq8-nix-2.1.3";
-  i686-linux = "/nix/store/6q3xi6y5qnsv7d62b8n00hqfxi8rs2xs-nix-2.1.3";
-  aarch64-linux = "/nix/store/2v93d0vimlm28jg0ms6v1i6lc0fq13pn-nix-2.1.3";
-  x86_64-darwin = "/nix/store/dkjlfkrknmxbjmpfk3dg4q3nmb7m3zvk-nix-2.1.3";
+  x86_64-linux = "/nix/store/pid1yakjasch4pwl63nzbj22z9zf0q26-nix-2.2";
+  i686-linux = "/nix/store/qpkl0cxy0xh4h432lv2qsjrmhvx5x2vy-nix-2.2";
+  aarch64-linux = "/nix/store/0jg7h94x986d8cskg6gcfza9x67spdbp-nix-2.2";
+  x86_64-darwin = "/nix/store/a48whqkmxnsfhwbk6nay74iyc1cf0lr2-nix-2.2";
 }
diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh
index 2af73519bc52..361c2e49e05c 100644
--- a/nixos/modules/installer/tools/nixos-rebuild.sh
+++ b/nixos/modules/installer/tools/nixos-rebuild.sh
@@ -53,11 +53,11 @@ while [ "$#" -gt 0 ]; do
         repair=1
         extraBuildFlags+=("$i")
         ;;
-      --max-jobs|-j|--cores|-I)
+      --max-jobs|-j|--cores|-I|--builders)
         j="$1"; shift 1
         extraBuildFlags+=("$i" "$j")
         ;;
-      --show-trace|--no-build-hook|--keep-failed|-K|--keep-going|-k|--verbose|-v|-vv|-vvv|-vvvv|-vvvvv|--fallback|--repair|--no-build-output|-Q|-j*)
+      --show-trace|--keep-failed|-K|--keep-going|-k|--verbose|-v|-vv|-vvv|-vvvv|-vvvvv|--fallback|--repair|--no-build-output|-Q|-j*)
         extraBuildFlags+=("$i")
         ;;
       --option)
diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix
index af0a3a2fcc88..00c4d5018bf5 100644
--- a/nixos/modules/installer/tools/tools.nix
+++ b/nixos/modules/installer/tools/tools.nix
@@ -37,7 +37,7 @@ let
     name = "nixos-generate-config";
     src = ./nixos-generate-config.pl;
     path = [ pkgs.btrfs-progs ];
-    perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl";
+    perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/${pkgs.perl.libPrefix}";
     inherit (config.system.nixos) release;
   };
 
diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix
index 93fbf16841e5..3a717fddaba2 100644
--- a/nixos/modules/misc/nixpkgs.nix
+++ b/nixos/modules/misc/nixpkgs.nix
@@ -55,7 +55,7 @@ let
     check = builtins.isAttrs;
   };
 
-  defaultPkgs = import ../../../pkgs/top-level/default.nix {
+  defaultPkgs = import ../../.. {
     inherit (cfg) config overlays localSystem crossSystem;
   };
 
@@ -68,7 +68,7 @@ in
 
     pkgs = mkOption {
       defaultText = literalExample
-        ''import "''${nixos}/../pkgs/top-level" {
+        ''import "''${nixos}/.." {
             inherit (cfg) config overlays localSystem crossSystem;
           }
         '';
diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix
index fd77f6372720..001505320c00 100644
--- a/nixos/modules/misc/version.nix
+++ b/nixos/modules/misc/version.nix
@@ -93,6 +93,7 @@ in
         VERSION_CODENAME=${toLower cfg.codeName}
         VERSION_ID="${cfg.version}"
         PRETTY_NAME="NixOS ${cfg.version} (${cfg.codeName})"
+        LOGO="nix-snowflake"
         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 8ae3c7dca00c..a597485120c4 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -696,7 +696,7 @@
   ./services/system/dbus.nix
   ./services/system/earlyoom.nix
   ./services/system/localtime.nix
-  ./services/system/kerberos.nix
+  ./services/system/kerberos/default.nix
   ./services/system/nscd.nix
   ./services/system/saslauthd.nix
   ./services/system/uptimed.nix
diff --git a/nixos/modules/profiles/hardened.nix b/nixos/modules/profiles/hardened.nix
index a588943fe710..9ab2ee87a19e 100644
--- a/nixos/modules/profiles/hardened.nix
+++ b/nixos/modules/profiles/hardened.nix
@@ -29,11 +29,20 @@ with lib;
   security.apparmor.enable = mkDefault true;
 
   boot.kernelParams = [
+    # Slab/slub sanity checks, redzoning, and poisoning
+    "slub_debug=FZP"
+
+    # Disable slab merging to make certain heap overflow attacks harder
+    "slab_nomerge"
+
     # Overwrite free'd memory
     "page_poison=1"
 
     # Disable legacy virtual syscalls
     "vsyscall=none"
+
+    # Enable PTI even if CPU claims to be safe from meltdown
+    "pti=on"
   ];
 
   boot.blacklistedKernelModules = [
diff --git a/nixos/modules/profiles/headless.nix b/nixos/modules/profiles/headless.nix
index 131ee272859a..46a9b6a7d8d5 100644
--- a/nixos/modules/profiles/headless.nix
+++ b/nixos/modules/profiles/headless.nix
@@ -6,7 +6,6 @@
 with lib;
 
 {
-  sound.enable = false;
   boot.vesa = false;
 
   # Don't start a tty on the serial consoles.
diff --git a/nixos/modules/profiles/minimal.nix b/nixos/modules/profiles/minimal.nix
index 138eda117c74..809bedc588f2 100644
--- a/nixos/modules/profiles/minimal.nix
+++ b/nixos/modules/profiles/minimal.nix
@@ -13,5 +13,5 @@ with lib;
 
   documentation.enable = mkDefault false;
 
-  sound.enable = mkDefault false;
+  services.nixosManual.enable = mkDefault false;
 }
diff --git a/nixos/modules/programs/command-not-found/command-not-found.nix b/nixos/modules/programs/command-not-found/command-not-found.nix
index bbe7165c62fb..656c255fcb18 100644
--- a/nixos/modules/programs/command-not-found/command-not-found.nix
+++ b/nixos/modules/programs/command-not-found/command-not-found.nix
@@ -16,7 +16,7 @@ let
     isExecutable = true;
     inherit (pkgs) perl;
     inherit (cfg) dbPath;
-    perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ")
+    perlFlags = concatStrings (map (path: "-I ${path}/${pkgs.perl.libPrefix} ")
       [ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite pkgs.perlPackages.StringShellQuote ]);
   };
 
diff --git a/nixos/modules/programs/nano.nix b/nixos/modules/programs/nano.nix
index 27b6d446c75d..6a4d46338e19 100644
--- a/nixos/modules/programs/nano.nix
+++ b/nixos/modules/programs/nano.nix
@@ -2,6 +2,7 @@
 
 let
   cfg = config.programs.nano;
+  LF = "\n";
 in
 
 {
@@ -33,9 +34,9 @@ in
 
   ###### implementation
 
-  config = lib.mkIf (cfg.nanorc != "") {
+  config = lib.mkIf (cfg.nanorc != "" || cfg.syntaxHighlight) {
     environment.etc."nanorc".text = lib.concatStrings [ cfg.nanorc
-      (lib.optionalString cfg.syntaxHighlight ''include "${pkgs.nano}/share/nano/*.nanorc"'') ];
+      (lib.optionalString cfg.syntaxHighlight ''${LF}include "${pkgs.nano}/share/nano/*.nanorc"'') ];
   };
 
 }
diff --git a/nixos/modules/programs/sway.nix b/nixos/modules/programs/sway.nix
index 0eaaf6b85b99..b3847db8cd9c 100644
--- a/nixos/modules/programs/sway.nix
+++ b/nixos/modules/programs/sway.nix
@@ -7,11 +7,18 @@ let
   swayPackage = pkgs.sway;
 
   swayWrapped = pkgs.writeShellScriptBin "sway" ''
-    if [[ "$#" -ge 1 ]]; then
+    set -o errexit
+
+    if [ ! "$_SWAY_WRAPPER_ALREADY_EXECUTED" ]; then
+      export _SWAY_WRAPPER_ALREADY_EXECUTED=1
+      ${cfg.extraSessionCommands}
+    fi
+
+    if [ "$DBUS_SESSION_BUS_ADDRESS" ]; then
+      export DBUS_SESSION_BUS_ADDRESS
       exec sway-setcap "$@"
     else
-      ${cfg.extraSessionCommands}
-      exec ${pkgs.dbus.dbus-launch} --exit-with-session sway-setcap
+      exec ${pkgs.dbus}/bin/dbus-run-session sway-setcap "$@"
     fi
   '';
   swayJoined = pkgs.symlinkJoin {
diff --git a/nixos/modules/programs/way-cooler.nix b/nixos/modules/programs/way-cooler.nix
index 633e959be9f3..f27bd42bd764 100644
--- a/nixos/modules/programs/way-cooler.nix
+++ b/nixos/modules/programs/way-cooler.nix
@@ -8,7 +8,7 @@ let
 
   wcWrapped = pkgs.writeShellScriptBin "way-cooler" ''
     ${cfg.extraSessionCommands}
-    exec ${pkgs.dbus.dbus-launch} --exit-with-session ${way-cooler}/bin/way-cooler
+    exec ${pkgs.dbus}/bin/dbus-run-session ${way-cooler}/bin/way-cooler
   '';
   wcJoined = pkgs.symlinkJoin {
     name = "way-cooler-wrapped";
diff --git a/nixos/modules/programs/xss-lock.nix b/nixos/modules/programs/xss-lock.nix
index 49d522c604f5..c290df01b960 100644
--- a/nixos/modules/programs/xss-lock.nix
+++ b/nixos/modules/programs/xss-lock.nix
@@ -9,7 +9,8 @@ in
   options.programs.xss-lock = {
     enable = mkEnableOption "xss-lock";
     lockerCommand = mkOption {
-      example = "xlock";
+      default = "${pkgs.i3lock}/bin/i3lock";
+      example = literalExample ''''${pkgs.i3lock-fancy}/bin/i3lock-fancy'';
       type = types.string;
       description = "Locker to be used with xsslock";
     };
diff --git a/nixos/modules/services/backup/borgbackup.nix b/nixos/modules/services/backup/borgbackup.nix
index bf41aee8fe0e..2ad116a7872a 100644
--- a/nixos/modules/services/backup/borgbackup.nix
+++ b/nixos/modules/services/backup/borgbackup.nix
@@ -191,10 +191,9 @@ in {
         options = {
 
           paths = mkOption {
-            type = with types; either path (listOf str);
+            type = with types; coercedTo str lib.singleton (listOf str);
             description = "Path(s) to back up.";
             example = "/home/user";
-            apply = x: if isList x then x else [ x ];
           };
 
           repo = mkOption {
diff --git a/nixos/modules/services/databases/cassandra.nix b/nixos/modules/services/databases/cassandra.nix
index 86e74d5d5ab4..d741ee48c48f 100644
--- a/nixos/modules/services/databases/cassandra.nix
+++ b/nixos/modules/services/databases/cassandra.nix
@@ -34,11 +34,13 @@ let
     { name = "cassandra-etc";
       cassandraYaml = builtins.toJSON cassandraConfigWithAddresses;
       cassandraEnvPkg = "${cfg.package}/conf/cassandra-env.sh";
+      cassandraLogbackConfig = pkgs.writeText "logback.xml" cfg.logbackConfig;
       buildCommand = ''
         mkdir -p "$out"
 
         echo "$cassandraYaml" > "$out/cassandra.yaml"
         ln -s "$cassandraEnvPkg" "$out/cassandra-env.sh"
+        ln -s "$cassandraLogbackConfig" "$out/logback.xml"
       '';
     };
 in {
@@ -139,7 +141,27 @@ in {
         correspond to a single address, IP aliasing is not supported.
       '';
     };
+    logbackConfig = mkOption {
+      type = types.lines;
+      default = ''
+        <configuration scan="false">
+          <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+            <encoder>
+              <pattern>%-5level %date{HH:mm:ss,SSS} %msg%n</pattern>
+            </encoder>
+          </appender>
 
+          <root level="INFO">
+            <appender-ref ref="STDOUT" />
+          </root>
+
+          <logger name="com.thinkaurelius.thrift" level="ERROR"/>
+        </configuration>
+      '';
+      description = ''
+        XML logback configuration for cassandra
+      '';
+    };
     extraConfig = mkOption {
       type = types.attrs;
       default = {};
diff --git a/nixos/modules/services/desktops/gnome3/gnome-keyring.nix b/nixos/modules/services/desktops/gnome3/gnome-keyring.nix
index aa1165ab3bba..5ea4350be5b4 100644
--- a/nixos/modules/services/desktops/gnome3/gnome-keyring.nix
+++ b/nixos/modules/services/desktops/gnome3/gnome-keyring.nix
@@ -33,7 +33,7 @@ with lib;
 
     environment.systemPackages = [ pkgs.gnome3.gnome-keyring ];
 
-    services.dbus.packages = [ pkgs.gnome3.gnome-keyring pkgs.gnome3.gcr ];
+    services.dbus.packages = [ pkgs.gnome3.gnome-keyring pkgs.gcr ];
 
   };
 
diff --git a/nixos/modules/services/hardware/lirc.nix b/nixos/modules/services/hardware/lirc.nix
index 0072406a438c..826e512c75d1 100644
--- a/nixos/modules/services/hardware/lirc.nix
+++ b/nixos/modules/services/hardware/lirc.nix
@@ -32,7 +32,6 @@ in {
         default = [];
         description = "Extra arguments to lircd.";
       };
-
     };
   };
 
@@ -43,14 +42,15 @@ in {
     # Note: LIRC executables raises a warning, if lirc_options.conf do not exists
     environment.etc."lirc/lirc_options.conf".text = cfg.options;
 
+    passthru.lirc.socket = "/run/lirc/lircd";
+
     environment.systemPackages = [ pkgs.lirc ];
 
     systemd.sockets.lircd = {
       description = "LIRC daemon socket";
       wantedBy = [ "sockets.target" ];
       socketConfig = {
-        # default search path
-        ListenStream = "/run/lirc/lircd";
+        ListenStream = config.passthru.lirc.socket;
         SocketUser = "lirc";
         SocketMode = "0660";
       };
diff --git a/nixos/modules/services/hardware/tlp.nix b/nixos/modules/services/hardware/tlp.nix
index 68425822a884..b894025c0fd5 100644
--- a/nixos/modules/services/hardware/tlp.nix
+++ b/nixos/modules/services/hardware/tlp.nix
@@ -56,6 +56,8 @@ in
 
     powerManagement.scsiLinkPolicy = null;
     powerManagement.cpuFreqGovernor = null;
+    powerManagement.cpufreq.max = null;
+    powerManagement.cpufreq.min = null;
 
     systemd.sockets."systemd-rfkill".enable = false;
 
diff --git a/nixos/modules/services/hardware/vdr.nix b/nixos/modules/services/hardware/vdr.nix
index 75136a2f7964..4822506a899b 100644
--- a/nixos/modules/services/hardware/vdr.nix
+++ b/nixos/modules/services/hardware/vdr.nix
@@ -33,12 +33,14 @@ in {
         default = [];
         description = "Additional command line arguments to pass to VDR.";
       };
+
+      enableLirc = mkEnableOption "enable LIRC";
     };
   };
 
   ###### implementation
 
-  config = mkIf cfg.enable {
+  config = mkIf cfg.enable (mkMerge [{
     systemd.tmpfiles.rules = [
       "d ${cfg.videoDir} 0755 vdr vdr -"
       "Z ${cfg.videoDir} - vdr vdr -"
@@ -67,5 +69,13 @@ in {
     };
 
     users.groups.vdr = {};
-  };
+  }
+
+  (mkIf cfg.enableLirc {
+    services.lirc.enable = true;
+    users.users.vdr.extraGroups = [ "lirc" ];
+    services.vdr.extraArguments = [
+      "--lirc=${config.passthru.lirc.socket}"
+    ];
+  })]);
 }
diff --git a/nixos/modules/services/misc/gitea.nix b/nixos/modules/services/misc/gitea.nix
index 7a10bd872994..be4d38719785 100644
--- a/nixos/modules/services/misc/gitea.nix
+++ b/nixos/modules/services/misc/gitea.nix
@@ -46,6 +46,9 @@ let
     ROOT_PATH = ${cfg.log.rootPath}
     LEVEL = ${cfg.log.level}
 
+    [service]
+    DISABLE_REGISTRATION = ${boolToString cfg.disableRegistration}
+
     ${cfg.extraConfig}
   '';
 in
@@ -248,6 +251,18 @@ in
         description = "Upper level of template and static files path.";
       };
 
+      disableRegistration = mkEnableOption "the registration lock" // {
+        description = ''
+          By default any user can create an account on this <literal>gitea</literal> instance.
+          This can be disabled by using this option.
+
+          <emphasis>Note:</emphasis> please keep in mind that this should be added after the initial
+          deploy unless <link linkend="opt-services.gitea.useWizard">services.gitea.useWizard</link>
+          is <literal>true</literal> as the first registered user will be the administrator if
+          no install wizard is used.
+        '';
+      };
+
       extraConfig = mkOption {
         type = types.str;
         default = "";
@@ -263,7 +278,7 @@ in
       description = "gitea";
       after = [ "network.target" ] ++ lib.optional usePostgresql "postgresql.service" ++ lib.optional useMysql "mysql.service";
       wantedBy = [ "multi-user.target" ];
-      path = [ gitea.bin ];
+      path = [ gitea.bin pkgs.gitAndTools.git ];
 
       preStart = let
         runConfig = "${cfg.stateDir}/custom/conf/app.ini";
diff --git a/nixos/modules/services/misc/nzbget.nix b/nixos/modules/services/misc/nzbget.nix
index a472b6c7157c..e24cecf20807 100644
--- a/nixos/modules/services/misc/nzbget.nix
+++ b/nixos/modules/services/misc/nzbget.nix
@@ -16,6 +16,20 @@ in {
         description = "The NZBGet package to use";
       };
 
+      dataDir = mkOption {
+        type = types.str;
+        default = "/var/lib/nzbget";
+        description = "The directory where NZBGet stores its configuration files.";
+      };
+
+      openFirewall = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Open ports in the firewall for the NZBGet web interface
+        '';
+      };
+
       user = mkOption {
         type = types.str;
         default = "nzbget";
@@ -40,7 +54,8 @@ in {
         p7zip
       ];
       preStart = ''
-        datadir=/var/lib/nzbget
+        datadir=${cfg.dataDir}
+        configfile=${cfg.dataDir}/nzbget.conf
         cfgtemplate=${cfg.package}/share/nzbget/nzbget.conf
         test -d $datadir || {
           echo "Creating nzbget data directory in $datadir"
@@ -60,7 +75,7 @@ in {
       '';
 
       script = ''
-        configfile=/var/lib/nzbget/nzbget.conf
+        configfile=${cfg.dataDir}/nzbget.conf
         args="--daemon --configfile $configfile"
         # The script in preStart (above) copies nzbget's config template to datadir on first run, containing paths that point to the nzbget derivation installed at the time. 
         # These paths break when nzbget is upgraded & the original derivation is garbage collected. If such broken paths are found in the config file, override them to point to 
@@ -86,6 +101,10 @@ in {
       };
     };
 
+    networking.firewall = mkIf cfg.openFirewall {
+      allowedTCPPorts = [ 8989 ];
+    };
+
     users.users = mkIf (cfg.user == "nzbget") {
       nzbget = {
         group = cfg.group;
diff --git a/nixos/modules/services/misc/sonarr.nix b/nixos/modules/services/misc/sonarr.nix
index 97b67a0b5033..a99445a268d7 100644
--- a/nixos/modules/services/misc/sonarr.nix
+++ b/nixos/modules/services/misc/sonarr.nix
@@ -9,6 +9,32 @@ in
   options = {
     services.sonarr = {
       enable = mkEnableOption "Sonarr";
+
+      dataDir = mkOption {
+        type = types.str;
+        default = "/var/lib/sonarr/.config/NzbDrone";
+        description = "The directory where Sonarr stores its data files.";
+      };
+
+      openFirewall = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Open ports in the firewall for the Sonarr web interface
+        '';
+      };
+
+      user = mkOption {
+        type = types.str;
+        default = "sonarr";
+        description = "User account under which Sonaar runs.";
+      };
+
+      group = mkOption {
+        type = types.str;
+        default = "sonarr";
+        description = "Group under which Sonaar runs.";
+      };
     };
   };
 
@@ -18,30 +44,38 @@ in
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
       preStart = ''
-        test -d /var/lib/sonarr/ || {
-          echo "Creating sonarr data directory in /var/lib/sonarr/"
-          mkdir -p /var/lib/sonarr/
+        test -d ${cfg.dataDir} || {
+          echo "Creating sonarr data directory in ${cfg.dataDir}"
+          mkdir -p ${cfg.dataDir}
         }
-        chown -R sonarr:sonarr /var/lib/sonarr/
-        chmod 0700 /var/lib/sonarr/
+        chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}
+        chmod 0700 ${cfg.dataDir}
       '';
 
       serviceConfig = {
         Type = "simple";
-        User = "sonarr";
-        Group = "sonarr";
+        User = cfg.user;
+        Group = cfg.group;
         PermissionsStartOnly = "true";
-        ExecStart = "${pkgs.sonarr}/bin/NzbDrone --no-browser";
+        ExecStart = "${pkgs.sonarr}/bin/NzbDrone -nobrowser -data='${cfg.dataDir}'";
         Restart = "on-failure";
       };
     };
 
-    users.users.sonarr = {
-      uid = config.ids.uids.sonarr;
-      home = "/var/lib/sonarr";
-      group = "sonarr";
+    networking.firewall = mkIf cfg.openFirewall {
+      allowedTCPPorts = [ 8989 ];
+    };
+
+    users.users = mkIf (cfg.user == "sonarr") {
+      sonarr = {
+        group = cfg.group;
+        home = cfg.dataDir;
+        uid = config.ids.uids.sonarr;
+      };
     };
-    users.groups.sonarr.gid = config.ids.gids.sonarr;
 
+    users.groups = mkIf (cfg.group == "sonarr") {
+      sonarr.gid = config.ids.gids.sonarr;
+    };
   };
 }
diff --git a/nixos/modules/services/monitoring/datadog-agent.nix b/nixos/modules/services/monitoring/datadog-agent.nix
index 5434fe99347d..a4d29d45bacf 100644
--- a/nixos/modules/services/monitoring/datadog-agent.nix
+++ b/nixos/modules/services/monitoring/datadog-agent.nix
@@ -186,7 +186,7 @@ in {
       type = types.attrs;
       default = {
         init_config = {};
-        instances = [ { use-mount = "no"; } ];
+        instances = [ { use_mount = "false"; } ];
       };
     };
 
diff --git a/nixos/modules/services/monitoring/prometheus/exporters.nix b/nixos/modules/services/monitoring/prometheus/exporters.nix
index 5308c9c4ee08..0a084561002f 100644
--- a/nixos/modules/services/monitoring/prometheus/exporters.nix
+++ b/nixos/modules/services/monitoring/prometheus/exporters.nix
@@ -33,6 +33,7 @@ let
     tor       = import ./exporters/tor.nix       { inherit config lib pkgs; };
     unifi     = import ./exporters/unifi.nix     { inherit config lib pkgs; };
     varnish   = import ./exporters/varnish.nix   { inherit config lib pkgs; };
+    bind      = import ./exporters/bind.nix      { inherit config lib pkgs; };
   };
 
   mkExporterOpts = ({ name, port }: {
diff --git a/nixos/modules/services/monitoring/prometheus/exporters/bind.nix b/nixos/modules/services/monitoring/prometheus/exporters/bind.nix
new file mode 100644
index 000000000000..a9746c4d65d5
--- /dev/null
+++ b/nixos/modules/services/monitoring/prometheus/exporters/bind.nix
@@ -0,0 +1,55 @@
+{ config, lib, pkgs }:
+
+with lib;
+
+let
+  cfg = config.services.prometheus.exporters.bind;
+in
+{
+  port = 9119;
+  extraOpts = {
+    bindURI = mkOption {
+      type = types.str;
+      default = "http://localhost:8053/";
+      description = ''
+        HTTP XML API address of an Bind server.
+      '';
+    };
+    bindTimeout = mkOption {
+      type = types.str;
+      default = "10s";
+      description = ''
+        Timeout for trying to get stats from Bind.
+      '';
+    };
+    bindVersion = mkOption {
+      type = types.enum [ "xml.v2" "xml.v3" "auto" ];
+      default = "auto";
+      description = ''
+        BIND statistics version. Can be detected automatically.
+      '';
+    };
+    bindGroups = mkOption {
+      type = types.listOf (types.enum [ "server" "view" "tasks" ]);
+      default = [ "server" "view" ];
+      description = ''
+        List of statistics to collect. Available: [server, view, tasks]
+      '';
+    };
+  };
+  serviceOpts = {
+    serviceConfig = {
+      DynamicUser = true;
+      ExecStart = ''
+        ${pkgs.prometheus-bind-exporter}/bin/bind_exporter \
+          -web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
+          -bind.pid-file /var/run/named/named.pid \
+          -bind.timeout ${toString cfg.bindTimeout} \
+          -bind.stats-url ${cfg.bindURI} \
+          -bind.stats-version ${cfg.bindVersion} \
+          -bind.stats-groups ${concatStringsSep "," cfg.bindGroups} \
+          ${concatStringsSep " \\\n  " cfg.extraFlags}
+      '';
+    };
+  };
+}
diff --git a/nixos/modules/services/network-filesystems/glusterfs.nix b/nixos/modules/services/network-filesystems/glusterfs.nix
index eb7f060c7da0..00875c6c4a18 100644
--- a/nixos/modules/services/network-filesystems/glusterfs.nix
+++ b/nixos/modules/services/network-filesystems/glusterfs.nix
@@ -201,7 +201,6 @@ in
 
       serviceConfig = {
         Type="simple";
-        Environment="PYTHONPATH=${glusterfs}/usr/lib/python2.7/site-packages";
         PIDFile="/run/glustereventsd.pid";
         ExecStart="${glusterfs}/sbin/glustereventsd --pid-file /run/glustereventsd.pid";
         ExecReload="/bin/kill -SIGUSR2 $MAINPID";
diff --git a/nixos/modules/services/networking/nsd.nix b/nixos/modules/services/networking/nsd.nix
index cde47bf23eae..8b918dab86dd 100644
--- a/nixos/modules/services/networking/nsd.nix
+++ b/nixos/modules/services/networking/nsd.nix
@@ -435,7 +435,9 @@ let
 
   dnssecZones = (filterAttrs (n: v: if v ? dnssec then v.dnssec else false) zoneConfigs);
 
-  dnssec = length (attrNames dnssecZones) != 0; 
+  dnssec = dnssecZones != {};
+
+  dnssecTools = pkgs.bind.override { enablePython = true; };
 
   signZones = optionalString dnssec ''
     mkdir -p ${stateDir}/dnssec
@@ -445,8 +447,8 @@ let
     ${concatStrings (mapAttrsToList signZone dnssecZones)}
   '';
   signZone = name: zone: ''
-    ${pkgs.bind}/bin/dnssec-keymgr -g ${pkgs.bind}/bin/dnssec-keygen -s ${pkgs.bind}/bin/dnssec-settime -K ${stateDir}/dnssec -c ${policyFile name zone.dnssecPolicy} ${name}
-    ${pkgs.bind}/bin/dnssec-signzone -S -K ${stateDir}/dnssec -o ${name} -O full -N date ${stateDir}/zones/${name}
+    ${dnssecTools}/bin/dnssec-keymgr -g ${dnssecTools}/bin/dnssec-keygen -s ${dnssecTools}/bin/dnssec-settime -K ${stateDir}/dnssec -c ${policyFile name zone.dnssecPolicy} ${name}
+    ${dnssecTools}/bin/dnssec-signzone -S -K ${stateDir}/dnssec -o ${name} -O full -N date ${stateDir}/zones/${name}
     ${nsdPkg}/sbin/nsd-checkzone ${name} ${stateDir}/zones/${name}.signed && mv -v ${stateDir}/zones/${name}.signed ${stateDir}/zones/${name}
   '';
   policyFile = name: policy: pkgs.writeText "${name}.policy" ''
@@ -953,10 +955,6 @@ in
       '';
     };
 
-    nixpkgs.config = mkIf dnssec {
-      bind.enablePython = true;
-    };
-
     systemd.timers."nsd-dnssec" = mkIf dnssec {
       description = "Automatic DNSSEC key rollover";
 
diff --git a/nixos/modules/services/networking/shairport-sync.nix b/nixos/modules/services/networking/shairport-sync.nix
index 90c0689dc7bf..68e005ab81da 100644
--- a/nixos/modules/services/networking/shairport-sync.nix
+++ b/nixos/modules/services/networking/shairport-sync.nix
@@ -27,7 +27,7 @@ in
       };
 
       arguments = mkOption {
-        default = "-v pulse";
+        default = "-v -o pa";
         description = ''
           Arguments to pass to the daemon. Defaults to a local pulseaudio
           server.
diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix
index 5fab79f1b3d7..90d08ca31316 100644
--- a/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixos/modules/services/networking/ssh/sshd.nix
@@ -352,6 +352,10 @@ in
             path = [ cfgc.package pkgs.gawk ];
             environment.LD_LIBRARY_PATH = nssModulesPath;
 
+            restartTriggers = optionals (!cfg.startWhenNeeded) [
+              config.environment.etc."ssh/sshd_config".source
+            ];
+
             preStart =
               ''
                 # Make sure we don't write to stdout, since in case of
@@ -387,6 +391,7 @@ in
                 Restart = "always";
                 Type = "simple";
               });
+
           };
       in
 
diff --git a/nixos/modules/services/search/elasticsearch-curator.nix b/nixos/modules/services/search/elasticsearch-curator.nix
index 43785c392fee..8cb1275284a3 100644
--- a/nixos/modules/services/search/elasticsearch-curator.nix
+++ b/nixos/modules/services/search/elasticsearch-curator.nix
@@ -82,11 +82,12 @@ in {
   };
 
   config = mkIf cfg.enable {
-
     systemd.services.elasticsearch-curator = {
       startAt = cfg.interval;
       serviceConfig = {
-        ExecStart = ''${pkgs.python36Packages.elasticsearch-curator}/bin/curator --config ${curatorConfig} ${curatorAction}'';
+        ExecStart =
+          "${pkgs.python3Packages.elasticsearch-curator}/bin/curator" +
+          " --config ${curatorConfig} ${curatorAction}";
       };
     };
   };
diff --git a/nixos/modules/services/system/kerberos.nix b/nixos/modules/services/system/kerberos.nix
deleted file mode 100644
index e2c45ed64ac0..000000000000
--- a/nixos/modules/services/system/kerberos.nix
+++ /dev/null
@@ -1,64 +0,0 @@
-{pkgs, config, lib, ...}:
-
-let
-
-  inherit (lib) mkOption mkIf;
-
-  inherit (pkgs) heimdalFull;
-
-  stateDir = "/var/heimdal";
-in
-
-{
-
-  ###### interface
-
-  options = {
-
-    services.kerberos_server = {
-
-      enable = mkOption {
-        default = false;
-        description = ''
-          Enable the kerberos authentification server.
-        '';
-      };
-
-    };
-
-  };
-
-
-  ###### implementation
-
-  config = mkIf config.services.kerberos_server.enable {
-
-    environment.systemPackages = [ heimdalFull ];
-
-    services.xinetd.enable = true;
-    services.xinetd.services = lib.singleton
-      { name = "kerberos-adm";
-        flags = "REUSE NAMEINARGS";
-        protocol = "tcp";
-        user = "root";
-        server = "${pkgs.tcp_wrappers}/bin/tcpd";
-        serverArgs = "${pkgs.heimdalFull}/libexec/heimdal/kadmind";
-      };
-
-    systemd.services.kdc = {
-      description = "Key Distribution Center daemon";
-      wantedBy = [ "multi-user.target" ];
-      preStart = ''
-        mkdir -m 0755 -p ${stateDir}
-      '';
-      script = "${heimdalFull}/libexec/heimdal/kdc";
-    };
-
-    systemd.services.kpasswdd = {
-      description = "Kerberos Password Changing daemon";
-      wantedBy = [ "multi-user.target" ];
-      script = "${heimdalFull}/libexec/heimdal/kpasswdd";
-    };
-  };
-
-}
diff --git a/nixos/modules/services/system/kerberos/default.nix b/nixos/modules/services/system/kerberos/default.nix
new file mode 100644
index 000000000000..26ac85de402f
--- /dev/null
+++ b/nixos/modules/services/system/kerberos/default.nix
@@ -0,0 +1,80 @@
+{pkgs, config, lib, ...}:
+
+let
+  inherit (lib) mkOption mkIf types length attrNames;
+  cfg = config.services.kerberos_server;
+  kerberos = config.krb5.kerberos;
+
+  aclEntry = {
+    options = {
+      principal = mkOption {
+        type = types.str;
+        description = "Which principal the rule applies to";
+      };
+      access = mkOption {
+        type = types.either
+          (types.listOf (types.enum ["add" "cpw" "delete" "get" "list" "modify"]))
+          (types.enum ["all"]);
+        default = "all";
+        description = "The changes the principal is allowed to make.";
+      };
+      target = mkOption {
+        type = types.str;
+        default = "*";
+        description = "The principals that 'access' applies to.";
+      };
+    };
+  };
+
+  realm = {
+    options = {
+      acl = mkOption {
+        type = types.listOf (types.submodule aclEntry);
+        default = [
+          { principal = "*/admin"; access = "all"; }
+          { principal = "admin"; access = "all"; }
+        ];
+        description = ''
+          The privileges granted to a user.
+        '';
+      };
+    };
+  };
+in
+
+{
+  imports = [
+    ./mit.nix
+    ./heimdal.nix
+  ];
+
+  ###### interface
+  options = {
+    services.kerberos_server = {
+      enable = mkOption {
+        default = false;
+        description = ''
+          Enable the kerberos authentification server.
+        '';
+      };
+
+      realms = mkOption {
+        type = types.attrsOf (types.submodule realm);
+        description = ''
+          The realm(s) to serve keys for.
+        '';
+      };
+    };
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ kerberos ];
+    assertions = [{
+      assertion = length (attrNames cfg.realms) <= 1;
+      message = "Only one realm per server is currently supported.";
+    }];
+  };
+}
diff --git a/nixos/modules/services/system/kerberos/heimdal.nix b/nixos/modules/services/system/kerberos/heimdal.nix
new file mode 100644
index 000000000000..d0f470f836ed
--- /dev/null
+++ b/nixos/modules/services/system/kerberos/heimdal.nix
@@ -0,0 +1,68 @@
+{ pkgs, config, lib, ... } :
+
+let
+  inherit (lib) mkIf concatStringsSep concatMapStrings toList mapAttrs
+    mapAttrsToList attrValues;
+  cfg = config.services.kerberos_server;
+  kerberos = config.krb5.kerberos;
+  stateDir = "/var/heimdal";
+  aclFiles = mapAttrs
+    (name: {acl, ...}: pkgs.writeText "${name}.acl" (concatMapStrings ((
+      {principal, access, target, ...} :
+      "${principal}\t${concatStringsSep "," (toList access)}\t${target}\n"
+    )) acl)) cfg.realms;
+
+  kdcConfigs = mapAttrsToList (name: value: ''
+    database = {
+      dbname = ${stateDir}/heimdal
+      acl_file = ${value}
+    }
+  '') aclFiles;
+  kdcConfFile = pkgs.writeText "kdc.conf" ''
+    [kdc]
+    ${concatStringsSep "\n" kdcConfigs}
+  '';
+in
+
+{
+  # No documentation about correct triggers, so guessing at them.
+
+  config = mkIf (cfg.enable && kerberos == pkgs.heimdalFull) {
+    systemd.services.kadmind = {
+      description = "Kerberos Administration Daemon";
+      wantedBy = [ "multi-user.target" ];
+      preStart = ''
+        mkdir -m 0755 -p ${stateDir}
+      '';
+      serviceConfig.ExecStart =
+        "${kerberos}/libexec/heimdal/kadmind --config-file=/etc/heimdal-kdc/kdc.conf";
+      restartTriggers = [ kdcConfFile ];
+    };
+
+    systemd.services.kdc = {
+      description = "Key Distribution Center daemon";
+      wantedBy = [ "multi-user.target" ];
+      preStart = ''
+        mkdir -m 0755 -p ${stateDir}
+      '';
+      serviceConfig.ExecStart =
+        "${kerberos}/libexec/heimdal/kdc --config-file=/etc/heimdal-kdc/kdc.conf";
+      restartTriggers = [ kdcConfFile ];
+    };
+
+    systemd.services.kpasswdd = {
+      description = "Kerberos Password Changing daemon";
+      wantedBy = [ "multi-user.target" ];
+      preStart = ''
+        mkdir -m 0755 -p ${stateDir}
+      '';
+      serviceConfig.ExecStart = "${kerberos}/libexec/heimdal/kpasswdd";
+      restartTriggers = [ kdcConfFile ];
+    };
+
+    environment.etc = {
+      # Can be set via the --config-file option to KDC
+      "heimdal-kdc/kdc.conf".source = kdcConfFile;
+    };
+  };
+}
diff --git a/nixos/modules/services/system/kerberos/mit.nix b/nixos/modules/services/system/kerberos/mit.nix
new file mode 100644
index 000000000000..a53d9dd0c6b5
--- /dev/null
+++ b/nixos/modules/services/system/kerberos/mit.nix
@@ -0,0 +1,68 @@
+{ pkgs, config, lib, ... } :
+
+let
+  inherit (lib) mkIf concatStrings concatStringsSep concatMapStrings toList
+    mapAttrs mapAttrsToList attrValues;
+  cfg = config.services.kerberos_server;
+  kerberos = config.krb5.kerberos;
+  stateDir = "/var/lib/krb5kdc";
+  PIDFile = "/run/kdc.pid";
+  aclMap = {
+    add = "a"; cpw = "c"; delete = "d"; get = "i"; list = "l"; modify = "m";
+    all = "*";
+  };
+  aclFiles = mapAttrs
+    (name: {acl, ...}: (pkgs.writeText "${name}.acl" (concatMapStrings (
+      {principal, access, target, ...} :
+      let access_code = map (a: aclMap.${a}) (toList access); in
+      "${principal} ${concatStrings access_code} ${target}\n"
+    ) acl))) cfg.realms;
+  kdcConfigs = mapAttrsToList (name: value: ''
+    ${name} = {
+      acl_file = ${value}
+    }
+  '') aclFiles;
+  kdcConfFile = pkgs.writeText "kdc.conf" ''
+    [realms]
+    ${concatStringsSep "\n" kdcConfigs}
+  '';
+  env = {
+    # What Debian uses, could possibly link directly to Nix store?
+    KRB5_KDC_PROFILE = "/etc/krb5kdc/kdc.conf";
+  };
+in
+
+{
+  config = mkIf (cfg.enable && kerberos == pkgs.krb5Full) {
+    systemd.services.kadmind = {
+      description = "Kerberos Administration Daemon";
+      wantedBy = [ "multi-user.target" ];
+      preStart = ''
+        mkdir -m 0755 -p ${stateDir}
+      '';
+      serviceConfig.ExecStart = "${kerberos}/bin/kadmind -nofork";
+      restartTriggers = [ kdcConfFile ];
+      environment = env;
+    };
+
+    systemd.services.kdc = {
+      description = "Key Distribution Center daemon";
+      wantedBy = [ "multi-user.target" ];
+      preStart = ''
+        mkdir -m 0755 -p ${stateDir}
+      '';
+      serviceConfig = {
+        Type = "forking";
+        PIDFile = PIDFile;
+        ExecStart = "${kerberos}/bin/krb5kdc -P ${PIDFile}";
+      };
+      restartTriggers = [ kdcConfFile ];
+      environment = env;
+    };
+
+    environment.etc = {
+      "krb5kdc/kdc.conf".source = kdcConfFile;
+    };
+    environment.variables = env;
+  };
+}
diff --git a/nixos/modules/services/web-apps/atlassian/confluence.nix b/nixos/modules/services/web-apps/atlassian/confluence.nix
index f896d92fd6fc..b71887fcc6ee 100644
--- a/nixos/modules/services/web-apps/atlassian/confluence.nix
+++ b/nixos/modules/services/web-apps/atlassian/confluence.nix
@@ -166,7 +166,7 @@ in
         ln -sf ${cfg.home}/{logs,work,temp,server.xml} /run/confluence
         ln -sf ${cfg.home} /run/confluence/home
 
-        chown -R ${cfg.user} ${cfg.home}
+        chown ${cfg.user} ${cfg.home}
 
         sed -e 's,port="8090",port="${toString cfg.listenPort}" address="${cfg.listenAddress}",' \
         '' + (lib.optionalString cfg.proxy.enable ''
diff --git a/nixos/modules/services/web-apps/atlassian/crowd.nix b/nixos/modules/services/web-apps/atlassian/crowd.nix
index b6cb9f3b7c41..9f48d1e16a44 100644
--- a/nixos/modules/services/web-apps/atlassian/crowd.nix
+++ b/nixos/modules/services/web-apps/atlassian/crowd.nix
@@ -130,9 +130,10 @@ in
         mkdir -p ${cfg.home}/{logs,database,work}
 
         mkdir -p /run/atlassian-crowd
-        ln -sf ${cfg.home}/{database,work,server.xml} /run/atlassian-crowd
+        ln -sf ${cfg.home}/{database,logs,work,server.xml} /run/atlassian-crowd
 
-        chown -R ${cfg.user}:${cfg.group} ${cfg.home}
+        chown ${cfg.user}:${cfg.group} ${cfg.home}
+        chown ${cfg.user}:${cfg.group} ${cfg.home}/{logs,database,work}
 
         sed -e 's,port="8095",port="${toString cfg.listenPort}" address="${cfg.listenAddress}",' \
         '' + (lib.optionalString cfg.proxy.enable ''
diff --git a/nixos/modules/services/web-apps/atlassian/jira.nix b/nixos/modules/services/web-apps/atlassian/jira.nix
index f5ec0a5f31b8..dba970c612bc 100644
--- a/nixos/modules/services/web-apps/atlassian/jira.nix
+++ b/nixos/modules/services/web-apps/atlassian/jira.nix
@@ -171,7 +171,7 @@ in
         ln -sf ${cfg.home}/{logs,work,temp,server.xml} /run/atlassian-jira
         ln -sf ${cfg.home} /run/atlassian-jira/home
 
-        chown -R ${cfg.user} ${cfg.home}
+        chown ${cfg.user} ${cfg.home}
 
         sed -e 's,port="8080",port="${toString cfg.listenPort}" address="${cfg.listenAddress}",' \
         '' + (lib.optionalString cfg.proxy.enable ''
diff --git a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
index c810b914e258..c68bfd25f6a8 100644
--- a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
@@ -85,10 +85,10 @@ let
       # remove bundled themes(s) coming with wordpress
       rm -Rf $out/wp-content/themes/*
 
-      # symlink additional theme(s)
-      ${concatMapStrings (theme: "ln -s ${theme} $out/wp-content/themes/${theme.name}\n") config.themes}
-      # symlink additional plugin(s)
-      ${concatMapStrings (plugin: "ln -s ${plugin} $out/wp-content/plugins/${plugin.name}\n") (config.plugins) }
+      # copy additional theme(s)
+      ${concatMapStrings (theme: "cp -r ${theme} $out/wp-content/themes/${theme.name}\n") config.themes}
+      # copy additional plugin(s)
+      ${concatMapStrings (plugin: "cp -r ${plugin} $out/wp-content/plugins/${plugin.name}\n") (config.plugins) }
 
       # symlink additional translation(s)
       mkdir -p $out/wp-content/languages
diff --git a/nixos/modules/services/web-servers/lighttpd/collectd.nix b/nixos/modules/services/web-servers/lighttpd/collectd.nix
index 35b5edced68b..e70c980d5243 100644
--- a/nixos/modules/services/web-servers/lighttpd/collectd.nix
+++ b/nixos/modules/services/web-servers/lighttpd/collectd.nix
@@ -48,7 +48,7 @@ in
           "/collectd" => "${cfg.collectionCgi}"
         )
         setenv.add-environment = (
-          "PERL5LIB" => "${with pkgs; lib.makePerlPath [ perlPackages.CGI perlPackages.HTMLParser perlPackages.URI rrdtool ]}",
+          "PERL5LIB" => "${with pkgs.perlPackages; makePerlPath [ CGI HTMLParser URI pkgs.rrdtool ]}",
           "COLLECTION_CONF" => "${collectionConf}"
         )
       }
diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix
index ba6d333b534e..dfff6c720d79 100644
--- a/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -5,14 +5,6 @@ with lib;
 let
   cfg = config.services.xserver.desktopManager.gnome3;
 
-  # Remove packages of ys from xs, based on their names
-  removePackagesByName = xs: ys:
-    let
-      pkgName = drv: (builtins.parseDrvName drv.name).name;
-      ysNames = map pkgName ys;
-    in
-      filter (x: !(builtins.elem (pkgName x) ysNames)) xs;
-
   # Prioritize nautilus by default when opening directories
   mimeAppsList = pkgs.writeTextFile {
     name = "gnome-mimeapps";
@@ -167,7 +159,7 @@ in {
                                                 "${pkgs.gnome3.glib-networking.out}/lib/gio/modules"
                                                 "${pkgs.gnome3.gvfs}/lib/gio/modules" ];
     environment.systemPackages = pkgs.gnome3.corePackages ++ cfg.sessionPath
-      ++ (removePackagesByName pkgs.gnome3.optionalPackages config.environment.gnome3.excludePackages) ++ [
+      ++ (pkgs.gnome3.removePackagesByName pkgs.gnome3.optionalPackages config.environment.gnome3.excludePackages) ++ [
       pkgs.xdg-user-dirs # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
     ];
 
@@ -179,7 +171,10 @@ in {
                               networkmanager-iodine networkmanager-l2tp; };
 
     # Needed for themes and backgrounds
-    environment.pathsToLink = [ "/share" ];
+    environment.pathsToLink = [
+      "/share"
+      "/share/nautilus-python/extensions"
+    ];
 
   };
 
diff --git a/nixos/modules/services/x11/desktop-managers/lxqt.nix b/nixos/modules/services/x11/desktop-managers/lxqt.nix
index 896f70c86ebb..686bbd0dcf98 100644
--- a/nixos/modules/services/x11/desktop-managers/lxqt.nix
+++ b/nixos/modules/services/x11/desktop-managers/lxqt.nix
@@ -3,15 +3,6 @@
 with lib;
 
 let
-
-  # Remove packages of ys from xs, based on their names
-  removePackagesByName = xs: ys:
-    let
-      pkgName = drv: (builtins.parseDrvName drv.name).name;
-      ysNames = map pkgName ys;
-    in
-      filter (x: !(builtins.elem (pkgName x) ysNames)) xs;
-
   xcfg = config.services.xserver;
   cfg = xcfg.desktopManager.lxqt;
 
@@ -60,7 +51,7 @@ in
     environment.systemPackages =
       pkgs.lxqt.preRequisitePackages ++
       pkgs.lxqt.corePackages ++
-      (removePackagesByName
+      (pkgs.gnome3.removePackagesByName
         pkgs.lxqt.optionalPackages
         config.environment.lxqt.excludePackages);
 
diff --git a/nixos/modules/services/x11/desktop-managers/mate.nix b/nixos/modules/services/x11/desktop-managers/mate.nix
index db83aaf3c19f..4d2fafd14961 100644
--- a/nixos/modules/services/x11/desktop-managers/mate.nix
+++ b/nixos/modules/services/x11/desktop-managers/mate.nix
@@ -4,14 +4,6 @@ with lib;
 
 let
 
-  # Remove packages of ys from xs, based on their names
-  removePackagesByName = xs: ys:
-    let
-      pkgName = drv: (builtins.parseDrvName drv.name).name;
-      ysNames = map pkgName ys;
-    in
-      filter (x: !(builtins.elem (pkgName x) ysNames)) xs;
-
   addToXDGDirs = p: ''
     if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then
       export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name}
@@ -96,7 +88,7 @@ in
 
     environment.systemPackages =
       pkgs.mate.basePackages ++
-      (removePackagesByName
+      (pkgs.gnome3.removePackagesByName
         pkgs.mate.extraPackages
         config.environment.mate.excludePackages);
 
diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix
index 047321bd9495..0e87e6adbab8 100644
--- a/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixos/modules/services/x11/display-managers/default.nix
@@ -191,7 +191,9 @@ let
       '') names}
 
       ${concatMapStrings (pkg: ''
-        ${xorg.lndir}/bin/lndir ${pkg}/share/xsessions $out/share/xsessions
+        if test -d ${pkg}/share/xsessions; then
+          ${xorg.lndir}/bin/lndir ${pkg}/share/xsessions $out/share/xsessions
+        fi
       '') cfg.displayManager.extraSessionFilePackages}
 
       
diff --git a/nixos/modules/services/x11/urxvtd.nix b/nixos/modules/services/x11/urxvtd.nix
index 5531d7f153c2..d916fa5bb393 100644
--- a/nixos/modules/services/x11/urxvtd.nix
+++ b/nixos/modules/services/x11/urxvtd.nix
@@ -7,14 +7,24 @@ with lib;
 let
   cfg = config.services.urxvtd;
 in {
+  options.services.urxvtd = {
+    enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Enable urxvtd, the urxvt terminal daemon. To use urxvtd, run
+        "urxvtc".
+      '';
+    };
 
-  options.services.urxvtd.enable = mkOption {
-    type = types.bool;
-    default = false;
-    description = ''
-      Enable urxvtd, the urxvt terminal daemon. To use urxvtd, run
-      "urxvtc".
-    '';
+    package = mkOption {
+      default = pkgs.rxvt_unicode-with-plugins;
+      defaultText = "pkgs.rxvt_unicode-with-plugins";
+      description = ''
+        Package to install. Usually pkgs.rxvt_unicode-with-plugins or pkgs.rxvt_unicode
+      '';
+      type = types.package;
+    };
   };
 
   config = mkIf cfg.enable {
@@ -24,14 +34,14 @@ in {
       partOf = [ "graphical-session.target" ];
       path = [ pkgs.xsel ];
       serviceConfig = {
-        ExecStart = "${pkgs.rxvt_unicode-with-plugins}/bin/urxvtd -o";
+        ExecStart = "${cfg.package}/bin/urxvtd -o";
         Environment = "RXVT_SOCKET=%t/urxvtd-socket";
         Restart = "on-failure";
         RestartSec = "5s";
       };
     };
 
-    environment.systemPackages = [ pkgs.rxvt_unicode-with-plugins ];
+    environment.systemPackages = [ cfg.package ];
     environment.variables.RXVT_SOCKET = "/run/user/$(id -u)/urxvtd-socket";
   };
 
diff --git a/nixos/modules/system/boot/initrd-network.nix b/nixos/modules/system/boot/initrd-network.nix
index dd0ea69e9685..cb8fc957a990 100644
--- a/nixos/modules/system/boot/initrd-network.nix
+++ b/nixos/modules/system/boot/initrd-network.nix
@@ -56,7 +56,8 @@ in
         is acquired using DHCP.
 
         You should add the module(s) required for your network card to
-        boot.initrd.availableKernelModules. lspci -v -s &lt;ethernet controller&gt;
+        boot.initrd.availableKernelModules.
+        <literal>lspci -v | grep -iA8 'network\|ethernet'</literal>
         will tell you which.
       '';
     };
diff --git a/nixos/modules/system/boot/initrd-ssh.nix b/nixos/modules/system/boot/initrd-ssh.nix
index 53e993603e27..2d3e3b05c980 100644
--- a/nixos/modules/system/boot/initrd-ssh.nix
+++ b/nixos/modules/system/boot/initrd-ssh.nix
@@ -82,6 +82,7 @@ in
       default = config.users.users.root.openssh.authorizedKeys.keys;
       description = ''
         Authorized keys for the root user on initrd.
+        Note that Dropbear doesn't support OpenSSH's Ed25519 key type.
       '';
     };
 
diff --git a/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix b/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix
index 2d27611946e2..ff90a9b46179 100644
--- a/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix
+++ b/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix
@@ -7,8 +7,8 @@ let
   generationsDirBuilder = pkgs.substituteAll {
     src = ./generations-dir-builder.sh;
     isExecutable = true;
-    inherit (pkgs) bash;
-    path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
+    inherit (pkgs.buildPackages) bash;
+    path = with pkgs.buildPackages; [coreutils gnused gnugrep];
     inherit (config.boot.loader.generationsDir) copyKernels;
   };
 
diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix b/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix
index af39c7bb6841..5f5dbe1092d0 100644
--- a/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix
+++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix
@@ -8,7 +8,7 @@ let
 
   timeoutStr = if blCfg.timeout == null then "-1" else toString blCfg.timeout;
 
-  builder = import ./extlinux-conf-builder.nix { inherit pkgs; };
+  builder = import ./extlinux-conf-builder.nix { pkgs = pkgs.buildPackages; };
 in
 {
   options = {
diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
index 576a07c1d272..9ac6b6b12242 100644
--- a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
+++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
@@ -3,6 +3,6 @@
 pkgs.substituteAll {
   src = ./extlinux-conf-builder.sh;
   isExecutable = true;
-  path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
-  inherit (pkgs) bash;
+  path = [pkgs.buildPackages.coreutils pkgs.buildPackages.gnused pkgs.buildPackages.gnugrep];
+  inherit (pkgs.buildPackages) bash;
 }
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index 3a33b3f65d36..a1537ad3cedc 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -586,7 +586,7 @@ in
         in pkgs.writeScript "install-grub.sh" (''
         #!${pkgs.runtimeShell}
         set -e
-        export PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX XMLSAXBase ListCompare ])}
+        export PERL5LIB=${with pkgs.perlPackages; makePerlPath [ FileSlurp XMLLibXML XMLSAX XMLSAXBase ListCompare ]}
         ${optionalString cfg.enableCryptodisk "export GRUB_ENABLE_CRYPTODISK=y"}
       '' + flip concatMapStrings cfg.mirroredBoots (args: ''
         ${pkgs.perl}/bin/perl ${install-grub-pl} ${grubConfig args} $@
diff --git a/nixos/modules/system/boot/loader/init-script/init-script.nix b/nixos/modules/system/boot/loader/init-script/init-script.nix
index 374d9524ff1e..385a26036784 100644
--- a/nixos/modules/system/boot/loader/init-script/init-script.nix
+++ b/nixos/modules/system/boot/loader/init-script/init-script.nix
@@ -7,8 +7,8 @@ let
   initScriptBuilder = pkgs.substituteAll {
     src = ./init-script-builder.sh;
     isExecutable = true;
-    inherit (pkgs) bash;
-    path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
+    inherit (pkgs.buildPackages) bash;
+    path = with pkgs.buildPackages; [coreutils gnused gnugrep];
   };
 
 in
diff --git a/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix b/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix
index 7e089507ff20..047651dc6426 100644
--- a/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix
+++ b/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix
@@ -19,7 +19,7 @@ let
   blCfg = config.boot.loader;
   timeoutStr = if blCfg.timeout == null then "-1" else toString blCfg.timeout;
 
-  isAarch64 = pkgs.stdenv.isAarch64;
+  isAarch64 = pkgs.stdenv.hostPlatform.isAarch64;
   optional = pkgs.stdenv.lib.optionalString;
 
   configTxt =
@@ -97,7 +97,7 @@ in
 
   config = mkIf cfg.enable {
     assertions = singleton {
-      assertion = !pkgs.stdenv.isAarch64 || cfg.version == 3;
+      assertion = !pkgs.stdenv.hostPlatform.isAarch64 || cfg.version == 3;
       message = "Only Raspberry Pi 3 supports aarch64.";
     };
 
diff --git a/nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix b/nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix
index e929c33c6ee3..94599a0081c6 100644
--- a/nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix
+++ b/nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix
@@ -1,7 +1,7 @@
 { pkgs, version, configTxt }:
 
 let
-  isAarch64 = pkgs.stdenv.isAarch64;
+  isAarch64 = pkgs.stdenv.hostPlatform.isAarch64;
 
   uboot =
     if version == 0 then
@@ -18,18 +18,17 @@ let
 
   extlinuxConfBuilder =
     import ../generic-extlinux-compatible/extlinux-conf-builder.nix {
-      inherit pkgs;
+      pkgs = pkgs.buildPackages;
     };
 in
 pkgs.substituteAll {
   src = ./uboot-builder.sh;
   isExecutable = true;
-  inherit (pkgs) bash;
-  path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
+  inherit (pkgs.buildPackages) bash;
+  path = with pkgs.buildPackages; [coreutils gnused gnugrep];
   firmware = pkgs.raspberrypifw;
   inherit uboot;
   inherit configTxt;
   inherit extlinuxConfBuilder;
   inherit version;
 }
-
diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
index feed863efd66..9ad2a2779e18 100644
--- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
+++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
@@ -12,7 +12,7 @@ let
 
     isExecutable = true;
 
-    inherit (pkgs) python3;
+    inherit (pkgs.buildPackages) python3;
 
     systemd = config.systemd.package;
 
diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix
index 018e7b2e7f89..aa4a5f8abcce 100644
--- a/nixos/modules/system/boot/luksroot.nix
+++ b/nixos/modules/system/boot/luksroot.nix
@@ -144,7 +144,7 @@ let
                     fi
                 fi
             done
-            echo -n "Verifiying passphrase for ${device}..."
+            echo -n "Verifying passphrase for ${device}..."
             echo -n "$passphrase" | ${csopen} --key-file=-
             if [ $? == 0 ]; then
                 echo " - success"
diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh
index 6a4ac8128ab3..6dafc6cddde7 100644
--- a/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixos/modules/system/boot/stage-1-init.sh
@@ -340,6 +340,10 @@ mountFS() {
                 echo "resizing $device..."
                 e2fsck -fp "$device"
                 resize2fs "$device"
+            elif [ "$fsType" = f2fs ]; then
+                echo "resizing $device..."
+                fsck.f2fs -fp "$device"
+                resize.f2fs "$device" 
             fi
             ;;
     esac
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index e7167999a6f8..c8ea1401528c 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -127,8 +127,8 @@ let
       copy_bin_and_libs ${pkgs.kmod}/bin/kmod
       ln -sf kmod $out/bin/modprobe
 
-      # Copy resize2fs if needed.
-      ${optionalString (any (fs: fs.autoResize) fileSystems) ''
+      # Copy resize2fs if any ext* filesystems are to be resized
+      ${optionalString (any (fs: fs.autoResize && (lib.hasPrefix "ext" fs.fsType)) fileSystems) ''
         # We need mke2fs in the initrd.
         copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/resize2fs
       ''}
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index d1029bb57982..860268ab23a6 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -898,6 +898,7 @@ in
     systemd.services.systemd-remount-fs.restartIfChanged = false;
     systemd.services.systemd-update-utmp.restartIfChanged = false;
     systemd.services.systemd-user-sessions.restartIfChanged = false; # Restart kills all active sessions.
+    systemd.services.systemd-udev-settle.restartIfChanged = false; # Causes long delays in nixos-rebuild
     # Restarting systemd-logind breaks X11
     # - upstream commit: https://cgit.freedesktop.org/xorg/xserver/commit/?id=dc48bd653c7e101
     # - systemd announcement: https://github.com/systemd/systemd/blob/22043e4317ecd2bc7834b48a6d364de76bb26d91/NEWS#L103-L112
diff --git a/nixos/modules/system/etc/etc.nix b/nixos/modules/system/etc/etc.nix
index 7d43ba07ca57..57ade2880962 100644
--- a/nixos/modules/system/etc/etc.nix
+++ b/nixos/modules/system/etc/etc.nix
@@ -154,7 +154,7 @@ in
       ''
         # Set up the statically computed bits of /etc.
         echo "setting up /etc..."
-        ${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl ${./setup-etc.pl} ${etc}/etc
+        ${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/${pkgs.perl.libPrefix} ${./setup-etc.pl} ${etc}/etc
       '';
 
   };
diff --git a/nixos/modules/tasks/cpu-freq.nix b/nixos/modules/tasks/cpu-freq.nix
index 5f8b5df52acf..513382936e47 100644
--- a/nixos/modules/tasks/cpu-freq.nix
+++ b/nixos/modules/tasks/cpu-freq.nix
@@ -10,43 +10,81 @@ in
 {
   ###### interface
 
-  options = {
+  options.powerManagement = {
 
-    powerManagement.cpuFreqGovernor = mkOption {
+    # TODO: This should be aliased to powerManagement.cpufreq.governor.
+    # https://github.com/NixOS/nixpkgs/pull/53041#commitcomment-31825338
+    cpuFreqGovernor = mkOption {
       type = types.nullOr types.str;
       default = null;
       example = "ondemand";
       description = ''
         Configure the governor used to regulate the frequence of the
         available CPUs. By default, the kernel configures the
-        performance governor.
+        performance governor, although this may be overwritten in your
+        hardware-configuration.nix file.
+
+        Often used values: "ondemand", "powersave", "performance"
       '';
     };
 
+    cpufreq = {
+
+      max = mkOption {
+        type = types.nullOr types.ints.unsigned;
+        default = null;
+        example = 2200000;
+        description = ''
+          The maximum frequency the CPU will use.  Defaults to the maximum possible.
+        '';
+      };
+
+      min = mkOption {
+        type = types.nullOr types.ints.unsigned;
+        default = null;
+        example = 800000;
+        description = ''
+          The minimum frequency the CPU will use.
+        '';
+      };
+    };
+
   };
 
 
   ###### implementation
 
-  config = mkIf (!config.boot.isContainer && config.powerManagement.cpuFreqGovernor != null) {
+  config =
+    let
+      governorEnable = cfg.cpuFreqGovernor != null;
+      maxEnable = cfg.cpufreq.max != null;
+      minEnable = cfg.cpufreq.min != null;
+      enable =
+        !config.boot.isContainer &&
+        (governorEnable || maxEnable || minEnable);
+    in
+    mkIf enable {
 
-    boot.kernelModules = [ "cpufreq_${cfg.cpuFreqGovernor}" ];
+      boot.kernelModules = optional governorEnable "cpufreq_${cfg.cpuFreqGovernor}";
 
-    environment.systemPackages = [ cpupower ];
+      environment.systemPackages = [ cpupower ];
 
-    systemd.services.cpufreq = {
-      description = "CPU Frequency Governor Setup";
-      after = [ "systemd-modules-load.service" ];
-      wantedBy = [ "multi-user.target" ];
-      path = [ cpupower pkgs.kmod ];
-      unitConfig.ConditionVirtualization = false;
-      serviceConfig = {
-        Type = "oneshot";
-        RemainAfterExit = "yes";
-        ExecStart = "${cpupower}/bin/cpupower frequency-set -g ${cfg.cpuFreqGovernor}";
-        SuccessExitStatus = "0 237";
+      systemd.services.cpufreq = {
+        description = "CPU Frequency Setup";
+        after = [ "systemd-modules-load.service" ];
+        wantedBy = [ "multi-user.target" ];
+        path = [ cpupower pkgs.kmod ];
+        unitConfig.ConditionVirtualization = false;
+        serviceConfig = {
+          Type = "oneshot";
+          RemainAfterExit = "yes";
+          ExecStart = "${cpupower}/bin/cpupower frequency-set " +
+            optionalString governorEnable "--governor ${cfg.cpuFreqGovernor} " +
+            optionalString maxEnable "--max ${toString cfg.cpufreq.max} " +
+            optionalString minEnable "--min ${toString cfg.cpufreq.min} ";
+          SuccessExitStatus = "0 237";
+        };
       };
-    };
 
   };
 }
diff --git a/nixos/modules/tasks/filesystems/f2fs.nix b/nixos/modules/tasks/filesystems/f2fs.nix
index d103ff1a57b5..a305235979a2 100644
--- a/nixos/modules/tasks/filesystems/f2fs.nix
+++ b/nixos/modules/tasks/filesystems/f2fs.nix
@@ -4,6 +4,7 @@ with lib;
 
 let
   inInitrd = any (fs: fs == "f2fs") config.boot.initrd.supportedFilesystems;
+  fileSystems = filter (x: x.fsType == "f2fs") config.system.build.fileSystems;
 in
 {
   config = mkIf (any (fs: fs == "f2fs") config.boot.supportedFilesystems) {
@@ -14,6 +15,11 @@ in
 
     boot.initrd.extraUtilsCommands = mkIf inInitrd ''
       copy_bin_and_libs ${pkgs.f2fs-tools}/sbin/fsck.f2fs
+      ${optionalString (any (fs: fs.autoResize) fileSystems) ''
+        # We need f2fs-tools' tools to resize filesystems
+        copy_bin_and_libs ${pkgs.f2fs-tools}/sbin/resize.f2fs
+      ''}
+
     '';
   };
 }
diff --git a/nixos/modules/testing/service-runner.nix b/nixos/modules/testing/service-runner.nix
index 25490d671152..5ead75788e5c 100644
--- a/nixos/modules/testing/service-runner.nix
+++ b/nixos/modules/testing/service-runner.nix
@@ -6,7 +6,7 @@ let
 
   makeScript = name: service: pkgs.writeScript "${name}-runner"
     ''
-      #! ${pkgs.perl}/bin/perl -w -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl
+      #! ${pkgs.perl}/bin/perl -w -I${pkgs.perlPackages.FileSlurp}/${pkgs.perl.libPrefix}
 
       use File::Slurp;
 
diff --git a/nixos/modules/virtualisation/container-config.nix b/nixos/modules/virtualisation/container-config.nix
index 78c59d98a5eb..604fb8a75932 100644
--- a/nixos/modules/virtualisation/container-config.nix
+++ b/nixos/modules/virtualisation/container-config.nix
@@ -7,7 +7,6 @@ with lib;
   config = mkIf config.boot.isContainer {
 
     # Disable some features that are not useful in a container.
-    sound.enable = mkDefault false;
     services.udisks2.enable = mkDefault false;
     powerManagement.enable = mkDefault false;
 
diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix
index 3dd36f9b12e1..c2e6e9f6a136 100644
--- a/nixos/modules/virtualisation/containers.nix
+++ b/nixos/modules/virtualisation/containers.nix
@@ -188,6 +188,8 @@ let
           ''
         else
           ''
+            echo "Bring ${name} up"
+            ip link set dev ${name} up
             # Set IPs and routes for ${name}
             ${optionalString (cfg.hostAddress != null) ''
               ip addr add ${cfg.hostAddress} dev ${name}
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 860262eeb6cd..9ee8ac2995be 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -92,7 +92,7 @@ in
   hadoop.yarn = handleTestOn [ "x86_64-linux" ] ./hadoop/yarn.nix {};
   handbrake = handleTestOn ["x86_64-linux"] ./handbrake.nix {};
   haproxy = handleTest ./haproxy.nix {};
-  #hardened = handleTest ./hardened.nix {}; # broken due useSandbox = true
+  hardened = handleTest ./hardened.nix {};
   hibernate = handleTest ./hibernate.nix {};
   hitch = handleTest ./hitch {};
   hocker-fetchdocker = handleTest ./hocker-fetchdocker {};
@@ -109,6 +109,7 @@ in
   ipv6 = handleTest ./ipv6.nix {};
   jenkins = handleTest ./jenkins.nix {};
   #kafka = handleTest ./kafka.nix {}; # broken since openjdk: 8u181 -> 8u192
+  kerberos = handleTest ./kerberos/default.nix {};
   kernel-latest = handleTest ./kernel-latest.nix {};
   kernel-lts = handleTest ./kernel-lts.nix {};
   keymap = handleTest ./keymap.nix {};
diff --git a/nixos/tests/containers-extra_veth.nix b/nixos/tests/containers-extra_veth.nix
index b4c48afe48ba..b3d3bce87579 100644
--- a/nixos/tests/containers-extra_veth.nix
+++ b/nixos/tests/containers-extra_veth.nix
@@ -13,6 +13,7 @@ import ./make-test.nix ({ pkgs, ...} : {
       virtualisation.memorySize = 768;
       virtualisation.vlans = [];
 
+      networking.useDHCP = false;
       networking.bridges = {
         br0 = {
           interfaces = [];
diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix
index ecd14b274eb3..58f106314ab3 100644
--- a/nixos/tests/docker-tools.nix
+++ b/nixos/tests/docker-tools.nix
@@ -62,6 +62,7 @@ import ./make-test.nix ({ pkgs, ... }: {
       # Ensure Layered Docker images work
       $docker->succeed("docker load --input='${pkgs.dockerTools.examples.layered-image}'");
       $docker->succeed("docker run --rm ${pkgs.dockerTools.examples.layered-image.imageName}");
+      $docker->succeed("docker run --rm ${pkgs.dockerTools.examples.layered-image.imageName} cat extraCommands");
 
       # Ensure building an image on top of a layered Docker images work
       $docker->succeed("docker load --input='${pkgs.dockerTools.examples.layered-on-top}'");
diff --git a/nixos/tests/gitea.nix b/nixos/tests/gitea.nix
index 354334991852..28e6479e9cbe 100644
--- a/nixos/tests/gitea.nix
+++ b/nixos/tests/gitea.nix
@@ -64,6 +64,7 @@ with pkgs.lib;
     machine =
       { config, pkgs, ... }:
       { services.gitea.enable = true;
+        services.gitea.disableRegistration = true;
       };
 
     testScript = ''
@@ -72,6 +73,7 @@ with pkgs.lib;
       $machine->waitForUnit('gitea.service');
       $machine->waitForOpenPort('3000');
       $machine->succeed("curl --fail http://localhost:3000/");
+      $machine->succeed("curl --fail http://localhost:3000/user/sign_up | grep 'Registration is disabled. Please contact your site administrator.'");
     '';
   };
 }
diff --git a/nixos/tests/hardened.nix b/nixos/tests/hardened.nix
index 683f56c45af4..07bd10963bab 100644
--- a/nixos/tests/hardened.nix
+++ b/nixos/tests/hardened.nix
@@ -5,7 +5,7 @@ import ./make-test.nix ({ pkgs, ...} : {
   };
 
   machine =
-    { lib, pkgs, ... }:
+    { lib, pkgs, config, ... }:
     with lib;
     { users.users.alice = { isNormalUser = true; extraGroups = [ "proc" ]; };
       users.users.sybil = { isNormalUser = true; group = "wheel"; };
@@ -22,12 +22,19 @@ import ./make-test.nix ({ pkgs, ...} : {
           options = [ "noauto" ];
         };
       };
+      boot.extraModulePackages = [ config.boot.kernelPackages.wireguard ];
+      boot.kernelModules = [ "wireguard" ];
     };
 
   testScript =
     ''
       $machine->waitForUnit("multi-user.target");
 
+      # Test loading out-of-tree modules
+      subtest "extra-module-packages", sub {
+          $machine->succeed("grep -Fq wireguard /proc/modules");
+      };
+
       # Test hidepid
       subtest "hidepid", sub {
           $machine->succeed("grep -Fq hidepid=2 /proc/mounts");
diff --git a/nixos/tests/kerberos/default.nix b/nixos/tests/kerberos/default.nix
new file mode 100644
index 000000000000..f2f1a438918c
--- /dev/null
+++ b/nixos/tests/kerberos/default.nix
@@ -0,0 +1,7 @@
+{ system ? builtins.currentSystem
+, pkgs ? import ../../.. { inherit system; }
+}:
+{
+  mit = import ./mit.nix { inherit system pkgs; };
+  heimdal = import ./heimdal.nix { inherit system pkgs; };
+}
diff --git a/nixos/tests/kerberos/heimdal.nix b/nixos/tests/kerberos/heimdal.nix
new file mode 100644
index 000000000000..a0551b131e91
--- /dev/null
+++ b/nixos/tests/kerberos/heimdal.nix
@@ -0,0 +1,53 @@
+import ../make-test.nix ({pkgs, ...}: {
+  name = "kerberos_server-heimdal";
+  machine = { config, libs, pkgs, ...}:
+  { services.kerberos_server =
+    { enable = true;
+      realms = {
+        "FOO.BAR".acl = [{principal = "admin"; access = ["add" "cpw"];}];
+      };
+    };
+    krb5 = {
+      enable = true;
+      kerberos = pkgs.heimdalFull;
+      libdefaults = {
+        default_realm = "FOO.BAR";
+      };
+      realms = {
+        "FOO.BAR" = {
+          admin_server = "machine";
+          kdc = "machine";
+        };
+      };
+    };
+  };
+
+  testScript = ''
+    $machine->start;
+
+    $machine->succeed(
+      "kadmin -l init --realm-max-ticket-life='8 day' \\
+       --realm-max-renewable-life='10 day' FOO.BAR"
+    );
+
+    $machine->succeed("systemctl restart kadmind.service kdc.service");
+    $machine->waitForUnit("kadmind.service");
+    $machine->waitForUnit("kdc.service");
+    $machine->waitForUnit("kpasswdd.service");
+
+    $machine->succeed(
+      "kadmin -l add --password=admin_pw --use-defaults admin"
+    );
+    $machine->succeed(
+      "kadmin -l ext_keytab --keytab=admin.keytab admin"
+    );
+    $machine->succeed(
+      "kadmin -p admin -K admin.keytab add --password=alice_pw --use-defaults \\
+       alice"
+    );
+    $machine->succeed(
+      "kadmin -l ext_keytab --keytab=alice.keytab alice"
+    );
+    $machine->succeed("kinit -kt alice.keytab alice");
+  '';
+})
diff --git a/nixos/tests/kerberos/mit.nix b/nixos/tests/kerberos/mit.nix
new file mode 100644
index 000000000000..6da3a384aa99
--- /dev/null
+++ b/nixos/tests/kerberos/mit.nix
@@ -0,0 +1,45 @@
+import ../make-test.nix ({pkgs, ...}: {
+  name = "kerberos_server-mit";
+  machine = { config, libs, pkgs, ...}:
+  { services.kerberos_server =
+    { enable = true;
+      realms = {
+        "FOO.BAR".acl = [{principal = "admin"; access = ["add" "cpw"];}];
+      };
+    };
+    krb5 = {
+      enable = true;
+      kerberos = pkgs.krb5Full;
+      libdefaults = {
+        default_realm = "FOO.BAR";
+      };
+      realms = {
+        "FOO.BAR" = {
+          admin_server = "machine";
+          kdc = "machine";
+        };
+      };
+    };
+    users.extraUsers.alice = { isNormalUser = true; };
+  };
+
+  testScript = ''
+    $machine->start;
+
+    $machine->succeed(
+      "kdb5_util create -s -r FOO.BAR -P master_key"
+    );
+
+    $machine->succeed("systemctl restart kadmind.service kdc.service");
+    $machine->waitForUnit("kadmind.service");
+    $machine->waitForUnit("kdc.service");
+
+    $machine->succeed(
+      "kadmin.local add_principal -pw admin_pw admin"
+    );
+    $machine->succeed(
+      "kadmin -p admin -w admin_pw addprinc -pw alice_pw alice"
+    );
+    $machine->succeed("echo alice_pw | sudo -u alice kinit");
+  '';
+})
diff --git a/nixos/tests/nexus.nix b/nixos/tests/nexus.nix
index bf49d2247bd8..783c9f5c019f 100644
--- a/nixos/tests/nexus.nix
+++ b/nixos/tests/nexus.nix
@@ -14,7 +14,7 @@ import ./make-test.nix ({ pkgs, ...} : {
     server =
       { ... }:
       { virtualisation.memorySize = 2047; # qemu-system-i386 has a 2047M limit
-        virtualisation.diskSize = 2048;
+        virtualisation.diskSize = 8192;
 
         services.nexus.enable = true;
       };
diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix
index 5d1e004c5dd1..140687a8182f 100644
--- a/nixos/tests/prometheus-exporters.nix
+++ b/nixos/tests/prometheus-exporters.nix
@@ -106,6 +106,25 @@ let
       '';
     };
 
+    bind = {
+      exporterConfig = {
+        enable = true;
+      };
+      metricProvider = {
+        services.bind.enable = true;
+        services.bind.extraConfig = ''
+          statistics-channels {
+            inet 127.0.0.1 port 8053 allow { localhost; };
+          };
+        '';
+      };
+      exporterTest = ''
+        waitForUnit("prometheus-bind-exporter.service");
+        waitForOpenPort(9119);
+        succeed("curl -sSf http://localhost:9119/metrics" | grep -q 'bind_query_recursions_total 0');
+      '';
+    };
+
     dovecot = {
       exporterConfig = {
         enable = true;
diff --git a/nixos/tests/xss-lock.nix b/nixos/tests/xss-lock.nix
index 045667bdcdec..b46bb1a8f6e9 100644
--- a/nixos/tests/xss-lock.nix
+++ b/nixos/tests/xss-lock.nix
@@ -9,7 +9,6 @@ with lib;
   machine = {
     imports = [ ./common/x11.nix ./common/user-account.nix ];
     programs.xss-lock.enable = true;
-    programs.xss-lock.lockerCommand = "${pkgs.xlockmore}/bin/xlock";
     services.xserver.displayManager.auto.user = "alice";
   };
 
@@ -20,6 +19,6 @@ with lib;
 
     $machine->fail("pgrep xlock");
     $machine->succeed("su -l alice -c 'xset dpms force standby'");
-    $machine->waitUntilSucceeds("pgrep xlock");
+    $machine->waitUntilSucceeds("pgrep i3lock");
   '';
 })