about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorFrederik Rietdijk <fridh@fridh.nl>2019-10-16 11:17:12 +0200
committerFrederik Rietdijk <fridh@fridh.nl>2019-10-16 11:17:12 +0200
commit12441bdf9f09a4d355f927f9b2957a90d5c98822 (patch)
tree9a57120c6f99ed0e7abc62e5ced7db816df79a6b /nixos
parent41abe12bb38266e421e61a1332953a6a0409ea5f (diff)
parent22bbaf09fedc7ca9addc59c9b1738fc0b83fe2fd (diff)
downloadnixlib-12441bdf9f09a4d355f927f9b2957a90d5c98822.tar
nixlib-12441bdf9f09a4d355f927f9b2957a90d5c98822.tar.gz
nixlib-12441bdf9f09a4d355f927f9b2957a90d5c98822.tar.bz2
nixlib-12441bdf9f09a4d355f927f9b2957a90d5c98822.tar.lz
nixlib-12441bdf9f09a4d355f927f9b2957a90d5c98822.tar.xz
nixlib-12441bdf9f09a4d355f927f9b2957a90d5c98822.tar.zst
nixlib-12441bdf9f09a4d355f927f9b2957a90d5c98822.zip
Merge staging-next into staging
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/release-notes/rl-1909.xml2
-rw-r--r--nixos/doc/manual/release-notes/rl-2003.xml13
-rw-r--r--nixos/modules/config/pulseaudio.nix3
-rw-r--r--nixos/modules/config/system-environment.nix7
-rw-r--r--nixos/modules/hardware/steam-hardware.nix7
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/profiles/hardened.nix21
-rw-r--r--nixos/modules/programs/environment.nix2
-rw-r--r--nixos/modules/services/backup/borgbackup.nix25
-rw-r--r--nixos/modules/services/databases/mysql.nix10
-rw-r--r--nixos/modules/services/misc/matrix-synapse.nix40
-rw-r--r--nixos/modules/services/monitoring/prometheus/exporters.nix1
-rw-r--r--nixos/modules/services/monitoring/prometheus/exporters/nextcloud.nix58
-rw-r--r--nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix14
-rw-r--r--nixos/modules/services/network-filesystems/samba.nix1
-rw-r--r--nixos/modules/services/web-apps/shiori.nix50
-rw-r--r--nixos/modules/services/x11/display-managers/gdm.nix5
-rw-r--r--nixos/modules/services/x11/display-managers/lightdm.nix5
-rw-r--r--nixos/modules/system/boot/systemd-nspawn.nix24
-rw-r--r--nixos/modules/tasks/filesystems/zfs.nix17
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/babeld.nix148
-rw-r--r--nixos/tests/gnome3-xorg.nix2
-rw-r--r--nixos/tests/gnome3.nix2
-rw-r--r--nixos/tests/login.nix6
-rw-r--r--nixos/tests/nextcloud/with-postgresql-and-redis.nix37
-rw-r--r--nixos/tests/pantheon.nix2
-rw-r--r--nixos/tests/plasma5.nix2
-rw-r--r--nixos/tests/prometheus-exporters.nix34
-rw-r--r--nixos/tests/shiori.nix17
-rw-r--r--nixos/tests/xfce.nix2
-rw-r--r--nixos/tests/xfce4-14.nix4
32 files changed, 468 insertions, 95 deletions
diff --git a/nixos/doc/manual/release-notes/rl-1909.xml b/nixos/doc/manual/release-notes/rl-1909.xml
index 446597e74fe9..1b7ca76c2f05 100644
--- a/nixos/doc/manual/release-notes/rl-1909.xml
+++ b/nixos/doc/manual/release-notes/rl-1909.xml
@@ -532,6 +532,8 @@
        is set to <literal>/var/lib/gitlab/state</literal>, <literal>gitlab</literal> and all parent directories
        must be owned by either <literal>root</literal> or the user specified in <option>services.gitlab.user</option>.
      </para>
+   </listitem>
+   <listitem>
      <para>
       The <option>networking.useDHCP</option> option is unsupported in combination with
       <option>networking.useNetworkd</option> in anticipation of defaulting to it by default.
diff --git a/nixos/doc/manual/release-notes/rl-2003.xml b/nixos/doc/manual/release-notes/rl-2003.xml
index bdf56acd5451..ab0951e831ce 100644
--- a/nixos/doc/manual/release-notes/rl-2003.xml
+++ b/nixos/doc/manual/release-notes/rl-2003.xml
@@ -36,6 +36,19 @@
      quirk in the boot menu.
     </para>
    </listitem>
+   <listitem>
+     <para>
+       By default zfs pools will now be trimmed on a weekly basis.
+       Trimming is only done on supported devices (i.e. NVME or SSDs)
+       and should improve throughput and lifetime of these devices.
+       It is controlled by the <varname>services.zfs.trim.enable</varname> varname.
+       The zfs scrub service (<varname>services.zfs.autoScrub.enable</varname>)
+       and the zfs autosnapshot service (<varname>services.zfs.autoSnapshot.enable</varname>)
+       are now only enabled if zfs is set in <varname>config.boot.initrd.supportedFilesystems</varname> or
+       <varname>config.boot.supportedFilesystems</varname>. These lists will automatically contain
+       zfs as soon as any zfs mountpoint is configured in <varname>fileSystems</varname>.
+     </para>
+   </listitem>
   </itemizedlist>
  </section>
 
diff --git a/nixos/modules/config/pulseaudio.nix b/nixos/modules/config/pulseaudio.nix
index 5c3e39302583..b3bc4a451aa0 100644
--- a/nixos/modules/config/pulseaudio.nix
+++ b/nixos/modules/config/pulseaudio.nix
@@ -51,8 +51,7 @@ let
   # that we can disable the autospawn feature in programs that
   # are built with PulseAudio support (like KDE).
   clientConf = writeText "client.conf" ''
