about summary refs log tree commit diff
path: root/nixpkgs/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos')
-rw-r--r--nixpkgs/nixos/doc/manual/configuration/x-windows.xml4
-rw-r--r--nixpkgs/nixos/doc/manual/development/debugging-nixos-tests.xml37
-rw-r--r--nixpkgs/nixos/doc/manual/development/nixos-tests.xml1
-rw-r--r--nixpkgs/nixos/doc/manual/installation/installing-usb.xml2
-rw-r--r--nixpkgs/nixos/doc/manual/installation/installing-virtualbox-guest.xml8
-rw-r--r--nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml53
-rw-r--r--nixpkgs/nixos/doc/manual/release-notes/rl-1903.xml107
-rw-r--r--nixpkgs/nixos/lib/build-vms.nix2
-rw-r--r--nixpkgs/nixos/lib/make-disk-image.nix9
-rw-r--r--nixpkgs/nixos/lib/make-ext4-fs.nix61
-rw-r--r--nixpkgs/nixos/lib/make-squashfs.nix5
-rw-r--r--nixpkgs/nixos/lib/test-driver/Logger.pm3
-rw-r--r--nixpkgs/nixos/lib/test-driver/Machine.pm12
-rw-r--r--nixpkgs/nixos/lib/testing.nix6
-rw-r--r--nixpkgs/nixos/modules/config/ldap.nix56
-rw-r--r--nixpkgs/nixos/modules/config/pulseaudio.nix5
-rw-r--r--nixpkgs/nixos/modules/config/system-path.nix2
-rw-r--r--nixpkgs/nixos/modules/config/users-groups.nix4
-rw-r--r--nixpkgs/nixos/modules/config/zram.nix81
-rw-r--r--nixpkgs/nixos/modules/hardware/all-firmware.nix2
-rw-r--r--nixpkgs/nixos/modules/hardware/opengl.nix12
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/channel.nix2
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix6
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix9
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix9
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix9
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix8
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl13
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-option.sh6
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh4
-rw-r--r--nixpkgs/nixos/modules/installer/tools/tools.nix2
-rw-r--r--nixpkgs/nixos/modules/misc/ids.nix6
-rw-r--r--nixpkgs/nixos/modules/misc/nixpkgs.nix4
-rw-r--r--nixpkgs/nixos/modules/misc/version.nix1
-rw-r--r--nixpkgs/nixos/modules/module-list.nix5
-rw-r--r--nixpkgs/nixos/modules/profiles/hardened.nix9
-rw-r--r--nixpkgs/nixos/modules/profiles/headless.nix1
-rw-r--r--nixpkgs/nixos/modules/profiles/minimal.nix2
-rw-r--r--nixpkgs/nixos/modules/programs/command-not-found/command-not-found.nix2
-rw-r--r--nixpkgs/nixos/modules/programs/nano.nix5
-rw-r--r--nixpkgs/nixos/modules/programs/ssh.nix12
-rw-r--r--nixpkgs/nixos/modules/programs/sway-beta.nix3
-rw-r--r--nixpkgs/nixos/modules/programs/sway.nix13
-rw-r--r--nixpkgs/nixos/modules/programs/way-cooler.nix2
-rw-r--r--nixpkgs/nixos/modules/programs/xss-lock.nix3
-rw-r--r--nixpkgs/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix22
-rw-r--r--nixpkgs/nixos/modules/rename.nix3
-rw-r--r--nixpkgs/nixos/modules/security/pam.nix111
-rw-r--r--nixpkgs/nixos/modules/services/backup/borgbackup.nix3
-rw-r--r--nixpkgs/nixos/modules/services/backup/postgresql-backup.nix51
-rw-r--r--nixpkgs/nixos/modules/services/backup/restic.nix7
-rw-r--r--nixpkgs/nixos/modules/services/databases/cassandra.nix22
-rw-r--r--nixpkgs/nixos/modules/services/databases/mysql.nix6
-rw-r--r--nixpkgs/nixos/modules/services/desktops/gnome3/file-roller.nix32
-rw-r--r--nixpkgs/nixos/modules/services/desktops/gnome3/gnome-keyring.nix2
-rw-r--r--nixpkgs/nixos/modules/services/games/minecraft-server.nix201
-rw-r--r--nixpkgs/nixos/modules/services/hardware/fwupd.nix26
-rw-r--r--nixpkgs/nixos/modules/services/hardware/lirc.nix6
-rw-r--r--nixpkgs/nixos/modules/services/hardware/tlp.nix2
-rw-r--r--nixpkgs/nixos/modules/services/hardware/vdr.nix14
-rw-r--r--nixpkgs/nixos/modules/services/misc/gitea.nix17
-rw-r--r--nixpkgs/nixos/modules/services/misc/gitlab.nix7
-rw-r--r--nixpkgs/nixos/modules/services/misc/home-assistant.nix79
-rw-r--r--nixpkgs/nixos/modules/services/misc/nzbget.nix23
-rw-r--r--nixpkgs/nixos/modules/services/misc/plex.nix2
-rw-r--r--nixpkgs/nixos/modules/services/misc/pykms.nix67
-rw-r--r--nixpkgs/nixos/modules/services/misc/redmine.nix38
-rw-r--r--nixpkgs/nixos/modules/services/misc/sonarr.nix60
-rw-r--r--nixpkgs/nixos/modules/services/misc/weechat.xml4
-rw-r--r--nixpkgs/nixos/modules/services/misc/zoneminder.nix362
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/collectd.nix2
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/datadog-agent.nix2
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/grafana.nix184
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/munin.nix209
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/netdata.nix25
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/prometheus/default.nix3
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix1
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/bind.nix55
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix24
-rw-r--r--nixpkgs/nixos/modules/services/network-filesystems/glusterfs.nix1
-rw-r--r--nixpkgs/nixos/modules/services/networking/ddclient.nix3
-rw-r--r--nixpkgs/nixos/modules/services/networking/firefox/sync-server.nix26
-rw-r--r--nixpkgs/nixos/modules/services/networking/ndppd.nix170
-rw-r--r--nixpkgs/nixos/modules/services/networking/nsd.nix12
-rw-r--r--nixpkgs/nixos/modules/services/networking/nylon.nix1
-rw-r--r--nixpkgs/nixos/modules/services/networking/prosody.nix1
-rw-r--r--nixpkgs/nixos/modules/services/networking/shairport-sync.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/ssh/sshd.nix9
-rw-r--r--nixpkgs/nixos/modules/services/networking/syncthing.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/unifi.nix1
-rw-r--r--nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix4
-rw-r--r--nixpkgs/nixos/modules/services/networking/xrdp.nix6
-rw-r--r--nixpkgs/nixos/modules/services/search/elasticsearch-curator.nix5
-rw-r--r--nixpkgs/nixos/modules/services/security/certmgr.nix11
-rw-r--r--nixpkgs/nixos/modules/services/security/munge.nix2
-rw-r--r--nixpkgs/nixos/modules/services/security/nginx-sso.nix58
-rw-r--r--nixpkgs/nixos/modules/services/security/sks.nix28
-rw-r--r--nixpkgs/nixos/modules/services/security/sshguard.nix99
-rw-r--r--nixpkgs/nixos/modules/services/system/kerberos.nix64
-rw-r--r--nixpkgs/nixos/modules/services/system/kerberos/default.nix80
-rw-r--r--nixpkgs/nixos/modules/services/system/kerberos/heimdal.nix68
-rw-r--r--nixpkgs/nixos/modules/services/system/kerberos/mit.nix68
-rw-r--r--nixpkgs/nixos/modules/services/torrent/transmission.nix3
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/atlassian/confluence.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/atlassian/crowd.nix5
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/atlassian/jira.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/nextcloud.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix25
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/apache-httpd/wordpress.nix8
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/lighttpd/collectd.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/phpfpm/default.nix31
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/phpfpm/pool-options.nix15
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix65
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/lxqt.nix11
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix10
-rw-r--r--nixpkgs/nixos/modules/services/x11/display-managers/default.nix4
-rw-r--r--nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix35
-rw-r--r--nixpkgs/nixos/modules/services/x11/urxvtd.nix28
-rw-r--r--nixpkgs/nixos/modules/system/boot/initrd-network.nix3
-rw-r--r--nixpkgs/nixos/modules/system/boot/initrd-ssh.nix1
-rw-r--r--nixpkgs/nixos/modules/system/boot/kernel_config.nix137
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix4
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix2
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix4
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix2
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/init-script/init-script.nix4
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix4
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix9
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix2
-rw-r--r--nixpkgs/nixos/modules/system/boot/luksroot.nix2
-rw-r--r--nixpkgs/nixos/modules/system/boot/stage-1-init.sh4
-rw-r--r--nixpkgs/nixos/modules/system/boot/stage-1.nix26
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix9
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd.nix7
-rw-r--r--nixpkgs/nixos/modules/system/etc/etc.nix2
-rw-r--r--nixpkgs/nixos/modules/tasks/auto-upgrade.nix2
-rw-r--r--nixpkgs/nixos/modules/tasks/cpu-freq.nix74
-rw-r--r--nixpkgs/nixos/modules/tasks/encrypted-devices.nix6
-rw-r--r--nixpkgs/nixos/modules/tasks/filesystems.nix2
-rw-r--r--nixpkgs/nixos/modules/tasks/filesystems/f2fs.nix6
-rw-r--r--nixpkgs/nixos/modules/tasks/filesystems/zfs.nix1
-rw-r--r--nixpkgs/nixos/modules/testing/service-runner.nix27
-rw-r--r--nixpkgs/nixos/modules/testing/test-instrumentation.nix3
-rw-r--r--nixpkgs/nixos/modules/virtualisation/container-config.nix1
-rw-r--r--nixpkgs/nixos/modules/virtualisation/containers.nix30
-rw-r--r--nixpkgs/nixos/tests/all-tests.nix13
-rw-r--r--nixpkgs/nixos/tests/bittorrent.nix2
-rw-r--r--nixpkgs/nixos/tests/containers-bridge.nix17
-rw-r--r--nixpkgs/nixos/tests/containers-extra_veth.nix1
-rw-r--r--nixpkgs/nixos/tests/docker-tools.nix1
-rw-r--r--nixpkgs/nixos/tests/fwupd.nix2
-rw-r--r--nixpkgs/nixos/tests/gitea.nix2
-rw-r--r--nixpkgs/nixos/tests/hardened.nix9
-rw-r--r--nixpkgs/nixos/tests/home-assistant.nix20
-rw-r--r--nixpkgs/nixos/tests/installer.nix2
-rw-r--r--nixpkgs/nixos/tests/jackett.nix18
-rw-r--r--nixpkgs/nixos/tests/kerberos/default.nix7
-rw-r--r--nixpkgs/nixos/tests/kerberos/heimdal.nix53
-rw-r--r--nixpkgs/nixos/tests/kerberos/mit.nix45
-rw-r--r--nixpkgs/nixos/tests/ldap.nix383
-rw-r--r--nixpkgs/nixos/tests/lidarr.nix18
-rw-r--r--nixpkgs/nixos/tests/mongodb.nix2
-rw-r--r--nixpkgs/nixos/tests/munin.nix4
-rw-r--r--nixpkgs/nixos/tests/nat.nix2
-rw-r--r--nixpkgs/nixos/tests/ndppd.nix61
-rw-r--r--nixpkgs/nixos/tests/neo4j.nix20
-rw-r--r--nixpkgs/nixos/tests/networking.nix3
-rw-r--r--nixpkgs/nixos/tests/nexus.nix2
-rw-r--r--nixpkgs/nixos/tests/nfs.nix2
-rw-r--r--nixpkgs/nixos/tests/nginx-sso.nix44
-rw-r--r--nixpkgs/nixos/tests/pam-u2f.nix23
-rw-r--r--nixpkgs/nixos/tests/postgis.nix5
-rw-r--r--nixpkgs/nixos/tests/postgresql.nix24
-rw-r--r--nixpkgs/nixos/tests/prometheus-exporters.nix19
-rw-r--r--nixpkgs/nixos/tests/radarr.nix18
-rw-r--r--nixpkgs/nixos/tests/redmine.nix84
-rw-r--r--nixpkgs/nixos/tests/sonarr.nix18
-rw-r--r--nixpkgs/nixos/tests/telegraf.nix30
-rw-r--r--nixpkgs/nixos/tests/virtualbox.nix2
-rw-r--r--nixpkgs/nixos/tests/xss-lock.nix3
180 files changed, 3776 insertions, 806 deletions
diff --git a/nixpkgs/nixos/doc/manual/configuration/x-windows.xml b/nixpkgs/nixos/doc/manual/configuration/x-windows.xml
index 703a1b8b7f09..e7d66f391f55 100644
--- a/nixpkgs/nixos/doc/manual/configuration/x-windows.xml
+++ b/nixpkgs/nixos/doc/manual/configuration/x-windows.xml
@@ -35,11 +35,11 @@
  </para>
  <para>
   NixOS’s default <emphasis>display manager</emphasis> (the program that
-  provides a graphical login prompt and manages the X server) is SLiM. You can
+  provides a graphical login prompt and manages the X server) is LightDM. You can
   select an alternative one by picking one of the following lines:
 <programlisting>
 <xref linkend="opt-services.xserver.displayManager.sddm.enable"/> = true;
-<xref linkend="opt-services.xserver.displayManager.lightdm.enable"/> = true;
+<xref linkend="opt-services.xserver.displayManager.slim.enable"/> = true;
 </programlisting>
  </para>
  <para>
diff --git a/nixpkgs/nixos/doc/manual/development/debugging-nixos-tests.xml b/nixpkgs/nixos/doc/manual/development/debugging-nixos-tests.xml
deleted file mode 100644
index 30e58e1e3554..000000000000
--- a/nixpkgs/nixos/doc/manual/development/debugging-nixos-tests.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<section xmlns="http://docbook.org/ns/docbook"
-        xmlns:xlink="http://www.w3.org/1999/xlink"
-        xmlns:xi="http://www.w3.org/2001/XInclude"
-        version="5.0"
-        xml:id="sec-debugging-nixos-tests">
- <title>Debugging NixOS tests</title>
-
- <para>
-  Tests may fail and infrastructure offers access to inspect machine state.
- </para>
-
- <para>
-  To prevent test from stopping and cleaning up, insert a sleep command:
- </para>
-
-<programlisting>
-$machine->succeed("sleep 84000");
-</programlisting>
-
- <para>
-  As soon as machine starts run as root:
- </para>
-
-<programlisting>
-nix-shell -p socat --run "socat STDIO,raw,echo=0,escape=0x11 UNIX:/tmp/nix-build-vm-test-run-*.drv-0/vm-state-machine/backdoor"
-</programlisting>
-
- <para>
-  You may need to find the correct path, replacing <literal>/tmp</literal>,
-  <literal>*</literal> or <literal>machine</literal>.
- </para>
-
- <para>
-  Press "enter" to open up console and login as "root". After you're done,
-  press "ctrl-q" to exit the console.
- </para>
-</section>
diff --git a/nixpkgs/nixos/doc/manual/development/nixos-tests.xml b/nixpkgs/nixos/doc/manual/development/nixos-tests.xml
index d068887200a9..2695082e3867 100644
--- a/nixpkgs/nixos/doc/manual/development/nixos-tests.xml
+++ b/nixpkgs/nixos/doc/manual/development/nixos-tests.xml
@@ -16,5 +16,4 @@ xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/tests">nixos/test
  <xi:include href="writing-nixos-tests.xml" />
  <xi:include href="running-nixos-tests.xml" />
  <xi:include href="running-nixos-tests-interactively.xml" />
- <xi:include href="debugging-nixos-tests.xml" />
 </chapter>
diff --git a/nixpkgs/nixos/doc/manual/installation/installing-usb.xml b/nixpkgs/nixos/doc/manual/installation/installing-usb.xml
index 0b311189430c..c0372e8ebd9b 100644
--- a/nixpkgs/nixos/doc/manual/installation/installing-usb.xml
+++ b/nixpkgs/nixos/doc/manual/installation/installing-usb.xml
@@ -23,7 +23,7 @@ $ diskutil list
 [..]
 $ diskutil unmountDisk diskN
 Unmount of all volumes on diskN was successful
-$ sudo dd bs=1m if=nix.iso of=/dev/rdiskN
+$ sudo dd if=nix.iso of=/dev/rdiskN
 </programlisting>
     Using the 'raw' <command>rdiskN</command> device instead of
     <command>diskN</command> completes in minutes instead of hours. After
diff --git a/nixpkgs/nixos/doc/manual/installation/installing-virtualbox-guest.xml b/nixpkgs/nixos/doc/manual/installation/installing-virtualbox-guest.xml
index da78b480f5aa..766785dfe070 100644
--- a/nixpkgs/nixos/doc/manual/installation/installing-virtualbox-guest.xml
+++ b/nixpkgs/nixos/doc/manual/installation/installing-virtualbox-guest.xml
@@ -77,18 +77,22 @@
   Shared folders can be given a name and a path in the host system in the
   VirtualBox settings (Machine / Settings / Shared Folders, then click on the
   "Add" icon). Add the following to the
-  <literal>/etc/nixos/configuration.nix</literal> to auto-mount them:
+  <literal>/etc/nixos/configuration.nix</literal> to auto-mount them. If you 
+   do not add <literal>"nofail"</literal>, the system will no boot properly. 
+   The same goes for disabling <literal>rngd</literal> which is normally used 
+   to get randomness but this does not work in virtual machines.
  </para>
 
 <programlisting>
 { config, pkgs, ...} :
 {
+  security.rngd.enable = false; // otherwise vm will not boot
   ...
 
   fileSystems."/virtualboxshare" = {
     fsType = "vboxsf";
     device = "nameofthesharedfolder";
-    options = [ "rw" ];
+    options = [ "rw" "nofail" ];
   };
 }
 </programlisting>
diff --git a/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml b/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml
index 551a65f5e96b..b6a247286d4b 100644
--- a/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml
+++ b/nixpkgs/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/nixpkgs/nixos/doc/manual/release-notes/rl-1903.xml b/nixpkgs/nixos/doc/manual/release-notes/rl-1903.xml
index d99c88817279..d84e57333e98 100644
--- a/nixpkgs/nixos/doc/manual/release-notes/rl-1903.xml
+++ b/nixpkgs/nixos/doc/manual/release-notes/rl-1903.xml
@@ -331,18 +331,53 @@
    <para>
      The <literal>pam_unix</literal> account module is now loaded with its
      control field set to <literal>required</literal> instead of
-     <literal>sufficient</literal>, so that later pam account modules that
+     <literal>sufficient</literal>, so that later PAM account modules that
      might do more extensive checks are being executed.
      Previously, the whole account module verification was exited prematurely
      in case a nss module provided the account name to
      <literal>pam_unix</literal>.
      The LDAP and SSSD NixOS modules already add their NSS modules when
-     enabled. In case your setup breaks due to some later pam account module
+     enabled. In case your setup breaks due to some later PAM account module
      previosuly shadowed, or failing NSS lookups, please file a bug. You can
      get back the old behaviour by manually setting
      <literal><![CDATA[security.pam.services.<name?>.text]]></literal>.
    </para>
   </listitem>
+  <listitem>
+   <para>
+     The <literal>pam_unix</literal> password module is now loaded with its
+     control field set to <literal>sufficient</literal> instead of
+     <literal>required</literal>, so that password managed only
+     by later PAM password modules are being executed.
+     Previously, for example, changing an LDAP account's password through PAM
+     was not possible: the whole password module verification
+     was exited prematurely by <literal>pam_unix</literal>,
+     preventing <literal>pam_ldap</literal> to manage the password as it should.
+   </para>
+  </listitem>
+   <listitem>
+    <para>
+     <literal>fish</literal> has been upgraded to 3.0.
+     It comes with a number of improvements and backwards incompatible changes.
+     See the <literal>fish</literal> <link xlink:href="https://github.com/fish-shell/fish-shell/releases/tag/3.0.0">release notes</link> for more information.
+    </para>
+   </listitem>
+  <listitem>
+    <para>
+      The ibus-table input method has had a change in config format, which
+      causes all previous settings to be lost. See
+      <link xlink:href="https://github.com/mike-fabian/ibus-table/commit/f9195f877c5212fef0dfa446acb328c45ba5852b">this commit message</link>
+      for details.
+    </para>
+  </listitem>
+  <listitem>
+   <para>
+    Support for NixOS module system type <literal>types.optionSet</literal> and
+    <literal>lib.mkOption</literal> argument <literal>options</literal> is removed.
+    Use <literal>types.submodule</literal> instead.
+    (<link xlink:href="https://github.com/NixOS/nixpkgs/pull/54637">#54637</link>)
+   </para>
+  </listitem>
   </itemizedlist>
  </section>
 
@@ -363,6 +398,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
@@ -391,10 +432,72 @@
    </listitem>
    <listitem>
      <para>
+       The astah-community package was removed from nixpkgs due to it being discontinued and the downloads not being available anymore.
+     </para>
+   </listitem>
+   <listitem>
+     <para>
+       The httpd service now saves log files with a .log file extension by default for
+       easier integration with the logrotate service.
+     </para>
+   </listitem>
+   <listitem>
+     <para>
        The owncloud server packages and httpd subservice module were removed
        from nixpkgs due to the lack of maintainers.
      </para>
    </listitem>
+   <listitem>
+     <para>
+       It is possible now to uze ZRAM devices as general purpose ephemeral block devices,
+       not only as swap. Using more than 1 device as ZRAM swap is no longer recommended,
+       but is still possible by setting <literal>zramSwap.swapDevices</literal> explicitly.
+     </para>
+     <para>
+      Default algorithm for ZRAM swap was changed to <literal>zstd</literal>.
+     </para>
+     <para>
+      Changes to ZRAM algorithm are applied during <literal>nixos-rebuild switch</literal>,
+      so make sure you have enough swap space on disk to survive ZRAM device rebuild. Alternatively,
+      use <literal>nixos-rebuild boot; reboot</literal>.
+     </para>
+   </listitem>
+   <listitem>
+    <para>
+      Flat volumes are now disabled by default in <literal>hardware.pulseaudio</literal>.
+      This has been done to prevent applications, which are unaware of this feature, setting
+      their volumes to 100% on startup causing harm to your audio hardware and potentially your ears.
+    </para>
+    <note>
+     <para>
+      With this change application specific volumes are relative to the master volume which can be
+      adjusted independently, whereas before they were absolute; meaning that in effect, it scaled the
+      device-volume with the volume of the loudest application.
+     </para>
+    </note>
+   </listitem>
+   <listitem>
+    <para>
+     The <link xlink:href="https://github.com/DanielAdolfsson/ndppd"><literal>ndppd</literal></link> module
+     now supports <link linkend="opt-services.ndppd.enable">all config options</link> provided by the current
+     upstream version as service options. Additionally the <literal>ndppd</literal> package doesn't contain
+     the systemd unit configuration from upstream anymore, the unit is completely configured by the NixOS module now.
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     New installs of NixOS will default to the Redmine 4.x series unless otherwise specified in
+     <literal>services.redmine.package</literal> while existing installs of NixOS will default to
+     the Redmine 3.x series.
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     The <link linkend="opt-services.grafana.enable">Grafana module</link> now supports declarative
+     <link xlink:href="http://docs.grafana.org/administration/provisioning/">datasource and dashboard</link>
+     provisioning.
+    </para>
+   </listitem>
   </itemizedlist>
  </section>
 </section>
diff --git a/nixpkgs/nixos/lib/build-vms.nix b/nixpkgs/nixos/lib/build-vms.nix
index 024f4414ebeb..a5580f4712eb 100644
--- a/nixpkgs/nixos/lib/build-vms.nix
+++ b/nixpkgs/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/nixpkgs/nixos/lib/make-disk-image.nix b/nixpkgs/nixos/lib/make-disk-image.nix
index bf32a36895c5..5e86ea479d51 100644
--- a/nixpkgs/nixos/lib/make-disk-image.nix
+++ b/nixpkgs/nixos/lib/make-disk-image.nix
@@ -27,6 +27,9 @@
 , # The root file system type.
   fsType ? "ext4"
 
+, # Filesystem label
+  label ? "nixos"
+
 , # The initial NixOS configuration file to be copied to
   # /etc/nixos/configuration.nix.
   configFile ? null
@@ -84,7 +87,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
@@ -134,9 +137,9 @@ let format' = format; in let
       # Get start & length of the root partition in sectors to $START and $SECTORS.
       eval $(partx $diskImage -o START,SECTORS --nr ${rootPartition} --pairs)
 
-      mkfs.${fsType} -F -L nixos $diskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K
+      mkfs.${fsType} -F -L ${label} $diskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K
     '' else ''
-      mkfs.${fsType} -F -L nixos $diskImage
+      mkfs.${fsType} -F -L ${label} $diskImage
     ''}
 
     root="$PWD/root"
diff --git a/nixpkgs/nixos/lib/make-ext4-fs.nix b/nixpkgs/nixos/lib/make-ext4-fs.nix
index 694142a5123a..47c6374c81ad 100644
--- a/nixpkgs/nixos/lib/make-ext4-fs.nix
+++ b/nixpkgs/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/nixpkgs/nixos/lib/make-squashfs.nix b/nixpkgs/nixos/lib/make-squashfs.nix
index 7ab84e47f53b..ee76c9c5bf24 100644
--- a/nixpkgs/nixos/lib/make-squashfs.nix
+++ b/nixpkgs/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/nixpkgs/nixos/lib/test-driver/Logger.pm b/nixpkgs/nixos/lib/test-driver/Logger.pm
index 3fe5ef67c144..080310ea34e0 100644
--- a/nixpkgs/nixos/lib/test-driver/Logger.pm
+++ b/nixpkgs/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/nixpkgs/nixos/lib/test-driver/Machine.pm b/nixpkgs/nixos/lib/test-driver/Machine.pm
index a00fe25c2b8e..006da889671e 100644
--- a/nixpkgs/nixos/lib/test-driver/Machine.pm
+++ b/nixpkgs/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'};
@@ -155,10 +156,8 @@ sub start {
         $ENV{USE_TMPDIR} = 1;
         $ENV{QEMU_OPTS} =
             ($self->{allowReboot} ? "" : "-no-reboot ") .
-            "-monitor unix:./monitor " .
-            "-chardev socket,id=shell,path=./shell -device virtio-serial -device virtconsole,chardev=shell " .
-            # socket backdoor, see "Debugging NixOS tests" section in NixOS manual
-            "-chardev socket,id=backdoor,path=./backdoor,server,nowait -device virtio-serial -device virtconsole,chardev=backdoor " .
+            "-monitor unix:./monitor -chardev socket,id=shell,path=./shell " .
+            "-device virtio-serial -device virtconsole,chardev=shell " .
             "-device virtio-rng-pci " .
             ($showGraphics ? "-serial stdio" : "-nographic") . " " . ($ENV{QEMU_OPTS} || "");
         chdir $self->{stateDir} or die;
@@ -249,12 +248,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/nixpkgs/nixos/lib/testing.nix b/nixpkgs/nixos/lib/testing.nix
index c0b4041d7e30..a13e76a69560 100644
--- a/nixpkgs/nixos/lib/testing.nix
+++ b/nixpkgs/nixos/lib/testing.nix
@@ -3,7 +3,7 @@
   # Use a minimal kernel?
 , minimal ? false
   # Ignored
-, config ? null
+, config ? {}
   # Modules to add to each VM
 , extraConfigurations ? [] }:
 
@@ -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/nixpkgs/nixos/modules/config/ldap.nix b/nixpkgs/nixos/modules/config/ldap.nix
index 0693e896f715..f65a3fc50d54 100644
--- a/nixpkgs/nixos/modules/config/ldap.nix
+++ b/nixpkgs/nixos/modules/config/ldap.nix
@@ -38,6 +38,8 @@ let
       bind_timelimit ${toString cfg.bind.timeLimit}
       ${optionalString (cfg.bind.distinguishedName != "")
         "binddn ${cfg.bind.distinguishedName}" }
+      ${optionalString (cfg.daemon.rootpwmoddn != "")
+        "rootpwmoddn ${cfg.daemon.rootpwmoddn}" }
       ${optionalString (cfg.daemon.extraConfig != "") cfg.daemon.extraConfig }
     '';
   };
@@ -126,6 +128,26 @@ in
             the end of the nslcd configuration file (nslcd.conf).
           '' ;
         } ;
+
+        rootpwmoddn = mkOption {
+          default = "";
+          example = "cn=admin,dc=example,dc=com";
+          type = types.str;
+          description = ''
+            The distinguished name to use to bind to the LDAP server
+            when the root user tries to modify a user's password.
+          '';
+        };
+
+        rootpwmodpw = mkOption {
+          default = "";
+          example = "/run/keys/nslcd.rootpwmodpw";
+          type = types.str;
+          description = ''
+            The path to a file containing the credentials with which
+            to bind to the LDAP server if the root user tries to change a user's password
+          '';
+        };
       };
 
       bind = {
@@ -203,9 +225,11 @@ in
     system.activationScripts = mkIf insertLdapPassword {
       ldap = stringAfter [ "etc" "groups" "users" ] ''
         if test -f "${cfg.bind.password}" ; then
-          echo "bindpw "$(cat ${cfg.bind.password})"" | cat ${ldapConfig.source} - > /etc/ldap.conf.bindpw
-          mv -fT /etc/ldap.conf.bindpw /etc/ldap.conf
-          chmod 600 /etc/ldap.conf
+          umask 0077
+          conf="$(mktemp)"
+          printf 'bindpw %s\n' "$(cat ${cfg.bind.password})" |
+          cat ${ldapConfig.source} - >"$conf"
+          mv -fT "$conf" /etc/ldap.conf
         fi
       '';
     };
@@ -232,21 +256,31 @@ in
         wantedBy = [ "multi-user.target" ];
 
         preStart = ''
-          mkdir -p /run/nslcd
-          rm -f /run/nslcd/nslcd.pid;
-          chown nslcd.nslcd /run/nslcd
-          ${optionalString (cfg.bind.distinguishedName != "") ''
-            if test -s "${cfg.bind.password}" ; then
-              ln -sfT "${cfg.bind.password}" /run/nslcd/bindpw
-            fi
-          ''}
+          umask 0077
+          conf="$(mktemp)"
+          {
+            cat ${nslcdConfig.source}
+            test -z '${cfg.bind.distinguishedName}' -o ! -f '${cfg.bind.password}' ||
+            printf 'bindpw %s\n' "$(cat '${cfg.bind.password}')"
+            test -z '${cfg.daemon.rootpwmoddn}' -o ! -f '${cfg.daemon.rootpwmodpw}' ||
+            printf 'rootpwmodpw %s\n' "$(cat '${cfg.daemon.rootpwmodpw}')"
+          } >"$conf"
+          mv -fT "$conf" /etc/nslcd.conf
         '';
 
+        # NOTE: because one cannot pass a custom config path to `nslcd`
+        # (which is only able to use `/etc/nslcd.conf`)
+        # changes in `nslcdConfig` won't change `serviceConfig`,
+        # and thus won't restart `nslcd`.
+        # Therefore `restartTriggers` is used on `/etc/nslcd.conf`.
+        restartTriggers = [ nslcdConfig.source ];
+
         serviceConfig = {
           ExecStart = "${nss_pam_ldapd}/sbin/nslcd";
           Type = "forking";
           PIDFile = "/run/nslcd/nslcd.pid";
           Restart = "always";
+          RuntimeDirectory = [ "nslcd" ];
         };
       };
 
