summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/installation/installing-usb.xml2
-rw-r--r--nixos/doc/manual/release-notes/rl-1803.xml2
-rw-r--r--nixos/lib/make-disk-image.nix2
-rw-r--r--nixos/lib/test-driver/Machine.pm11
-rw-r--r--nixos/lib/testing.nix1
-rw-r--r--nixos/modules/config/debug-info.nix7
-rw-r--r--nixos/modules/config/nsswitch.nix2
-rw-r--r--nixos/modules/config/system-path.nix1
-rw-r--r--nixos/modules/config/timezone.nix5
-rw-r--r--nixos/modules/hardware/network/intel-2030.nix3
-rw-r--r--nixos/modules/hardware/network/intel-2100bg.nix30
-rw-r--r--nixos/modules/hardware/network/intel-3945abg.nix29
-rw-r--r--nixos/modules/hardware/network/intel-4965agn.nix3
-rw-r--r--nixos/modules/hardware/network/intel-5000.nix3
-rw-r--r--nixos/modules/hardware/network/intel-5150.nix3
-rw-r--r--nixos/modules/hardware/network/intel-6000.nix3
-rw-r--r--nixos/modules/hardware/network/intel-6000g2a.nix3
-rw-r--r--nixos/modules/hardware/network/intel-6000g2b.nix3
-rw-r--r--nixos/modules/hardware/network/ralink.nix26
-rw-r--r--nixos/modules/hardware/network/rtl8192c.nix26
-rw-r--r--nixos/modules/installer/scan/detected.nix5
-rw-r--r--nixos/modules/installer/tools/nixos-generate-config.pl12
-rw-r--r--nixos/modules/misc/ids.nix6
-rw-r--r--nixos/modules/misc/locate.nix16
-rw-r--r--nixos/modules/module-list.nix12
-rw-r--r--nixos/modules/profiles/all-hardware.nix5
-rw-r--r--nixos/modules/programs/command-not-found/command-not-found.nix9
-rw-r--r--nixos/modules/programs/sway.nix19
-rw-r--r--nixos/modules/programs/zsh/zsh-syntax-highlighting.nix116
-rw-r--r--nixos/modules/rename.nix6
-rw-r--r--nixos/modules/service-managers/docker.nix29
-rw-r--r--nixos/modules/service-managers/trivial.nix35
-rw-r--r--nixos/modules/services/continuous-integration/jenkins/default.nix9
-rw-r--r--nixos/modules/services/misc/gitea.nix270
-rw-r--r--nixos/modules/services/misc/gitlab.nix5
-rw-r--r--nixos/modules/services/misc/nix-daemon.nix1
-rw-r--r--nixos/modules/services/misc/plex.nix2
-rw-r--r--nixos/modules/services/misc/pykms.nix90
-rw-r--r--nixos/modules/services/misc/tzupdate.nix45
-rw-r--r--nixos/modules/services/monitoring/graphite.nix54
-rw-r--r--nixos/modules/services/monitoring/prometheus/minio-exporter.nix117
-rw-r--r--nixos/modules/services/network-filesystems/kbfs.nix3
-rw-r--r--nixos/modules/services/network-filesystems/openafs-client/default.nix1
-rw-r--r--nixos/modules/services/networking/connman.nix5
-rw-r--r--nixos/modules/services/networking/dnscache.nix11
-rw-r--r--nixos/modules/services/networking/firewall.nix8
-rw-r--r--nixos/modules/services/networking/keybase.nix3
-rw-r--r--nixos/modules/services/networking/unbound.nix2
-rw-r--r--nixos/modules/services/networking/znc.nix2
-rw-r--r--nixos/modules/services/scheduling/atd.nix4
-rw-r--r--nixos/modules/services/scheduling/fcron.nix7
-rw-r--r--nixos/modules/services/security/hologram-server.nix14
-rw-r--r--nixos/modules/services/security/sshguard.nix2
-rw-r--r--nixos/modules/services/web-apps/mattermost.nix10
-rw-r--r--nixos/modules/services/web-servers/lighttpd/default.nix6
-rw-r--r--nixos/modules/services/x11/compton.nix72
-rw-r--r--nixos/modules/services/x11/desktop-managers/mate.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/plasma5.nix5
-rw-r--r--nixos/modules/services/x11/display-managers/default.nix9
-rw-r--r--nixos/modules/services/x11/display-managers/sddm.nix11
-rw-r--r--nixos/modules/services/x11/hardware/libinput.nix15
-rw-r--r--nixos/modules/services/x11/xautolock.nix92
-rw-r--r--nixos/modules/system/boot/kernel.nix17
-rw-r--r--nixos/modules/system/boot/loader/grub/install-grub.pl2
-rw-r--r--nixos/modules/system/boot/resolved.nix72
-rw-r--r--nixos/modules/tasks/encrypted-devices.nix3
-rw-r--r--nixos/modules/tasks/filesystems/ext.nix3
-rw-r--r--nixos/modules/tasks/powertop.nix1
-rw-r--r--nixos/modules/virtualisation/brightbox-image.nix6
-rw-r--r--nixos/release-combined.nix12
-rw-r--r--nixos/release.nix5
-rw-r--r--nixos/tests/atd.nix36
-rw-r--r--nixos/tests/gitolite.nix139
-rw-r--r--nixos/tests/graphite.nix26
-rw-r--r--nixos/tests/installer.nix64
-rw-r--r--nixos/tests/minio.nix4
-rw-r--r--nixos/tests/postgis.nix10
-rw-r--r--nixos/tests/prometheus.nix3
-rw-r--r--nixos/tests/run-in-machine.nix17
-rw-r--r--nixos/tests/virtualbox.nix4
80 files changed, 1255 insertions, 480 deletions
diff --git a/nixos/doc/manual/installation/installing-usb.xml b/nixos/doc/manual/installation/installing-usb.xml
index b97f989d902c..31d51816e39b 100644
--- a/nixos/doc/manual/installation/installing-usb.xml
+++ b/nixos/doc/manual/installation/installing-usb.xml
@@ -31,7 +31,7 @@ ISO, copy its contents verbatim to your drive, then either:
     <para>Edit <filename>loader/entries/nixos-livecd.conf</filename> on the drive
     and change the <literal>root=</literal> field in the <literal>options</literal>
     line to point to your drive (see the documentation on <literal>root=</literal>
-    in <link xlink:href="https://www.kernel.org/doc/Documentation/kernel-parameters.txt">
+    in <link xlink:href="https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt">
     the kernel documentation</link> for more details).</para>
   </listitem>
   <listitem>
diff --git a/nixos/doc/manual/release-notes/rl-1803.xml b/nixos/doc/manual/release-notes/rl-1803.xml
index 830e7cdd2696..47522fe3cc92 100644
--- a/nixos/doc/manual/release-notes/rl-1803.xml
+++ b/nixos/doc/manual/release-notes/rl-1803.xml
@@ -71,6 +71,8 @@ following incompatible changes:</para>
 <itemizedlist>
   <listitem>
     <para>
+      ZNC option <option>services.znc.mutable</option> now defaults to <literal>true</literal>.
+      That means that old configuration is not overwritten by default when update to the znc options are made.
     </para>
   </listitem>
 </itemizedlist>
diff --git a/nixos/lib/make-disk-image.nix b/nixos/lib/make-disk-image.nix
index d4b2e338c3ef..9fa848301f60 100644
--- a/nixos/lib/make-disk-image.nix
+++ b/nixos/lib/make-disk-image.nix
@@ -80,7 +80,7 @@ let
     truncate -s ${toString diskSize}M $diskImage
 
     ${if partitioned then ''
-      parted $diskImage -- mklabel msdos mkpart primary ext4 1M -1s
+      parted --script $diskImage -- mklabel msdos mkpart primary ext4 1M -1s
       offset=$((2048*512))
     '' else ''
       offset=0
diff --git a/nixos/lib/test-driver/Machine.pm b/nixos/lib/test-driver/Machine.pm
index cd375352c4ca..a7ed5d1faa38 100644
--- a/nixos/lib/test-driver/Machine.pm
+++ b/nixos/lib/test-driver/Machine.pm
@@ -372,6 +372,17 @@ sub getUnitInfo {
     return $info;
 }
 
+# Fail if the given systemd unit is not in the "active" state.
+sub requireActiveUnit {
+    my ($self, $unit) = @_;
+    $self->nest("checking if unit ‘$unit’ has reached state 'active'", sub {
+        my $info = $self->getUnitInfo($unit);
+        my $state = $info->{ActiveState};
+        if ($state ne "active") {
+            die "Expected unit ‘$unit’ to to be in state 'active' but it is in state ‘$state’\n";
+        };
+    });
+}
 
 # Wait for a systemd unit to reach the "active" state.
 sub waitForUnit {
diff --git a/nixos/lib/testing.nix b/nixos/lib/testing.nix
index 58c447c76db6..9339ba78ff0c 100644
--- a/nixos/lib/testing.nix
+++ b/nixos/lib/testing.nix
@@ -149,6 +149,7 @@ rec {
           { key = "run-in-machine";
             networking.hostName = "client";
             nix.readOnlyStore = false;
+            virtualisation.writableStore = false;
           }
         ];
 
diff --git a/nixos/modules/config/debug-info.nix b/nixos/modules/config/debug-info.nix
index 49991d22a933..2942ae5905d1 100644
--- a/nixos/modules/config/debug-info.nix
+++ b/nixos/modules/config/debug-info.nix
@@ -30,14 +30,15 @@ with lib;
   };
 
 
-  config = {
+  config = mkIf config.environment.enableDebugInfo {
 
     # FIXME: currently disabled because /lib is already in
     # environment.pathsToLink, and we can't have both.
     #environment.pathsToLink = [ "/lib/debug/.build-id" ];
 
-    environment.extraOutputsToInstall =
-      optional config.environment.enableDebugInfo "debug";
+    environment.extraOutputsToInstall = [ "debug" ];
+
+    environment.variables.NIX_DEBUG_INFO_DIRS = [ "/run/current-system/sw/lib/debug" ];
 
   };
 
diff --git a/nixos/modules/config/nsswitch.nix b/nixos/modules/config/nsswitch.nix
index 97278238dcd5..7b36d4f1cbdf 100644
--- a/nixos/modules/config/nsswitch.nix
+++ b/nixos/modules/config/nsswitch.nix
@@ -18,7 +18,7 @@ let
 
   hostArray = [ "files" ]
     ++ optionals mymachines [ "mymachines" ]
-    ++ optionals nssmdns [ "mdns_minimal [!UNAVAIL=return]" ]
+    ++ optionals nssmdns [ "mdns_minimal [NOTFOUND=return]" ]
     ++ optionals nsswins [ "wins" ]
     ++ optionals resolved ["resolve [!UNAVAIL=return]"]
     ++ [ "dns" ]
diff --git a/nixos/modules/config/system-path.nix b/nixos/modules/config/system-path.nix
index 5d339eaea485..d3212d931605 100644
--- a/nixos/modules/config/system-path.nix
+++ b/nixos/modules/config/system-path.nix
@@ -31,6 +31,7 @@ let
       pkgs.nano
       pkgs.ncurses
       pkgs.netcat
+      pkgs.nix-info
       config.programs.ssh.package
       pkgs.perl
       pkgs.procps
diff --git a/nixos/modules/config/timezone.nix b/nixos/modules/config/timezone.nix
index aa030a816d04..b15948f6e2e5 100644
--- a/nixos/modules/config/timezone.nix
+++ b/nixos/modules/config/timezone.nix
@@ -5,6 +5,9 @@ with lib;
 let
 
   tzdir = "${pkgs.tzdata}/share/zoneinfo";
+  nospace  = str: filter (c: c == " ") (stringToCharacters str) == [];
+  timezone = types.nullOr (types.addCheck types.str nospace)
+    // { description = "null or string without spaces"; };
 
 in
 
@@ -15,7 +18,7 @@ in
 
       timeZone = mkOption {
         default = null;
-        type = types.nullOr types.str;
+        type = timezone;
         example = "America/New_York";
         description = ''
           The time zone used when displaying times and dates. See <link
diff --git a/nixos/modules/hardware/network/intel-2030.nix b/nixos/modules/hardware/network/intel-2030.nix
deleted file mode 100644
index c92b7a0509d0..000000000000
--- a/nixos/modules/hardware/network/intel-2030.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  hardware.enableRedistributableFirmware = true;
-}
diff --git a/nixos/modules/hardware/network/intel-2100bg.nix b/nixos/modules/hardware/network/intel-2100bg.nix
deleted file mode 100644
index 0ec81474ad3e..000000000000
--- a/nixos/modules/hardware/network/intel-2100bg.nix
+++ /dev/null
@@ -1,30 +0,0 @@
-{ config, pkgs, lib, ... }:
-
-{
-
-  ###### interface
-
-  options = {
-
-    networking.enableIntel2100BGFirmware = lib.mkOption {
-      default = false;
-      type = lib.types.bool;
-      description = ''
-        Turn on this option if you want firmware for the Intel
-        PRO/Wireless 2100BG to be loaded automatically.  This is
-        required if you want to use this device.
-      '';
-    };
-
-  };
-
-
-  ###### implementation
-
-  config = lib.mkIf config.networking.enableIntel2100BGFirmware {
-
-    hardware.enableRedistributableFirmware = true;
-
-  };
-
-}
diff --git a/nixos/modules/hardware/network/intel-3945abg.nix b/nixos/modules/hardware/network/intel-3945abg.nix
deleted file mode 100644
index 27a3f228b7d1..000000000000
--- a/nixos/modules/hardware/network/intel-3945abg.nix
+++ /dev/null
@@ -1,29 +0,0 @@
-{ config, pkgs, lib, ... }:
-
-{
-
-  ###### interface
-
-  options = {
-
-    networking.enableIntel3945ABGFirmware = lib.mkOption {
-      default = false;
-      type = lib.types.bool;
-      description = ''
-        This option enables automatic loading of the firmware for the Intel
-        PRO/Wireless 3945ABG.
-      '';
-    };
-
-  };
-
-
-  ###### implementation
-
-  config = lib.mkIf config.networking.enableIntel3945ABGFirmware {
-
-    hardware.enableRedistributableFirmware = true;
-
-  };
-
-}
diff --git a/nixos/modules/hardware/network/intel-4965agn.nix b/nixos/modules/hardware/network/intel-4965agn.nix
deleted file mode 100644
index c92b7a0509d0..000000000000
--- a/nixos/modules/hardware/network/intel-4965agn.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  hardware.enableRedistributableFirmware = true;
-}
diff --git a/nixos/modules/hardware/network/intel-5000.nix b/nixos/modules/hardware/network/intel-5000.nix
deleted file mode 100644
index c92b7a0509d0..000000000000
--- a/nixos/modules/hardware/network/intel-5000.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  hardware.enableRedistributableFirmware = true;
-}
diff --git a/nixos/modules/hardware/network/intel-5150.nix b/nixos/modules/hardware/network/intel-5150.nix
deleted file mode 100644
index c92b7a0509d0..000000000000
--- a/nixos/modules/hardware/network/intel-5150.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  hardware.enableRedistributableFirmware = true;
-}
diff --git a/nixos/modules/hardware/network/intel-6000.nix b/nixos/modules/hardware/network/intel-6000.nix
deleted file mode 100644
index c92b7a0509d0..000000000000
--- a/nixos/modules/hardware/network/intel-6000.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  hardware.enableRedistributableFirmware = true;
-}
diff --git a/nixos/modules/hardware/network/intel-6000g2a.nix b/nixos/modules/hardware/network/intel-6000g2a.nix
deleted file mode 100644
index c92b7a0509d0..000000000000
--- a/nixos/modules/hardware/network/intel-6000g2a.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  hardware.enableRedistributableFirmware = true;
-}
diff --git a/nixos/modules/hardware/network/intel-6000g2b.nix b/nixos/modules/hardware/network/intel-6000g2b.nix
deleted file mode 100644
index c92b7a0509d0..000000000000
--- a/nixos/modules/hardware/network/intel-6000g2b.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  hardware.enableRedistributableFirmware = true;
-}
diff --git a/nixos/modules/hardware/network/ralink.nix b/nixos/modules/hardware/network/ralink.nix
deleted file mode 100644
index 36182e2cb996..000000000000
--- a/nixos/modules/hardware/network/ralink.nix
+++ /dev/null
@@ -1,26 +0,0 @@
-{pkgs, config, lib, ...}:
-
-{
-
-  ###### interface
-
-  options = {
-
-    networking.enableRalinkFirmware = lib.mkOption {
-      default = false;
-      type = lib.types.bool;
-      description = ''
-        Turn on this option if you want firmware for the RT73 NIC.
-      '';
-    };
-
-  };
-
-
-  ###### implementation
-
-  config = lib.mkIf config.networking.enableRalinkFirmware {
-    hardware.enableRedistributableFirmware = true;
-  };
-
-}
diff --git a/nixos/modules/hardware/network/rtl8192c.nix b/nixos/modules/hardware/network/rtl8192c.nix
deleted file mode 100644
index bf328c2d3224..000000000000
--- a/nixos/modules/hardware/network/rtl8192c.nix
+++ /dev/null
@@ -1,26 +0,0 @@
-{pkgs, config, lib, ...}:
-
-{
-
-  ###### interface
-
-  options = {
-
-    networking.enableRTL8192cFirmware = lib.mkOption {
-      default = false;
-      type = lib.types.bool;
-      description = ''
-        Turn on this option if you want firmware for the RTL8192c (and related) NICs.
-      '';
-    };
-
-  };
-
-
-  ###### implementation
-
-  config = lib.mkIf config.networking.enableRTL8192cFirmware {
-    hardware.enableRedistributableFirmware = true;
-  };
-
-}
diff --git a/nixos/modules/installer/scan/detected.nix b/nixos/modules/installer/scan/detected.nix
index e72c78532943..7e181acb93b1 100644
--- a/nixos/modules/installer/scan/detected.nix
+++ b/nixos/modules/installer/scan/detected.nix
@@ -6,8 +6,7 @@ with lib;
 
 {
   config = mkDefault {
-    # Wireless card firmware
-    networking.enableIntel2200BGFirmware = true;
-    networking.enableIntel3945ABGFirmware = true;
+    # Common firmware, i.e. for wifi cards
+    hardware.enableRedistributableFirmware = true;
   };
 }
diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl
index 4ec48b773358..926d1e3133f7 100644
--- a/nixos/modules/installer/tools/nixos-generate-config.pl
+++ b/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -398,19 +398,15 @@ EOF
 
     # Is this a btrfs filesystem?
     if ($fsType eq "btrfs") {
-        my ($status, @id_info) = runCommand("btrfs subvol show $rootDir$mountPoint");
-        if ($status != 0 || join("", @id_info) =~ /ERROR:/) {
+        my ($status, @info) = runCommand("btrfs subvol show $rootDir$mountPoint");
+        if ($status != 0 || join("", @info) =~ /ERROR:/) {
             die "Failed to retrieve subvolume info for $mountPoint\n";
         }
-        my @ids = join("", @id_info) =~ m/Subvolume ID:[ \t\n]*([^ \t\n]*)/;
+        my @ids = join("\n", @info) =~ m/^(?!\/\n).*Subvolume ID:[ \t\n]*([0-9]+)/s;
         if ($#ids > 0) {
             die "Btrfs subvol name for $mountPoint listed multiple times in mount\n"
         } elsif ($#ids == 0) {
-            my ($status, @path_info) = runCommand("btrfs subvol list $rootDir$mountPoint");
-            if ($status != 0) {
-                die "Failed to find $mountPoint subvolume id from btrfs\n";
-            }
-            my @paths = join("", @path_info) =~ m/ID $ids[0] [^\n]* path ([^\n]*)/;
+            my @paths = join("", @info) =~ m/^([^\n]*)/;
             if ($#paths > 0) {
                 die "Btrfs returned multiple paths for a single subvolume id, mountpoint $mountPoint\n";
             } elsif ($#paths != 0) {
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index 508a76d3cab5..7d9d9984cf28 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -296,6 +296,9 @@
       clickhouse = 278;
       rslsync = 279;
       minio = 280;
+      kanboard = 281;
+      pykms = 282;
+      kodi = 283;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
@@ -561,6 +564,9 @@
       clickhouse = 278;
       rslsync = 279;
       minio = 280;
+      kanboard = 281;
+      pykms = 282;
+      kodi = 283;
 
       # When adding a gid, make sure it doesn't match an existing
       # uid. Users and groups with the same name should have equal
diff --git a/nixos/modules/misc/locate.nix b/nixos/modules/misc/locate.nix
index 0fe91435ce8c..51953d1110c4 100644
--- a/nixos/modules/misc/locate.nix
+++ b/nixos/modules/misc/locate.nix
@@ -125,13 +125,16 @@ in {
     warnings = optional (isMLocate && cfg.localuser != null) "mlocate does not support searching as user other than root"
             ++ optional (isFindutils && cfg.pruneNames != []) "findutils locate does not support pruning by directory component"
             ++ optional (isFindutils && cfg.pruneBindMounts) "findutils locate does not support skipping bind mounts";
-  
+
+    # directory creation needs to be separated from main service
+    # because ReadWritePaths fails when the directory doesn't already exist
+    systemd.tmpfiles.rules = [ "d ${dirOf cfg.output} 0755 root root -" ];
+
     systemd.services.update-locatedb =
       { description = "Update Locate Database";
         path = mkIf (!isMLocate) [ pkgs.su ];
         script =
           ''
-            mkdir -m 0755 -p ${dirOf cfg.output}
             exec ${cfg.locate}/bin/updatedb \
               ${optionalString (cfg.localuser != null && ! isMLocate) ''--localuser=${cfg.localuser}''} \
               --output=${toString cfg.output} ${concatStringsSep " " cfg.extraFlags}
@@ -147,8 +150,13 @@ in {
         serviceConfig.PrivateTmp = "yes";
         serviceConfig.PrivateNetwork = "yes";
         serviceConfig.NoNewPrivileges = "yes";
-        serviceConfig.ReadOnlyDirectories = "/";
-        serviceConfig.ReadWriteDirectories = dirOf cfg.output;
+        serviceConfig.ReadOnlyPaths = "/";
+        # Use dirOf cfg.output because mlocate creates temporary files next to
+        # the actual database. We could specify and create them as well,
+        # but that would make this quite brittle when they change something.
+        # NOTE: If /var/cache does not exist, this leads to the misleading error message:
+        # update-locatedb.service: Failed at step NAMESPACE spawning …/update-locatedb-start: No such file or directory
+        serviceConfig.ReadWritePaths = dirOf cfg.output;
       };
 
     systemd.timers.update-locatedb =
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 8ac7e5b52d69..e67e6ae32b9a 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -35,11 +35,6 @@
   ./hardware/ksm.nix
   ./hardware/mcelog.nix
   ./hardware/network/b43.nix
-  ./hardware/network/intel-2100bg.nix
-  ./hardware/network/intel-2200bg.nix
-  ./hardware/network/intel-3945abg.nix
-  ./hardware/network/ralink.nix
-  ./hardware/network/rtl8192c.nix
   ./hardware/nitrokey.nix
   ./hardware/opengl.nix
   ./hardware/pcmcia.nix
@@ -104,6 +99,7 @@
   ./programs/ssh.nix
   ./programs/ssmtp.nix
   ./programs/sysdig.nix
+  ./programs/sway.nix
   ./programs/thefuck.nix
   ./programs/tmux.nix
   ./programs/venus.nix
@@ -136,8 +132,6 @@
   ./security/rtkit.nix
   ./security/wrappers/default.nix
   ./security/sudo.nix
-  ./service-managers/docker.nix
-  ./service-managers/trivial.nix
   ./services/admin/salt/master.nix
   ./services/admin/salt/minion.nix
   ./services/amqp/activemq/default.nix
@@ -303,6 +297,7 @@
   ./services/misc/fstrim.nix
   ./services/misc/gammu-smsd.nix
   ./services/misc/geoip-updater.nix
+  ./services/misc/gitea.nix
   #./services/misc/gitit.nix
   ./services/misc/gitlab.nix
   ./services/misc/gitolite.nix
@@ -333,6 +328,7 @@
   ./services/misc/parsoid.nix
   ./services/misc/phd.nix
   ./services/misc/plex.nix
+  ./services/misc/pykms.nix
   ./services/misc/radarr.nix
   ./services/misc/redmine.nix
   ./services/misc/rippled.nix
@@ -349,6 +345,7 @@
   ./services/misc/svnserve.nix
   ./services/misc/synergy.nix
   ./services/misc/taskserver
+  ./services/misc/tzupdate.nix
   ./services/misc/uhub.nix
   ./services/misc/zookeeper.nix
   ./services/monitoring/apcupsd.nix
@@ -375,6 +372,7 @@
   ./services/monitoring/prometheus/collectd-exporter.nix
   ./services/monitoring/prometheus/fritzbox-exporter.nix
   ./services/monitoring/prometheus/json-exporter.nix
+  ./services/monitoring/prometheus/minio-exporter.nix
   ./services/monitoring/prometheus/nginx-exporter.nix
   ./services/monitoring/prometheus/node-exporter.nix
   ./services/monitoring/prometheus/snmp-exporter.nix
diff --git a/nixos/modules/profiles/all-hardware.nix b/nixos/modules/profiles/all-hardware.nix
index 6e6ae98e19fc..3c7e516c497f 100644
--- a/nixos/modules/profiles/all-hardware.nix
+++ b/nixos/modules/profiles/all-hardware.nix
@@ -41,15 +41,12 @@
 
       # Virtio (QEMU, KVM etc.) support.
       "virtio_net" "virtio_pci" "virtio_blk" "virtio_scsi" "virtio_balloon" "virtio_console"
-      
+
       # VMware support.
       "mptspi" "vmw_balloon" "vmwgfx" "vmw_vmci" "vmw_vsock_vmci_transport" "vmxnet3" "vsock"
 
       # Hyper-V support.
       "hv_storvsc"
-
-      # Keyboards
-      "usbhid" "hid_apple" "hid_logitech_dj" "hid_lenovo_tpkbd" "hid_roccat"
     ];
 
   # Include lots of firmware.
diff --git a/nixos/modules/programs/command-not-found/command-not-found.nix b/nixos/modules/programs/command-not-found/command-not-found.nix
index 55529d73cb60..bbe7165c62fb 100644
--- a/nixos/modules/programs/command-not-found/command-not-found.nix
+++ b/nixos/modules/programs/command-not-found/command-not-found.nix
@@ -25,7 +25,14 @@ in
 {
   options.programs.command-not-found = {
 
-    enable = mkEnableOption "command-not-found hook for interactive shell";
+    enable = mkOption {
+      type = types.bool;
+      default = true;
+      description = ''
+        Whether interactive shells should show which Nix package (if
+        any) provides a missing command.
+      '';
+    };
 
     dbPath = mkOption {
       default = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite" ;
diff --git a/nixos/modules/programs/sway.nix b/nixos/modules/programs/sway.nix
new file mode 100644
index 000000000000..fc8a06d106ae
--- /dev/null
+++ b/nixos/modules/programs/sway.nix
@@ -0,0 +1,19 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+{
+  options.programs.sway.enable = mkEnableOption "sway";
+
+  config = mkIf config.programs.sway.enable {
+    environment.systemPackages = [ pkgs.sway pkgs.xwayland ];
+    security.wrappers.sway = {
+      source = "${pkgs.sway}/bin/sway";
+      capabilities = "cap_sys_ptrace,cap_sys_tty_config=eip";
+      owner = "root";
+      group = "sway";
+      permissions = "u+rx,g+rx";
+    };
+
+    users.extraGroups.sway = {};
+  };
+}
diff --git a/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix b/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix
index 9452489e2fb4..e7cf17c2c00c 100644
--- a/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix
+++ b/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix
@@ -5,74 +5,74 @@ with lib;
 let
   cfg = config.programs.zsh.syntaxHighlighting;
 in
-  {
-    options = {
-      programs.zsh.syntaxHighlighting = {
-        enable = mkEnableOption "zsh-syntax-highlighting";
+{
+  options = {
+    programs.zsh.syntaxHighlighting = {
+      enable = mkEnableOption "zsh-syntax-highlighting";
 
-        highlighters = mkOption {
-          default = [ "main" ];
+      highlighters = mkOption {
+        default = [ "main" ];
 
-          # https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters.md
-          type = types.listOf(types.enum([
-            "main"
-            "brackets"
-            "pattern"
-            "cursor"
-            "root"
-            "line"
-          ]));
+        # https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters.md
+        type = types.listOf(types.enum([
+          "main"
+          "brackets"
+          "pattern"
+          "cursor"
+          "root"
+          "line"
+        ]));
 
-          description = ''
-            Specifies the highlighters to be used by zsh-syntax-highlighting.
+        description = ''
+          Specifies the highlighters to be used by zsh-syntax-highlighting.
 
-            The following defined options can be found here:
-            https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters.md
-          '';
-        };
+          The following defined options can be found here:
+          https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters.md
+        '';
+      };
 
-        patterns = mkOption {
-          default = {};
-          type = types.attrsOf types.string;
+      patterns = mkOption {
+        default = {};
+        type = types.attrsOf types.string;
 
-          example = literalExample ''
-            {
-              "rm -rf *" = "fg=white,bold,bg=red";
-            }
-          '';
+        example = literalExample ''
+          {
+            "rm -rf *" = "fg=white,bold,bg=red";
+          }
+        '';
 
-          description = ''
-            Specifies custom patterns to be highlighted by zsh-syntax-highlighting.
+        description = ''
+          Specifies custom patterns 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/pattern.md
-          '';
-        };
+          Please refer to the docs for more information about the usage:
+          https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters/pattern.md
+        '';
       };
     };
+  };
 
-    config = mkIf cfg.enable {
-      environment.systemPackages = with pkgs; [ zsh-syntax-highlighting ];
-
-      programs.zsh.interactiveShellInit = with pkgs; with builtins; ''
-        source ${zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
+  config = mkIf cfg.enable {
+    environment.systemPackages = with pkgs; [ zsh-syntax-highlighting ];
 
-        ${optionalString (length(cfg.highlighters) > 0)
-          "ZSH_HIGHLIGHT_HIGHLIGHTERS=(${concatStringsSep " " cfg.highlighters})"
-        }
+    assertions = [
+      {
+        assertion = length(attrNames cfg.patterns) > 0 -> elem "pattern" cfg.highlighters;
+        message = ''
+          When highlighting patterns, "pattern" needs to be included in the list of highlighters.
+        '';
+      }
+    ];
 
-        ${let
-            n = attrNames cfg.patterns;
-          in
-            optionalString (length(n) > 0)
-              (assert(elem "pattern" cfg.highlighters); (foldl (
-                a: b:
-                  ''
-                    ${a}
-                    ZSH_HIGHLIGHT_PATTERNS+=('${b}' '${attrByPath [b] "" cfg.patterns}')
-                  ''
-              ) "") n)
-        }
-      '';
-    };
-  }
+    programs.zsh.interactiveShellInit = with pkgs;
+      lib.concatStringsSep "\n" ([
+        "source ${zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
+      ] ++ optional (length(cfg.highlighters) > 0)
+        "ZSH_HIGHLIGHT_HIGHLIGHTERS=(${concatStringsSep " " cfg.highlighters})"
+        ++ optionals (length(attrNames cfg.patterns) > 0)
+          (mapAttrsToList (
+            pattern: design:
+            "ZSH_HIGHLIGHT_PATTERNS+=('${pattern}' '${design}')"
+          ) cfg.patterns)
+      );
+  };
+}
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index deff4067957a..b1b3f67a41d0 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -11,7 +11,11 @@ with lib;
     (mkRenamedOptionModule [ "fonts" "extraFonts" ] [ "fonts" "fonts" ])
 
     (mkRenamedOptionModule [ "networking" "enableWLAN" ] [ "networking" "wireless" "enable" ])
-    (mkRenamedOptionModule [ "networking" "enableRT73Firmware" ] [ "networking" "enableRalinkFirmware" ])
+    (mkRenamedOptionModule [ "networking" "enableRT73Firmware" ] [ "hardware" "enableRedistributableFirmware" ])
+    (mkRenamedOptionModule [ "networking" "enableIntel3945ABGFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
+    (mkRenamedOptionModule [ "networking" "enableIntel2100BGFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
+    (mkRenamedOptionModule [ "networking" "enableRalinkFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
+    (mkRenamedOptionModule [ "networking" "enableRTL8192cFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
 
     (mkRenamedOptionModule [ "services" "cadvisor" "host" ] [ "services" "cadvisor" "listenAddress" ])
     (mkChangedOptionModule [ "services" "printing" "gutenprint" ] [ "services" "printing" "drivers" ]
diff --git a/nixos/modules/service-managers/docker.nix b/nixos/modules/service-managers/docker.nix
deleted file mode 100644
index 8e9c763b18af..000000000000
--- a/nixos/modules/service-managers/docker.nix
+++ /dev/null
@@ -1,29 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
-  cfg = config.docker-containers;
-
-  containerModule = {
-    script = mkOption {
-      type = types.lines;
-      description = "Shell commands executed as the service's main process.";
-    };
-  };
-
-  toContainer = name: value: pkgs.dockerTools.buildImage {
-    inherit name;
-    config = {
-      Cmd = [ value.script ];
-    };
-  };
-in {
-  options.docker-containers = mkOption {
-    default = {};
-    type = with types; attrsOf (types.submodule containerModule);
-    description = "Definition of docker containers";
-  };
-
-  config.system.build.toplevel-docker = lib.mapAttrs toContainer cfg;
-}
diff --git a/nixos/modules/service-managers/trivial.nix b/nixos/modules/service-managers/trivial.nix
deleted file mode 100644
index 77e615d1e2e2..000000000000
--- a/nixos/modules/service-managers/trivial.nix
+++ /dev/null
@@ -1,35 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
-  cfg = config.trivial-services;
-
-  serviceModule.options = {
-    script = mkOption {
-      type = types.lines;
-      description = "Shell commands executed as the service's main process.";
-    };
-
-    environment = mkOption {
-      default = {};
-      type = types.attrs; # FIXME
-      example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; };
-      description = "Environment variables passed to the service's processes.";
-    };
-  };
-
-  launcher = name: value: pkgs.writeScript name ''
-    #!${pkgs.stdenv.shell} -eu
-
-    ${pkgs.writeScript "${name}-entry" value.script}
-  '';
-in {
-  options.trivial-services = mkOption {
-    default = {};
-    type = with types; attrsOf (types.submodule serviceModule);
-    description = "Definition of trivial services";
-  };
-
-  config.system.build.toplevel-trivial = lib.mapAttrs launcher cfg;
-}
diff --git a/nixos/modules/services/continuous-integration/jenkins/default.nix b/nixos/modules/services/continuous-integration/jenkins/default.nix
index c14aa4167231..0dd59e4fb444 100644
--- a/nixos/modules/services/continuous-integration/jenkins/default.nix
+++ b/nixos/modules/services/continuous-integration/jenkins/default.nix
@@ -78,6 +78,13 @@ in {
         '';
       };
 
+      package = mkOption {
+        default = pkgs.jenkins;
+        defaultText = "pkgs.jenkins";
+        type = types.package;
+        description = "Jenkins package to use.";
+      };
+
       packages = mkOption {
         default = [ pkgs.stdenv pkgs.git pkgs.jdk config.programs.ssh.package pkgs.nix ];
         defaultText = "[ pkgs.stdenv pkgs.git pkgs.jdk config.programs.ssh.package pkgs.nix ]";
@@ -194,7 +201,7 @@ in {
         '';
 
       script = ''
-        ${pkgs.jdk}/bin/java ${concatStringsSep " " cfg.extraJavaOptions} -jar ${pkgs.jenkins}/webapps/jenkins.war --httpListenAddress=${cfg.listenAddress} \
+        ${pkgs.jdk}/bin/java ${concatStringsSep " " cfg.extraJavaOptions} -jar ${cfg.package}/webapps/jenkins.war --httpListenAddress=${cfg.listenAddress} \
                                                   --httpPort=${toString cfg.port} \
                                                   --prefix=${cfg.prefix} \
                                                   ${concatStringsSep " " cfg.extraOptions}
diff --git a/nixos/modules/services/misc/gitea.nix b/nixos/modules/services/misc/gitea.nix
new file mode 100644
index 000000000000..f0b44b7bedeb
--- /dev/null
+++ b/nixos/modules/services/misc/gitea.nix
@@ -0,0 +1,270 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.gitea;
+  configFile = pkgs.writeText "app.ini" ''
+    APP_NAME = ${cfg.appName}
+    RUN_USER = ${cfg.user}
+    RUN_MODE = prod
+
+    [database]
+    DB_TYPE = ${cfg.database.type}
+    HOST = ${cfg.database.host}:${toString cfg.database.port}
+    NAME = ${cfg.database.name}
+    USER = ${cfg.database.user}
+    PASSWD = #dbpass#
+    PATH = ${cfg.database.path}
+
+    [repository]
+    ROOT = ${cfg.repositoryRoot}
+
+    [server]
+    DOMAIN = ${cfg.domain}
+    HTTP_ADDR = ${cfg.httpAddress}
+    HTTP_PORT = ${toString cfg.httpPort}
+    ROOT_URL = ${cfg.rootUrl}
+    STATIC_ROOT_PATH = ${cfg.staticRootPath}
+
+    [session]
+    COOKIE_NAME = session
+    COOKIE_SECURE = ${boolToString cfg.cookieSecure}
+
+    [security]
+    SECRET_KEY = #secretkey#
+    INSTALL_LOCK = true
+
+    ${cfg.extraConfig}
+  '';
+in
+
+{
+  options = {
+    services.gitea = {
+      enable = mkOption {
+        default = false;
+        type = types.bool;
+        description = "Enable Gitea Service.";
+      };
+
+      useWizard = mkOption {
+        default = false;
+        type = types.bool;
+        description = "Do not generate a configuration and use gitea' installation wizard instead. The first registered user will be administrator.";
+      };
+
+      stateDir = mkOption {
+        default = "/var/lib/gitea";
+        type = types.str;
+        description = "gitea data directory.";
+      };
+
+      user = mkOption {
+        type = types.str;
+        default = "gitea";
+        description = "User account under which gitea runs.";
+      };
+
+      database = {
+        type = mkOption {
+          type = types.enum [ "sqlite3" "mysql" "postgres" ];
+          example = "mysql";
+          default = "sqlite3";
+          description = "Database engine to use.";
+        };
+
+        host = mkOption {
+          type = types.str;
+          default = "127.0.0.1";
+          description = "Database host address.";
+        };
+
+        port = mkOption {
+          type = types.int;
+          default = 3306;
+          description = "Database host port.";
+        };
+
+        name = mkOption {
+          type = types.str;
+          default = "gitea";
+          description = "Database name.";
+        };
+
+        user = mkOption {
+          type = types.str;
+          default = "gitea";
+          description = "Database user.";
+        };
+
+        password = mkOption {
+          type = types.str;
+          default = "";
+          description = ''
+            The password corresponding to <option>database.user</option>.
+            Warning: this is stored in cleartext in the Nix store!
+            Use <option>database.passwordFile</option> instead.
+          '';
+        };
+
+        passwordFile = mkOption {
+          type = types.nullOr types.path;
+          default = null;
+          example = "/run/keys/gitea-dbpassword";
+          description = ''
+            A file containing the password corresponding to
+            <option>database.user</option>.
+          '';
+        };
+
+        path = mkOption {
+          type = types.str;
+          default = "${cfg.stateDir}/data/gitea.db";
+          description = "Path to the sqlite3 database file.";
+        };
+      };
+
+      appName = mkOption {
+        type = types.str;
+        default = "gitea: Gitea Service";
+        description = "Application name.";
+      };
+
+      repositoryRoot = mkOption {
+        type = types.str;
+        default = "${cfg.stateDir}/repositories";
+        description = "Path to the git repositories.";
+      };
+
+      domain = mkOption {
+        type = types.str;
+        default = "localhost";
+        description = "Domain name of your server.";
+      };
+
+      rootUrl = mkOption {
+        type = types.str;
+        default = "http://localhost:3000/";
+        description = "Full public URL of gitea server.";
+      };
+
+      httpAddress = mkOption {
+        type = types.str;
+        default = "0.0.0.0";
+        description = "HTTP listen address.";
+      };
+
+      httpPort = mkOption {
+        type = types.int;
+        default = 3000;
+        description = "HTTP listen port.";
+      };
+
+      cookieSecure = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Marks session cookies as "secure" as a hint for browsers to only send
+          them via HTTPS. This option is recommend, if gitea is being served over HTTPS.
+        '';
+      };
+
+      staticRootPath = mkOption {
+        type = types.str;
+        default = "${pkgs.gitea.data}";
+        example = "/var/lib/gitea/data";
+        description = "Upper level of template and static files path.";
+      };
+
+      extraConfig = mkOption {
+        type = types.str;
+        default = "";
+        description = "Configuration lines appended to the generated gitea configuration file.";
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+
+    systemd.services.gitea = {
+      description = "gitea";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      path = [ pkgs.gitea.bin ];
+
+      preStart = let
+        runConfig = "${cfg.stateDir}/custom/conf/app.ini";
+        secretKey = "${cfg.stateDir}/custom/conf/secret_key";
+      in ''
+        mkdir -p ${cfg.stateDir}
+
+        # copy custom configuration and generate a random secret key if needed
+        ${optionalString (cfg.useWizard == false) ''
+          mkdir -p ${cfg.stateDir}/custom/conf
+          cp -f ${configFile} ${runConfig}
+
+          if [ ! -e ${secretKey} ]; then
+              head -c 16 /dev/urandom | base64 > ${secretKey}
+          fi
+
+          KEY=$(head -n1 ${secretKey})
+          DBPASS=$(head -n1 ${cfg.database.passwordFile})
+          sed -e "s,#secretkey#,$KEY,g" \
+              -e "s,#dbpass#,$DBPASS,g" \
+              -i ${runConfig}
+          chmod 640 ${runConfig} ${secretKey}
+        ''}
+
+        mkdir -p ${cfg.repositoryRoot}
+        # update all hooks' binary paths
+        HOOKS=$(find ${cfg.repositoryRoot} -mindepth 4 -maxdepth 4 -type f -wholename "*git/hooks/*")
+        if [ "$HOOKS" ]
+        then
+          sed -ri 's,/nix/store/[a-z0-9.-]+/bin/gitea,${pkgs.gitea.bin}/bin/gitea,g' $HOOKS
+          sed -ri 's,/nix/store/[a-z0-9.-]+/bin/env,${pkgs.coreutils}/bin/env,g' $HOOKS
+          sed -ri 's,/nix/store/[a-z0-9.-]+/bin/bash,${pkgs.bash}/bin/bash,g' $HOOKS
+          sed -ri 's,/nix/store/[a-z0-9.-]+/bin/perl,${pkgs.perl}/bin/perl,g' $HOOKS
+        fi
+        if [ ! -d ${cfg.stateDir}/conf/locale ]
+        then
+          mkdir -p ${cfg.stateDir}/conf
+          cp -r ${pkgs.gitea.out}/locale ${cfg.stateDir}/conf/locale
+        fi
+      '';
+
+      serviceConfig = {
+        Type = "simple";
+        User = cfg.user;
+        WorkingDirectory = cfg.stateDir;
+        ExecStart = "${pkgs.gitea.bin}/bin/gitea web";
+        Restart = "always";
+      };
+
+      environment = {
+        USER = cfg.user;
+        HOME = cfg.stateDir;
+        GITEA_WORK_DIR = cfg.stateDir;
+      };
+    };
+
+    users = mkIf (cfg.user == "gitea") {
+      extraUsers.gitea = {
+        description = "Gitea Service";
+        home = cfg.stateDir;
+        createHome = true;
+      };
+    };
+
+    warnings = optional (cfg.database.password != "")
+      ''config.services.gitea.database.password will be stored as plaintext
+        in the Nix store. Use database.passwordFile instead.'';
+
+    # Create database passwordFile default when password is configured.
+    services.gitea.database.passwordFile =
+      (mkDefault (toString (pkgs.writeTextFile {
+        name = "gitea-database-password";
+        text = cfg.database.password;
+      })));
+  };
+}
diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix
index 0fa9e417785f..14c184c3d685 100644
--- a/nixos/modules/services/misc/gitlab.nix
+++ b/nixos/modules/services/misc/gitlab.nix
@@ -581,6 +581,7 @@ in {
         mkdir -p ${cfg.statePath}/{log,uploads}
         ln -sf ${cfg.statePath}/log /run/gitlab/log
         ln -sf ${cfg.statePath}/uploads /run/gitlab/uploads
+        ln -sf ${cfg.statePath}/tmp /run/gitlab/tmp
         chown -R ${cfg.user}:${cfg.group} /run/gitlab
 
         # Prepare home directory
@@ -639,10 +640,10 @@ in {
         chmod -R ug+rwX,o-rwx ${cfg.statePath}/repositories
         chmod -R ug-s ${cfg.statePath}/repositories
         find ${cfg.statePath}/repositories -type d -print0 | xargs -0 chmod g+s
-        chmod 700 ${cfg.statePath}/uploads
+        chmod 770 ${cfg.statePath}/uploads
         chown -R git ${cfg.statePath}/uploads
         find ${cfg.statePath}/uploads -type f -exec chmod 0644 {} \;
-        find ${cfg.statePath}/uploads -type d -not -path ${cfg.statePath}/uploads -exec chmod 0700 {} \;
+        find ${cfg.statePath}/uploads -type d -not -path ${cfg.statePath}/uploads -exec chmod 0770 {} \;
       '';
 
       serviceConfig = {
diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix
index efa3b5b6bd76..beca820d2d60 100644
--- a/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixos/modules/services/misc/nix-daemon.nix
@@ -189,6 +189,7 @@ in
               sshKey = "/root/.ssh/id_buildfarm";
               system = "x86_64-linux";
               maxJobs = 2;
+              speedFactor = 2;
               supportedFeatures = [ "kvm" ];
               mandatoryFeatures = [ "perf" ];
             }
diff --git a/nixos/modules/services/misc/plex.nix b/nixos/modules/services/misc/plex.nix
index e37b486375bd..46221ace3084 100644
--- a/nixos/modules/services/misc/plex.nix
+++ b/nixos/modules/services/misc/plex.nix
@@ -137,7 +137,7 @@ in
         User = cfg.user;
         Group = cfg.group;
         PermissionsStartOnly = "true";
-        ExecStart = "/bin/sh -c ${cfg.package}/usr/lib/plexmediaserver/Plex\\ Media\\ Server";
+        ExecStart = "\"${cfg.package}/usr/lib/plexmediaserver/Plex Media Server\"";
         KillSignal = "SIGQUIT";
         Restart = "on-failure";
       };
diff --git a/nixos/modules/services/misc/pykms.nix b/nixos/modules/services/misc/pykms.nix
new file mode 100644
index 000000000000..897e856e2a2d
--- /dev/null
+++ b/nixos/modules/services/misc/pykms.nix
@@ -0,0 +1,90 @@
+{ config, lib, pkgs, ... }:
+
+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 {
+
+  options = {
+    services.pykms = rec {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Whether to enable the PyKMS service.";
+      };
+
+      listenAddress = mkOption {
+        type = types.str;
+        default = "0.0.0.0";
+        description = "The IP address on which to listen.";
+      };
+
+      port = mkOption {
+        type = types.int;
+        default = 1688;
+        description = "The port on which to listen.";
+      };
+
+      verbose = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Show verbose output.";
+      };
+
+      openFirewallPort = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Whether the listening port should be opened automatically.";
+      };
+    };
+  };
+
+  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 = {
+      extraUsers.pykms = {
+        name = "pykms";
+        group = "pykms";
+        home  = home;
+        createHome = true;
+        uid = config.ids.uids.pykms;
+        description = "PyKMS daemon user";
+      };
+
+      extraGroups.pykms = {
+        gid = config.ids.gids.pykms;
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/misc/tzupdate.nix b/nixos/modules/services/misc/tzupdate.nix
new file mode 100644
index 000000000000..570982ced29a
--- /dev/null
+++ b/nixos/modules/services/misc/tzupdate.nix
@@ -0,0 +1,45 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.tzupdate;
+in {
+  options.services.tzupdate = {
+    enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Enable the tzupdate timezone updating service. This provides
+        a one-shot service which can be activated with systemctl to 
+        update the timezone.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    # We need to have imperative time zone management for this to work.
+    # This will give users an error if they have set an explicit time
+    # zone, which is better than silently overriding it.
+    time.timeZone = null; 
+
+    # We provide a one-shot service which can be manually run. We could
+    # provide a service that runs on startup, but it's tricky to get
+    # a service to run after you have *internet* access.
+    systemd.services.tzupdate = {
+      description = "tzupdate timezone update service";
+      wants = [ "network-online.target" ];
+      after = [ "network-online.target" ];
+
+      serviceConfig = {
+        Type = "oneshot";
+        # We could link directly into pkgs.tzdata, but at least timedatectl seems
+        # to expect the symlink to point directly to a file in etc.
+        # Setting the "debian timezone file" to point at /dev/null stops it doing anything.
+        ExecStart = "${pkgs.tzupdate}/bin/tzupdate -z /etc/zoneinfo -d /dev/null";
+      };
+    };
+  };
+
+  meta.maintainers = [ maintainers.michaelpj ];
+}
diff --git a/nixos/modules/services/monitoring/graphite.nix b/nixos/modules/services/monitoring/graphite.nix
index 332a04634d06..01b4aca91731 100644
--- a/nixos/modules/services/monitoring/graphite.nix
+++ b/nixos/modules/services/monitoring/graphite.nix
@@ -7,6 +7,19 @@ let
   writeTextOrNull = f: t: mapNullable (pkgs.writeTextDir f) t;
 
   dataDir = cfg.dataDir;
+  staticDir = cfg.dataDir + "/static";
+
+  graphiteLocalSettingsDir = pkgs.runCommand "graphite_local_settings"
+    {inherit graphiteLocalSettings;} ''
+    mkdir -p $out
+    ln -s $graphiteLocalSettings $out/graphite_local_settings.py
+  '';
+
+  graphiteLocalSettings = pkgs.writeText "graphite_local_settings.py" (
+    "STATIC_ROOT = '${staticDir}'\n" +
+    optionalString (! isNull config.time.timeZone) "TIME_ZONE = '${config.time.timeZone}'\n"
+    + cfg.web.extraConfig
+  );
 
   graphiteApiConfig = pkgs.writeText "graphite-api.yaml" ''
     time_zone: ${config.time.timeZone}
@@ -94,6 +107,15 @@ in {
         default = 8080;
         type = types.int;
       };
+
+      extraConfig = mkOption {
+        type = types.str;
+        default = "";
+        description = ''
+          Graphite webapp settings. See:
+          <link xlink:href="http://graphite.readthedocs.io/en/latest/config-local-settings.html"/>
+        '';
+      };
     };
 
     api = {
@@ -460,9 +482,13 @@ in {
                 ];
               };
               penvPack = "${penv}/${pkgs.python.sitePackages}";
-              # opt/graphite/webapp contains graphite/settings.py
-              # explicitly adding pycairo in path because it cannot be imported via buildEnv
-            in "${penvPack}/opt/graphite/webapp:${penvPack}:${pkgs.pythonPackages.pycairo}/${pkgs.python.sitePackages}";
+            in concatStringsSep ":" [
+                 "${graphiteLocalSettingsDir}"
+                 "${penvPack}/opt/graphite/webapp"
+                 "${penvPack}"
+                 # explicitly adding pycairo in path because it cannot be imported via buildEnv
+                 "${pkgs.pythonPackages.pycairo}/${pkgs.python.sitePackages}"
+               ];
           DJANGO_SETTINGS_MODULE = "graphite.settings";
           GRAPHITE_CONF_DIR = configDir;
           GRAPHITE_STORAGE_DIR = dataDir;
@@ -470,9 +496,9 @@ in {
         };
         serviceConfig = {
           ExecStart = ''
-            ${pkgs.python27Packages.waitress}/bin/waitress-serve \
-            --host=${cfg.web.listenAddress} --port=${toString cfg.web.port} \
-            --call django.core.handlers.wsgi:WSGIHandler'';
+            ${pkgs.python27Packages.waitress-django}/bin/waitress-serve-django \
+              --host=${cfg.web.listenAddress} --port=${toString cfg.web.port}
+          '';
           User = "graphite";
           Group = "graphite";
           PermissionsStartOnly = true;
@@ -482,16 +508,20 @@ in {
             mkdir -p ${dataDir}/{whisper/,log/webapp/}
             chmod 0700 ${dataDir}/{whisper/,log/webapp/}
 
-            # populate database
-            ${pkgs.python27Packages.graphite_web}/bin/manage-graphite.py syncdb --noinput
+            ${pkgs.pythonPackages.django_1_8}/bin/django-admin.py migrate --noinput
 
-            # create index
-            ${pkgs.python27Packages.graphite_web}/bin/build-index.sh
-
-            chown -R graphite:graphite ${cfg.dataDir}
+            chown -R graphite:graphite ${dataDir}
 
             touch ${dataDir}/db-created
           fi
+
+          # Only collect static files when graphite_web changes.
+          if ! [ "${dataDir}/current_graphite_web" -ef "${pkgs.python27Packages.graphite_web}" ]; then
+            mkdir -p ${staticDir}
+            ${pkgs.pythonPackages.django_1_8}/bin/django-admin.py collectstatic  --noinput --clear
+            chown -R graphite:graphite ${staticDir}
+            ln -sfT "${pkgs.python27Packages.graphite_web}" "${dataDir}/current_graphite_web"
+          fi
         '';
       };
 
diff --git a/nixos/modules/services/monitoring/prometheus/minio-exporter.nix b/nixos/modules/services/monitoring/prometheus/minio-exporter.nix
new file mode 100644
index 000000000000..4314671523cf
--- /dev/null
+++ b/nixos/modules/services/monitoring/prometheus/minio-exporter.nix
@@ -0,0 +1,117 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.services.prometheus.minioExporter;
+in {
+  options = {
+    services.prometheus.minioExporter = {
+      enable = mkEnableOption "prometheus minio exporter";
+
+      port = mkOption {
+        type = types.int;
+        default = 9290;
+        description = ''
+          Port to listen on.
+        '';
+      };
+
+      listenAddress = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        example = "0.0.0.0";
+        description = ''
+          Address to listen on for web interface and telemetry.
+        '';
+      };
+
+      minioAddress = mkOption {
+        type = types.str;
+        example = "https://10.0.0.1:9000";
+        default = if config.services.minio.enable then "http://localhost:9000" else null;
+        description = ''
+          The URL of the minio server.
+          Use HTTPS if Minio accepts secure connections only.
+          By default this connects to the local minio server if enabled.
+        '';
+      };
+
+      minioAccessKey = mkOption ({
+        type = types.str;
+        example = "BKIKJAA5BMMU2RHO6IBB";
+        description = ''
+          The value of the Minio access key.
+          It is required in order to connect to the server.
+          By default this uses the one from the local minio server if enabled
+          and <literal>config.services.minio.accessKey</literal>.
+        '';
+      } // optionalAttrs (config.services.minio.enable && config.services.minio.accessKey != "") {
+        default = config.services.minio.accessKey;
+      });
+
+      minioAccessSecret = mkOption ({
+        type = types.str;
+        description = ''
+          The calue of the Minio access secret.
+          It is required in order to connect to the server.
+          By default this uses the one from the local minio server if enabled
+          and <literal>config.services.minio.secretKey</literal>.
+        '';
+      } // optionalAttrs (config.services.minio.enable && config.services.minio.secretKey != "") {
+        default = config.services.minio.secretKey;
+      });
+
+      minioBucketStats = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Collect statistics about the buckets and files in buckets.
+          It requires more computation, use it carefully in case of large buckets..
+        '';
+      };
+
+      extraFlags = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        description = ''
+          Extra commandline options when launching the minio exporter.
+        '';
+      };
+
+      openFirewall = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Open port in firewall for incoming connections.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
+
+    systemd.services.prometheus-minio-exporter = {
+      description = "Prometheus exporter for Minio server metrics";
+      unitConfig.Documentation = "https://github.com/joe-pll/minio-exporter";
+      wantedBy = [ "multi-user.target" ];
+      after = optional config.services.minio.enable "minio.service";
+      serviceConfig = {
+        DynamicUser = true;
+        Restart = "always";
+        PrivateTmp = true;
+        WorkingDirectory = /tmp;
+        ExecStart = ''
+          ${pkgs.prometheus-minio-exporter}/bin/minio-exporter \
+            -web.listen-address ${optionalString (cfg.listenAddress != null) cfg.listenAddress}:${toString cfg.port} \
+            -minio.server ${cfg.minioAddress} \
+            -minio.access-key ${cfg.minioAccessKey} \
+            -minio.access-secret ${cfg.minioAccessSecret} \
+            ${optionalString cfg.minioBucketStats "-minio.bucket-stats"} \
+            ${concatStringsSep " \\\n  " cfg.extraFlags}
+        '';
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/network-filesystems/kbfs.nix b/nixos/modules/services/network-filesystems/kbfs.nix
index cf1d7617cca6..7b2eea3b5850 100644
--- a/nixos/modules/services/network-filesystems/kbfs.nix
+++ b/nixos/modules/services/network-filesystems/kbfs.nix
@@ -55,8 +55,11 @@ in {
         Restart = "on-failure";
         PrivateTmp = true;
       };
+      wantedBy = [ "default.target" ];
     };
 
     services.keybase.enable = true;
+
+    environment.systemPackages = [ pkgs.kbfs ];
   };
 }
diff --git a/nixos/modules/services/network-filesystems/openafs-client/default.nix b/nixos/modules/services/network-filesystems/openafs-client/default.nix
index 94f93162cfee..0946e379e796 100644
--- a/nixos/modules/services/network-filesystems/openafs-client/default.nix
+++ b/nixos/modules/services/network-filesystems/openafs-client/default.nix
@@ -93,7 +93,6 @@ in
       preStop = ''
         ${pkgs.utillinux}/bin/umount /afs
         ${openafsPkgs}/sbin/afsd -shutdown
-        ${pkgs.kmod}/sbin/rmmod libafs
       '';
     };
   };
diff --git a/nixos/modules/services/networking/connman.nix b/nixos/modules/services/networking/connman.nix
index d0683b877801..546d27069232 100644
--- a/nixos/modules/services/networking/connman.nix
+++ b/nixos/modules/services/networking/connman.nix
@@ -115,10 +115,5 @@ in {
       wireless.enable = true;
       networkmanager.enable = false;
     };
-
-    powerManagement.resumeCommands = ''
-      systemctl restart connman
-    '';
-
   };
 }
diff --git a/nixos/modules/services/networking/dnscache.nix b/nixos/modules/services/networking/dnscache.nix
index f782be97f6fa..379203cd1ab6 100644
--- a/nixos/modules/services/networking/dnscache.nix
+++ b/nixos/modules/services/networking/dnscache.nix
@@ -18,10 +18,13 @@ let
       '') ips}
     '') cfg.domainServers)}
 
-    # djbdns contains an outdated list of root servers;
-    # if one was not provided in config, provide a current list
-    if [ ! -e servers/@ ]; then
-      awk '/^.?.ROOT-SERVERS.NET/ { print $4 }' ${pkgs.dns-root-data}/root.hints > $out/servers/@
+    # if a list of root servers was not provided in config, copy it
+    # over. (this is also done by dnscache-conf, but we 'rm -rf
+    # /var/lib/dnscache/root' below & replace it wholesale with this,
+    # so we have to ensure servers/@ exists ourselves.)
+    if [ ! -e $out/servers/@ ]; then
+      # symlink does not work here, due chroot
+      cp ${pkgs.djbdns}/etc/dnsroots.global $out/servers/@;
     fi
   '';
 
diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix
index 68a814b23053..9bd88ca1707b 100644
--- a/nixos/modules/services/networking/firewall.nix
+++ b/nixos/modules/services/networking/firewall.nix
@@ -95,18 +95,18 @@ let
     ip46tables -N nixos-fw-log-refuse
 
     ${optionalString cfg.logRefusedConnections ''
-      ip46tables -A nixos-fw-log-refuse -p tcp --syn -j LOG --log-level info --log-prefix "rejected connection: "
+      ip46tables -A nixos-fw-log-refuse -p tcp --syn -j LOG --log-level info --log-prefix "refused connection: "
     ''}
     ${optionalString (cfg.logRefusedPackets && !cfg.logRefusedUnicastsOnly) ''
       ip46tables -A nixos-fw-log-refuse -m pkttype --pkt-type broadcast \
-        -j LOG --log-level info --log-prefix "rejected broadcast: "
+        -j LOG --log-level info --log-prefix "refused broadcast: "
       ip46tables -A nixos-fw-log-refuse -m pkttype --pkt-type multicast \
-        -j LOG --log-level info --log-prefix "rejected multicast: "
+        -j LOG --log-level info --log-prefix "refused multicast: "
     ''}
     ip46tables -A nixos-fw-log-refuse -m pkttype ! --pkt-type unicast -j nixos-fw-refuse
     ${optionalString cfg.logRefusedPackets ''
       ip46tables -A nixos-fw-log-refuse \
-        -j LOG --log-level info --log-prefix "rejected packet: "
+        -j LOG --log-level info --log-prefix "refused packet: "
     ''}
     ip46tables -A nixos-fw-log-refuse -j nixos-fw-refuse
 
diff --git a/nixos/modules/services/networking/keybase.nix b/nixos/modules/services/networking/keybase.nix
index ca5c279ac6f0..7c7982ee8eac 100644
--- a/nixos/modules/services/networking/keybase.nix
+++ b/nixos/modules/services/networking/keybase.nix
@@ -28,11 +28,12 @@ in {
       description = "Keybase service";
       serviceConfig = {
         ExecStart = ''
-          ${pkgs.keybase}/bin/keybase service
+          ${pkgs.keybase}/bin/keybase -d service --auto-forked
         '';
         Restart = "on-failure";
         PrivateTmp = true;
       };
+      wantedBy = [ "default.target" ];
     };
 
     environment.systemPackages = [ pkgs.keybase ];
diff --git a/nixos/modules/services/networking/unbound.nix b/nixos/modules/services/networking/unbound.nix
index f3a04d97c98e..bcce4accdd6e 100644
--- a/nixos/modules/services/networking/unbound.nix
+++ b/nixos/modules/services/networking/unbound.nix
@@ -105,7 +105,7 @@ in
       description = "Unbound recursive Domain Name Server";
       after = [ "network.target" ];
       before = [ "nss-lookup.target" ];
-      wants = [" nss-lookup.target" ];
+      wants = [ "nss-lookup.target" ];
       wantedBy = [ "multi-user.target" ];
 
       preStart = ''
diff --git a/nixos/modules/services/networking/znc.nix b/nixos/modules/services/networking/znc.nix
index 3d9cec46a582..72313ab2ee14 100644
--- a/nixos/modules/services/networking/znc.nix
+++ b/nixos/modules/services/networking/znc.nix
@@ -329,7 +329,7 @@ in
       };
 
       mutable = mkOption {
-        default = false;
+        default = true;
         type = types.bool;
         description = ''
           Indicates whether to allow the contents of the `dataDir` directory to be changed
diff --git a/nixos/modules/services/scheduling/atd.nix b/nixos/modules/services/scheduling/atd.nix
index 0216c9771c96..77a3f6b51e80 100644
--- a/nixos/modules/services/scheduling/atd.nix
+++ b/nixos/modules/services/scheduling/atd.nix
@@ -42,6 +42,8 @@ in
 
   config = mkIf cfg.enable {
 
+    # Not wrapping "batch" because it's a shell script (kernel drops perms
+    # anyway) and it's patched to invoke the "at" setuid wrapper.
     security.wrappers = builtins.listToAttrs (
       map (program: { name = "${program}"; value = {
       source = "${at}/bin/${program}";
@@ -49,7 +51,7 @@ in
       group = "atd";
       setuid = true;
       setgid = true;
-    };}) [ "at" "atq" "atrm" "batch" ]);
+    };}) [ "at" "atq" "atrm" ]);
 
     environment.systemPackages = [ at ];
 
diff --git a/nixos/modules/services/scheduling/fcron.nix b/nixos/modules/services/scheduling/fcron.nix
index af4f9f41fd04..ac589be57736 100644
--- a/nixos/modules/services/scheduling/fcron.nix
+++ b/nixos/modules/services/scheduling/fcron.nix
@@ -137,10 +137,7 @@ in
       after = [ "local-fs.target" ];
       wantedBy = [ "multi-user.target" ];
 
-      # FIXME use specific path
-      environment = {
-        PATH = "/run/current-system/sw/bin";
-      };
+      path = [ pkgs.fcron ];
 
       preStart = ''
         install \
@@ -149,7 +146,7 @@ in
           --group fcron \
           --directory /var/spool/fcron
         # load system crontab file
-        /run/wrappers/bin/fcrontab -u systab ${pkgs.writeText "systab" cfg.systab}
+        /run/wrappers/bin/fcrontab -u systab - < ${pkgs.writeText "systab" cfg.systab}
       '';
 
       serviceConfig = {
diff --git a/nixos/modules/services/security/hologram-server.nix b/nixos/modules/services/security/hologram-server.nix
index 8315c9ea5d61..e267fed27955 100644
--- a/nixos/modules/services/security/hologram-server.nix
+++ b/nixos/modules/services/security/hologram-server.nix
@@ -23,8 +23,6 @@ let
     stats  = cfg.statsAddress;
     listen = cfg.listenAddress;
   });
-
-  script = "${pkgs.hologram.bin}/bin/hologram-server --debug --conf ${cfgFile}";
 in {
   options = {
     services.hologram-server = {
@@ -96,15 +94,9 @@ in {
       after       = [ "network.target" ];
       wantedBy    = [ "multi-user.target" ];
 
-      inherit script;
-    };
-
-    docker-containers.hologram-server = {
-      inherit script;
-    };
-
-    trivial-services.hologram-server = {
-      inherit script;
+      serviceConfig = {
+        ExecStart = "${pkgs.hologram.bin}/bin/hologram-server --debug --conf ${cfgFile}";
+      };
     };
   };
 }
diff --git a/nixos/modules/services/security/sshguard.nix b/nixos/modules/services/security/sshguard.nix
index 5a183443f71d..7f09e8893c4d 100644
--- a/nixos/modules/services/security/sshguard.nix
+++ b/nixos/modules/services/security/sshguard.nix
@@ -89,7 +89,7 @@ in {
 
     environment.systemPackages = [ pkgs.sshguard pkgs.iptables pkgs.ipset ];
 
-    environment.etc."sshguard.conf".text = let 
+    environment.etc."sshguard.conf".text = let
         list_services = ( name:  "-t ${name} ");
       in ''
         BACKEND="${pkgs.sshguard}/libexec/sshg-fw-ipset"
diff --git a/nixos/modules/services/web-apps/mattermost.nix b/nixos/modules/services/web-apps/mattermost.nix
index bc88a808abc9..0b637e3991b4 100644
--- a/nixos/modules/services/web-apps/mattermost.nix
+++ b/nixos/modules/services/web-apps/mattermost.nix
@@ -184,10 +184,12 @@ in
           fi
         '' + lib.optionalString cfg.localDatabaseCreate ''
           if ! test -e "${cfg.statePath}/.db-created"; then
-            ${config.services.postgresql.package}/bin/psql postgres -c \
-              "CREATE ROLE ${cfg.localDatabaseUser} WITH LOGIN NOCREATEDB NOCREATEROLE ENCRYPTED PASSWORD '${cfg.localDatabasePassword}'"
-            ${config.services.postgresql.package}/bin/createdb \
-              --owner ${cfg.localDatabaseUser} ${cfg.localDatabaseName}
+            ${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser} \
+              ${config.services.postgresql.package}/bin/psql postgres -c \
+                "CREATE ROLE ${cfg.localDatabaseUser} WITH LOGIN NOCREATEDB NOCREATEROLE ENCRYPTED PASSWORD '${cfg.localDatabasePassword}'"
+            ${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser} \
+              ${config.services.postgresql.package}/bin/createdb \
+                --owner ${cfg.localDatabaseUser} ${cfg.localDatabaseName}
             touch ${cfg.statePath}/.db-created
           fi
         '' + ''
diff --git a/nixos/modules/services/web-servers/lighttpd/default.nix b/nixos/modules/services/web-servers/lighttpd/default.nix
index 45a65965112a..700b4469c565 100644
--- a/nixos/modules/services/web-servers/lighttpd/default.nix
+++ b/nixos/modules/services/web-servers/lighttpd/default.nix
@@ -15,7 +15,8 @@ let
   # Some modules are always imported and should not appear in the config:
   # disallowedModules = [ "mod_indexfile" "mod_dirlisting" "mod_staticfile" ];
   #
-  # Get full module list: "ls -1 $lighttpd/lib/*.so"
+  # For full module list, see the output of running ./configure in the lighttpd
+  # source.
   allKnownModules = [
     "mod_rewrite"
     "mod_redirect"
@@ -38,12 +39,15 @@ let
     "mod_accesslog"
     # Remaining list of modules, order assumed to be unimportant.
     "mod_authn_file"
+    "mod_authn_gssapi"
+    "mod_authn_ldap"
     "mod_authn_mysql"
     "mod_cml"
     "mod_deflate"
     "mod_evasive"
     "mod_extforward"
     "mod_flv_streaming"
+    "mod_geoip"
     "mod_magnet"
     "mod_mysql_vhost"
     "mod_scgi"
diff --git a/nixos/modules/services/x11/compton.nix b/nixos/modules/services/x11/compton.nix
index 56bc66b71796..8701354b5285 100644
--- a/nixos/modules/services/x11/compton.nix
+++ b/nixos/modules/services/x11/compton.nix
@@ -7,6 +7,14 @@ let
 
   cfg = config.services.compton;
 
+  floatBetween = a: b: with lib; with types;
+    addCheck str (x: versionAtLeast x a && versionOlder x b);
+
+  pairOf = x: with types; addCheck (listOf x) (y: lib.length y == 2);
+
+  opacityRules = optionalString (length cfg.opacityRules != 0)
+    (concatMapStringsSep ",\n" (rule: ''"${rule}"'') cfg.opacityRules);
+
   configFile = pkgs.writeText "compton.conf"
     (optionalString cfg.fade ''
       # fading
@@ -30,7 +38,11 @@ let
       active-opacity   = ${cfg.activeOpacity};
       inactive-opacity = ${cfg.inactiveOpacity};
       menu-opacity     = ${cfg.menuOpacity};
-      
+
+      opacity-rule = [
+        ${opacityRules}
+      ];
+
       # other options
       backend = ${toJSON cfg.backend};
       vsync = ${toJSON cfg.vSync};
@@ -57,7 +69,7 @@ in {
     };
 
     fadeDelta = mkOption {
-      type = types.int;
+      type = types.addCheck types.int (x: x > 0);
       default = 10;
       example = 5;
       description = ''
@@ -66,11 +78,12 @@ in {
     };
 
     fadeSteps = mkOption {
-      type = types.listOf types.str;
+      type = pairOf (floatBetween "0.01" "1.01");
       default = [ "0.028" "0.03" ];
       example = [ "0.04" "0.04" ];
       description = ''
         Opacity change between fade steps (in and out).
+        (numbers in range 0.01 - 1.0)
       '';
     };
 
@@ -97,7 +110,7 @@ in {
     };
 
     shadowOffsets = mkOption {
-      type = types.listOf types.int;
+      type = pairOf types.int;
       default = [ (-15) (-15) ];
       example = [ (-10) (-15) ];
       description = ''
@@ -106,11 +119,11 @@ in {
     };
 
     shadowOpacity = mkOption {
-      type = types.str;
+      type = floatBetween "0.0" "1.01";
       default = "0.75";
       example = "0.8";
       description = ''
-        Window shadows opacity (number in range 0 - 1).
+        Window shadows opacity (number in range 0.0 - 1.0).
       '';
     };
 
@@ -129,52 +142,67 @@ in {
     };
 
     activeOpacity = mkOption {
-      type = types.str;
+      type = floatBetween "0.0" "1.01";
       default = "1.0";
       example = "0.8";
       description = ''
-        Opacity of active windows.
+        Opacity of active windows (number in range 0.0 - 1.0).
       '';
     };
 
     inactiveOpacity = mkOption {
-      type = types.str;
+      type = floatBetween "0.1" "1.01";
       default = "1.0";
       example = "0.8";
       description = ''
-        Opacity of inactive windows.
+        Opacity of inactive windows (number in range 0.1 - 1.0).
       '';
     };
 
     menuOpacity = mkOption {
-      type = types.str;
+      type = floatBetween "0.0" "1.01";
       default = "1.0";
       example = "0.8";
       description = ''
-        Opacity of dropdown and popup menu.
+        Opacity of dropdown and popup menu (number in range 0.0 - 1.0).
+      '';
+    };
+
+    opacityRules = mkOption {
+      type = types.listOf types.str;
+      default = [];
+      example = [
+        "95:class_g = 'URxvt' && !_NET_WM_STATE@:32a"
+        "0:_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'"
+      ];
+      description = ''
+        Rules that control the opacity of windows, in format PERCENT:PATTERN.
       '';
     };
 
     backend = mkOption {
-      type = types.str;
-      default = "glx";
+      type = types.enum [ "glx" "xrender" ];
+      default = "xrender";
       description = ''
         Backend to use: <literal>glx</literal> or <literal>xrender</literal>.
       '';
     };
 
     vSync = mkOption {
-     type = types.str;
-     default = "none";
-     example = "opengl-swc";
-     description = ''
-       Enable vertical synchronization using the specified method.
-       See <literal>compton(1)</literal> man page available methods.
-     '';
+      type = types.enum [
+        "none" "drm" "opengl"
+        "opengl-oml" "opengl-swc" "opengl-mswc"
+      ];
+      default = "none";
+      example = "opengl-swc";
+      description = ''
+        Enable vertical synchronization using the specified method.
+        See <literal>compton(1)</literal> man page an explanation.
+      '';
     };
 
     refreshRate = mkOption {
-      type = types.int;
+      type = types.addCheck types.int (x: x >= 0);
       default = 0;
       example = 60;
       description = ''
diff --git a/nixos/modules/services/x11/desktop-managers/mate.nix b/nixos/modules/services/x11/desktop-managers/mate.nix
index 7a95ac6549d8..ab8a0a48b483 100644
--- a/nixos/modules/services/x11/desktop-managers/mate.nix
+++ b/nixos/modules/services/x11/desktop-managers/mate.nix
@@ -72,6 +72,7 @@ in
     ];
 
     services.gnome3.gnome-keyring.enable = true;
+    services.upower.enable = config.powerManagement.enable;
 
     environment.pathsToLink = [ "/share" ];
   };
diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix
index f099117f4777..b9498b1627fb 100644
--- a/nixos/modules/services/x11/desktop-managers/plasma5.nix
+++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix
@@ -47,7 +47,7 @@ in
             ${getBin config.hardware.pulseaudio.package}/bin/pactl load-module module-device-manager "do_routing=1"
           ''}
 
-          exec "${plasma5.startkde}"
+          exec "${getBin plasma5.plasma-workspace}/bin/startkde"
         '';
       };
 
@@ -142,7 +142,8 @@ in
 
           kde-gtk-config breeze-gtk
 
-          phonon-backend-gstreamer
+          libsForQt56.phonon-backend-gstreamer
+          libsForQt5.phonon-backend-gstreamer
         ]
 
         ++ lib.optionals cfg.enableQt4Support [ breeze-qt4 pkgs.phonon-backend-gstreamer ]
diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix
index 58773685ec1f..3fa482fb6722 100644
--- a/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixos/modules/services/x11/display-managers/default.nix
@@ -92,9 +92,12 @@ let
         ${config.hardware.pulseaudio.package.out}/bin/pactl load-module module-x11-publish "display=$DISPLAY"
       ''}
 
-      # Tell systemd about our $DISPLAY. This is needed by the
-      # ssh-agent unit.
-      ${config.systemd.package}/bin/systemctl --user import-environment DISPLAY
+      # Tell systemd about our $DISPLAY and $XAUTHORITY.
+      # This is needed by the ssh-agent unit.
+      #
+      # Also tell systemd about the dbus session bus address.
+      # This is required by user units using the session bus.
+      ${config.systemd.package}/bin/systemctl --user import-environment DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS
 
       # Load X defaults.
       ${xorg.xrdb}/bin/xrdb -merge ${xresourcesXft}
diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix
index e6cc02e4d491..facaea131ae5 100644
--- a/nixos/modules/services/x11/display-managers/sddm.nix
+++ b/nixos/modules/services/x11/display-managers/sddm.nix
@@ -19,6 +19,17 @@ let
 
   Xsetup = pkgs.writeScript "Xsetup" ''
     #!/bin/sh
+
+    # Prior to Qt 5.9.2, there is a QML cache invalidation bug which sometimes
+    # strikes new Plasma 5 releases. If the QML cache is not invalidated, SDDM
+    # will segfault without explanation. We really tore our hair out for awhile
+    # before finding the bug:
+    # https://bugreports.qt.io/browse/QTBUG-62302
+    # We work around the problem by deleting the QML cache before startup. It
+    # will be regenerated, causing a small but perceptible delay when SDDM
+    # starts.
+    rm -fr /var/lib/sddm/.cache/sddm-greeter/qmlcache
+
     ${cfg.setupScript}
   '';
 
diff --git a/nixos/modules/services/x11/hardware/libinput.nix b/nixos/modules/services/x11/hardware/libinput.nix
index d75c785270b3..44555cb6e2a9 100644
--- a/nixos/modules/services/x11/hardware/libinput.nix
+++ b/nixos/modules/services/x11/hardware/libinput.nix
@@ -75,12 +75,13 @@ in {
         default = null;
         description =
           ''
-            Enables a click method. Permitted values are none, buttonareas, clickfinger.
+            Enables a click method. Permitted values are <literal>none</literal>,
+            <literal>buttonareas</literal>, <literal>clickfinger</literal>.
             Not all devices support all methods, if an option is unsupported,
-            the default click method for this device is used. 
+            the default click method for this device is used.
           '';
       };
-      
+
       leftHanded = mkOption {
         type = types.bool;
         default = false;
@@ -96,7 +97,7 @@ in {
             simultaneously produces a middle mouse button click.
           '';
       };
-      
+
       naturalScrolling = mkOption {
         type = types.bool;
         default = false;
@@ -120,7 +121,8 @@ in {
         example = "edge";
         description =
           ''
-            Specify the scrolling method.
+            Specify the scrolling method: <literal>twofinger</literal>, <literal>edge</literal>,
+            or <literal>none</literal>
           '';
       };
 
@@ -141,7 +143,8 @@ in {
         example = "disabled";
         description =
           ''
-            Sets the send events mode to disabled, enabled, or "disable when an external mouse is connected".
+            Sets the send events mode to <literal>disabled</literal>, <literal>enabled</literal>,
+            or <literal>disabled-on-external-mouse</literal>
           '';
       };
 
diff --git a/nixos/modules/services/x11/xautolock.nix b/nixos/modules/services/x11/xautolock.nix
index 60ce9e6ed5c0..28fc92024bcb 100644
--- a/nixos/modules/services/x11/xautolock.nix
+++ b/nixos/modules/services/x11/xautolock.nix
@@ -31,7 +31,17 @@ in
           type = types.string;
 
           description = ''
-            The script to use when locking the computer.
+            The script to use when automatically locking the computer.
+          '';
+        };
+
+        nowlocker = mkOption {
+          default = null;
+          example = "i3lock -i /path/to/img";
+          type = types.nullOr types.string;
+
+          description = ''
+            The script to use when manually locking the computer with <command>xautolock -locknow</command>.
           '';
         };
 
@@ -45,28 +55,82 @@ in
         };
 
         notifier = mkOption {
-          default = "notify-send 'Locking in 10 seconds'";
-          type = types.string;
+          default = null;
+          example = literalExample ''
+            "${pkgs.libnotify}/bin/notify-send \"Locking in 10 seconds\""
+          '';
+          type = types.nullOr types.string;
 
           description = ''
             Notification script to be used to warn about the pending autolock.
           '';
         };
+
+        killer = mkOption {
+          default = null; # default according to `man xautolock` is none
+          example = "systemctl suspend";
+          type = types.nullOr types.string;
+
+          description = ''
+            The script to use when nothing has happend for as long as <option>killtime</option>
+          '';
+        };
+
+        killtime = mkOption {
+          default = 20; # default according to `man xautolock`
+          type = types.int;
+
+          description = ''
+            Minutes xautolock waits until it executes the script specified in <option>killer</option>
+            (Has to be at least 10 minutes)
+          '';
+        };
+
+        extraOptions = mkOption {
+          type = types.listOf types.str;
+          default = [ ];
+          example = [ "-detectsleep" ];
+          description = ''
+            Additional command-line arguments to pass to
+            <command>xautolock</command>.
+          '';
+        };
       };
     };
 
     config = mkIf cfg.enable {
       environment.systemPackages = with pkgs; [ xautolock ];
-
-      services.xserver.displayManager.sessionCommands = with builtins; with pkgs; ''
-        ${xautolock}/bin/xautolock \
-          ${concatStringsSep " \\\n" ([
-            "-time ${toString(cfg.time)}"
-            "-locker ${cfg.locker}"
-          ] ++ optional cfg.enableNotifier (concatStringsSep " " [ 
-            "-notify ${toString(cfg.notify)}"
-            "-notifier \"${cfg.notifier}\""
-          ]))} &
-      '';
+      systemd.user.services.xautolock = {
+        description = "xautolock service";
+        wantedBy = [ "graphical-session.target" ];
+        partOf = [ "graphical-session.target" ];
+        serviceConfig = with lib; {
+          ExecStart = strings.concatStringsSep " " ([
+            "${pkgs.xautolock}/bin/xautolock"
+            "-noclose"
+            "-time ${toString cfg.time}"
+            "-locker '${cfg.locker}'"
+          ] ++ optionals cfg.enableNotifier [
+            "-notify ${toString cfg.notify}"
+            "-notifier '${cfg.notifier}'"
+          ] ++ optionals (cfg.nowlocker != null) [
+            "-nowlocker '${cfg.nowlocker}'"
+          ] ++ optionals (cfg.killer != null) [
+            "-killer '${cfg.killer}'"
+            "-killtime ${toString cfg.killtime}"
+          ] ++ cfg.extraOptions);
+          Restart = "always";
+        };
+      };
+      assertions = [
+        {
+          assertion = cfg.enableNotifier -> cfg.notifier != null;
+          message = "When enabling the notifier for xautolock, you also need to specify the notify script";
+        }
+        {
+          assertion = cfg.killer != null -> cfg.killtime >= 10;
+          message = "killtime has to be at least 10 minutes according to `man xautolock`";
+        }
+      ];
     };
   }
diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix
index cf70a891c0ca..4db9631743e3 100644
--- a/nixos/modules/system/boot/kernel.nix
+++ b/nixos/modules/system/boot/kernel.nix
@@ -193,11 +193,6 @@ in
         "sd_mod"
         "sr_mod"
 
-        # Standard IDE stuff.
-        "ide_cd"
-        "ide_disk"
-        "ide_generic"
-
         # SD cards and internal eMMC drives.
         "mmc_block"
 
@@ -211,21 +206,11 @@ in
         "xhci_hcd"
         "xhci_pci"
         "usbhid"
-        "hid_generic" "hid_lenovo"
-        "hid_apple" "hid_logitech_dj" "hid_lenovo_tpkbd" "hid_roccat"
+        "hid_generic" "hid_lenovo" "hid_apple" "hid_roccat"
 
         # Misc. keyboard stuff.
         "pcips2" "atkbd" "i8042"
 
-        # Temporary fix for https://github.com/NixOS/nixpkgs/issues/18451
-        # Remove as soon as upstream gets fixed - marking it:
-        # TODO
-        # FIXME
-        "i8042"
-
-        # To wait for SCSI devices to appear.
-        "scsi_wait_scan"
-
         # Needed by the stage 2 init script.
         "rtc_cmos"
       ];
diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl
index 82b5bcda9217..cc03e54ead63 100644
--- a/nixos/modules/system/boot/loader/grub/install-grub.pl
+++ b/nixos/modules/system/boot/loader/grub/install-grub.pl
@@ -197,7 +197,7 @@ sub GrubFs {
                 if ($status != 0) {
                     die "Failed to retrieve subvolume info for @{[$fs->mount]}\n";
                 }
-                my @ids = join("", @id_info) =~ m/Subvolume ID:[ \t\n]*([^ \t\n]*)/;
+                my @ids = join("\n", @id_info) =~ m/^(?!\/\n).*Subvolume ID:[ \t\n]*([0-9]+)/s;
                 if ($#ids > 0) {
                     die "Btrfs subvol name for @{[$fs->device]} listed multiple times in mount\n"
                 } elsif ($#ids == 0) {
diff --git a/nixos/modules/system/boot/resolved.nix b/nixos/modules/system/boot/resolved.nix
index a3fb733c289d..2147d43c4f19 100644
--- a/nixos/modules/system/boot/resolved.nix
+++ b/nixos/modules/system/boot/resolved.nix
@@ -31,8 +31,15 @@ in
       example = [ "example.com" ];
       type = types.listOf types.str;
       description = ''
-        A list of domains. These domains are used as search suffixes when resolving single-label host names (domain names which contain no dot), in order to qualify them into fully-qualified domain names (FQDNs).
-        For compatibility reasons, if this setting is not specified, the search domains listed in /etc/resolv.conf are used instead, if that file exists and any domains are configured in it.
+        A list of domains. These domains are used as search suffixes
+        when resolving single-label host names (domain names which
+        contain no dot), in order to qualify them into fully-qualified
+        domain names (FQDNs).
+        </para><para>
+        For compatibility reasons, if this setting is not specified,
+        the search domains listed in
+        <filename>/etc/resolv.conf</filename> are used instead, if
+        that file exists and any domains are configured in it.
       '';
     };
 
@@ -41,10 +48,30 @@ in
       example = "false";
       type = types.enum [ "true" "resolve" "false" ];
       description = ''
-        Controls Link-Local Multicast Name Resolution support (RFC 4794) on the local host.
-        If true, enables full LLMNR responder and resolver support.
-        If false, disables both.
-        If set to "resolve", only resolution support is enabled, but responding is disabled.
+        Controls Link-Local Multicast Name Resolution support
+        (RFC 4795) on the local host.
+        </para><para>
+        If set to
+        <variablelist>
+        <varlistentry>
+          <term><literal>"true"</literal></term>
+          <listitem><para>
+            Enables full LLMNR responder and resolver support.
+          </para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><literal>"false"</literal></term>
+          <listitem><para>
+            Disables both.
+          </para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><literal>"resolve"</literal></term>
+          <listitem><para>
+            Only resolution support is enabled, but responding is disabled.
+          </para></listitem>
+        </varlistentry>
+        </variablelist>
       '';
     };
 
@@ -53,9 +80,36 @@ in
       example = "true";
       type = types.enum [ "true" "allow-downgrade" "false" ];
       description = ''
-        If true all DNS lookups are DNSSEC-validated locally (excluding LLMNR and Multicast DNS). Note that this mode requires a DNS server that supports DNSSEC. If the DNS server does not properly support DNSSEC all validations will fail.
-        If set to "allow-downgrade" DNSSEC validation is attempted, but if the server does not support DNSSEC properly, DNSSEC mode is automatically disabled. Note that this mode makes DNSSEC validation vulnerable to "downgrade" attacks, where an attacker might be able to trigger a downgrade to non-DNSSEC mode by synthesizing a DNS response that suggests DNSSEC was not supported.
-        If set to false, DNS lookups are not DNSSEC validated.
+        If set to
+        <variablelist>
+        <varlistentry>
+          <term><literal>"true"</literal></term>
+          <listitem><para>
+            all DNS lookups are DNSSEC-validated locally (excluding
+            LLMNR and Multicast DNS). Note that this mode requires a
+            DNS server that supports DNSSEC. If the DNS server does
+            not properly support DNSSEC all validations will fail.
+          </para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><literal>"allow-downgrade"</literal></term>
+          <listitem><para>
+            DNSSEC validation is attempted, but if the server does not
+            support DNSSEC properly, DNSSEC mode is automatically
+            disabled. Note that this mode makes DNSSEC validation
+            vulnerable to "downgrade" attacks, where an attacker might
+            be able to trigger a downgrade to non-DNSSEC mode by
+            synthesizing a DNS response that suggests DNSSEC was not
+            supported.
+          </para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><literal>"false"</literal></term>
+          <listitem><para>
+            DNS lookups are not DNSSEC validated.
+          </para></listitem>
+        </varlistentry>
+        </variablelist>
       '';
     };
 
diff --git a/nixos/modules/tasks/encrypted-devices.nix b/nixos/modules/tasks/encrypted-devices.nix
index 6bbf335e7db7..da0c9408d891 100644
--- a/nixos/modules/tasks/encrypted-devices.nix
+++ b/nixos/modules/tasks/encrypted-devices.nix
@@ -36,7 +36,7 @@ let
 
       keyFile = mkOption {
         default = null;
-        example = "/root/.swapkey";
+        example = "/mnt-root/root/.swapkey";
         type = types.nullOr types.str;
         description = "File system location of keyfile. This unlocks the drive after the root has been mounted to <literal>/mnt-root</literal>.";
       };
@@ -67,7 +67,6 @@ in
       luks = {
         devices =
           map (dev: { name = dev.encrypted.label; device = dev.encrypted.blkDev; } ) keylessEncDevs;
-        cryptoModules = [ "aes" "sha256" "sha1" "xts" ];
         forceLuksSupportInInitrd = true;
       };
       postMountCommands =
diff --git a/nixos/modules/tasks/filesystems/ext.nix b/nixos/modules/tasks/filesystems/ext.nix
index cc9d0ef37d59..3a8999c242bd 100644
--- a/nixos/modules/tasks/filesystems/ext.nix
+++ b/nixos/modules/tasks/filesystems/ext.nix
@@ -5,7 +5,8 @@
 
     system.fsPackages = [ pkgs.e2fsprogs ];
 
-    boot.initrd.availableKernelModules = [ "ext2" "ext3" "ext4" ];
+    # As of kernel 4.3, there is no separate ext3 driver (they're also handled by ext4.ko)
+    boot.initrd.availableKernelModules = [ "ext2" "ext4" ];
 
     boot.initrd.extraUtilsCommands =
       ''
diff --git a/nixos/modules/tasks/powertop.nix b/nixos/modules/tasks/powertop.nix
index 0ec4974789b4..609831506e16 100644
--- a/nixos/modules/tasks/powertop.nix
+++ b/nixos/modules/tasks/powertop.nix
@@ -16,6 +16,7 @@ in {
       powertop = {
         wantedBy = [ "multi-user.target" ];
         description = "Powertop tunings";
+        path = [ pkgs.kmod ];
         serviceConfig = {
           Type = "oneshot";
           RemainAfterExit = "yes";
diff --git a/nixos/modules/virtualisation/brightbox-image.nix b/nixos/modules/virtualisation/brightbox-image.nix
index 7f45f0f34f71..08bbcfd9d7c2 100644
--- a/nixos/modules/virtualisation/brightbox-image.nix
+++ b/nixos/modules/virtualisation/brightbox-image.nix
@@ -33,9 +33,9 @@ in
         }
         ''
           # Create partition table
-          ${pkgs.parted}/sbin/parted /dev/vda mklabel msdos
-          ${pkgs.parted}/sbin/parted /dev/vda mkpart primary ext4 1 ${diskSize}
-          ${pkgs.parted}/sbin/parted /dev/vda print
+          ${pkgs.parted}/sbin/parted --script /dev/vda mklabel msdos
+          ${pkgs.parted}/sbin/parted --script /dev/vda mkpart primary ext4 1 ${diskSize}
+          ${pkgs.parted}/sbin/parted --script /dev/vda print
           . /sys/class/block/vda1/uevent
           mknod /dev/vda1 b $MAJOR $MINOR
 
diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix
index f61d80f55991..125e6b7050bc 100644
--- a/nixos/release-combined.nix
+++ b/nixos/release-combined.nix
@@ -42,12 +42,11 @@ in rec {
     name = "nixos-${nixos.channel.version}";
     meta = {
       description = "Release-critical builds for the NixOS channel";
-      maintainers = [ pkgs.lib.maintainers.eelco ];
+      maintainers = with pkgs.lib.maintainers; [ eelco fpletz ];
     };
     constituents =
       let
-        all = x: map (system: x.${system})
-          (supportedSystems ++ limitedSupportedSystems);
+        all = x: map (system: x.${system}) supportedSystems;
       in [
         nixos.channel
         (all nixos.dummy)
@@ -61,7 +60,7 @@ in rec {
         nixos.tests.chromium
         (all nixos.tests.firefox)
         (all nixos.tests.firewall)
-        nixos.tests.gnome3.x86_64-linux # FIXME: i686-linux
+        (all nixos.tests.gnome3)
         nixos.tests.installer.zfsroot.x86_64-linux # ZFS is 64bit only
         (all nixos.tests.installer.lvm)
         (all nixos.tests.installer.luksroot)
@@ -80,9 +79,8 @@ in rec {
         (all nixos.tests.boot.uefiCdrom)
         (all nixos.tests.boot.uefiUsb)
         (all nixos.tests.boot-stage1)
-        nixos.tests.hibernate.x86_64-linux # i686 is flaky, see #23107
+        (all nixos.tests.hibernate)
         nixos.tests.docker
-        nixos.tests.docker-edge
         (all nixos.tests.ecryptfs)
         (all nixos.tests.env)
         (all nixos.tests.ipv6)
@@ -93,7 +91,7 @@ in rec {
         (all nixos.tests.keymap.dvp)
         (all nixos.tests.keymap.neo)
         (all nixos.tests.keymap.qwertz)
-        nixos.tests.plasma5.x86_64-linux # avoid big build on i686
+        (all nixos.tests.plasma5)
         #(all nixos.tests.lightdm)
         (all nixos.tests.login)
         (all nixos.tests.misc)
diff --git a/nixos/release.nix b/nixos/release.nix
index ee706ff986d4..3016b1ef9442 100644
--- a/nixos/release.nix
+++ b/nixos/release.nix
@@ -214,6 +214,7 @@ in rec {
   # Run the tests for each platform.  You can run a test by doing
   # e.g. ‘nix-build -A tests.login.x86_64-linux’, or equivalently,
   # ‘nix-build tests/login.nix -A result’.
+  tests.atd = callTest tests/atd.nix {};
   tests.acme = callTest tests/acme.nix {};
   tests.avahi = callTest tests/avahi.nix {};
   tests.bittorrent = callTest tests/bittorrent.nix {};
@@ -249,12 +250,14 @@ in rec {
   tests.firewall = callTest tests/firewall.nix {};
   tests.fleet = hydraJob (import tests/fleet.nix { system = "x86_64-linux"; });
   #tests.gitlab = callTest tests/gitlab.nix {};
+  tests.gitolite = callTest tests/gitolite.nix {};
   tests.glance = callTest tests/glance.nix {};
   tests.gocd-agent = callTest tests/gocd-agent.nix {};
   tests.gocd-server = callTest tests/gocd-server.nix {};
   tests.gnome3 = callTest tests/gnome3.nix {};
   tests.gnome3-gdm = callTest tests/gnome3-gdm.nix {};
   tests.grafama = callTest tests/grafana.nix {};
+  tests.graphite = callTest tests/graphite.nix {};
   tests.hardened = callTest tests/hardened.nix { };
   tests.hibernate = callTest tests/hibernate.nix {};
   tests.hound = callTest tests/hound.nix {};
@@ -303,8 +306,10 @@ in rec {
   #tests.panamax = hydraJob (import tests/panamax.nix { system = "x86_64-linux"; });
   tests.peerflix = callTest tests/peerflix.nix {};
   tests.postgresql = callSubTests tests/postgresql.nix {};
+  tests.postgis = callTest tests/postgis.nix {};
   #tests.pgjwt = callTest tests/pgjwt.nix {};
   tests.printing = callTest tests/printing.nix {};
+  tests.prometheus = callTest tests/prometheus.nix {};
   tests.proxy = callTest tests/proxy.nix {};
   tests.pumpio = callTest tests/pump.io.nix {};
   # tests.quagga = callTest tests/quagga.nix {};
diff --git a/nixos/tests/atd.nix b/nixos/tests/atd.nix
new file mode 100644
index 000000000000..c2c0a716e0de
--- /dev/null
+++ b/nixos/tests/atd.nix
@@ -0,0 +1,36 @@
+import ./make-test.nix ({ pkgs, lib, ... }:
+
+{
+  name = "atd";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ bjornfor ];
+  };
+
+  machine =
+    { config, pkgs, ... }:
+    { services.atd.enable = true;
+      users.extraUsers.alice = { isNormalUser = true; };
+    };
+
+  # "at" has a resolution of 1 minute
+  testScript = ''
+    startAll;
+
+    $machine->fail("test -f ~root/at-1");
+    $machine->fail("test -f ~root/batch-1");
+    $machine->fail("test -f ~alice/at-1");
+    $machine->fail("test -f ~alice/batch-1");
+
+    $machine->succeed("echo 'touch ~root/at-1' | at now+1min");
+    $machine->succeed("echo 'touch ~root/batch-1' | batch");
+    $machine->succeed("su - alice -c \"echo 'touch at-1' | at now+1min\"");
+    $machine->succeed("su - alice -c \"echo 'touch batch-1' | batch\"");
+
+    $machine->succeed("sleep 1.5m");
+
+    $machine->succeed("test -f ~root/at-1");
+    $machine->succeed("test -f ~root/batch-1");
+    $machine->succeed("test -f ~alice/at-1");
+    $machine->succeed("test -f ~alice/batch-1");
+  '';
+})
diff --git a/nixos/tests/gitolite.nix b/nixos/tests/gitolite.nix
new file mode 100644
index 000000000000..643ea4ff03ef
--- /dev/null
+++ b/nixos/tests/gitolite.nix
@@ -0,0 +1,139 @@
+import ./make-test.nix ({ pkgs, ...}:
+
+let
+  adminPrivateKey = pkgs.writeText "id_ed25519" ''
+    -----BEGIN OPENSSH PRIVATE KEY-----
+    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+    QyNTUxOQAAACDu7qxYQAPdAU6RrhB3llk2N1v4PTwcVzcX1oX265uC3gAAAJBJiYxDSYmM
+    QwAAAAtzc2gtZWQyNTUxOQAAACDu7qxYQAPdAU6RrhB3llk2N1v4PTwcVzcX1oX265uC3g
+    AAAEDE1W6vMwSEUcF1r7Hyypm/+sCOoDmKZgPxi3WOa1mD2u7urFhAA90BTpGuEHeWWTY3
+    W/g9PBxXNxfWhfbrm4LeAAAACGJmb0BtaW5pAQIDBAU=
+    -----END OPENSSH PRIVATE KEY-----
+  '';
+
+  adminPublicKey = pkgs.writeText "id_ed25519.pub" ''
+    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO7urFhAA90BTpGuEHeWWTY3W/g9PBxXNxfWhfbrm4Le root@client
+  '';
+
+  alicePrivateKey = pkgs.writeText "id_ed25519" ''
+    -----BEGIN OPENSSH PRIVATE KEY-----
+    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+    QyNTUxOQAAACBbeWvHh/AWGWI6EIc1xlSihyXtacNQ9KeztlW/VUy8wQAAAJAwVQ5VMFUO
+    VQAAAAtzc2gtZWQyNTUxOQAAACBbeWvHh/AWGWI6EIc1xlSihyXtacNQ9KeztlW/VUy8wQ
+    AAAEB7lbfkkdkJoE+4TKHPdPQWBKLSx+J54Eg8DaTr+3KoSlt5a8eH8BYZYjoQhzXGVKKH
+    Je1pw1D0p7O2Vb9VTLzBAAAACGJmb0BtaW5pAQIDBAU=
+    -----END OPENSSH PRIVATE KEY-----
+  '';
+
+  alicePublicKey = pkgs.writeText "id_ed25519.pub" ''
+    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFt5a8eH8BYZYjoQhzXGVKKHJe1pw1D0p7O2Vb9VTLzB alice@client
+  '';
+
+  bobPrivateKey = pkgs.writeText "id_ed25519" ''
+    -----BEGIN OPENSSH PRIVATE KEY-----
+    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+    QyNTUxOQAAACCWTaJ1D9Xjxy6759FvQ9oXTes1lmWBciXPkEeqTikBMAAAAJDQBmNV0AZj
+    VQAAAAtzc2gtZWQyNTUxOQAAACCWTaJ1D9Xjxy6759FvQ9oXTes1lmWBciXPkEeqTikBMA
+    AAAEDM1IYYFUwk/IVxauha9kuR6bbRtT3gZ6ZA0GLb9txb/pZNonUP1ePHLrvn0W9D2hdN
+    6zWWZYFyJc+QR6pOKQEwAAAACGJmb0BtaW5pAQIDBAU=
+    -----END OPENSSH PRIVATE KEY-----
+  '';
+
+  bobPublicKey = pkgs.writeText "id_ed25519.pub" ''
+    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJZNonUP1ePHLrvn0W9D2hdN6zWWZYFyJc+QR6pOKQEw bob@client
+  '';
+
+  gitoliteAdminConfSnippet = ''
+    repo alice-project
+        RW+     =   alice
+  '';
+in
+{
+  name = "gitolite";
+
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ bjornfor ];
+  };
+
+  nodes = {
+
+    server =
+      { config, pkgs, lib, ... }:
+      {
+        services.gitolite = {
+          enable = true;
+          adminPubkey = builtins.readFile adminPublicKey;
+        };
+        services.openssh.enable = true;
+      };
+
+    client =
+      { config, pkgs, lib, ... }:
+      {
+        environment.systemPackages = [ pkgs.git ];
+        programs.ssh.extraConfig = ''
+          Host *
+            UserKnownHostsFile /dev/null
+            StrictHostKeyChecking no
+            # there's nobody around that can input password
+            PreferredAuthentications publickey
+        '';
+        users.extraUsers.alice = { isNormalUser = true; };
+        users.extraUsers.bob = { isNormalUser = true; };
+      };
+
+  };
+
+  testScript = ''
+    startAll;
+
+    subtest "can setup ssh keys on system", sub {
+      $client->mustSucceed("mkdir -p ~root/.ssh");
+      $client->mustSucceed("cp ${adminPrivateKey} ~root/.ssh/id_ed25519");
+      $client->mustSucceed("chmod 600 ~root/.ssh/id_ed25519");
+
+      $client->mustSucceed("sudo -u alice mkdir -p ~alice/.ssh");
+      $client->mustSucceed("sudo -u alice cp ${alicePrivateKey} ~alice/.ssh/id_ed25519");
+      $client->mustSucceed("sudo -u alice chmod 600 ~alice/.ssh/id_ed25519");
+
+      $client->mustSucceed("sudo -u bob mkdir -p ~bob/.ssh");
+      $client->mustSucceed("sudo -u bob cp ${bobPrivateKey} ~bob/.ssh/id_ed25519");
+      $client->mustSucceed("sudo -u bob chmod 600 ~bob/.ssh/id_ed25519");
+    };
+
+    subtest "gitolite server starts", sub {
+      $server->waitForUnit("gitolite-init.service");
+      $server->waitForUnit("sshd.service");
+      $client->mustSucceed('ssh gitolite@server info');
+    };
+
+    subtest "admin can clone and configure gitolite-admin.git", sub {
+      $client->mustSucceed('git clone gitolite@server:gitolite-admin.git');
+      $client->mustSucceed("git config --global user.name 'System Administrator'");
+      $client->mustSucceed("git config --global user.email root\@domain.example");
+      $client->mustSucceed("cp ${alicePublicKey} gitolite-admin/keydir/alice.pub");
+      $client->mustSucceed("cp ${bobPublicKey} gitolite-admin/keydir/bob.pub");
+      $client->mustSucceed('(cd gitolite-admin && git add . && git commit -m "Add keys for alice, bob" && git push)');
+      $client->mustSucceed("printf '${gitoliteAdminConfSnippet}' >> gitolite-admin/conf/gitolite.conf");
+      $client->mustSucceed('(cd gitolite-admin && git add . && git commit -m "Add repo for alice" && git push)');
+    };
+
+    subtest "non-admins cannot clone gitolite-admin.git", sub {
+      $client->mustFail('sudo -i -u alice git clone gitolite@server:gitolite-admin.git');
+      $client->mustFail('sudo -i -u bob git clone gitolite@server:gitolite-admin.git');
+    };
+
+    subtest "non-admins can clone testing.git", sub {
+      $client->mustSucceed('sudo -i -u alice git clone gitolite@server:testing.git');
+      $client->mustSucceed('sudo -i -u bob git clone gitolite@server:testing.git');
+    };
+
+    subtest "alice can clone alice-project.git", sub {
+      $client->mustSucceed('sudo -i -u alice git clone gitolite@server:alice-project.git');
+    };
+
+    subtest "bob cannot clone alice-project.git", sub {
+      $client->mustFail('sudo -i -u bob git clone gitolite@server:alice-project.git');
+    };
+  '';
+})
diff --git a/nixos/tests/graphite.nix b/nixos/tests/graphite.nix
new file mode 100644
index 000000000000..4fd7de192d55
--- /dev/null
+++ b/nixos/tests/graphite.nix
@@ -0,0 +1,26 @@
+import ./make-test.nix ({ pkgs, ...} :
+{
+  name = "graphite";
+  nodes = {
+    one =
+      { config, pkgs, ... }: {
+        services.graphite = {
+          web = {
+            enable = true;
+          };
+          carbon = {
+            enableCache = true;
+          };
+        };
+      };
+    };
+
+  testScript = ''
+    startAll;
+    $one->waitForUnit("default.target");
+    $one->requireActiveUnit("graphiteWeb.service");
+    $one->requireActiveUnit("carbonCache.service");
+    $one->succeed("echo \"foo 1 `date +%s`\" | nc -q0 localhost 2003");
+    $one->waitUntilSucceeds("curl 'http://localhost:8080/metrics/find/?query=foo&format=treejson' --silent | grep foo")
+  '';
+})
diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix
index c1dae2a34fa3..da9582deec1d 100644
--- a/nixos/tests/installer.nix
+++ b/nixos/tests/installer.nix
@@ -260,9 +260,9 @@ in {
     { createPartitions =
         ''
           $machine->succeed(
-              "parted /dev/vda mklabel msdos",
-              "parted /dev/vda -- mkpart primary linux-swap 1M 1024M",
-              "parted /dev/vda -- mkpart primary ext2 1024M -1s",
+              "parted --script /dev/vda mklabel msdos",
+              "parted --script /dev/vda -- mkpart primary linux-swap 1M 1024M",
+              "parted --script /dev/vda -- mkpart primary ext2 1024M -1s",
               "udevadm settle",
               "mkswap /dev/vda1 -L swap",
               "swapon -L swap",
@@ -277,11 +277,11 @@ in {
     { createPartitions =
         ''
           $machine->succeed(
-              "parted /dev/vda mklabel gpt",
-              "parted -s /dev/vda -- mkpart ESP fat32 1M 50MiB", # /boot
-              "parted -s /dev/vda -- set 1 boot on",
-              "parted -s /dev/vda -- mkpart primary linux-swap 50MiB 1024MiB",
-              "parted -s /dev/vda -- mkpart primary ext2 1024MiB -1MiB", # /
+              "parted --script /dev/vda mklabel gpt",
+              "parted --script /dev/vda -- mkpart ESP fat32 1M 50MiB", # /boot
+              "parted --script /dev/vda -- set 1 boot on",
+              "parted --script /dev/vda -- mkpart primary linux-swap 50MiB 1024MiB",
+              "parted --script /dev/vda -- mkpart primary ext2 1024MiB -1MiB", # /
               "udevadm settle",
               "mkswap /dev/vda2 -L swap",
               "swapon -L swap",
@@ -300,10 +300,10 @@ in {
     { createPartitions =
         ''
           $machine->succeed(
-              "parted /dev/vda mklabel msdos",
-              "parted /dev/vda -- mkpart primary ext2 1M 50MB", # /boot
-              "parted /dev/vda -- mkpart primary linux-swap 50MB 1024M",
-              "parted /dev/vda -- mkpart primary ext2 1024M -1s", # /
+              "parted --script /dev/vda mklabel msdos",
+              "parted --script /dev/vda -- mkpart primary ext2 1M 50MB", # /boot
+              "parted --script /dev/vda -- mkpart primary linux-swap 50MB 1024M",
+              "parted --script /dev/vda -- mkpart primary ext2 1024M -1s", # /
               "udevadm settle",
               "mkswap /dev/vda2 -L swap",
               "swapon -L swap",
@@ -321,10 +321,10 @@ in {
     { createPartitions =
         ''
           $machine->succeed(
-              "parted /dev/vda mklabel msdos",
-              "parted /dev/vda -- mkpart primary ext2 1M 50MB", # /boot
-              "parted /dev/vda -- mkpart primary linux-swap 50MB 1024M",
-              "parted /dev/vda -- mkpart primary ext2 1024M -1s", # /
+              "parted --script /dev/vda mklabel msdos",
+              "parted --script /dev/vda -- mkpart primary ext2 1M 50MB", # /boot
+              "parted --script /dev/vda -- mkpart primary linux-swap 50MB 1024M",
+              "parted --script /dev/vda -- mkpart primary ext2 1024M -1s", # /
               "udevadm settle",
               "mkswap /dev/vda2 -L swap",
               "swapon -L swap",
@@ -357,9 +357,9 @@ in {
       createPartitions =
         ''
           $machine->succeed(
-              "parted /dev/vda mklabel msdos",
-              "parted /dev/vda -- mkpart primary linux-swap 1M 1024M",
-              "parted /dev/vda -- mkpart primary 1024M -1s",
+              "parted --script /dev/vda mklabel msdos",
+              "parted --script /dev/vda -- mkpart primary linux-swap 1M 1024M",
+              "parted --script /dev/vda -- mkpart primary 1024M -1s",
               "udevadm settle",
 
               "mkswap /dev/vda1 -L swap",
@@ -380,11 +380,11 @@ in {
     { createPartitions =
         ''
           $machine->succeed(
-              "parted /dev/vda mklabel msdos",
-              "parted /dev/vda -- mkpart primary 1M 2048M", # PV1
-              "parted /dev/vda -- set 1 lvm on",
-              "parted /dev/vda -- mkpart primary 2048M -1s", # PV2
-              "parted /dev/vda -- set 2 lvm on",
+              "parted --script /dev/vda mklabel msdos",
+              "parted --script /dev/vda -- mkpart primary 1M 2048M", # PV1
+              "parted --script /dev/vda -- set 1 lvm on",
+              "parted --script /dev/vda -- mkpart primary 2048M -1s", # PV2
+              "parted --script /dev/vda -- set 2 lvm on",
               "udevadm settle",
               "pvcreate /dev/vda1 /dev/vda2",
               "vgcreate MyVolGroup /dev/vda1 /dev/vda2",
@@ -402,10 +402,10 @@ in {
   luksroot = makeInstallerTest "luksroot"
     { createPartitions = ''
         $machine->succeed(
-          "parted /dev/vda mklabel msdos",
-          "parted /dev/vda -- mkpart primary ext2 1M 50MB", # /boot
-          "parted /dev/vda -- mkpart primary linux-swap 50M 1024M",
-          "parted /dev/vda -- mkpart primary 1024M -1s", # LUKS
+          "parted --script /dev/vda mklabel msdos",
+          "parted --script /dev/vda -- mkpart primary ext2 1M 50MB", # /boot
+          "parted --script /dev/vda -- mkpart primary linux-swap 50M 1024M",
+          "parted --script /dev/vda -- mkpart primary 1024M -1s", # LUKS
           "udevadm settle",
           "mkswap /dev/vda2 -L swap",
           "swapon -L swap",
@@ -434,7 +434,7 @@ in {
     { createPartitions =
         ''
           $machine->succeed(
-              "parted /dev/vda --"
+              "parted --script /dev/vda --"
               . " mklabel msdos"
               . " mkpart primary ext2 1M 100MB" # /boot
               . " mkpart extended 100M -1s"
@@ -469,9 +469,9 @@ in {
     { createPartitions =
         ''
           $machine->succeed(
-              "parted /dev/sda mklabel msdos",
-              "parted /dev/sda -- mkpart primary linux-swap 1M 1024M",
-              "parted /dev/sda -- mkpart primary ext2 1024M -1s",
+              "parted --script /dev/sda mklabel msdos",
+              "parted --script /dev/sda -- mkpart primary linux-swap 1M 1024M",
+              "parted --script /dev/sda -- mkpart primary ext2 1024M -1s",
               "udevadm settle",
               "mkswap /dev/sda1 -L swap",
               "swapon -L swap",
diff --git a/nixos/tests/minio.nix b/nixos/tests/minio.nix
index a349265b2f57..07a292a9baa5 100644
--- a/nixos/tests/minio.nix
+++ b/nixos/tests/minio.nix
@@ -12,6 +12,9 @@ import ./make-test.nix ({ pkgs, ...} : {
         secretKey = "V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12";
       };
       environment.systemPackages = [ pkgs.minio-client ];
+
+      # Minio requires at least 1GiB of free disk space to run.
+      virtualisation.diskSize = 4 * 1024;
     };
   };
 
@@ -20,7 +23,6 @@ import ./make-test.nix ({ pkgs, ...} : {
       startAll;
       $machine->waitForUnit("minio.service");
       $machine->waitForOpenPort(9000);
-      $machine->succeed("curl --fail http://localhost:9000/minio/index.html");
 
       # Create a test bucket on the server
       $machine->succeed("mc config host add minio http://localhost:9000 BKIKJAA5BMMU2RHO6IBB V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12 S3v4");
diff --git a/nixos/tests/postgis.nix b/nixos/tests/postgis.nix
index 1dba5c363c09..f6ce3fe38ed3 100644
--- a/nixos/tests/postgis.nix
+++ b/nixos/tests/postgis.nix
@@ -9,15 +9,11 @@ import ./make-test.nix ({ pkgs, ...} : {
       { pkgs, config, ... }:
 
       {
-        services.postgresql = let mypg = pkgs.postgresql95; in {
+        services.postgresql = let mypg = pkgs.postgresql100; in {
             enable = true;
             package = mypg;
-            extraPlugins = [ (pkgs.postgis.override { postgresql = mypg; }).v_2_2_1 ];
-            initialScript =  pkgs.writeText "postgresql-init.sql"
-          ''
-          CREATE ROLE postgres WITH superuser login createdb;
-          '';
-          };
+            extraPlugins = [ (pkgs.postgis.override { postgresql = mypg; }).v_2_4_0 ];
+        };
       };
   };
 
diff --git a/nixos/tests/prometheus.nix b/nixos/tests/prometheus.nix
index ade097597bb8..374fb2d634b4 100644
--- a/nixos/tests/prometheus.nix
+++ b/nixos/tests/prometheus.nix
@@ -5,9 +5,6 @@ import ./make-test.nix {
     one = { config, pkgs, ... }: {
       services.prometheus = {
         enable = true;
-        globalConfig = {
-          labels = { foo = "bar"; };
-        };
         scrapeConfigs = [{
           job_name = "prometheus";
           static_configs = [{
diff --git a/nixos/tests/run-in-machine.nix b/nixos/tests/run-in-machine.nix
index d1102f8d4073..a6dfece44a92 100644
--- a/nixos/tests/run-in-machine.nix
+++ b/nixos/tests/run-in-machine.nix
@@ -2,7 +2,16 @@
 
 with import ../lib/testing.nix { inherit system; };
 
-runInMachine {
-  drv = pkgs.hello;
-  machine = { config, pkgs, ... }: { /* services.sshd.enable = true; */ };
-}
+let
+  output = runInMachine {
+    drv = pkgs.hello;
+    machine = { config, pkgs, ... }: { /* services.sshd.enable = true; */ };
+  };
+in pkgs.runCommand "verify-output" { inherit output; } ''
+  if [ ! -e "$output/bin/hello" ]; then
+    echo "Derivation built using runInMachine produced incorrect output:" >&2
+    ls -laR "$output" >&2
+    exit 1
+  fi
+  "$output/bin/hello" > "$out"
+''
diff --git a/nixos/tests/virtualbox.nix b/nixos/tests/virtualbox.nix
index a1ab7614871a..c519d7dae8be 100644
--- a/nixos/tests/virtualbox.nix
+++ b/nixos/tests/virtualbox.nix
@@ -107,8 +107,8 @@ let
 
     buildInputs = [ pkgs.utillinux pkgs.perl ];
   } ''
-    ${pkgs.parted}/sbin/parted /dev/vda mklabel msdos
-    ${pkgs.parted}/sbin/parted /dev/vda -- mkpart primary ext2 1M -1s
+    ${pkgs.parted}/sbin/parted --script /dev/vda mklabel msdos
+    ${pkgs.parted}/sbin/parted --script /dev/vda -- mkpart primary ext2 1M -1s
     . /sys/class/block/vda1/uevent
     mknod /dev/vda1 b $MAJOR $MINOR