-    autospawn=${if nonSystemWide then "yes" else "no"}
-    ${optionalString nonSystemWide "daemon-binary=${binary}"}
+    autospawn=no
     ${cfg.extraClientConf}
   '';
 
diff --git a/nixos/modules/config/system-environment.nix b/nixos/modules/config/system-environment.nix
index 361c3cfc553d..4888740ba3d5 100644
--- a/nixos/modules/config/system-environment.nix
+++ b/nixos/modules/config/system-environment.nix
@@ -88,6 +88,13 @@ in
           (mapAttrsToList pamVariable
           (zipAttrsWith (n: concatLists)
             [
+              # Make sure security wrappers are prioritized without polluting
+              # shell environments with an extra entry. Sessions which depend on
+              # pam for its environment will otherwise have eg. broken sudo. In
+              # particular Gnome Shell sometimes fails to source a proper
+              # environment from a shell.
+              { PATH = [ config.security.wrapperDir ]; }
+
               (mapAttrs (n: toList) cfg.sessionVariables)
               suffixedVariables
             ]));
diff --git a/nixos/modules/hardware/steam-hardware.nix b/nixos/modules/hardware/steam-hardware.nix
index 378aeffe71b5..6218c9ffbb9b 100644
--- a/nixos/modules/hardware/steam-hardware.nix
+++ b/nixos/modules/hardware/steam-hardware.nix
@@ -21,5 +21,12 @@ in
     services.udev.packages = [
       pkgs.steamPackages.steam
     ];
+
+    # The uinput module needs to be loaded in order to trigger the udev rules
+    # defined in the steam package for setting permissions on /dev/uinput.
+    #
+    # If the udev rules are not triggered, some controllers won't work with
+    # steam.
+    boot.kernelModules = [ "uinput" ];
   };
 }
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 6829a4e25788..4d177ae9699e 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -806,6 +806,7 @@
   ./services/web-apps/restya-board.nix
   ./services/web-apps/tt-rss.nix
   ./services/web-apps/selfoss.nix
+  ./services/web-apps/shiori.nix
   ./services/web-apps/virtlyst.nix
   ./services/web-apps/wordpress.nix
   ./services/web-apps/youtrack.nix
diff --git a/nixos/modules/profiles/hardened.nix b/nixos/modules/profiles/hardened.nix
index 626d8b1d2bde..f7b2f5c7fc1e 100644
--- a/nixos/modules/profiles/hardened.nix
+++ b/nixos/modules/profiles/hardened.nix
@@ -52,6 +52,27 @@ with lib;
     "ax25"
     "netrom"
     "rose"
+
+    # Old or rare or insufficiently audited filesystems
+    "adfs"
+    "affs"
+    "bfs"
+    "befs"
+    "cramfs"
+    "efs"
+    "erofs"
+    "exofs"
+    "freevxfs"
+    "f2fs"
+    "hfs"
+    "hpfs"
+    "jfs"
+    "minix"
+    "nilfs2"
+    "qnx4"
+    "qnx6"
+    "sysv"
+    "ufs"
   ];
 
   # Restrict ptrace() usage to processes with a pre-defined relationship
diff --git a/nixos/modules/programs/environment.nix b/nixos/modules/programs/environment.nix
index fcffb2134980..38bdabb4fa81 100644
--- a/nixos/modules/programs/environment.nix
+++ b/nixos/modules/programs/environment.nix
@@ -21,8 +21,6 @@ in
         PAGER = mkDefault "less -R";
         EDITOR = mkDefault "nano";
         XDG_CONFIG_DIRS = [ "/etc/xdg" ]; # needs to be before profile-relative paths to allow changes through environment.etc
-        GTK_DATA_PREFIX = "${config.system.path}"; # needed for gtk2 apps to find themes
-        GTK_EXE_PREFIX = "${config.system.path}";
       };
 
     environment.profiles = mkAfter
diff --git a/nixos/modules/services/backup/borgbackup.nix b/nixos/modules/services/backup/borgbackup.nix
index 2ad116a7872a..10d42325a6b1 100644
--- a/nixos/modules/services/backup/borgbackup.nix
+++ b/nixos/modules/services/backup/borgbackup.nix
@@ -8,7 +8,7 @@ let
     builtins.substring 0 1 x == "/"      # absolute path
     || builtins.substring 0 1 x == "."   # relative path
     || builtins.match "[.*:.*]" == null; # not machine:path
- 
+
   mkExcludeFile = cfg:
     # Write each exclude pattern to a new line
     pkgs.writeText "excludefile" (concatStringsSep "\n" cfg.exclude);
@@ -104,12 +104,12 @@ let
       install = "install -o ${cfg.user} -g ${cfg.group}";
     in
       nameValuePair "borgbackup-job-${name}" (stringAfter [ "users" ] (''
-        # Eensure that the home directory already exists
+        # Ensure that the home directory already exists
         # We can't assert createHome == true because that's not the case for root
-        cd "${config.users.users.${cfg.user}.home}"                                                                                                         
+        cd "${config.users.users.${cfg.user}.home}"
         ${install} -d .config/borg
         ${install} -d .cache/borg
-      '' + optionalString (isLocalPath cfg.repo) ''
+      '' + optionalString (isLocalPath cfg.repo && !cfg.removableDevice) ''
         ${install} -d ${escapeShellArg cfg.repo}
       ''));
 
@@ -163,6 +163,13 @@ let
       + " without at least one public key";
   };
 