diff --git a/nixpkgs/nixos/modules/config/pulseaudio.nix b/nixpkgs/nixos/modules/config/pulseaudio.nix
index 67f7105fe2fe..e61a3a731201 100644
--- a/nixpkgs/nixos/modules/config/pulseaudio.nix
+++ b/nixpkgs/nixos/modules/config/pulseaudio.nix
@@ -180,7 +180,7 @@ in {
           type = types.attrsOf types.unspecified;
           default = {};
           description = ''Config of the pulse daemon. See <literal>man pulse-daemon.conf</literal>.'';
-          example = literalExample ''{ flat-volumes = "no"; }'';
+          example = literalExample ''{ realtime-scheduling = "yes"; }'';
         };
       };
 
@@ -242,6 +242,9 @@ in {
           source = writeText "libao.conf" "default_driver=pulse"; }
       ];
 
+      # Disable flat volumes to enable relative ones
+      hardware.pulseaudio.daemon.config.flat-volumes = mkDefault "no";
+
       # Allow PulseAudio to get realtime priority using rtkit.
       security.rtkit.enable = true;
 
diff --git a/nixpkgs/nixos/modules/config/system-path.nix b/nixpkgs/nixos/modules/config/system-path.nix
index aece7aa67ac3..7a65e44e828d 100644
--- a/nixpkgs/nixos/modules/config/system-path.nix
+++ b/nixpkgs/nixos/modules/config/system-path.nix
@@ -7,7 +7,7 @@ with lib;
 
 let
 
-  requiredPackages =
+  requiredPackages = map lib.lowPrio
     [ config.nix.package
       pkgs.acl
       pkgs.attr
diff --git a/nixpkgs/nixos/modules/config/users-groups.nix b/nixpkgs/nixos/modules/config/users-groups.nix
index 137ee243813d..c3f228c9bcc4 100644
--- a/nixpkgs/nixos/modules/config/users-groups.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/config/zram.nix b/nixpkgs/nixos/modules/config/zram.nix
index c1748812821e..925d945c081e 100644
--- a/nixpkgs/nixos/modules/config/zram.nix
+++ b/nixpkgs/nixos/modules/config/zram.nix
@@ -6,10 +6,27 @@ let
 
   cfg = config.zramSwap;
 
-  devices = map (nr: "zram${toString nr}") (range 0 (cfg.numDevices - 1));
+  # don't set swapDevices as mkDefault, so we can detect user had read our warning
+  # (see below) and made an action (or not)
+  devicesCount = if cfg.swapDevices != null then cfg.swapDevices else cfg.numDevices;
+
+  devices = map (nr: "zram${toString nr}") (range 0 (devicesCount - 1));
 
   modprobe = "${pkgs.kmod}/bin/modprobe";
 
+  warnings =
+  assert cfg.swapDevices != null -> cfg.numDevices >= cfg.swapDevices;
+  flatten [
+    (optional (cfg.numDevices > 1 && cfg.swapDevices == null) ''
+      Using several small zram devices as swap is no better than using one large.
+      Set either zramSwap.numDevices = 1 or explicitly set zramSwap.swapDevices.
+
+      Previously multiple zram devices were used to enable multithreaded
+      compression. Linux supports multithreaded compression for 1 device
+      since 3.15. See https://lkml.org/lkml/2014/2/28/404 for details.
+    '')
+  ];
+
 in
 
 {
@@ -24,9 +41,11 @@ in
         default = false;
         type = types.bool;
         description = ''
-          Enable in-memory compressed swap space provided by the zram kernel
-          module.
-          See https://www.kernel.org/doc/Documentation/blockdev/zram.txt
+          Enable in-memory compressed devices and swap space provided by the zram
+          kernel module.
+          See <link xlink:href="https://www.kernel.org/doc/Documentation/blockdev/zram.txt">
+            https://www.kernel.org/doc/Documentation/blockdev/zram.txt
+          </link>.
         '';
       };
 
@@ -34,7 +53,19 @@ in
         default = 1;
         type = types.int;
         description = ''
-          Number of zram swap devices to create.
+          Number of zram devices to create. See also
+          <literal>zramSwap.swapDevices</literal>
+        '';
+      };
+
+      swapDevices = mkOption {
+        default = null;
+        example = 1;
+        type = with types; nullOr int;
+        description = ''
+          Number of zram devices to be used as swap. Must be
+          <literal>&lt;= zramSwap.numDevices</literal>.
+          Default is same as <literal>zramSwap.numDevices</literal>, recommended is 1.
         '';
       };
 
@@ -44,7 +75,8 @@ in
         description = ''
           Maximum amount of memory that can be used by the zram swap devices
           (as a percentage of your total memory). Defaults to 1/2 of your total
-          RAM.
+          RAM. Run <literal>zramctl</literal> to check how good memory is
+          compressed.
         '';
       };
 
@@ -58,12 +90,26 @@ in
         '';
       };
 
+      algorithm = mkOption {
+        default = "zstd";
+        example = "lzo";
+        type = with types; either (enum [ "lzo" "lz4" "zstd" ]) str;
+        description = ''
+          Compression algorithm. <literal>lzo</literal> has good compression,
+          but is slow. <literal>lz4</literal> has bad compression, but is fast.
+          <literal>zstd</literal> is both good compression and fast.
+          You can check what other algorithms are supported by your zram device with
+          <programlisting>cat /sys/class/block/zram*/comp_algorithm</programlisting>
+        '';
+      };
     };
 
   };
 
   config = mkIf cfg.enable {
 
+    inherit warnings;
+
     system.requiredKernelConfig = with config.lib.kernelConfig; [
       (isModule "ZRAM")
     ];
@@ -85,25 +131,25 @@ in
         createZramInitService = dev:
           nameValuePair "zram-init-${dev}" {
             description = "Init swap on zram-based device ${dev}";
-            bindsTo = [ "dev-${dev}.swap" ];
             after = [ "dev-${dev}.device" "zram-reloader.service" ];
             requires = [ "dev-${dev}.device" "zram-reloader.service" ];
             before = [ "dev-${dev}.swap" ];
             requiredBy = [ "dev-${dev}.swap" ];
+            unitConfig.DefaultDependencies = false; # needed to prevent a cycle
             serviceConfig = {
               Type = "oneshot";
               RemainAfterExit = true;
               ExecStop = "${pkgs.runtimeShell} -c 'echo 1 > /sys/class/block/${dev}/reset'";
             };
             script = ''
-              set -u
-              set -o pipefail
-              
+              set -euo pipefail
+
               # Calculate memory to use for zram
-              totalmem=$(${pkgs.gnugrep}/bin/grep 'MemTotal: ' /proc/meminfo | ${pkgs.gawk}/bin/awk '{print $2}')
-              mem=$(((totalmem * ${toString cfg.memoryPercent} / 100 / ${toString cfg.numDevices}) * 1024))
+              mem=$(${pkgs.gawk}/bin/awk '/MemTotal: / {
+                  print int($2*${toString cfg.memoryPercent}/100.0/${toString devicesCount}*1024)
+              }' /proc/meminfo)
 
-              echo $mem > /sys/class/block/${dev}/disksize
+              ${pkgs.utillinux}/sbin/zramctl --size $mem --algorithm ${cfg.algorithm} /dev/${dev}
               ${pkgs.utillinux}/sbin/mkswap /dev/${dev}
             '';
             restartIfChanged = false;
@@ -111,6 +157,9 @@ in
       in listToAttrs ((map createZramInitService devices) ++ [(nameValuePair "zram-reloader"
         {
           description = "Reload zram kernel module when number of devices changes";
+          wants = [ "systemd-udevd.service" ];
+          after = [ "systemd-udevd.service" ];
+          unitConfig.DefaultDependencies = false; # needed to prevent a cycle
           serviceConfig = {
             Type = "oneshot";
             RemainAfterExit = true;
@@ -118,7 +167,11 @@ in
             ExecStart = "${modprobe} zram";
             ExecStop = "${modprobe} -r zram";
           };
-          restartTriggers = [ cfg.numDevices ];
+          restartTriggers = [
+            cfg.numDevices
+            cfg.algorithm
+            cfg.memoryPercent
+          ];
           restartIfChanged = true;
         })]);
 
diff --git a/nixpkgs/nixos/modules/hardware/all-firmware.nix b/nixpkgs/nixos/modules/hardware/all-firmware.nix
index e978ec6b40ad..69cc22aaa34b 100644
--- a/nixpkgs/nixos/modules/hardware/all-firmware.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/hardware/opengl.nix b/nixpkgs/nixos/modules/hardware/opengl.nix
index 48e0072e0892..6b7b8069fd44 100644
--- a/nixpkgs/nixos/modules/hardware/opengl.nix
+++ b/nixpkgs/nixos/modules/hardware/opengl.nix
@@ -124,10 +124,14 @@ in
 
   config = mkIf cfg.enable {
 
-    assertions = lib.singleton {
-      assertion = cfg.driSupport32Bit -> pkgs.stdenv.isx86_64;
-      message = "Option driSupport32Bit only makes sense on a 64-bit system.";
-    };
+    assertions = [
+      { assertion = cfg.driSupport32Bit -> pkgs.stdenv.isx86_64;
+        message = "Option driSupport32Bit only makes sense on a 64-bit system.";
+      }
+      { assertion = cfg.driSupport32Bit -> (config.boot.kernelPackages.kernel.features.ia32Emulation or false);
+        message = "Option driSupport32Bit requires a kernel that supports 32bit emulation";
+      }
+    ];
 
     systemd.tmpfiles.rules = [
       "L+ /run/opengl-driver - - - - ${package}"
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/channel.nix b/nixpkgs/nixos/modules/installer/cd-dvd/channel.nix
index 01cfe8a02e10..e946c4abc576 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/channel.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix b/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
index 9475da23b1ff..e78e290e7438 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -339,11 +339,11 @@ let
     #   dates (cp -p, touch, mcopy -m, faketime for label), IDs (mkfs.vfat -i)
     ''
       mkdir ./contents && cd ./contents
-      cp -rp "${efiDir}"/* .
+      cp -rp "${efiDir}"/EFI .
       mkdir ./boot
       cp -p "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}" \
         "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}" ./boot/
-      touch --date=@0 ./*
+      touch --date=@0 ./EFI ./boot
 
       usage_size=$(du -sb --apparent-size . | tr -cd '[:digit:]')
       # Make the image 110% as big as the files need to make up for FAT overhead
@@ -355,7 +355,7 @@ let
       echo "Image size: $image_size"
       truncate --size=$image_size "$out"
       ${pkgs.libfaketime}/bin/faketime "2000-01-01 00:00:00" ${pkgs.dosfstools}/sbin/mkfs.vfat -i 12345678 -n EFIBOOT "$out"
-      mcopy -psvm -i "$out" ./* ::
+      mcopy -psvm -i "$out" ./EFI ./boot ::
       # Verify the FAT partition.
       ${pkgs.dosfstools}/sbin/fsck.vfat -vn "$out"
     ''; # */
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix b/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix
index 2db71eb20c5d..5f7194e92a36 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix b/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
index 695c79ca1707..71448f74c361 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix b/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
index e395b265d15e..96e06670694e 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix b/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix
index 1cfc8ff8612e..5d431df4b114 100644
--- a/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl b/nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl
index 52a129b39bcd..3bcf90258d79 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -340,6 +340,8 @@ foreach my $fs (read_file("/proc/self/mountinfo")) {
     chomp $fs;
     my @fields = split / /, $fs;
     my $mountPoint = $fields[4];
+    $mountPoint =~ s/\\040/ /g; # account for mount points with spaces in the name (\040 is the escape character)
+    $mountPoint =~ s/\\011/\t/g; # account for mount points with tabs in the name (\011 is the escape character)
     next unless -d $mountPoint;
     my @mountOptions = split /,/, $fields[5];
 
@@ -355,6 +357,8 @@ foreach my $fs (read_file("/proc/self/mountinfo")) {
     my $fsType = $fields[$n];
     my $device = $fields[$n + 1];
     my @superOptions = split /,/, $fields[$n + 2];
+    $device =~ s/\\040/ /g; # account for devices with spaces in the name (\040 is the escape character)
+    $device =~ s/\\011/\t/g; # account for mount points with tabs in the name (\011 is the escape character)
 
     # Skip the read-only bind-mount on /nix/store.
     next if $mountPoint eq "/nix/store" && (grep { $_ eq "rw" } @superOptions) && (grep { $_ eq "ro" } @mountOptions);
@@ -449,7 +453,11 @@ EOF
                 if (-e $slave) {
                     my $dmName = read_file("/sys/class/block/$deviceName/dm/name");
                     chomp $dmName;
-                    $fileSystems .= "  boot.initrd.luks.devices.\"$dmName\".device = \"${\(findStableDevPath $slave)}\";\n\n";
+                    # Ensure to add an entry only once
+                    my $luksDevice = "  boot.initrd.luks.devices.\"$dmName\".device";
+                    if ($fileSystems !~ /^\Q$luksDevice\E/m) {
+                        $fileSystems .= "$luksDevice = \"${\(findStableDevPath $slave)}\";\n\n";
+                    }
                 }
             }
         }
@@ -631,9 +639,10 @@ $bootLoaderConfig
   # services.xserver.desktopManager.plasma5.enable = true;
 
   # Define a user account. Don't forget to set a password with ‘passwd’.
-  # users.users.guest = {
+  # users.users.jane = {
   #   isNormalUser = true;
   #   uid = 1000;
+  #   extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
   # };
 
   # This value determines the NixOS release with which your system is to be
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-option.sh b/nixpkgs/nixos/modules/installer/tools/nixos-option.sh
index 327e3e6989f7..4560e9c7403a 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-option.sh
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-option.sh
@@ -314,13 +314,13 @@ else
   # echo 1>&2 "Warning: This value is not an option."
 
   result=$(evalCfg "")
-  if names=$(attrNames "$result" 2> /dev/null); then
+  if [ ! -z "$result" ]; then
+    names=$(attrNames "$result" 2> /dev/null)
     echo 1>&2 "This attribute set contains:"
     escapeQuotes () { eval echo "$1"; }
     nixMap escapeQuotes "$names"
   else
-    echo 1>&2 "An error occurred while looking for attribute names."
-    echo $result
+    echo 1>&2 "An error occurred while looking for attribute names. Are you sure that '$option' exists?"
   fi
 fi
 
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh b/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh
index 2af73519bc52..361c2e49e05c 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh
+++ b/nixpkgs/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/nixpkgs/nixos/modules/installer/tools/tools.nix b/nixpkgs/nixos/modules/installer/tools/tools.nix
index af0a3a2fcc88..00c4d5018bf5 100644
--- a/nixpkgs/nixos/modules/installer/tools/tools.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/misc/ids.nix b/nixpkgs/nixos/modules/misc/ids.nix
index 5a3f6b199372..1e6eeb22b6b8 100644
--- a/nixpkgs/nixos/modules/misc/ids.nix
+++ b/nixpkgs/nixos/modules/misc/ids.nix
@@ -306,7 +306,7 @@
       rslsync = 279;
       minio = 280;
       kanboard = 281;
-      pykms = 282;
+      # pykms = 282; # DynamicUser = true
       kodi = 283;
       restya-board = 284;
       mighttpd2 = 285;
@@ -338,6 +338,7 @@
       minetest = 311;
       rss2email = 312;
       cockroachdb = 313;
+      zoneminder = 314;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
@@ -604,7 +605,7 @@
       rslsync = 279;
       minio = 280;
       kanboard = 281;
-      pykms = 282;
+      # pykms = 282; # DynamicUser = true
       kodi = 283;
       restya-board = 284;
       mighttpd2 = 285;
@@ -636,6 +637,7 @@
       minetest = 311;
       rss2email = 312;
       cockroachdb = 313;
+      zoneminder = 314;
 
       # When adding a gid, make sure it doesn't match an existing
       # uid. Users and groups with the same name should have equal
diff --git a/nixpkgs/nixos/modules/misc/nixpkgs.nix b/nixpkgs/nixos/modules/misc/nixpkgs.nix
index 93fbf16841e5..3a717fddaba2 100644
--- a/nixpkgs/nixos/modules/misc/nixpkgs.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/misc/version.nix b/nixpkgs/nixos/modules/misc/version.nix
index fd77f6372720..001505320c00 100644
--- a/nixpkgs/nixos/modules/misc/version.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/module-list.nix b/nixpkgs/nixos/modules/module-list.nix
index 4a392b6f5c9c..3ee242ab2226 100644
--- a/nixpkgs/nixos/modules/module-list.nix
+++ b/nixpkgs/nixos/modules/module-list.nix
@@ -248,6 +248,7 @@
   ./services/desktops/gnome3/at-spi2-core.nix
   ./services/desktops/gnome3/chrome-gnome-shell.nix
   ./services/desktops/gnome3/evolution-data-server.nix
+  ./services/desktops/gnome3/file-roller.nix
   ./services/desktops/gnome3/gnome-disks.nix
   ./services/desktops/gnome3/gnome-documents.nix
   ./services/desktops/gnome3/gnome-keyring.nix
@@ -432,6 +433,7 @@
   ./services/misc/uhub.nix
   ./services/misc/weechat.nix
   ./services/misc/xmr-stak.nix
+  ./services/misc/zoneminder.nix
   ./services/misc/zookeeper.nix
   ./services/monitoring/alerta.nix
   ./services/monitoring/apcupsd.nix
@@ -679,6 +681,7 @@
   ./services/security/hologram-server.nix
   ./services/security/hologram-agent.nix
   ./services/security/munge.nix
+  ./services/security/nginx-sso.nix
   ./services/security/oauth2_proxy.nix
   ./services/security/oauth2_proxy_nginx.nix
   ./services/security/physlock.nix
@@ -695,7 +698,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/nixpkgs/nixos/modules/profiles/hardened.nix b/nixpkgs/nixos/modules/profiles/hardened.nix
index a588943fe710..9ab2ee87a19e 100644
--- a/nixpkgs/nixos/modules/profiles/hardened.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/profiles/headless.nix b/nixpkgs/nixos/modules/profiles/headless.nix
index 131ee272859a..46a9b6a7d8d5 100644
--- a/nixpkgs/nixos/modules/profiles/headless.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/profiles/minimal.nix b/nixpkgs/nixos/modules/profiles/minimal.nix
index 138eda117c74..f044e6f39ea5 100644
--- a/nixpkgs/nixos/modules/profiles/minimal.nix
+++ b/nixpkgs/nixos/modules/profiles/minimal.nix
@@ -13,5 +13,5 @@ with lib;
 
   documentation.enable = mkDefault false;
 
-  sound.enable = mkDefault false;
+  documentation.nixos.enable = mkDefault false;
 }
diff --git a/nixpkgs/nixos/modules/programs/command-not-found/command-not-found.nix b/nixpkgs/nixos/modules/programs/command-not-found/command-not-found.nix
index bbe7165c62fb..656c255fcb18 100644
--- a/nixpkgs/nixos/modules/programs/command-not-found/command-not-found.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/programs/nano.nix b/nixpkgs/nixos/modules/programs/nano.nix
index 27b6d446c75d..6a4d46338e19 100644
--- a/nixpkgs/nixos/modules/programs/nano.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/programs/ssh.nix b/nixpkgs/nixos/modules/programs/ssh.nix
index cc398174e6ce..4640c1d78d20 100644
--- a/nixpkgs/nixos/modules/programs/ssh.nix
+++ b/nixpkgs/nixos/modules/programs/ssh.nix
@@ -167,16 +167,16 @@ in
           The set of system-wide known SSH hosts.
         '';
         example = literalExample ''
-          [
-            {
+          {
+            myhost = {
               hostNames = [ "myhost" "myhost.mydomain.com" "10.10.1.4" ];
               publicKeyFile = ./pubkeys/myhost_ssh_host_dsa_key.pub;
-            }
-            {
+            };
+            myhost2 = {
               hostNames = [ "myhost2" ];
               publicKeyFile = ./pubkeys/myhost2_ssh_host_dsa_key.pub;
-            }
-          ]
+            };
+          }
         '';
       };
 
diff --git a/nixpkgs/nixos/modules/programs/sway-beta.nix b/nixpkgs/nixos/modules/programs/sway-beta.nix
index 7fc5979a38aa..3c235de0ce63 100644
--- a/nixpkgs/nixos/modules/programs/sway-beta.nix
+++ b/nixpkgs/nixos/modules/programs/sway-beta.nix
@@ -60,10 +60,11 @@ in {
     extraPackages = mkOption {
       type = with types; listOf package;
       default = with pkgs; [
+        swaylock swayidle
         xwayland rxvt_unicode dmenu
       ];
       defaultText = literalExample ''
-        with pkgs; [ xwayland rxvt_unicode dmenu ];
+        with pkgs; [ swaylock swayidle xwayland rxvt_unicode dmenu ];
       '';
       example = literalExample ''
         with pkgs; [
diff --git a/nixpkgs/nixos/modules/programs/sway.nix b/nixpkgs/nixos/modules/programs/sway.nix
index 0eaaf6b85b99..b3847db8cd9c 100644
--- a/nixpkgs/nixos/modules/programs/sway.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/programs/way-cooler.nix b/nixpkgs/nixos/modules/programs/way-cooler.nix
index 633e959be9f3..f27bd42bd764 100644
--- a/nixpkgs/nixos/modules/programs/way-cooler.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/programs/xss-lock.nix b/nixpkgs/nixos/modules/programs/xss-lock.nix
index 49d522c604f5..c290df01b960 100644
--- a/nixpkgs/nixos/modules/programs/xss-lock.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix b/nixpkgs/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix
index e7cf17c2c00c..89087a229eb7 100644
--- a/nixpkgs/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix
+++ b/nixpkgs/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix
@@ -48,6 +48,23 @@ in
           https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters/pattern.md
         '';
       };
+      styles = mkOption {
+        default = {};
+        type = types.attrsOf types.string;
+
+        example = literalExample ''
+          {
+            "alias" = "fg=magenta,bold";
+          }
+        '';
+
+        description = ''
+          Specifies custom styles to be highlighted by zsh-syntax-highlighting.
+
+          Please refer to the docs for more information about the usage:
+          https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters/main.md
+        '';
+      };
     };
   };
 
@@ -73,6 +90,11 @@ in
             pattern: design:
             "ZSH_HIGHLIGHT_PATTERNS+=('${pattern}' '${design}')"
           ) cfg.patterns)
+        ++ optionals (length(attrNames cfg.styles) > 0)
+          (mapAttrsToList (
+            styles: design:
+            "ZSH_HIGHLIGHT_STYLES[${styles}]='${design}'"
+          ) cfg.styles)
       );
   };
 }
diff --git a/nixpkgs/nixos/modules/rename.nix b/nixpkgs/nixos/modules/rename.nix
index dc0a175d5bb8..24ab963f718a 100644
--- a/nixpkgs/nixos/modules/rename.nix
+++ b/nixpkgs/nixos/modules/rename.nix
@@ -69,6 +69,9 @@ with lib;
     (mkRemovedOptionModule [ "security" "setuidOwners" ] "Use security.wrappers instead")
     (mkRemovedOptionModule [ "security" "setuidPrograms" ] "Use security.wrappers instead")
 
+    # PAM
+    (mkRenamedOptionModule [ "security" "pam" "enableU2F" ] [ "security" "pam" "u2f" "enable" ])
+
     (mkRemovedOptionModule [ "services" "rmilter" "bindInetSockets" ] "Use services.rmilter.bindSocket.* instead")
     (mkRemovedOptionModule [ "services" "rmilter" "bindUnixSockets" ] "Use services.rmilter.bindSocket.* instead")
 
diff --git a/nixpkgs/nixos/modules/security/pam.nix b/nixpkgs/nixos/modules/security/pam.nix
index b1a0eff98c20..206b529ed680 100644
--- a/nixpkgs/nixos/modules/security/pam.nix
+++ b/nixpkgs/nixos/modules/security/pam.nix
@@ -37,12 +37,14 @@ let
       };
 
       u2fAuth = mkOption {
-        default = config.security.pam.enableU2F;
+        default = config.security.pam.u2f.enable;
         type = types.bool;
         description = ''
           If set, users listed in
-          <filename>~/.config/Yubico/u2f_keys</filename> are able to log in
-          with the associated U2F key.
+          <filename>$XDG_CONFIG_HOME/Yubico/u2f_keys</filename> (or
+          <filename>$HOME/.config/Yubico/u2f_keys</filename> if XDG variable is
+          not set) are able to log in with the associated U2F key. Path can be
+          changed using <option>security.pam.u2f.authFile</option> option.
         '';
       };
 
@@ -320,8 +322,8 @@ let
               "auth sufficient ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so file=~/.ssh/authorized_keys:~/.ssh/authorized_keys2:/etc/ssh/authorized_keys.d/%u"}
           ${optionalString cfg.fprintAuth
               "auth sufficient ${pkgs.fprintd}/lib/security/pam_fprintd.so"}
