summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorFrederik Rietdijk <fridh@fridh.nl>2019-06-09 12:28:52 +0200
committerFrederik Rietdijk <fridh@fridh.nl>2019-06-09 12:28:52 +0200
commitd3afcac771d86e9e3c482a8564513ab1a72b87e5 (patch)
treef002f6e54b1d505c7d1ac4fadc648ce6e2bb3b81 /nixos
parent480cd436fc077c60e86fccd68d5971dc831f5947 (diff)
parente596a33dc08b9b7d34aa62c0418218de7469ae7f (diff)
downloadnixpkgs-d3afcac771d86e9e3c482a8564513ab1a72b87e5.tar
nixpkgs-d3afcac771d86e9e3c482a8564513ab1a72b87e5.tar.gz
nixpkgs-d3afcac771d86e9e3c482a8564513ab1a72b87e5.tar.bz2
nixpkgs-d3afcac771d86e9e3c482a8564513ab1a72b87e5.tar.lz
nixpkgs-d3afcac771d86e9e3c482a8564513ab1a72b87e5.tar.xz
nixpkgs-d3afcac771d86e9e3c482a8564513ab1a72b87e5.tar.zst
nixpkgs-d3afcac771d86e9e3c482a8564513ab1a72b87e5.zip
Merge master into staging-next
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/administration/imperative-containers.xml7
-rw-r--r--nixos/doc/manual/release-notes/rl-1909.xml6
-rw-r--r--nixos/modules/module-list.nix2
-rw-r--r--nixos/modules/programs/zsh/zsh.nix4
-rw-r--r--nixos/modules/services/audio/jack.nix15
-rw-r--r--nixos/modules/services/misc/zoneminder.nix2
-rw-r--r--nixos/modules/services/monitoring/prometheus/exporters.nix1
-rw-r--r--nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix42
-rw-r--r--nixos/modules/services/networking/mtprotoproxy.nix110
-rw-r--r--nixos/modules/services/networking/wireguard.nix4
-rw-r--r--nixos/modules/services/web-apps/cryptpad.nix54
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/default.nix55
-rw-r--r--nixos/modules/system/boot/loader/generations-dir/generations-dir.nix4
-rw-r--r--nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix2
-rw-r--r--nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix4
-rw-r--r--nixos/modules/system/boot/loader/init-script/init-script.nix4
-rw-r--r--nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix7
-rw-r--r--nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix2
-rw-r--r--nixos/modules/tasks/filesystems/zfs.nix6
-rw-r--r--nixos/modules/virtualisation/containers.nix19
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/docker-tools.nix6
-rw-r--r--nixos/tests/prometheus-exporters.nix23
-rw-r--r--nixos/tests/slurm.nix4
-rw-r--r--nixos/tests/uwsgi.nix38
25 files changed, 351 insertions, 71 deletions
diff --git a/nixos/doc/manual/administration/imperative-containers.xml b/nixos/doc/manual/administration/imperative-containers.xml
index 9bb62bc2ece..7ded0c11786 100644
--- a/nixos/doc/manual/administration/imperative-containers.xml
+++ b/nixos/doc/manual/administration/imperative-containers.xml
@@ -30,6 +30,13 @@
   <link linkend="opt-users.users._name__.openssh.authorizedKeys.keys">users.users.root.openssh.authorizedKeys.keys</link> = ["ssh-dss AAAAB3N…"];
 '
 </screen>
+  By default the next free address in the <literal>10.233.0.0/16</literal> subnet will be chosen
+  as container IP. This behavior can be altered by setting <literal>--host-address</literal> and
+  <literal>--local-address</literal>:
+<screen>
+# nixos-container create test --config-file test-container.nix \
+    --local-address 10.235.1.2 --host-address 10.235.1.1
+</screen>
  </para>
 
  <para>