+  mkRemovableDeviceAssertions = name: cfg: {
+    assertion = !(isLocalPath cfg.repo) -> !cfg.removableDevice;
+    message = ''
+      borgbackup.repos.${name}: repo isn't a local path, thus it can't be a removable device!
+    '';
+  };
+
 in {
   meta.maintainers = with maintainers; [ dotlambda ];
 
@@ -202,6 +209,12 @@ in {
             example = "user@machine:/path/to/repo";
           };
 
+          removableDevice = mkOption {
+            type = types.bool;
+            default = false;
+            description = "Whether the repo (which must be local) is a removable device.";
+          };
+
           archiveBaseName = mkOption {
             type = types.strMatching "[^/{}]+";
             default = "${globalConfig.networking.hostName}-${name}";
@@ -511,7 +524,6 @@ in {
     type = types.attrsOf (types.submodule (
       { ... }: {
         options = {
-          
           path = mkOption {
             type = types.path;
             description = ''
@@ -598,7 +610,8 @@ in {
     (with config.services.borgbackup; {
       assertions =
         mapAttrsToList mkPassAssertion jobs
-        ++ mapAttrsToList mkKeysAssertion repos;
+        ++ mapAttrsToList mkKeysAssertion repos
+        ++ mapAttrsToList mkRemovableDeviceAssertions jobs;
 
       system.activationScripts = mapAttrs' mkActivationScript jobs;
 
diff --git a/nixos/modules/services/databases/mysql.nix b/nixos/modules/services/databases/mysql.nix
index df74cfc9a26b..39192d059485 100644
--- a/nixos/modules/services/databases/mysql.nix
+++ b/nixos/modules/services/databases/mysql.nix
@@ -272,8 +272,13 @@ in
       port = ${toString cfg.port}
       datadir = ${cfg.dataDir}
       ${optionalString (cfg.bind != null) "bind-address = ${cfg.bind}" }
-      ${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "log-bin=mysql-bin"}
-      ${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "server-id = ${toString cfg.replication.serverId}"}
+      ${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave")
+      ''
+        log-bin=mysql-bin-${toString cfg.replication.serverId}
+        log-bin-index=mysql-bin-${toString cfg.replication.serverId}.index
+        relay-log=mysql-relay-bin
+        server-id = ${toString cfg.replication.serverId}
+      ''}
       ${optionalString (cfg.ensureUsers != [])
       ''
         plugin-load-add = auth_socket.so
@@ -381,6 +386,7 @@ in
 
                         ( echo "stop slave;"
                           echo "change master to master_host='${cfg.replication.masterHost}', master_user='${cfg.replication.masterUser}', master_password='${cfg.replication.masterPassword}';"
+                          echo "set global slave_exec_mode='IDEMPOTENT';"
                           echo "start slave;"
                         ) | ${mysql}/bin/mysql -u root -N
                       ''}
diff --git a/nixos/modules/services/misc/matrix-synapse.nix b/nixos/modules/services/misc/matrix-synapse.nix
index 018fac386163..0f4eb2ccfcad 100644
--- a/nixos/modules/services/misc/matrix-synapse.nix
+++ b/nixos/modules/services/misc/matrix-synapse.nix
@@ -79,7 +79,11 @@ turn_user_lifetime: "${cfg.turn_user_lifetime}"
 user_creation_max_duration: ${cfg.user_creation_max_duration}
 bcrypt_rounds: ${cfg.bcrypt_rounds}
 allow_guest_access: ${boolToString cfg.allow_guest_access}
-trusted_third_party_id_servers: ${builtins.toJSON cfg.trusted_third_party_id_servers}
+
+account_threepid_delegates:
+  ${optionalString (cfg.account_threepid_delegates.email != null) "email: ${cfg.account_threepid_delegates.email}"}
+  ${optionalString (cfg.account_threepid_delegates.msisdn != null) "msisdn: ${cfg.account_threepid_delegates.msisdn}"}
+
 room_invite_state_types: ${builtins.toJSON cfg.room_invite_state_types}
 ${optionalString (cfg.macaroon_secret_key != null) ''
   macaroon_secret_key: "${cfg.macaroon_secret_key}"
@@ -102,6 +106,7 @@ perspectives:
     '') cfg.servers)}
     }
   }
+redaction_retention_period: ${toString cfg.redaction_retention_period}
 app_service_config_files: ${builtins.toJSON cfg.app_service_config_files}
 
 ${cfg.extraConfig}
@@ -552,14 +557,18 @@ in {
           accessible to anonymous users.
         '';
       };
-      trusted_third_party_id_servers = mkOption {
-        type = types.listOf types.str;
-        default = [
-          "matrix.org"
-          "vector.im"
-        ];
+      account_threepid_delegates.email = mkOption {
+        type = types.nullOr types.str;
+        default = null;
         description = ''
-          The list of identity servers trusted to verify third party identifiers by this server.
+          Delegate email sending to https://example.org
+        '';
+      };
+      account_threepid_delegates.msisdn = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        description = ''
+          Delegate SMS sending to this local process (https://localhost:8090)
         '';
       };
       room_invite_state_types = mkOption {
@@ -600,6 +609,13 @@ in {
           A list of application service config file to use
         '';
       };
+      redaction_retention_period = mkOption {
+        type = types.int;
+        default = 7;
+        description = ''
+          How long to keep redacted events in unredacted form in the database.
+        '';
+      };
       extraConfig = mkOption {
         type = types.lines;
         default = "";
@@ -699,4 +715,12 @@ in {
       };
     };
   };
+
+  imports = [
+    (mkRemovedOptionModule [ "services" "matrix-synapse" "trusted_third_party_id_servers" ] ''
+      The `trusted_third_party_id_servers` option as been removed in `matrix-synapse` v1.4.0
+      as the behavior is now obsolete.
+    '')
+  ];
+
 }
diff --git a/nixos/modules/services/monitoring/prometheus/exporters.nix b/nixos/modules/services/monitoring/prometheus/exporters.nix
index 84486aa98a40..35b513bac571 100644
--- a/nixos/modules/services/monitoring/prometheus/exporters.nix
+++ b/nixos/modules/services/monitoring/prometheus/exporters.nix
@@ -30,6 +30,7 @@ let
     "json"
     "mail"
     "minio"
+    "nextcloud"
     "nginx"
     "node"
     "postfix"
diff --git a/nixos/modules/services/monitoring/prometheus/exporters/nextcloud.nix b/nixos/modules/services/monitoring/prometheus/exporters/nextcloud.nix
new file mode 100644
index 000000000000..5f9a52053f79
--- /dev/null
+++ b/nixos/modules/services/monitoring/prometheus/exporters/nextcloud.nix
@@ -0,0 +1,58 @@
+{ config, lib, pkgs, options }:
+
+with lib;
+
+let
+  cfg = config.services.prometheus.exporters.nextcloud;
+in
+{
+  port = 9205;
+  extraOpts = {
+    url = mkOption {
+      type = types.str;
+      example = "https://domain.tld";
+      description = ''
+        URL to the Nextcloud serverinfo page.
+        Adding the path to the serverinfo API is optional, it defaults
+        to <literal>/ocs/v2.php/apps/serverinfo/api/v1/info</literal>.
+      '';
+    };
+    username = mkOption {
+      type = types.str;
+      default = "nextcloud-exporter";
+      description = ''
+        Username for connecting to Nextcloud.
+        Note that this account needs to have admin privileges in Nextcloud.
+      '';
+    };
+    passwordFile = mkOption {
+      type = types.path;
+      example = "/path/to/password-file";
+      description = ''
+        File containing the password for connecting to Nextcloud.
+        Make sure that this file is readable by the exporter user.
+      '';
+    };
+    timeout = mkOption {
+      type = types.str;
+      default = "5s";
+      description = ''
+        Timeout for getting server info document.
+      '';
+    };
+  };
+  serviceOpts = {
+    serviceConfig = {
+      DynamicUser = false;
+      ExecStart = ''
+        ${pkgs.prometheus-nextcloud-exporter}/bin/nextcloud-exporter \
+          -a ${cfg.listenAddress}:${toString cfg.port} \
+          -u ${cfg.username} \
+          -t ${cfg.timeout} \
+          -l ${cfg.url} \
+          -p @${cfg.passwordFile} \
+          ${concatStringsSep " \\\n  " cfg.extraFlags}
+      '';
+    };
+  };
+}
diff --git a/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix b/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix
index 82e881236adf..374f83a2939d 100644
--- a/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix
+++ b/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix
@@ -6,6 +6,10 @@ let
   cfg = config.services.prometheus.exporters.wireguard;
 in {
   port = 9586;
+  imports = [
+    (mkRenamedOptionModule [ "addr" ] [ "listenAddress" ])
+    ({ options.warnings = options.warnings; options.assertions = options.assertions; })
+  ];
   extraOpts = {
     verbose = mkEnableOption "Verbose logging mode for prometheus-wireguard-exporter";
 
@@ -42,14 +46,6 @@ in {
         Whether or not the remote IP of a WireGuard peer should be exposed via prometheus.
       '';
     };
-
-    addr = mkOption {
-      type = types.str;
-      default = "0.0.0.0";
-      description = ''
-        IP address of the exporter.
-      '';
-    };
   };
   serviceOpts = {
     path = [ pkgs.wireguard-tools ];
@@ -59,7 +55,7 @@ in {
       ExecStart = ''
         ${pkgs.prometheus-wireguard-exporter}/bin/prometheus_wireguard_exporter \
           -p ${toString cfg.port} \
-          -l ${cfg.addr} \
+          -l ${cfg.listenAddress} \
           ${optionalString cfg.verbose "-v"} \
           ${optionalString cfg.singleSubnetPerField "-s"} \
           ${optionalString cfg.withRemoteIp "-r"} \
diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix
index 055508a32244..ce565dbaab81 100644
--- a/nixos/modules/services/network-filesystems/samba.nix
+++ b/nixos/modules/services/network-filesystems/samba.nix
@@ -45,6 +45,7 @@ let
   daemonService = appName: args:
     { description = "Samba Service Daemon ${appName}";
 
+      after = [ "network.target" ];
       requiredBy = [ "samba.target" ];
       partOf = [ "samba.target" ];
 
diff --git a/nixos/modules/services/web-apps/shiori.nix b/nixos/modules/services/web-apps/shiori.nix
new file mode 100644
index 000000000000..1817a2039352
--- /dev/null
+++ b/nixos/modules/services/web-apps/shiori.nix
@@ -0,0 +1,50 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.services.shiori;
+in {
+  options = {
+    services.shiori = {
+      enable = mkEnableOption "Shiori simple bookmarks manager";
+
+      package = mkOption {
+        type = types.package;
+        default = pkgs.shiori;
+        defaultText = "pkgs.shiori";
+        description = "The Shiori package to use.";
+      };
+
+      address = mkOption {
+        type = types.str;
+        default = "";
+        description = ''
+          The IP address on which Shiori will listen.
+          If empty, listens on all interfaces.
+        '';
+      };
+
+      port = mkOption {
+        type = types.port;
+        default = 8080;
+        description = "The port of the Shiori web application";
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.shiori = with cfg; {
+      description = "Shiori simple bookmarks manager";
+      wantedBy = [ "multi-user.target" ];
+
+      serviceConfig = {
+        ExecStart = "${package}/bin/shiori serve --address '${address}' --port '${toString port}'";
+        DynamicUser = true;
+        Environment = "SHIORI_DIR=/var/lib/shiori";
+        StateDirectory = "shiori";
+      };
+    };
+  };
+
+  meta.maintainers = with maintainers; [ minijackson ];
+}
diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix
index 597fb57a1790..e5990aec4b9c 100644
--- a/nixos/modules/services/x11/display-managers/gdm.nix
+++ b/nixos/modules/services/x11/display-managers/gdm.nix
@@ -170,8 +170,9 @@ in
       "plymouth-start.service"
     ];
     systemd.services.display-manager.conflicts = [
-      "getty@tty${gdm.initialVT}.service"
-      "plymouth-quit.service"
+       "getty@tty${gdm.initialVT}.service"
+       # TODO: Add "plymouth-quit.service" so GDM can control when plymouth quits.
+       # Currently this breaks switching configurations while using plymouth.
     ];
     systemd.services.display-manager.onFailure = [
       "plymouth-quit.service"
diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix
index aeee48de701d..cf4c05acbccd 100644
--- a/nixos/modules/services/x11/display-managers/lightdm.nix
+++ b/nixos/modules/services/x11/display-managers/lightdm.nix
@@ -220,10 +220,11 @@ in
       exec ${lightdm}/sbin/lightdm
     '';
 
-    # Replaces getty and plymouth quit since it quits plymouth on it's own.
+    # Replaces getty
     systemd.services.display-manager.conflicts = [
       "getty@tty7.service"
-      "plymouth-quit.service"
+      # TODO: Add "plymouth-quit.service" so LightDM can control when plymouth
+      # quits. Currently this breaks switching to configurations with plymouth.
      ];
 
     # Pull in dependencies of services we replace.
diff --git a/nixos/modules/system/boot/systemd-nspawn.nix b/nixos/modules/system/boot/systemd-nspawn.nix
index db6e06b41072..3ddd45b13482 100644
--- a/nixos/modules/system/boot/systemd-nspawn.nix
+++ b/nixos/modules/system/boot/systemd-nspawn.nix
@@ -113,11 +113,21 @@ in {
   config =
     let
       units = mapAttrs' (n: v: let nspawnFile = "${n}.nspawn"; in nameValuePair nspawnFile (instanceToUnit nspawnFile v)) cfg;
-    in mkIf (cfg != {}) {
-
-      environment.etc."systemd/nspawn".source = generateUnits "nspawn" units [] [];
-
-      systemd.targets.multi-user.wants = [ "machines.target" ];
-  };
-
+    in 
+      mkMerge [
+        (mkIf (cfg != {}) { 
+          environment.etc."systemd/nspawn".source = mkIf (cfg != {}) (generateUnits "nspawn" units [] []);
+        })
+        {
+          systemd.targets.multi-user.wants = [ "machines.target" ];
+
+          # Workaround for https://github.com/NixOS/nixpkgs/pull/67232#issuecomment-531315437 and https://github.com/systemd/systemd/issues/13622
+          # Once systemd fixes this upstream, we can re-enable -U
+          systemd.services."systemd-nspawn@".serviceConfig.ExecStart = [ 
+            ""  # deliberately empty. signals systemd to override the ExecStart
+            # Only difference between upstream is that we do not pass the -U flag
+            "${pkgs.systemd}/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth --settings=override --machine=%i"
+          ];
+        }
+      ];
 }
diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix
index cfdc0a31020b..fe11917c609c 100644
--- a/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixos/modules/tasks/filesystems/zfs.nix
@@ -16,9 +16,7 @@ let
   inInitrd = any (fs: fs == "zfs") config.boot.initrd.supportedFilesystems;
   inSystem = any (fs: fs == "zfs") config.boot.supportedFilesystems;
 
-  enableAutoSnapshots = cfgSnapshots.enable;
-  enableAutoScrub = cfgScrub.enable;
-  enableZfs = inInitrd || inSystem || enableAutoSnapshots || enableAutoScrub;
+  enableZfs = inInitrd || inSystem;
 
   kernel = config.boot.kernelPackages;
 
@@ -392,10 +390,11 @@ in
       };
 
       environment.etc."zfs/zed.d".source = "${packages.zfsUser}/etc/zfs/zed.d/";
+      environment.etc."zfs/zpool.d".source = "${packages.zfsUser}/etc/zfs/zpool.d/";
 
       system.fsPackages = [ packages.zfsUser ]; # XXX: needed? zfs doesn't have (need) a fsck
       environment.systemPackages = [ packages.zfsUser ]
-        ++ optional enableAutoSnapshots autosnapPkg; # so the user can run the command to see flags
+        ++ optional cfgSnapshots.enable autosnapPkg; # so the user can run the command to see flags
 
       services.udev.packages = [ packages.zfsUser ]; # to hook zvol naming, etc.
       systemd.packages = [ packages.zfsUser ];
@@ -487,7 +486,7 @@ in
       systemd.targets.zfs.wantedBy = [ "multi-user.target" ];
     })
 
-    (mkIf enableAutoSnapshots {
+    (mkIf (enableZfs && cfgSnapshots.enable) {
       systemd.services = let
                            descr = name: if name == "frequent" then "15 mins"
                                     else if name == "hourly" then "hour"
@@ -525,7 +524,7 @@ in
                             }) snapshotNames);
     })
 
-    (mkIf enableAutoScrub {
+    (mkIf (enableZfs && cfgScrub.enable) {
       systemd.services.zfs-scrub = {
         description = "ZFS pools scrubbing";
         after = [ "zfs-import.target" ];
@@ -552,15 +551,13 @@ in
       };
     })
 
-    (mkIf cfgTrim.enable {
+    (mkIf (enableZfs && cfgTrim.enable) {
       systemd.services.zpool-trim = {
         description = "ZFS pools trim";
         after = [ "zfs-import.target" ];
         path = [ packages.zfsUser ];
         startAt = cfgTrim.interval;
-        script = ''
-          zpool list -H -o name | xargs -n1 zpool trim
-        '';
+        serviceConfig.ExecStart = "${pkgs.runtimeShell} -c 'zpool list -H -o name | xargs --no-run-if-empty -n1 zpool trim'";
       };
     })
   ];
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 04323317a994..914b32f97c3a 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -25,6 +25,7 @@ in
   atd = handleTest ./atd.nix {};
   automysqlbackup = handleTest ./automysqlbackup.nix {};
   avahi = handleTest ./avahi.nix {};
+  babeld = handleTest ./babeld.nix {};
   bcachefs = handleTestOn ["x86_64-linux"] ./bcachefs.nix {}; # linux-4.18.2018.10.12 is unsupported on aarch64
   beanstalkd = handleTest ./beanstalkd.nix {};
   beegfs = handleTestOn ["x86_64-linux"] ./beegfs.nix {}; # beegfs is unsupported on aarch64
diff --git a/nixos/tests/babeld.nix b/nixos/tests/babeld.nix
new file mode 100644
index 000000000000..5242cf395d70
--- /dev/null
+++ b/nixos/tests/babeld.nix
@@ -0,0 +1,148 @@
+
+import ./make-test.nix ({ pkgs, lib, ...} : {
+  name = "babeld";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ hexa ];
+  };
+
+  nodes =
+    { client = { pkgs, lib, ... }:
+      {
+        virtualisation.vlans = [ 10 ];
+
+        networking = {
+          useDHCP = false;
+          interfaces."eth1" = {
+            ipv4.addresses = lib.mkForce [ { address = "192.168.10.2"; prefixLength = 24; } ];
+            ipv4.routes = lib.mkForce [ { address = "0.0.0.0"; prefixLength = 0; via = "192.168.10.1"; } ];
+            ipv6.addresses = lib.mkForce [ { address = "2001:db8:10::2"; prefixLength = 64; } ];
+            ipv6.routes = lib.mkForce [ { address = "::"; prefixLength = 0; via = "2001:db8:10::1"; } ];
+          };
+        };
+      };
+
+      localRouter = { pkgs, lib, ... }:
+      {
+        virtualisation.vlans = [ 10 20 ];
+
+        boot.kernel.sysctl."net.ipv4.conf.all.forwarding" = 1;
+        boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
+
+        networking = {
+          useDHCP = false;
+          firewall.enable = false;
+
+          interfaces."eth1" = {
+            ipv4.addresses = lib.mkForce [ { address = "192.168.10.1"; prefixLength = 24; } ];
+            ipv6.addresses = lib.mkForce [ { address = "2001:db8:10::1"; prefixLength = 64; } ];
+          };
+
+          interfaces."eth2" = {
+            ipv4.addresses = lib.mkForce [ { address = "192.168.20.1"; prefixLength = 24; } ];
+            ipv6.addresses = lib.mkForce [ { address = "2001:db8:20::1"; prefixLength = 64; } ];
+          };
+        };
+
+        services.babeld = {
+          enable = true;
+          interfaces.eth2 = {
+            hello-interval = 1;
+            type = "wired";
+          };
+          extraConfig = ''
+            local-port-readwrite 33123
+
+            import-table 254 # main
+            export-table 254 # main
+
+            in ip 192.168.10.0/24 deny
+            in ip 192.168.20.0/24 deny
+            in ip 2001:db8:10::/64 deny
+            in ip 2001:db8:20::/64 deny
+
+            in ip 192.168.30.0/24 allow
+            in ip 2001:db8:30::/64 allow
+
+            in deny
+
+            redistribute local proto 2
+            redistribute local deny
+          '';
+        };
+      };
+      remoteRouter = { pkgs, lib, ... }:
+      {
+        virtualisation.vlans = [ 20 30 ];
+
+        boot.kernel.sysctl."net.ipv4.conf.all.forwarding" = 1;
+        boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
+
+        networking = {
+          useDHCP = false;
+          firewall.enable = false;
+
+          interfaces."eth1" = {
+            ipv4.addresses = lib.mkForce [ { address = "192.168.20.2"; prefixLength = 24; } ];
+            ipv6.addresses = lib.mkForce [ { address = "2001:db8:20::2"; prefixLength = 64; } ];
+          };
+
+          interfaces."eth2" = {
+            ipv4.addresses = lib.mkForce [ { address = "192.168.30.1"; prefixLength = 24; } ];
+            ipv6.addresses = lib.mkForce [ { address = "2001:db8:30::1"; prefixLength = 64; } ];
+          };
+        };
+
+        services.babeld = {
+          enable = true;
+          interfaces.eth1 = {
+            hello-interval = 1;
+            type = "wired";
+          };
+          extraConfig = ''
+            local-port-readwrite 33123
+
+            import-table 254 # main
+            export-table 254 # main
+
+            in ip 192.168.20.0/24 deny
+            in ip 192.168.30.0/24 deny
+            in ip 2001:db8:20::/64 deny
+            in ip 2001:db8:30::/64 deny
+
+            in ip 192.168.10.0/24 allow
+            in ip 2001:db8:10::/64 allow
+
+            in deny
+
+            redistribute local proto 2
+            redistribute local deny
+          '';
+        };
+
+      };
+    };
+
+  testScript =
+    ''
+      startAll;
+
+      $client->waitForUnit("network-online.target");
+      $localRouter->waitForUnit("network-online.target");
+      $remoteRouter->waitForUnit("network-online.target");
+
+      $localRouter->waitForUnit("babeld.service");
+      $remoteRouter->waitForUnit("babeld.service");
+
+      $localRouter->waitUntilSucceeds("ip route get 192.168.30.1");
+      $localRouter->waitUntilSucceeds("ip route get 2001:db8:30::1");
+
+      $remoteRouter->waitUntilSucceeds("ip route get 192.168.10.1");
+      $remoteRouter->waitUntilSucceeds("ip route get 2001:db8:10::1");
+
+      $client->succeed("ping -c1 192.168.30.1");
+      $client->succeed("ping -c1 2001:db8:30::1");
+
+      $remoteRouter->succeed("ping -c1 192.168.10.2");
+      $remoteRouter->succeed("ping -c1 2001:db8:10::2");
+    '';
+})
diff --git a/nixos/tests/gnome3-xorg.nix b/nixos/tests/gnome3-xorg.nix
index f12361da0372..eb4c376319be 100644
--- a/nixos/tests/gnome3-xorg.nix
+++ b/nixos/tests/gnome3-xorg.nix
@@ -29,7 +29,7 @@ import ./make-test.nix ({ pkgs, ...} : {
       $machine->waitForUnit("default.target","alice");
 
       # Check that logging in has given the user ownership of devices.
-      $machine->succeed("getfacl /dev/snd/timer | grep -q alice");
+      $machine->succeed("getfacl -p /dev/snd/timer | grep -q alice");
 
       $machine->succeed("su - alice -c 'DISPLAY=:0.0 gnome-terminal &'");
       $machine->succeed("xauth merge ~alice/.Xauthority");
diff --git a/nixos/tests/gnome3.nix b/nixos/tests/gnome3.nix
index b6fe602a7327..ab363efb6a19 100644
--- a/nixos/tests/gnome3.nix
+++ b/nixos/tests/gnome3.nix
@@ -44,7 +44,7 @@ import ./make-test.nix ({ pkgs, ...} : {
       $machine->waitForUnit("default.target","alice");
 
       # Check that logging in has given the user ownership of devices.
-      $machine->succeed("getfacl /dev/snd/timer | grep -q alice");
+      $machine->succeed("getfacl -p /dev/snd/timer | grep -q alice");
 
       # Wait for the wayland server
       $machine->waitForFile("/run/user/1000/wayland-0");
diff --git a/nixos/tests/login.nix b/nixos/tests/login.nix
index 2a7c063d3033..bd8ed23a7b8e 100644
--- a/nixos/tests/login.nix
+++ b/nixos/tests/login.nix
@@ -48,12 +48,12 @@ import ./make-test.nix ({ pkgs, latestKernel ? false, ... }:
       # Check whether systemd gives and removes device ownership as
       # needed.
       subtest "device permissions", sub {
-          $machine->succeed("getfacl /dev/snd/timer | grep -q alice");
+          $machine->succeed("getfacl -p /dev/snd/timer | grep -q alice");
           $machine->sendKeys("alt-f1");
           $machine->waitUntilSucceeds("[ \$(fgconsole) = 1 ]");
-          $machine->fail("getfacl /dev/snd/timer | grep -q alice");
+          $machine->fail("getfacl -p /dev/snd/timer | grep -q alice");
           $machine->succeed("chvt 2");
-          $machine->waitUntilSucceeds("getfacl /dev/snd/timer | grep -q alice");
+          $machine->waitUntilSucceeds("getfacl -p /dev/snd/timer | grep -q alice");
       };
 
       # Log out.
diff --git a/nixos/tests/nextcloud/with-postgresql-and-redis.nix b/nixos/tests/nextcloud/with-postgresql-and-redis.nix
index 81c269c23788..f655aba9d45e 100644
--- a/nixos/tests/nextcloud/with-postgresql-and-redis.nix
+++ b/nixos/tests/nextcloud/with-postgresql-and-redis.nix
@@ -36,49 +36,16 @@ in {
       };
 
       services.redis = {
-        unixSocket = "/var/run/redis/redis.sock";
         enable = true;
-        extraConfig = ''
-          unixsocketperm 770
-        '';
-      };
-
-      systemd.services.redis = {
-        preStart = ''
-          mkdir -p /var/run/redis
-          chown ${config.services.redis.user}:${config.services.nginx.group} /var/run/redis
-        '';
-        serviceConfig.PermissionsStartOnly = true;
       };
 
       systemd.services.nextcloud-setup= {
         requires = ["postgresql.service"];
         after = [
           "postgresql.service"
-          "chown-redis-socket.service"
         ];
       };
 
-      # At the time of writing, redis creates its socket with the "nobody"
-      # group.  I figure this is slightly less bad than making the socket world
-      # readable.
-      systemd.services.chown-redis-socket = {
-        enable = true;
-        script = ''
-          until ${pkgs.redis}/bin/redis-cli ping; do
-            echo "waiting for redis..."
-            sleep 1
-          done
-          chown ${config.services.redis.user}:${config.services.nginx.group} /var/run/redis/redis.sock
-        '';
-        after = [ "redis.service" ];
-        requires = [ "redis.service" ];
-        wantedBy = [ "redis.service" ];
-        serviceConfig = {
-          Type = "oneshot";
-        };
-      };
-
       services.postgresql = {
         enable = true;
         ensureDatabases = [ "nextcloud" ];
@@ -94,8 +61,8 @@ in {
   testScript = let
     configureRedis = pkgs.writeScript "configure-redis" ''
       #!${pkgs.stdenv.shell}
-      nextcloud-occ config:system:set redis 'host' --value '/var/run/redis/redis.sock' --type string
-      nextcloud-occ config:system:set redis 'port' --value 0 --type integer
+      nextcloud-occ config:system:set redis 'host' --value 'localhost' --type string
+      nextcloud-occ config:system:set redis 'port' --value 6379 --type integer
       nextcloud-occ config:system:set memcache.local --value '\OC\Memcache\Redis' --type string
       nextcloud-occ config:system:set memcache.locking --value '\OC\Memcache\Redis' --type string
     '';
diff --git a/nixos/tests/pantheon.nix b/nixos/tests/pantheon.nix
index c50f77f86173..9888887ee8b5 100644
--- a/nixos/tests/pantheon.nix
+++ b/nixos/tests/pantheon.nix
@@ -42,7 +42,7 @@ import ./make-test.nix ({ pkgs, ...} :
     $machine->waitForWindow(qr/plank/);
 
     # Check that logging in has given the user ownership of devices.
-    $machine->succeed("getfacl /dev/snd/timer | grep -q alice");
+    $machine->succeed("getfacl -p /dev/snd/timer | grep -q alice");
 
     # Open elementary terminal
     $machine->execute("su - alice -c 'DISPLAY=:0.0 io.elementary.terminal &'");
diff --git a/nixos/tests/plasma5.nix b/nixos/tests/plasma5.nix
index 88d4ff334369..614fc9bf316e 100644
--- a/nixos/tests/plasma5.nix
+++ b/nixos/tests/plasma5.nix
@@ -48,7 +48,7 @@ import ./make-test.nix ({ pkgs, ...} :
     $machine->waitForWindow("^Desktop ");
 
     # Check that logging in has given the user ownership of devices.
-    $machine->succeed("getfacl /dev/snd/timer | grep -q alice");
+    $machine->succeed("getfacl -p /dev/snd/timer | grep -q alice");
 
     $machine->execute("su - alice -c 'DISPLAY=:0.0 dolphin &'");
     $machine->waitForWindow(" Dolphin");
diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix
index 9826b56b74d7..676183f6356f 100644
--- a/nixos/tests/prometheus-exporters.nix
+++ b/nixos/tests/prometheus-exporters.nix
@@ -229,6 +229,40 @@ let
       '';
     };
 
+    nextcloud = {
+      exporterConfig = {
+        enable = true;
+        passwordFile = "/var/nextcloud-pwfile";
+        url = "http://localhost/negative-space.xml";
+      };
+      metricProvider = {
+        systemd.services.nc-pwfile = let
+          passfile = (pkgs.writeText "pwfile" "snakeoilpw");
+        in {
+          requiredBy = [ "prometheus-nextcloud-exporter.service" ];
+          before = [ "prometheus-nextcloud-exporter.service" ];
+          serviceConfig.ExecStart = ''
+            ${pkgs.coreutils}/bin/install -o nextcloud-exporter -m 0400 ${passfile} /var/nextcloud-pwfile
+          '';
+        };
+        services.nginx = {
+          enable = true;
+          virtualHosts."localhost" = {
+            basicAuth.nextcloud-exporter = "snakeoilpw";
+            locations."/" = {
+              root = "${pkgs.prometheus-nextcloud-exporter.src}/serverinfo/testdata";
+            };
+          };
+        };
+      };
+      exporterTest = ''
+        waitForUnit("nginx.service")
+        waitForUnit("prometheus-nextcloud-exporter.service")
+        waitForOpenPort(9205)
+        succeed("curl -sSf http://localhost:9205/metrics | grep -q 'nextcloud_up 1'")
+      '';
+    };
+
     nginx = {
       exporterConfig = {
         enable = true;
diff --git a/nixos/tests/shiori.nix b/nixos/tests/shiori.nix
new file mode 100644
index 000000000000..0022a7220fe2
--- /dev/null
+++ b/nixos/tests/shiori.nix
@@ -0,0 +1,17 @@
+import ./make-test.nix ({ lib, ...}:
+
+{
+  name = "shiori";
+  meta.maintainers = with lib.maintainers; [ minijackson ];
+
+  machine =
+    { ... }:
+    { services.shiori.enable = true; };
+
+  testScript = ''
+    $machine->waitForUnit('shiori.service');
+    $machine->waitForOpenPort('8080');
+    $machine->succeed("curl --fail http://localhost:8080/");
+    $machine->succeed("curl --fail --location http://localhost:8080/ | grep -qi shiori");
+  '';
+})
diff --git a/nixos/tests/xfce.nix b/nixos/tests/xfce.nix
index 6cb4fae2021f..7ff623062d93 100644
--- a/nixos/tests/xfce.nix
+++ b/nixos/tests/xfce.nix
@@ -32,7 +32,7 @@ import ./make-test.nix ({ pkgs, ...} : {
       $machine->sleep(10);
 
       # Check that logging in has given the user ownership of devices.
-      $machine->succeed("getfacl /dev/snd/timer | grep -q alice");
+      $machine->succeed("getfacl -p /dev/snd/timer | grep -q alice");
 
       $machine->succeed("su - alice -c 'DISPLAY=:0.0 xfce4-terminal &'");
       $machine->waitForWindow(qr/Terminal/);
diff --git a/nixos/tests/xfce4-14.nix b/nixos/tests/xfce4-14.nix
index 94378f0c8d34..d9b87b084376 100644
--- a/nixos/tests/xfce4-14.nix
+++ b/nixos/tests/xfce4-14.nix
@@ -14,7 +14,7 @@ import ./make-test.nix ({ pkgs, ...} : {
       services.xserver.desktopManager.xfce4-14.enable = true;
 
       hardware.pulseaudio.enable = true; # needed for the factl test, /dev/snd/* exists without them but udev doesn't care then
-  
+
       virtualisation.memorySize = 1024;
     };
 
@@ -27,7 +27,7 @@ import ./make-test.nix ({ pkgs, ...} : {
       $machine->sleep(10);
 
       # Check that logging in has given the user ownership of devices.
-      $machine->succeed("getfacl /dev/snd/timer | grep -q alice");
+      $machine->succeed("getfacl -p /dev/snd/timer | grep -q alice");
 
       $machine->succeed("su - alice -c 'DISPLAY=:0.0 xfce4-terminal &'");
       $machine->waitForWindow(qr/Terminal/);