-          ${optionalString cfg.u2fAuth
-              "auth sufficient ${pkgs.pam_u2f}/lib/security/pam_u2f.so"}
+          ${let u2f = config.security.pam.u2f; in optionalString cfg.u2fAuth
+              "auth ${u2f.control} ${pkgs.pam_u2f}/lib/security/pam_u2f.so ${optionalString u2f.debug "debug"} ${optionalString (u2f.authFile != null) "authfile=${u2f.authFile}"} ${optionalString u2f.interactive "interactive"} ${optionalString u2f.cue "cue"}"}
           ${optionalString cfg.usbAuth
               "auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so"}
           ${let oath = config.security.pam.oath; in optionalString cfg.oathAuth
@@ -368,7 +370,7 @@ let
           auth required pam_deny.so
 
           # Password management.
-          password requisite pam_unix.so nullok sha512
+          password sufficient pam_unix.so nullok sha512
           ${optionalString config.security.pam.enableEcryptfs
               "password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
           ${optionalString cfg.pamMount
@@ -527,11 +529,96 @@ in
       '';
     };
 
-    security.pam.enableU2F = mkOption {
-      default = false;
-      description = ''
-        Enable the U2F PAM module.
-      '';
+    security.pam.u2f = {
+      enable = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          Enables U2F PAM (<literal>pam-u2f</literal>) module.
+
+          If set, users listed in
+          <filename>$XDG_CONFIG_HOME/Yubico/u2f_keys</filename> (or
+          <filename>$HOME/.config/Yubico/u2f_keys</filename> if XDG variable is
+          not set) are able to log in with the associated U2F key. The path can
+          be changed using <option>security.pam.u2f.authFile</option> option.
+
+          File format is:
+          <literal>username:first_keyHandle,first_public_key: second_keyHandle,second_public_key</literal>
+          This file can be generated using <command>pamu2fcfg</command> command.
+
+          More information can be found <link
+          xlink:href="https://developers.yubico.com/pam-u2f/">here</link>.
+        '';
+      };
+
+      authFile = mkOption {
+        default = null;
+        type = with types; nullOr path;
+        description = ''
+          By default <literal>pam-u2f</literal> module reads the keys from
+          <filename>$XDG_CONFIG_HOME/Yubico/u2f_keys</filename> (or
+          <filename>$HOME/.config/Yubico/u2f_keys</filename> if XDG variable is
+          not set).
+
+          If you want to change auth file locations or centralize database (for
+          example use <filename>/etc/u2f-mappings</filename>) you can set this
+          option.
+
+          File format is:
+          <literal>username:first_keyHandle,first_public_key: second_keyHandle,second_public_key</literal>
+          This file can be generated using <command>pamu2fcfg</command> command.
+
+          More information can be found <link
+          xlink:href="https://developers.yubico.com/pam-u2f/">here</link>.
+        '';
+      };
+
+      control = mkOption {
+        default = "sufficient";
+        type = types.enum [ "required" "requisite" "sufficient" "optional" ];
+        description = ''
+          This option sets pam "control".
+          If you want to have multi factor authentication, use "required".
+          If you want to use U2F device instead of regular password, use "sufficient".
+
+          Read
+          <citerefentry>
+            <refentrytitle>pam.conf</refentrytitle>
+            <manvolnum>5</manvolnum>
+          </citerefentry>
+          for better understanding of this option.
+        '';
+      };
+
+      debug = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          Debug output to stderr.
+        '';
+      };
+
+      interactive = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          Set to prompt a message and wait before testing the presence of a U2F device.
+          Recommended if your device doesn’t have a tactile trigger.
+        '';
+      };
+
+      cue = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          By default <literal>pam-u2f</literal> module does not inform user
+          that he needs to use the u2f device, it just waits without a prompt.
+
+          If you set this option to <literal>true</literal>,
+          <literal>cue</literal> option is added to <literal>pam-u2f</literal>
+          module and reminder message will be displayed.
+        '';
+      };
     };
 
     security.pam.enableEcryptfs = mkOption {
@@ -563,7 +650,7 @@ in
       ++ optionals config.krb5.enable [pam_krb5 pam_ccreds]
       ++ optionals config.security.pam.enableOTPW [ pkgs.otpw ]
       ++ optionals config.security.pam.oath.enable [ pkgs.oathToolkit ]
-      ++ optionals config.security.pam.enableU2F [ pkgs.pam_u2f ];
+      ++ optionals config.security.pam.u2f.enable [ pkgs.pam_u2f ];
 
     boot.supportedFilesystems = optionals config.security.pam.enableEcryptfs [ "ecryptfs" ];
 
diff --git a/nixpkgs/nixos/modules/services/backup/borgbackup.nix b/nixpkgs/nixos/modules/services/backup/borgbackup.nix
index bf41aee8fe0e..2ad116a7872a 100644
--- a/nixpkgs/nixos/modules/services/backup/borgbackup.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/backup/postgresql-backup.nix b/nixpkgs/nixos/modules/services/backup/postgresql-backup.nix
index f9f9568faa5c..11efa47ec5b2 100644
--- a/nixpkgs/nixos/modules/services/backup/postgresql-backup.nix
+++ b/nixpkgs/nixos/modules/services/backup/postgresql-backup.nix
@@ -6,11 +6,11 @@ let
 
   cfg = config.services.postgresqlBackup;
 
-  postgresqlBackupService = db :
+  postgresqlBackupService = db: dumpCmd:
     {
       enable = true;
 
-      description = "Backup of database ${db}";
+      description = "Backup of ${db} database(s)";
 
       requires = [ "postgresql.service" ];
 
@@ -26,7 +26,7 @@ let
           ${pkgs.coreutils}/bin/mv ${cfg.location}/${db}.sql.gz ${cfg.location}/${db}.prev.sql.gz
         fi
 
-        ${config.services.postgresql.package}/bin/pg_dump ${cfg.pgdumpOptions} ${db} | \
+        ${dumpCmd} | \
           ${pkgs.gzip}/bin/gzip -c > ${cfg.location}/${db}.sql.gz
       '';
 
@@ -42,9 +42,7 @@ let
 in {
 
   options = {
-
     services.postgresqlBackup = {
-
       enable = mkOption {
         default = false;
         description = ''
@@ -61,6 +59,19 @@ in {
         '';
       };
 
+      backupAll = mkOption {
+        default = cfg.databases == [];
+        defaultText = "services.postgresqlBackup.databases == []";
+        type = lib.types.bool;
+        description = ''
+          Backup all databases using pg_dumpall.
+          This option is mutual exclusive to
+          <literal>services.postgresqlBackup.databases</literal>.
+          The resulting backup dump will have the name all.sql.gz.
+          This option is the default if no databases are specified.
+        '';
+      };
+
       databases = mkOption {
         default = [];
         description = ''
@@ -79,18 +90,36 @@ in {
         type = types.string;
         default = "-Cbo";
         description = ''
-          Command line options for pg_dump.
+          Command line options for pg_dump. This options is not used
+          if <literal>config.services.postgresqlBackup.backupAll</literal> is enabled.
+          Note that config.services.postgresqlBackup.backupAll is also active,
+          when no databases where specified.
         '';
       };
     };
 
   };
 
-  config = mkIf config.services.postgresqlBackup.enable {
-
-    systemd.services = listToAttrs (map (db : {
+  config = mkMerge [
+    {
+      assertions = [{
+        assertion = cfg.backupAll -> cfg.databases == [];
+        message = "config.services.postgresqlBackup.backupAll cannot be used together with config.services.postgresqlBackup.databases";
+      }];
+    }
+    (mkIf (cfg.enable && cfg.backupAll) {
+      systemd.services.postgresqlBackup =
+        postgresqlBackupService "all" "${config.services.postgresql.package}/bin/pg_dumpall";
+    })
+    (mkIf (cfg.enable && !cfg.backupAll) {
+      systemd.services = listToAttrs (map (db:
+        let
+          cmd = "${config.services.postgresql.package}/bin/pg_dump ${cfg.pgdumpOptions} ${db}";
+        in {
           name = "postgresqlBackup-${db}";
-          value = postgresqlBackupService db; } ) cfg.databases);
-  };
+          value = postgresqlBackupService db cmd;
+        }) cfg.databases);
+    })
+  ];
 
 }
diff --git a/nixpkgs/nixos/modules/services/backup/restic.nix b/nixpkgs/nixos/modules/services/backup/restic.nix
index 6ece5a9b5ad6..7e8e91e4b9c3 100644
--- a/nixpkgs/nixos/modules/services/backup/restic.nix
+++ b/nixpkgs/nixos/modules/services/backup/restic.nix
@@ -1,6 +1,11 @@
 { config, lib, pkgs, ... }:
 
 with lib;
+
+let
+  # Type for a valid systemd unit option. Needed for correctly passing "timerConfig" to "systemd.timers"
+  unitOption = (import ../../system/boot/systemd-unit-options.nix { inherit config lib; }).unitOption;
+in
 {
   options.services.restic.backups = mkOption {
     description = ''
@@ -47,7 +52,7 @@ with lib;
         };
 
         timerConfig = mkOption {
-          type = types.attrsOf types.str;
+          type = types.attrsOf unitOption;
           default = {
             OnCalendar = "daily";
           };
diff --git a/nixpkgs/nixos/modules/services/databases/cassandra.nix b/nixpkgs/nixos/modules/services/databases/cassandra.nix
index 86e74d5d5ab4..d741ee48c48f 100644
--- a/nixpkgs/nixos/modules/services/databases/cassandra.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/databases/mysql.nix b/nixpkgs/nixos/modules/services/databases/mysql.nix
index df6f3876585e..467feb09b3a3 100644
--- a/nixpkgs/nixos/modules/services/databases/mysql.nix
+++ b/nixpkgs/nixos/modules/services/databases/mysql.nix
@@ -249,6 +249,7 @@ in
 
         after = [ "network.target" ];
         wantedBy = [ "multi-user.target" ];
+        restartTriggers = [ config.environment.etc."my.cnf".source ];
 
         unitConfig.RequiresMountsFor = "${cfg.dataDir}";
 
@@ -274,7 +275,8 @@ in
         serviceConfig = {
           Type = if hasNotify then "notify" else "simple";
           RuntimeDirectory = "mysqld";
-          ExecStart = "${mysql}/bin/mysqld --defaults-file=/etc/my.cnf ${mysqldOptions}";
+          # The last two environment variables are used for starting Galera clusters
+          ExecStart = "${mysql}/bin/mysqld --defaults-file=/etc/my.cnf ${mysqldOptions} $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION";
         };
 
         postStart = ''
@@ -362,7 +364,7 @@ in
             ${optionalString (cfg.ensureDatabases != []) ''
               (
               ${concatMapStrings (database: ''
-                echo "CREATE DATABASE IF NOT EXISTS ${database};"
+                echo "CREATE DATABASE IF NOT EXISTS \`${database}\`;"
               '') cfg.ensureDatabases}
               ) | ${mysql}/bin/mysql -u root -N
             ''}
diff --git a/nixpkgs/nixos/modules/services/desktops/gnome3/file-roller.nix b/nixpkgs/nixos/modules/services/desktops/gnome3/file-roller.nix
new file mode 100644
index 000000000000..7fb558a98953
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/desktops/gnome3/file-roller.nix
@@ -0,0 +1,32 @@
+# File Roller.
+
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.gnome3.file-roller = {
+
+      enable = mkEnableOption "File Roller, an archive manager for GNOME";
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf config.services.gnome3.file-roller.enable {
+
+    environment.systemPackages = [ pkgs.gnome3.file-roller ];
+
+    services.dbus.packages = [ pkgs.gnome3.file-roller ];
+
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/services/desktops/gnome3/gnome-keyring.nix b/nixpkgs/nixos/modules/services/desktops/gnome3/gnome-keyring.nix
index aa1165ab3bba..5ea4350be5b4 100644
--- a/nixpkgs/nixos/modules/services/desktops/gnome3/gnome-keyring.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/games/minecraft-server.nix b/nixpkgs/nixos/modules/services/games/minecraft-server.nix
index f50d2897843a..7d26d1501650 100644
--- a/nixpkgs/nixos/modules/services/games/minecraft-server.nix
+++ b/nixpkgs/nixos/modules/services/games/minecraft-server.nix
@@ -4,8 +4,41 @@ with lib;
 
 let
   cfg = config.services.minecraft-server;
-in
-{
+
+  # We don't allow eula=false anyways
+  eulaFile = builtins.toFile "eula.txt" ''
+    # eula.txt managed by NixOS Configuration
+    eula=true
+  '';
+
+  whitelistFile = pkgs.writeText "whitelist.json"
+    (builtins.toJSON
+      (mapAttrsToList (n: v: { name = n; uuid = v; }) cfg.whitelist));
+
+  cfgToString = v: if builtins.isBool v then boolToString v else toString v;
+
+  serverPropertiesFile = pkgs.writeText "server.properties" (''
+    # server.properties managed by NixOS configuration
+  '' + concatStringsSep "\n" (mapAttrsToList
+    (n: v: "${n}=${cfgToString v}") cfg.serverProperties));
+
+
+  # To be able to open the firewall, we need to read out port values in the
+  # server properties, but fall back to the defaults when those don't exist.
+  # These defaults are from https://minecraft.gamepedia.com/Server.properties#Java_Edition_3
+  defaultServerPort = 25565;
+
+  serverPort = cfg.serverProperties.server-port or defaultServerPort;
+
+  rconPort = if cfg.serverProperties.enable-rcon or false
+    then cfg.serverProperties."rcon.port" or 25575
+    else null;
+
+  queryPort = if cfg.serverProperties.enable-query or false
+    then cfg.serverProperties."query.port" or 25565
+    else null;
+
+in {
   options = {
     services.minecraft-server = {
 
@@ -13,10 +46,32 @@ in
         type = types.bool;
         default = false;
         description = ''
-          If enabled, start a Minecraft Server. The listening port for
-          the server is always <literal>25565</literal>. The server
+          If enabled, start a Minecraft Server. The server
           data will be loaded from and saved to
-          <literal>${cfg.dataDir}</literal>.
+          <option>services.minecraft-server.dataDir</option>.
+        '';
+      };
+
+      declarative = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to use a declarative Minecraft server configuration.
+          Only if set to <literal>true</literal>, the options
+          <option>services.minecraft-server.whitelist</option> and
+          <option>services.minecraft-server.serverProperties</option> will be
+          applied.
+        '';
+      };
+
+      eula = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether you agree to
+          <link xlink:href="https://account.mojang.com/documents/minecraft_eula">
+          Mojangs EULA</link>. This option must be set to
+          <literal>true</literal> to run Minecraft server.
         '';
       };
 
@@ -24,7 +79,7 @@ in
         type = types.path;
         default = "/var/lib/minecraft";
         description = ''
-          Directory to store minecraft database and other state/data files.
+          Directory to store Minecraft database and other state/data files.
         '';
       };
 
@@ -32,21 +87,84 @@ in
         type = types.bool;
         default = false;
         description = ''
-          Whether to open ports in the firewall (if enabled) for the server.
+          Whether to open ports in the firewall for the server.
+        '';
+      };
+
+      whitelist = mkOption {
+        type = let
+          minecraftUUID = types.strMatching
+            "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" // {
+              description = "Minecraft UUID";
+            };
+          in types.attrsOf minecraftUUID;
+        default = {};
+        description = ''
+          Whitelisted players, only has an effect when
+          <option>services.minecraft-server.declarative</option> is
+          <literal>true</literal> and the whitelist is enabled
+          via <option>services.minecraft-server.serverProperties</option> by
+          setting <literal>white-list</literal> to <literal>true</literal>.
+          This is a mapping from Minecraft usernames to UUIDs.
+          You can use <link xlink:href="https://mcuuid.net/"/> to get a
+          Minecraft UUID for a username.
+        '';
+        example = literalExample ''
+          {
+            username1 = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
+            username2 = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy";
+          };
+        '';
+      };
+
+      serverProperties = mkOption {
+        type = with types; attrsOf (either bool (either int str));
+        default = {};
+        example = literalExample ''
+          {
+            server-port = 43000;
+            difficulty = 3;
+            gamemode = 1;
+            max-players = 5;
+            motd = "NixOS Minecraft server!";
+            white-list = true;
+            enable-rcon = true;
+            "rcon.password" = "hunter2";
+          }
+        '';
+        description = ''
+          Minecraft server properties for the server.properties file. Only has
+          an effect when <option>services.minecraft-server.declarative</option>
+          is set to <literal>true</literal>. See
+          <link xlink:href="https://minecraft.gamepedia.com/Server.properties#Java_Edition_3"/>
+          for documentation on these values.
         '';
       };
 
+      package = mkOption {
+        type = types.package;
+        default = pkgs.minecraft-server;
+        defaultText = "pkgs.minecraft-server";
+        example = literalExample "pkgs.minecraft-server_1_12_2";
+        description = "Version of minecraft-server to run.";
+      };
+
       jvmOpts = mkOption {
-        type = types.str;
+        type = types.separatedString " ";
         default = "-Xmx2048M -Xms2048M";
-        description = "JVM options for the Minecraft Service.";
+        # Example options from https://minecraft.gamepedia.com/Tutorials/Server_startup_script
+        example = "-Xmx2048M -Xms4092M -XX:+UseG1GC -XX:+CMSIncrementalPacing "
+          + "-XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=2 "
+          + "-XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10";
+        description = "JVM options for the Minecraft server.";
       };
     };
   };
 
   config = mkIf cfg.enable {
+
     users.users.minecraft = {
-      description     = "Minecraft Server Service user";
+      description     = "Minecraft server service user";
       home            = cfg.dataDir;
       createHome      = true;
       uid             = config.ids.uids.minecraft;
@@ -57,17 +175,60 @@ in
       wantedBy      = [ "multi-user.target" ];
       after         = [ "network.target" ];
 
-      serviceConfig.Restart = "always";
-      serviceConfig.User    = "minecraft";
-      script = ''
-        cd ${cfg.dataDir}
-        exec ${pkgs.minecraft-server}/bin/minecraft-server ${cfg.jvmOpts}
-      '';
-    };
+      serviceConfig = {
+        ExecStart = "${cfg.package}/bin/minecraft-server ${cfg.jvmOpts}";
+        Restart = "always";
+        User = "minecraft";
+        WorkingDirectory = cfg.dataDir;
+      };
+
+      preStart = ''
+        ln -sf ${eulaFile} eula.txt
+      '' + (if cfg.declarative then ''
+
+        if [ -e .declarative ]; then
+
+          # Was declarative before, no need to back up anything
+          ln -sf ${whitelistFile} whitelist.json
+          cp -f ${serverPropertiesFile} server.properties
+
+        else
 
-    networking.firewall = mkIf cfg.openFirewall {
-      allowedUDPPorts = [ 25565 ];
-      allowedTCPPorts = [ 25565 ];
+          # Declarative for the first time, backup stateful files
+          ln -sb --suffix=.stateful ${whitelistFile} whitelist.json
+          cp -b --suffix=.stateful ${serverPropertiesFile} server.properties
+
+          # server.properties must have write permissions, because every time
+          # the server starts it first parses the file and then regenerates it..
+          chmod +w server.properties
+          echo "Autogenerated file that signifies that this server configuration is managed declaratively by NixOS" \
+            > .declarative
+
+        fi
+      '' else ''
+        if [ -e .declarative ]; then
+          rm .declarative
+        fi
+      '');
     };
+
+    networking.firewall = mkIf cfg.openFirewall (if cfg.declarative then {
+      allowedUDPPorts = [ serverPort ];
+      allowedTCPPorts = [ serverPort ]
+        ++ optional (! isNull queryPort) queryPort
+        ++ optional (! isNull rconPort) rconPort;
+    } else {
+      allowedUDPPorts = [ defaultServerPort ];
+      allowedTCPPorts = [ defaultServerPort ];
+    });
+
+    assertions = [
+      { assertion = cfg.eula;
+        message = "You must agree to Mojangs EULA to run minecraft-server."
+          + " Read https://account.mojang.com/documents/minecraft_eula and"
+          + " set `services.minecraft-server.eula` to `true` if you agree.";
+      }
+    ];
+
   };
 }
diff --git a/nixpkgs/nixos/modules/services/hardware/fwupd.nix b/nixpkgs/nixos/modules/services/hardware/fwupd.nix
index 7743f81fd622..cad9fa20de0f 100644
--- a/nixpkgs/nixos/modules/services/hardware/fwupd.nix
+++ b/nixpkgs/nixos/modules/services/hardware/fwupd.nix
@@ -15,6 +15,19 @@ let
       mkName = p: "pki/fwupd/${baseNameOf (toString p)}";
       mkEtcFile = p: nameValuePair (mkName p) { source = p; };
     in listToAttrs (map mkEtcFile cfg.extraTrustedKeys);
+
+  # We cannot include the file in $out and rely on filesInstalledToEtc
+  # to install it because it would create a cyclic dependency between
+  # the outputs. We also need to enable the remote,
+  # which should not be done by default.
+  testRemote = if cfg.enableTestRemote then {
+    "fwupd/remotes.d/fwupd-tests.conf" = {
+      source = pkgs.runCommand "fwupd-tests-enabled.conf" {} ''
+        sed "s,^Enabled=false,Enabled=true," \
+        "${pkgs.fwupd.installedTests}/etc/fwupd/remotes.d/fwupd-tests.conf" > "$out"
+      '';
+    };
+  } else {};
 in {
 
   ###### interface
@@ -40,7 +53,7 @@ in {
 
       blacklistPlugins = mkOption {
         type = types.listOf types.string;
-        default = [];
+        default = [ "test" ];
         example = [ "udev" ];
         description = ''
           Allow blacklisting specific plugins
@@ -55,6 +68,15 @@ in {
           Installing a public key allows firmware signed with a matching private key to be recognized as trusted, which may require less authentication to install than for untrusted files. By default trusted firmware can be upgraded (but not downgraded) without the user or administrator password. Only very few keys are installed by default.
         '';
       };
+
+      enableTestRemote = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable test remote. This is used by
+          <link xlink:href="https://github.com/hughsie/fwupd/blob/master/data/installed-tests/README.md">installed tests</link>.
+        '';
+      };
     };
   };
 
@@ -78,7 +100,7 @@ in {
         '';
       };
 
-    } // originalEtc // extraTrustedKeys;
+    } // originalEtc // extraTrustedKeys // testRemote;
 
     services.dbus.packages = [ pkgs.fwupd ];
 
diff --git a/nixpkgs/nixos/modules/services/hardware/lirc.nix b/nixpkgs/nixos/modules/services/hardware/lirc.nix
index 0072406a438c..826e512c75d1 100644
--- a/nixpkgs/nixos/modules/services/hardware/lirc.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/hardware/tlp.nix b/nixpkgs/nixos/modules/services/hardware/tlp.nix
index 68425822a884..b894025c0fd5 100644
--- a/nixpkgs/nixos/modules/services/hardware/tlp.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/hardware/vdr.nix b/nixpkgs/nixos/modules/services/hardware/vdr.nix
index 75136a2f7964..4822506a899b 100644
--- a/nixpkgs/nixos/modules/services/hardware/vdr.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/misc/gitea.nix b/nixpkgs/nixos/modules/services/misc/gitea.nix
index 7a10bd872994..be4d38719785 100644
--- a/nixpkgs/nixos/modules/services/misc/gitea.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/misc/gitlab.nix b/nixpkgs/nixos/modules/services/misc/gitlab.nix
index 769a9526cf64..25c258ebe134 100644
--- a/nixpkgs/nixos/modules/services/misc/gitlab.nix
+++ b/nixpkgs/nixos/modules/services/misc/gitlab.nix
@@ -497,7 +497,12 @@ in {
     systemd.services.gitaly = {
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
-      path = with pkgs; [ gitAndTools.git cfg.packages.gitaly.rubyEnv cfg.packages.gitaly.rubyEnv.wrappedRuby ];
+      path = with pkgs; [
+        openssh
+        gitAndTools.git
+        cfg.packages.gitaly.rubyEnv
+        cfg.packages.gitaly.rubyEnv.wrappedRuby
+      ];
       serviceConfig = {
         Type = "simple";
         User = cfg.user;
diff --git a/nixpkgs/nixos/modules/services/misc/home-assistant.nix b/nixpkgs/nixos/modules/services/misc/home-assistant.nix
index 2e9aa33aeeee..4eabda1d4188 100644
--- a/nixpkgs/nixos/modules/services/misc/home-assistant.nix
+++ b/nixpkgs/nixos/modules/services/misc/home-assistant.nix
@@ -6,9 +6,18 @@ let
   cfg = config.services.home-assistant;
 
   # cfg.config != null can be assumed here
-  configFile = pkgs.writeText "configuration.json"
+  configJSON = pkgs.writeText "configuration.json"
     (builtins.toJSON (if cfg.applyDefaultConfig then
-    (lib.recursiveUpdate defaultConfig cfg.config) else cfg.config));
+    (recursiveUpdate defaultConfig cfg.config) else cfg.config));
+  configFile = pkgs.runCommand "configuration.yaml" { } ''
+    ${pkgs.remarshal}/bin/json2yaml -i ${configJSON} -o $out
+  '';
+
+  lovelaceConfigJSON = pkgs.writeText "ui-lovelace.json"
+    (builtins.toJSON cfg.lovelaceConfig);
+  lovelaceConfigFile = pkgs.runCommand "ui-lovelace.yaml" { } ''
+    ${pkgs.remarshal}/bin/json2yaml -i ${lovelaceConfigJSON} -o $out
+  '';
 
   availableComponents = pkgs.home-assistant.availableComponents;
 
@@ -45,6 +54,8 @@ let
   defaultConfig = {
     homeassistant.time_zone = config.time.timeZone;
     http.server_port = (toString cfg.port);
+  } // optionalAttrs (cfg.lovelaceConfig != null) {
+    lovelace.mode = "yaml";
   };
 
 in {
@@ -99,6 +110,53 @@ in {
       '';
     };
 
+    configWritable = mkOption {
+      default = false;
+      type = types.bool;
+      description = ''
+        Whether to make <filename>configuration.yaml</filename> writable.
+        This only has an effect if <option>config</option> is set.
+        This will allow you to edit it from Home Assistant's web interface.
+        However, bear in mind that it will be overwritten at every start of the service.
+      '';
+    };
+
+    lovelaceConfig = mkOption {
+      default = null;
+      type = with types; nullOr attrs;
+      # from https://www.home-assistant.io/lovelace/yaml-mode/
+      example = literalExample ''
+        {
+          title = "My Awesome Home";
+          views = [ {
+            title = "Example";
+            cards = [ {
+              type = "markdown";
+              title = "Lovelace";
+              content = "Welcome to your **Lovelace UI**.";
+            } ];
+          } ];
+        }
+      '';
+      description = ''
+        Your <filename>ui-lovelace.yaml</filename> as a Nix attribute set.
+        Setting this option will automatically add
+        <literal>lovelace.mode = "yaml";</literal> to your <option>config</option>.
+        Beware that setting this option will delete your previous <filename>ui-lovelace.yaml</filename>
+      '';
+    };
+
+    lovelaceConfigWritable = mkOption {
+      default = false;
+      type = types.bool;
+      description = ''
+        Whether to make <filename>ui-lovelace.yaml</filename> writable.
+        This only has an effect if <option>lovelaceConfig</option> is set.
+        This will allow you to edit it from Home Assistant's web interface.
+        However, bear in mind that it will be overwritten at every start of the service.
+      '';
+    };
+
     package = mkOption {
       default = pkgs.home-assistant;
       defaultText = "pkgs.home-assistant";
@@ -144,12 +202,17 @@ in {
     systemd.services.home-assistant = {
       description = "Home Assistant";
       after = [ "network.target" ];
-      preStart = lib.optionalString (cfg.config != null) ''
-        config=${cfg.configDir}/configuration.yaml
-        rm -f $config
-        ${pkgs.remarshal}/bin/json2yaml -i ${configFile} -o $config
-        chmod 444 $config
-      '';
+      preStart = optionalString (cfg.config != null) (if cfg.configWritable then ''
+        cp --no-preserve=mode ${configFile} "${cfg.configDir}/configuration.yaml"
+      '' else ''
+        rm -f "${cfg.configDir}/configuration.yaml"
+        ln -s ${configFile} "${cfg.configDir}/configuration.yaml"
+      '') + optionalString (cfg.lovelaceConfig != null) (if cfg.lovelaceConfigWritable then ''
+        cp --no-preserve=mode ${lovelaceConfigFile} "${cfg.configDir}/ui-lovelace.yaml"
+      '' else ''
+        rm -f "${cfg.configDir}/ui-lovelace.yaml"
+        ln -s ${lovelaceConfigFile} "${cfg.configDir}/ui-lovelace.yaml"
+      '');
       serviceConfig = {
         ExecStart = "${package}/bin/hass --config '${cfg.configDir}'";
         User = "hass";
diff --git a/nixpkgs/nixos/modules/services/misc/nzbget.nix b/nixpkgs/nixos/modules/services/misc/nzbget.nix
index a472b6c7157c..e24cecf20807 100644
--- a/nixpkgs/nixos/modules/services/misc/nzbget.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/misc/plex.nix b/nixpkgs/nixos/modules/services/misc/plex.nix
index 8fe5879c2764..e4810ce9f876 100644
--- a/nixpkgs/nixos/modules/services/misc/plex.nix
+++ b/nixpkgs/nixos/modules/services/misc/plex.nix
@@ -145,7 +145,7 @@ in
         PLEX_MEDIA_SERVER_HOME="${cfg.package}/usr/lib/plexmediaserver";
         PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS="6";
         PLEX_MEDIA_SERVER_TMPDIR="/tmp";
-        LD_LIBRARY_PATH="${cfg.package}/usr/lib/plexmediaserver";
+        LD_LIBRARY_PATH="/run/opengl-driver/lib:${cfg.package}/usr/lib/plexmediaserver";
         LC_ALL="en_US.UTF-8";
         LANG="en_US.UTF-8";
       };
diff --git a/nixpkgs/nixos/modules/services/misc/pykms.nix b/nixpkgs/nixos/modules/services/misc/pykms.nix
index a11296e1bd02..ef90d124a284 100644
--- a/nixpkgs/nixos/modules/services/misc/pykms.nix
+++ b/nixpkgs/nixos/modules/services/misc/pykms.nix
@@ -5,20 +5,8 @@ with lib;
 let
   cfg = config.services.pykms;
 
-  home = "/var/lib/pykms";
-
-  services = {
-    serviceConfig = {
-      Restart = "on-failure";
-      RestartSec = "10s";
-      StartLimitInterval = "1min";
-      PrivateTmp = true;
-      ProtectSystem = "full";
-      ProtectHome = true;
-    };
-  };
-
 in {
+  meta.maintainers = with lib.maintainers; [ peterhoeg ];
 
   options = {
     services.pykms = rec {
@@ -51,39 +39,38 @@ in {
         default = false;
         description = "Whether the listening port should be opened automatically.";
       };
+
+      memoryLimit = mkOption {
+        type = types.str;
+        default = "64M";
+        description = "How much memory to use at most.";
+      };
     };
   };
 
   config = mkIf cfg.enable {
     networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewallPort [ cfg.port ];
 
-    systemd.services = {
-      pykms = services // {
-        description = "Python KMS";
-        wantedBy = [ "multi-user.target" ];
-        serviceConfig = with pkgs; {
-          User = "pykms";
-          Group = "pykms";
-          ExecStartPre = "${getBin pykms}/bin/create_pykms_db.sh ${home}/clients.db";
-          ExecStart = "${getBin pykms}/bin/server.py ${optionalString cfg.verbose "--verbose"} ${cfg.listenAddress} ${toString cfg.port}";
-          WorkingDirectory = home;
-          MemoryLimit = "64M";
-        };
-      };
-    };
-
-    users = {
-      users.pykms = {
-        name = "pykms";
-        group = "pykms";
-        home  = home;
-        createHome = true;
-        uid = config.ids.uids.pykms;
-        description = "PyKMS daemon user";
-      };
-
-      groups.pykms = {
-        gid = config.ids.gids.pykms;
+    systemd.services.pykms = let
+      home = "/var/lib/pykms";
+    in {
+      description = "Python KMS";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      # python programs with DynamicUser = true require HOME to be set
+      environment.HOME = home;
+      serviceConfig = with pkgs; {
+        DynamicUser = true;
+        StateDirectory = baseNameOf home;
+        ExecStartPre = "${getBin pykms}/bin/create_pykms_db.sh ${home}/clients.db";
+        ExecStart = lib.concatStringsSep " " ([
+          "${getBin pykms}/bin/server.py"
+          cfg.listenAddress
+          (toString cfg.port)
+        ] ++ lib.optional cfg.verbose "--verbose");
+        WorkingDirectory = home;
+        Restart = "on-failure";
+        MemoryLimit = cfg.memoryLimit;
       };
     };
   };
diff --git a/nixpkgs/nixos/modules/services/misc/redmine.nix b/nixpkgs/nixos/modules/services/misc/redmine.nix
index 8d25ac5cb76f..98e9c8953c84 100644
--- a/nixpkgs/nixos/modules/services/misc/redmine.nix
+++ b/nixpkgs/nixos/modules/services/misc/redmine.nix
@@ -30,6 +30,13 @@ let
     ${cfg.extraConfig}
   '';
 
+  additionalEnvironment = pkgs.writeText "additional_environment.rb" ''
+    config.logger = Logger.new("${cfg.stateDir}/log/production.log", 14, 1048576)
+    config.logger.level = Logger::INFO
+
+    ${cfg.extraEnv}
+  '';
+
   unpackTheme = unpack "theme";
   unpackPlugin = unpack "plugin";
   unpack = id: (name: source:
@@ -54,12 +61,20 @@ in
         description = "Enable the Redmine service.";
       };
 
+      # default to the 4.x series not forcing major version upgrade of those on the 3.x series
       package = mkOption {
         type = types.package;
-        default = pkgs.redmine;
+        default = if versionAtLeast config.system.stateVersion "19.03"
+          then pkgs.redmine_4
+          else pkgs.redmine
+        ;
         defaultText = "pkgs.redmine";
-        description = "Which Redmine package to use.";
-        example = "pkgs.redmine.override { ruby = pkgs.ruby_2_3; }";
+        description = ''
+          Which Redmine package to use. This defaults to version 3.x if
+          <literal>system.stateVersion &lt; 19.03</literal> and version 4.x
+          otherwise.
+        '';
+        example = "pkgs.redmine_4.override { ruby = pkgs.ruby_2_4; }";
       };
 
       user = mkOption {
@@ -103,6 +118,19 @@ in
         '';
       };
 
+      extraEnv = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Extra configuration in additional_environment.rb.
+
+          See https://svn.redmine.org/redmine/trunk/config/additional_environment.rb.example
+        '';
+        example = literalExample ''
+          config.logger.level = Logger::DEBUG
+        '';
+      };
+
       themes = mkOption {
         type = types.attrsOf types.path;
         default = {};
@@ -249,6 +277,9 @@ in
         # link in the application configuration
         ln -fs ${configurationYml} "${cfg.stateDir}/config/configuration.yml"
 
+        # link in the additional environment configuration
+        ln -fs ${additionalEnvironment} "${cfg.stateDir}/config/additional_environment.rb"
+
 
         # link in all user specified themes
         rm -rf "${cfg.stateDir}/public/themes/"*
@@ -292,6 +323,7 @@ in
         # execute redmine required commands prior to starting the application
         # NOTE: su required in case using mysql socket authentication
         /run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake db:migrate'
+        /run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake redmine:plugins:migrate'
         /run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake redmine:load_default_data'
 
 
diff --git a/nixpkgs/nixos/modules/services/misc/sonarr.nix b/nixpkgs/nixos/modules/services/misc/sonarr.nix
index 97b67a0b5033..a99445a268d7 100644
--- a/nixpkgs/nixos/modules/services/misc/sonarr.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/misc/weechat.xml b/nixpkgs/nixos/modules/services/misc/weechat.xml
index b7f755bbc5c7..7255edfb9da3 100644
--- a/nixpkgs/nixos/modules/services/misc/weechat.xml
+++ b/nixpkgs/nixos/modules/services/misc/weechat.xml
@@ -8,7 +8,7 @@
   <link xlink:href="https://weechat.org/">WeeChat</link> is a fast and
   extensible IRC client.
  </para>
- <section>
+ <section xml:id="module-services-weechat-basic-usage">
   <title>Basic Usage</title>
 
   <para>
@@ -35,7 +35,7 @@
    in the state directory <literal>/var/lib/weechat</literal>.
   </para>
  </section>
- <section>
+ <section xml:id="module-services-weechat-reattach">
   <title>Re-attaching to WeeChat</title>
 
   <para>
diff --git a/nixpkgs/nixos/modules/services/misc/zoneminder.nix b/nixpkgs/nixos/modules/services/misc/zoneminder.nix
new file mode 100644
index 000000000000..a40e9e846137
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/misc/zoneminder.nix
@@ -0,0 +1,362 @@
+{ config, lib, pkgs, ... }:
+
+let
+  cfg = config.services.zoneminder;
+  pkg = pkgs.zoneminder;
+
+  dirName = pkg.dirName;
+
+  user = "zoneminder";
+  group = {
+    nginx = config.services.nginx.group;
+    none  = user;
+  }."${cfg.webserver}";
+
+  useNginx = cfg.webserver == "nginx";
+
+  defaultDir = "/var/lib/${user}";
+  home = if useCustomDir then cfg.storageDir else defaultDir;
+
+  useCustomDir = !(builtins.isNull cfg.storageDir);
+
+  socket = "/run/phpfpm/${dirName}.sock";
+
+  zms = "/cgi-bin/zms";
+
+  dirs = dirList: [ dirName ] ++ map (e: "${dirName}/${e}") dirList;
+
+  cacheDirs = [ "swap" ];
+  libDirs   = [ "events" "exports" "images" "sounds" ];
+
+  dirStanzas = baseDir:
+    lib.concatStringsSep "\n" (map (e:
+      "ZM_DIR_${lib.toUpper e}=${baseDir}/${e}"
+      ) libDirs);
+
+  defaultsFile = pkgs.writeText "60-defaults.conf" ''
+    # 01-system-paths.conf
+    ${dirStanzas home}
+    ZM_PATH_ARP=${lib.getBin pkgs.nettools}/bin/arp
+    ZM_PATH_LOGS=/var/log/${dirName}
+    ZM_PATH_MAP=/dev/shm
+    ZM_PATH_SOCKS=/run/${dirName}
+    ZM_PATH_SWAP=/var/cache/${dirName}/swap
+    ZM_PATH_ZMS=${zms}
+
+    # 02-multiserver.conf
+    ZM_SERVER_HOST=
+
+    # Database
+    ZM_DB_TYPE=mysql
+    ZM_DB_HOST=${cfg.database.host}
+    ZM_DB_NAME=${cfg.database.name}
+    ZM_DB_USER=${cfg.database.username}
+    ZM_DB_PASS=${cfg.database.password}
+
+    # Web
+    ZM_WEB_USER=${user}
+    ZM_WEB_GROUP=${group}
+  '';
+
+  configFile = pkgs.writeText "80-nixos.conf" ''
+    # You can override defaults here
+
+    ${cfg.extraConfig}
+  '';
+
+  phpExtensions = with pkgs.phpPackages; [
+    { pkg = apcu; name = "apcu"; }
+  ];
+
+in {
+  options = {
+    services.zoneminder = with lib; {
+      enable = lib.mkEnableOption ''
+        ZoneMinder
+        </para><para>
+        If you intend to run the database locally, you should set
+        `config.services.zoneminder.database.createLocally` to true. Otherwise,
+        when set to `false` (the default), you will have to create the database
+        and database user as well as populate the database yourself.
+      '';
+
+      webserver = mkOption {
+        type = types.enum [ "nginx" "none" ];
+        default = "nginx";
+        description = ''
+          The webserver to configure for the PHP frontend.
+          </para>
+          <para>
+
+          Set it to `none` if you want to configure it yourself. PRs are welcome
+          for support for other web servers.
+        '';
+      };
+
+      hostname = mkOption {
+        type = types.str;
+        default = "localhost";
+        description = ''
+          The hostname on which to listen.
+        '';
+      };
+
+      port = mkOption {
+        type = types.int;
+        default = 8095;
+        description = ''
+          The port on which to listen.
+        '';
+      };
+
+      openFirewall = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Open the firewall port(s).
+        '';
+      };
+
+      database = {
+        createLocally = mkOption {
+          type = types.bool;
+          default = false;
+          description = ''
+            Create the database and database user locally.
+          '';
+        };
+
+        host = mkOption {
+          type = types.str;
+          default = "localhost";
+          description = ''
+            Hostname hosting the database.
+          '';
+        };
+
+        name = mkOption {
+          type = types.str;
+          default = "zm";
+          description = ''
+            Name of database.
+          '';
+        };
+
+        username = mkOption {
+          type = types.str;
+          default = "zmuser";
+          description = ''
+            Username for accessing the database.
+          '';
+        };
+
+        password = mkOption {
+          type = types.str;
+          default = "zmpass";
+          description = ''
+            Username for accessing the database.
+          '';
+        };
+      };
+
+      cameras = mkOption {
+        type = types.int;
+        default = 1;
+        description = ''
+          Set this to the number of cameras you expect to support.
+        '';
+      };
+
+      storageDir = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        example = "/storage/tank";
+        description = ''
+          ZoneMinder can generate quite a lot of data, so in case you don't want
+          to use the default ${home}, you can override the path here.
+        '';
+      };
+
+      extraConfig = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Additional configuration added verbatim to the configuration file.
+        '';
+      };
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+
+    environment.etc = {
+      "zoneminder/60-defaults.conf".source = defaultsFile;
+      "zoneminder/80-nixos.conf".source    = configFile;
+    };
+
+    networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ];
+
+    services = {
+      fcgiwrap = lib.mkIf useNginx {
+        enable = true;
+        preforkProcesses = cfg.cameras;
+        inherit user group;
+      };
+
+      mysql = lib.mkIf cfg.database.createLocally {
+        ensureDatabases = [ cfg.database.name ];
+        ensureUsers = {
+          name = cfg.database.username;
+          ensurePermissions = [
+            { "${cfg.database.name}.*" = "ALL PRIVILEGES"; }
+          ];
+          initialDatabases = [
+            { inherit (cfg.database) name; schema = "${pkg}/share/zoneminder/db/zm_create.sql"; }
+          ];
+        };
+      };
+
+      nginx = lib.mkIf useNginx {
+        enable = true;
+        virtualHosts = {
+          "${cfg.hostname}" = {
+            default = true;
+            root = "${pkg}/share/zoneminder/www";
+            listen = [ { addr = "0.0.0.0"; inherit (cfg) port; } ];
+            extraConfig = let
+              fcgi = config.services.fcgiwrap;
+            in ''
+              index index.php;
+
+              location / {
+                try_files $uri $uri/ /index.php?$args =404;
+
+                location ~ /api/(css|img|ico) {
+                  rewrite ^/api(.+)$ /api/app/webroot/$1 break;
+                  try_files $uri $uri/ =404;
+                }
+
+                location ~ \.(gif|ico|jpg|jpeg|png)$ {
+                  access_log off;
+                  expires 30d;
+                }
+
+                location /api {
+                  rewrite ^/api(.+)$ /api/app/webroot/index.php?p=$1 last;
+                }
+
+                location /cgi-bin {
+                  gzip off;
+
+                  include ${pkgs.nginx}/conf/fastcgi_params;
+                  fastcgi_param SCRIPT_FILENAME ${pkg}/libexec/zoneminder/${zms};
+                  fastcgi_param HTTP_PROXY "";
+                  fastcgi_intercept_errors on;
+
+                  fastcgi_pass ${fcgi.socketType}:${fcgi.socketAddress};
+                }
+
+                location /cache {
+                  alias /var/cache/${dirName};
+                }
+
+                location ~ \.php$ {
+                  try_files $uri =404;
+                  fastcgi_index index.php;
+
+                  include ${pkgs.nginx}/conf/fastcgi_params;
+                  fastcgi_param SCRIPT_FILENAME $request_filename;
+                  fastcgi_param HTTP_PROXY "";
+
+                  fastcgi_pass unix:${socket};
+                }
+              }
+            '';
+          };
+        };
+      };
+
+      phpfpm = lib.mkIf useNginx {
+        phpOptions = ''
+          date.timezone = "${config.time.timeZone}"
+
+          ${lib.concatStringsSep "\n" (map (e:
+          "extension=${e.pkg}/lib/php/extensions/${e.name}.so") phpExtensions)}
+        '';
+        pools.zoneminder = {
+          listen = socket;
+          extraConfig = ''
+            user = ${user}
+            group = ${group}
+
+            listen.owner = ${user}
+            listen.group = ${group}
+            listen.mode = 0660
+
+            pm = dynamic
+            pm.start_servers = 1
+            pm.min_spare_servers = 1
+            pm.max_spare_servers = 2
+            pm.max_requests = 500
+            pm.max_children = 5
+            pm.status_path = /$pool-status
+            ping.path = /$pool-ping
+          '';
+        };
+      };
+    };
+
+    systemd.services = {
+      zoneminder = with pkgs; rec {
+        inherit (zoneminder.meta) description;
+        documentation = [ "https://zoneminder.readthedocs.org/en/latest/" ];
+        path = [
+          coreutils
+          procps
+          psmisc
+        ];
+        after = [ "mysql.service" "nginx.service" ];
+        wantedBy = [ "multi-user.target" ];
+        restartTriggers = [ defaultsFile configFile ];
+        preStart = lib.mkIf useCustomDir ''
+          install -dm775 -o ${user} -g ${group} ${cfg.storageDir}/{${lib.concatStringsSep "," libDirs}}
+        '';
+        serviceConfig = {
+          User = user;
+          Group = group;
+          SupplementaryGroups = [ "video" ];
+          ExecStart  = "${zoneminder}/bin/zmpkg.pl start";
+          ExecStop   = "${zoneminder}/bin/zmpkg.pl stop";
+          ExecReload = "${zoneminder}/bin/zmpkg.pl restart";
+          PIDFile = "/run/${dirName}/zm.pid";
+          Type = "forking";
+          Restart = "on-failure";
+          RestartSec = "10s";
+          CacheDirectory = dirs cacheDirs;
+          RuntimeDirectory = dirName;
+          ReadWriteDirectories = lib.mkIf useCustomDir [ cfg.storageDir ];
+          StateDirectory = dirs (if useCustomDir then [] else libDirs);
+          LogsDirectory = dirName;
+          PrivateTmp = true;
+          ProtectSystem = "strict";
+          ProtectKernelTunables = true;
+          SystemCallArchitectures = "native";
+          NoNewPrivileges = true;
+        };
+      };
+    };
+
+    users.groups."${user}" = {
+      gid = config.ids.gids.zoneminder;
+    };
+
+    users.users."${user}" = {
+      uid = config.ids.uids.zoneminder;
+      group = user;
+      inherit home;
+      inherit (pkgs.zoneminder.meta) description;
+    };
+  };
+
+  meta.maintainers = with lib.maintainers; [ peterhoeg ];
+}
diff --git a/nixpkgs/nixos/modules/services/monitoring/collectd.nix b/nixpkgs/nixos/modules/services/monitoring/collectd.nix
index 6606980cdad8..45e3312c0f44 100644
--- a/nixpkgs/nixos/modules/services/monitoring/collectd.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/collectd.nix
@@ -88,6 +88,8 @@ in {
         ExecStart = "${cfg.package}/sbin/collectd -C ${conf} -f";
         User = cfg.user;
         PermissionsStartOnly = true;
+        Restart = "on-failure";
+        RestartSec = 3;
       };
 
       preStart = ''
diff --git a/nixpkgs/nixos/modules/services/monitoring/datadog-agent.nix b/nixpkgs/nixos/modules/services/monitoring/datadog-agent.nix
index 5434fe99347d..a4d29d45bacf 100644
--- a/nixpkgs/nixos/modules/services/monitoring/datadog-agent.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/monitoring/grafana.nix b/nixpkgs/nixos/modules/services/monitoring/grafana.nix
index 5fb3e3771221..85879cfe0b33 100644
--- a/nixpkgs/nixos/modules/services/monitoring/grafana.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/grafana.nix
@@ -50,6 +50,158 @@ let
     SMTP_FROM_ADDRESS = cfg.smtp.fromAddress;
   } // cfg.extraOptions;
 
+  datasourceConfiguration = {
+    apiVersion = 1;
+    datasources = cfg.provision.datasources;
+  };
+
+  datasourceFile = pkgs.writeText "datasource.yaml" (builtins.toJSON datasourceConfiguration);
+
+  dashboardConfiguration = {
+    apiVersion = 1;
+    providers = cfg.provision.dashboards;
+  };
+
+  dashboardFile = pkgs.writeText "dashboard.yaml" (builtins.toJSON dashboardConfiguration);
+
+  provisionConfDir =  pkgs.runCommand "grafana-provisioning" { } ''
+    mkdir -p $out/{datasources,dashboards}
+    ln -sf ${datasourceFile} $out/datasources/datasource.yaml
+    ln -sf ${dashboardFile} $out/dashboards/dashboard.yaml
+  '';
+
+  # Get a submodule without any embedded metadata:
+  _filter = x: filterAttrs (k: v: k != "_module") x;
+
+  # http://docs.grafana.org/administration/provisioning/#datasources
+  grafanaTypes.datasourceConfig = types.submodule {
+    options = {
+      name = mkOption {
+        type = types.str;
+        description = "Name of the datasource. Required";
+      };
+      type = mkOption {
+        type = types.enum ["graphite" "prometheus" "cloudwatch" "elasticsearch" "influxdb" "opentsdb" "mysql" "mssql" "postgres" "loki"];
+        description = "Datasource type. Required";
+      };
+      access = mkOption {
+        type = types.enum ["proxy" "direct"];
+        default = "proxy";
+        description = "Access mode. proxy or direct (Server or Browser in the UI). Required";
+      };
+      orgId = mkOption {
+        type = types.int;
+        default = 1;
+        description = "Org id. will default to orgId 1 if not specified";
+      };
+      url = mkOption {
+        type = types.str;
+        description = "Url of the datasource";
+      };
+      password = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        description = "Database password, if used";
+      };
+      user = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        description = "Database user, if used";
+      };
+      database = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        description = "Database name, if used";
+      };
+      basicAuth = mkOption {
+        type = types.nullOr types.bool;
+        default = null;
+        description = "Enable/disable basic auth";
+      };
+      basicAuthUser = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        description = "Basic auth username";
+      };
+      basicAuthPassword = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        description = "Basic auth password";
+      };
+      withCredentials = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Enable/disable with credentials headers";
+      };
+      isDefault = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Mark as default datasource. Max one per org";
+      };
+      jsonData = mkOption {
+        type = types.nullOr types.attrs;
+        default = null;
+        description = "Datasource specific configuration";
+      };
+      secureJsonData = mkOption {
+        type = types.nullOr types.attrs;
+        default = null;
+        description = "Datasource specific secure configuration";
+      };
+      version = mkOption {
+        type = types.int;
+        default = 1;
+        description = "Version";
+      };
+      editable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Allow users to edit datasources from the UI.";
+      };
+    };
+  };
+
+  # http://docs.grafana.org/administration/provisioning/#dashboards
+  grafanaTypes.dashboardConfig = types.submodule {
+    options = {
+      name = mkOption {
+        type = types.str;
+        default = "default";
+        description = "Provider name";
+      };
+      orgId = mkOption {
+        type = types.int;
+        default = 1;
+        description = "Organization ID";
+      };
+      folder = mkOption {
+        type = types.str;
+        default = "";
+        description = "Add dashboards to the speciied folder";
+      };
+      type = mkOption {
+        type = types.str;
+        default = "file";
+        description = "Dashboard provider type";
+      };
+      disableDeletion = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Disable deletion when JSON file is removed";
+      };
+      updateIntervalSeconds = mkOption {
+        type = types.int;
+        default = 10;
+        description = "How often Grafana will scan for changed dashboards";
+      };
+      options = {
+        path = mkOption {
+          type = types.path;
+          description = "Path grafana will watch for dashboards";
+        };
+      };
+    };
+  };
 in {
   options.services.grafana = {
     enable = mkEnableOption "grafana";
@@ -175,6 +327,22 @@ in {
       };
     };
 
+    provision = {
+      enable = mkEnableOption "provision";
+      datasources = mkOption {
+        description = "Grafana datasources configuration";
+        default = [];
+        type = types.listOf grafanaTypes.datasourceConfig;
+        apply = x: map _filter x;
+      };
+      dashboards = mkOption {
+        description = "Grafana dashboard configuration";
+        default = [];
+        type = types.listOf grafanaTypes.dashboardConfig;
+        apply = x: map _filter x;
+      };
+    };
+
     security = {
       adminUser = mkOption {
         description = "Default admin username.";
@@ -313,10 +481,15 @@ in {
   };
 
   config = mkIf cfg.enable {
-    warnings = optional (
-      cfg.database.password != opt.database.password.default ||
-      cfg.security.adminPassword != opt.security.adminPassword.default
-    ) "Grafana passwords will be stored as plaintext in the Nix store!";
+    warnings = flatten [
+      (optional (
+        cfg.database.password != opt.database.password.default ||
+        cfg.security.adminPassword != opt.security.adminPassword.default
+      ) "Grafana passwords will be stored as plaintext in the Nix store!")
+      (optional (
+        any (x: x.password != null || x.basicAuthPassword != null || x.secureJsonData != null) cfg.provision.datasources
+      ) "Datasource passwords will be stored as plaintext in the Nix store!")
+    ];
 
     environment.systemPackages = [ cfg.package ];
 
@@ -359,6 +532,9 @@ in {
         ${optionalString (cfg.smtp.passwordFile != null) ''
           export GF_SMTP_PASSWORD="$(cat ${escapeShellArg cfg.smtp.passwordFile})"
         ''}
+        ${optionalString cfg.provision.enable ''
+          export GF_PATHS_PROVISIONING=${provisionConfDir};
+        ''}
         exec ${cfg.package.bin}/bin/grafana-server -homepath ${cfg.dataDir}
       '';
       serviceConfig = {
diff --git a/nixpkgs/nixos/modules/services/monitoring/munin.nix b/nixpkgs/nixos/modules/services/monitoring/munin.nix
index 2b265d5b5a90..f67986327245 100644
--- a/nixpkgs/nixos/modules/services/monitoring/munin.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/munin.nix
@@ -4,7 +4,7 @@
 # TODO: LWP/Pg perl libs aren't recognized
 
 # TODO: support fastcgi
-# http://munin-monitoring.org/wiki/CgiHowto2
+# http://guide.munin-monitoring.org/en/latest/example/webserver/apache-cgi.html
 # spawn-fcgi -s /run/munin/fastcgi-graph.sock -U www-data   -u munin -g munin /usr/lib/munin/cgi/munin-cgi-graph
 # spawn-fcgi -s /run/munin/fastcgi-html.sock  -U www-data   -u munin -g munin /usr/lib/munin/cgi/munin-cgi-html
 # https://paste.sh/vofcctHP#-KbDSXVeWoifYncZmLfZzgum
@@ -24,6 +24,8 @@ let
       logdir    /var/log/munin
       rundir    /run/munin
 
+      ${lib.optionalString (cronCfg.extraCSS != "") "staticdir ${customStaticDir}"}
+
       ${cronCfg.extraGlobalConfig}
 
       ${cronCfg.hosts}
@@ -63,6 +65,11 @@ let
       [ipmi*]
       user root
       group root
+
+      [munin*]
+      env.UPDATE_STATSFILE /var/lib/munin/munin-update.stats
+
+      ${nodeCfg.extraPluginConfig}
     '';
 
   pluginConfDir = pkgs.stdenv.mkDerivation {
@@ -72,6 +79,54 @@ let
       ln -s ${pluginConf} $out/nixos-config
     '';
   };
+
+  # Copy one Munin plugin into the Nix store with a specific name.
+  # This is suitable for use with plugins going directly into /etc/munin/plugins,
+  # i.e. munin.extraPlugins.
+  internOnePlugin = name: path:
+    "cp -a '${path}' '${name}'";
+
+  # Copy an entire tree of Munin plugins into a single directory in the Nix
+  # store, with no renaming.
+  # This is suitable for use with munin-node-configure --suggest, i.e.
+  # munin.extraAutoPlugins.
+  internManyPlugins = name: path:
+    "find '${path}' -type f -perm /a+x -exec cp -a -t . '{}' '+'";
+
+  # Use the appropriate intern-fn to copy the plugins into the store and patch
+  # them afterwards in an attempt to get them to run on NixOS.
+  internAndFixPlugins = name: intern-fn: paths:
+    pkgs.runCommand name {} ''
+      mkdir -p "$out"
+      cd "$out"
+      ${lib.concatStringsSep "\n"
+          (lib.attrsets.mapAttrsToList intern-fn paths)}
+      chmod -R u+w .
+      find . -type f -exec sed -E -i '
+        s,(/usr)?/s?bin/,/run/current-system/sw/bin/,g
+      ' '{}' '+'
+    '';
+
+  # TODO: write a derivation for munin-contrib, so that for contrib plugins
+  # you can just refer to them by name rather than needing to include a copy
+  # of munin-contrib in your nixos configuration.
+  extraPluginDir = internAndFixPlugins "munin-extra-plugins.d"
+    internOnePlugin nodeCfg.extraPlugins;
+
+  extraAutoPluginDir = internAndFixPlugins "munin-extra-auto-plugins.d"
+    internManyPlugins
+    (builtins.listToAttrs
+      (map
+        (path: { name = baseNameOf path; value = path; })
+        nodeCfg.extraAutoPlugins));
+
+  customStaticDir = pkgs.runCommand "munin-custom-static-data" {} ''
+    cp -a "${pkgs.munin}/etc/opt/munin/static" "$out"
+    cd "$out"
+    chmod -R u+w .
+    echo "${cronCfg.extraCSS}" >> style.css
+    echo "${cronCfg.extraCSS}" >> style-new.css
+  '';
 in
 
 {
@@ -82,11 +137,12 @@ in
 
       enable = mkOption {
         default = false;
+        type = types.bool;
         description = ''
           Enable Munin Node agent. Munin node listens on 0.0.0.0 and
           by default accepts connections only from 127.0.0.1 for security reasons.
 
-          See <link xlink:href='http://munin-monitoring.org/wiki/munin-node.conf' />.
+          See <link xlink:href='http://guide.munin-monitoring.org/en/latest/architecture/index.html' />.
         '';
       };
 
@@ -95,18 +151,108 @@ in
         type = types.lines;
         description = ''
           <filename>munin-node.conf</filename> extra configuration. See
-          <link xlink:href='http://munin-monitoring.org/wiki/munin-node.conf' />
+          <link xlink:href='http://guide.munin-monitoring.org/en/latest/reference/munin-node.conf.html' />
+        '';
+      };
+
+      extraPluginConfig = mkOption {
+        default = "";
+        type = types.lines;
+        description = ''
+          <filename>plugin-conf.d</filename> extra plugin configuration. See
+          <link xlink:href='http://guide.munin-monitoring.org/en/latest/plugin/use.html' />
+        '';
+        example = ''
+          [fail2ban_*]
+          user root
         '';
       };
 
-      # TODO: add option to add additional plugins
+      extraPlugins = mkOption {
+        default = {};
+        type = with types; attrsOf path;
+        description = ''
+          Additional Munin plugins to activate. Keys are the name of the plugin
+          symlink, values are the path to the underlying plugin script. You
+          can use the same plugin script multiple times (e.g. for wildcard
+          plugins).
+
+          Note that these plugins do not participate in autoconfiguration. If
+          you want to autoconfigure additional plugins, use
+          <option>services.munin-node.extraAutoPlugins</option>.
+
+          Plugins enabled in this manner take precedence over autoconfigured
+          plugins.
+
+          Plugins will be copied into the Nix store, and it will attempt to
+          modify them to run properly by fixing hardcoded references to
+          <literal>/bin</literal>, <literal>/usr/bin</literal>,
+          <literal>/sbin</literal>, and <literal>/usr/sbin</literal>.
+        '';
+        example = literalExample ''
+          {
+            zfs_usage_bigpool = /src/munin-contrib/plugins/zfs/zfs_usage_;
+            zfs_usage_smallpool = /src/munin-contrib/plugins/zfs/zfs_usage_;
+            zfs_list = /src/munin-contrib/plugins/zfs/zfs_list;
+          };
+        '';
+      };
 
+      extraAutoPlugins = mkOption {
+        default = [];
+        type = with types; listOf path;
+        description = ''
+          Additional Munin plugins to autoconfigure, using
+          <literal>munin-node-configure --suggest</literal>. These should be
+          the actual paths to the plugin files (or directories containing them),
+          not just their names.
+
+          If you want to manually enable individual plugins instead, use
+          <option>services.munin-node.extraPlugins</option>.
+
+          Note that only plugins that have the 'autoconfig' capability will do
+          anything if listed here, since plugins that cannot autoconfigure
+          won't be automatically enabled by
+          <literal>munin-node-configure</literal>.
+
+          Plugins will be copied into the Nix store, and it will attempt to
+          modify them to run properly by fixing hardcoded references to
+          <literal>/bin</literal>, <literal>/usr/bin</literal>,
+          <literal>/sbin</literal>, and <literal>/usr/sbin</literal>.
+        '';
+        example = literalExample ''
+          [
+            /src/munin-contrib/plugins/zfs
+            /src/munin-contrib/plugins/ssh
+          ];
+        '';
+      };
+
+      disabledPlugins = mkOption {
+        # TODO: figure out why Munin isn't writing the log file and fix it.
+        # In the meantime this at least suppresses a useless graph full of
+        # NaNs in the output.
+        default = [ "munin_stats" ];
+        type = with types; listOf string;
+        description = ''
+          Munin plugins to disable, even if
+          <literal>munin-node-configure --suggest</literal> tries to enable
+          them. To disable a wildcard plugin, use an actual wildcard, as in
+          the example.
+
+          munin_stats is disabled by default as it tries to read
+          <literal>/var/log/munin/munin-update.log</literal> for timing
+          information, and the NixOS build of Munin does not write this file.
+        '';
+        example = [ "diskstats" "zfs_usage_*" ];
+      };
     };
 
     services.munin-cron = {
 
       enable = mkOption {
         default = false;
+        type = types.bool;
         description = ''
           Enable munin-cron. Takes care of all heavy lifting to collect data from
           nodes and draws graphs to html. Runs munin-update, munin-limits,
@@ -119,11 +265,12 @@ in
 
       extraGlobalConfig = mkOption {
         default = "";
+        type = types.lines;
         description = ''
           <filename>munin.conf</filename> extra global configuration.
-          See <link xlink:href='http://munin-monitoring.org/wiki/munin.conf' />.
+          See <link xlink:href='http://guide.munin-monitoring.org/en/latest/reference/munin.conf.html' />.
           Useful to setup notifications, see
-          <link xlink:href='http://munin-monitoring.org/wiki/HowToContact' />
+          <link xlink:href='http://guide.munin-monitoring.org/en/latest/tutorial/alert.html' />
         '';
         example = ''
           contact.email.command mail -s "Munin notification for ''${var:host}" someone@example.com
@@ -131,14 +278,34 @@ in
       };
 
       hosts = mkOption {
+        default = "";
+        type = types.lines;
+        description = ''
+          Definitions of hosts of nodes to collect data from. Needs at least one
+          host for cron to succeed. See
+          <link xlink:href='http://guide.munin-monitoring.org/en/latest/reference/munin.conf.html' />
+        '';
         example = ''
           [''${config.networking.hostName}]
           address localhost
         '';
+      };
+
+      extraCSS = mkOption {
+        default = "";
+        type = types.lines;
         description = ''
-          Definitions of hosts of nodes to collect data from. Needs at least one
-          hosts for cron to succeed. See
-          <link xlink:href='http://munin-monitoring.org/wiki/munin.conf' />
+          Custom styling for the HTML that munin-cron generates. This will be
+          appended to the CSS files used by munin-cron and will thus take
+          precedence over the builtin styles.
+        '';
+        example = ''
+          /* A simple dark theme. */
+          html, body { background: #222222; }
+          #header, #footer { background: #333333; }
+          img.i, img.iwarn, img.icrit, img.iunkn {
+            filter: invert(100%) hue-rotate(-30deg);
+          }
         '';
       };
 
@@ -155,6 +322,7 @@ in
       description = "Munin monitoring user";
       group = "munin";
       uid = config.ids.uids.munin;
+      home = "/var/lib/munin";
     }];
 
     users.groups = [{
@@ -173,14 +341,27 @@ in
       environment.MUNIN_PLUGSTATE = "/run/munin";
       environment.MUNIN_LOGDIR = "/var/log/munin";
       preStart = ''
-        echo "updating munin plugins..."
+        echo "Updating munin plugins..."
 
         mkdir -p /etc/munin/plugins
         rm -rf /etc/munin/plugins/*
+
+        # Autoconfigure builtin plugins
         ${pkgs.munin}/bin/munin-node-configure --suggest --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${pkgs.munin}/lib/plugins --servicedir=/etc/munin/plugins --sconfdir=${pluginConfDir} 2>/dev/null | ${pkgs.bash}/bin/bash
 
-        # NOTE: we disable disktstats because plugin seems to fail and it hangs html generation (100% CPU + memory leak)
-        rm /etc/munin/plugins/diskstats || true
+        # Autoconfigure extra plugins
+        ${pkgs.munin}/bin/munin-node-configure --suggest --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${extraAutoPluginDir} --servicedir=/etc/munin/plugins --sconfdir=${pluginConfDir} 2>/dev/null | ${pkgs.bash}/bin/bash
+
+        ${lib.optionalString (nodeCfg.extraPlugins != {}) ''
+            # Link in manually enabled plugins
+            ln -f -s -t /etc/munin/plugins ${extraPluginDir}/*
+          ''}
+
+        ${lib.optionalString (nodeCfg.disabledPlugins != []) ''
+            # Disable plugins
+            cd /etc/munin/plugins
+            rm -f ${toString nodeCfg.disabledPlugins}
+          ''}
       '';
       serviceConfig = {
         ExecStart = "${pkgs.munin}/sbin/munin-node --config ${nodeConf} --servicedir /etc/munin/plugins/ --sconfdir=${pluginConfDir}";
@@ -192,6 +373,10 @@ in
 
   }) (mkIf cronCfg.enable {
 
+    # Munin is hardcoded to use DejaVu Mono and the graphs come out wrong if
+    # it's not available.
+    fonts.fonts = [ pkgs.dejavu_fonts ];
+
     systemd.timers.munin-cron = {
       description = "batch Munin master programs";
       wantedBy = [ "timers.target" ];
diff --git a/nixpkgs/nixos/modules/services/monitoring/netdata.nix b/nixpkgs/nixos/modules/services/monitoring/netdata.nix
index 4873ab1fc608..1d86c5d893de 100644
--- a/nixpkgs/nixos/modules/services/monitoring/netdata.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/netdata.nix
@@ -10,9 +10,14 @@ let
     ln -s /run/wrappers/bin/apps.plugin $out/libexec/netdata/plugins.d/apps.plugin
   '';
 
+  plugins = [
+    "${pkgs.netdata}/libexec/netdata/plugins.d"
+    "${wrappedPlugins}/libexec/netdata/plugins.d"
+  ] ++ cfg.extraPluginPaths;
+
   localConfig = {
     global = {
-      "plugins directory" = "${pkgs.netdata}/libexec/netdata/plugins.d ${wrappedPlugins}/libexec/netdata/plugins.d";
+      "plugins directory" = concatStringsSep " " plugins;
     };
     web = {
       "web files owner" = "root";
@@ -78,6 +83,24 @@ in {
         };
       };
 
+      extraPluginPaths = mkOption {
+        type = types.listOf types.path;
+        default = [ ];
+        example = literalExample ''
+          [ "/path/to/plugins.d" ]
+        '';
+        description = ''
+          Extra paths to add to the netdata global "plugins directory"
+          option.  Useful for when you want to include your own
+          collection scripts.
+          </para><para>
+          Details about writing a custom netdata plugin are available at:
+          <link xlink:href="https://docs.netdata.cloud/collectors/plugins.d/"/>
+          </para><para>
+          Cannot be combined with configText.
+        '';
+      };
+
       config = mkOption {
         type = types.attrsOf types.attrs;
         default = {};
diff --git a/nixpkgs/nixos/modules/services/monitoring/prometheus/default.nix b/nixpkgs/nixos/modules/services/monitoring/prometheus/default.nix
index bf4dfc666bb6..1b1503ab5fc0 100644
--- a/nixpkgs/nixos/modules/services/monitoring/prometheus/default.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/prometheus/default.nix
@@ -325,7 +325,8 @@ let
   promTypes.relabel_config = types.submodule {
     options = {
       source_labels = mkOption {
-        type = types.listOf types.str;
+        type = with types; nullOr (listOf str);
+        default = null;
         description = ''
           The source labels select values from existing labels. Their content
           is concatenated using the configured separator and matched against
diff --git a/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix b/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix
index 5308c9c4ee08..0a084561002f 100644
--- a/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/bind.nix b/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/bind.nix
new file mode 100644
index 000000000000..a9746c4d65d5
--- /dev/null
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix b/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix
index 4ca6d4e5f8b6..c47e87a3dc35 100644
--- a/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix
@@ -18,12 +18,34 @@ in
     socketPath = mkOption {
       type = types.path;
       default = "/var/run/dovecot/stats";
-      example = "/var/run/dovecot2/stats";
+      example = "/var/run/dovecot2/old-stats";
       description = ''
         Path under which the stats socket is placed.
         The user/group under which the exporter runs,
         should be able to access the socket in order
         to scrape the metrics successfully.
+
+        Please keep in mind that the stats module has changed in
+        <link xlink:href="https://wiki2.dovecot.org/Upgrading/2.3">Dovecot 2.3+</link> which
+        is not <link xlink:href="https://github.com/kumina/dovecot_exporter/issues/8">compatible with this exporter</link>.
+
+        The following extra config has to be passed to Dovecot to ensure that recent versions
+        work with this exporter:
+        <programlisting>
+        {
+          <xref linkend="opt-services.prometheus.exporters.dovecot.enable" /> = true;
+          <xref linkend="opt-services.prometheus.exporters.dovecot.socketPath" /> = "/var/run/dovecot2/old-stats";
+          <xref linkend="opt-services.dovecot2.extraConfig" /> = '''
+            mail_plugins = $mail_plugins old_stats
+            service old-stats {
+              unix_listener old-stats {
+                user = nobody
+                group = nobody
+              }
+            }
+          ''';
+        }
+        </programlisting>
       '';
     };
     scopes = mkOption {
diff --git a/nixpkgs/nixos/modules/services/network-filesystems/glusterfs.nix b/nixpkgs/nixos/modules/services/network-filesystems/glusterfs.nix
index eb7f060c7da0..00875c6c4a18 100644
--- a/nixpkgs/nixos/modules/services/network-filesystems/glusterfs.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/networking/ddclient.nix b/nixpkgs/nixos/modules/services/networking/ddclient.nix
index a70967820b32..9a2e13e9553c 100644
--- a/nixpkgs/nixos/modules/services/networking/ddclient.nix
+++ b/nixpkgs/nixos/modules/services/networking/ddclient.nix
@@ -182,10 +182,9 @@ with lib;
       serviceConfig = rec {
         DynamicUser = true;
         RuntimeDirectory = StateDirectory;
-        RuntimeDirectoryMode = "0750";
         StateDirectory = builtins.baseNameOf dataDir;
         Type = "oneshot";
-        ExecStartPre = "!${lib.getBin pkgs.coreutils}/bin/install -m660 ${cfg.configFile} /run/${RuntimeDirectory}/ddclient.conf";
+        ExecStartPre = "!${lib.getBin pkgs.coreutils}/bin/install -m666 ${cfg.configFile} /run/${RuntimeDirectory}/ddclient.conf";
         ExecStart = "${lib.getBin pkgs.ddclient}/bin/ddclient -file /run/${RuntimeDirectory}/ddclient.conf";
       };
     };
diff --git a/nixpkgs/nixos/modules/services/networking/firefox/sync-server.nix b/nixpkgs/nixos/modules/services/networking/firefox/sync-server.nix
index 97d223a56cab..6842aa735617 100644
--- a/nixpkgs/nixos/modules/services/networking/firefox/sync-server.nix
+++ b/nixpkgs/nixos/modules/services/networking/firefox/sync-server.nix
@@ -13,7 +13,7 @@ let
     overrides = ${cfg.privateConfig}
 
     [server:main]
-    use = egg:Paste#http
+    use = egg:gunicorn
     host = ${cfg.listen.address}
     port = ${toString cfg.listen.port}
 
@@ -30,6 +30,8 @@ let
     audiences = ${removeSuffix "/" cfg.publicUrl}
   '';
 
+  user = "syncserver";
+  group = "syncserver";
 in
 
 {
@@ -126,15 +128,14 @@ in
 
   config = mkIf cfg.enable {
 
-    systemd.services.syncserver = let
-      syncServerEnv = pkgs.python.withPackages(ps: with ps; [ syncserver pasteScript requests ]);
-      user = "syncserver";
-      group = "syncserver";
-    in {
+    systemd.services.syncserver = {
       after = [ "network.target" ];
       description = "Firefox Sync Server";
       wantedBy = [ "multi-user.target" ];
-      path = [ pkgs.coreutils syncServerEnv ];
+      path = [
+        pkgs.coreutils
+        (pkgs.python.withPackages (ps: [ pkgs.syncserver ps.gunicorn ]))
+      ];
 
       serviceConfig = {
         User = user;
@@ -166,14 +167,17 @@ in
           chown ${user}:${group} ${defaultDbLocation}
         fi
       '';
-      serviceConfig.ExecStart = "${syncServerEnv}/bin/paster serve ${syncServerIni}";
+
+      script = ''
+        gunicorn --paste ${syncServerIni}
+      '';
     };
 
-    users.users.syncserver = {
-      group = "syncserver";
+    users.users.${user} = {
+      inherit group;
       isSystemUser = true;
     };
 
-    users.groups.syncserver = {};
+    users.groups.${group} = {};
   };
 }
diff --git a/nixpkgs/nixos/modules/services/networking/ndppd.nix b/nixpkgs/nixos/modules/services/networking/ndppd.nix
index 1d6c48dd8d37..ba17f1ba825a 100644
--- a/nixpkgs/nixos/modules/services/networking/ndppd.nix
+++ b/nixpkgs/nixos/modules/services/networking/ndppd.nix
@@ -5,43 +5,163 @@ with lib;
 let
   cfg = config.services.ndppd;
 
-  configFile = pkgs.runCommand "ndppd.conf" {} ''
-    substitute ${pkgs.ndppd}/etc/ndppd.conf $out \
-      --replace eth0 ${cfg.interface} \
-      --replace 1111:: ${cfg.network}
-  '';
-in {
-  options = {
-    services.ndppd = {
-      enable = mkEnableOption "daemon that proxies NDP (Neighbor Discovery Protocol) messages between interfaces";
+  render = s: f: concatStringsSep "\n" (mapAttrsToList f s);
+  prefer = a: b: if a != null then a else b;
+
+  ndppdConf = prefer cfg.configFile (pkgs.writeText "ndppd.conf" ''
+    route-ttl ${toString cfg.routeTTL}
+    ${render cfg.proxies (proxyInterfaceName: proxy: ''
+    proxy ${prefer proxy.interface proxyInterfaceName} {
+      router ${boolToString proxy.router}
+      timeout ${toString proxy.timeout}
+      ttl ${toString proxy.ttl}
+      ${render proxy.rules (ruleNetworkName: rule: ''
+      rule ${prefer rule.network ruleNetworkName} {
+        ${rule.method}${if rule.method == "iface" then " ${rule.interface}" else ""}
+      }'')}
+    }'')}
+  '');
+
+  proxy = types.submodule {
+    options = {
       interface = mkOption {
-        type = types.string;
-        default = "eth0";
-        example = "ens3";
-        description = "Interface which is on link-level with router.";
+        type = types.nullOr types.str;
+        description = ''
+          Listen for any Neighbor Solicitation messages on this interface,
+          and respond to them according to a set of rules.
+          Defaults to the name of the attrset.
+        '';
+        default = null;
+      };
+      router = mkOption {
+        type = types.bool;
+        description = ''
+          Turns on or off the router flag for Neighbor Advertisement Messages.
+        '';
+        default = true;
+      };
+      timeout = mkOption {
+        type = types.int;
+        description = ''
+          Controls how long to wait for a Neighbor Advertisment Message before 
+          invalidating the entry, in milliseconds.
+        '';
+        default = 500;
+      };
+      ttl = mkOption {
+        type = types.int;
+        description = ''
+          Controls how long a valid or invalid entry remains in the cache, in 
+          milliseconds.
+        '';
+        default = 30000;
       };
+      rules = mkOption {
+        type = types.attrsOf rule;
+        description = ''
+          This is a rule that the target address is to match against. If no netmask
+          is provided, /128 is assumed. You may have several rule sections, and the
+          addresses may or may not overlap.
+        '';
+        default = {};
+      };
+    };
+  };
+
+  rule = types.submodule {
+    options = {
       network = mkOption {
-        type = types.string;
-        default = "1111::";
-        example = "2001:DB8::/32";
-        description = "Network that we proxy.";
+        type = types.nullOr types.str;
+        description = ''
+          This is the target address is to match against. If no netmask
+          is provided, /128 is assumed. The addresses of serveral rules
+          may or may not overlap.
+          Defaults to the name of the attrset.
+        '';
+        default = null;
+      };
+      method = mkOption {
+        type = types.enum [ "static" "iface" "auto" ];
+        description = ''
+          static: Immediately answer any Neighbor Solicitation Messages
+            (if they match the IP rule).
+          iface: Forward the Neighbor Solicitation Message through the specified
+            interface and only respond if a matching Neighbor Advertisement
+            Message is received.
+          auto: Same as iface, but instead of manually specifying the outgoing
+            interface, check for a matching route in /proc/net/ipv6_route.
+        '';
+        default = "auto";
       };
-      configFile = mkOption {
-        type = types.nullOr types.path;
+      interface = mkOption {
+        type = types.nullOr types.str;
+        description = "Interface to use when method is iface.";
         default = null;
-        description = "Path to configuration file.";
       };
     };
   };
 
+in {
+  options.services.ndppd = {
+    enable = mkEnableOption "daemon that proxies NDP (Neighbor Discovery Protocol) messages between interfaces";
+    interface = mkOption {
+      type = types.nullOr types.str;
+      description = ''
+        Interface which is on link-level with router.
+        (Legacy option, use services.ndppd.proxies.&lt;interface&gt;.rules.&lt;network&gt; instead)
+      '';
+      default = null;
+      example = "eth0";
+    };
+    network = mkOption {
+      type = types.nullOr types.str;
+      description = ''
+        Network that we proxy.
+        (Legacy option, use services.ndppd.proxies.&lt;interface&gt;.rules.&lt;network&gt; instead)
+      '';
+      default = null;
+      example = "1111::/64";
+    };
+    configFile = mkOption {
+      type = types.nullOr types.path;
+      description = "Path to configuration file.";
+      default = null;
+    };
+    routeTTL = mkOption {
+      type = types.int;
+      description = ''
+        This tells 'ndppd' how often to reload the route file /proc/net/ipv6_route,
+        in milliseconds.
+      '';
+      default = 30000;
+    };
+    proxies = mkOption {
+      type = types.attrsOf proxy;
+      description = ''
+        This sets up a listener, that will listen for any Neighbor Solicitation
+        messages, and respond to them according to a set of rules.
+      '';
+      default = {};
+      example = { "eth0".rules."1111::/64" = {}; };
+    };
+  };
+
   config = mkIf cfg.enable {
-    systemd.packages = [ pkgs.ndppd ];
-    environment.etc."ndppd.conf".source = if (cfg.configFile != null) then cfg.configFile else configFile;
+    warnings = mkIf (cfg.interface != null && cfg.network != null) [ ''
+      The options services.ndppd.interface and services.ndppd.network will probably be removed soon,
+      please use services.ndppd.proxies.<interface>.rules.<network> instead.
+    '' ];
+
+    services.ndppd.proxies = mkIf (cfg.interface != null && cfg.network != null) {
+      "${cfg.interface}".rules."${cfg.network}" = {};
+    };
+
     systemd.services.ndppd = {
-      serviceConfig.RuntimeDirectory = [ "ndppd" ];
+      description = "NDP Proxy Daemon";
+      documentation = [ "man:ndppd(1)" "man:ndppd.conf(5)" ];
+      after = [ "network-pre.target" ];
       wantedBy = [ "multi-user.target" ];
+      serviceConfig.ExecStart = "${pkgs.ndppd}/bin/ndppd -c ${ndppdConf}";
     };
   };
-
-  meta.maintainers = with maintainers; [ gnidorah ];
 }
diff --git a/nixpkgs/nixos/modules/services/networking/nsd.nix b/nixpkgs/nixos/modules/services/networking/nsd.nix
index cde47bf23eae..8b918dab86dd 100644
--- a/nixpkgs/nixos/modules/services/networking/nsd.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/networking/nylon.nix b/nixpkgs/nixos/modules/services/networking/nylon.nix
index 613b0e0fb51a..b061ce34ed2c 100644
--- a/nixpkgs/nixos/modules/services/networking/nylon.nix
+++ b/nixpkgs/nixos/modules/services/networking/nylon.nix
@@ -142,7 +142,6 @@ in
       description = "Collection of named nylon instances";
       type = with types; loaOf (submodule nylonOpts);
       internal = true;
-      options = [ nylonOpts ];
     };
 
   };
diff --git a/nixpkgs/nixos/modules/services/networking/prosody.nix b/nixpkgs/nixos/modules/services/networking/prosody.nix
index 25b7d6dbeba2..de316e5f4669 100644
--- a/nixpkgs/nixos/modules/services/networking/prosody.nix
+++ b/nixpkgs/nixos/modules/services/networking/prosody.nix
@@ -513,6 +513,7 @@ in
         RuntimeDirectory = [ "prosody" ];
         PIDFile = "/run/prosody/prosody.pid";
         ExecStart = "${cfg.package}/bin/prosodyctl start";
+        ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
       };
     };
 
diff --git a/nixpkgs/nixos/modules/services/networking/shairport-sync.nix b/nixpkgs/nixos/modules/services/networking/shairport-sync.nix
index 90c0689dc7bf..68e005ab81da 100644
--- a/nixpkgs/nixos/modules/services/networking/shairport-sync.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix b/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
index 5fab79f1b3d7..95dc8a62a454 100644
--- a/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
@@ -11,7 +11,7 @@ let
 
   userOptions = {
 
-    openssh.authorizedKeys = {
+    options.openssh.authorizedKeys = {
       keys = mkOption {
         type = types.listOf types.str;
         default = [];
@@ -320,7 +320,7 @@ in
     };
 
     users.users = mkOption {
-      options = [ userOptions ];
+      type = with types; loaOf (submodule userOptions);
     };
 
   };
@@ -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/nixpkgs/nixos/modules/services/networking/syncthing.nix b/nixpkgs/nixos/modules/services/networking/syncthing.nix
index b2ef1885a955..702481ec5177 100644
--- a/nixpkgs/nixos/modules/services/networking/syncthing.nix
+++ b/nixpkgs/nixos/modules/services/networking/syncthing.nix
@@ -122,7 +122,7 @@ in {
 
     systemd.packages = [ pkgs.syncthing ];
 
-    users = mkIf (cfg.user == defaultUser) {
+    users = mkIf (cfg.systemService && cfg.user == defaultUser) {
       users."${defaultUser}" =
         { group = cfg.group;
           home  = cfg.dataDir;
diff --git a/nixpkgs/nixos/modules/services/networking/unifi.nix b/nixpkgs/nixos/modules/services/networking/unifi.nix
index ac10e77ba306..89b9ac4eadf5 100644
--- a/nixpkgs/nixos/modules/services/networking/unifi.nix
+++ b/nixpkgs/nixos/modules/services/networking/unifi.nix
@@ -184,4 +184,5 @@ in
 
   };
 
+  meta.maintainers = with lib.maintainers; [ erictapen ];
 }
diff --git a/nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix b/nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix
index c788528fa47b..8622212f0856 100644
--- a/nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix
+++ b/nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix
@@ -1,4 +1,4 @@
-{ config, lib, pkgs, ... }:
+{ config, lib, pkgs, utils, ... }:
 
 with lib;
 
@@ -193,7 +193,7 @@ in {
     # FIXME: start a separate wpa_supplicant instance per interface.
     systemd.services.wpa_supplicant = let
       ifaces = cfg.interfaces;
-      deviceUnit = interface: [ "sys-subsystem-net-devices-${interface}.device" ];
+      deviceUnit = interface: [ "sys-subsystem-net-devices-${utils.escapeSystemdPath interface}.device" ];
     in {
       description = "WPA Supplicant";
 
diff --git a/nixpkgs/nixos/modules/services/networking/xrdp.nix b/nixpkgs/nixos/modules/services/networking/xrdp.nix
index 9ed3025e47d4..a1c5d879f3cb 100644
--- a/nixpkgs/nixos/modules/services/networking/xrdp.nix
+++ b/nixpkgs/nixos/modules/services/networking/xrdp.nix
@@ -26,6 +26,12 @@ let
     substituteInPlace $out/sesman.ini \
       --replace LogFile=xrdp-sesman.log LogFile=/dev/null \
       --replace EnableSyslog=1 EnableSyslog=0
+
+    # Ensure that clipboard works for non-ASCII characters
+    sed -i -e '/.*SessionVariables.*/ a\
+    LANG=${config.i18n.defaultLocale}\
+    LOCALE_ARCHIVE=${config.i18n.glibcLocales}/lib/locale/locale-archive
+    ' $out/sesman.ini
   '';
 in
 {
diff --git a/nixpkgs/nixos/modules/services/search/elasticsearch-curator.nix b/nixpkgs/nixos/modules/services/search/elasticsearch-curator.nix
index 43785c392fee..8cb1275284a3 100644
--- a/nixpkgs/nixos/modules/services/search/elasticsearch-curator.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/security/certmgr.nix b/nixpkgs/nixos/modules/services/security/certmgr.nix
index 22d5817ec4f0..e89078883ebe 100644
--- a/nixpkgs/nixos/modules/services/security/certmgr.nix
+++ b/nixpkgs/nixos/modules/services/security/certmgr.nix
@@ -30,13 +30,20 @@ let
 
   preStart = ''
     ${concatStringsSep " \\\n" (["mkdir -p"] ++ map escapeShellArg specPaths)}
-    ${pkgs.certmgr}/bin/certmgr -f ${certmgrYaml} check
+    ${cfg.package}/bin/certmgr -f ${certmgrYaml} check
   '';
 in
 {
   options.services.certmgr = {
     enable = mkEnableOption "certmgr";
 
+    package = mkOption {
+      type = types.package;
+      default = pkgs.certmgr;
+      defaultText = "pkgs.certmgr";
+      description = "Which certmgr package to use in the service.";
+    };
+
     defaultRemote = mkOption {
       type = types.str;
       default = "127.0.0.1:8888";
@@ -187,7 +194,7 @@ in
       serviceConfig = {
         Restart = "always";
         RestartSec = "10s";
-        ExecStart = "${pkgs.certmgr}/bin/certmgr -f ${certmgrYaml}";
+        ExecStart = "${cfg.package}/bin/certmgr -f ${certmgrYaml}";
       };
     };
   };
diff --git a/nixpkgs/nixos/modules/services/security/munge.nix b/nixpkgs/nixos/modules/services/security/munge.nix
index fda864f2c30a..504bc66c6d10 100644
--- a/nixpkgs/nixos/modules/services/security/munge.nix
+++ b/nixpkgs/nixos/modules/services/security/munge.nix
@@ -50,7 +50,7 @@ in
       path = [ pkgs.munge pkgs.coreutils ];
 
       preStart = ''
-        chmod 0700 ${cfg.password}
+        chmod 0400 ${cfg.password}
         mkdir -p /var/lib/munge -m 0711
         chown -R munge:munge /var/lib/munge
         mkdir -p /run/munge -m 0755
diff --git a/nixpkgs/nixos/modules/services/security/nginx-sso.nix b/nixpkgs/nixos/modules/services/security/nginx-sso.nix
new file mode 100644
index 000000000000..d792f90abe64
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/security/nginx-sso.nix
@@ -0,0 +1,58 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.nginx.sso;
+  pkg = getBin pkgs.nginx-sso;
+  configYml = pkgs.writeText "nginx-sso.yml" (builtins.toJSON cfg.configuration);
+in {
+  options.services.nginx.sso = {
+    enable = mkEnableOption "nginx-sso service";
+
+    configuration = mkOption {
+      type = types.attrsOf types.unspecified;
+      default = {};
+      example = literalExample ''
+        {
+          listen = { addr = "127.0.0.1"; port = 8080; };
+
+          providers.token.tokens = {
+            myuser = "MyToken";
+          };
+
+          acl = {
+            rule_sets = [
+              {
+                rules = [ { field = "x-application"; equals = "MyApp"; } ];
+                allow = [ "myuser" ];
+              }
+            ];
+          };
+        }
+      '';
+      description = ''
+        nginx-sso configuration
+        (<link xlink:href="https://github.com/Luzifer/nginx-sso/wiki/Main-Configuration">documentation</link>)
+        as a Nix attribute set.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.nginx-sso = {
+      description = "Nginx SSO Backend";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        ExecStart = ''
+          ${pkg}/bin/nginx-sso \
+            --config ${configYml} \
+            --frontend-dir ${pkg}/share/frontend
+        '';
+        Restart = "always";
+        DynamicUser = true;
+      };
+    };
+  };
+}
diff --git a/nixpkgs/nixos/modules/services/security/sks.nix b/nixpkgs/nixos/modules/services/security/sks.nix
index 9f0261038d5b..8136a5c763a9 100644
--- a/nixpkgs/nixos/modules/services/security/sks.nix
+++ b/nixpkgs/nixos/modules/services/security/sks.nix
@@ -5,6 +5,9 @@ with lib;
 let
   cfg = config.services.sks;
   sksPkg = cfg.package;
+  dbConfig = pkgs.writeText "DB_CONFIG" ''
+    ${cfg.extraDbConfig}
+  '';
 
 in {
   meta.maintainers = with maintainers; [ primeos calbrecht jcumming ];
@@ -39,6 +42,20 @@ in {
         '';
       };
 
+      extraDbConfig = mkOption {
+        type = types.str;
+        default = "";
+        description = ''
+          Set contents of the files "KDB/DB_CONFIG" and "PTree/DB_CONFIG" within
+          the ''${dataDir} directory. This is used to configure options for the
+          database for the sks key server.
+
+          Documentation of available options are available in the file named
+          "sampleConfig/DB_CONFIG" in the following repository:
+          https://bitbucket.org/skskeyserver/sks-keyserver/src
+        '';
+      };
+
       hkpAddress = mkOption {
         default = [ "127.0.0.1" "::1" ];
         type = types.listOf types.str;
@@ -99,6 +116,17 @@ in {
           ${lib.optionalString (cfg.webroot != null)
             "ln -sfT \"${cfg.webroot}\" web"}
           mkdir -p dump
+          # Check that both database configs are symlinks before overwriting them
+          if [ -e KDB/DB_CONFIG ] && [ ! -L KBD/DB_CONFIG ]; then
+            echo "KDB/DB_CONFIG exists but is not a symlink." >&2
+            exit 1
+          fi
+          if [ -e PTree/DB_CONFIG ] && [ ! -L PTree/DB_CONFIG ]; then
+            echo "PTree/DB_CONFIG exists but is not a symlink." >&2
+            exit 1
+          fi
+          ln -sf ${dbConfig} KDB/DB_CONFIG
+          ln -sf ${dbConfig} PTree/DB_CONFIG
           ${sksPkg}/bin/sks build dump/*.gpg -n 10 -cache 100 || true #*/
           ${sksPkg}/bin/sks cleandb || true
           ${sksPkg}/bin/sks pbuild -cache 20 -ptree_cache 70 || true
diff --git a/nixpkgs/nixos/modules/services/security/sshguard.nix b/nixpkgs/nixos/modules/services/security/sshguard.nix
index 137c3d610186..3892cd5c72b8 100644
--- a/nixpkgs/nixos/modules/services/security/sshguard.nix
+++ b/nixpkgs/nixos/modules/services/security/sshguard.nix
@@ -4,6 +4,7 @@ with lib;
 
 let
   cfg = config.services.sshguard;
+
 in {
 
   ###### interface
@@ -77,65 +78,65 @@ in {
             Systemd services sshguard should receive logs of.
           '';
       };
-
     };
-
   };
 
-
   ###### implementation
 
   config = mkIf cfg.enable {
 
-    environment.systemPackages = [ pkgs.sshguard pkgs.iptables pkgs.ipset ];
-
     environment.etc."sshguard.conf".text = let
-        list_services = ( name:  "-t ${name} ");
-      in ''
-        BACKEND="${pkgs.sshguard}/libexec/sshg-fw-ipset"
-        LOGREADER="LANG=C ${pkgs.systemd}/bin/journalctl -afb -p info -n1 ${toString (map list_services cfg.services)} -o cat"
+      args = lib.concatStringsSep " " ([
+        "-afb"
+        "-p info"
+        "-o cat"
+        "-n1"
+      ] ++ (map (name: "-t ${escapeShellArg name}") cfg.services));
+    in ''
+      BACKEND="${pkgs.sshguard}/libexec/sshg-fw-ipset"
+      LOGREADER="LANG=C ${pkgs.systemd}/bin/journalctl ${args}"
+    '';
+
+    systemd.services.sshguard = {
+      description = "SSHGuard brute-force attacks protection system";
+
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network.target" ];
+      partOf = optional config.networking.firewall.enable "firewall.service";
+
+      path = with pkgs; [ iptables ipset iproute systemd ];
+
+      postStart = ''
+        ${pkgs.ipset}/bin/ipset -quiet create -exist sshguard4 hash:ip family inet
+        ${pkgs.ipset}/bin/ipset -quiet create -exist sshguard6 hash:ip family inet6
+        ${pkgs.iptables}/bin/iptables  -I INPUT -m set --match-set sshguard4 src -j DROP
+        ${pkgs.iptables}/bin/ip6tables -I INPUT -m set --match-set sshguard6 src -j DROP
+      '';
+
+      preStop = ''
+        ${pkgs.iptables}/bin/iptables  -D INPUT -m set --match-set sshguard4 src -j DROP
+        ${pkgs.iptables}/bin/ip6tables -D INPUT -m set --match-set sshguard6 src -j DROP
       '';
 
-    systemd.services.sshguard =
-      { description = "SSHGuard brute-force attacks protection system";
-
-        wantedBy = [ "multi-user.target" ];
-        after = [ "network.target" ];
-        partOf = optional config.networking.firewall.enable "firewall.service";
-
-        path = [ pkgs.iptables pkgs.ipset pkgs.iproute pkgs.systemd ];
-
-        postStart = ''
-          mkdir -p /var/lib/sshguard
-          ${pkgs.ipset}/bin/ipset -quiet create -exist sshguard4 hash:ip family inet
-          ${pkgs.ipset}/bin/ipset -quiet create -exist sshguard6 hash:ip family inet6
-          ${pkgs.iptables}/bin/iptables -I INPUT -m set --match-set sshguard4 src -j DROP
-          ${pkgs.iptables}/bin/ip6tables -I INPUT -m set --match-set sshguard6 src -j DROP
-        '';
-
-        preStop = ''
-          ${pkgs.iptables}/bin/iptables -D INPUT -m set --match-set sshguard4 src -j DROP
-          ${pkgs.iptables}/bin/ip6tables -D INPUT -m set --match-set sshguard6 src -j DROP
-        '';
-
-        unitConfig.Documentation = "man:sshguard(8)";
-
-        serviceConfig = {
-            Type = "simple";
-            ExecStart = let
-                list_whitelist = ( name:  "-w ${name} ");
-              in ''
-                 ${pkgs.sshguard}/bin/sshguard -a ${toString cfg.attack_threshold} ${optionalString (cfg.blacklist_threshold != null) "-b ${toString cfg.blacklist_threshold}:${cfg.blacklist_file} "}-i /run/sshguard/sshguard.pid -p ${toString cfg.blocktime} -s ${toString cfg.detection_time} ${toString (map list_whitelist cfg.whitelist)}
-              '';
-            PIDFile = "/run/sshguard/sshguard.pid";
-            Restart = "always";
-
-            ReadOnlyDirectories = "/";
-            ReadWriteDirectories = "/run/sshguard /var/lib/sshguard";
-            RuntimeDirectory = "sshguard";
-            StateDirectory = "sshguard";
-            CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_RAW";
-         };
+      unitConfig.Documentation = "man:sshguard(8)";
+
+      serviceConfig = {
+        Type = "simple";
+        ExecStart = let
+          args = lib.concatStringsSep " " ([
+            "-a ${toString cfg.attack_threshold}"
+            "-p ${toString cfg.blocktime}"
+            "-s ${toString cfg.detection_time}"
+            (optionalString (cfg.blacklist_threshold != null) "-b ${toString cfg.blacklist_threshold}:${cfg.blacklist_file}")
+          ] ++ (map (name: "-w ${escapeShellArg name}") cfg.whitelist));
+        in "${pkgs.sshguard}/bin/sshguard ${args}";
+        Restart = "always";
+        ProtectSystem = "strict";
+        ProtectHome = "tmpfs";
+        RuntimeDirectory = "sshguard";
+        StateDirectory = "sshguard";
+        CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_RAW";
       };
+    };
   };
 }
diff --git a/nixpkgs/nixos/modules/services/system/kerberos.nix b/nixpkgs/nixos/modules/services/system/kerberos.nix
deleted file mode 100644
index e2c45ed64ac0..000000000000
--- a/nixpkgs/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/nixpkgs/nixos/modules/services/system/kerberos/default.nix b/nixpkgs/nixos/modules/services/system/kerberos/default.nix
new file mode 100644
index 000000000000..26ac85de402f
--- /dev/null
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/system/kerberos/heimdal.nix b/nixpkgs/nixos/modules/services/system/kerberos/heimdal.nix
new file mode 100644
index 000000000000..d0f470f836ed
--- /dev/null
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/system/kerberos/mit.nix b/nixpkgs/nixos/modules/services/system/kerberos/mit.nix
new file mode 100644
index 000000000000..a53d9dd0c6b5
--- /dev/null
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/torrent/transmission.nix b/nixpkgs/nixos/modules/services/torrent/transmission.nix
index 719eb76f42c2..f544928fb6b1 100644
--- a/nixpkgs/nixos/modules/services/torrent/transmission.nix
+++ b/nixpkgs/nixos/modules/services/torrent/transmission.nix
@@ -143,6 +143,9 @@ in
           ${getLib pkgs.lz4}/lib/liblz4*.so*               mr,
           ${getLib pkgs.libkrb5}/lib/lib*.so*              mr,
           ${getLib pkgs.keyutils}/lib/libkeyutils*.so*     mr,
+          ${getLib pkgs.utillinuxMinimal.out}/lib/libblkid.so.* mr,
+          ${getLib pkgs.utillinuxMinimal.out}/lib/libmount.so.* mr,
+          ${getLib pkgs.utillinuxMinimal.out}/lib/libuuid.so.* mr,
 
           @{PROC}/sys/kernel/random/uuid   r,
           @{PROC}/sys/vm/overcommit_memory r,
diff --git a/nixpkgs/nixos/modules/services/web-apps/atlassian/confluence.nix b/nixpkgs/nixos/modules/services/web-apps/atlassian/confluence.nix
index f896d92fd6fc..b71887fcc6ee 100644
--- a/nixpkgs/nixos/modules/services/web-apps/atlassian/confluence.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/web-apps/atlassian/crowd.nix b/nixpkgs/nixos/modules/services/web-apps/atlassian/crowd.nix
index b6cb9f3b7c41..9f48d1e16a44 100644
--- a/nixpkgs/nixos/modules/services/web-apps/atlassian/crowd.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/web-apps/atlassian/jira.nix b/nixpkgs/nixos/modules/services/web-apps/atlassian/jira.nix
index f5ec0a5f31b8..dba970c612bc 100644
--- a/nixpkgs/nixos/modules/services/web-apps/atlassian/jira.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix b/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
index ecb1c5615d58..ee1354d6a997 100644
--- a/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
@@ -426,7 +426,7 @@ in {
               "~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\\.php(?:$|/)" = {
                 priority = 500;
                 extraConfig = ''
-                  include ${pkgs.nginxMainline}/conf/fastcgi.conf;
+                  include ${config.services.nginx.package}/conf/fastcgi.conf;
                   fastcgi_split_path_info ^(.+\.php)(/.*)$;
                   fastcgi_param PATH_INFO $fastcgi_path_info;
                   fastcgi_param HTTPS ${if cfg.https then "on" else "off"};
diff --git a/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
index 73607c6f9a3b..bb9623347869 100644
--- a/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
@@ -151,7 +151,7 @@ let
 
 
   loggingConf = (if mainCfg.logFormat != "none" then ''
-    ErrorLog ${mainCfg.logDir}/error_log
+    ErrorLog ${mainCfg.logDir}/error.log
 
     LogLevel notice
 
@@ -160,7 +160,7 @@ let
     LogFormat "%{Referer}i -> %U" referer
     LogFormat "%{User-agent}i" agent
 
-    CustomLog ${mainCfg.logDir}/access_log ${mainCfg.logFormat}
+    CustomLog ${mainCfg.logDir}/access.log ${mainCfg.logFormat}
   '' else ''
     ErrorLog /dev/null
   '');
@@ -187,8 +187,8 @@ let
     SSLRandomSeed startup builtin
     SSLRandomSeed connect builtin
 
-    SSLProtocol All -SSLv2 -SSLv3
-    SSLCipherSuite HIGH:!aNULL:!MD5:!EXP
+    SSLProtocol ${mainCfg.sslProtocols}
+    SSLCipherSuite ${mainCfg.sslCiphers}
     SSLHonorCipherOrder on
   '';
 
@@ -261,8 +261,8 @@ let
     '' else ""}
 
     ${if !isMainServer && mainCfg.logPerVirtualHost then ''
-      ErrorLog ${mainCfg.logDir}/error_log-${cfg.hostName}
-      CustomLog ${mainCfg.logDir}/access_log-${cfg.hostName} ${cfg.logFormat}
+      ErrorLog ${mainCfg.logDir}/error-${cfg.hostName}.log
+      CustomLog ${mainCfg.logDir}/access-${cfg.hostName}.log ${cfg.logFormat}
     '' else ""}
 
     ${optionalString (robotsTxt != "") ''
@@ -630,6 +630,19 @@ in
         description =
           "Maximum number of httpd requests answered per httpd child (prefork), 0 means unlimited";
       };
+
+      sslCiphers = mkOption {
+        type = types.str;
+        default = "HIGH:!aNULL:!MD5:!EXP";
+        description = "Cipher Suite available for negotiation in SSL proxy handshake.";
+      };
+
+      sslProtocols = mkOption {
+        type = types.str;
+        default = "All -SSLv2 -SSLv3";
+        example = "All -SSLv2 -SSLv3 -TLSv1";
+        description = "Allowed SSL/TLS protocol versions.";
+      };
     }
 
     # Include the options shared between the main server and virtual hosts.
diff --git a/nixpkgs/nixos/modules/services/web-servers/apache-httpd/wordpress.nix b/nixpkgs/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
index c810b914e258..c68bfd25f6a8 100644
--- a/nixpkgs/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/web-servers/lighttpd/collectd.nix b/nixpkgs/nixos/modules/services/web-servers/lighttpd/collectd.nix
index 35b5edced68b..e70c980d5243 100644
--- a/nixpkgs/nixos/modules/services/web-servers/lighttpd/collectd.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/web-servers/phpfpm/default.nix b/nixpkgs/nixos/modules/services/web-servers/phpfpm/default.nix
index e1f4ff5db7f2..152c89a2caec 100644
--- a/nixpkgs/nixos/modules/services/web-servers/phpfpm/default.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/phpfpm/default.nix
@@ -8,21 +8,31 @@ let
 
   stateDir = "/run/phpfpm";
 
-  poolConfigs = cfg.poolConfigs // mapAttrs mkPool cfg.pools;
+  poolConfigs =
+    (mapAttrs mapPoolConfig cfg.poolConfigs) //
+    (mapAttrs mapPool cfg.pools);
 
-  mkPool = n: p: ''
-    listen = ${p.listen}
-    ${p.extraConfig}
-  '';
+  mapPoolConfig = n: p: {
+    phpPackage = cfg.phpPackage;
+    config = p;
+  };
+
+  mapPool = n: p: {
+    phpPackage = p.phpPackage;
+    config = ''
+      listen = ${p.listen}
+      ${p.extraConfig}
+    '';
+  };
 
-  fpmCfgFile = pool: poolConfig: pkgs.writeText "phpfpm-${pool}.conf" ''
+  fpmCfgFile = pool: conf: pkgs.writeText "phpfpm-${pool}.conf" ''
     [global]
     error_log = syslog
     daemonize = no
     ${cfg.extraConfig}
 
     [${pool}]
-    ${poolConfig}
+    ${conf}
   '';
 
   phpIni = pkgs.runCommand "php.ini" {
@@ -97,13 +107,14 @@ in {
 
       pools = mkOption {
         type = types.attrsOf (types.submodule (import ./pool-options.nix {
-          inherit lib;
+          inherit lib config;
         }));
         default = {};
         example = literalExample ''
          {
            mypool = {
              listen = "/path/to/unix/socket";
+             phpPackage = pkgs.php;
              extraConfig = '''
                user = nobody
                pm = dynamic
@@ -144,7 +155,7 @@ in {
           mkdir -p ${stateDir}
         '';
         serviceConfig = let
-          cfgFile = fpmCfgFile pool poolConfig;
+          cfgFile = fpmCfgFile pool poolConfig.config;
         in {
           Slice = "phpfpm.slice";
           PrivateDevices = true;
@@ -153,7 +164,7 @@ in {
           # XXX: We need AF_NETLINK to make the sendmail SUID binary from postfix work
           RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK";
           Type = "notify";
-          ExecStart = "${cfg.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${phpIni}";
+          ExecStart = "${poolConfig.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${phpIni}";
           ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID";
         };
       }
diff --git a/nixpkgs/nixos/modules/services/web-servers/phpfpm/pool-options.nix b/nixpkgs/nixos/modules/services/web-servers/phpfpm/pool-options.nix
index cc688c2c48a2..40c83cddb957 100644
--- a/nixpkgs/nixos/modules/services/web-servers/phpfpm/pool-options.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/phpfpm/pool-options.nix
@@ -1,4 +1,8 @@
-{ lib }:
+{ lib, config }:
+
+let
+  fpmCfg = config.services.phpfpm;
+in
 
 with lib; {
 
@@ -12,6 +16,15 @@ with lib; {
       '';
     };
 
+    phpPackage = mkOption {
+      type = types.package;
+      default = fpmCfg.phpPackage;
+      defaultText = "config.services.phpfpm.phpPackage";
+      description = ''
+        The PHP package to use for running this PHP-FPM pool.
+      '';
+    };
+
     extraConfig = mkOption {
       type = types.lines;
       example = ''
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
index ba6d333b534e..7544ba4638ac 100644
--- a/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixpkgs/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";
@@ -44,6 +36,8 @@ let
      ${pkgs.glib.dev}/bin/glib-compile-schemas $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas/
     '';
 
+  flashbackEnabled = cfg.flashback.enableMetacity || length cfg.flashback.customSessions > 0;
+
 in {
 
   options = {
@@ -79,6 +73,36 @@ in {
       };
 
       debug = mkEnableOption "gnome-session debug messages";
+
+      flashback = {
+        enableMetacity = mkEnableOption "Enable the standard GNOME Flashback session with Metacity.";
+
+        customSessions = mkOption {
+          type = types.listOf (types.submodule {
+            options = {
+              wmName = mkOption {
+                type = types.str;
+                description = "The filename-compatible name of the window manager to use.";
+                example = "xmonad";
+              };
+
+              wmLabel = mkOption {
+                type = types.str;
+                description = "The pretty name of the window manager to use.";
+                example = "XMonad";
+              };
+
+              wmCommand = mkOption {
+                type = types.str;
+                description = "The executable of the window manager to use.";
+                example = "\${pkgs.haskellPackages.xmonad}/bin/xmonad";
+              };
+            };
+          });
+          default = [];
+          description = "Other GNOME Flashback sessions to enable.";
+        };
+      };
     };
 
     environment.gnome3.excludePackages = mkOption {
@@ -103,6 +127,7 @@ in {
     services.dleyna-server.enable = mkDefault true;
     services.gnome3.at-spi2-core.enable = true;
     services.gnome3.evolution-data-server.enable = true;
+    services.gnome3.file-roller.enable = mkDefault true;
     services.gnome3.gnome-disks.enable = mkDefault true;
     services.gnome3.gnome-documents.enable = mkDefault true;
     services.gnome3.gnome-keyring.enable = true;
@@ -120,7 +145,9 @@ in {
     services.telepathy.enable = mkDefault true;
     networking.networkmanager.enable = mkDefault true;
     services.upower.enable = config.powerManagement.enable;
-    services.dbus.packages = mkIf config.services.printing.enable [ pkgs.system-config-printer ];
+    services.dbus.packages =
+      optional config.services.printing.enable pkgs.system-config-printer ++
+      optional flashbackEnabled pkgs.gnome3.gnome-screensaver;
     services.colord.enable = mkDefault true;
     services.packagekit.enable = mkDefault true;
     hardware.bluetooth.enable = mkDefault true;
@@ -134,7 +161,15 @@ in {
 
     fonts.fonts = [ pkgs.dejavu_fonts pkgs.cantarell-fonts ];
 
-    services.xserver.displayManager.extraSessionFilePackages = [ pkgs.gnome3.gnome-session ];
+    services.xserver.displayManager.extraSessionFilePackages = [ pkgs.gnome3.gnome-session ]
+      ++ map
+        (wm: pkgs.gnome3.gnome-flashback.mkSessionForWm {
+          inherit (wm) wmName wmLabel wmCommand;
+        }) (optional cfg.flashback.enableMetacity {
+              wmName = "metacity";
+              wmLabel = "Metacity";
+              wmCommand = "${pkgs.gnome3.metacity}/bin/metacity";
+            } ++ cfg.flashback.customSessions);
 
     environment.extraInit = ''
       ${concatMapStrings (p: ''
@@ -167,7 +202,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,8 +214,14 @@ in {
                               networkmanager-iodine networkmanager-l2tp; };
 
     # Needed for themes and backgrounds
-    environment.pathsToLink = [ "/share" ];
+    environment.pathsToLink = [
+      "/share"
+      "/share/nautilus-python/extensions"
+    ];
 
+    security.pam.services.gnome-screensaver = mkIf flashbackEnabled {
+      enableGnomeKeyring = true;
+    };
   };
 
 
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/lxqt.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/lxqt.nix
index 896f70c86ebb..686bbd0dcf98 100644
--- a/nixpkgs/nixos/modules/services/x11/desktop-managers/lxqt.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix
index db83aaf3c19f..4d2fafd14961 100644
--- a/nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/display-managers/default.nix b/nixpkgs/nixos/modules/services/x11/display-managers/default.nix
index 047321bd9495..0e87e6adbab8 100644
--- a/nixpkgs/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix
index d1ee076e9185..efec943c0075 100644
--- a/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix
+++ b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix
@@ -6,12 +6,14 @@ let
 
   dmcfg = config.services.xserver.displayManager;
   ldmcfg = dmcfg.lightdm;
+  xcfg = config.services.xserver;
   cfg = ldmcfg.greeters.gtk;
 
   inherit (pkgs) writeText;
 
   theme = cfg.theme.package;
   icons = cfg.iconTheme.package;
+  cursors = cfg.cursorTheme.package;
 
   # The default greeter provided with this expression is the GTK greeter.
   # Again, we need a few things in the environment for the greeter to run with
@@ -28,7 +30,8 @@ let
         --set GTK_EXE_PREFIX "${theme}" \
         --set GTK_DATA_PREFIX "${theme}" \
         --set XDG_DATA_DIRS "${theme}/share:${icons}/share" \
-        --set XDG_CONFIG_HOME "${theme}/share"
+        --set XDG_CONFIG_HOME "${theme}/share" \
+        --set XCURSOR_PATH "${cursors}/share/icons"
 
       cat - > $out/lightdm-gtk-greeter.desktop << EOF
       [Desktop Entry]
@@ -44,9 +47,12 @@ let
     [greeter]
     theme-name = ${cfg.theme.name}
     icon-theme-name = ${cfg.iconTheme.name}
+    cursor-theme-name = ${cfg.cursorTheme.name}
+    cursor-theme-size = ${toString cfg.cursorTheme.size}
     background = ${ldmcfg.background}
     ${optionalString (cfg.clock-format != null) "clock-format = ${cfg.clock-format}"}
     ${optionalString (cfg.indicators != null) "indicators = ${concatStringsSep ";" cfg.indicators}"}
+    ${optionalString (xcfg.dpi != null) "xft-dpi=${toString xcfg.dpi}"}
     ${cfg.extraConfig}
     '';
 
@@ -106,6 +112,33 @@ in
 
       };
 
+      cursorTheme = {
+
+        package = mkOption {
+          default = pkgs.gnome3.defaultIconTheme;
+          defaultText = "pkgs.gnome3.defaultIconTheme";
+          description = ''
+            The package path that contains the cursor theme given in the name option.
+          '';
+        };
+
+        name = mkOption {
+          type = types.str;
+          default = "Adwaita";
+          description = ''
+            Name of the cursor theme to use for the lightdm-gtk-greeter.
+          '';
+        };
+
+        size = mkOption {
+          type = types.int;
+          default = 16;
+          description = ''
+            Size of the cursor theme to use for the lightdm-gtk-greeter.
+          '';
+        };
+      };
+
       clock-format = mkOption {
         type = types.nullOr types.str;
         default = null;
diff --git a/nixpkgs/nixos/modules/services/x11/urxvtd.nix b/nixpkgs/nixos/modules/services/x11/urxvtd.nix
index 5531d7f153c2..d916fa5bb393 100644
--- a/nixpkgs/nixos/modules/services/x11/urxvtd.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/initrd-network.nix b/nixpkgs/nixos/modules/system/boot/initrd-network.nix
index dd0ea69e9685..cb8fc957a990 100644
--- a/nixpkgs/nixos/modules/system/boot/initrd-network.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/initrd-ssh.nix b/nixpkgs/nixos/modules/system/boot/initrd-ssh.nix
index 53e993603e27..2d3e3b05c980 100644
--- a/nixpkgs/nixos/modules/system/boot/initrd-ssh.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/kernel_config.nix b/nixpkgs/nixos/modules/system/boot/kernel_config.nix
new file mode 100644
index 000000000000..fbbd0982b2c6
--- /dev/null
+++ b/nixpkgs/nixos/modules/system/boot/kernel_config.nix
@@ -0,0 +1,137 @@
+{ lib, config, ... }:
+
+with lib;
+let
+  findWinner = candidates: winner:
+    any (x: x == winner) candidates;
+
+  # winners is an ordered list where first item wins over 2nd etc
+  mergeAnswer = winners: locs: defs:
+    let
+      values = map (x: x.value) defs;
+      freeformAnswer = intersectLists values winners;
+      inter = intersectLists values winners;
+      winner = head winners;
+    in
+    if defs == [] then abort "This case should never happen."
+    else if winner == [] then abort "Give a valid list of winner"
+    else if inter == [] then mergeOneOption locs defs
+    else if findWinner values winner then
+      winner
+    else
+      mergeAnswer (tail winners) locs defs;
+
+  mergeFalseByDefault = locs: defs:
+    if defs == [] then abort "This case should never happen."
+    else if any (x: x == false) defs then false
+    else true;
+
+  kernelItem = types.submodule {
+    options = {
+      tristate = mkOption {
+        type = types.enum [ "y" "m" "n" null ] // {
+          merge = mergeAnswer [ "y" "m" "n" ];
+        };
+        default = null;
+        internal = true;
+        visible = true;
+        description = ''
+          Use this field for tristate kernel options expecting a "y" or "m" or "n".
+        '';
+      };
+
+      freeform = mkOption {
+        type = types.nullOr types.str // {
+          merge = mergeEqualOption;
+        };
+        default = null;
+        example = ''MMC_BLOCK_MINORS.freeform = "32";'';
+        description = ''
+          Freeform description of a kernel configuration item value.
+        '';
+      };
+
+      optional = mkOption {
+        type = types.bool // { merge = mergeFalseByDefault; };
+        default = false;
+        description = ''
+          Wether option should generate a failure when unused.
+        '';
+      };
+    };
+  };
+
+  mkValue = with lib; val:
+  let
+    isNumber = c: elem c ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"];
+
+  in
+    if (val == "") then "\"\""
+    else if val == "y" || val == "m" || val == "n" then val
+    else if all isNumber (stringToCharacters val) then val
+    else if substring 0 2 val == "0x" then val
+    else val; # FIXME: fix quoting one day
+
+
+  # generate nix intermediate kernel config file of the form
+  #
+  #       VIRTIO_MMIO m
+  #       VIRTIO_BLK y
+  #       VIRTIO_CONSOLE n
+  #       NET_9P_VIRTIO? y
+  #
+  # Borrowed from copumpkin https://github.com/NixOS/nixpkgs/pull/12158
+  # returns a string, expr should be an attribute set
+  # Use mkValuePreprocess to preprocess option values, aka mark 'modules' as 'yes' or vice-versa
+  # use the identity if you don't want to override the configured values
+  generateNixKConf = exprs:
+  let
+    mkConfigLine = key: item:
+      let
+        val = if item.freeform != null then item.freeform else item.tristate;
+      in
+        if val == null
+          then ""
+          else if (item.optional)
+            then "${key}? ${mkValue val}\n"
+            else "${key} ${mkValue val}\n";
+
+    mkConf = cfg: concatStrings (mapAttrsToList mkConfigLine cfg);
+  in mkConf exprs;
+
+in
+{
+
+  options = {
+
+    intermediateNixConfig = mkOption {
+      readOnly = true;
+      type = types.lines;
+      example = ''
+        USB? y
+        DEBUG n
+      '';
+      description = ''
+        The result of converting the structured kernel configuration in settings
+        to an intermediate string that can be parsed by generate-config.pl to
+        answer the kernel `make defconfig`.
+      '';
+    };
+
+    settings = mkOption {
+      type = types.attrsOf kernelItem;
+      example = literalExample '' with lib.kernel; {
+        "9P_NET" = yes;
+        USB = optional yes;
+        MMC_BLOCK_MINORS = freeform "32";
+      }'';
+      description = ''
+        Structured kernel configuration.
+      '';
+    };
+  };
+
+  config = {
+    intermediateNixConfig = generateNixKConf config.settings;
+  };
+}
diff --git a/nixpkgs/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix b/nixpkgs/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix
index 2d27611946e2..ff90a9b46179 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix b/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix
index af39c7bb6841..5f5dbe1092d0 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix b/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
index 576a07c1d272..9ac6b6b12242 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix b/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix
index 3a33b3f65d36..a1537ad3cedc 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/loader/init-script/init-script.nix b/nixpkgs/nixos/modules/system/boot/loader/init-script/init-script.nix
index 374d9524ff1e..385a26036784 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/init-script/init-script.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix b/nixpkgs/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix
index 7e089507ff20..047651dc6426 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix b/nixpkgs/nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix
index e929c33c6ee3..94599a0081c6 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
index feed863efd66..9ad2a2779e18 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/luksroot.nix b/nixpkgs/nixos/modules/system/boot/luksroot.nix
index 018e7b2e7f89..aa4a5f8abcce 100644
--- a/nixpkgs/nixos/modules/system/boot/luksroot.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/stage-1-init.sh b/nixpkgs/nixos/modules/system/boot/stage-1-init.sh
index 6a4ac8128ab3..6dafc6cddde7 100644
--- a/nixpkgs/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixpkgs/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/nixpkgs/nixos/modules/system/boot/stage-1.nix b/nixpkgs/nixos/modules/system/boot/stage-1.nix
index e7167999a6f8..5e27b24ac447 100644
--- a/nixpkgs/nixos/modules/system/boot/stage-1.nix
+++ b/nixpkgs/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
       ''}
@@ -525,16 +525,18 @@ in
       };
 
     fileSystems = mkOption {
-      options.neededForBoot = mkOption {
-        default = false;
-        type = types.bool;
-        description = ''
-          If set, this file system will be mounted in the initial
-          ramdisk.  By default, this applies to the root file system
-          and to the file system containing
-          <filename>/nix/store</filename>.
-        '';
-      };
+      type = with lib.types; loaOf (submodule {
+        options.neededForBoot = mkOption {
+          default = false;
+          type = types.bool;
+          description = ''
+            If set, this file system will be mounted in the initial
+            ramdisk.  By default, this applies to the root file system
+            and to the file system containing
+            <filename>/nix/store</filename>.
+          '';
+        };
+      });
     };
 
   };
diff --git a/nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix b/nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix
index 5f2bec5c34ae..63f974b704f3 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix
@@ -210,6 +210,15 @@ in rec {
       '';
     };
 
+    startLimitIntervalSec = mkOption {
+       type = types.int;
+       description = ''
+         Configure unit start rate limiting. Units which are started
+         more than burst times within an interval time interval are
+         not permitted to start any more.
+       '';
+    };
+
   };
 
 
diff --git a/nixpkgs/nixos/modules/system/boot/systemd.nix b/nixpkgs/nixos/modules/system/boot/systemd.nix
index d1029bb57982..f783daba902a 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd.nix
@@ -193,7 +193,7 @@ let
     let mkScriptName =  s: "unit-script-" + (replaceChars [ "\\" "@" ] [ "-" "_" ] (shellEscape s) );
     in  pkgs.writeTextFile { name = mkScriptName name; executable = true; inherit text; };
 
-  unitConfig = { config, ... }: {
+  unitConfig = { config, options, ... }: {
     config = {
       unitConfig =
         optionalAttrs (config.requires != [])
@@ -219,7 +219,9 @@ let
         // optionalAttrs (config.documentation != []) {
           Documentation = toString config.documentation; }
         // optionalAttrs (config.onFailure != []) {
-          OnFailure = toString config.onFailure;
+          OnFailure = toString config.onFailure; }
+        // optionalAttrs (options.startLimitIntervalSec.isDefined) {
+          StartLimitIntervalSec = toString config.startLimitIntervalSec;
         };
     };
   };
@@ -898,6 +900,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/nixpkgs/nixos/modules/system/etc/etc.nix b/nixpkgs/nixos/modules/system/etc/etc.nix
index 7d43ba07ca57..57ade2880962 100644
--- a/nixpkgs/nixos/modules/system/etc/etc.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/tasks/auto-upgrade.nix b/nixpkgs/nixos/modules/tasks/auto-upgrade.nix
index 7b756b70e2fc..d225778a3878 100644
--- a/nixpkgs/nixos/modules/tasks/auto-upgrade.nix
+++ b/nixpkgs/nixos/modules/tasks/auto-upgrade.nix
@@ -78,7 +78,7 @@ let cfg = config.system.autoUpgrade; in
           HOME = "/root";
         } // config.networking.proxy.envVars;
 
-      path = [ pkgs.gnutar pkgs.xz.bin config.nix.package.out ];
+      path = [ pkgs.gnutar pkgs.xz.bin pkgs.gitMinimal config.nix.package.out ];
 
       script = ''
         ${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch ${toString cfg.flags}
diff --git a/nixpkgs/nixos/modules/tasks/cpu-freq.nix b/nixpkgs/nixos/modules/tasks/cpu-freq.nix
index 5f8b5df52acf..513382936e47 100644
--- a/nixpkgs/nixos/modules/tasks/cpu-freq.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/tasks/encrypted-devices.nix b/nixpkgs/nixos/modules/tasks/encrypted-devices.nix
index 11ed5d7e4d0c..2c9231f55236 100644
--- a/nixpkgs/nixos/modules/tasks/encrypted-devices.nix
+++ b/nixpkgs/nixos/modules/tasks/encrypted-devices.nix
@@ -12,7 +12,7 @@ let
 
   encryptedFSOptions = {
 
-    encrypted = {
+    options.encrypted = {
       enable = mkOption {
         default = false;
         type = types.bool;
@@ -47,10 +47,10 @@ in
 
   options = {
     fileSystems = mkOption {
-      options = [encryptedFSOptions];
+      type = with lib.types; loaOf (submodule encryptedFSOptions);
     };
     swapDevices = mkOption {
-      options = [encryptedFSOptions];
+      type = with lib.types; listOf (submodule encryptedFSOptions);
     };
   };
 
diff --git a/nixpkgs/nixos/modules/tasks/filesystems.nix b/nixpkgs/nixos/modules/tasks/filesystems.nix
index 9e4057b50897..07f8214cea2c 100644
--- a/nixpkgs/nixos/modules/tasks/filesystems.nix
+++ b/nixpkgs/nixos/modules/tasks/filesystems.nix
@@ -231,7 +231,7 @@ in
         fsToSkipCheck = [ "none" "bindfs" "btrfs" "zfs" "tmpfs" "nfs" "vboxsf" "glusterfs" ];
         skipCheck = fs: fs.noCheck || fs.device == "none" || builtins.elem fs.fsType fsToSkipCheck;
         # https://wiki.archlinux.org/index.php/fstab#Filepath_spaces
-        escape = string: builtins.replaceStrings [ " " ] [ "\\040" ] string;
+        escape = string: builtins.replaceStrings [ " " "\t" ] [ "\\040" "\\011" ] string;
       in ''
         # This is a generated file.  Do not edit!
         #
diff --git a/nixpkgs/nixos/modules/tasks/filesystems/f2fs.nix b/nixpkgs/nixos/modules/tasks/filesystems/f2fs.nix
index d103ff1a57b5..a305235979a2 100644
--- a/nixpkgs/nixos/modules/tasks/filesystems/f2fs.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix
index 8f8c9e23e13e..37a19fb9fc8c 100644
--- a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix
@@ -535,6 +535,7 @@ in
 
       systemd.timers.zfs-scrub = {
         wantedBy = [ "timers.target" ];
+        after = [ "multi-user.target" ]; # Apparently scrubbing before boot is complete hangs the system? #53583
         timerConfig = {
           OnCalendar = cfgScrub.interval;
           Persistent = "yes";
diff --git a/nixpkgs/nixos/modules/testing/service-runner.nix b/nixpkgs/nixos/modules/testing/service-runner.nix
index 25490d671152..17d5e3376908 100644
--- a/nixpkgs/nixos/modules/testing/service-runner.nix
+++ b/nixpkgs/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;
 
@@ -92,23 +92,24 @@ let
       exit($mainRes & 127 ? 255 : $mainRes << 8);
     '';
 
+  opts = { config, name, ... }: {
+    options.runner = mkOption {
+    internal = true;
+    description = ''
+        A script that runs the service outside of systemd,
+        useful for testing or for using NixOS services outside
+        of NixOS.
+    '';
+    };
+    config.runner = makeScript name config;
+  };
+
 in
 
 {
   options = {
     systemd.services = mkOption {
-      options =
-        { config, name, ... }:
-        { options.runner = mkOption {
-            internal = true;
-            description = ''
-              A script that runs the service outside of systemd,
-              useful for testing or for using NixOS services outside
-              of NixOS.
-            '';
-          };
-          config.runner = makeScript name config;
-        };
+      type = with types; attrsOf (submodule opts);
     };
   };
 }
diff --git a/nixpkgs/nixos/modules/testing/test-instrumentation.nix b/nixpkgs/nixos/modules/testing/test-instrumentation.nix
index aa0db4afd978..ed4cfa7805e2 100644
--- a/nixpkgs/nixos/modules/testing/test-instrumentation.nix
+++ b/nixpkgs/nixos/modules/testing/test-instrumentation.nix
@@ -55,8 +55,7 @@ with import ../../lib/qemu-flags.nix { inherit pkgs; };
     systemd.services."serial-getty@hvc0".enable = false;
 
     # Only use a serial console, no TTY.
-    # hvc1: socket backdoor, see "Debugging NixOS tests" section in NixOS manual
-    virtualisation.qemu.consoles = [ "hvc1" qemuSerialDevice ];
+    virtualisation.qemu.consoles = [ qemuSerialDevice ];
 
     boot.initrd.preDeviceCommands =
       ''
diff --git a/nixpkgs/nixos/modules/virtualisation/container-config.nix b/nixpkgs/nixos/modules/virtualisation/container-config.nix
index 78c59d98a5eb..604fb8a75932 100644
--- a/nixpkgs/nixos/modules/virtualisation/container-config.nix
+++ b/nixpkgs/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/nixpkgs/nixos/modules/virtualisation/containers.nix b/nixpkgs/nixos/modules/virtualisation/containers.nix
index 3dd36f9b12e1..7c9909ae2787 100644
--- a/nixpkgs/nixos/modules/virtualisation/containers.nix
+++ b/nixpkgs/nixos/modules/virtualisation/containers.nix
@@ -36,7 +36,7 @@ let
         #! ${pkgs.runtimeShell} -e
 
         # Initialise the container side of the veth pair.
-        if [ -n "$HOST_ADDRESS" ] || [ -n "$LOCAL_ADDRESS" ]; then
+        if [ -n "$HOST_ADDRESS" ] || [ -n "$LOCAL_ADDRESS" ] || [ -n "$HOST_BRIDGE" ]; then
 
           ip link set host0 name eth0
           ip link set dev eth0 up
@@ -90,18 +90,20 @@ let
 
       if [ -n "$HOST_ADDRESS" ] || [ -n "$LOCAL_ADDRESS" ]; then
         extraFlags+=" --network-veth"
-        if [ -n "$HOST_BRIDGE" ]; then
-          extraFlags+=" --network-bridge=$HOST_BRIDGE"
-        fi
-        if [ -n "$HOST_PORT" ]; then
-          OIFS=$IFS
-          IFS=","
-          for i in $HOST_PORT
-          do
-              extraFlags+=" --port=$i"
-          done
-          IFS=$OIFS
-        fi
+      fi
+
+      if [ -n "$HOST_PORT" ]; then
+        OIFS=$IFS
+        IFS=","
+        for i in $HOST_PORT
+        do
+            extraFlags+=" --port=$i"
+        done
+        IFS=$OIFS
+      fi
+
+      if [ -n "$HOST_BRIDGE" ]; then
+        extraFlags+=" --network-bridge=$HOST_BRIDGE"
       fi
 
       extraFlags+=" ${concatStringsSep " " (mapAttrsToList nspawnExtraVethArgs cfg.extraVeths)}"
@@ -188,6 +190,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/nixpkgs/nixos/tests/all-tests.nix b/nixpkgs/nixos/tests/all-tests.nix
index 860262eeb6cd..4450cafd2800 100644
--- a/nixpkgs/nixos/tests/all-tests.nix
+++ b/nixpkgs/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 {};
@@ -107,8 +107,10 @@ in
   initrdNetwork = handleTest ./initrd-network.nix {};
   installer = handleTest ./installer.nix {};
   ipv6 = handleTest ./ipv6.nix {};
+  jackett = handleTest ./jackett.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 {};
@@ -119,6 +121,7 @@ in
   latestKernel.login = handleTest ./login.nix { latestKernel = true; };
   ldap = handleTest ./ldap.nix {};
   leaps = handleTest ./leaps.nix {};
+  lidarr = handleTest ./lidarr.nix {};
   #lightdm = handleTest ./lightdm.nix {};
   login = handleTest ./login.nix {};
   #logstash = handleTest ./logstash.nix {};
@@ -126,6 +129,7 @@ in
   matrix-synapse = handleTest ./matrix-synapse.nix {};
   memcached = handleTest ./memcached.nix {};
   mesos = handleTest ./mesos.nix {};
+  minio = handleTest ./minio.nix {};
   misc = handleTest ./misc.nix {};
   mongodb = handleTest ./mongodb.nix {};
   morty = handleTest ./morty.nix {};
@@ -139,6 +143,8 @@ in
   nat.firewall = handleTest ./nat.nix { withFirewall = true; };
   nat.firewall-conntrack = handleTest ./nat.nix { withFirewall = true; withConntrackHelpers = true; };
   nat.standalone = handleTest ./nat.nix { withFirewall = false; };
+  ndppd = handleTest ./ndppd.nix {};
+  neo4j = handleTest ./neo4j.nix {};
   netdata = handleTest ./netdata.nix {};
   networking.networkd = handleTest ./networking.nix { networkd = true; };
   networking.scripted = handleTest ./networking.nix { networkd = false; };
@@ -150,6 +156,7 @@ in
   nfs4 = handleTest ./nfs.nix { version = 4; };
   nghttpx = handleTest ./nghttpx.nix {};
   nginx = handleTest ./nginx.nix {};
+  nginx-sso = handleTest ./nginx-sso.nix {};
   nix-ssh-serve = handleTest ./nix-ssh-serve.nix {};
   novacomd = handleTestOn ["x86_64-linux"] ./novacomd.nix {};
   nsd = handleTest ./nsd.nix {};
@@ -159,6 +166,7 @@ in
   osquery = handleTest ./osquery.nix {};
   ostree = handleTest ./ostree.nix {};
   pam-oath-login = handleTest ./pam-oath-login.nix {};
+  pam-u2f = handleTest ./pam-u2f.nix {};
   peerflix = handleTest ./peerflix.nix {};
   pgjwt = handleTest ./pgjwt.nix {};
   pgmanage = handleTest ./pgmanage.nix {};
@@ -177,6 +185,7 @@ in
   quagga = handleTest ./quagga.nix {};
   quake3 = handleTest ./quake3.nix {};
   rabbitmq = handleTest ./rabbitmq.nix {};
+  radarr = handleTest ./radarr.nix {};
   radicale = handleTest ./radicale.nix {};
   redmine = handleTest ./redmine.nix {};
   roundcube = handleTest ./roundcube.nix {};
@@ -193,12 +202,14 @@ in
   smokeping = handleTest ./smokeping.nix {};
   snapper = handleTest ./snapper.nix {};
   solr = handleTest ./solr.nix {};
+  sonarr = handleTest ./sonarr.nix {};
   strongswan-swanctl = handleTest ./strongswan-swanctl.nix {};
   sudo = handleTest ./sudo.nix {};
   switchTest = handleTest ./switch-test.nix {};
   syncthing-relay = handleTest ./syncthing-relay.nix {};
   systemd = handleTest ./systemd.nix {};
   taskserver = handleTest ./taskserver.nix {};
+  telegraf = handleTest ./telegraf.nix {};
   tomcat = handleTest ./tomcat.nix {};
   tor = handleTest ./tor.nix {};
   transmission = handleTest ./transmission.nix {};
diff --git a/nixpkgs/nixos/tests/bittorrent.nix b/nixpkgs/nixos/tests/bittorrent.nix
index 8977be9b859f..27871f72b4e5 100644
--- a/nixpkgs/nixos/tests/bittorrent.nix
+++ b/nixpkgs/nixos/tests/bittorrent.nix
@@ -23,7 +23,7 @@ in
 {
   name = "bittorrent";
   meta = with pkgs.stdenv.lib.maintainers; {
-    maintainers = [ domenkozar eelco chaoflow rob wkennington bobvanderlinden ];
+    maintainers = [ domenkozar eelco chaoflow rob bobvanderlinden ];
   };
 
   nodes =
diff --git a/nixpkgs/nixos/tests/containers-bridge.nix b/nixpkgs/nixos/tests/containers-bridge.nix
index 777cf9a7e7f9..0eae51433d20 100644
--- a/nixpkgs/nixos/tests/containers-bridge.nix
+++ b/nixpkgs/nixos/tests/containers-bridge.nix
@@ -45,6 +45,19 @@ import ./make-test.nix ({ pkgs, ...} : {
             };
         };
 
+      containers.web-noip =
+        {
+          autoStart = true;
+          privateNetwork = true;
+          hostBridge = "br0";
+          config =
+            { services.httpd.enable = true;
+              services.httpd.adminAddr = "foo@example.org";
+              networking.firewall.allowedTCPPorts = [ 80 ];
+            };
+        };
+
+
       virtualisation.pathsInNixDB = [ pkgs.stdenv ];
     };
 
@@ -56,6 +69,10 @@ import ./make-test.nix ({ pkgs, ...} : {
       # Start the webserver container.
       $machine->succeed("nixos-container status webserver") =~ /up/ or die;
 
+      # Check if bridges exist inside containers
+      $machine->succeed("nixos-container run webserver -- ip link show eth0");
+      $machine->succeed("nixos-container run web-noip -- ip link show eth0");
+
       "${containerIp}" =~ /([^\/]+)\/([0-9+])/;
       my $ip = $1;
       chomp $ip;
diff --git a/nixpkgs/nixos/tests/containers-extra_veth.nix b/nixpkgs/nixos/tests/containers-extra_veth.nix
index b4c48afe48ba..b3d3bce87579 100644
--- a/nixpkgs/nixos/tests/containers-extra_veth.nix
+++ b/nixpkgs/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/nixpkgs/nixos/tests/docker-tools.nix b/nixpkgs/nixos/tests/docker-tools.nix
index ecd14b274eb3..58f106314ab3 100644
--- a/nixpkgs/nixos/tests/docker-tools.nix
+++ b/nixpkgs/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/nixpkgs/nixos/tests/fwupd.nix b/nixpkgs/nixos/tests/fwupd.nix
index 2e64149b2db3..88dac8ccbcdb 100644
--- a/nixpkgs/nixos/tests/fwupd.nix
+++ b/nixpkgs/nixos/tests/fwupd.nix
@@ -8,6 +8,8 @@ import ./make-test.nix ({ pkgs, ... }: {
 
   machine = { pkgs, ... }: {
     services.fwupd.enable = true;
+    services.fwupd.blacklistPlugins = []; # don't blacklist test plugin
+    services.fwupd.enableTestRemote = true;
     environment.systemPackages = with pkgs; [ gnome-desktop-testing ];
     environment.variables.XDG_DATA_DIRS = [ "${pkgs.fwupd.installedTests}/share" ];
     virtualisation.memorySize = 768;
diff --git a/nixpkgs/nixos/tests/gitea.nix b/nixpkgs/nixos/tests/gitea.nix
index 354334991852..28e6479e9cbe 100644
--- a/nixpkgs/nixos/tests/gitea.nix
+++ b/nixpkgs/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/nixpkgs/nixos/tests/hardened.nix b/nixpkgs/nixos/tests/hardened.nix
index 683f56c45af4..07bd10963bab 100644
--- a/nixpkgs/nixos/tests/hardened.nix
+++ b/nixpkgs/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/nixpkgs/nixos/tests/home-assistant.nix b/nixpkgs/nixos/tests/home-assistant.nix
index 73c1e71eb516..a93360b252f6 100644
--- a/nixpkgs/nixos/tests/home-assistant.nix
+++ b/nixpkgs/nixos/tests/home-assistant.nix
@@ -50,6 +50,18 @@ in {
               }
             ];
           };
+          lovelaceConfig = {
+            title = "My Awesome Home";
+            views = [ {
+              title = "Example";
+              cards = [ {
+                type = "markdown";
+                title = "Lovelace";
+                content = "Welcome to your **Lovelace UI**.";
+              } ];
+            } ];
+          };
+          lovelaceConfigWritable = true;
         };
       };
   };
@@ -59,8 +71,10 @@ in {
     $hass->waitForUnit("home-assistant.service");
 
     # The config is specified using a Nix attribute set,
-    # but then converted from JSON to YAML
-    $hass->succeed("test -f ${configDir}/configuration.yaml");
+    # converted from JSON to YAML, and linked to the config dir
+    $hass->succeed("test -L ${configDir}/configuration.yaml");
+    # The lovelace config is copied because lovelaceConfigWritable = true
+    $hass->succeed("test -f ${configDir}/ui-lovelace.yaml");
 
     # Check that Home Assistant's web interface and API can be reached
     $hass->waitForOpenPort(8123);
@@ -73,7 +87,7 @@ in {
     $hass->succeed("curl http://localhost:8123/api/states/binary_sensor.mqtt_binary_sensor -H 'x-ha-access: ${apiPassword}' | grep -qF '\"state\": \"on\"'");
 
     # Toggle a binary sensor using hass-cli
-    $hass->succeed("${hassCli} entity get binary_sensor.mqtt_binary_sensor | grep -qF '\"state\": \"on\"'");
+    $hass->succeed("${hassCli} --output json entity get binary_sensor.mqtt_binary_sensor | grep -qF '\"state\": \"on\"'");
     $hass->succeed("${hassCli} entity edit binary_sensor.mqtt_binary_sensor --json='{\"state\": \"off\"}'");
     $hass->succeed("curl http://localhost:8123/api/states/binary_sensor.mqtt_binary_sensor -H 'x-ha-access: ${apiPassword}' | grep -qF '\"state\": \"off\"'");
 
diff --git a/nixpkgs/nixos/tests/installer.nix b/nixpkgs/nixos/tests/installer.nix
index c8edaaba1585..2553a0d116ae 100644
--- a/nixpkgs/nixos/tests/installer.nix
+++ b/nixpkgs/nixos/tests/installer.nix
@@ -200,7 +200,7 @@ let
       name = "installer-" + name;
       meta = with pkgs.stdenv.lib.maintainers; {
         # put global maintainers here, individuals go into makeInstallerTest fkt call
-        maintainers = [ wkennington ] ++ (meta.maintainers or []);
+        maintainers = (meta.maintainers or []);
       };
       nodes = {
 
diff --git a/nixpkgs/nixos/tests/jackett.nix b/nixpkgs/nixos/tests/jackett.nix
new file mode 100644
index 000000000000..399a0c272327
--- /dev/null
+++ b/nixpkgs/nixos/tests/jackett.nix
@@ -0,0 +1,18 @@
+import ./make-test.nix ({ lib, ... }:
+
+with lib;
+
+rec {
+  name = "jackett";
+  meta.maintainers = with maintainers; [ etu ];
+
+  nodes.machine =
+    { pkgs, ... }:
+    { services.jackett.enable = true; };
+
+  testScript = ''
+    $machine->waitForUnit('jackett.service');
+    $machine->waitForOpenPort('9117');
+    $machine->succeed("curl --fail http://localhost:9117/");
+  '';
+})
diff --git a/nixpkgs/nixos/tests/kerberos/default.nix b/nixpkgs/nixos/tests/kerberos/default.nix
new file mode 100644
index 000000000000..f2f1a438918c
--- /dev/null
+++ b/nixpkgs/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/nixpkgs/nixos/tests/kerberos/heimdal.nix b/nixpkgs/nixos/tests/kerberos/heimdal.nix
new file mode 100644
index 000000000000..a0551b131e91
--- /dev/null
+++ b/nixpkgs/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/nixpkgs/nixos/tests/kerberos/mit.nix b/nixpkgs/nixos/tests/kerberos/mit.nix
new file mode 100644
index 000000000000..6da3a384aa99
--- /dev/null
+++ b/nixpkgs/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/nixpkgs/nixos/tests/ldap.nix b/nixpkgs/nixos/tests/ldap.nix
index 035a81924174..b3fd42e75886 100644
--- a/nixpkgs/nixos/tests/ldap.nix
+++ b/nixpkgs/nixos/tests/ldap.nix
@@ -1,41 +1,23 @@
 import ./make-test.nix ({ pkgs, lib, ...} :
 
 let
+  unlines = lib.concatStringsSep "\n";
+  unlinesAttrs = f: as: unlines (lib.mapAttrsToList f as);
 
+  dbDomain = "example.com";
   dbSuffix = "dc=example,dc=com";
-  dbPath = "/var/db/openldap";
   dbAdminDn = "cn=admin,${dbSuffix}";
-  dbAdminPwd = "test";
-  serverUri = "ldap:///";
+  dbAdminPwd = "admin-password";
+  # NOTE: slappasswd -h "{SSHA}" -s '${dbAdminPwd}'
+  dbAdminPwdHash = "{SSHA}i7FopSzkFQMrHzDMB1vrtkI0rBnwouP8";
   ldapUser = "test-ldap-user";
   ldapUserId = 10000;
-  ldapUserPwd = "test";
+  ldapUserPwd = "user-password";
+  # NOTE: slappasswd -h "{SSHA}" -s '${ldapUserPwd}'
+  ldapUserPwdHash = "{SSHA}v12XICMZNGT6r2KJ26rIkN8Vvvp4QX6i";
   ldapGroup = "test-ldap-group";
   ldapGroupId = 10000;
-  setupLdif = pkgs.writeText "test-ldap.ldif" ''
-    dn: ${dbSuffix}
-    dc: ${with lib; let dc = head (splitString "," dbSuffix); dcName = head (tail (splitString "=" dc)); in dcName}
-    o: ${dbSuffix}
-    objectclass: top
-    objectclass: dcObject
-    objectclass: organization
-
-    dn: cn=${ldapUser},${dbSuffix}
-    sn: ${ldapUser}
-    objectClass: person
-    objectClass: posixAccount
-    uid: ${ldapUser}
-    uidNumber: ${toString ldapUserId}
-    gidNumber: ${toString ldapGroupId}
-    homeDirectory: /home/${ldapUser}
-    loginShell: /bin/sh
-    userPassword: ${ldapUserPwd}
-
-    dn: cn=${ldapGroup},${dbSuffix}
-    objectClass: posixGroup
-    gidNumber: ${toString ldapGroupId}
-    memberUid: ${ldapUser}
-  '';
+
   mkClient = useDaemon:
     { lib, ... }:
     {
@@ -43,13 +25,24 @@ let
       virtualisation.vlans = [ 1 ];
       security.pam.services.su.rootOK = lib.mkForce false;
       users.ldap.enable = true;
-      users.ldap.daemon.enable = useDaemon;
+      users.ldap.daemon = {
+        enable = useDaemon;
+        rootpwmoddn = "cn=admin,${dbSuffix}";
+        rootpwmodpw = "/etc/nslcd.rootpwmodpw";
+      };
+      # NOTE: password stored in clear in Nix's store, but this is a test.
+      environment.etc."nslcd.rootpwmodpw".source = pkgs.writeText "rootpwmodpw" dbAdminPwd;
       users.ldap.loginPam = true;
       users.ldap.nsswitch = true;
       users.ldap.server = "ldap://server";
-      users.ldap.base = "${dbSuffix}";
+      users.ldap.base = "ou=posix,${dbSuffix}";
+      users.ldap.bind = {
+        distinguishedName = "cn=admin,${dbSuffix}";
+        password = "/etc/ldap/bind.password";
+      };
+      # NOTE: password stored in clear in Nix's store, but this is a test.
+      environment.etc."ldap/bind.password".source = pkgs.writeText "password" dbAdminPwd;
     };
-
 in
 
 {
@@ -61,28 +54,237 @@ in
   nodes = {
 
     server =
-      { pkgs, ... }:
+      { pkgs, config, ... }:
+      let
+        inherit (config.services) openldap;
+
+        slapdConfig = pkgs.writeText "cn=config.ldif" (''
+          dn: cn=config
+          objectClass: olcGlobal
+          #olcPidFile: /run/slapd/slapd.pid
+          # List of arguments that were passed to the server
+          #olcArgsFile: /run/slapd/slapd.args
+          # Read slapd-config(5) for possible values
+          olcLogLevel: none
+          # The tool-threads parameter sets the actual amount of CPU's
+          # that is used for indexing.
+          olcToolThreads: 1
+
+          dn: olcDatabase={-1}frontend,cn=config
+          objectClass: olcDatabaseConfig
+          objectClass: olcFrontendConfig
+          # The maximum number of entries that is returned for a search operation
+          olcSizeLimit: 500
+          # Allow unlimited access to local connection from the local root user
+          olcAccess: to *
+            by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
+            by * break
+          # Allow unauthenticated read access for schema and base DN autodiscovery
+          olcAccess: to dn.exact=""
+            by * read
+          olcAccess: to dn.base="cn=Subschema"
+            by * read
+
+          dn: olcDatabase=config,cn=config
+          objectClass: olcDatabaseConfig
+          olcRootDN: cn=admin,cn=config
+          #olcRootPW:
+          # NOTE: access to cn=config, system root can be manager
+          # with SASL mechanism (-Y EXTERNAL) over unix socket (-H ldapi://)
+          olcAccess: to *
+            by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
+            by * break
+
+          dn: cn=schema,cn=config
+          objectClass: olcSchemaConfig
+
+          include: file://${pkgs.openldap}/etc/schema/core.ldif
+          include: file://${pkgs.openldap}/etc/schema/cosine.ldif
+          include: file://${pkgs.openldap}/etc/schema/nis.ldif
+          include: file://${pkgs.openldap}/etc/schema/inetorgperson.ldif
+
+          dn: cn=module{0},cn=config
+          objectClass: olcModuleList
+          # Where the dynamically loaded modules are stored
+          #olcModulePath: /usr/lib/ldap
+          olcModuleLoad: back_mdb
+
+          ''
+          + unlinesAttrs (olcSuffix: {conf, ...}:
+              "include: file://" + pkgs.writeText "config.ldif" conf
+            ) slapdDatabases
+          );
+
+        slapdDatabases = {
+          "${dbSuffix}" = {
+            conf = ''
+              dn: olcBackend={1}mdb,cn=config
+              objectClass: olcBackendConfig
+
+              dn: olcDatabase={1}mdb,cn=config
+              olcSuffix: ${dbSuffix}
+              olcDbDirectory: ${openldap.dataDir}/${dbSuffix}
+              objectClass: olcDatabaseConfig
+              objectClass: olcMdbConfig
+              # NOTE: checkpoint the database periodically in case of system failure
+              # and to speed up slapd shutdown.
+              olcDbCheckpoint: 512 30
+              # Database max size is 1G
+              olcDbMaxSize: 1073741824
+              olcLastMod: TRUE
+              # NOTE: database superuser. Needed for syncrepl,
+              # and used to auth as admin through a TCP connection.
+              olcRootDN: cn=admin,${dbSuffix}
+              olcRootPW: ${dbAdminPwdHash}
+              #
+              olcDbIndex: objectClass eq
+              olcDbIndex: cn,uid eq
+              olcDbIndex: uidNumber,gidNumber eq
+              olcDbIndex: member,memberUid eq
+              #
+              olcAccess: to attrs=userPassword
+                by self write
+                by anonymous auth
+                by dn="cn=admin,${dbSuffix}" write
+                by dn="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
+                by * none
+              olcAccess: to attrs=shadowLastChange
+                by self write
+                by dn="cn=admin,${dbSuffix}" write
+                by dn="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
+                by * none
+              olcAccess: to dn.sub="ou=posix,${dbSuffix}"
+                by self read
+                by dn="cn=admin,${dbSuffix}" read
+                by dn="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
+              olcAccess: to *
+                by self read
+                by * none
+            '';
+            data = ''
+              dn: ${dbSuffix}
+              objectClass: top
+              objectClass: dcObject
+              objectClass: organization
+              o: ${dbDomain}
+
+              dn: cn=admin,${dbSuffix}
+              objectClass: simpleSecurityObject
+              objectClass: organizationalRole
+              description: ${dbDomain} LDAP administrator
+              roleOccupant: ${dbSuffix}
+              userPassword: ${ldapUserPwdHash}
+
+              dn: ou=posix,${dbSuffix}
+              objectClass: top
+              objectClass: organizationalUnit
+
+              dn: ou=accounts,ou=posix,${dbSuffix}
+              objectClass: top
+              objectClass: organizationalUnit
+
+              dn: ou=groups,ou=posix,${dbSuffix}
+              objectClass: top
+              objectClass: organizationalUnit
+            ''
+            + lib.concatMapStrings posixAccount [
+              { uid=ldapUser; uidNumber=ldapUserId; gidNumber=ldapGroupId; userPassword=ldapUserPwdHash; }
+            ]
+            + lib.concatMapStrings posixGroup [
+              { gid=ldapGroup; gidNumber=ldapGroupId; members=[]; }
+            ];
+          };
+        };
+
+        # NOTE: create a user account using the posixAccount objectClass.
+        posixAccount =
+          { uid
+          , uidNumber ? null
+          , gidNumber ? null
+          , cn ? ""
+          , sn ? ""
+          , userPassword ? ""
+          , loginShell ? "/bin/sh"
+          }: ''
+
+            dn: uid=${uid},ou=accounts,ou=posix,${dbSuffix}
+            objectClass: person
+            objectClass: posixAccount
+            objectClass: shadowAccount
+            cn: ${cn}
+            gecos:
+            ${if gidNumber == null then "#" else "gidNumber: ${toString gidNumber}"}
+            homeDirectory: /home/${uid}
+            loginShell: ${loginShell}
+            sn: ${sn}
+            ${if uidNumber == null then "#" else "uidNumber: ${toString uidNumber}"}
+            ${if userPassword == "" then "#" else "userPassword: ${userPassword}"}
+          '';
+
+        # NOTE: create a group using the posixGroup objectClass.
+        posixGroup =
+          { gid
+          , gidNumber
+          , members
+          }: ''
+
+            dn: cn=${gid},ou=groups,ou=posix,${dbSuffix}
+            objectClass: top
+            objectClass: posixGroup
+            gidNumber: ${toString gidNumber}
+            ${lib.concatMapStrings (member: "memberUid: ${member}\n") members}
+          '';
+      in
       {
         virtualisation.memorySize = 256;
         virtualisation.vlans = [ 1 ];
         networking.firewall.allowedTCPPorts = [ 389 ];
         services.openldap.enable = true;
-        services.openldap.dataDir = dbPath;
+        services.openldap.dataDir = "/var/db/openldap";
+        services.openldap.configDir = "/var/db/slapd";
         services.openldap.urlList = [
-          serverUri
+          "ldap:///"
+          "ldapi:///"
         ];
-        services.openldap.extraConfig = ''
-          include ${pkgs.openldap.out}/etc/schema/core.schema
-          include ${pkgs.openldap.out}/etc/schema/cosine.schema
-          include ${pkgs.openldap.out}/etc/schema/inetorgperson.schema
-          include ${pkgs.openldap.out}/etc/schema/nis.schema
-
-          database mdb
-          suffix ${dbSuffix}
-          rootdn ${dbAdminDn}
-          rootpw ${dbAdminPwd}
-          directory ${dbPath}
-        '';
+        systemd.services.openldap = {
+          preStart = ''
+              set -e
+              # NOTE: slapd's config is always re-initialized.
+              rm -rf "${openldap.configDir}"/cn=config \
+                     "${openldap.configDir}"/cn=config.ldif
+              install -D -d -m 0700 -o "${openldap.user}" -g "${openldap.group}" "${openldap.configDir}"
+              # NOTE: olcDbDirectory must be created before adding the config.
+              '' +
+              unlinesAttrs (olcSuffix: {data, ...}: ''
+                # NOTE: database is always re-initialized.
+                rm -rf "${openldap.dataDir}/${olcSuffix}"
+                install -D -d -m 0700 -o "${openldap.user}" -g "${openldap.group}" \
+                 "${openldap.dataDir}/${olcSuffix}"
+                '') slapdDatabases
+              + ''
+              # NOTE: slapd is supposed to be stopped while in preStart,
+              #       hence slap* commands can safely be used.
+              umask 0077
+              ${pkgs.openldap}/bin/slapadd -n 0 \
+               -F "${openldap.configDir}" \
+               -l ${slapdConfig}
+              chown -R "${openldap.user}:${openldap.group}" "${openldap.configDir}"
+              # NOTE: slapadd(8): To populate the config database slapd-config(5),
+              #                   use -n 0 as it is always the first database.
+              #                   It must physically exist on the filesystem prior to this, however.
+            '' +
+            unlinesAttrs (olcSuffix: {data, ...}: ''
+              # NOTE: load database ${olcSuffix}
+              # (as root to avoid depending on sudo or chpst)
+              ${pkgs.openldap}/bin/slapadd \
+               -F "${openldap.configDir}" \
+               -l ${pkgs.writeText "data.ldif" data}
+              '' + ''
+              # NOTE: redundant with default openldap's preStart, but do not harm.
+              chown -R "${openldap.user}:${openldap.group}" \
+               "${openldap.dataDir}/${olcSuffix}"
+            '') slapdDatabases;
+        };
       };
 
     client1 = mkClient true; # use nss_pam_ldapd
@@ -91,15 +293,91 @@ in
   };
 
   testScript = ''
-    startAll;
+    $server->start;
     $server->waitForUnit("default.target");
+
+    subtest "slapd", sub {
+      subtest "auth as database admin with SASL and check a POSIX account", sub {
+        $server->succeed(join ' ', 'test',
+         '"$(ldapsearch -LLL -H ldapi:// -Y EXTERNAL',
+             '-b \'uid=${ldapUser},ou=accounts,ou=posix,${dbSuffix}\' ',
+             '-s base uidNumber |',
+           'sed -ne \'s/^uidNumber: \\(.*\\)/\\1/p\' ',
+         ')" -eq ${toString ldapUserId}');
+      };
+      subtest "auth as database admin with password and check a POSIX account", sub {
+        $server->succeed(join ' ', 'test',
+         '"$(ldapsearch -LLL -H ldap://server',
+             '-D \'cn=admin,${dbSuffix}\' -w \'${dbAdminPwd}\' ',
+             '-b \'uid=${ldapUser},ou=accounts,ou=posix,${dbSuffix}\' ',
+             '-s base uidNumber |',
+           'sed -ne \'s/^uidNumber: \\(.*\\)/\\1/p\' ',
+         ')" -eq ${toString ldapUserId}');
+      };
+    };
+
+    $client1->start;
     $client1->waitForUnit("default.target");
-    $client2->waitForUnit("default.target");
 
-    $server->succeed("ldapadd -D '${dbAdminDn}' -w ${dbAdminPwd} -H ${serverUri} -f '${setupLdif}'");
+    subtest "password", sub {
+      subtest "su with password to a POSIX account", sub {
+        $client1->succeed("${pkgs.expect}/bin/expect -c '" . join ';',
+          'spawn su "${ldapUser}"',
+          'expect "Password:"',
+          'send "${ldapUserPwd}\n"',
+          'expect "*"',
+          'send "whoami\n"',
+          'expect -ex "${ldapUser}" {exit}',
+          'exit 1' . "'");
+      };
+      subtest "change password of a POSIX account as root", sub {
+        $client1->succeed("chpasswd <<<'${ldapUser}:new-password'");
+        $client1->succeed("${pkgs.expect}/bin/expect -c '" . join ';',
+          'spawn su "${ldapUser}"',
+          'expect "Password:"',
+          'send "new-password\n"',
+          'expect "*"',
+          'send "whoami\n"',
+          'expect -ex "${ldapUser}" {exit}',
+          'exit 1' . "'");
+        $client1->succeed('chpasswd <<<\'${ldapUser}:${ldapUserPwd}\' ');
+      };
+      subtest "change password of a POSIX account from itself", sub {
+        $client1->succeed('chpasswd <<<\'${ldapUser}:${ldapUserPwd}\' ');
+        $client1->succeed("${pkgs.expect}/bin/expect -c '" . join ';',
+          'spawn su --login ${ldapUser} -c passwd',
+          'expect "Password: "',
+          'send "${ldapUserPwd}\n"',
+          'expect "(current) UNIX password: "',
+          'send "${ldapUserPwd}\n"',
+          'expect "New password: "',
+          'send "new-password\n"',
+          'expect "Retype new password: "',
+          'send "new-password\n"',
+          'expect "passwd: password updated successfully" {exit}',
+          'exit 1' . "'");
+        $client1->succeed("${pkgs.expect}/bin/expect -c '" . join ';',
+          'spawn su "${ldapUser}"',
+          'expect "Password:"',
+          'send "${ldapUserPwd}\n"',
+          'expect "su: Authentication failure" {exit}',
+          'exit 1' . "'");
+        $client1->succeed("${pkgs.expect}/bin/expect -c '" . join ';',
+          'spawn su "${ldapUser}"',
+          'expect "Password:"',
+          'send "new-password\n"',
+          'expect "*"',
+          'send "whoami\n"',
+          'expect -ex "${ldapUser}" {exit}',
+          'exit 1' . "'");
+        $client1->succeed('chpasswd <<<\'${ldapUser}:${ldapUserPwd}\' ');
+      };
+    };
+
+    $client2->start;
+    $client2->waitForUnit("default.target");
 
-    # NSS tests
-    subtest "nss", sub {
+    subtest "NSS", sub {
         $client1->succeed("test \"\$(id -u '${ldapUser}')\" -eq ${toString ldapUserId}");
         $client1->succeed("test \"\$(id -u -n '${ldapUser}')\" = '${ldapUser}'");
         $client1->succeed("test \"\$(id -g '${ldapUser}')\" -eq ${toString ldapGroupId}");
@@ -110,8 +388,7 @@ in
         $client2->succeed("test \"\$(id -g -n '${ldapUser}')\" = '${ldapGroup}'");
     };
 
-    # PAM tests
-    subtest "pam", sub {
+    subtest "PAM", sub {
         $client1->succeed("echo ${ldapUserPwd} | su -l '${ldapUser}' -c true");
         $client2->succeed("echo ${ldapUserPwd} | su -l '${ldapUser}' -c true");
     };
diff --git a/nixpkgs/nixos/tests/lidarr.nix b/nixpkgs/nixos/tests/lidarr.nix
new file mode 100644
index 000000000000..58bf82503f8c
--- /dev/null
+++ b/nixpkgs/nixos/tests/lidarr.nix
@@ -0,0 +1,18 @@
+import ./make-test.nix ({ lib, ... }:
+
+with lib;
+
+rec {
+  name = "lidarr";
+  meta.maintainers = with maintainers; [ etu ];
+
+  nodes.machine =
+    { pkgs, ... }:
+    { services.lidarr.enable = true; };
+
+  testScript = ''
+    $machine->waitForUnit('lidarr.service');
+    $machine->waitForOpenPort('8686');
+    $machine->succeed("curl --fail http://localhost:8686/");
+  '';
+})
diff --git a/nixpkgs/nixos/tests/mongodb.nix b/nixpkgs/nixos/tests/mongodb.nix
index 2f380ff543e9..c9439b65292d 100644
--- a/nixpkgs/nixos/tests/mongodb.nix
+++ b/nixpkgs/nixos/tests/mongodb.nix
@@ -8,7 +8,7 @@ import ./make-test.nix ({ pkgs, ...} : let
 in {
   name = "mongodb";
   meta = with pkgs.stdenv.lib.maintainers; {
-    maintainers = [ bluescreen303 offline wkennington cstrahan rvl ];
+    maintainers = [ bluescreen303 offline cstrahan rvl ];
   };
 
   nodes = {
diff --git a/nixpkgs/nixos/tests/munin.nix b/nixpkgs/nixos/tests/munin.nix
index 9f66005292ab..95cecf17b8cc 100644
--- a/nixpkgs/nixos/tests/munin.nix
+++ b/nixpkgs/nixos/tests/munin.nix
@@ -15,9 +15,7 @@ import ./make-test.nix ({ pkgs, ...} : {
            munin-node = {
              enable = true;
              # disable a failing plugin to prevent irrelevant error message, see #23049
-             extraConfig = ''
-               ignore_file ^apc_nis$
-             '';
+             disabledPlugins = [ "apc_nis" ];
            };
            munin-cron = {
             enable = true;
diff --git a/nixpkgs/nixos/tests/nat.nix b/nixpkgs/nixos/tests/nat.nix
index 04b4f0f045f0..34229e913110 100644
--- a/nixpkgs/nixos/tests/nat.nix
+++ b/nixpkgs/nixos/tests/nat.nix
@@ -24,7 +24,7 @@ import ./make-test.nix ({ pkgs, lib, withFirewall, withConntrackHelpers ? false,
     name = "nat" + (if withFirewall then "WithFirewall" else "Standalone")
                  + (lib.optionalString withConntrackHelpers "withConntrackHelpers");
     meta = with pkgs.stdenv.lib.maintainers; {
-      maintainers = [ eelco chaoflow rob wkennington ];
+      maintainers = [ eelco chaoflow rob ];
     };
 
     nodes =
diff --git a/nixpkgs/nixos/tests/ndppd.nix b/nixpkgs/nixos/tests/ndppd.nix
new file mode 100644
index 000000000000..9f24eb6d9d45
--- /dev/null
+++ b/nixpkgs/nixos/tests/ndppd.nix
@@ -0,0 +1,61 @@
+import ./make-test.nix ({ pkgs, lib, ...} : {
+  name = "ndppd";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ fpletz ];
+  };
+
+  nodes = {
+    upstream = { pkgs, ... }: {
+      environment.systemPackages = [ pkgs.tcpdump ];
+      networking.useDHCP = false;
+      networking.interfaces = {
+        eth1 = {
+          ipv6.addresses = [
+            { address = "fd23::1"; prefixLength = 112; }
+          ];
+          ipv6.routes = [
+            { address = "fd42::";
+              prefixLength = 112;
+            }
+          ];
+        };
+      };
+    };
+    server = { pkgs, ... }: {
+      boot.kernel.sysctl = {
+        "net.ipv6.conf.all.forwarding" = "1";
+        "net.ipv6.conf.default.forwarding" = "1";
+      };
+      environment.systemPackages = [ pkgs.tcpdump ];
+      networking.useDHCP = false;
+      networking.interfaces = {
+        eth1 = {
+          ipv6.addresses = [
+            { address = "fd23::2"; prefixLength = 112; }
+          ];
+        };
+      };
+      services.ndppd = {
+        enable = true;
+        interface = "eth1";
+        network = "fd42::/112";
+      };
+      containers.client = {
+        autoStart = true;
+        privateNetwork = true;
+        hostAddress = "192.168.255.1";
+        localAddress = "192.168.255.2";
+        hostAddress6 = "fd42::1";
+        localAddress6 = "fd42::2";
+        config = {};
+      };
+    };
+  };
+
+  testScript = ''
+    startAll;
+    $server->waitForUnit("multi-user.target");
+    $upstream->waitForUnit("multi-user.target");
+    $upstream->waitUntilSucceeds("ping -c5 fd42::2");
+  '';
+})
diff --git a/nixpkgs/nixos/tests/neo4j.nix b/nixpkgs/nixos/tests/neo4j.nix
new file mode 100644
index 000000000000..86ed8970517c
--- /dev/null
+++ b/nixpkgs/nixos/tests/neo4j.nix
@@ -0,0 +1,20 @@
+import ./make-test.nix {
+  name = "neo4j";
+
+  nodes = {
+    master =
+      { ... }:
+
+      {
+        services.neo4j.enable = true;
+      };
+  };
+
+  testScript = ''
+    startAll;
+
+    $master->waitForUnit("neo4j");
+    $master->sleep(20); # Hopefully this is long enough!!
+    $master->succeed("curl http://localhost:7474/");
+  '';
+}
diff --git a/nixpkgs/nixos/tests/networking.nix b/nixpkgs/nixos/tests/networking.nix
index e689eadf1dd8..ed9f287d5582 100644
--- a/nixpkgs/nixos/tests/networking.nix
+++ b/nixpkgs/nixos/tests/networking.nix
@@ -606,7 +606,4 @@ let
 
 in mapAttrs (const (attrs: makeTest (attrs // {
   name = "${attrs.name}-Networking-${if networkd then "Networkd" else "Scripted"}";
-  meta = with pkgs.stdenv.lib.maintainers; {
-    maintainers = [ wkennington ];
-  };
 }))) testCases
diff --git a/nixpkgs/nixos/tests/nexus.nix b/nixpkgs/nixos/tests/nexus.nix
index bf49d2247bd8..783c9f5c019f 100644
--- a/nixpkgs/nixos/tests/nexus.nix
+++ b/nixpkgs/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/nixpkgs/nixos/tests/nfs.nix b/nixpkgs/nixos/tests/nfs.nix
index 0ef44f1a4890..ce1717018933 100644
--- a/nixpkgs/nixos/tests/nfs.nix
+++ b/nixpkgs/nixos/tests/nfs.nix
@@ -20,7 +20,7 @@ in
 {
   name = "nfs";
   meta = with pkgs.stdenv.lib.maintainers; {
-    maintainers = [ eelco chaoflow wkennington ];
+    maintainers = [ eelco chaoflow  ];
   };
 
   nodes =
diff --git a/nixpkgs/nixos/tests/nginx-sso.nix b/nixpkgs/nixos/tests/nginx-sso.nix
new file mode 100644
index 000000000000..e19992cb6bf7
--- /dev/null
+++ b/nixpkgs/nixos/tests/nginx-sso.nix
@@ -0,0 +1,44 @@
+import ./make-test.nix ({ pkgs, ... }: {
+  name = "nginx-sso";
+  meta = {
+    maintainers = with pkgs.stdenv.lib.maintainers; [ delroth ];
+  };
+
+  machine = {
+    services.nginx.sso = {
+      enable = true;
+      configuration = {
+        listen = { addr = "127.0.0.1"; port = 8080; };
+
+        providers.token.tokens = {
+          myuser = "MyToken";
+        };
+
+        acl = {
+          rule_sets = [
+            {
+              rules = [ { field = "x-application"; equals = "MyApp"; } ];
+              allow = [ "myuser" ];
+            }
+          ];
+        };
+      };
+    };
+  };
+
+  testScript = ''
+    startAll;
+
+    $machine->waitForUnit("nginx-sso.service");
+    $machine->waitForOpenPort(8080);
+
+    # No valid user -> 401.
+    $machine->fail("curl -sSf http://localhost:8080/auth");
+
+    # Valid user but no matching ACL -> 403.
+    $machine->fail("curl -sSf -H 'Authorization: Token MyToken' http://localhost:8080/auth");
+
+    # Valid user and matching ACL -> 200.
+    $machine->succeed("curl -sSf -H 'Authorization: Token MyToken' -H 'X-Application: MyApp' http://localhost:8080/auth");
+  '';
+})
diff --git a/nixpkgs/nixos/tests/pam-u2f.nix b/nixpkgs/nixos/tests/pam-u2f.nix
new file mode 100644
index 000000000000..1052a2f3b916
--- /dev/null
+++ b/nixpkgs/nixos/tests/pam-u2f.nix
@@ -0,0 +1,23 @@
+import ./make-test.nix ({ ... }:
+
+{
+  name = "pam-u2f";
+
+  machine =
+    { ... }:
+    {
+      security.pam.u2f = {
+        control = "required";
+        cue = true;
+        debug = true;
+        enable = true;
+        interactive = true;
+      };
+    };
+
+  testScript =
+    ''
+      $machine->waitForUnit('multi-user.target');
+      $machine->succeed('egrep "auth required .*/lib/security/pam_u2f.so.*debug.*interactive.*cue" /etc/pam.d/ -R');
+    '';
+})
diff --git a/nixpkgs/nixos/tests/postgis.nix b/nixpkgs/nixos/tests/postgis.nix
index 49be0672a8e5..294eb50b5fe5 100644
--- a/nixpkgs/nixos/tests/postgis.nix
+++ b/nixpkgs/nixos/tests/postgis.nix
@@ -12,7 +12,9 @@ import ./make-test.nix ({ pkgs, ...} : {
         services.postgresql = let mypg = pkgs.postgresql_11; in {
             enable = true;
             package = mypg;
-            extraPlugins = [ (pkgs.postgis.override { postgresql = mypg; }) ];
+            extraPlugins = with mypg.pkgs; [
+              postgis
+            ];
         };
       };
   };
@@ -22,5 +24,6 @@ import ./make-test.nix ({ pkgs, ...} : {
     $master->waitForUnit("postgresql");
     $master->sleep(10); # Hopefully this is long enough!!
     $master->succeed("sudo -u postgres psql -c 'CREATE EXTENSION postgis;'");
+    $master->succeed("sudo -u postgres psql -c 'CREATE EXTENSION postgis_topology;'");
   '';
 })
diff --git a/nixpkgs/nixos/tests/postgresql.nix b/nixpkgs/nixos/tests/postgresql.nix
index 1d434b62a5cb..ae5d6d095ea2 100644
--- a/nixpkgs/nixos/tests/postgresql.nix
+++ b/nixpkgs/nixos/tests/postgresql.nix
@@ -7,7 +7,7 @@ with import ../lib/testing.nix { inherit system pkgs; };
 with pkgs.lib;
 
 let
-  postgresql-versions = pkgs.callPackages ../../pkgs/servers/sql/postgresql { };
+  postgresql-versions = import ../../pkgs/servers/sql/postgresql pkgs;
   test-sql = pkgs.writeText "postgresql-test" ''
     CREATE EXTENSION pgcrypto; -- just to check if lib loading works
     CREATE TABLE sth (
@@ -21,7 +21,7 @@ let
     CREATE TABLE xmltest ( doc xml );
     INSERT INTO xmltest (doc) VALUES ('<test>ok</test>'); -- check if libxml2 enabled
   '';
-  make-postgresql-test = postgresql-name: postgresql-package: makeTest {
+  make-postgresql-test = postgresql-name: postgresql-package: backup-all: makeTest {
     name = postgresql-name;
     meta = with pkgs.stdenv.lib.maintainers; {
       maintainers = [ zagy ];
@@ -29,14 +29,17 @@ let
 
     machine = {...}:
       {
-        services.postgresql.package=postgresql-package;
         services.postgresql.enable = true;
+        services.postgresql.package = postgresql-package;
 
         services.postgresqlBackup.enable = true;
-        services.postgresqlBackup.databases = [ "postgres" ];
+        services.postgresqlBackup.databases = optional (!backup-all) "postgres";
       };
 
-    testScript = ''
+    testScript = let
+      backupName = if backup-all then "all" else "postgres";
+      backupService = if backup-all then "postgresqlBackup" else "postgresqlBackup-postgres";
+    in ''
       sub check_count {
         my ($select, $nlines) = @_;
         return 'test $(sudo -u postgres psql postgres -tAc "' . $select . '"|wc -l) -eq ' . $nlines;
@@ -56,12 +59,15 @@ let
       $machine->succeed(check_count("SELECT xpath(\'/test/text()\', doc) FROM xmltest;", 1));
 
       # Check backup service
-      $machine->succeed("systemctl start postgresqlBackup-postgres.service");
-      $machine->succeed("zcat /var/backup/postgresql/postgres.sql.gz | grep '<test>ok</test>'");
-      $machine->succeed("stat -c '%a' /var/backup/postgresql/postgres.sql.gz | grep 600");
+      $machine->succeed("systemctl start ${backupService}.service");
+      $machine->succeed("zcat /var/backup/postgresql/${backupName}.sql.gz | grep '<test>ok</test>'");
+      $machine->succeed("stat -c '%a' /var/backup/postgresql/${backupName}.sql.gz | grep 600");
       $machine->shutdown;
     '';
 
   };
 in
-  mapAttrs' (p-name: p-package: {name=p-name; value=make-postgresql-test p-name p-package;}) postgresql-versions
+  (mapAttrs' (name: package: { inherit name; value=make-postgresql-test name package false;}) postgresql-versions) // {
+    postgresql_11-backup-all = make-postgresql-test "postgresql_11-backup-all" postgresql-versions.postgresql_11 true;
+  }
+
diff --git a/nixpkgs/nixos/tests/prometheus-exporters.nix b/nixpkgs/nixos/tests/prometheus-exporters.nix
index 5d1e004c5dd1..140687a8182f 100644
--- a/nixpkgs/nixos/tests/prometheus-exporters.nix
+++ b/nixpkgs/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/nixpkgs/nixos/tests/radarr.nix b/nixpkgs/nixos/tests/radarr.nix
new file mode 100644
index 000000000000..6b9a909e44b5
--- /dev/null
+++ b/nixpkgs/nixos/tests/radarr.nix
@@ -0,0 +1,18 @@
+import ./make-test.nix ({ lib, ... }:
+
+with lib;
+
+rec {
+  name = "radarr";
+  meta.maintainers = with maintainers; [ etu ];
+
+  nodes.machine =
+    { pkgs, ... }:
+    { services.radarr.enable = true; };
+
+  testScript = ''
+    $machine->waitForUnit('radarr.service');
+    $machine->waitForOpenPort('7878');
+    $machine->succeed("curl --fail http://localhost:7878/");
+  '';
+})
diff --git a/nixpkgs/nixos/tests/redmine.nix b/nixpkgs/nixos/tests/redmine.nix
index 330f72854cac..ea72a0121d11 100644
--- a/nixpkgs/nixos/tests/redmine.nix
+++ b/nixpkgs/nixos/tests/redmine.nix
@@ -1,40 +1,58 @@
-import ./make-test.nix ({ pkgs, lib, ... }:
-{
-  name = "redmine";
-  meta.maintainers = [ lib.maintainers.aanderse ];
+{ system ? builtins.currentSystem,
+  config ? {},
+  pkgs ? import ../.. { inherit system config; }
+}:
+
+with import ../lib/testing.nix { inherit system pkgs; };
+with pkgs.lib;
 
-  machine =
-    { config, pkgs, ... }:
-    { services.mysql.enable = true;
-      services.mysql.package = pkgs.mariadb;
-      services.mysql.ensureDatabases = [ "redmine" ];
-      services.mysql.ensureUsers = [
-        { name = "redmine";
-          ensurePermissions = { "redmine.*" = "ALL PRIVILEGES"; };
-        }
-      ];
+let
+  redmineTest = package: makeTest {
+    machine =
+      { config, pkgs, ... }:
+      { services.mysql.enable = true;
+        services.mysql.package = pkgs.mariadb;
+        services.mysql.ensureDatabases = [ "redmine" ];
+        services.mysql.ensureUsers = [
+          { name = "redmine";
+            ensurePermissions = { "redmine.*" = "ALL PRIVILEGES"; };
+          }
+        ];
 
-      services.redmine.enable = true;
-      services.redmine.database.socket = "/run/mysqld/mysqld.sock";
-      services.redmine.plugins = {
-        redmine_env_auth = pkgs.fetchurl {
-          url = https://github.com/Intera/redmine_env_auth/archive/0.6.zip;
-          sha256 = "0yyr1yjd8gvvh832wdc8m3xfnhhxzk2pk3gm2psg5w9jdvd6skak";
+        services.redmine.enable = true;
+        services.redmine.package = package;
+        services.redmine.database.socket = "/run/mysqld/mysqld.sock";
+        services.redmine.plugins = {
+          redmine_env_auth = pkgs.fetchurl {
+            url = https://github.com/Intera/redmine_env_auth/archive/0.7.zip;
+            sha256 = "1xb8lyarc7mpi86yflnlgyllh9hfwb9z304f19dx409gqpia99sc";
+          };
         };
-      };
-      services.redmine.themes = {
-        dkuk-redmine_alex_skin = pkgs.fetchurl {
-          url = https://bitbucket.org/dkuk/redmine_alex_skin/get/1842ef675ef3.zip;
-          sha256 = "0hrin9lzyi50k4w2bd2b30vrf1i4fi1c0gyas5801wn8i7kpm9yl";
+        services.redmine.themes = {
+          dkuk-redmine_alex_skin = pkgs.fetchurl {
+            url = https://bitbucket.org/dkuk/redmine_alex_skin/get/1842ef675ef3.zip;
+            sha256 = "0hrin9lzyi50k4w2bd2b30vrf1i4fi1c0gyas5801wn8i7kpm9yl";
+          };
         };
       };
-    };
 
-  testScript = ''
-    startAll;
+    testScript = ''
+      startAll;
+
+      $machine->waitForUnit('redmine.service');
+      $machine->waitForOpenPort('3000');
+      $machine->succeed("curl --fail http://localhost:3000/");
+    '';
+  };
+in
+{
+  redmine_3 = redmineTest pkgs.redmine // {
+    name = "redmine_3";
+    meta.maintainers = [ maintainers.aanderse ];
+  };
 
-    $machine->waitForUnit('redmine.service');
-    $machine->waitForOpenPort('3000');
-    $machine->succeed("curl --fail http://localhost:3000/");
-  '';
-})
+  redmine_4 = redmineTest pkgs.redmine_4 // {
+    name = "redmine_4";
+    meta.maintainers = [ maintainers.aanderse ];
+  };
+}
diff --git a/nixpkgs/nixos/tests/sonarr.nix b/nixpkgs/nixos/tests/sonarr.nix
new file mode 100644
index 000000000000..3d5c3b19b6ea
--- /dev/null
+++ b/nixpkgs/nixos/tests/sonarr.nix
@@ -0,0 +1,18 @@
+import ./make-test.nix ({ lib, ... }:
+
+with lib;
+
+rec {
+  name = "sonarr";
+  meta.maintainers = with maintainers; [ etu ];
+
+  nodes.machine =
+    { pkgs, ... }:
+    { services.sonarr.enable = true; };
+
+  testScript = ''
+    $machine->waitForUnit('sonarr.service');
+    $machine->waitForOpenPort('8989');
+    $machine->succeed("curl --fail http://localhost:8989/");
+  '';
+})
diff --git a/nixpkgs/nixos/tests/telegraf.nix b/nixpkgs/nixos/tests/telegraf.nix
new file mode 100644
index 000000000000..6776f8d8c37f
--- /dev/null
+++ b/nixpkgs/nixos/tests/telegraf.nix
@@ -0,0 +1,30 @@
+import ./make-test.nix ({ pkgs, ...} : {
+  name = "telegraf";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ mic92 ];
+  };
+
+  machine = { ... }: {
+    services.telegraf.enable = true;
+    services.telegraf.extraConfig = {
+      agent.interval = "1s";
+      agent.flush_interval = "1s";
+      inputs.exec = {
+        commands = [
+          "${pkgs.runtimeShell} -c 'echo example,tag=a i=42i'"
+        ];
+        timeout = "5s";
+        data_format = "influx";
+      };
+      outputs.file.files = ["/tmp/metrics.out"];
+      outputs.file.data_format = "influx";
+    };
+  };
+
+  testScript = ''
+    startAll;
+
+    $machine->waitForUnit("telegraf.service");
+    $machine->waitUntilSucceeds("grep -q example /tmp/metrics.out");
+  '';
+})
diff --git a/nixpkgs/nixos/tests/virtualbox.nix b/nixpkgs/nixos/tests/virtualbox.nix
index 385e2939fe3b..84d5f3e1530e 100644
--- a/nixpkgs/nixos/tests/virtualbox.nix
+++ b/nixpkgs/nixos/tests/virtualbox.nix
@@ -379,7 +379,7 @@ let
     '';
 
     meta = with pkgs.stdenv.lib.maintainers; {
-      maintainers = [ aszlig wkennington cdepillabout ];
+      maintainers = [ aszlig cdepillabout ];
     };
   };
 
diff --git a/nixpkgs/nixos/tests/xss-lock.nix b/nixpkgs/nixos/tests/xss-lock.nix
index 045667bdcdec..b46bb1a8f6e9 100644
--- a/nixpkgs/nixos/tests/xss-lock.nix
+++ b/nixpkgs/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");
   '';
 })