about summary refs log tree commit diff
path: root/nixpkgs/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos')
-rw-r--r--nixpkgs/nixos/doc/manual/development/option-types.xml12
-rw-r--r--nixpkgs/nixos/doc/manual/installation/changing-config.xml7
-rw-r--r--nixpkgs/nixos/doc/manual/installation/installing.xml19
-rw-r--r--nixpkgs/nixos/doc/manual/man-nixos-enter.xml16
-rw-r--r--nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml32
-rw-r--r--nixpkgs/nixos/doc/manual/release-notes/rl-1909.xml34
-rw-r--r--nixpkgs/nixos/lib/build-vms.nix6
-rw-r--r--nixpkgs/nixos/lib/make-options-doc/default.nix47
-rw-r--r--nixpkgs/nixos/maintainers/option-usages.nix2
-rw-r--r--nixpkgs/nixos/modules/config/users-groups.nix5
-rw-r--r--nixpkgs/nixos/modules/hardware/device-tree.nix56
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix19
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix17
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix4
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-enter.sh21
-rw-r--r--nixpkgs/nixos/modules/misc/crashdump.nix1
-rw-r--r--nixpkgs/nixos/modules/module-list.nix3
-rw-r--r--nixpkgs/nixos/modules/profiles/hardened.nix6
-rw-r--r--nixpkgs/nixos/modules/profiles/installation-device.nix27
-rw-r--r--nixpkgs/nixos/modules/programs/environment.nix5
-rw-r--r--nixpkgs/nixos/modules/programs/fuse.nix37
-rw-r--r--nixpkgs/nixos/modules/rename.nix3
-rw-r--r--nixpkgs/nixos/modules/services/admin/oxidized.nix4
-rw-r--r--nixpkgs/nixos/modules/services/backup/automysqlbackup.nix2
-rw-r--r--nixpkgs/nixos/modules/services/databases/memcached.nix18
-rw-r--r--nixpkgs/nixos/modules/services/desktops/flatpak.nix11
-rw-r--r--nixpkgs/nixos/modules/services/editors/emacs.xml2
-rw-r--r--nixpkgs/nixos/modules/services/games/minecraft-server.nix2
-rw-r--r--nixpkgs/nixos/modules/services/mail/davmail.nix2
-rw-r--r--nixpkgs/nixos/modules/services/mail/postfix.nix2
-rw-r--r--nixpkgs/nixos/modules/services/mail/rspamd.nix2
-rw-r--r--nixpkgs/nixos/modules/services/mail/rss2email.nix2
-rw-r--r--nixpkgs/nixos/modules/services/misc/gitlab.nix2
-rw-r--r--nixpkgs/nixos/modules/services/misc/matrix-synapse.nix2
-rw-r--r--nixpkgs/nixos/modules/services/misc/metabase.nix103
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/cadvisor.nix11
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/loki.nix2
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/riemann-tools.nix12
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/ups.nix2
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/zabbix-proxy.nix11
-rw-r--r--nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix6
-rw-r--r--nixpkgs/nixos/modules/services/networking/cjdns.nix21
-rw-r--r--nixpkgs/nixos/modules/services/networking/consul.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/hylafax/systemd.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/shadowsocks.nix6
-rw-r--r--nixpkgs/nixos/modules/services/networking/ssh/sshd.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/znc/default.nix4
-rw-r--r--nixpkgs/nixos/modules/services/printing/cupsd.nix20
-rw-r--r--nixpkgs/nixos/modules/services/search/elasticsearch.nix1
-rw-r--r--nixpkgs/nixos/modules/services/security/bitwarden_rs/default.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/limesurvey.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/caddy.nix2
-rw-r--r--nixpkgs/nixos/modules/services/x11/compton.nix2
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix13
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix8
-rw-r--r--nixpkgs/nixos/modules/services/x11/xautolock.nix2
-rw-r--r--nixpkgs/nixos/modules/services/x11/xserver.nix4
-rw-r--r--nixpkgs/nixos/modules/system/activation/top-level.nix4
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh5
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix2
-rw-r--r--nixpkgs/nixos/modules/system/boot/networkd.nix2
-rw-r--r--nixpkgs/nixos/modules/system/boot/stage-1.nix8
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix2
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd.nix40
-rw-r--r--nixpkgs/nixos/modules/tasks/filesystems/nfs.nix1
-rw-r--r--nixpkgs/nixos/modules/tasks/network-interfaces-systemd.nix8
-rw-r--r--nixpkgs/nixos/modules/tasks/network-interfaces.nix12
-rw-r--r--nixpkgs/nixos/modules/tasks/swraid.nix43
-rw-r--r--nixpkgs/nixos/modules/virtualisation/amazon-image.nix7
-rw-r--r--nixpkgs/nixos/tests/all-tests.nix1
-rw-r--r--nixpkgs/nixos/tests/metabase.nix20
-rw-r--r--nixpkgs/nixos/tests/mosquitto.nix33
-rw-r--r--nixpkgs/nixos/tests/networking.nix2
-rw-r--r--nixpkgs/nixos/tests/printing.nix6
-rw-r--r--nixpkgs/nixos/tests/systemd.nix18
76 files changed, 683 insertions, 203 deletions
diff --git a/nixpkgs/nixos/doc/manual/development/option-types.xml b/nixpkgs/nixos/doc/manual/development/option-types.xml
index 069cc36573d8..8fcbb627342b 100644
--- a/nixpkgs/nixos/doc/manual/development/option-types.xml
+++ b/nixpkgs/nixos/doc/manual/development/option-types.xml
@@ -348,6 +348,18 @@
    </varlistentry>
    <varlistentry>
     <term>
+     <varname>types.oneOf</varname> [ <replaceable>t1</replaceable> <replaceable>t2</replaceable> ... ]
+    </term>
+    <listitem>
+     <para>
+      Type <replaceable>t1</replaceable> or type <replaceable>t2</replaceable> and so forth,
+      e.g. <literal>with types; oneOf [ int str bool ]</literal>. Multiple definitions
+      cannot be merged.
+     </para>
+    </listitem>
+   </varlistentry>
+   <varlistentry>
+    <term>
      <varname>types.coercedTo</varname> <replaceable>from</replaceable> <replaceable>f</replaceable> <replaceable>to</replaceable>
     </term>
     <listitem>
diff --git a/nixpkgs/nixos/doc/manual/installation/changing-config.xml b/nixpkgs/nixos/doc/manual/installation/changing-config.xml
index b77d71389a9d..48193d986ab7 100644
--- a/nixpkgs/nixos/doc/manual/installation/changing-config.xml
+++ b/nixpkgs/nixos/doc/manual/installation/changing-config.xml
@@ -14,6 +14,13 @@
   to build the new configuration, make it the default configuration for
   booting, and try to realise the configuration in the running system (e.g., by
   restarting system services).
+  <warning>
+   <para>
+    This command doesn't start/stop <link linkend="opt-systemd.user.services">user
+    services</link> automatically. <command>nixos-rebuild</command> only runs a
+    <literal>daemon-reload</literal> for each user with running user services.
+   </para>
+  </warning>
  </para>
  <warning>
   <para>
diff --git a/nixpkgs/nixos/doc/manual/installation/installing.xml b/nixpkgs/nixos/doc/manual/installation/installing.xml
index 742376378dea..9cea2db610e0 100644
--- a/nixpkgs/nixos/doc/manual/installation/installing.xml
+++ b/nixpkgs/nixos/doc/manual/installation/installing.xml
@@ -29,13 +29,14 @@
   </para>
 
   <para>
-   You are logged-in automatically as <literal>root</literal>. (The
-   <literal>root</literal> user account has an empty password.)
+   You are logged-in automatically as <literal>nixos</literal>.
+   The <literal>nixos</literal> user account has an empty password so you
+   can use <command>sudo</command> without a password.
   </para>
 
   <para>
    If you downloaded the graphical ISO image, you can run <command>systemctl
-   start display-manager</command> to start KDE. If you want to continue on the
+   start display-manager</command> to start the desktop environment. If you want to continue on the
    terminal, you can use <command>loadkeys</command> to switch to your
    preferred keyboard layout. (We even provide neo2 via <command>loadkeys de
    neo</command>!)
@@ -65,9 +66,9 @@
 
    <para>
     If you would like to continue the installation from a different machine you
-    need to activate the SSH daemon via <literal>systemctl start
-    sshd</literal>. In order to be able to login you also need to set a
-    password for <literal>root</literal> using <literal>passwd</literal>.
+    need to activate the SSH daemon via <command>systemctl start
+    sshd</command>. You then must set a password for either <literal>root</literal> or
+    <literal>nixos</literal> with <command>passwd></command> to be able to login.
    </para>
   </section>
  </section>
@@ -334,7 +335,7 @@
      If you’re using the graphical ISO image, other editors may be available
      (such as <command>vim</command>). If you have network access, you can also
      install other editors — for instance, you can install Emacs by running
-     <literal>nix-env -i emacs</literal>.
+     <literal>nix-env -f '&lt;nixpkgs&gt;' -iA emacs</literal>.
     </para>
     <variablelist>
      <varlistentry>
@@ -466,10 +467,10 @@ Retype new UNIX password: ***</screen>
     <para>
      You may also want to install some software. For instance,
 <screen>
-<prompt>$ </prompt>nix-env -qa \*</screen>
+<prompt>$ </prompt>nix-env -qaP \*</screen>
      shows what packages are available, and
 <screen>
-<prompt>$ </prompt>nix-env -i w3m</screen>
+<prompt>$ </prompt>nix-env -f '&lt;nixpkgs&gt;' -iA w3m</screen>
      install the <literal>w3m</literal> browser.
     </para>
    </listitem>
diff --git a/nixpkgs/nixos/doc/manual/man-nixos-enter.xml b/nixpkgs/nixos/doc/manual/man-nixos-enter.xml
index 42edaa1ae5b6..1481db467122 100644
--- a/nixpkgs/nixos/doc/manual/man-nixos-enter.xml
+++ b/nixpkgs/nixos/doc/manual/man-nixos-enter.xml
@@ -34,6 +34,12 @@
     </arg>
      <replaceable>shell-command</replaceable>
    </arg>
+
+   <arg>
+    <arg choice='plain'>
+     <option>--silent</option>
+    </arg>
+   </arg>
     
    <arg>
     <arg choice='plain'>
@@ -102,6 +108,16 @@
    </varlistentry>
    <varlistentry>
     <term>
+     <option>--silent</option>
+    </term>
+    <listitem>
+     <para>
+       Suppresses all output from the activation script of the target system.
+     </para>
+    </listitem>
+   </varlistentry>
+   <varlistentry>
+    <term>
      <option>--</option>
     </term>
     <listitem>
diff --git a/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml b/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml
index 9cec83f1e28b..4c20cfcdd7d2 100644
--- a/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml
+++ b/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml
@@ -90,6 +90,35 @@
    <arg>
     <option>--show-trace</option>
    </arg>
+   <arg>
+    <option>-I</option>
+    <replaceable>path</replaceable>
+   </arg>
+   <arg>
+    <group choice='req'>
+     <arg choice='plain'><option>--verbose</option></arg>
+     <arg choice='plain'><option>-v</option></arg>
+    </group>
+   </arg>
+   <arg>
+    <group choice='req'>
+     <arg choice='plain'><option>--max-jobs</option></arg>
+     <arg choice='plain'><option>-j</option></arg>
+    </group>
+    <replaceable>number</replaceable>
+   </arg>
+   <arg>
+    <group choice='req'>
+     <arg choice='plain'><option>--keep-failed</option></arg>
+     <arg choice='plain'><option>-K</option></arg>
+    </group>
+   </arg>
+   <arg>
+    <group choice='req'>
+     <arg choice='plain'><option>--keep-going</option></arg>
+     <arg choice='plain'><option>-k</option></arg>
+    </group>
+   </arg>
   </cmdsynopsis>
  </refsynopsisdiv>
  <refsection>
