about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/development/option-declarations.section.md4
-rw-r--r--nixos/doc/manual/from_md/development/option-declarations.section.xml12
-rw-r--r--nixos/doc/manual/from_md/installation/upgrading.chapter.xml4
-rw-r--r--nixos/doc/manual/from_md/release-notes/rl-2305.section.xml16
-rw-r--r--nixos/doc/manual/installation/upgrading.chapter.md4
-rw-r--r--nixos/doc/manual/release-notes/rl-2305.section.md4
-rw-r--r--nixos/lib/make-options-doc/mergeJSON.py9
-rw-r--r--nixos/modules/config/users-groups.nix4
-rw-r--r--nixos/modules/misc/documentation.nix2
-rw-r--r--nixos/modules/misc/version.nix9
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/profiles/installation-device.nix1
-rw-r--r--nixos/modules/profiles/macos-builder.nix10
-rw-r--r--nixos/modules/programs/_1password-gui.nix2
-rw-r--r--nixos/modules/programs/_1password.nix2
-rw-r--r--nixos/modules/programs/flashrom.nix2
-rw-r--r--nixos/modules/programs/gnupg.nix2
-rw-r--r--nixos/modules/programs/iay.nix37
-rw-r--r--nixos/modules/programs/nix-ld.nix29
-rw-r--r--nixos/modules/programs/skim.nix4
-rw-r--r--nixos/modules/programs/streamdeck-ui.nix2
-rw-r--r--nixos/modules/rename.nix2
-rw-r--r--nixos/modules/services/continuous-integration/gitlab-runner.nix90
-rw-r--r--nixos/modules/services/databases/dgraph.nix2
-rw-r--r--nixos/modules/services/desktops/pipewire/daemon/jack.conf.json25
-rw-r--r--nixos/modules/services/desktops/pipewire/daemon/pipewire-pulse.conf.json15
-rw-r--r--nixos/modules/services/desktops/pipewire/daemon/pipewire.conf.json8
-rw-r--r--nixos/modules/services/mail/listmonk.nix2
-rw-r--r--nixos/modules/services/misc/input-remapper.nix2
-rw-r--r--nixos/modules/services/misc/paperless.nix21
-rw-r--r--nixos/modules/services/misc/polaris.nix2
-rw-r--r--nixos/modules/services/monitoring/apcupsd.nix17
-rw-r--r--nixos/modules/services/monitoring/parsedmarc.md1
-rw-r--r--nixos/modules/services/monitoring/parsedmarc.nix46
-rw-r--r--nixos/modules/services/monitoring/parsedmarc.xml7
-rw-r--r--nixos/modules/services/networking/ntp/chrony.nix56
-rw-r--r--nixos/modules/services/networking/openconnect.nix2
-rw-r--r--nixos/modules/services/networking/radicale.nix2
-rw-r--r--nixos/modules/services/networking/shellhub-agent.nix2
-rw-r--r--nixos/modules/services/networking/ssh/sshd.nix4
-rw-r--r--nixos/modules/services/networking/vdirsyncer.nix2
-rw-r--r--nixos/modules/services/networking/webhook.nix2
-rw-r--r--nixos/modules/services/torrent/transmission.nix6
-rw-r--r--nixos/modules/services/web-apps/snipe-it.nix5
-rw-r--r--nixos/modules/services/web-servers/nginx/default.nix2
-rw-r--r--nixos/modules/services/x11/desktop-managers/cinnamon.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/plasma5.nix11
-rw-r--r--nixos/modules/services/x11/picom.nix2
-rw-r--r--nixos/modules/services/x11/window-managers/i3.nix3
-rw-r--r--nixos/modules/services/x11/window-managers/katriawm.nix4
-rw-r--r--nixos/modules/services/x11/window-managers/qtile.nix2
-rw-r--r--nixos/modules/system/boot/systemd/initrd.nix2
-rw-r--r--nixos/modules/virtualisation/podman/default.nix47
-rw-r--r--nixos/modules/virtualisation/podman/dnsname.nix36
-rw-r--r--nixos/modules/virtualisation/waydroid.nix6
-rw-r--r--nixos/tests/all-tests.nix2
-rw-r--r--nixos/tests/apcupsd.nix41
-rw-r--r--nixos/tests/paperless.nix4
-rw-r--r--nixos/tests/parsedmarc/default.nix1
-rw-r--r--nixos/tests/podman/default.nix25
-rw-r--r--nixos/tests/podman/dnsname.nix42
-rw-r--r--nixos/tests/wordpress.nix33
62 files changed, 488 insertions, 257 deletions
diff --git a/nixos/doc/manual/development/option-declarations.section.md b/nixos/doc/manual/development/option-declarations.section.md
index f89aae5730682..aa747f47c9c81 100644
--- a/nixos/doc/manual/development/option-declarations.section.md
+++ b/nixos/doc/manual/development/option-declarations.section.md
@@ -88,7 +88,7 @@ lib.mkOption {
 }
 ```
 
-### `mkPackageOption` {#sec-option-declarations-util-mkPackageOption}
+### `mkPackageOption`, `mkPackageOptionMD` {#sec-option-declarations-util-mkPackageOption}
 
 Usage:
 
@@ -106,6 +106,8 @@ The second argument is the name of the option, used in the description "The \<na
 
 You can omit the default path if the name of the option is also attribute path in nixpkgs.
 
+During the transition to CommonMark documentation `mkPackageOption` creates an option with a DocBook description attribute, once the transition is completed it will create a CommonMark description instead. `mkPackageOptionMD` always creates an option with a CommonMark description attribute and will be removed some time after the transition is completed.
+
 ::: {#ex-options-declarations-util-mkPackageOption .title}
 Examples:
 
diff --git a/nixos/doc/manual/from_md/development/option-declarations.section.xml b/nixos/doc/manual/from_md/development/option-declarations.section.xml
index 2e6a12d530953..cc4893939c280 100644
--- a/nixos/doc/manual/from_md/development/option-declarations.section.xml
+++ b/nixos/doc/manual/from_md/development/option-declarations.section.xml
@@ -138,7 +138,8 @@ lib.mkOption {
 }
 </programlisting>
       <section xml:id="sec-option-declarations-util-mkPackageOption">
-        <title><literal>mkPackageOption</literal></title>
+        <title><literal>mkPackageOption</literal>,
+        <literal>mkPackageOptionMD</literal></title>
         <para>
           Usage:
         </para>
@@ -172,6 +173,15 @@ mkPackageOption pkgs &quot;name&quot; { default = [ &quot;path&quot; &quot;in&qu
           You can omit the default path if the name of the option is
           also attribute path in nixpkgs.
         </para>
+        <para>
+          During the transition to CommonMark documentation
+          <literal>mkPackageOption</literal> creates an option with a
+          DocBook description attribute, once the transition is
+          completed it will create a CommonMark description instead.
+          <literal>mkPackageOptionMD</literal> always creates an option
+          with a CommonMark description attribute and will be removed
+          some time after the transition is completed.
+        </para>
         <anchor xml:id="ex-options-declarations-util-mkPackageOption" />
         <para>
           Examples:
diff --git a/nixos/doc/manual/from_md/installation/upgrading.chapter.xml b/nixos/doc/manual/from_md/installation/upgrading.chapter.xml
index 9f4cfaf36b628..99882784b46fc 100644
--- a/nixos/doc/manual/from_md/installation/upgrading.chapter.xml
+++ b/nixos/doc/manual/from_md/installation/upgrading.chapter.xml
@@ -12,7 +12,7 @@
     <listitem>
       <para>
         <emphasis>Stable channels</emphasis>, such as
-        <link xlink:href="https://nixos.org/channels/nixos-22.05"><literal>nixos-22.11</literal></link>.
+        <link xlink:href="https://nixos.org/channels/nixos-22.11"><literal>nixos-22.11</literal></link>.
         These only get conservative bug fixes and package upgrades. For
         instance, a channel update may cause the Linux kernel on your
         system to be upgraded from 4.19.34 to 4.19.38 (a minor bug fix),
@@ -33,7 +33,7 @@
     <listitem>
       <para>
         <emphasis>Small channels</emphasis>, such as
-        <link xlink:href="https://nixos.org/channels/nixos-22.05-small"><literal>nixos-22.11-small</literal></link>
+        <link xlink:href="https://nixos.org/channels/nixos-22.11-small"><literal>nixos-22.11-small</literal></link>
         or
         <link xlink:href="https://nixos.org/channels/nixos-unstable-small"><literal>nixos-unstable-small</literal></link>.
         These are identical to the stable and unstable channels
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml
index ea3be31a20606..12e4d490300ec 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml
@@ -117,6 +117,15 @@
       </listitem>
       <listitem>
         <para>
+          <literal>podman</literal> now uses the
+          <literal>netavark</literal> network stack. Users will need to
+          delete all of their local containers, images, volumes, etc, by
+          running <literal>podman system reset --force</literal> once
+          before upgrading their systems.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
           The EC2 image module no longer fetches instance metadata in
           stage-1. This results in a significantly smaller initramfs,
           since network drivers no longer need to be included, and
@@ -341,6 +350,13 @@
       </listitem>
       <listitem>
         <para>
+          <literal>services.chronyd</literal> is now started with
+          additional systemd sandbox/hardening options for better
+          security.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
           The module <literal>services.headscale</literal> was
           refactored to be compliant with
           <link xlink:href="https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md">RFC
diff --git a/nixos/doc/manual/installation/upgrading.chapter.md b/nixos/doc/manual/installation/upgrading.chapter.md
index 249bcd97cec84..26b6b8cc23ef1 100644
--- a/nixos/doc/manual/installation/upgrading.chapter.md
+++ b/nixos/doc/manual/installation/upgrading.chapter.md
@@ -6,7 +6,7 @@ expressions and associated binaries. The NixOS channels are updated
 automatically from NixOS's Git repository after certain tests have
 passed and all packages have been built. These channels are:
 
--   *Stable channels*, such as [`nixos-22.11`](https://nixos.org/channels/nixos-22.05).
+-   *Stable channels*, such as [`nixos-22.11`](https://nixos.org/channels/nixos-22.11).
     These only get conservative bug fixes and package upgrades. For
     instance, a channel update may cause the Linux kernel on your system
     to be upgraded from 4.19.34 to 4.19.38 (a minor bug fix), but not
@@ -19,7 +19,7 @@ passed and all packages have been built. These channels are:
     radical changes between channel updates. It's not recommended for
     production systems.
 
--   *Small channels*, such as [`nixos-22.11-small`](https://nixos.org/channels/nixos-22.05-small)
+-   *Small channels*, such as [`nixos-22.11-small`](https://nixos.org/channels/nixos-22.11-small)
     or [`nixos-unstable-small`](https://nixos.org/channels/nixos-unstable-small).
     These are identical to the stable and unstable channels described above,
     except that they contain fewer binary packages. This means they get updated
diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md
index df0ec622e56e7..07ee346c2c872 100644
--- a/nixos/doc/manual/release-notes/rl-2305.section.md
+++ b/nixos/doc/manual/release-notes/rl-2305.section.md
@@ -40,6 +40,8 @@ In addition to numerous new and upgraded packages, this release has the followin
 
 - `borgbackup` module now has an option for inhibiting system sleep while backups are running, defaulting to off (not inhibiting sleep), available as [`services.borgbackup.jobs.<name>.inhibitsSleep`](#opt-services.borgbackup.jobs._name_.inhibitsSleep).
 
+- `podman` now uses the `netavark` network stack. Users will need to delete all of their local containers, images, volumes, etc, by running `podman system reset --force` once before upgrading their systems.
+
 - The EC2 image module no longer fetches instance metadata in stage-1. This results in a significantly smaller initramfs, since network drivers no longer need to be included, and faster boots, since metadata fetching can happen in parallel with startup of other services.
   This breaks services which rely on metadata being present by the time stage-2 is entered. Anything which reads EC2 metadata from `/etc/ec2-metadata` should now have an `after` dependency on `fetch-ec2-metadata.service`
 
@@ -94,6 +96,8 @@ In addition to numerous new and upgraded packages, this release has the followin
 
   And backup your data.
 
+- `services.chronyd` is now started with additional systemd sandbox/hardening options for better security.
+
 - The module `services.headscale` was refactored to be compliant with [RFC 0042](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md). To be precise, this means that the following things have changed:
 
   - Most settings has been migrated under [services.headscale.settings](#opt-services.headscale.settings) which is an attribute-set that
diff --git a/nixos/lib/make-options-doc/mergeJSON.py b/nixos/lib/make-options-doc/mergeJSON.py
index 750cd24fc653d..7b14af40c313b 100644
--- a/nixos/lib/make-options-doc/mergeJSON.py
+++ b/nixos/lib/make-options-doc/mergeJSON.py
@@ -306,14 +306,17 @@ if hasDocBookErrors:
     print("Explanation: The documentation contains descriptions, examples, or defaults written in DocBook. " +
         "NixOS is in the process of migrating from DocBook to Markdown, and " +
         "DocBook is disallowed for in-tree modules. To change your contribution to "+
-        "use Markdown, apply mdDoc and literalMD. For example:\n" +
+        "use Markdown, apply mdDoc and literalMD and use the *MD variants of option creation " +
+        "functions where they are available. For example:\n" +
         "\n" +
         "  example.foo = mkOption {\n" +
         "    description = lib.mdDoc ''your description'';\n" +
         "    defaultText = lib.literalMD ''your description of default'';\n" +
-        "  }\n" +
+        "  };\n" +
         "\n" +
-        "  example.enable = mkEnableOption (lib.mdDoc ''your thing'');",
+        "  example.enable = mkEnableOption (lib.mdDoc ''your thing'');\n" +
+        "  example.package = mkPackageOptionMD pkgs \"your-package\" {};\n" +
+        "  imports = [ (mkAliasOptionModuleMD [ \"example\" \"args\" ] [ \"example\" \"settings\" ]) ];",
         file = sys.stderr)
 
 if hasErrors:
diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix
index 19319b9309cd1..76092e738ebd4 100644
--- a/nixos/modules/config/users-groups.nix
+++ b/nixos/modules/config/users-groups.nix
@@ -444,8 +444,8 @@ let
 
 in {
   imports = [
-    (mkAliasOptionModule [ "users" "extraUsers" ] [ "users" "users" ])
-    (mkAliasOptionModule [ "users" "extraGroups" ] [ "users" "groups" ])
+    (mkAliasOptionModuleMD [ "users" "extraUsers" ] [ "users" "users" ])
+    (mkAliasOptionModuleMD [ "users" "extraGroups" ] [ "users" "groups" ])
     (mkRenamedOptionModule ["security" "initialRootPassword"] ["users" "users" "root" "initialHashedPassword"])
   ];
 
diff --git a/nixos/modules/misc/documentation.nix b/nixos/modules/misc/documentation.nix
index 64a8f7846b463..e44a9899772f1 100644
--- a/nixos/modules/misc/documentation.nix
+++ b/nixos/modules/misc/documentation.nix
@@ -50,7 +50,7 @@ let
           (name: value:
             let
               wholeName = "${namePrefix}.${name}";
-              guard = lib.warn "Attempt to evaluate package ${wholeName} in option documentation; this is not supported and will eventually be an error. Use `mkPackageOption` or `literalExpression` instead.";
+              guard = lib.warn "Attempt to evaluate package ${wholeName} in option documentation; this is not supported and will eventually be an error. Use `mkPackageOption{,MD}` or `literalExpression` instead.";
             in if isAttrs value then
               scrubDerivations wholeName value
               // optionalAttrs (isDerivation value) {
diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix
index 1067b21a22b07..c9e06382b7ac2 100644
--- a/nixos/modules/misc/version.nix
+++ b/nixos/modules/misc/version.nix
@@ -28,6 +28,8 @@ let
     DOCUMENTATION_URL = "https://nixos.org/learn.html";
     SUPPORT_URL = "https://nixos.org/community.html";
     BUG_REPORT_URL = "https://github.com/NixOS/nixpkgs/issues";
+  } // lib.optionalAttrs (cfg.variant_id != null) {
+    VARIANT_ID = cfg.variant_id;
   };
 
   initrdReleaseContents = osReleaseContents // {
@@ -87,6 +89,13 @@ in
       description = lib.mdDoc "The NixOS release code name (e.g. `Emu`).";
     };
 
+    nixos.variant_id = mkOption {
+      type = types.nullOr (types.strMatching "^[a-z0-9._-]+$");
+      default = null;
+      description = lib.mdDoc "A lower-case string identifying a specific variant or edition of the operating system";
+      example = "installer";
+    };
+
     stateVersion = mkOption {
       type = types.str;
       # TODO Remove this and drop the default of the option so people are forced to set it.
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 41b953dc34733..b2e80b10fc243 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -179,6 +179,7 @@
   ./programs/haguichi.nix
   ./programs/hamster.nix
   ./programs/htop.nix
+  ./programs/iay.nix
   ./programs/iftop.nix
   ./programs/i3lock.nix
   ./programs/iotop.nix
diff --git a/nixos/modules/profiles/installation-device.nix b/nixos/modules/profiles/installation-device.nix
index ae9be08c8d859..4d9bd69666c09 100644
--- a/nixos/modules/profiles/installation-device.nix
+++ b/nixos/modules/profiles/installation-device.nix
@@ -20,6 +20,7 @@ with lib;
     ];
 
   config = {
+    system.nixos.variant_id = lib.mkDefault "installer";
 
     # Enable in installer, even if the minimal profile disables it.
     documentation.enable = mkImageMediaOverride true;
diff --git a/nixos/modules/profiles/macos-builder.nix b/nixos/modules/profiles/macos-builder.nix
index fddf19ad12517..4a5359582bce0 100644
--- a/nixos/modules/profiles/macos-builder.nix
+++ b/nixos/modules/profiles/macos-builder.nix
@@ -59,10 +59,14 @@ in
     trusted-users = [ "root" user ];
   };
 
-  services.openssh = {
-    enable = true;
+  services = {
+    getty.autologinUser = user;
 
-    authorizedKeysFiles = [ "${keysDirectory}/%u_${keyType}.pub" ];
+    openssh = {
+      enable = true;
+
+      authorizedKeysFiles = [ "${keysDirectory}/%u_${keyType}.pub" ];
+    };
   };
 
   system.build.macos-builder-installer =
diff --git a/nixos/modules/programs/_1password-gui.nix b/nixos/modules/programs/_1password-gui.nix
index 83ef6037fb5a3..27c0d34a2eedf 100644
--- a/nixos/modules/programs/_1password-gui.nix
+++ b/nixos/modules/programs/_1password-gui.nix
@@ -27,7 +27,7 @@ in
         '';
       };
 
-      package = mkPackageOption pkgs "1Password GUI" {
+      package = mkPackageOptionMD pkgs "1Password GUI" {
         default = [ "_1password-gui" ];
       };
     };
diff --git a/nixos/modules/programs/_1password.nix b/nixos/modules/programs/_1password.nix
index 91246150755d5..8537484c7e67d 100644
--- a/nixos/modules/programs/_1password.nix
+++ b/nixos/modules/programs/_1password.nix
@@ -18,7 +18,7 @@ in
     programs._1password = {
       enable = mkEnableOption (lib.mdDoc "the 1Password CLI tool");
 
-      package = mkPackageOption pkgs "1Password CLI" {
+      package = mkPackageOptionMD pkgs "1Password CLI" {
         default = [ "_1password" ];
       };
     };
diff --git a/nixos/modules/programs/flashrom.nix b/nixos/modules/programs/flashrom.nix
index ff495558c9e04..294b208a37208 100644
--- a/nixos/modules/programs/flashrom.nix
+++ b/nixos/modules/programs/flashrom.nix
@@ -16,7 +16,7 @@ in
         group.
       '';
     };
-    package = mkPackageOption pkgs "flashrom" { };
+    package = mkPackageOptionMD pkgs "flashrom" { };
   };
 
   config = mkIf cfg.enable {
diff --git a/nixos/modules/programs/gnupg.nix b/nixos/modules/programs/gnupg.nix
index 828f24f99111d..cb8d0ecff4cb8 100644
--- a/nixos/modules/programs/gnupg.nix
+++ b/nixos/modules/programs/gnupg.nix
@@ -135,7 +135,7 @@ in
       # The SSH agent protocol doesn't have support for changing TTYs; however we
       # can simulate this with the `exec` feature of openssh (see ssh_config(5))
       # that hooks a command to the shell currently running the ssh program.
-      Match host * exec "${cfg.package}/bin/gpg-connect-agent --quiet updatestartuptty /bye >/dev/null 2>&1"
+      Match host * exec "${pkgs.runtimeShell} -c '${cfg.package}/bin/gpg-connect-agent --quiet updatestartuptty /bye >/dev/null 2>&1'"
     '';
 
     environment.extraInit = mkIf cfg.agent.enableSSHSupport ''
diff --git a/nixos/modules/programs/iay.nix b/nixos/modules/programs/iay.nix
new file mode 100644
index 0000000000000..1fa00e43795ad
--- /dev/null
+++ b/nixos/modules/programs/iay.nix
@@ -0,0 +1,37 @@
+{ config, lib, pkgs, ... }:
+
+let
+  cfg = config.programs.iay;
+  inherit (lib) mkEnableOption mkIf mkOption mkPackageOption optionalString types;
+in {
+  options.programs.iay = {
+    enable = mkEnableOption (lib.mdDoc "iay");
+    package = mkPackageOption pkgs "iay" {};
+
+    minimalPrompt = mkOption {
+      type = types.bool;
+      default = false;
+      description = lib.mdDoc "Use minimal one-liner prompt.";
+    };
+  };
+
+  config = mkIf cfg.enable {
+    programs.bash.promptInit = ''
+      if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then
+        PS1='$(iay ${optionalString cfg.minimalPrompt "-m"})'
+      fi
+    '';
+
+    programs.zsh.promptInit = ''
+      if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then
+        autoload -Uz add-zsh-hook
+        _iay_prompt() {
+          PROMPT="$(iay -z ${optionalString cfg.minimalPrompt "-m"})"
+        }
+        add-zsh-hook precmd _iay_prompt
+      fi
+    '';
+  };
+
+  meta.maintainers = pkgs.iay.meta.maintainers;
+}
diff --git a/nixos/modules/programs/nix-ld.nix b/nixos/modules/programs/nix-ld.nix
index f753cf5f97e5b..9a12b4ca5c74f 100644
--- a/nixos/modules/programs/nix-ld.nix
+++ b/nixos/modules/programs/nix-ld.nix
@@ -36,23 +36,22 @@ let
 in
 {
   meta.maintainers = [ lib.maintainers.mic92 ];
-  options = {
-    programs.nix-ld = {
-      enable = lib.mkEnableOption (lib.mdDoc ''nix-ld, Documentation: <https://github.com/Mic92/nix-ld>'');
-      package = lib.mkOption {
-        type = lib.types.package;
-        description = lib.mdDoc "Which package to use for the nix-ld.";
-        default = pkgs.nix-ld;
-        defaultText = lib.mdDoc "pkgs.nix-ld";
-      };
-      libraries = lib.mkOption {
-        type = lib.types.listOf lib.types.package;
-        description = lib.mdDoc "Libraries that automatically become available to all programs. The default set includes common libraries.";
-        default = baseLibraries;
-        defaultText = lib.mdDoc "baseLibraries";
-      };
+  options.programs.nix-ld = {
+    enable = lib.mkEnableOption (lib.mdDoc ''nix-ld, Documentation: <https://github.com/Mic92/nix-ld>'');
+    package = lib.mkOption {
+      type = lib.types.package;
+      description = lib.mdDoc "Which package to use for the nix-ld.";
+      default = pkgs.nix-ld;
+      defaultText = lib.literalExpression "pkgs.nix-ld";
+    };
+    libraries = lib.mkOption {
+      type = lib.types.listOf lib.types.package;
+      description = lib.mdDoc "Libraries that automatically become available to all programs. The default set includes common libraries.";
+      default = baseLibraries;
+      defaultText = lib.literalExpression "baseLibraries derived from systemd and nix dependencies.";
     };
   };
+
   config = lib.mkIf config.programs.nix-ld.enable {
     systemd.tmpfiles.packages = [ cfg.package ];
 
diff --git a/nixos/modules/programs/skim.nix b/nixos/modules/programs/skim.nix
index 57a5d68ec3d5a..8dadf322606e2 100644
--- a/nixos/modules/programs/skim.nix
+++ b/nixos/modules/programs/skim.nix
@@ -1,6 +1,6 @@
 { pkgs, config, lib, ... }:
 let
-  inherit (lib) mdDoc mkEnableOption mkPackageOption optional optionalString;
+  inherit (lib) mdDoc mkEnableOption mkPackageOptionMD optional optionalString;
   cfg = config.programs.skim;
 in
 {
@@ -8,7 +8,7 @@ in
     programs.skim = {
       fuzzyCompletion = mkEnableOption (mdDoc "fuzzy completion with skim");
       keybindings = mkEnableOption (mdDoc "skim keybindings");
-      package = mkPackageOption pkgs "skim" {};
+      package = mkPackageOptionMD pkgs "skim" {};
     };
   };
 
diff --git a/nixos/modules/programs/streamdeck-ui.nix b/nixos/modules/programs/streamdeck-ui.nix
index 113d1d49e151a..4c055029e39b9 100644
--- a/nixos/modules/programs/streamdeck-ui.nix
+++ b/nixos/modules/programs/streamdeck-ui.nix
@@ -15,7 +15,7 @@ in
       description = lib.mdDoc "Whether streamdeck-ui should be started automatically.";
     };
 
-    package = mkPackageOption pkgs "streamdeck-ui" {
+    package = mkPackageOptionMD pkgs "streamdeck-ui" {
       default = [ "streamdeck-ui" ];
     };
 
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index aef42d0f4db10..d88baac7a5d4d 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -14,7 +14,7 @@ with lib;
 
     # This alias module can't be where _module.check is defined because it would
     # be added to submodules as well there
-    (mkAliasOptionModule [ "environment" "checkConfigurationOptions" ] [ "_module" "check" ])
+    (mkAliasOptionModuleMD [ "environment" "checkConfigurationOptions" ] [ "_module" "check" ])
 
     # Completely removed modules
     (mkRemovedOptionModule [ "environment" "blcr" "enable" ] "The BLCR module has been removed")
diff --git a/nixos/modules/services/continuous-integration/gitlab-runner.nix b/nixos/modules/services/continuous-integration/gitlab-runner.nix
index 7b1c4da862606..d18c4cff04057 100644
--- a/nixos/modules/services/continuous-integration/gitlab-runner.nix
+++ b/nixos/modules/services/continuous-integration/gitlab-runner.nix
@@ -4,24 +4,41 @@ with lib;
 let
   cfg = config.services.gitlab-runner;
   hasDocker = config.virtualisation.docker.enable;
+
+  /* The whole logic of this module is to diff the hashes of the desired vs existing runners
+  The hash is recorded in the runner's name because we can't do better yet
+  See https://gitlab.com/gitlab-org/gitlab-runner/-/issues/29350 for more details
+  */
+  genRunnerName = service: let
+      hash = substring 0 12 (hashString "md5" (unsafeDiscardStringContext (toJSON service)));
+    in if service ? description
+    then "${hash} ${service.description}"
+    else "${name}_${config.networking.hostName}_${hash}";
+
   hashedServices = mapAttrs'
-    (name: service: nameValuePair
-      "${name}_${config.networking.hostName}_${
-        substring 0 12
-        (hashString "md5" (unsafeDiscardStringContext (toJSON service)))}"
-      service)
-    cfg.services;
-  configPath = "$HOME/.gitlab-runner/config.toml";
-  configureScript = pkgs.writeShellScriptBin "gitlab-runner-configure" (
-    if (cfg.configFile != null) then ''
-      mkdir -p $(dirname ${configPath})
+    (name: service: nameValuePair (genRunnerName service) service) cfg.services;
+  configPath = ''"$HOME"/.gitlab-runner/config.toml'';
+  configureScript = pkgs.writeShellApplication {
+    name = "gitlab-runner-configure";
+    runtimeInputs = with pkgs; [
+        bash
+        gawk
+        jq
+        moreutils
+        remarshal
+        util-linux
+        cfg.package
+        perl
+        python3
+    ];
+    text = if (cfg.configFile != null) then ''
       cp ${cfg.configFile} ${configPath}
       # make config file readable by service
       chown -R --reference=$HOME $(dirname ${configPath})
     '' else ''
       export CONFIG_FILE=${configPath}
 
-      mkdir -p $(dirname ${configPath})
+      mkdir -p "$(dirname "${configPath}")"
       touch ${configPath}
 
       # update global options
@@ -34,22 +51,43 @@ let
       # remove no longer existing services
       gitlab-runner verify --delete
 
-      # current and desired state
-      NEEDED_SERVICES=$(echo ${concatStringsSep " " (attrNames hashedServices)} | tr " " "\n")
-      REGISTERED_SERVICES=$(gitlab-runner list 2>&1 | grep 'Executor' | awk '{ print $1 }')
+      ${toShellVar "NEEDED_SERVICES" (lib.mapAttrs (name: value: 1) hashedServices)}
+
+      declare -A REGISTERED_SERVICES
+
+      while IFS="," read -r name token;
+      do
+        REGISTERED_SERVICES["$name"]="$token"
+      done < <(gitlab-runner --log-format json list 2>&1 | grep Token  | jq -r '.msg +"," + .Token')
+
+      echo "NEEDED_SERVICES: " "''${!NEEDED_SERVICES[@]}"
+      echo "REGISTERED_SERVICES:" "''${!REGISTERED_SERVICES[@]}"
 
       # difference between current and desired state
-      NEW_SERVICES=$(grep -vxF -f <(echo "$REGISTERED_SERVICES") <(echo "$NEEDED_SERVICES") || true)
-      OLD_SERVICES=$(grep -vxF -f <(echo "$NEEDED_SERVICES") <(echo "$REGISTERED_SERVICES") || true)
+      declare -A NEW_SERVICES
+      for name in "''${!NEEDED_SERVICES[@]}"; do
+        if [ ! -v 'REGISTERED_SERVICES[$name]' ]; then
+          NEW_SERVICES[$name]=1
+        fi
+      done
+
+      declare -A OLD_SERVICES
+      # shellcheck disable=SC2034
+      for name in "''${!REGISTERED_SERVICES[@]}"; do
+        if [ ! -v 'NEEDED_SERVICES[$name]' ]; then
+          OLD_SERVICES[$name]=1
+        fi
+      done
 
       # register new services
       ${concatStringsSep "\n" (mapAttrsToList (name: service: ''
-        if echo "$NEW_SERVICES" | grep -xq "${name}"; then
+        # TODO so here we should mention NEW_SERVICES
+        if [ -v 'NEW_SERVICES["${name}"]' ] ; then
           bash -c ${escapeShellArg (concatStringsSep " \\\n " ([
             "set -a && source ${service.registrationConfigFile} &&"
             "gitlab-runner register"
             "--non-interactive"
-            (if service.description != null then "--description \"${service.description}\"" else "--name '${name}'")
+            "--name '${name}'"
             "--executor ${service.executor}"
             "--limit ${toString service.limit}"
             "--request-concurrency ${toString service.requestConcurrency}"
@@ -92,22 +130,26 @@ let
         fi
       '') hashedServices)}
 
+      # check key is in array https://stackoverflow.com/questions/30353951/how-to-check-if-dictionary-contains-a-key-in-bash
+
+      echo "NEW_SERVICES: ''${NEW_SERVICES[*]}"
+      echo "OLD_SERVICES: ''${OLD_SERVICES[*]}"
       # unregister old services
-      for NAME in $(echo "$OLD_SERVICES")
+      for NAME in "''${!OLD_SERVICES[@]}"
       do
-        [ ! -z "$NAME" ] && gitlab-runner unregister \
+        [ -n "$NAME" ] && gitlab-runner unregister \
           --name "$NAME" && sleep 1
       done
 
       # make config file readable by service
-      chown -R --reference=$HOME $(dirname ${configPath})
-    '');
+      chown -R --reference="$HOME" "$(dirname ${configPath})"
+    '';
+  };
   startScript = pkgs.writeShellScriptBin "gitlab-runner-start" ''
     export CONFIG_FILE=${configPath}
     exec gitlab-runner run --working-directory $HOME
   '';
-in
-{
+in {
   options.services.gitlab-runner = {
     enable = mkEnableOption (lib.mdDoc "Gitlab Runner");
     configFile = mkOption {
diff --git a/nixos/modules/services/databases/dgraph.nix b/nixos/modules/services/databases/dgraph.nix
index 5726851a43f95..887164fa5b943 100644
--- a/nixos/modules/services/databases/dgraph.nix
+++ b/nixos/modules/services/databases/dgraph.nix
@@ -55,7 +55,7 @@ in
     services.dgraph = {
       enable = mkEnableOption (lib.mdDoc "Dgraph native GraphQL database with a graph backend");
 
-      package = lib.mkPackageOption pkgs "dgraph" { };
+      package = lib.mkPackageOptionMD pkgs "dgraph" { };
 
       settings = mkOption {
         type = settingsFormat.type;
diff --git a/nixos/modules/services/desktops/pipewire/daemon/jack.conf.json b/nixos/modules/services/desktops/pipewire/daemon/jack.conf.json
index 128178bfa027f..4a173f7322972 100644
--- a/nixos/modules/services/desktops/pipewire/daemon/jack.conf.json
+++ b/nixos/modules/services/desktops/pipewire/daemon/jack.conf.json
@@ -33,6 +33,31 @@
       "actions": {
         "update-props": {}
       }
+    },
+    {
+      "matches": [
+        {
+          "application.process.binary": "jack_bufsize"
+        }
+      ],
+      "actions": {
+        "update-props": {
+          "jack.global-buffer-size": true
+        }
+      }
+    },
+    {
+      "matches": [
+        {
+          "application.process.binary": "qsynth"
+        }
+      ],
+      "actions": {
+        "update-props": {
+          "node.pause-on-idle": false,
+          "node.passive": true
+        }
+      }
     }
   ]
 }
diff --git a/nixos/modules/services/desktops/pipewire/daemon/pipewire-pulse.conf.json b/nixos/modules/services/desktops/pipewire/daemon/pipewire-pulse.conf.json
index 114afbfb0ea46..b1a864853325c 100644
--- a/nixos/modules/services/desktops/pipewire/daemon/pipewire-pulse.conf.json
+++ b/nixos/modules/services/desktops/pipewire/daemon/pipewire-pulse.conf.json
@@ -32,10 +32,12 @@
       "args": {}
     }
   ],
-  "context.exec": [
+  "context.exec": [],
+  "pulse.cmd": [
     {
-      "path": "pactl",
-      "args": "load-module module-always-sink"
+      "cmd": "load-module",
+      "args": "module-always-sink",
+      "flags": []
     }
   ],
   "stream.properties": {},
@@ -89,13 +91,14 @@
     {
       "matches": [
         {
-          "application.name": "~speech-dispatcher*"
+          "application.name": "~speech-dispatcher.*"
         }
       ],
       "actions": {
         "update-props": {
-          "pulse.min.req": "1024/48000",
-          "pulse.min.quantum": "1024/48000"
+          "pulse.min.req": "512/48000",
+          "pulse.min.quantum": "512/48000",
+          "pulse.idle.timeout": 5
         }
       }
     }
diff --git a/nixos/modules/services/desktops/pipewire/daemon/pipewire.conf.json b/nixos/modules/services/desktops/pipewire/daemon/pipewire.conf.json
index bf3b2d660827a..53fc103d22144 100644
--- a/nixos/modules/services/desktops/pipewire/daemon/pipewire.conf.json
+++ b/nixos/modules/services/desktops/pipewire/daemon/pipewire.conf.json
@@ -70,6 +70,14 @@
     },
     {
       "name": "libpipewire-module-session-manager"
+    },
+    {
+      "name": "libpipewire-module-x11-bell",
+      "args": {},
+      "flags": [
+        "ifexists",
+        "nofail"
+      ]
     }
   ],
   "context.objects": [
diff --git a/nixos/modules/services/mail/listmonk.nix b/nixos/modules/services/mail/listmonk.nix
index 8b636bd5b1ff6..251362fdd89d3 100644
--- a/nixos/modules/services/mail/listmonk.nix
+++ b/nixos/modules/services/mail/listmonk.nix
@@ -128,7 +128,7 @@ in {
           '';
         };
       };
-      package = mkPackageOption pkgs "listmonk" {};
+      package = mkPackageOptionMD pkgs "listmonk" {};
       settings = mkOption {
         type = types.submodule { freeformType = tomlFormat.type; };
         description = lib.mdDoc ''
diff --git a/nixos/modules/services/misc/input-remapper.nix b/nixos/modules/services/misc/input-remapper.nix
index 51e1abdc98a08..6353966f5c3ff 100644
--- a/nixos/modules/services/misc/input-remapper.nix
+++ b/nixos/modules/services/misc/input-remapper.nix
@@ -7,7 +7,7 @@ let cfg = config.services.input-remapper; in
   options = {
     services.input-remapper = {
       enable = mkEnableOption (lib.mdDoc "input-remapper, an easy to use tool to change the mapping of your input device buttons.");
-      package = options.mkPackageOption pkgs "input-remapper" { };
+      package = mkPackageOptionMD pkgs "input-remapper" { };
       enableUdevRules = mkEnableOption (lib.mdDoc "udev rules added by input-remapper to handle hotplugged devices. Currently disabled by default due to https://github.com/sezanzeb/input-remapper/issues/140");
       serviceWantedBy = mkOption {
         default = [ "graphical.target" ];
diff --git a/nixos/modules/services/misc/paperless.nix b/nixos/modules/services/misc/paperless.nix
index 33a8394dff2d2..1dddd147ac095 100644
--- a/nixos/modules/services/misc/paperless.nix
+++ b/nixos/modules/services/misc/paperless.nix
@@ -212,14 +212,14 @@ in
 
     systemd.services.paperless-scheduler = {
       description = "Paperless Celery Beat";
+      wantedBy = [ "multi-user.target" ];
+      wants = [ "paperless-consumer.service" "paperless-web.service" "paperless-task-queue.service" ];
       serviceConfig = defaultServiceConfig // {
         User = cfg.user;
         ExecStart = "${pkg}/bin/celery --app paperless beat --loglevel INFO";
         Restart = "on-failure";
       };
       environment = env;
-      wantedBy = [ "multi-user.target" ];
-      wants = [ "paperless-consumer.service" "paperless-web.service" "paperless-task-queue.service" ];
 
       preStart = ''
         ln -sf ${manage} ${cfg.dataDir}/paperless-manage
@@ -248,6 +248,7 @@ in
 
     systemd.services.paperless-task-queue = {
       description = "Paperless Celery Workers";
+      after = [ "paperless-scheduler.service" ];
       serviceConfig = defaultServiceConfig // {
         User = cfg.user;
         ExecStart = "${pkg}/bin/celery --app paperless worker --loglevel INFO";
@@ -275,20 +276,24 @@ in
 
     systemd.services.paperless-consumer = {
       description = "Paperless document consumer";
+      # Bind to `paperless-scheduler` so that the consumer never runs
+      # during migrations
+      bindsTo = [ "paperless-scheduler.service" ];
+      after = [ "paperless-scheduler.service" ];
       serviceConfig = defaultServiceConfig // {
         User = cfg.user;
         ExecStart = "${pkg}/bin/paperless-ngx document_consumer";
         Restart = "on-failure";
       };
       environment = env;
-      # Bind to `paperless-scheduler` so that the consumer never runs
-      # during migrations
-      bindsTo = [ "paperless-scheduler.service" ];
-      after = [ "paperless-scheduler.service" ];
     };
 
     systemd.services.paperless-web = {
       description = "Paperless web server";
+      # Bind to `paperless-scheduler` so that the web server never runs
+      # during migrations
+      bindsTo = [ "paperless-scheduler.service" ];
+      after = [ "paperless-scheduler.service" ];
       serviceConfig = defaultServiceConfig // {
         User = cfg.user;
         ExecStart = ''
@@ -312,10 +317,6 @@ in
       # Allow the web interface to access the private /tmp directory of the server.
       # This is required to support uploading files via the web interface.
       unitConfig.JoinsNamespaceOf = "paperless-task-queue.service";
-      # Bind to `paperless-scheduler` so that the web server never runs
-      # during migrations
-      bindsTo = [ "paperless-scheduler.service" ];
-      after = [ "paperless-scheduler.service" ];
     };
 
     users = optionalAttrs (cfg.user == defaultUser) {
diff --git a/nixos/modules/services/misc/polaris.nix b/nixos/modules/services/misc/polaris.nix
index 83da486083b42..70f097f028406 100644
--- a/nixos/modules/services/misc/polaris.nix
+++ b/nixos/modules/services/misc/polaris.nix
@@ -13,7 +13,7 @@ in
     services.polaris = {
       enable = mkEnableOption (lib.mdDoc "Polaris Music Server");
 
-      package = mkPackageOption pkgs "polaris" { };
+      package = mkPackageOptionMD pkgs "polaris" { };
 
       user = mkOption {
         type = types.str;
diff --git a/nixos/modules/services/monitoring/apcupsd.nix b/nixos/modules/services/monitoring/apcupsd.nix
index d4216b44cdc8c..666479c78a84d 100644
--- a/nixos/modules/services/monitoring/apcupsd.nix
+++ b/nixos/modules/services/monitoring/apcupsd.nix
@@ -62,6 +62,21 @@ let
 
   );
 
+  # Ensure the CLI uses our generated configFile
+  wrappedBinaries = pkgs.runCommandLocal "apcupsd-wrapped-binaries"
+    { nativeBuildInputs = [ pkgs.makeWrapper ]; }
+    ''
+      for p in "${lib.getBin pkgs.apcupsd}/bin/"*; do
+          bname=$(basename "$p")
+          makeWrapper "$p" "$out/bin/$bname" --add-flags "-f ${configFile}"
+      done
+    '';
+
+  apcupsdWrapped = pkgs.symlinkJoin {
+    name = "apcupsd-wrapped";
+    # Put wrappers first so they "win"
+    paths = [ wrappedBinaries pkgs.apcupsd ];
+  };
 in
 
 {
@@ -138,7 +153,7 @@ in
     } ];
 
     # Give users access to the "apcaccess" tool
-    environment.systemPackages = [ pkgs.apcupsd ];
+    environment.systemPackages = [ apcupsdWrapped ];
 
     # NOTE 1: apcupsd runs as root because it needs permission to run
     # "shutdown"
diff --git a/nixos/modules/services/monitoring/parsedmarc.md b/nixos/modules/services/monitoring/parsedmarc.md
index d93134a4cc767..5a17f79da5d46 100644
--- a/nixos/modules/services/monitoring/parsedmarc.md
+++ b/nixos/modules/services/monitoring/parsedmarc.md
@@ -17,7 +17,6 @@ services.parsedmarc = {
     host = "imap.example.com";
     user = "alice@example.com";
     password = "/path/to/imap_password_file";
-    watch = true;
   };
   provision.geoIp = false; # Not recommended!
 };
diff --git a/nixos/modules/services/monitoring/parsedmarc.nix b/nixos/modules/services/monitoring/parsedmarc.nix
index 3540d91fc9f37..40c76b804559c 100644
--- a/nixos/modules/services/monitoring/parsedmarc.nix
+++ b/nixos/modules/services/monitoring/parsedmarc.nix
@@ -123,7 +123,10 @@ in
             host = "imap.example.com";
             user = "alice@example.com";
             password = { _secret = "/run/keys/imap_password" };
+          };
+          mailbox = {
             watch = true;
+            batch_size = 30;
           };
           splunk_hec = {
             url = "https://splunkhec.example.com";
@@ -170,6 +173,24 @@ in
             };
           };
 
+          mailbox = {
+            watch = lib.mkOption {
+              type = lib.types.bool;
+              default = true;
+              description = lib.mdDoc ''
+                Use the IMAP IDLE command to process messages as they arrive.
+              '';
+            };
+
+            delete = lib.mkOption {
+              type = lib.types.bool;
+              default = false;
+              description = lib.mdDoc ''
+                Delete messages after processing them, instead of archiving them.
+              '';
+            };
+          };
+
           imap = {
             host = lib.mkOption {
               type = lib.types.str;
@@ -216,22 +237,6 @@ in
               '';
               apply = x: if isAttrs x || x == null then x else { _secret = x; };
             };
-
-            watch = lib.mkOption {
-              type = lib.types.bool;
-              default = true;
-              description = lib.mdDoc ''
-                Use the IMAP IDLE command to process messages as they arrive.
-              '';
-            };
-
-            delete = lib.mkOption {
-              type = lib.types.bool;
-              default = false;
-              description = lib.mdDoc ''
-                Delete messages after processing them, instead of archiving them.
-              '';
-            };
           };
 
           smtp = {
@@ -360,6 +365,13 @@ in
 
   config = lib.mkIf cfg.enable {
 
+    warnings = let
+      deprecationWarning = optname: "Starting in 8.0.0, the `${optname}` option has been moved from the `services.parsedmarc.settings.imap`"
+        + "configuration section to the `services.parsedmarc.settings.mailbox` configuration section.";
+      hasImapOpt = lib.flip builtins.hasAttr cfg.settings.imap;
+      movedOptions = [ "reports_folder" "archive_folder" "watch" "delete" "test" "batch_size" ];
+    in builtins.map deprecationWarning (builtins.filter hasImapOpt movedOptions);
+
     services.elasticsearch.enable = lib.mkDefault cfg.provision.elasticsearch;
 
     services.geoipupdate = lib.mkIf cfg.provision.geoIp {
@@ -444,6 +456,8 @@ in
           ssl = false;
           user = cfg.provision.localMail.recipientName;
           password = "${pkgs.writeText "imap-password" "@imap-password@"}";
+        };
+        mailbox = {
           watch = true;
         };
       })
diff --git a/nixos/modules/services/monitoring/parsedmarc.xml b/nixos/modules/services/monitoring/parsedmarc.xml
index 7167b52d0357d..b6a4bcf8ff5a5 100644
--- a/nixos/modules/services/monitoring/parsedmarc.xml
+++ b/nixos/modules/services/monitoring/parsedmarc.xml
@@ -15,14 +15,13 @@
       email address and saves them to a local Elasticsearch instance
       looks like this:
     </para>
-    <programlisting language="bash">
+    <programlisting>
 services.parsedmarc = {
   enable = true;
   settings.imap = {
     host = &quot;imap.example.com&quot;;
     user = &quot;alice@example.com&quot;;
     password = &quot;/path/to/imap_password_file&quot;;
-    watch = true;
   };
   provision.geoIp = false; # Not recommended!
 };
@@ -45,7 +44,7 @@ services.parsedmarc = {
       email address that should be configured in the domain’s dmarc
       policy is <literal>dmarc@monitoring.example.com</literal>.
     </para>
-    <programlisting language="bash">
+    <programlisting>
 services.parsedmarc = {
   enable = true;
   provision = {
@@ -68,7 +67,7 @@ services.parsedmarc = {
       Elasticsearch instance is automatically added as a Grafana
       datasource, and the dashboard is added to Grafana as well.
     </para>
-    <programlisting language="bash">
+    <programlisting>
 services.parsedmarc = {
   enable = true;
   provision = {
diff --git a/nixos/modules/services/networking/ntp/chrony.nix b/nixos/modules/services/networking/ntp/chrony.nix
index 7e3bb565d10bf..dc180d4a4f954 100644
--- a/nixos/modules/services/networking/ntp/chrony.nix
+++ b/nixos/modules/services/networking/ntp/chrony.nix
@@ -147,9 +147,9 @@ in
     systemd.services.systemd-timedated.environment = { SYSTEMD_TIMEDATED_NTP_SERVICES = "chronyd.service"; };
 
     systemd.tmpfiles.rules = [
-      "d ${stateDir} 0755 chrony chrony - -"
-      "f ${driftFile} 0640 chrony chrony -"
-      "f ${keyFile} 0640 chrony chrony -"
+      "d ${stateDir} 0750 chrony chrony - -"
+      "f ${driftFile} 0640 chrony chrony - -"
+      "f ${keyFile} 0640 chrony chrony - -"
     ];
 
     systemd.services.chronyd =
@@ -164,15 +164,47 @@ in
         path = [ chronyPkg ];
 
         unitConfig.ConditionCapability = "CAP_SYS_TIME";
-        serviceConfig =
-          { Type = "simple";
-            ExecStart = "${chronyPkg}/bin/chronyd ${builtins.toString chronyFlags}";
-
-            ProtectHome = "yes";
-            ProtectSystem = "full";
-            PrivateTmp = "yes";
-          };
-
+        serviceConfig = {
+          Type = "simple";
+          ExecStart = "${chronyPkg}/bin/chronyd ${builtins.toString chronyFlags}";
+
+          # Proc filesystem
+          ProcSubset = "pid";
+          ProtectProc = "invisible";
+          # Access write directories
+          ReadWritePaths = [ "${stateDir}" ];
+          UMask = "0027";
+          # Capabilities
+          CapabilityBoundingSet = [ "CAP_CHOWN" "CAP_DAC_OVERRIDE" "CAP_NET_BIND_SERVICE" "CAP_SETGID" "CAP_SETUID" "CAP_SYS_RESOURCE" "CAP_SYS_TIME" ];
+          # Device Access
+          DeviceAllow = [ "char-pps rw" "char-ptp rw" "char-rtc rw" ];
+          DevicePolicy = "closed";
+          # Security
+          NoNewPrivileges = true;
+          # Sandboxing
+          ProtectSystem = "full";
+          ProtectHome = true;
+          PrivateTmp = true;
+          PrivateDevices = true;
+          PrivateUsers = false;
+          ProtectHostname = true;
+          ProtectClock = false;
+          ProtectKernelTunables = true;
+          ProtectKernelModules = true;
+          ProtectKernelLogs = true;
+          ProtectControlGroups = true;
+          RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
+          RestrictNamespaces = true;
+          LockPersonality = true;
+          MemoryDenyWriteExecute = true;
+          RestrictRealtime = true;
+          RestrictSUIDSGID = true;
+          RemoveIPC = true;
+          PrivateMounts = true;
+          # System Call Filtering
+          SystemCallArchitectures = "native";
+          SystemCallFilter = [ "~@cpu-emulation @debug @keyring @mount @obsolete @privileged @resources" "@clock" "@setuid" "capset" "chown" ];
+        };
       };
   };
 }
diff --git a/nixos/modules/services/networking/openconnect.nix b/nixos/modules/services/networking/openconnect.nix
index 4676b1733af68..5a02bd072257f 100644
--- a/nixos/modules/services/networking/openconnect.nix
+++ b/nixos/modules/services/networking/openconnect.nix
@@ -116,7 +116,7 @@ let
   };
 in {
   options.networking.openconnect = {
-    package = mkPackageOption pkgs "openconnect" { };
+    package = mkPackageOptionMD pkgs "openconnect" { };
 
     interfaces = mkOption {
       description = lib.mdDoc "OpenConnect interfaces.";
diff --git a/nixos/modules/services/networking/radicale.nix b/nixos/modules/services/networking/radicale.nix
index 9ec507fe2ab6a..8e4789c7ca597 100644
--- a/nixos/modules/services/networking/radicale.nix
+++ b/nixos/modules/services/networking/radicale.nix
@@ -200,5 +200,5 @@ in {
     };
   };
 
-  meta.maintainers = with lib.maintainers; [ aneeshusa infinisil dotlambda ];
+  meta.maintainers = with lib.maintainers; [ infinisil dotlambda ];
 }
diff --git a/nixos/modules/services/networking/shellhub-agent.nix b/nixos/modules/services/networking/shellhub-agent.nix
index ad33c50f9d633..7cce23cb9c4e3 100644
--- a/nixos/modules/services/networking/shellhub-agent.nix
+++ b/nixos/modules/services/networking/shellhub-agent.nix
@@ -14,7 +14,7 @@ in
 
       enable = mkEnableOption (lib.mdDoc "ShellHub Agent daemon");
 
-      package = mkPackageOption pkgs "shellhub-agent" { };
+      package = mkPackageOptionMD pkgs "shellhub-agent" { };
 
       preferredHostname = mkOption {
         type = types.str;
diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix
index af8200c7e2951..37d7518ab3c4e 100644
--- a/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixos/modules/services/networking/ssh/sshd.nix
@@ -79,8 +79,8 @@ in
 
 {
   imports = [
-    (mkAliasOptionModule [ "services" "sshd" "enable" ] [ "services" "openssh" "enable" ])
-    (mkAliasOptionModule [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ])
+    (mkAliasOptionModuleMD [ "services" "sshd" "enable" ] [ "services" "openssh" "enable" ])
+    (mkAliasOptionModuleMD [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ])
     (mkRenamedOptionModule [ "services" "openssh" "challengeResponseAuthentication" ] [ "services" "openssh" "kbdInteractiveAuthentication" ])
   ];
 
diff --git a/nixos/modules/services/networking/vdirsyncer.nix b/nixos/modules/services/networking/vdirsyncer.nix
index 6a069943434da..f9b880c763e3d 100644
--- a/nixos/modules/services/networking/vdirsyncer.nix
+++ b/nixos/modules/services/networking/vdirsyncer.nix
@@ -71,7 +71,7 @@ in
     services.vdirsyncer = {
       enable = mkEnableOption (mdDoc "vdirsyncer");
 
-      package = mkPackageOption pkgs "vdirsyncer" {};
+      package = mkPackageOptionMD pkgs "vdirsyncer" {};
 
       jobs = mkOption {
         description = mdDoc "vdirsyncer job configurations";
diff --git a/nixos/modules/services/networking/webhook.nix b/nixos/modules/services/networking/webhook.nix
index b020db6961c32..2a78491941cf9 100644
--- a/nixos/modules/services/networking/webhook.nix
+++ b/nixos/modules/services/networking/webhook.nix
@@ -36,7 +36,7 @@ in {
         which execute configured commands for any person or service that knows the URL
       '');
 
-      package = mkPackageOption pkgs "webhook" {};
+      package = mkPackageOptionMD pkgs "webhook" {};
       user = mkOption {
         type = types.str;
         default = defaultUser;
diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix
index 4378233848338..752ab91fe6315 100644
--- a/nixos/modules/services/torrent/transmission.nix
+++ b/nixos/modules/services/torrent/transmission.nix
@@ -19,8 +19,8 @@ in
   imports = [
     (mkRenamedOptionModule ["services" "transmission" "port"]
                            ["services" "transmission" "settings" "rpc-port"])
-    (mkAliasOptionModule ["services" "transmission" "openFirewall"]
-                         ["services" "transmission" "openPeerPorts"])
+    (mkAliasOptionModuleMD ["services" "transmission" "openFirewall"]
+                           ["services" "transmission" "openPeerPorts"])
   ];
   options = {
     services.transmission = {
@@ -174,7 +174,7 @@ in
         };
       };
 
-      package = mkPackageOption pkgs "transmission" {};
+      package = mkPackageOptionMD pkgs "transmission" {};
 
       downloadDirPermissions = mkOption {
         type = with types; nullOr str;
diff --git a/nixos/modules/services/web-apps/snipe-it.nix b/nixos/modules/services/web-apps/snipe-it.nix
index 314a69a73a872..93b0aafab64bf 100644
--- a/nixos/modules/services/web-apps/snipe-it.nix
+++ b/nixos/modules/services/web-apps/snipe-it.nix
@@ -454,8 +454,9 @@ in {
 
           # A placeholder file for invalid barcodes
           invalid_barcode_location="${cfg.dataDir}/public/uploads/barcodes/invalid_barcode.gif"
-          [ ! -e "$invalid_barcode_location" ] \
-              && cp ${snipe-it}/share/snipe-it/invalid_barcode.gif "$invalid_barcode_location"
+          if [ ! -e "$invalid_barcode_location" ]; then
+              cp ${snipe-it}/share/snipe-it/invalid_barcode.gif "$invalid_barcode_location"
+          fi
         '';
     };
 
diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix
index 95e600ea79a5a..d31f3d5d4650b 100644
--- a/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixos/modules/services/web-servers/nginx/default.nix
@@ -571,7 +571,7 @@ in
         defaultText = literalExpression "pkgs.nginxStable";
         type = types.package;
         apply = p: p.override {
-          modules = p.modules ++ cfg.additionalModules;
+          modules = lib.unique (p.modules ++ cfg.additionalModules);
         };
         description = lib.mdDoc ''
           Nginx package to use. This defaults to the stable version. Note
diff --git a/nixos/modules/services/x11/desktop-managers/cinnamon.nix b/nixos/modules/services/x11/desktop-managers/cinnamon.nix
index 08c5625fc7ddd..df1b6f731a4e4 100644
--- a/nixos/modules/services/x11/desktop-managers/cinnamon.nix
+++ b/nixos/modules/services/x11/desktop-managers/cinnamon.nix
@@ -180,6 +180,7 @@ in
         mint-themes
         mint-x-icons
         mint-y-icons
+        xapp # provides some xapp-* icons
       ] config.environment.cinnamon.excludePackages);
 
       xdg.mime.enable = true;
diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix
index 9fcb408c287d5..8270b64787f8f 100644
--- a/nixos/modules/services/x11/desktop-managers/plasma5.nix
+++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix
@@ -32,7 +32,7 @@ let
   inherit (lib)
     getBin optionalString literalExpression
     mkRemovedOptionModule mkRenamedOptionModule
-    mkDefault mkIf mkMerge mkOption types;
+    mkDefault mkIf mkMerge mkOption mkPackageOptionMD types;
 
   ini = pkgs.formats.ini { };
 
@@ -198,6 +198,11 @@ in
       example = literalExpression "[ pkgs.plasma5Packages.oxygen ]";
     };
 
+    notoPackage = mkPackageOptionMD pkgs "Noto fonts" {
+      default = [ "noto-fonts" ];
+      example = "noto-fonts-lgc-plus";
+    };
+
     # Internally allows configuring kdeglobals globally
     kdeglobals = mkOption {
       internal = true;
@@ -401,7 +406,7 @@ in
       # Enable GTK applications to load SVG icons
       services.xserver.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];
 
-      fonts.fonts = with pkgs; [ noto-fonts hack-font ];
+      fonts.fonts = with pkgs; [ cfg.notoPackage hack-font ];
       fonts.fontconfig.defaultFonts = {
         monospace = [ "Hack" "Noto Sans Mono" ];
         sansSerif = [ "Noto Sans" ];
@@ -545,7 +550,7 @@ in
         }
         {
           # The user interface breaks without pulse
-          assertion = config.hardware.pulseaudio.enable;
+          assertion = config.hardware.pulseaudio.enable || (config.services.pipewire.enable && config.services.pipewire.pulse.enable);
           message = "Plasma Mobile requires pulseaudio.";
         }
       ];
diff --git a/nixos/modules/services/x11/picom.nix b/nixos/modules/services/x11/picom.nix
index 4a0578de09cb5..1d6f3daa40225 100644
--- a/nixos/modules/services/x11/picom.nix
+++ b/nixos/modules/services/x11/picom.nix
@@ -41,7 +41,7 @@ let
 in {
 
   imports = [
-    (mkAliasOptionModule [ "services" "compton" ] [ "services" "picom" ])
+    (mkAliasOptionModuleMD [ "services" "compton" ] [ "services" "picom" ])
     (mkRemovedOptionModule [ "services" "picom" "refreshRate" ] ''
       This option corresponds to `refresh-rate`, which has been unused
       since picom v6 and was subsequently removed by upstream.
diff --git a/nixos/modules/services/x11/window-managers/i3.nix b/nixos/modules/services/x11/window-managers/i3.nix
index 64109e0c39fdd..5bb73cd0bfb17 100644
--- a/nixos/modules/services/x11/window-managers/i3.nix
+++ b/nixos/modules/services/x11/window-managers/i3.nix
@@ -31,7 +31,6 @@ in
       type        = types.package;
       default     = pkgs.i3;
       defaultText = literalExpression "pkgs.i3";
-      example     = literalExpression "pkgs.i3-gaps";
       description = lib.mdDoc ''
         i3 package to use.
       '';
@@ -73,6 +72,6 @@ in
 
   imports = [
     (mkRemovedOptionModule [ "services" "xserver" "windowManager" "i3-gaps" "enable" ]
-      "Use services.xserver.windowManager.i3.enable and set services.xserver.windowManager.i3.package to pkgs.i3-gaps to use i3-gaps.")
+      "i3-gaps was merged into i3. Use services.xserver.windowManager.i3.enable instead.")
   ];
 }
diff --git a/nixos/modules/services/x11/window-managers/katriawm.nix b/nixos/modules/services/x11/window-managers/katriawm.nix
index 106631792ff4e..9a3fd5f3ca44a 100644
--- a/nixos/modules/services/x11/window-managers/katriawm.nix
+++ b/nixos/modules/services/x11/window-managers/katriawm.nix
@@ -1,7 +1,7 @@
 { config, lib, pkgs, ... }:
 
 let
-  inherit (lib) mdDoc mkEnableOption mkIf mkPackageOption singleton;
+  inherit (lib) mdDoc mkEnableOption mkIf mkPackageOptionMD singleton;
   cfg = config.services.xserver.windowManager.katriawm;
 in
 {
@@ -9,7 +9,7 @@ in
   options = {
     services.xserver.windowManager.katriawm = {
       enable = mkEnableOption (mdDoc "katriawm");
-      package = mkPackageOption pkgs "katriawm" {};
+      package = mkPackageOptionMD pkgs "katriawm" {};
     };
   };
 
diff --git a/nixos/modules/services/x11/window-managers/qtile.nix b/nixos/modules/services/x11/window-managers/qtile.nix
index 523642591d947..fc27566d49ee6 100644
--- a/nixos/modules/services/x11/window-managers/qtile.nix
+++ b/nixos/modules/services/x11/window-managers/qtile.nix
@@ -10,7 +10,7 @@ in
   options.services.xserver.windowManager.qtile = {
     enable = mkEnableOption (lib.mdDoc "qtile");
 
-    package = mkPackageOption pkgs "qtile" { };
+    package = mkPackageOptionMD pkgs "qtile" { };
   };
 
   config = mkIf cfg.enable {
diff --git a/nixos/modules/system/boot/systemd/initrd.nix b/nixos/modules/system/boot/systemd/initrd.nix
index 196f44ccd783c..d30f61146e189 100644
--- a/nixos/modules/system/boot/systemd/initrd.nix
+++ b/nixos/modules/system/boot/systemd/initrd.nix
@@ -142,7 +142,7 @@ in {
       '';
     };
 
-    package = (mkPackageOption pkgs "systemd" {
+    package = (mkPackageOptionMD pkgs "systemd" {
       default = "systemdStage1";
     }) // {
       visible = false;
diff --git a/nixos/modules/virtualisation/podman/default.nix b/nixos/modules/virtualisation/podman/default.nix
index 13bbb4471ea5d..6c00fabaa1858 100644
--- a/nixos/modules/virtualisation/podman/default.nix
+++ b/nixos/modules/virtualisation/podman/default.nix
@@ -1,7 +1,6 @@
 { config, lib, pkgs, ... }:
 let
   cfg = config.virtualisation.podman;
-  toml = pkgs.formats.toml { };
   json = pkgs.formats.json { };
 
   inherit (lib) mkOption types;
@@ -27,24 +26,13 @@ let
     done
   '';
 
-  net-conflist = pkgs.runCommand "87-podman-bridge.conflist"
-    {
-      nativeBuildInputs = [ pkgs.jq ];
-      extraPlugins = builtins.toJSON cfg.defaultNetwork.extraPlugins;
-      jqScript = ''
-        . + { "plugins": (.plugins + $extraPlugins) }
-      '';
-    } ''
-    jq <${cfg.package}/etc/cni/net.d/87-podman-bridge.conflist \
-      --argjson extraPlugins "$extraPlugins" \
-      "$jqScript" \
-      >$out
-  '';
-
 in
 {
   imports = [
-    ./dnsname.nix
+    (lib.mkRemovedOptionModule [ "virtualisation" "podman" "defaultNetwork" "dnsname" ]
+      "Use virtualisation.podman.defaultNetwork.settings.dns_enabled instead.")
+    (lib.mkRemovedOptionModule [ "virtualisation" "podman" "defaultNetwork" "extraPlugins" ]
+      "Netavark isn't compatible with CNI plugins.")
     ./network-socket.nix
   ];
 
@@ -149,11 +137,11 @@ in
       '';
     };
 
-    defaultNetwork.extraPlugins = lib.mkOption {
-      type = types.listOf json.type;
-      default = [ ];
+    defaultNetwork.settings = lib.mkOption {
+      type = json.type;
+      default = { };
       description = lib.mdDoc ''
-        Extra CNI plugin configurations to add to podman's default network.
+        Settings for podman's default network.
       '';
     };
 
@@ -164,11 +152,26 @@ in
       environment.systemPackages = [ cfg.package ]
         ++ lib.optional cfg.dockerCompat dockerCompat;
 
-      environment.etc."cni/net.d/87-podman-bridge.conflist".source = net-conflist;
+      # https://github.com/containers/podman/blob/097cc6eb6dd8e598c0e8676d21267b4edb11e144/docs/tutorials/basic_networking.md#default-network
+      environment.etc."containers/networks/podman.json" = lib.mkIf (cfg.defaultNetwork.settings != { }) {
+        source = json.generate "podman.json" ({
+          dns_enabled = false;
+          driver = "bridge";
+          id = "0000000000000000000000000000000000000000000000000000000000000000";
+          internal = false;
+          ipam_options = { driver = "host-local"; };
+          ipv6_enabled = false;
+          name = "podman";
+          network_interface = "podman0";
+          subnets = [{ gateway = "10.88.0.1"; subnet = "10.88.0.0/16"; }];
+        } // cfg.defaultNetwork.settings);
+      };
 
       virtualisation.containers = {
         enable = true; # Enable common /etc/containers configuration
-        containersConf.settings = lib.optionalAttrs cfg.enableNvidia {
+        containersConf.settings = {
+          network.network_backend = "netavark";
+        } // lib.optionalAttrs cfg.enableNvidia {
           engine = {
             conmon_env_vars = [ "PATH=${lib.makeBinPath [ pkgs.nvidia-podman ]}" ];
             runtimes.nvidia = [ "${pkgs.nvidia-podman}/bin/nvidia-container-runtime" ];
diff --git a/nixos/modules/virtualisation/podman/dnsname.nix b/nixos/modules/virtualisation/podman/dnsname.nix
deleted file mode 100644
index 3e7d35ae1e44d..0000000000000
--- a/nixos/modules/virtualisation/podman/dnsname.nix
+++ /dev/null
@@ -1,36 +0,0 @@
-{ config, lib, pkgs, ... }:
-let
-  inherit (lib)
-    mkOption
-    mkIf
-    types
-    ;
-
-  cfg = config.virtualisation.podman;
-
-in
-{
-  options = {
-    virtualisation.podman = {
-
-      defaultNetwork.dnsname.enable = mkOption {
-        type = types.bool;
-        default = false;
-        description = lib.mdDoc ''
-          Enable DNS resolution in the default podman network.
-        '';
-      };
-
-    };
-  };
-
-  config = {
-    virtualisation.containers.containersConf.cniPlugins = mkIf cfg.defaultNetwork.dnsname.enable [ pkgs.dnsname-cni ];
-    virtualisation.podman.defaultNetwork.extraPlugins =
-      lib.optional cfg.defaultNetwork.dnsname.enable {
-        type = "dnsname";
-        domainName = "dns.podman";
-        capabilities.aliases = true;
-      };
-  };
-}
diff --git a/nixos/modules/virtualisation/waydroid.nix b/nixos/modules/virtualisation/waydroid.nix
index a2cfd806f322e..46e5f901015d9 100644
--- a/nixos/modules/virtualisation/waydroid.nix
+++ b/nixos/modules/virtualisation/waydroid.nix
@@ -56,12 +56,8 @@ in
 
       wantedBy = [ "multi-user.target" ];
 
-      unitConfig = {
-        ConditionPathExists = "/var/lib/waydroid/lxc/waydroid";
-      };
-
       serviceConfig = {
-        ExecStart = "${pkgs.waydroid}/bin/waydroid container start";
+        ExecStart = "${pkgs.waydroid}/bin/waydroid -w container start";
         ExecStop = "${pkgs.waydroid}/bin/waydroid container stop";
         ExecStopPost = "${pkgs.waydroid}/bin/waydroid session stop";
       };
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 75f01d888b218..83ad7c48a0892 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -78,6 +78,7 @@ in {
   allTerminfo = handleTest ./all-terminfo.nix {};
   alps = handleTest ./alps.nix {};
   amazon-init-shell = handleTest ./amazon-init-shell.nix {};
+  apcupsd = handleTest ./apcupsd.nix {};
   apfs = handleTest ./apfs.nix {};
   apparmor = handleTest ./apparmor.nix {};
   atd = handleTest ./atd.nix {};
@@ -527,7 +528,6 @@ in {
   plotinus = handleTest ./plotinus.nix {};
   podgrab = handleTest ./podgrab.nix {};
   podman = handleTestOn ["aarch64-linux" "x86_64-linux"] ./podman/default.nix {};
-  podman-dnsname = handleTestOn ["aarch64-linux" "x86_64-linux"] ./podman/dnsname.nix {};
   podman-tls-ghostunnel = handleTestOn ["aarch64-linux" "x86_64-linux"] ./podman/tls-ghostunnel.nix {};
   polaris = handleTest ./polaris.nix {};
   pomerium = handleTestOn ["x86_64-linux"] ./pomerium.nix {};
diff --git a/nixos/tests/apcupsd.nix b/nixos/tests/apcupsd.nix
new file mode 100644
index 0000000000000..287140f039d85
--- /dev/null
+++ b/nixos/tests/apcupsd.nix
@@ -0,0 +1,41 @@
+let
+  # arbitrary address
+  ipAddr = "192.168.42.42";
+in
+import ./make-test-python.nix ({ lib, pkgs, ... }: {
+  name = "apcupsd";
+  meta.maintainers = with lib.maintainers; [ bjornfor ];
+
+  nodes = {
+    machine = {
+      services.apcupsd = {
+        enable = true;
+        configText = ''
+          UPSTYPE usb
+          BATTERYLEVEL 42
+          # Configure NISIP so that the only way apcaccess can work is to read
+          # this config.
+          NISIP ${ipAddr}
+        '';
+      };
+      networking.interfaces.eth1 = {
+        ipv4.addresses = [{
+          address = ipAddr;
+          prefixLength = 24;
+        }];
+      };
+    };
+  };
+
+  # Check that the service starts, that the CLI (apcaccess) works and that it
+  # uses the config (ipAddr) defined in the service config.
+  testScript = ''
+    start_all()
+    machine.wait_for_unit("apcupsd.service")
+    machine.wait_for_open_port(3551, "${ipAddr}")
+    res = machine.succeed("apcaccess")
+    expect_line="MBATTCHG : 42 Percent"
+    assert "MBATTCHG : 42 Percent" in res, f"expected apcaccess output to contain '{expect_line}' but got '{res}'"
+    machine.shutdown()
+  '';
+})
diff --git a/nixos/tests/paperless.nix b/nixos/tests/paperless.nix
index b97834835c2c9..7f36de4c29b71 100644
--- a/nixos/tests/paperless.nix
+++ b/nixos/tests/paperless.nix
@@ -26,6 +26,10 @@ import ./make-test-python.nix ({ lib, ... }: {
         # Wait until server accepts connections
         machine.wait_until_succeeds("curl -fs localhost:28981")
 
+    # Required for consuming documents via the web interface
+    with subtest("Task-queue gets ready"):
+        machine.wait_for_unit("paperless-task-queue.service")
+
     with subtest("Add a document via the web interface"):
         machine.succeed(
             "convert -size 400x40 xc:white -font 'DejaVu-Sans' -pointsize 20 -fill black "
diff --git a/nixos/tests/parsedmarc/default.nix b/nixos/tests/parsedmarc/default.nix
index 50b977723e9c7..837cf9d7e6dce 100644
--- a/nixos/tests/parsedmarc/default.nix
+++ b/nixos/tests/parsedmarc/default.nix
@@ -155,7 +155,6 @@ in
                   ssl = true;
                   user = "alice";
                   password = "${pkgs.writeText "imap-password" "foobar"}";
-                  watch = true;
                 };
               };
 
diff --git a/nixos/tests/podman/default.nix b/nixos/tests/podman/default.nix
index 106ba2057d063..c2ea399d65af3 100644
--- a/nixos/tests/podman/default.nix
+++ b/nixos/tests/podman/default.nix
@@ -13,6 +13,13 @@ import ../make-test-python.nix (
           isNormalUser = true;
         };
       };
+      dns = { pkgs, ... }: {
+        virtualisation.podman.enable = true;
+
+        virtualisation.podman.defaultNetwork.settings.dns_enabled = true;
+
+        networking.firewall.allowedUDPPorts = [ 53 ];
+      };
       docker = { pkgs, ... }: {
         virtualisation.podman.enable = true;
 
@@ -43,6 +50,7 @@ import ../make-test-python.nix (
 
 
       podman.wait_for_unit("sockets.target")
+      dns.wait_for_unit("sockets.target")
       docker.wait_for_unit("sockets.target")
       start_all()
 
@@ -120,6 +128,23 @@ import ../make-test-python.nix (
           pid = podman.succeed("podman run --rm --init busybox readlink /proc/self").strip()
           assert pid == "2"
 
+      with subtest("aardvark-dns"):
+        dns.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
+        dns.succeed(
+          "podman run -d --name=webserver -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin -w ${pkgs.writeTextDir "index.html" "<h1>Hi</h1>"} scratchimg ${pkgs.python3}/bin/python -m http.server 8000"
+        )
+        dns.succeed("podman ps | grep webserver")
+        dns.succeed("""
+          for i in `seq 0 120`; do
+            podman run --rm --name=client -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg ${pkgs.curl}/bin/curl http://webserver:8000 >/dev/console \
+              && exit 0
+            sleep 0.5
+          done
+          exit 1
+        """)
+        dns.succeed("podman stop webserver")
+        dns.succeed("podman rm webserver")
+
       with subtest("A podman member can use the docker cli"):
           docker.succeed(su_cmd("docker version"))
 
diff --git a/nixos/tests/podman/dnsname.nix b/nixos/tests/podman/dnsname.nix
deleted file mode 100644
index 3768ae79e0676..0000000000000
--- a/nixos/tests/podman/dnsname.nix
+++ /dev/null
@@ -1,42 +0,0 @@
-import ../make-test-python.nix (
-  { pkgs, lib, ... }:
-  let
-    inherit (pkgs) writeTextDir python3 curl;
-    webroot = writeTextDir "index.html" "<h1>Hi</h1>";
-  in
-  {
-    name = "podman-dnsname";
-    meta = {
-      maintainers = with lib.maintainers; [ roberth ] ++ lib.teams.podman.members;
-    };
-
-    nodes = {
-      podman = { pkgs, ... }: {
-        virtualisation.podman.enable = true;
-        virtualisation.podman.defaultNetwork.dnsname.enable = true;
-      };
-    };
-
-    testScript = ''
-      podman.wait_for_unit("sockets.target")
-
-      with subtest("DNS works"): # also tests inter-container tcp routing
-        podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
-        podman.succeed(
-          "podman run -d --name=webserver -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin -w ${webroot} scratchimg ${python3}/bin/python -m http.server 8000"
-        )
-        podman.succeed("podman ps | grep webserver")
-        podman.succeed("""
-          for i in `seq 0 120`; do
-            podman run --rm --name=client -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg ${curl}/bin/curl http://webserver:8000 >/dev/console \
-              && exit 0
-            sleep 0.5
-          done
-          exit 1
-        """)
-        podman.succeed("podman stop webserver")
-        podman.succeed("podman rm webserver")
-
-    '';
-  }
-)
diff --git a/nixos/tests/wordpress.nix b/nixos/tests/wordpress.nix
index 416a20aa7fe81..6a460dbce3547 100644
--- a/nixos/tests/wordpress.nix
+++ b/nixos/tests/wordpress.nix
@@ -1,6 +1,6 @@
-import ./make-test-python.nix ({ pkgs, ... }:
+import ./make-test-python.nix ({ lib, pkgs, ... }:
 
-{
+rec {
   name = "wordpress";
   meta = with pkgs.lib.maintainers; {
     maintainers = [
@@ -10,17 +10,22 @@ import ./make-test-python.nix ({ pkgs, ... }:
     ];
   };
 
-  nodes = {
-    wp_httpd = { ... }: {
+  nodes = lib.foldl (a: version: let
+    package = pkgs."wordpress${version}";
+  in a // {
+    "wp${version}_httpd" = _: {
       services.httpd.adminAddr = "webmaster@site.local";
       services.httpd.logPerVirtualHost = true;
 
+      services.wordpress.webserver = "httpd";
       services.wordpress.sites = {
         "site1.local" = {
           database.tablePrefix = "site1_";
+          inherit package;
         };
         "site2.local" = {
           database.tablePrefix = "site2_";
+          inherit package;
         };
       };
 
@@ -28,14 +33,16 @@ import ./make-test-python.nix ({ pkgs, ... }:
       networking.hosts."127.0.0.1" = [ "site1.local" "site2.local" ];
     };
 
-    wp_nginx = { ... }: {
+    "wp${version}_nginx" = _: {
       services.wordpress.webserver = "nginx";
       services.wordpress.sites = {
         "site1.local" = {
           database.tablePrefix = "site1_";
+          inherit package;
         };
         "site2.local" = {
           database.tablePrefix = "site2_";
+          inherit package;
         };
       };
 
@@ -43,34 +50,38 @@ import ./make-test-python.nix ({ pkgs, ... }:
       networking.hosts."127.0.0.1" = [ "site1.local" "site2.local" ];
     };
 
-    wp_caddy = { ... }: {
+    "wp${version}_caddy" = _: {
       services.wordpress.webserver = "caddy";
       services.wordpress.sites = {
         "site1.local" = {
           database.tablePrefix = "site1_";
+          inherit package;
         };
         "site2.local" = {
           database.tablePrefix = "site2_";
+          inherit package;
         };
       };
 
       networking.firewall.allowedTCPPorts = [ 80 ];
       networking.hosts."127.0.0.1" = [ "site1.local" "site2.local" ];
     };
-  };
+  }) {} [
+    "6_1"
+  ];
 
   testScript = ''
     import re
 
     start_all()
 
-    wp_httpd.wait_for_unit("httpd")
-    wp_nginx.wait_for_unit("nginx")
-    wp_caddy.wait_for_unit("caddy")
+    ${lib.concatStrings (lib.mapAttrsToList (name: value: ''
+      ${name}.wait_for_unit("${(value null).services.wordpress.webserver}")
+    '') nodes)}
 
     site_names = ["site1.local", "site2.local"]
 
-    for machine in (wp_httpd, wp_nginx, wp_caddy):
+    for machine in (${lib.concatStringsSep ", " (builtins.attrNames nodes)}):
         for site_name in site_names:
             machine.wait_for_unit(f"phpfpm-wordpress-{site_name}")