diff --git a/nixos/doc/manual/release-notes/rl-1909.xml b/nixos/doc/manual/release-notes/rl-1909.xml
index 922239998ad..7f0c1d21e37 100644
--- a/nixos/doc/manual/release-notes/rl-1909.xml
+++ b/nixos/doc/manual/release-notes/rl-1909.xml
@@ -165,6 +165,12 @@
       <link xlink:href="https://github.com/NixOS/nixpkgs/issues/62211">issue #62211</link>.
     </para>
   </listitem>
+  <listitem>
+    <para>
+      The setopt declarations will be evaluated at the end of <literal>/etc/zshrc</literal>, so any code in <xref linkend="opt-programs.zsh.interactiveShellInit" />,
+      <xref linkend="opt-programs.zsh.loginShellInit" /> and <xref linkend="opt-programs.zsh.promptInit" /> may break if it relies on those options being set.
+    </para>
+   </listitem>
   </itemizedlist>
  </section>
 
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 1017d25bf28..bf2716d6cae 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -611,6 +611,7 @@
   ./services/networking/morty.nix
   ./services/networking/miredo.nix
   ./services/networking/mstpd.nix
+  ./services/networking/mtprotoproxy.nix
   ./services/networking/murmur.nix
   ./services/networking/mxisd.nix
   ./services/networking/namecoind.nix
@@ -759,6 +760,7 @@
   ./services/web-apps/atlassian/crowd.nix
   ./services/web-apps/atlassian/jira.nix
   ./services/web-apps/codimd.nix
+  ./services/web-apps/cryptpad.nix
   ./services/web-apps/documize.nix
   ./services/web-apps/frab.nix
   ./services/web-apps/icingaweb2/icingaweb2.nix
diff --git a/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix
index bdb37eae23e..bd1a7768066 100644
--- a/nixos/modules/programs/zsh/zsh.nix
+++ b/nixos/modules/programs/zsh/zsh.nix
@@ -194,8 +194,6 @@ in
         HISTSIZE=${toString cfg.histSize}
         HISTFILE=${cfg.histFile}
 
-        ${optionalString (cfg.setOptions != []) "setopt ${concatStringsSep " " cfg.setOptions}"}
-
         HELPDIR="${pkgs.zsh}/share/zsh/$ZSH_VERSION/help"
 
         # Tell zsh how to find installed completions
@@ -209,6 +207,8 @@ in
 
         ${cfg.interactiveShellInit}
 
+        ${optionalString (cfg.setOptions != []) "setopt ${concatStringsSep " " cfg.setOptions}"}
+
         ${zshAliases}
 
         ${cfg.promptInit}
diff --git a/nixos/modules/services/audio/jack.nix b/nixos/modules/services/audio/jack.nix
index 1364abd4044..aa3351f401a 100644
--- a/nixos/modules/services/audio/jack.nix
+++ b/nixos/modules/services/audio/jack.nix
@@ -98,6 +98,20 @@ in {
           '';
         };
 