@@ -101,7 +130,8 @@
    NixOS module, you must run <command>nixos-rebuild</command> to make the
    changes take effect. It builds the new system in
    <filename>/nix/store</filename>, runs its activation script, and stop and
-   (re)starts any system services if needed.
+   (re)starts any system services if needed. Please note that user services need
+   to be started manually as they aren't detected by the activation script at the moment.
   </para>
   <para>
    This command has one required argument, which specifies the desired
diff --git a/nixpkgs/nixos/doc/manual/release-notes/rl-1909.xml b/nixpkgs/nixos/doc/manual/release-notes/rl-1909.xml
index b12858cfc963..b780cba357e8 100644
--- a/nixpkgs/nixos/doc/manual/release-notes/rl-1909.xml
+++ b/nixpkgs/nixos/doc/manual/release-notes/rl-1909.xml
@@ -42,6 +42,12 @@
        set up binfmt interpreters for each of those listed systems.
      </para>
    </listitem>
+   <listitem>
+     <para>
+     The installer now uses a less privileged <literal>nixos</literal> user whereas before we logged in as root.
+     To gain root privileges use <literal>sudo -i</literal> without a password.
+    </para>
+   </listitem>
   </itemizedlist>
  </section>
 
@@ -248,6 +254,15 @@
        If IBus support in Qt 4.x applications is required, add the <literal>ibus-qt</literal> package to your <xref linkend="opt-environment.systemPackages" /> manually.
      </para>
    </listitem>
+   <listitem>
+     <para>
+       The CUPS Printing service now uses socket-based activation by
+       default, only starting when needed. The previous behavior can
+       be restored by setting
+       <option>services.cups.startWhenNeeded</option> to
+       <literal>false</literal>.
+     </para>
+   </listitem>
   </itemizedlist>
  </section>
 
@@ -409,6 +424,25 @@
      installer after creating <literal>/var/lib/nextcloud</literal>.
     </para>
    </listitem>
+   <listitem>
+    <para>
+     There exists now <literal>lib.forEach</literal>, which is like <literal>map</literal>, but with
+     arguments flipped. When mapping function body spans many lines (or has nested
+     <literal>map</literal>s), it is often hard to follow which list is modified.
+    </para>
+    <para>
+     Previous solution to this problem was either to use <literal>lib.flip map</literal>
+     idiom or extract that anonymous mapping function to a named one. Both can still be used
+     but <literal>lib.forEach</literal> is preferred over <literal>lib.flip map</literal>.
+    </para>
+   </listitem>
+  <listitem>
+   <para>
+    <literal>systemd.packages</literal> option now also supports generators and
+    shutdown scripts. Old <literal>systemd.generator-packages</literal> option has
+    been removed.
+   </para>
+  </listitem>
   </itemizedlist>
  </section>
 </section>
diff --git a/nixpkgs/nixos/lib/build-vms.nix b/nixpkgs/nixos/lib/build-vms.nix
index b622a4d59e89..1bad63b9194c 100644
--- a/nixpkgs/nixos/lib/build-vms.nix
+++ b/nixpkgs/nixos/lib/build-vms.nix
@@ -54,11 +54,11 @@ rec {
 
       machinesNumbered = zipLists machines (range 1 254);
 
-      nodes_ = flip map machinesNumbered (m: nameValuePair m.fst
+      nodes_ = forEach machinesNumbered (m: nameValuePair m.fst
         [ ( { config, nodes, ... }:
             let
               interfacesNumbered = zipLists config.virtualisation.vlans (range 1 255);
-              interfaces = flip map interfacesNumbered ({ fst, snd }:
+              interfaces = forEach interfacesNumbered ({ fst, snd }:
                 nameValuePair "eth${toString snd}" { ipv4.addresses =
                   [ { address = "192.168.${toString fst}.${toString m.snd}";
                       prefixLength = 24;
@@ -88,7 +88,7 @@ rec {
                          "${config.networking.hostName}\n"));
 
                   virtualisation.qemu.options =
-                    flip map interfacesNumbered
+                    forEach interfacesNumbered
                       ({ fst, snd }: qemuNICFlags snd fst m.snd);
                 };
             }
diff --git a/nixpkgs/nixos/lib/make-options-doc/default.nix b/nixpkgs/nixos/lib/make-options-doc/default.nix
index c22c7500335d..88e052106a28 100644
--- a/nixpkgs/nixos/lib/make-options-doc/default.nix
+++ b/nixpkgs/nixos/lib/make-options-doc/default.nix
@@ -88,8 +88,49 @@ let
   # Convert the list of options into an XML file.
   optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList);
 
+  optionsNix = builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList);
+
+  # TODO: declarations: link to github
+  singleAsciiDoc = name: value: ''
+    == ${name}
+
+    ${value.description}
+
+    [discrete]
+    === details
+
+    Type:: ${value.type}
+    ${ if lib.hasAttr "default" value
+       then ''
+        Default::
+        +
+        ----
+        ${builtins.toJSON value.default}
+        ----
+      ''
+      else "No Default:: {blank}"
+    }
+    ${ if value.readOnly
+       then "Read Only:: {blank}"
+      else ""
+    }
+    ${ if lib.hasAttr "example" value
+       then ''
+        Example::
+        +
+        ----
+        ${builtins.toJSON value.example}
+        ----
+      ''
+      else "No Example:: {blank}"
+    }
+  '';
+
 in rec {
-  # The NixOS options in JSON format.
+  inherit optionsNix;
+
+  optionsAsciiDoc = lib.concatStringsSep "\n" (lib.mapAttrsToList singleAsciiDoc optionsNix);
+
   optionsJSON = pkgs.runCommand "options.json"
     { meta.description = "List of NixOS options in JSON format";
     }
@@ -98,9 +139,7 @@ in rec {
       dst=$out/share/doc/nixos
       mkdir -p $dst
 
-      cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
-        (builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList))))
-      } $dst/options.json
+      cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON optionsNix))} $dst/options.json
 
       mkdir -p $out/nix-support
       echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products
diff --git a/nixpkgs/nixos/maintainers/option-usages.nix b/nixpkgs/nixos/maintainers/option-usages.nix
index a67a0ab960e5..11247666ecda 100644
--- a/nixpkgs/nixos/maintainers/option-usages.nix
+++ b/nixpkgs/nixos/maintainers/option-usages.nix
@@ -102,7 +102,7 @@ let
       # builtins multiply by 4 the memory usage and the time used to compute
       # each options.
       tryCollectOptions = moduleResult:
-        flip map (excludeOptions (collect isOption moduleResult)) (opt:
+        forEach (excludeOptions (collect isOption moduleResult)) (opt:
           { name = showOption opt.loc; } // builtins.tryEval (strict opt.value));
      in
        keepNames (
diff --git a/nixpkgs/nixos/modules/config/users-groups.nix b/nixpkgs/nixos/modules/config/users-groups.nix
index c3f228c9bcc4..25f1c67ce830 100644
--- a/nixpkgs/nixos/modules/config/users-groups.nix
+++ b/nixpkgs/nixos/modules/config/users-groups.nix
@@ -564,7 +564,10 @@ in {
       };
     }) (filterAttrs (_: u: u.packages != []) cfg.users));
 