+        dmixConfig = mkOption {
+          type = types.lines;
+          default = "";
+          example = ''
+            period_size 2048
+            periods 2
+          '';
+          description = ''
+            For music production software that still doesn't support JACK natively you
+            would like to put buffer/period adjustments here
+            to decrease dmix device latency.
+          '';
+        };
+
         session = mkOption {
           type = types.lines;
           description = ''
@@ -150,6 +164,7 @@ in {
           ipc_key 219345
           slave {
             pcm loophw00
+            ${cfg.loopback.dmixConfig}
           }
         }
         pcm.asoftvol {
diff --git a/nixos/modules/services/misc/zoneminder.nix b/nixos/modules/services/misc/zoneminder.nix
index 01720ba432e..9c555e8031c 100644
--- a/nixos/modules/services/misc/zoneminder.nix
+++ b/nixos/modules/services/misc/zoneminder.nix
@@ -229,6 +229,8 @@ in {
               location / {
                 try_files $uri $uri/ /index.php?$args =404;
 
+                rewrite ^/skins/.*/css/fonts/(.*)$ /fonts/$1 permanent;
+
                 location ~ /api/(css|img|ico) {
                   rewrite ^/api(.+)$ /api/app/webroot/$1 break;
                   try_files $uri $uri/ =404;
diff --git a/nixos/modules/services/monitoring/prometheus/exporters.nix b/nixos/modules/services/monitoring/prometheus/exporters.nix
index fa53107ef24..20e7eba4341 100644
--- a/nixos/modules/services/monitoring/prometheus/exporters.nix
+++ b/nixos/modules/services/monitoring/prometheus/exporters.nix
@@ -34,6 +34,7 @@ let
     unifi     = import ./exporters/unifi.nix     { inherit config lib pkgs; };
     varnish   = import ./exporters/varnish.nix   { inherit config lib pkgs; };
     bind      = import ./exporters/bind.nix      { inherit config lib pkgs; };
+    wireguard = import ./exporters/wireguard.nix { inherit config lib pkgs; };
   };
 
   mkExporterOpts = ({ name, port }: {
diff --git a/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix b/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix
new file mode 100644
index 00000000000..c5b84e574b8
--- /dev/null
+++ b/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix
@@ -0,0 +1,42 @@
+{ config, lib, pkgs }:
+
+with lib;
+
+let
+  cfg = config.services.prometheus.exporters.wireguard;
+in {
+  port = 9586;
+  extraOpts = {
+    verbose = mkEnableOption "Verbose logging mode for prometheus-wireguard-exporter";
+
+    wireguardConfig = mkOption {
+      type = with types; nullOr (either path str);
+      default = null;
+
+      description = ''
+        Path to the Wireguard Config to
+        <link xlink:href="https://github.com/MindFlavor/prometheus_wireguard_exporter/tree/2.0.0#usage">add the peer's name to the stats of a peer</link>.
+
+        Please note that <literal>networking.wg-quick</literal> is required for this feature
+        as <literal>networking.wireguard</literal> uses
+        <citerefentry><refentrytitle>wg</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        to set the peers up.
+      '';
+    };
+  };
+  serviceOpts = {
+    script = ''
+      ${pkgs.prometheus-wireguard-exporter}/bin/prometheus_wireguard_exporter \
+        -p ${toString cfg.port} \
+        ${optionalString cfg.verbose "-v"} \
+        ${optionalString (cfg.wireguardConfig != null) "-n ${cfg.wireguardConfig}"}
+    '';
+
+    path = [ pkgs.wireguard-tools ];
+
+    serviceConfig = {
+      DynamicUser = true;
+      AmbientCapabilities = [ "CAP_NET_ADMIN" ];
+    };
+  };
+}
diff --git a/nixos/modules/services/networking/mtprotoproxy.nix b/nixos/modules/services/networking/mtprotoproxy.nix
new file mode 100644
index 00000000000..24bf33815da
--- /dev/null
+++ b/nixos/modules/services/networking/mtprotoproxy.nix
@@ -0,0 +1,110 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.mtprotoproxy;
+
+  configOpts = {
+    PORT = cfg.port;
+    USERS = cfg.users;
+    SECURE_ONLY = cfg.secureOnly;
+  } // lib.optionalAttrs (cfg.adTag != null) { AD_TAG = cfg.adTag; }
+    // cfg.extraConfig;
+
+  convertOption = opt:
+    if isString opt || isInt opt then
+      builtins.toJSON opt
+    else if isBool opt then
+      if opt then "True" else "False"
+    else if isList opt then
+      "[" + concatMapStringsSep "," convertOption opt + "]"
+    else if isAttrs opt then
+      "{" + concatStringsSep "," (mapAttrsToList (name: opt: "${builtins.toJSON name}: ${convertOption opt}") opt) + "}"
+    else
+      throw "Invalid option type";
+
+  configFile = pkgs.writeText "config.py" (concatStringsSep "\n" (mapAttrsToList (name: opt: "${name} = ${convertOption opt}") configOpts));
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.mtprotoproxy = {
+
+      enable = mkEnableOption "mtprotoproxy";
+
+      port = mkOption {
+        type = types.int;
+        default = 3256;
+        description = ''
+          TCP port to accept mtproto connections on.
+        '';
+      };
+
+      users = mkOption {
+        type = types.attrsOf types.str;
+        example = {
+          "tg" = "00000000000000000000000000000000";
+          "tg2" = "0123456789abcdef0123456789abcdef";
+        };
+        description = ''
+          Allowed users and their secrets. A secret is a 32 characters long hex string.
+        '';
+      };
+
+      secureOnly = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Don't allow users to connect in non-secure mode (without random padding).
+        '';
+      };
+
+      adTag = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        # Taken from mtproxyproto's repo.
+        example = "3c09c680b76ee91a4c25ad51f742267d";
+        description = ''
+          Tag for advertising that can be obtained from @MTProxybot.
+        '';
+      };
+
+      extraConfig = mkOption {
+        type = types.attrs;
+        default = {};
+        example = {
+          "STATS_PRINT_PERIOD" = 600;
+        };
+        description = ''
+          Extra configuration options for mtprotoproxy.
+        '';
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    systemd.services.mtprotoproxy = {
+      description = "MTProto Proxy Daemon";
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        ExecStart = "${pkgs.mtprotoproxy}/bin/mtprotoproxy ${configFile}";
+        DynamicUser = true;
+      };
+    };
+
+  };
+
+}
diff --git a/nixos/modules/services/networking/wireguard.nix b/nixos/modules/services/networking/wireguard.nix
index c07481582c2..4176da2c8cb 100644
--- a/nixos/modules/services/networking/wireguard.nix
+++ b/nixos/modules/services/networking/wireguard.nix
@@ -244,7 +244,7 @@ let
         description = "WireGuard Peer - ${interfaceName} - ${peer.publicKey}";
         requires = [ "wireguard-${interfaceName}.service" ];
         after = [ "wireguard-${interfaceName}.service" ];
-        wantedBy = [ "multi-user.target" ];
+        wantedBy = [ "multi-user.target" "wireguard-${interfaceName}.service" ];
         environment.DEVICE = interfaceName;
         environment.WG_ENDPOINT_RESOLUTION_RETRIES = "infinity";
         path = with pkgs; [ iproute wireguard-tools ];
@@ -303,7 +303,7 @@ let
         };
 
         script = ''
-          ${optionalString (!config.boot.isContainer) "modprobe wireguard"}
+          ${optionalString (!config.boot.isContainer) "modprobe wireguard || true"}
 
           ${values.preSetup}
 
diff --git a/nixos/modules/services/web-apps/cryptpad.nix b/nixos/modules/services/web-apps/cryptpad.nix
new file mode 100644
index 00000000000..69a89107d31
--- /dev/null
+++ b/nixos/modules/services/web-apps/cryptpad.nix
@@ -0,0 +1,54 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.cryptpad;
+in
+{
+  options.services.cryptpad = {
+    enable = mkEnableOption "the Cryptpad service";
+
+    package = mkOption {
+      default = pkgs.cryptpad;
+      defaultText = "pkgs.cryptpad";
+      type = types.package;
+      description = "
+        Cryptpad package to use.
+      ";
+    };
+
+    configFile = mkOption {
+      type = types.path;
+      default = "${cfg.package}/lib/node_modules/cryptpad/config/config.example.js";
+      defaultText = "\${cfg.package}/lib/node_modules/cryptpad/config/config.example.js";
+      description = ''
+        Path to the JavaScript configuration file.
+
+        See <link
+        xlink:href="https://github.com/xwiki-labs/cryptpad/blob/master/config/config.example.js"/>
+        for a configuration example.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.cryptpad = {
+      description = "Cryptpad Service";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "networking.target" ];
+      serviceConfig = {
+        DynamicUser = true;
+        Environment = [
+          "CRYPTPAD_CONFIG=${cfg.configFile}"
+          "HOME=%S/cryptpad"
+        ];
+        ExecStart = "${cfg.package}/bin/cryptpad";
+        PrivateTmp = true;
+        Restart = "always";
+        StateDirectory = "cryptpad";
+        WorkingDirectory = "%S/cryptpad";
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixos/modules/services/web-servers/apache-httpd/default.nix
index a8fb11f114e..bf99f6c132a 100644
--- a/nixos/modules/services/web-servers/apache-httpd/default.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/default.nix
@@ -8,8 +8,6 @@ let
 
   httpd = mainCfg.package.out;
 
-  version24 = !versionOlder httpd.version "2.4";
-
   httpdConf = mainCfg.configFile;
 
   php = mainCfg.phpPackage.override { apacheHttpd = httpd.dev; /* otherwise it only gets .out */ };
@@ -107,11 +105,10 @@ let
       "auth_basic" "auth_digest"
 
       # Authentication: is the user who he claims to be?
-      "authn_file" "authn_dbm" "authn_anon"
-      (if version24 then "authn_core" else "authn_alias")
+      "authn_file" "authn_dbm" "authn_anon" "authn_core"
 
       # Authorization: is the user allowed access?
-      "authz_user" "authz_groupfile" "authz_host"
+      "authz_user" "authz_groupfile" "authz_host" "authz_core"
 
       # Other modules.
       "ext_filter" "include" "log_config" "env" "mime_magic"
@@ -119,14 +116,9 @@ let
       "mime" "dav" "status" "autoindex" "asis" "info" "dav_fs"
       "vhost_alias" "negotiation" "dir" "imagemap" "actions" "speling"
       "userdir" "alias" "rewrite" "proxy" "proxy_http"
-    ]
-    ++ optionals version24 [
+      "unixd" "cache" "cache_disk" "slotmem_shm" "socache_shmcb"
       "mpm_${mainCfg.multiProcessingModule}"
-      "authz_core"
-      "unixd"
-      "cache" "cache_disk"
-      "slotmem_shm"
-      "socache_shmcb"
+
       # For compatibility with old configurations, the new module mod_access_compat is provided.
       "access_compat"
     ]
@@ -135,19 +127,8 @@ let
     ++ extraApacheModules;
 
 
-  allDenied = if version24 then ''
-    Require all denied
-  '' else ''
-    Order deny,allow
-    Deny from all
-  '';
-
-  allGranted = if version24 then ''
-    Require all granted
-  '' else ''
-    Order allow,deny
-    Allow from all
-  '';
+  allDenied = "Require all denied";
+  allGranted = "Require all granted";
 
 
   loggingConf = (if mainCfg.logFormat != "none" then ''
@@ -180,9 +161,9 @@ let
 
 
   sslConf = ''
-    SSLSessionCache ${if version24 then "shmcb" else "shm"}:${mainCfg.stateDir}/ssl_scache(512000)
+    SSLSessionCache shmcb:${mainCfg.stateDir}/ssl_scache(512000)
 
-    ${if version24 then "Mutex" else "SSLMutex"} posixsem
+    Mutex posixsem
 
     SSLRandomSeed startup builtin
     SSLRandomSeed connect builtin
@@ -322,9 +303,7 @@ let
 
     ServerRoot ${httpd}
 
-    ${optionalString version24 ''
-      DefaultRuntimeDir ${mainCfg.stateDir}/runtime
-    ''}
+    DefaultRuntimeDir ${mainCfg.stateDir}/runtime
 
     PidFile ${mainCfg.stateDir}/httpd.pid
 
@@ -397,14 +376,6 @@ let
     # Generate directives for the main server.
     ${perServerConf true mainCfg}
 
-    # Always enable virtual hosts; it doesn't seem to hurt.
-    ${let
-        listen = concatMap getListen allHosts;
-        uniqueListen = uniqList {inputList = listen;};
-        directives = concatMapStrings (listen: "NameVirtualHost ${listenToString listen}\n") uniqueListen;
-      in optionalString (!version24) directives
-    }
-
     ${let
         makeVirtualHost = vhost: ''
           <VirtualHost ${concatStringsSep " " (map listenToString (getListen vhost))}>
@@ -717,10 +688,10 @@ in
           ''
             mkdir -m 0750 -p ${mainCfg.stateDir}
             [ $(id -u) != 0 ] || chown root.${mainCfg.group} ${mainCfg.stateDir}
-            ${optionalString version24 ''
-              mkdir -m 0750 -p "${mainCfg.stateDir}/runtime"
-              [ $(id -u) != 0 ] || chown root.${mainCfg.group} "${mainCfg.stateDir}/runtime"
-            ''}
+
+            mkdir -m 0750 -p "${mainCfg.stateDir}/runtime"
+            [ $(id -u) != 0 ] || chown root.${mainCfg.group} "${mainCfg.stateDir}/runtime"
+
             mkdir -m 0700 -p ${mainCfg.logDir}
 
             # Get rid of old semaphores.  These tend to accumulate across
diff --git a/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix b/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix
index ff90a9b4617..2d27611946e 100644
--- a/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix
+++ b/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix
@@ -7,8 +7,8 @@ let
   generationsDirBuilder = pkgs.substituteAll {
     src = ./generations-dir-builder.sh;
     isExecutable = true;
-    inherit (pkgs.buildPackages) bash;
-    path = with pkgs.buildPackages; [coreutils gnused gnugrep];
+    inherit (pkgs) bash;
+    path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
     inherit (config.boot.loader.generationsDir) copyKernels;
   };
 
diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix b/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix
index 5f5dbe1092d..af39c7bb684 100644
--- a/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix
+++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix
@@ -8,7 +8,7 @@ let
 
   timeoutStr = if blCfg.timeout == null then "-1" else toString blCfg.timeout;
 
-  builder = import ./extlinux-conf-builder.nix { pkgs = pkgs.buildPackages; };
+  builder = import ./extlinux-conf-builder.nix { inherit pkgs; };
 in
 {
   options = {
diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
index 9ac6b6b1224..576a07c1d27 100644
--- a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
+++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
@@ -3,6 +3,6 @@
 pkgs.substituteAll {
   src = ./extlinux-conf-builder.sh;
   isExecutable = true;
-  path = [pkgs.buildPackages.coreutils pkgs.buildPackages.gnused pkgs.buildPackages.gnugrep];
-  inherit (pkgs.buildPackages) bash;
+  path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
+  inherit (pkgs) bash;
 }
diff --git a/nixos/modules/system/boot/loader/init-script/init-script.nix b/nixos/modules/system/boot/loader/init-script/init-script.nix
index 385a2603678..374d9524ff1 100644
--- a/nixos/modules/system/boot/loader/init-script/init-script.nix
+++ b/nixos/modules/system/boot/loader/init-script/init-script.nix
@@ -7,8 +7,8 @@ let
   initScriptBuilder = pkgs.substituteAll {
     src = ./init-script-builder.sh;
     isExecutable = true;
-    inherit (pkgs.buildPackages) bash;
-    path = with pkgs.buildPackages; [coreutils gnused gnugrep];
+    inherit (pkgs) bash;
+    path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
   };
 
 in
diff --git a/nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix b/nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix
index 94599a0081c..9d4f8a93d28 100644
--- a/nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix
+++ b/nixos/modules/system/boot/loader/raspberrypi/uboot-builder.nix
@@ -18,17 +18,18 @@ let
 
   extlinuxConfBuilder =
     import ../generic-extlinux-compatible/extlinux-conf-builder.nix {
-      pkgs = pkgs.buildPackages;
+      inherit pkgs;
     };
 in
 pkgs.substituteAll {
   src = ./uboot-builder.sh;
   isExecutable = true;
-  inherit (pkgs.buildPackages) bash;
-  path = with pkgs.buildPackages; [coreutils gnused gnugrep];
+  inherit (pkgs) bash;
+  path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
   firmware = pkgs.raspberrypifw;
   inherit uboot;
   inherit configTxt;
   inherit extlinuxConfBuilder;
   inherit version;
 }
+
diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
index ad464a456bc..3e39dc5dd39 100644
--- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
+++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
@@ -12,7 +12,7 @@ let
 
     isExecutable = true;
 
-    inherit (pkgs.buildPackages) python3;
+    inherit (pkgs) python3;
 
     systemd = config.systemd.package;
 
diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix
index 37a19fb9fc8..93bbd141284 100644
--- a/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixos/modules/tasks/filesystems/zfs.nix
@@ -24,11 +24,9 @@ let
   kernel = config.boot.kernelPackages;
 
   packages = if config.boot.zfs.enableUnstable then {
-    spl = null;
     zfs = kernel.zfsUnstable;
     zfsUser = pkgs.zfsUnstable;
   } else {
-    spl = kernel.spl;
     zfs = kernel.zfs;
     zfsUser = pkgs.zfs;
   };
@@ -325,8 +323,8 @@ in
       virtualisation.lxd.zfsSupport = true;
 
       boot = {
-        kernelModules = [ "zfs" ] ++ optional (!cfgZfs.enableUnstable) "spl";
-        extraModulePackages = with packages; [ zfs ] ++ optional (!cfgZfs.enableUnstable) spl;
+        kernelModules = [ "zfs" ];
+        extraModulePackages = with packages; [ zfs ];
       };
 
       boot.initrd = mkIf inInitrd {
diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix
index d10c4feecb4..97243e3304e 100644
--- a/nixos/modules/virtualisation/containers.nix
+++ b/nixos/modules/virtualisation/containers.nix
@@ -689,7 +689,7 @@ in
       [{ name = "container@"; value = unit; }]
       # declarative containers
       ++ (mapAttrsToList (name: cfg: nameValuePair "container@${name}" (let
-          config = cfg // (
+          containerConfig = cfg // (
           if cfg.enableTun then
             {
               allowedDevices = cfg.allowedDevices
@@ -700,18 +700,21 @@ in
           else {});
         in
           unit // {
-            preStart = preStartScript config;
-            script = startScript config;
-            postStart = postStartScript config;
-            serviceConfig = serviceDirectives config;
+            preStart = preStartScript containerConfig;
+            script = startScript containerConfig;
+            postStart = postStartScript containerConfig;
+            serviceConfig = serviceDirectives containerConfig;
           } // (
-          if config.autoStart then
+          if containerConfig.autoStart then
             {
               wantedBy = [ "machines.target" ];
               wants = [ "network.target" ];
               after = [ "network.target" ];
-              restartTriggers = [ config.path ];
-              reloadIfChanged = true;
+              restartTriggers = [
+                containerConfig.path
+                config.environment.etc."containers/${name}.conf".source
+              ];
+              restartIfChanged = true;
             }
           else {})
       )) config.containers)
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 2f84850f6b3..7ec3ede3832 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -249,6 +249,7 @@ in
   transmission = handleTest ./transmission.nix {};
   udisks2 = handleTest ./udisks2.nix {};
   upnp = handleTest ./upnp.nix {};
+  uwsgi = handleTest ./uwsgi.nix {};
   vault = handleTest ./vault.nix {};
   virtualbox = handleTestOn ["x86_64-linux"] ./virtualbox.nix {};
   wireguard = handleTest ./wireguard {};
diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix
index f91121077ea..9ab1a71f331 100644
--- a/nixos/tests/docker-tools.nix
+++ b/nixos/tests/docker-tools.nix
@@ -68,6 +68,12 @@ import ./make-test.nix ({ pkgs, ... }: {
       $docker->succeed("docker load --input='${pkgs.dockerTools.examples.layered-on-top}'");
       $docker->succeed("docker run --rm ${pkgs.dockerTools.examples.layered-on-top.imageName}");
 
+      # Ensure layers are shared between images
+      $docker->succeed("docker load --input='${pkgs.dockerTools.examples.another-layered-image}'");
+      $docker->succeed("docker inspect ${pkgs.dockerTools.examples.layered-image.imageName} | ${pkgs.jq}/bin/jq -r '.[] | .RootFS.Layers | .[]' | sort > layers1.sha256");
+      $docker->succeed("docker inspect ${pkgs.dockerTools.examples.another-layered-image.imageName} | ${pkgs.jq}/bin/jq -r '.[] | .RootFS.Layers | .[]' | sort > layers2.sha256");
+      $docker->succeed('[ $(comm -1 -2 layers1.sha256 layers2.sha256 | wc -l) -ne 0 ]');
+
       # Ensure order of layers is correct
       $docker->succeed("docker load --input='${pkgs.dockerTools.examples.layersOrder}'");
       $docker->succeed("docker run --rm  ${pkgs.dockerTools.examples.layersOrder.imageName} cat /tmp/layer1 | grep -q layer1");
diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix
index ac50ca93489..90c7c9701f6 100644
--- a/nixos/tests/prometheus-exporters.nix
+++ b/nixos/tests/prometheus-exporters.nix
@@ -315,6 +315,29 @@ let
         succeed("curl -sSf http://localhost:9131/metrics | grep -q 'varnish_up 1'");
       '';
     };
+
+    wireguard = let snakeoil = import ./wireguard/snakeoil-keys.nix; in {
+      exporterConfig.enable = true;
+      metricProvider = {
+        networking.wireguard.interfaces.wg0 = {
+          ips = [ "10.23.42.1/32" "fc00::1/128" ];
+          listenPort = 23542;
+
+          inherit (snakeoil.peer0) privateKey;
+
+          peers = singleton {
+            allowedIPs = [ "10.23.42.2/32" "fc00::2/128" ];
+
+            inherit (snakeoil.peer1) publicKey;
+          };
+        };
+      };
+      exporterTest = ''
+        waitForUnit("prometheus-wireguard-exporter.service");
+        waitForOpenPort(9586);
+        succeed("curl -sSf http://localhost:9586/metrics | grep '${snakeoil.peer1.publicKey}'");
+      '';
+    };
   };
 in
 mapAttrs (exporter: testConfig: (makeTest {
diff --git a/nixos/tests/slurm.nix b/nixos/tests/slurm.nix
index 720c36d472e..4c2cd3c3d26 100644
--- a/nixos/tests/slurm.nix
+++ b/nixos/tests/slurm.nix
@@ -135,8 +135,8 @@ in {
 
   subtest "check_slurm_dbd", sub {
     # find the srun job from above in the database
-    sleep 2;
-    $submit->succeed("sacct | grep hostname");
+    sleep 5;
+    $control->succeed("sacct | grep hostname");
   };
   '';
 })
diff --git a/nixos/tests/uwsgi.nix b/nixos/tests/uwsgi.nix
new file mode 100644
index 00000000000..afc03e74ed7
--- /dev/null
+++ b/nixos/tests/uwsgi.nix
@@ -0,0 +1,38 @@
+import ./make-test.nix ({ pkgs, ... }:
+{
+  name = "uwsgi";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ lnl7 ];
+  };
+  machine = { pkgs, ... }: {
+    services.uwsgi.enable = true;
+    services.uwsgi.plugins = [ "python3" ];
+    services.uwsgi.instance = {
+      type = "emperor";
+      vassals.hello = {
+        type = "normal";
+        master = true;
+        workers = 2;
+        http = ":8000";
+        module = "wsgi:application";
+        chdir = pkgs.writeTextDir "wsgi.py" ''
+          from flask import Flask
+          application = Flask(__name__)
+
+          @application.route("/")
+          def hello():
+              return "Hello World!"
+        '';
+        pythonPackages = self: with self; [ flask ];
+      };
+    };
+  };
+
+  testScript =
+    ''
+      $machine->waitForUnit('multi-user.target');
+      $machine->waitForUnit('uwsgi.service');
+      $machine->waitForOpenPort(8000);
+      $machine->succeed('curl -v 127.0.0.1:8000 | grep "Hello World!"');
+    '';
+})