-    environment.profiles = [ "/etc/profiles/per-user/$USER" ];
+    environment.profiles = [
+      "$HOME/.nix-profile"
+      "/etc/profiles/per-user/$USER"
+    ];
 
     assertions = [
       { assertion = !cfg.enforceIdUniqueness || (uidsAreUnique && gidsAreUnique);
diff --git a/nixpkgs/nixos/modules/hardware/device-tree.nix b/nixpkgs/nixos/modules/hardware/device-tree.nix
new file mode 100644
index 000000000000..f57502d4c83e
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/device-tree.nix
@@ -0,0 +1,56 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware.deviceTree;
+in {
+  options = {
+      hardware.deviceTree = {
+        enable = mkOption {
+          default = pkgs.stdenv.hostPlatform.platform.kernelDTB or false;
+          type = types.bool;
+          description = ''
+            Build device tree files. These are used to describe the
+            non-discoverable hardware of a system.
+          '';
+        };
+
+        base = mkOption {
+          default = "${config.boot.kernelPackages.kernel}/dtbs";
+          defaultText = "\${config.boot.kernelPackages.kernel}/dtbs";
+          example = literalExample "pkgs.deviceTree_rpi";
+          type = types.path;
+          description = ''
+            The package containing the base device-tree (.dtb) to boot. Contains
+            device trees bundled with the Linux kernel by default.
+          '';
+        };
+
+        overlays = mkOption {
+          default = [];
+          example = literalExample
+            "[\"\${pkgs.deviceTree_rpi.overlays}/w1-gpio.dtbo\"]";
+          type = types.listOf types.path;
+          description = ''
+            A path containing device tree overlays (.dtbo) to be applied to all
+            base device-trees.
+          '';
+        };
+
+        package = mkOption {
+          default = null;
+          type = types.nullOr types.path;
+          internal = true;
+          description = ''
+            A path containing the result of applying `overlays` to `base`.
+          '';
+        };
+      };
+  };
+
+  config = mkIf (cfg.enable) {
+    hardware.deviceTree.package = if (cfg.overlays != [])
+      then pkgs.deviceTree.applyOverlays cfg.base cfg.overlays else cfg.base;
+  };
+}
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix b/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix
index f65239a5bc0a..1578e1547bc1 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix
@@ -8,16 +8,30 @@ with lib;
 {
   imports = [ ./installation-cd-base.nix ];
 
+  # Whitelist wheel users to do anything
+  # This is useful for things like pkexec
+  #
+  # WARNING: this is dangerous for systems
+  # outside the installation-cd and shouldn't
+  # be used anywhere else.
+  security.polkit.extraConfig = ''
+    polkit.addRule(function(action, subject) {
+      if (subject.isInGroup("wheel")) {
+        return polkit.Result.YES;
+      }
+    });
+  '';
+
   services.xserver = {
     enable = true;
 
     # Don't start the X server by default.
     autorun = mkForce false;
 
-    # Automatically login as root.
+    # Automatically login as nixos.
     displayManager.slim = {
       enable = true;
-      defaultUser = "root";
+      defaultUser = "nixos";
       autoLogin = true;
     };
 
@@ -33,7 +47,6 @@ with lib;
 
   # Enable sound in graphical iso's.
   hardware.pulseaudio.enable = true;
-  hardware.pulseaudio.systemWide = true; # Needed since we run plasma as root.
 
   environment.systemPackages = [
     # Include gparted for partitioning disks.
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix b/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix
index 1c3c9cb30b41..2536ba73a1de 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix
@@ -1,5 +1,5 @@
 # This module defines a NixOS installation CD that contains X11 and
-# Plasma5.
+# Plasma 5.
 
 { config, lib, pkgs, ... }:
 
@@ -30,15 +30,20 @@ with lib;
       Version=1.0
       Type=Application
       Name=NixOS Manual
-      Exec=firefox ${config.system.build.manual.manualHTMLIndex}
+      Exec=firefox ${config.system.build.manual.manual}/share/doc/nixos/index.html
       Icon=text-html
     '';
 
+    homeDir = "/home/nixos/";
+    desktopDir = homeDir + "Desktop/";
+
   in ''
-    mkdir -p /root/Desktop
-    ln -sfT ${manualDesktopFile} /root/Desktop/nixos-manual.desktop
-    ln -sfT ${pkgs.konsole}/share/applications/org.kde.konsole.desktop /root/Desktop/org.kde.konsole.desktop
-    ln -sfT ${pkgs.gparted}/share/applications/gparted.desktop /root/Desktop/gparted.desktop
+    mkdir -p ${desktopDir}
+    chown nixos ${homeDir} ${desktopDir}
+
+    ln -sfT ${manualDesktopFile} ${desktopDir + "nixos-manual.desktop"}
+    ln -sfT ${pkgs.gparted}/share/applications/gparted.desktop ${desktopDir + "gparted.desktop"}
+    ln -sfT ${pkgs.konsole}/share/applications/org.kde.konsole.desktop ${desktopDir + "org.kde.konsole.desktop"}
   '';
 
 }
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix b/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix
index 0c407b199367..7f355a132496 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix
@@ -73,8 +73,8 @@ in
 
     firmwareSize = mkOption {
       type = types.int;
-      # As of 2019-05-31 the Raspberry pi firmware + u-bot takes ~13MiB
-      default = 20;
+      # As of 2019-08-18 the Raspberry pi firmware + u-boot takes ~18MiB
+      default = 30;
       description = ''
         Size of the /boot/firmware partition, in megabytes.
       '';
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh b/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
index 518dbbbf21e3..4680cd8ae95a 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
@@ -16,7 +16,8 @@ fi
 
 mountPoint=/mnt
 system=/nix/var/nix/profiles/system
-command=($system/sw/bin/bash "--login")
+command=("$system/sw/bin/bash" "--login")
+silent=0
 
 while [ "$#" -gt 0 ]; do
     i="$1"; shift 1
@@ -32,9 +33,12 @@ while [ "$#" -gt 0 ]; do
             exit 1
             ;;
         --command|-c)
-            command=($system/sw/bin/bash "-c" "$1")
+            command=("$system/sw/bin/bash" "-c" "$1")
             shift 1
             ;;
+        --silent)
+            silent=1
+            ;;
         --)
             command=("$@")
             break
@@ -51,11 +55,20 @@ if [[ ! -e $mountPoint/etc/NIXOS ]]; then
     exit 126
 fi
 
-mkdir -m 0755 -p "$mountPoint/dev" "$mountPoint/sys"
+mkdir -p "$mountPoint/dev" "$mountPoint/sys"
+chmod 0755 "$mountPoint/dev" "$mountPoint/sys"
 mount --rbind /dev "$mountPoint/dev"
 mount --rbind /sys "$mountPoint/sys"
 
+# If silent, write both stdout and stderr of activation script to /dev/null
+# otherwise, write both streams to stderr of this process
+if [ "$silent" -eq 0 ]; then
+    PIPE_TARGET="/dev/stderr"
+else
+    PIPE_TARGET="/dev/null"
+fi
+
 # Run the activation script. Set $LOCALE_ARCHIVE to supress some Perl locale warnings.
-LOCALE_ARCHIVE=$system/sw/lib/locale/locale-archive chroot "$mountPoint" "$system/activate" >&2 || true
+LOCALE_ARCHIVE="$system/sw/lib/locale/locale-archive" chroot "$mountPoint" "$system/activate" >>$PIPE_TARGET 2>&1 || true
 
 exec chroot "$mountPoint" "${command[@]}"
diff --git a/nixpkgs/nixos/modules/misc/crashdump.nix b/nixpkgs/nixos/modules/misc/crashdump.nix
index 6e0b49fa9af0..3c47e79d0512 100644
--- a/nixpkgs/nixos/modules/misc/crashdump.nix
+++ b/nixpkgs/nixos/modules/misc/crashdump.nix
@@ -58,7 +58,6 @@ in
        "crashkernel=${crashdump.reservedMemory}"
        "nmi_watchdog=panic"
        "softlockup_panic=1"
-       "idle=poll"
       ];
       kernelPatches = [ {
         name = "crashdump-config";
diff --git a/nixpkgs/nixos/modules/module-list.nix b/nixpkgs/nixos/modules/module-list.nix
index b077deb332c2..e662886ad199 100644
--- a/nixpkgs/nixos/modules/module-list.nix
+++ b/nixpkgs/nixos/modules/module-list.nix
@@ -46,6 +46,7 @@
   ./hardware/cpu/amd-microcode.nix
   ./hardware/cpu/intel-microcode.nix
   ./hardware/digitalbitbox.nix
+  ./hardware/device-tree.nix
   ./hardware/sensor/iio.nix
   ./hardware/ksm.nix
   ./hardware/ledger.nix
@@ -111,6 +112,7 @@
   ./programs/firejail.nix
   ./programs/fish.nix
   ./programs/freetds.nix
+  ./programs/fuse.nix
   ./programs/gnome-disks.nix
   ./programs/gnome-documents.nix
   ./programs/gpaste.nix
@@ -442,6 +444,7 @@
   ./services/misc/mediatomb.nix
   ./services/misc/mesos-master.nix
   ./services/misc/mesos-slave.nix
+  ./services/misc/metabase.nix
   ./services/misc/mwlib.nix
   ./services/misc/nix-daemon.nix
   ./services/misc/nix-gc.nix
diff --git a/nixpkgs/nixos/modules/profiles/hardened.nix b/nixpkgs/nixos/modules/profiles/hardened.nix
index 9e9ddd4f3788..3ff9a2b4fde0 100644
--- a/nixpkgs/nixos/modules/profiles/hardened.nix
+++ b/nixpkgs/nixos/modules/profiles/hardened.nix
@@ -44,6 +44,9 @@ with lib;
 
     # Disable legacy virtual syscalls
     "vsyscall=none"
+
+    # Enable page allocator randomization
+    "page_alloc.shuffle=1"
   ];
 
   boot.blacklistedKernelModules = [
@@ -121,4 +124,7 @@ with lib;
   # Ignore outgoing ICMP redirects (this is ipv4 only)
   boot.kernel.sysctl."net.ipv4.conf.all.send_redirects" = mkDefault false;
   boot.kernel.sysctl."net.ipv4.conf.default.send_redirects" = mkDefault false;
+
+  # Restrict userfaultfd syscalls to processes with the SYS_PTRACE capability
+  boot.kernel.sysctl."vm.unprivileged_userfaultfd" = mkDefault false;
 }
diff --git a/nixpkgs/nixos/modules/profiles/installation-device.nix b/nixpkgs/nixos/modules/profiles/installation-device.nix
index 580ea4a58e5b..1a6e06995603 100644
--- a/nixpkgs/nixos/modules/profiles/installation-device.nix
+++ b/nixpkgs/nixos/modules/profiles/installation-device.nix
@@ -32,19 +32,35 @@ with lib;
     #services.rogue.enable = true;
 
     # Disable some other stuff we don't need.
-    security.sudo.enable = mkDefault false;
     services.udisks2.enable = mkDefault false;
 
+    # Use less privileged nixos user
+    users.users.nixos = {
+      isNormalUser = true;
+      extraGroups = [ "wheel" "networkmanager" "video" ];
+      # Allow the graphical user to login without password
+      initialHashedPassword = "";
+    };
+
+    # Allow the user to log in as root without a password.
+    users.users.root.initialHashedPassword = "";
+
+    # Allow passwordless sudo from nixos user
+    security.sudo = {
+      enable = mkDefault true;
+      wheelNeedsPassword = mkForce false;
+    };
+
     # Automatically log in at the virtual consoles.
-    services.mingetty.autologinUser = "root";
+    services.mingetty.autologinUser = "nixos";
 
     # Some more help text.
     services.mingetty.helpLine =
       ''
 
-        The "root" account has an empty password.  ${
+        The "nixos" and "root" account have empty passwords.  ${
           optionalString config.services.xserver.enable
-            "Type `systemctl start display-manager' to\nstart the graphical user interface."}
+            "Type `sudo systemctl start display-manager' to\nstart the graphical user interface."}
       '';
 
     # Allow sshd to be started manually through "systemctl start sshd".
@@ -86,8 +102,5 @@ with lib;
     # because we have the firewall enabled. This makes installs from the
     # console less cumbersome if the machine has a public IP.
     networking.firewall.logRefusedConnections = mkDefault false;
-
-    # Allow the user to log in as root without a password.
-    users.users.root.initialHashedPassword = "";
   };
 }
diff --git a/nixpkgs/nixos/modules/programs/environment.nix b/nixpkgs/nixos/modules/programs/environment.nix
index 3c6d356ef998..4d762314298d 100644
--- a/nixpkgs/nixos/modules/programs/environment.nix
+++ b/nixpkgs/nixos/modules/programs/environment.nix
@@ -23,9 +23,8 @@ in
         XCURSOR_PATH = [ "$HOME/.icons" ];
       };
 
-    environment.profiles =
-      [ "$HOME/.nix-profile"
-        "/nix/var/nix/profiles/default"
+    environment.profiles = mkAfter
+      [ "/nix/var/nix/profiles/default"
         "/run/current-system/sw"
       ];
 
diff --git a/nixpkgs/nixos/modules/programs/fuse.nix b/nixpkgs/nixos/modules/programs/fuse.nix
new file mode 100644
index 000000000000..c15896efbb51
--- /dev/null
+++ b/nixpkgs/nixos/modules/programs/fuse.nix
@@ -0,0 +1,37 @@
+{ config, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.programs.fuse;
+in {
+  meta.maintainers = with maintainers; [ primeos ];
+
+  options.programs.fuse = {
+    mountMax = mkOption {
+      # In the C code it's an "int" (i.e. signed and at least 16 bit), but
+      # negative numbers obviously make no sense:
+      type = types.ints.between 0 32767; # 2^15 - 1
+      default = 1000;
+      description = ''
+        Set the maximum number of FUSE mounts allowed to non-root users.
+      '';
+    };
+
+    userAllowOther = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Allow non-root users to specify the allow_other or allow_root mount
+        options, see mount.fuse3(8).
+      '';
+    };
+  };
+
+  config =  {
+    environment.etc."fuse.conf".text = ''
+      ${optionalString (!cfg.userAllowOther) "#"}user_allow_other
+      mount_max = ${toString cfg.mountMax}
+    '';
+  };
+}
diff --git a/nixpkgs/nixos/modules/rename.nix b/nixpkgs/nixos/modules/rename.nix
index 7734209973b2..3ea139fc5ce4 100644
--- a/nixpkgs/nixos/modules/rename.nix
+++ b/nixpkgs/nixos/modules/rename.nix
@@ -225,6 +225,7 @@ with lib;
     (mkRemovedOptionModule [ "services" "mysql" "pidDir" ] "Don't wait for pidfiles, describe dependencies through systemd")
     (mkRemovedOptionModule [ "services" "mysql" "rootPassword" ] "Use socket authentication or set the password outside of the nix store.")
     (mkRemovedOptionModule [ "services" "zabbixServer" "dbPassword" ] "Use services.zabbixServer.database.passwordFile instead.")
+    (mkRemovedOptionModule [ "systemd" "generator-packages" ] "Use systemd.packages instead.")
 
     # ZSH
     (mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ])
@@ -275,7 +276,7 @@ with lib;
           throw "services.redshift.longitude is set to null, you can remove this"
           else builtins.fromJSON value))
 
-  ] ++ (flip map [ "blackboxExporter" "collectdExporter" "fritzboxExporter"
+  ] ++ (forEach [ "blackboxExporter" "collectdExporter" "fritzboxExporter"
                    "jsonExporter" "minioExporter" "nginxExporter" "nodeExporter"
                    "snmpExporter" "unifiExporter" "varnishExporter" ]
        (opt: mkRemovedOptionModule [ "services" "prometheus" "${opt}" ] ''
diff --git a/nixpkgs/nixos/modules/services/admin/oxidized.nix b/nixpkgs/nixos/modules/services/admin/oxidized.nix
index 687cdfb5ba57..39112c3970d5 100644
--- a/nixpkgs/nixos/modules/services/admin/oxidized.nix
+++ b/nixpkgs/nixos/modules/services/admin/oxidized.nix
@@ -97,8 +97,8 @@ in
 
       preStart = ''
         mkdir -p ${cfg.dataDir}/.config/oxidized
-        cp -v ${cfg.routerDB} ${cfg.dataDir}/.config/oxidized/router.db
-        cp -v ${cfg.configFile} ${cfg.dataDir}/.config/oxidized/config
+        ln -f -s ${cfg.routerDB} ${cfg.dataDir}/.config/oxidized/router.db
+        ln -f -s ${cfg.configFile} ${cfg.dataDir}/.config/oxidized/config
       '';
 
       serviceConfig = {
diff --git a/nixpkgs/nixos/modules/services/backup/automysqlbackup.nix b/nixpkgs/nixos/modules/services/backup/automysqlbackup.nix
index b845f370fb70..1884f3536a97 100644
--- a/nixpkgs/nixos/modules/services/backup/automysqlbackup.nix
+++ b/nixpkgs/nixos/modules/services/backup/automysqlbackup.nix
@@ -41,7 +41,7 @@ in
       };
 
       config = mkOption {
-        type = with types; attrsOf (either (either str (either int bool)) (listOf str));
+        type = with types; attrsOf (oneOf [ str int bool (listOf str) ]);
         default = {};
         description = ''
           automysqlbackup configuration. Refer to
diff --git a/nixpkgs/nixos/modules/services/databases/memcached.nix b/nixpkgs/nixos/modules/services/databases/memcached.nix
index 052ff1f308eb..f9e403dfc0c2 100644
--- a/nixpkgs/nixos/modules/services/databases/memcached.nix
+++ b/nixpkgs/nixos/modules/services/databases/memcached.nix
@@ -86,7 +86,25 @@ in
         in "${memcached}/bin/memcached ${networking} -m ${toString cfg.maxMemory} -c ${toString cfg.maxConnections} ${concatStringsSep " " cfg.extraOptions}";
 
         User = cfg.user;
+
+        # Filesystem access
+        ProtectSystem = "strict";
+        ProtectHome = true;
+        PrivateTmp = true;
+        PrivateDevices = true;
+        ProtectKernelTunables = true;
+        ProtectKernelModules = true;
+        ProtectControlGroups = true;
         RuntimeDirectory = "memcached";
+        # Caps
+        CapabilityBoundingSet = "";
+        NoNewPrivileges = true;
+        # Misc.
+        LockPersonality = true;
+        RestrictRealtime = true;
+        PrivateMounts = true;
+        PrivateUsers = true;
+        MemoryDenyWriteExecute = true;
       };
     };
   };
diff --git a/nixpkgs/nixos/modules/services/desktops/flatpak.nix b/nixpkgs/nixos/modules/services/desktops/flatpak.nix
index 1492d855aa03..7fb0024f37dc 100644
--- a/nixpkgs/nixos/modules/services/desktops/flatpak.nix
+++ b/nixpkgs/nixos/modules/services/desktops/flatpak.nix
@@ -38,5 +38,16 @@ in {
       "$HOME/.local/share/flatpak/exports"
       "/var/lib/flatpak/exports"
     ];
+
+    # It has been possible since https://github.com/flatpak/flatpak/releases/tag/1.3.2
+    # to build a SELinux policy module.
+
+    users.users.flatpak = {
+      description = "Flatpak system helper";
+      group = "flatpak";
+      isSystemUser = true;
+    };
+
+    users.groups.flatpak = { };
   };
 }
diff --git a/nixpkgs/nixos/modules/services/editors/emacs.xml b/nixpkgs/nixos/modules/services/editors/emacs.xml
index a3041ae22e78..acd69f18376c 100644
--- a/nixpkgs/nixos/modules/services/editors/emacs.xml
+++ b/nixpkgs/nixos/modules/services/editors/emacs.xml
@@ -552,7 +552,7 @@ emacsclient --create-frame --tty  # opens a new frame on the current terminal
     <xref linkend="opt-environment.systemPackages"/>
     (<link
       linkend="sec-declarative-package-mgmt">NixOS</link>), or run
-    <literal>nix-env -i pkgs.docbook5</literal>
+    <literal>nix-env -f '&lt;nixpkgs&gt;' -iA docbook5</literal>
     (<link linkend="sec-ad-hoc-packages">Nix</link>).
    </para>
 
diff --git a/nixpkgs/nixos/modules/services/games/minecraft-server.nix b/nixpkgs/nixos/modules/services/games/minecraft-server.nix
index 39a68f4b5536..eb9288fca586 100644
--- a/nixpkgs/nixos/modules/services/games/minecraft-server.nix
+++ b/nixpkgs/nixos/modules/services/games/minecraft-server.nix
@@ -118,7 +118,7 @@ in {
       };
 
       serverProperties = mkOption {
-        type = with types; attrsOf (either bool (either int str));
+        type = with types; attrsOf (oneOf [ bool int str ]);
         default = {};
         example = literalExample ''
           {
diff --git a/nixpkgs/nixos/modules/services/mail/davmail.nix b/nixpkgs/nixos/modules/services/mail/davmail.nix
index 5b5cc294e5c7..374a3dd75c1c 100644
--- a/nixpkgs/nixos/modules/services/mail/davmail.nix
+++ b/nixpkgs/nixos/modules/services/mail/davmail.nix
@@ -7,7 +7,7 @@ let
   cfg = config.services.davmail;
 
   configType = with types;
-    either (either (attrsOf configType) str) (either int bool) // {
+    oneOf [ (attrsOf configType) str int bool ] // {
       description = "davmail config type (str, int, bool or attribute set thereof)";
     };
 
diff --git a/nixpkgs/nixos/modules/services/mail/postfix.nix b/nixpkgs/nixos/modules/services/mail/postfix.nix
index dab1b29aa4be..2b08ab1e6aa6 100644
--- a/nixpkgs/nixos/modules/services/mail/postfix.nix
+++ b/nixpkgs/nixos/modules/services/mail/postfix.nix
@@ -447,7 +447,7 @@ in
       };
 
       config = mkOption {
-        type = with types; attrsOf (either bool (either str (listOf str)));
+        type = with types; attrsOf (oneOf [ bool str (listOf str) ]);
         description = ''
           The main.cf configuration file as key value set.
         '';
diff --git a/nixpkgs/nixos/modules/services/mail/rspamd.nix b/nixpkgs/nixos/modules/services/mail/rspamd.nix
index 5541b8b79b7e..e59d5715de05 100644
--- a/nixpkgs/nixos/modules/services/mail/rspamd.nix
+++ b/nixpkgs/nixos/modules/services/mail/rspamd.nix
@@ -331,7 +331,7 @@ in
         };
 
         config = mkOption {
-          type = with types; attrsOf (either bool (either str (listOf str)));
+          type = with types; attrsOf (oneOf [ bool str (listOf str) ]);
           description = ''
             Addon to postfix configuration
           '';
diff --git a/nixpkgs/nixos/modules/services/mail/rss2email.nix b/nixpkgs/nixos/modules/services/mail/rss2email.nix
index a123736005ab..df454abc8267 100644
--- a/nixpkgs/nixos/modules/services/mail/rss2email.nix
+++ b/nixpkgs/nixos/modules/services/mail/rss2email.nix
@@ -30,7 +30,7 @@ in {
       };
 
       config = mkOption {
-        type = with types; attrsOf (either str (either int bool));
+        type = with types; attrsOf (oneOf [ str int bool ]);
         default = {};
         description = ''
           The configuration to give rss2email.
diff --git a/nixpkgs/nixos/modules/services/misc/gitlab.nix b/nixpkgs/nixos/modules/services/misc/gitlab.nix
index 087630f21776..09c3a89d6a68 100644
--- a/nixpkgs/nixos/modules/services/misc/gitlab.nix
+++ b/nixpkgs/nixos/modules/services/misc/gitlab.nix
@@ -659,7 +659,7 @@ in {
         fi
 
         # We remove potentially broken links to old gitlab-shell versions
-        rm -f ${cfg.statePath}/repositories/**/*.git/hooks
+        rm -Rf ${cfg.statePath}/repositories/**/*.git/hooks
 
         ${pkgs.sudo}/bin/sudo -u ${cfg.user} -H ${pkgs.git}/bin/git config --global core.autocrlf "input"
       '';
diff --git a/nixpkgs/nixos/modules/services/misc/matrix-synapse.nix b/nixpkgs/nixos/modules/services/misc/matrix-synapse.nix
index 00c8e7408030..3eb649b08a2f 100644
--- a/nixpkgs/nixos/modules/services/misc/matrix-synapse.nix
+++ b/nixpkgs/nixos/modules/services/misc/matrix-synapse.nix
@@ -684,7 +684,7 @@ in {
         fi
       '';
       serviceConfig = {
-        Type = "simple";
+        Type = "notify";
         User = "matrix-synapse";
         Group = "matrix-synapse";
         WorkingDirectory = cfg.dataDir;
diff --git a/nixpkgs/nixos/modules/services/misc/metabase.nix b/nixpkgs/nixos/modules/services/misc/metabase.nix
new file mode 100644
index 000000000000..e78100a046a2
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/misc/metabase.nix
@@ -0,0 +1,103 @@
+{ config, lib, pkgs, ... }:
+
+let
+  cfg = config.services.metabase;
+
+  inherit (lib) mkEnableOption mkIf mkOption;
+  inherit (lib) optional optionalAttrs types;
+
+  dataDir = "/var/lib/metabase";
+
+in {
+
+  options = {
+
+    services.metabase = {
+      enable = mkEnableOption "Metabase service";
+
+      listen = {
+        ip = mkOption {
+          type = types.str;
+          default = "0.0.0.0";
+          description = ''
+            IP address that Metabase should listen on.
+          '';
+        };
+
+        port = mkOption {
+          type = types.port;
+          default = 3000;
+          description = ''
+            Listen port for Metabase.
+          '';
+        };
+      };
+
+      ssl = {
+        enable = mkOption {
+          type = types.bool;
+          default = false;
+          description = ''
+            Whether to enable SSL (https) support.
+          '';
+        };
+
+        port = mkOption {
+          type = types.port;
+          default = 8443;
+          description = ''
+            Listen port over SSL (https) for Metabase.
+          '';
+        };
+
+        keystore = mkOption {
+          type = types.nullOr types.path;
+          default = "${dataDir}/metabase.jks";
+          example = "/etc/secrets/keystore.jks";
+          description = ''
+            <link xlink:href="https://www.digitalocean.com/community/tutorials/java-keytool-essentials-working-with-java-keystores">Java KeyStore</link> file containing the certificates.
+          '';
+        };
+
+      };
+
+      openFirewall = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Open ports in the firewall for Metabase.
+        '';
+      };
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+
+    systemd.services.metabase = {
+      description = "Metabase server";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network-online.target" ];
+      environment = {
+        MB_PLUGINS_DIR = "${dataDir}/plugins";
+        MB_DB_FILE = "${dataDir}/metabase.db";
+        MB_JETTY_HOST = cfg.listen.ip;
+        MB_JETTY_PORT = toString cfg.listen.port;
+      } // optionalAttrs (cfg.ssl.enable) {
+        MB_JETTY_SSL = true;
+        MB_JETTY_SSL_PORT = toString cfg.ssl.port;
+        MB_JETTY_SSL_KEYSTORE = cfg.ssl.keystore;
+      };
+      serviceConfig = {
+        DynamicUser = true;
+        StateDirectory = baseNameOf dataDir;
+        ExecStart = "${pkgs.metabase}/bin/metabase";
+      };
+    };
+
+    networking.firewall = mkIf cfg.openFirewall {
+      allowedTCPPorts = [ cfg.listen.port ] ++ optional cfg.ssl.enable cfg.ssl.port;
+    };
+
+  };
+}
diff --git a/nixpkgs/nixos/modules/services/monitoring/cadvisor.nix b/nixpkgs/nixos/modules/services/monitoring/cadvisor.nix
index 6ca420a05b23..695a8c42e85e 100644
--- a/nixpkgs/nixos/modules/services/monitoring/cadvisor.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/cadvisor.nix
@@ -84,6 +84,16 @@ in {
         type = types.bool;
         description = "Cadvisor storage driver, enable secure communication.";
       };
+
+      extraOptions = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        description = ''
+          Additional cadvisor options.
+          
+          See <link xlink:href='https://github.com/google/cadvisor/blob/master/docs/runtime_options.md'/> for available options.
+        '';
+      };
     };
   };
 
@@ -112,6 +122,7 @@ in {
             -logtostderr=true \
             -listen_ip="${cfg.listenAddress}" \
             -port="${toString cfg.port}" \
+            ${escapeShellArgs cfg.extraOptions} \
             ${optionalString (cfg.storageDriver != null) ''
               -storage_driver "${cfg.storageDriver}" \
               -storage_driver_user "${cfg.storageDriverHost}" \
diff --git a/nixpkgs/nixos/modules/services/monitoring/loki.nix b/nixpkgs/nixos/modules/services/monitoring/loki.nix
index 4d11360d07e9..f4eec7e0d284 100644
--- a/nixpkgs/nixos/modules/services/monitoring/loki.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/loki.nix
@@ -103,7 +103,7 @@ in {
         PrivateTmp = true;
         ProtectHome = true;
         ProtectSystem = "full";
-        DecvicePolicy = "closed";
+        DevicePolicy = "closed";
         NoNewPrivileges = true;
         WorkingDirectory = cfg.dataDir;
       };
diff --git a/nixpkgs/nixos/modules/services/monitoring/riemann-tools.nix b/nixpkgs/nixos/modules/services/monitoring/riemann-tools.nix
index 9c400a1e3e46..2b647b6b1ade 100644
--- a/nixpkgs/nixos/modules/services/monitoring/riemann-tools.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/riemann-tools.nix
@@ -11,7 +11,7 @@ let
 
   healthLauncher = writeScriptBin "riemann-health" ''
     #!/bin/sh
-    exec ${pkgs.riemann-tools}/bin/riemann-health --host ${riemannHost}
+    exec ${pkgs.riemann-tools}/bin/riemann-health ${builtins.concatStringsSep " " cfg.extraArgs} --host ${riemannHost}
   '';
 
 
@@ -34,8 +34,16 @@ in {
           Address of the host riemann node. Defaults to localhost.
         '';
       };
+      extraArgs = mkOption {
+        type = types.listOf types.string;
+        default = [];
+        description = ''
+          A list of commandline-switches forwarded to a riemann-tool.
+          See for example `riemann-health --help` for available options.
+        '';
+        example = ["-p 5555" "--timeout=30" "--attribute=myattribute=42"];
+      };
     };
-
   };
 
   config = mkIf cfg.enableHealth {
diff --git a/nixpkgs/nixos/modules/services/monitoring/ups.nix b/nixpkgs/nixos/modules/services/monitoring/ups.nix
index bc755612fd9b..429b40227d47 100644
--- a/nixpkgs/nixos/modules/services/monitoring/ups.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/ups.nix
@@ -225,7 +225,7 @@ in
         ''
           maxstartdelay = ${toString cfg.maxStartDelay}
 
-          ${flip concatStringsSep (flip map (attrValues cfg.ups) (ups: ups.summary)) "
+          ${flip concatStringsSep (forEach (attrValues cfg.ups) (ups: ups.summary)) "
 
           "}
         '';
diff --git a/nixpkgs/nixos/modules/services/monitoring/zabbix-proxy.nix b/nixpkgs/nixos/modules/services/monitoring/zabbix-proxy.nix
index 9cfcd1697c11..90abed30db5d 100644
--- a/nixpkgs/nixos/modules/services/monitoring/zabbix-proxy.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/zabbix-proxy.nix
@@ -120,7 +120,8 @@ in
 
         name = mkOption {
           type = types.str;
-          default = "zabbix";
+          default = if cfg.database.type == "sqlite" then "${stateDir}/zabbix.db" else "zabbix";
+          defaultText = "zabbix";
           description = "Database name.";
         };
 
@@ -261,17 +262,17 @@ in
       preStart = optionalString pgsqlLocal ''
         if ! test -e "${stateDir}/db-created"; then
           cat ${cfg.package}/share/zabbix/database/postgresql/schema.sql | ${pgsql.package}/bin/psql ${cfg.database.name}
-          cat ${cfg.package}/share/zabbix/database/postgresql/images.sql | ${pgsql.package}/bin/psql ${cfg.database.name}
-          cat ${cfg.package}/share/zabbix/database/postgresql/data.sql | ${pgsql.package}/bin/psql ${cfg.database.name}
           touch "${stateDir}/db-created"
         fi
       '' + optionalString mysqlLocal ''
         if ! test -e "${stateDir}/db-created"; then
           cat ${cfg.package}/share/zabbix/database/mysql/schema.sql | ${mysql.package}/bin/mysql ${cfg.database.name}
-          cat ${cfg.package}/share/zabbix/database/mysql/images.sql | ${mysql.package}/bin/mysql ${cfg.database.name}
-          cat ${cfg.package}/share/zabbix/database/mysql/data.sql | ${mysql.package}/bin/mysql ${cfg.database.name}
           touch "${stateDir}/db-created"
         fi
+      '' + optionalString (cfg.database.type == "sqlite") ''
+        if ! test -e "${cfg.database.name}"; then
+          ${pkgs.sqlite}/bin/sqlite3 "${cfg.database.name}" < ${cfg.package}/share/zabbix/database/sqlite3/schema.sql
+        fi
       '' + optionalString (cfg.database.passwordFile != null) ''
         # create a copy of the supplied password file in a format zabbix can consume
         touch ${passwordFile}
diff --git a/nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix b/nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix
index f19bf9d81396..bbbfcf6a4738 100644
--- a/nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix
+++ b/nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix
@@ -208,9 +208,9 @@ in {
 
   config = mkIf cfg.enable {
     environment.systemPackages = [ wrapped ];
-    environment.etc."fuse.conf" = mkIf cfg.autoMount { text = ''
-      user_allow_other
-    ''; };
+    programs.fuse = mkIf cfg.autoMount {
+      userAllowOther = true;
+    };
 
     users.users = mkIf (cfg.user == "ipfs") {
       ipfs = {
diff --git a/nixpkgs/nixos/modules/services/networking/cjdns.nix b/nixpkgs/nixos/modules/services/networking/cjdns.nix
index c40962f4aa82..3fb85b16cbe2 100644
--- a/nixpkgs/nixos/modules/services/networking/cjdns.nix
+++ b/nixpkgs/nixos/modules/services/networking/cjdns.nix
@@ -44,9 +44,7 @@ let
   parseModules = x:
     x // { connectTo = mapAttrs (name: value: { inherit (value) password publicKey; }) x.connectTo; };
 
-  # would be nice to  merge 'cfg' with a //,
-  # but the json nesting is wacky.
-  cjdrouteConf = builtins.toJSON ( {
+  cjdrouteConf = builtins.toJSON ( recursiveUpdate {
     admin = {
       bind = cfg.admin.bind;
       password = "@CJDNS_ADMIN_PASSWORD@";
@@ -71,7 +69,7 @@ let
 
     security = [ { exemptAngel = 1; setuser = "nobody"; } ];
 
-  });
+  } cfg.extraConfig);
 
 in
 
@@ -91,6 +89,16 @@ in
         '';
       };
 
+      extraConfig = mkOption {
+        type = types.attrs;
+        default = {};
+        example = { router.interface.tunDevice = "tun10"; };
+        description = ''
+          Extra configuration, given as attrs, that will be merged recursively
+          with the rest of the JSON generated by this module, at the root node.
+        '';
+      };
+
       confFile = mkOption {
         type = types.nullOr types.path;
         default = null;
@@ -246,7 +254,10 @@ in
         if cfg.confFile != null then "${pkg}/bin/cjdroute < ${cfg.confFile}" else
           ''
             source /etc/cjdns.keys
-            echo '${cjdrouteConf}' | sed \
+            (cat <<'EOF'
+            ${cjdrouteConf}
+            EOF
+            ) | sed \
                 -e "s/@CJDNS_ADMIN_PASSWORD@/$CJDNS_ADMIN_PASSWORD/g" \
                 -e "s/@CJDNS_PRIVATE_KEY@/$CJDNS_PRIVATE_KEY/g" \
                 | ${pkg}/bin/cjdroute
diff --git a/nixpkgs/nixos/modules/services/networking/consul.nix b/nixpkgs/nixos/modules/services/networking/consul.nix
index 3a92a883fbf8..f080f12eaccd 100644
--- a/nixpkgs/nixos/modules/services/networking/consul.nix
+++ b/nixpkgs/nixos/modules/services/networking/consul.nix
@@ -15,7 +15,7 @@ let
     ++ cfg.extraConfigFiles;
 
   devices = attrValues (filterAttrs (_: i: i != null) cfg.interface);
-  systemdDevices = flip map devices
+  systemdDevices = forEach devices
     (i: "sys-subsystem-net-devices-${utils.escapeSystemdPath i}.device");
 in
 {
diff --git a/nixpkgs/nixos/modules/services/networking/hylafax/systemd.nix b/nixpkgs/nixos/modules/services/networking/hylafax/systemd.nix
index ef177e4be345..0c6602e7f8ab 100644
--- a/nixpkgs/nixos/modules/services/networking/hylafax/systemd.nix
+++ b/nixpkgs/nixos/modules/services/networking/hylafax/systemd.nix
@@ -7,7 +7,7 @@ let
   inherit (lib) concatStringsSep optionalString;
 
   cfg = config.services.hylafax;
-  mapModems = lib.flip map (lib.attrValues cfg.modems);
+  mapModems = lib.forEach (lib.attrValues cfg.modems);
 
   mkConfigFile = name: conf:
     # creates hylafax config file,
diff --git a/nixpkgs/nixos/modules/services/networking/shadowsocks.nix b/nixpkgs/nixos/modules/services/networking/shadowsocks.nix
index fe6d65a5f963..af12db590f00 100644
--- a/nixpkgs/nixos/modules/services/networking/shadowsocks.nix
+++ b/nixpkgs/nixos/modules/services/networking/shadowsocks.nix
@@ -35,10 +35,10 @@ in
       };
 
       localAddress = mkOption {
-        type = types.str;
-        default = "0.0.0.0";
+        type = types.coercedTo types.str singleton (types.listOf types.str);
+        default = [ "[::0]" "0.0.0.0" ];
         description = ''
-          Local address to which the server binds.
+          Local addresses to which the server binds.
         '';
       };
 
diff --git a/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix b/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
index 0f9d2420903b..91fc7d72bc6d 100644
--- a/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
@@ -502,7 +502,7 @@ in
 
     assertions = [{ assertion = if cfg.forwardX11 then cfgc.setXAuthLocation else true;
                     message = "cannot enable X11 forwarding without setting xauth location";}]
-      ++ flip map cfg.listenAddresses ({ addr, ... }: {
+      ++ forEach cfg.listenAddresses ({ addr, ... }: {
         assertion = addr != null;
         message = "addr must be specified in each listenAddresses entry";
       });
diff --git a/nixpkgs/nixos/modules/services/networking/znc/default.nix b/nixpkgs/nixos/modules/services/networking/znc/default.nix
index 46bff6954cdd..05f97bfa539f 100644
--- a/nixpkgs/nixos/modules/services/networking/znc/default.nix
+++ b/nixpkgs/nixos/modules/services/networking/znc/default.nix
@@ -62,9 +62,9 @@ let
       concatStringsSep "\n" (toLines cfg.config);
 
   semanticTypes = with types; rec {
-    zncAtom = nullOr (either (either int bool) str);
+    zncAtom = nullOr (oneOf [ int bool str ]);
     zncAttr = attrsOf (nullOr zncConf);
-    zncAll = either (either zncAtom (listOf zncAtom)) zncAttr;
+    zncAll = oneOf [ zncAtom (listOf zncAtom) zncAttr ];
     zncConf = attrsOf (zncAll // {
       # Since this is a recursive type and the description by default contains
       # the description of its subtypes, infinite recursion would occur without
diff --git a/nixpkgs/nixos/modules/services/printing/cupsd.nix b/nixpkgs/nixos/modules/services/printing/cupsd.nix
index 86b0c8d69beb..42c1b9482cb2 100644
--- a/nixpkgs/nixos/modules/services/printing/cupsd.nix
+++ b/nixpkgs/nixos/modules/services/printing/cupsd.nix
@@ -127,7 +127,7 @@ in
 
       startWhenNeeded = mkOption {
         type = types.bool;
-        default = false;
+        default = true;
         description = ''
           If set, CUPS is socket-activated; that is,
           instead of having it permanently running as a daemon,
@@ -296,11 +296,16 @@ in
     # gets loaded, and then cups cannot access the printers.
     boot.blacklistedKernelModules = [ "usblp" ];
 
+    # Some programs like print-manager rely on this value to get
+    # printer test pages.
+    environment.sessionVariables.CUPS_DATADIR = "${bindir}/share/cups";
+
     systemd.packages = [ cups.out ];
 
     systemd.sockets.cups = mkIf cfg.startWhenNeeded {
       wantedBy = [ "sockets.target" ];
-      listenStreams = map (x: replaceStrings ["localhost"] ["127.0.0.1"] (removePrefix "*:" x)) cfg.listenAddresses;
+      listenStreams = [ "/run/cups/cups.sock" ]
+        ++ map (x: replaceStrings ["localhost"] ["127.0.0.1"] (removePrefix "*:" x)) cfg.listenAddresses;
     };
 
     systemd.services.cups =
@@ -362,10 +367,10 @@ in
       { description = "CUPS Remote Printer Discovery";
 
         wantedBy = [ "multi-user.target" ];
-        wants = [ "cups.service" "avahi-daemon.service" ];
-        bindsTo = [ "cups.service" "avahi-daemon.service" ];
-        partOf = [ "cups.service" "avahi-daemon.service" ];
-        after = [ "cups.service" "avahi-daemon.service" ];
+        wants = [ "avahi-daemon.service" ] ++ optional (!cfg.startWhenNeeded) "cups.service";
+        bindsTo = [ "avahi-daemon.service" ] ++ optional (!cfg.startWhenNeeded) "cups.service";
+        partOf = [ "avahi-daemon.service" ] ++ optional (!cfg.startWhenNeeded) "cups.service";
+        after = [ "avahi-daemon.service" ] ++ optional (!cfg.startWhenNeeded) "cups.service";
 
         path = [ cups ];
 
@@ -421,4 +426,7 @@ in
     security.pam.services.cups = {};
 
   };
+
+  meta.maintainers = with lib.maintainers; [ matthewbauer ];
+
 }
diff --git a/nixpkgs/nixos/modules/services/search/elasticsearch.nix b/nixpkgs/nixos/modules/services/search/elasticsearch.nix
index 6b688c640d59..91d8f544e16b 100644
--- a/nixpkgs/nixos/modules/services/search/elasticsearch.nix
+++ b/nixpkgs/nixos/modules/services/search/elasticsearch.nix
@@ -131,6 +131,7 @@ in {
       description = "Extra elasticsearch plugins";
       default = [];
       type = types.listOf types.package;
+      example = lib.literalExample "[ pkgs.elasticsearchPlugins.discovery-ec2 ]";
     };
 
   };
diff --git a/nixpkgs/nixos/modules/services/security/bitwarden_rs/default.nix b/nixpkgs/nixos/modules/services/security/bitwarden_rs/default.nix
index bb036ee020f4..80fd65891ff8 100644
--- a/nixpkgs/nixos/modules/services/security/bitwarden_rs/default.nix
+++ b/nixpkgs/nixos/modules/services/security/bitwarden_rs/default.nix
@@ -36,7 +36,7 @@ in {
     };
 
     config = mkOption {
-      type = attrsOf (nullOr (either (either bool int) str));
+      type = attrsOf (nullOr (oneOf [ bool int str ]));
       default = {};
       example = literalExample ''
         {
diff --git a/nixpkgs/nixos/modules/services/web-apps/limesurvey.nix b/nixpkgs/nixos/modules/services/web-apps/limesurvey.nix
index 5b2f3875aaa9..84a94fc446e5 100644
--- a/nixpkgs/nixos/modules/services/web-apps/limesurvey.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/limesurvey.nix
@@ -14,7 +14,7 @@ let
 
   pkg = pkgs.limesurvey;
 
-  configType = with types; either (either (attrsOf configType) str) (either int bool) // {
+  configType = with types; oneOf [ (attrsOf configType) str int bool ] // {
     description = "limesurvey config type (str, int, bool or attribute set thereof)";
   };
 
diff --git a/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
index ea9476a7c915..12200c879beb 100644
--- a/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
@@ -336,7 +336,7 @@ let
           ++ optional enablePerl { name = "perl"; path = "${mod_perl}/modules/mod_perl.so"; }
           ++ concatMap (svc: svc.extraModules) allSubservices
           ++ extraForeignModules;
-      in concatMapStrings load allModules
+      in concatMapStrings load (unique allModules)
     }
 
     AddHandler type-map var
diff --git a/nixpkgs/nixos/modules/services/web-servers/caddy.nix b/nixpkgs/nixos/modules/services/web-servers/caddy.nix
index d0b936cb019f..6a1db6087840 100644
--- a/nixpkgs/nixos/modules/services/web-servers/caddy.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/caddy.nix
@@ -70,7 +70,7 @@ in {
         { CADDYPATH = cfg.dataDir; };
       serviceConfig = {
         ExecStart = ''
-          ${cfg.package.bin}/bin/caddy -root=/var/tmp -conf=${configFile} \
+          ${cfg.package}/bin/caddy -root=/var/tmp -conf=${configFile} \
             -ca=${cfg.ca} -email=${cfg.email} ${optionalString cfg.agree "-agree"}
         '';
         ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
diff --git a/nixpkgs/nixos/modules/services/x11/compton.nix b/nixpkgs/nixos/modules/services/x11/compton.nix
index c02c9bfd94e8..a94a76ff0c0f 100644
--- a/nixpkgs/nixos/modules/services/x11/compton.nix
+++ b/nixpkgs/nixos/modules/services/x11/compton.nix
@@ -215,7 +215,7 @@ in {
     };
 
     settings = let
-      configTypes = with types; either bool (either int (either float str));
+      configTypes = with types; oneOf [ bool int float str ];
       # types.loaOf converts lists to sets
       loaOf = t: with types; either (listOf t) (attrsOf t);
     in mkOption {
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
index 5e1e652a5089..cbfd2d3c2ea2 100644
--- a/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -15,12 +15,16 @@ let
     '';
   };
 
-  nixos-gsettings-desktop-schemas = pkgs.runCommand "nixos-gsettings-desktop-schemas" { preferLocalBuild = true; }
+  nixos-gsettings-desktop-schemas = let
+    defaultPackages = with pkgs; [ gsettings-desktop-schemas gnome3.gnome-shell ];
+  in
+  pkgs.runCommand "nixos-gsettings-desktop-schemas" { preferLocalBuild = true; }
     ''
      mkdir -p $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
-     cp -rf ${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/gsettings-desktop-schemas*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
 
-     ${concatMapStrings (pkg: "cp -rf ${pkg}/share/gsettings-schemas/*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas\n") cfg.extraGSettingsOverridePackages}
+     ${concatMapStrings
+        (pkg: "cp -rf ${pkg}/share/gsettings-schemas/*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas\n")
+        (defaultPackages ++ cfg.extraGSettingsOverridePackages)}
 
      chmod -R a+w $out/share/gsettings-schemas/nixos-gsettings-overrides
      cat - > $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas/nixos-defaults.gschema.override <<- EOF
@@ -30,6 +34,9 @@ let
        [org.gnome.desktop.screensaver]
        picture-uri='${pkgs.nixos-artwork.wallpapers.simple-dark-gray-bottom}/share/artwork/gnome/nix-wallpaper-simple-dark-gray_bottom.png'
 
+       [org.gnome.shell]
+       favorite-apps=[ 'org.gnome.Epiphany.desktop', 'evolution.desktop', 'org.gnome.Music.desktop', 'org.gnome.Photos.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]
+
        ${cfg.extraGSettingsOverrides}
      EOF
 
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
index 8e1272f3c92b..f0cafc377585 100644
--- a/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
@@ -123,11 +123,9 @@ in
     ];
     services.pantheon.contractor.enable = mkDefault true;
     services.gnome3.at-spi2-core.enable = true;
-    services.gnome3.evince.enable = mkDefault true;
     services.gnome3.evolution-data-server.enable = true;
-    services.gnome3.file-roller.enable = mkDefault true;
-    # TODO: gnome-keyring's xdg autostarts will still be in the environment (from elementary-session-settings) if disabled forcefully
     services.gnome3.glib-networking.enable = true;
+    # TODO: gnome-keyring's xdg autostarts will still be in the environment (from elementary-session-settings) if disabled forcefully
     services.gnome3.gnome-keyring.enable = true;
     services.gnome3.gnome-settings-daemon.enable = true;
     services.gnome3.gnome-settings-daemon.package = pkgs.pantheon.elementary-settings-daemon;
@@ -140,7 +138,6 @@ in
     services.xserver.libinput.enable = mkDefault true;
     services.xserver.updateDbusEnvironment = true;
     services.zeitgeist.enable = mkDefault true;
-
     services.geoclue2.enable = mkDefault true;
     # pantheon has pantheon-agent-geoclue2
     services.geoclue2.enableDemoAgent = false;
@@ -149,6 +146,9 @@ in
       isSystem = true;
     };
 
+    programs.evince.enable = mkDefault true;
+    programs.file-roller.enable = mkDefault true;
+
     networking.networkmanager.enable = mkDefault true;
     networking.networkmanager.basePackages =
       { inherit (pkgs) networkmanager modemmanager wpa_supplicant crda;
diff --git a/nixpkgs/nixos/modules/services/x11/xautolock.nix b/nixpkgs/nixos/modules/services/x11/xautolock.nix
index cbe000058dc6..10eef8aefbcd 100644
--- a/nixpkgs/nixos/modules/services/x11/xautolock.nix
+++ b/nixpkgs/nixos/modules/services/x11/xautolock.nix
@@ -129,7 +129,7 @@ in
           assertion = cfg.killer != null -> cfg.killtime >= 10;
           message = "killtime has to be at least 10 minutes according to `man xautolock`";
         }
-      ] ++ (lib.flip map [ "locker" "notifier" "nowlocker" "killer" ]
+      ] ++ (lib.forEach [ "locker" "notifier" "nowlocker" "killer" ]
         (option:
         {
           assertion = cfg."${option}" != null -> builtins.substring 0 1 cfg."${option}" == "/";
diff --git a/nixpkgs/nixos/modules/services/x11/xserver.nix b/nixpkgs/nixos/modules/services/x11/xserver.nix
index b1a316706976..c94a06438315 100644
--- a/nixpkgs/nixos/modules/services/x11/xserver.nix
+++ b/nixpkgs/nixos/modules/services/x11/xserver.nix
@@ -78,7 +78,7 @@ let
   in imap1 mkHead cfg.xrandrHeads;
 
   xrandrDeviceSection = let
-    monitors = flip map xrandrHeads (h: ''
+    monitors = forEach xrandrHeads (h: ''
       Option "monitor-${h.config.output}" "${h.name}"
     '');
     # First option is indented through the space in the config but any
@@ -714,7 +714,7 @@ in
       nativeBuildInputs = [ pkgs.xkbvalidate ];
       preferLocalBuild = true;
     } ''
-      validate "$xkbModel" "$layout" "$xkbVariant" "$xkbOptions"
+      xkbvalidate "$xkbModel" "$layout" "$xkbVariant" "$xkbOptions"
       touch "$out"
     '');
 
diff --git a/nixpkgs/nixos/modules/system/activation/top-level.nix b/nixpkgs/nixos/modules/system/activation/top-level.nix
index 5c88d27b6c65..f67d29005616 100644
--- a/nixpkgs/nixos/modules/system/activation/top-level.nix
+++ b/nixpkgs/nixos/modules/system/activation/top-level.nix
@@ -46,8 +46,8 @@ let
 
         ln -s ${kernelPath} $out/kernel
         ln -s ${config.system.modulesTree} $out/kernel-modules
-        ${optionalString (pkgs.stdenv.hostPlatform.platform.kernelDTB or false) ''
-          ln -s ${config.boot.kernelPackages.kernel}/dtbs $out/dtbs
+        ${optionalString (config.hardware.deviceTree.package != null) ''
+          ln -s ${config.hardware.deviceTree.package} $out/dtbs
         ''}
 
         echo -n "$kernelParams" > $out/kernel-params
diff --git a/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh b/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh
index c780a89b102c..0092ee92b62f 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh
+++ b/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh
@@ -75,9 +75,8 @@ addEntry() {
 
     copyToKernelsDir "$path/kernel"; kernel=$result
     copyToKernelsDir "$path/initrd"; initrd=$result
-    # XXX UGLY: maybe the system config should have a top-level "dtbs" entry?
-    dtbDir=$(readlink -m "$path/kernel/../dtbs")
-    if [ -d "$dtbDir" ]; then
+    dtbDir=$(readlink -m "$path/dtbs")
+    if [ -e "$dtbDir" ]; then
         copyToKernelsDir "$dtbDir"; dtbs=$result
     fi
 
diff --git a/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix b/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix
index 4e4d14985b0d..eca9dad64222 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix
@@ -684,7 +684,7 @@ in
           assertion = if args.efiSysMountPoint == null then true else hasPrefix "/" args.efiSysMountPoint;
           message = "EFI paths must be absolute, not ${args.efiSysMountPoint}";
         }
-      ] ++ flip map args.devices (device: {
+      ] ++ forEach args.devices (device: {
         assertion = device == "nodev" || hasPrefix "/" device;
         message = "GRUB devices must be absolute paths, not ${device} in ${args.path}";
       }));
diff --git a/nixpkgs/nixos/modules/system/boot/networkd.nix b/nixpkgs/nixos/modules/system/boot/networkd.nix
index f1aa9064bef4..d6b446e9ac22 100644
--- a/nixpkgs/nixos/modules/system/boot/networkd.nix
+++ b/nixpkgs/nixos/modules/system/boot/networkd.nix
@@ -10,7 +10,7 @@ let
 
   checkLink = checkUnitConfig "Link" [
     (assertOnlyFields [
-      "Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "Name"
+      "Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "OriginalName"
       "MTUBytes" "BitsPerSecond" "Duplex" "AutoNegotiation" "WakeOnLan" "Port"
       "TCPSegmentationOffload" "TCP6SegmentationOffload" "GenericSegmentationOffload"
       "GenericReceiveOffload" "LargeReceiveOffload" "RxChannels" "TxChannels"
diff --git a/nixpkgs/nixos/modules/system/boot/stage-1.nix b/nixpkgs/nixos/modules/system/boot/stage-1.nix
index 788e3f4a2ab1..4c2d130d5a5d 100644
--- a/nixpkgs/nixos/modules/system/boot/stage-1.nix
+++ b/nixpkgs/nixos/modules/system/boot/stage-1.nix
@@ -217,13 +217,11 @@ let
             --replace ata_id ${extraUtils}/bin/ata_id \
             --replace scsi_id ${extraUtils}/bin/scsi_id \
             --replace cdrom_id ${extraUtils}/bin/cdrom_id \
-            --replace ${pkgs.utillinux}/sbin/blkid ${extraUtils}/bin/blkid \
-            --replace /sbin/blkid ${extraUtils}/bin/blkid \
+            --replace ${pkgs.coreutils}/bin/basename ${extraUtils}/bin/basename \
+            --replace ${pkgs.utillinux}/bin/blkid ${extraUtils}/bin/blkid \
             --replace ${pkgs.lvm2}/sbin ${extraUtils}/bin \
-            --replace /sbin/mdadm ${extraUtils}/bin/mdadm \
+            --replace ${pkgs.mdadm}/sbin ${extraUtils}/sbin \
             --replace ${pkgs.bash}/bin/sh ${extraUtils}/bin/sh \
-            --replace /usr/bin/readlink ${extraUtils}/bin/readlink \
-            --replace /usr/bin/basename ${extraUtils}/bin/basename \
             --replace ${udev}/bin/udevadm ${extraUtils}/bin/udevadm
       done
 
diff --git a/nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix b/nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix
index ee4ae845a7d5..c1f2c98afcd8 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd-unit-options.nix
@@ -226,7 +226,7 @@ in rec {
 
     environment = mkOption {
       default = {};
-      type = with types; attrsOf (nullOr (either str (either path package)));
+      type = with types; attrsOf (nullOr (oneOf [ str path package ]));
       example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; };
       description = "Environment variables passed to the service's processes.";
     };
diff --git a/nixpkgs/nixos/modules/system/boot/systemd.nix b/nixpkgs/nixos/modules/system/boot/systemd.nix
index cf35504e5182..1914827d0e5d 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd.nix
@@ -427,7 +427,8 @@ in
     systemd.packages = mkOption {
       default = [];
       type = types.listOf types.package;
-      description = "Packages providing systemd units.";
+      example = literalExample "[ pkgs.systemd-cryptsetup-generator ]";
+      description = "Packages providing systemd units and hooks.";
     };
 
     systemd.targets = mkOption {
@@ -497,11 +498,14 @@ in
       '';
     };
 
-    systemd.generator-packages = mkOption {
-      default = [];
-      type = types.listOf types.package;
-      example = literalExample "[ pkgs.systemd-cryptsetup-generator ]";
-      description = "Packages providing systemd generators.";
+    systemd.shutdown = mkOption {
+      type = types.attrsOf types.path;
+      default = {};
+      description = ''
+        Definition of systemd shutdown executables.
+        For each <literal>NAME = VALUE</literal> pair of the attrSet, a link is generated from
+        <literal>/etc/systemd/system-shutdown/NAME</literal> to <literal>VALUE</literal>.
+      '';
     };
 
     systemd.defaultUnit = mkOption {
@@ -520,7 +524,7 @@ in
     };
 
     systemd.globalEnvironment = mkOption {
-      type = with types; attrsOf (nullOr (either str (either path package)));
+      type = with types; attrsOf (nullOr (oneOf [ str path package ]));
       default = {};
       example = { TZ = "CET"; };
       description = ''
@@ -761,18 +765,21 @@ in
     environment.systemPackages = [ systemd ];
 
     environment.etc = let
-      # generate contents for /etc/systemd/system-generators from
-      # systemd.generators and systemd.generator-packages
-      generators = pkgs.runCommand "system-generators" {
+      # generate contents for /etc/systemd/system-${type} from attrset of links and packages
+      hooks = type: links: pkgs.runCommand "system-${type}" {
           preferLocalBuild = true;
-          packages = cfg.generator-packages;
-        } ''
+          packages = cfg.packages;
+      } ''
+        set -e
         mkdir -p $out
         for package in $packages
         do
-          ln -s $package/lib/systemd/system-generators/* $out/
-        done;
-        ${concatStrings (mapAttrsToList (generator: target: "ln -s ${target} $out/${generator};\n") cfg.generators)}
+          for hook in $package/lib/systemd/system-${type}/*
+          do
+            ln -s $hook $out/
+          done
+        done
+        ${concatStrings (mapAttrsToList (exec: target: "ln -s ${target} $out/${exec};\n") links)}
       '';
     in ({
       "systemd/system".source = generateUnits "system" cfg.units upstreamSystemUnits upstreamSystemWants;
@@ -834,7 +841,8 @@ in
         ${concatStringsSep "\n" cfg.tmpfiles.rules}
       '';
 
-      "systemd/system-generators" = { source = generators; };
+      "systemd/system-generators" = { source = hooks "generators" cfg.generators; };
+      "systemd/system-shutdown" = { source = hooks "shutdown" cfg.shutdown; };
     });
 
     services.dbus.enable = true;
diff --git a/nixpkgs/nixos/modules/tasks/filesystems/nfs.nix b/nixpkgs/nixos/modules/tasks/filesystems/nfs.nix
index d3a558738f4b..e0e8bb1f03de 100644
--- a/nixpkgs/nixos/modules/tasks/filesystems/nfs.nix
+++ b/nixpkgs/nixos/modules/tasks/filesystems/nfs.nix
@@ -56,7 +56,6 @@ in
     boot.initrd.kernelModules = mkIf inInitrd [ "nfs" ];
 
     systemd.packages = [ pkgs.nfs-utils ];
-    systemd.generator-packages = [ pkgs.nfs-utils ];
 
     environment.etc = {
       "idmapd.conf".source = idmapdConfFile;
diff --git a/nixpkgs/nixos/modules/tasks/network-interfaces-systemd.nix b/nixpkgs/nixos/modules/tasks/network-interfaces-systemd.nix
index 857aaf1e6e30..fbca54978e5b 100644
--- a/nixpkgs/nixos/modules/tasks/network-interfaces-systemd.nix
+++ b/nixpkgs/nixos/modules/tasks/network-interfaces-systemd.nix
@@ -74,7 +74,7 @@ in
         enable = true;
         networks."99-main" = genericNetwork mkDefault;
       }
-      (mkMerge (flip map interfaces (i: {
+      (mkMerge (forEach interfaces (i: {
         netdevs = mkIf i.virtual ({
           "40-${i.name}" = {
             netdevConfig = {
@@ -90,7 +90,7 @@ in
           name = mkDefault i.name;
           DHCP = mkForce (dhcpStr
             (if i.useDHCP != null then i.useDHCP else cfg.useDHCP && interfaceIps i == [ ]));
-          address = flip map (interfaceIps i)
+          address = forEach (interfaceIps i)
             (ip: "${ip.address}/${toString ip.prefixLength}");
           networkConfig.IPv6PrivacyExtensions = "kernel";
         } ];
@@ -102,7 +102,7 @@ in
             Kind = "bridge";
           };
         };
-        networks = listToAttrs (flip map bridge.interfaces (bi:
+        networks = listToAttrs (forEach bridge.interfaces (bi:
           nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) {
             DHCP = mkOverride 0 (dhcpStr false);
             networkConfig.Bridge = name;
@@ -173,7 +173,7 @@ in
 
         };
 
-        networks = listToAttrs (flip map bond.interfaces (bi:
+        networks = listToAttrs (forEach bond.interfaces (bi:
           nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) {
             DHCP = mkOverride 0 (dhcpStr false);
             networkConfig.Bond = name;
diff --git a/nixpkgs/nixos/modules/tasks/network-interfaces.nix b/nixpkgs/nixos/modules/tasks/network-interfaces.nix
index c75d7cbc408b..5ac753c92a78 100644
--- a/nixpkgs/nixos/modules/tasks/network-interfaces.nix
+++ b/nixpkgs/nixos/modules/tasks/network-interfaces.nix
@@ -926,7 +926,7 @@ in
     warnings = concatMap (i: i.warnings) interfaces;
 
     assertions =
-      (flip map interfaces (i: {
+      (forEach interfaces (i: {
         # With the linux kernel, interface name length is limited by IFNAMSIZ
         # to 16 bytes, including the trailing null byte.
         # See include/linux/if.h in the kernel sources
@@ -934,12 +934,12 @@ in
         message = ''
           The name of networking.interfaces."${i.name}" is too long, it needs to be less than 16 characters.
         '';
-      })) ++ (flip map slaveIfs (i: {
+      })) ++ (forEach slaveIfs (i: {
         assertion = i.ipv4.addresses == [ ] && i.ipv6.addresses == [ ];
         message = ''
           The networking.interfaces."${i.name}" must not have any defined ips when it is a slave.
         '';
-      })) ++ (flip map interfaces (i: {
+      })) ++ (forEach interfaces (i: {
         assertion = i.preferTempAddress -> cfg.enableIPv6;
         message = ''
           Temporary addresses are only needed when IPv6 is enabled.
@@ -967,8 +967,8 @@ in
       "net.ipv6.conf.default.disable_ipv6" = mkDefault (!cfg.enableIPv6);
       "net.ipv6.conf.all.forwarding" = mkDefault (any (i: i.proxyARP) interfaces);
     } // listToAttrs (flip concatMap (filter (i: i.proxyARP) interfaces)
-        (i: flip map [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true)))
-      // listToAttrs (flip map (filter (i: i.preferTempAddress) interfaces)
+        (i: forEach [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true)))
+      // listToAttrs (forEach (filter (i: i.preferTempAddress) interfaces)
         (i: nameValuePair "net.ipv6.conf.${i.name}.use_tempaddr" 2));
 
     # Capabilities won't work unless we have at-least a 4.3 Linux
@@ -1050,7 +1050,7 @@ in
           ${cfg.localCommands}
         '';
       };
-    } // (listToAttrs (flip map interfaces (i:
+    } // (listToAttrs (forEach interfaces (i:
       let
         deviceDependency = if (config.boot.isContainer || i.name == "lo")
           then []
diff --git a/nixpkgs/nixos/modules/tasks/swraid.nix b/nixpkgs/nixos/modules/tasks/swraid.nix
index 93e03c44c868..8fa19194bed4 100644
--- a/nixpkgs/nixos/modules/tasks/swraid.nix
+++ b/nixpkgs/nixos/modules/tasks/swraid.nix
@@ -6,51 +6,12 @@
 
   services.udev.packages = [ pkgs.mdadm ];
 
+  systemd.packages = [ pkgs.mdadm ];
+
   boot.initrd.availableKernelModules = [ "md_mod" "raid0" "raid1" "raid10" "raid456" ];
 
   boot.initrd.extraUdevRulesCommands = ''
     cp -v ${pkgs.mdadm}/lib/udev/rules.d/*.rules $out/
   '';
 
-  systemd.services.mdadm-shutdown = {
-    wantedBy = [ "final.target"];
-    after = [ "umount.target" ];
-
-    unitConfig = {
-      DefaultDependencies = false;
-    };
-
-    serviceConfig = {
-      Type = "oneshot";
-      ExecStart = ''${pkgs.mdadm}/bin/mdadm --wait-clean --scan'';
-    };
-  };
-
-  systemd.services."mdmon@" = {
-    description = "MD Metadata Monitor on /dev/%I";
-
-    unitConfig.DefaultDependencies = false;
-
-    serviceConfig = {
-      Type = "forking";
-      Environment = "IMSM_NO_PLATFORM=1";
-      ExecStart = ''${pkgs.mdadm}/bin/mdmon --offroot --takeover %I'';
-      KillMode = "none";
-    };
-  };
-
-  systemd.services."mdadm-grow-continue@" = {
-    description = "Manage MD Reshape on /dev/%I";
-
-    unitConfig.DefaultDependencies = false;
-
-    serviceConfig = {
-      ExecStart = ''${pkgs.mdadm}/bin/mdadm --grow --continue /dev/%I'';
-      StandardInput = "null";
-      StandardOutput = "null";
-      StandardError = "null";
-      KillMode = "none";
-    };
-  };
- 
 }
diff --git a/nixpkgs/nixos/modules/virtualisation/amazon-image.nix b/nixpkgs/nixos/modules/virtualisation/amazon-image.nix
index d67790702f1f..0c4ad90b4eb6 100644
--- a/nixpkgs/nixos/modules/virtualisation/amazon-image.nix
+++ b/nixpkgs/nixos/modules/virtualisation/amazon-image.nix
@@ -35,10 +35,9 @@ in
       autoResize = true;
     };
 
-    boot.extraModulePackages =
-      [ config.boot.kernelPackages.ixgbevf
-        config.boot.kernelPackages.ena
-      ];
+    boot.extraModulePackages = [
+      config.boot.kernelPackages.ena
+    ];
     boot.initrd.kernelModules = [ "xen-blkfront" "xen-netfront" ];
     boot.initrd.availableKernelModules = [ "ixgbevf" "ena" "nvme" ];
     boot.kernelParams = mkIf cfg.hvm [ "console=ttyS0" ];
diff --git a/nixpkgs/nixos/tests/all-tests.nix b/nixpkgs/nixos/tests/all-tests.nix
index c24c8ae61a58..df75358eeef1 100644
--- a/nixpkgs/nixos/tests/all-tests.nix
+++ b/nixpkgs/nixos/tests/all-tests.nix
@@ -150,6 +150,7 @@ in
   mediawiki = handleTest ./mediawiki.nix {};
   memcached = handleTest ./memcached.nix {};
   mesos = handleTest ./mesos.nix {};
+  metabase = handleTest ./metabase.nix {};
   miniflux = handleTest ./miniflux.nix {};
   minio = handleTest ./minio.nix {};
   misc = handleTest ./misc.nix {};
diff --git a/nixpkgs/nixos/tests/metabase.nix b/nixpkgs/nixos/tests/metabase.nix
new file mode 100644
index 000000000000..be9e5ed5b1e8
--- /dev/null
+++ b/nixpkgs/nixos/tests/metabase.nix
@@ -0,0 +1,20 @@
+import ./make-test.nix ({ pkgs, ... }: {
+  name = "metabase";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ mmahut ];
+  };
+
+  nodes = {
+    machine = { ... }: {
+      services.metabase.enable = true;
+      virtualisation.memorySize = 1024;
+    };
+  };
+
+  testScript = ''
+    startAll;
+    $machine->waitForUnit("metabase.service");
+    $machine->waitForOpenPort(3000);
+    $machine->waitUntilSucceeds("curl -L http://localhost:3000/setup | grep Metabase");
+  '';
+})
diff --git a/nixpkgs/nixos/tests/mosquitto.nix b/nixpkgs/nixos/tests/mosquitto.nix
index 86b7f9c044d8..bd5447de15ff 100644
--- a/nixpkgs/nixos/tests/mosquitto.nix
+++ b/nixpkgs/nixos/tests/mosquitto.nix
@@ -49,21 +49,40 @@ in rec {
 
   testScript = let
     file = "/tmp/msg";
-    payload = "wootWOOT";
+    sub = args:
+      "(${cmd "sub"} -C 1 ${args} | tee ${file} &)";
   in ''
     startAll;
     $server->waitForUnit("mosquitto.service");
 
     $server->fail("test -f ${file}");
-    $server->execute("(${cmd "sub"} -C 1 | tee ${file} &)");
-
     $client1->fail("test -f ${file}");
-    $client1->execute("(${cmd "sub"} -C 1 | tee ${file} &)");
+    $client2->fail("test -f ${file}");
+
+
+    # QoS = 0, so only one subscribers should get it
+    $server->execute("${sub "-q 0"}");
+
+    # we need to give the subscribers some time to connect
+    $client2->execute("sleep 5");
+    $client2->succeed("${cmd "pub"} -m FOO -q 0");
+
+    $server->waitUntilSucceeds("grep -q FOO ${file}");
+    $server->execute("rm ${file}");
+
+
+    # QoS = 1, so both subscribers should get it
+    $server->execute("${sub "-q 1"}");
+    $client1->execute("${sub "-q 1"}");
 
-    $client2->succeed("${cmd "pub"} -m ${payload}");
+    # we need to give the subscribers some time to connect
+    $client2->execute("sleep 5");
+    $client2->succeed("${cmd "pub"} -m BAR -q 1");
 
-    $server->succeed("grep -q ${payload} ${file}");
+    $server->waitUntilSucceeds("grep -q BAR ${file}");
+    $server->execute("rm ${file}");
 
-    $client1->succeed("grep -q ${payload} ${file}");
+    $client1->waitUntilSucceeds("grep -q BAR ${file}");
+    $client1->execute("rm ${file}");
   '';
 })
diff --git a/nixpkgs/nixos/tests/networking.nix b/nixpkgs/nixos/tests/networking.nix
index 949d946bdc4c..6ce64dcebea0 100644
--- a/nixpkgs/nixos/tests/networking.nix
+++ b/nixpkgs/nixos/tests/networking.nix
@@ -21,7 +21,7 @@ let
         useNetworkd = networkd;
         firewall.checkReversePath = true;
         firewall.allowedUDPPorts = [ 547 ];
-        interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n:
+        interfaces = mkOverride 0 (listToAttrs (forEach vlanIfs (n:
           nameValuePair "eth${toString n}" {
             ipv4.addresses = [ { address = "192.168.${toString n}.1"; prefixLength = 24; } ];
             ipv6.addresses = [ { address = "fd00:1234:5678:${toString n}::1"; prefixLength = 64; } ];
diff --git a/nixpkgs/nixos/tests/printing.nix b/nixpkgs/nixos/tests/printing.nix
index e8702c1ffbf1..74583ae55623 100644
--- a/nixpkgs/nixos/tests/printing.nix
+++ b/nixpkgs/nixos/tests/printing.nix
@@ -3,7 +3,7 @@
 import ./make-test.nix ({pkgs, ... }: {
   name = "printing";
   meta = with pkgs.stdenv.lib.maintainers; {
-    maintainers = [ domenkozar eelco ];
+    maintainers = [ domenkozar eelco matthewbauer ];
   };
 
   nodes = {
@@ -34,10 +34,6 @@ import ./make-test.nix ({pkgs, ... }: {
     ''
       startAll;
 
-      # Make sure that cups is up on both sides.
-      $server->waitForUnit("cups.service");
-      $client->waitForUnit("cups.service");
-      $client->sleep(10); # wait until cups is fully initialized
       $client->succeed("lpstat -r") =~ /scheduler is running/ or die;
       # check local encrypted connections work without error
       $client->succeed("lpstat -E -r") =~ /scheduler is running/ or die;
diff --git a/nixpkgs/nixos/tests/systemd.nix b/nixpkgs/nixos/tests/systemd.nix
index 4d470126abee..344d675c5fe2 100644
--- a/nixpkgs/nixos/tests/systemd.nix
+++ b/nixpkgs/nixos/tests/systemd.nix
@@ -1,4 +1,4 @@
-import ./make-test.nix {
+import ./make-test.nix ({ pkgs, ... }: {
   name = "systemd";
 
   machine = { lib, ... }: {
@@ -21,6 +21,14 @@ import ./make-test.nix {
     services.journald.extraConfig = "Storage=volatile";
     services.xserver.displayManager.auto.user = "alice";
 
+    systemd.shutdown.test = pkgs.writeScript "test.shutdown" ''
+      #!${pkgs.stdenv.shell}
+      PATH=${lib.makeBinPath (with pkgs; [ utillinux coreutils ])}
+      mount -t 9p shared -o trans=virtio,version=9p2000.L /tmp/shared
+      touch /tmp/shared/shutdown-test
+      umount /tmp/shared
+    '';
+
     systemd.services.testservice1 = {
       description = "Test Service 1";
       wantedBy = [ "multi-user.target" ];
@@ -69,5 +77,11 @@ import ./make-test.nix {
       # has a last mount time, because the file system wasn't checked.
       $machine->fail('dumpe2fs /dev/vdb | grep -q "^Last mount time: *n/a"');
     };
+
+    subtest "systemd-shutdown works", sub {
+      $machine->shutdown;
+      $machine->waitForUnit('multi-user.target');
+      $machine->succeed('test -e /tmp/shared/shutdown-test');
+    };
   '';
-}
+})