about summary refs log tree commit diff
path: root/nixpkgs/nixos
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2024-03-22 16:41:59 +0100
committerAlyssa Ross <hi@alyssa.is>2024-03-22 16:41:59 +0100
commit46a88117a05c3469af5d99433af140c3de8ca088 (patch)
treed7f0557756d8f07a3081b3498c05ddc5a8ad429d /nixpkgs/nixos
parente97457545cea0b2ca421da257c83d8f1ef451d85 (diff)
parenta343533bccc62400e8a9560423486a3b6c11a23b (diff)
downloadnixlib-46a88117a05c3469af5d99433af140c3de8ca088.tar
nixlib-46a88117a05c3469af5d99433af140c3de8ca088.tar.gz
nixlib-46a88117a05c3469af5d99433af140c3de8ca088.tar.bz2
nixlib-46a88117a05c3469af5d99433af140c3de8ca088.tar.lz
nixlib-46a88117a05c3469af5d99433af140c3de8ca088.tar.xz
nixlib-46a88117a05c3469af5d99433af140c3de8ca088.tar.zst
nixlib-46a88117a05c3469af5d99433af140c3de8ca088.zip
Merge commit 'a343533bccc62400e8a9560423486a3b6c11a23b'
Diffstat (limited to 'nixpkgs/nixos')
-rw-r--r--nixpkgs/nixos/doc/manual/configuration/x-windows.chapter.md1
-rw-r--r--nixpkgs/nixos/doc/manual/development/replace-modules.section.md3
-rw-r--r--nixpkgs/nixos/doc/manual/development/running-nixos-tests.section.md10
-rw-r--r--nixpkgs/nixos/doc/manual/development/writing-modules.chapter.md7
-rw-r--r--nixpkgs/nixos/doc/manual/release-notes/rl-2405.section.md23
-rw-r--r--nixpkgs/nixos/lib/make-disk-image.nix7
-rw-r--r--nixpkgs/nixos/lib/test-driver/test_driver/driver.py7
-rw-r--r--nixpkgs/nixos/lib/test-driver/test_driver/logger.py12
-rw-r--r--nixpkgs/nixos/lib/testing/nodes.nix22
-rw-r--r--nixpkgs/nixos/lib/testing/pkgs.nix6
-rw-r--r--nixpkgs/nixos/lib/testing/run.nix4
-rw-r--r--nixpkgs/nixos/modules/config/users-groups.nix5
-rw-r--r--nixpkgs/nixos/modules/i18n/input-method/fcitx5.nix14
-rw-r--r--nixpkgs/nixos/modules/misc/nixpkgs.nix6
-rw-r--r--nixpkgs/nixos/modules/misc/nixpkgs/test.nix6
-rw-r--r--nixpkgs/nixos/modules/module-list.nix5
-rw-r--r--nixpkgs/nixos/modules/programs/chromium.nix19
-rw-r--r--nixpkgs/nixos/modules/programs/coolercontrol.nix37
-rw-r--r--nixpkgs/nixos/modules/programs/kdeconnect.nix5
-rw-r--r--nixpkgs/nixos/modules/programs/steam.nix22
-rw-r--r--nixpkgs/nixos/modules/security/pam.nix4
-rw-r--r--nixpkgs/nixos/modules/services/backup/syncoid.nix2
-rw-r--r--nixpkgs/nixos/modules/services/databases/memcached.nix2
-rw-r--r--nixpkgs/nixos/modules/services/databases/postgresql.nix43
-rw-r--r--nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix6
-rw-r--r--nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix8
-rw-r--r--nixpkgs/nixos/modules/services/development/nixseparatedebuginfod.nix4
-rw-r--r--nixpkgs/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/cdi-generate.nix57
-rw-r--r--nixpkgs/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/default.nix8
-rw-r--r--nixpkgs/nixos/modules/services/home-automation/ebusd.nix2
-rw-r--r--nixpkgs/nixos/modules/services/home-automation/matter-server.nix125
-rw-r--r--nixpkgs/nixos/modules/services/mail/listmonk.nix6
-rw-r--r--nixpkgs/nixos/modules/services/misc/docker-registry.nix10
-rw-r--r--nixpkgs/nixos/modules/services/misc/etebase-server.nix28
-rw-r--r--nixpkgs/nixos/modules/services/misc/homepage-dashboard.nix224
-rw-r--r--nixpkgs/nixos/modules/services/misc/paperless.nix1
-rw-r--r--nixpkgs/nixos/modules/services/misc/tabby.nix203
-rw-r--r--nixpkgs/nixos/modules/services/misc/transfer-sh.nix102
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/mackerel-agent.nix2
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/restic.nix13
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/scrutiny.nix149
-rw-r--r--nixpkgs/nixos/modules/services/networking/bird-lg.nix4
-rw-r--r--nixpkgs/nixos/modules/services/networking/tailscale.nix9
-rw-r--r--nixpkgs/nixos/modules/services/security/vaultwarden/default.nix10
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/miniflux.nix28
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/nextcloud.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/photoprism.nix1
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/vikunja.nix47
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/plasma6.nix15
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py11
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix73
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd.nix2
-rw-r--r--nixpkgs/nixos/modules/tasks/filesystems.nix2
-rw-r--r--nixpkgs/nixos/modules/tasks/filesystems/zfs.nix20
-rw-r--r--nixpkgs/nixos/modules/virtualisation/incus.nix7
-rw-r--r--nixpkgs/nixos/modules/virtualisation/oci-containers.nix2
-rw-r--r--nixpkgs/nixos/modules/virtualisation/qemu-vm.nix4
-rw-r--r--nixpkgs/nixos/modules/virtualisation/virtualbox-host.nix51
-rw-r--r--nixpkgs/nixos/tests/acme.nix5
-rw-r--r--nixpkgs/nixos/tests/akkoma.nix12
-rw-r--r--nixpkgs/nixos/tests/all-tests.nix5
-rw-r--r--nixpkgs/nixos/tests/docker-registry.nix2
-rw-r--r--nixpkgs/nixos/tests/homepage-dashboard.nix30
-rw-r--r--nixpkgs/nixos/tests/knot.nix21
-rw-r--r--nixpkgs/nixos/tests/matter-server.nix45
-rw-r--r--nixpkgs/nixos/tests/miniflux.nix78
-rw-r--r--nixpkgs/nixos/tests/minio.nix6
-rw-r--r--nixpkgs/nixos/tests/nixops/default.nix3
-rw-r--r--nixpkgs/nixos/tests/qemu-vm-external-disk-image.nix3
-rw-r--r--nixpkgs/nixos/tests/sanoid.nix3
-rw-r--r--nixpkgs/nixos/tests/systemd-boot.nix38
-rw-r--r--nixpkgs/nixos/tests/transfer-sh.nix20
-rw-r--r--nixpkgs/nixos/tests/vikunja.nix26
-rw-r--r--nixpkgs/nixos/tests/virtualbox.nix47
-rw-r--r--nixpkgs/nixos/tests/zfs.nix18
75 files changed, 1482 insertions, 388 deletions
diff --git a/nixpkgs/nixos/doc/manual/configuration/x-windows.chapter.md b/nixpkgs/nixos/doc/manual/configuration/x-windows.chapter.md
index 0451e4d25265..bf1872ae01ac 100644
--- a/nixpkgs/nixos/doc/manual/configuration/x-windows.chapter.md
+++ b/nixpkgs/nixos/doc/manual/configuration/x-windows.chapter.md
@@ -150,6 +150,7 @@ Or if you have an older card, you may have to use one of the legacy
 drivers:
 
 ```nix
+services.xserver.videoDrivers = [ "nvidiaLegacy470" ];
 services.xserver.videoDrivers = [ "nvidiaLegacy390" ];
 services.xserver.videoDrivers = [ "nvidiaLegacy340" ];
 services.xserver.videoDrivers = [ "nvidiaLegacy304" ];
diff --git a/nixpkgs/nixos/doc/manual/development/replace-modules.section.md b/nixpkgs/nixos/doc/manual/development/replace-modules.section.md
index ac9f5adbaf98..45e2adbc2608 100644
--- a/nixpkgs/nixos/doc/manual/development/replace-modules.section.md
+++ b/nixpkgs/nixos/doc/manual/development/replace-modules.section.md
@@ -47,9 +47,8 @@ without having to know its implementation details.
 ```nix
 { config, lib, pkgs, ... }:
 
-with lib;
-
 let
+  inherit (lib) mkIf mkOption types;
   cfg = config.programs.man;
 in
 
diff --git a/nixpkgs/nixos/doc/manual/development/running-nixos-tests.section.md b/nixpkgs/nixos/doc/manual/development/running-nixos-tests.section.md
index 33076f5dc2a7..b8191ebd313c 100644
--- a/nixpkgs/nixos/doc/manual/development/running-nixos-tests.section.md
+++ b/nixpkgs/nixos/doc/manual/development/running-nixos-tests.section.md
@@ -18,3 +18,13 @@ you can view a log of the test:
 ```ShellSession
 $ nix-store --read-log result
 ```
+
+## System Requirements {#sec-running-nixos-tests-requirements}
+
+NixOS tests require virtualization support.
+This means that the machine must have `kvm` in its [system features](https://nixos.org/manual/nix/stable/command-ref/conf-file.html?highlight=system-features#conf-system-features) list, or `apple-virt` in case of macOS.
+These features are autodetected locally, but `apple-virt` is only autodetected since Nix 2.19.0.
+
+Features of **remote builders** must additionally be configured manually on the client, e.g. on NixOS with [`nix.buildMachines.*.supportedFeatures`](https://search.nixos.org/options?show=nix.buildMachines.*.supportedFeatures&sort=alpha_asc&query=nix.buildMachines) or through general [Nix configuration](https://nixos.org/manual/nix/stable/advanced-topics/distributed-builds).
+
+If you run the tests on a **macOS** machine, you also need a "remote" builder for Linux; possibly a VM. [nix-darwin](https://daiderd.com/nix-darwin/) users may enable [`nix.linux-builder.enable`](https://daiderd.com/nix-darwin/manual/index.html#opt-nix.linux-builder.enable) to launch such a VM.
diff --git a/nixpkgs/nixos/doc/manual/development/writing-modules.chapter.md b/nixpkgs/nixos/doc/manual/development/writing-modules.chapter.md
index e07b899e6df7..20157a21e890 100644
--- a/nixpkgs/nixos/doc/manual/development/writing-modules.chapter.md
+++ b/nixpkgs/nixos/doc/manual/development/writing-modules.chapter.md
@@ -104,9 +104,8 @@ functions system environment substitution should *not* be disabled explicitly.
 ```nix
 { config, lib, pkgs, ... }:
 
-with lib;
-
 let
+  inherit (lib) concatStringsSep mkIf mkOption optionalString types;
   cfg = config.services.locate;
 in {
   options.services.locate = {
@@ -163,9 +162,7 @@ in {
 ::: {#exec-escaping-example .example}
 ### Escaping in Exec directives
 ```nix
-{ config, lib, pkgs, utils, ... }:
-
-with lib;
+{ config, pkgs, utils, ... }:
 
 let
   cfg = config.services.echo;
diff --git a/nixpkgs/nixos/doc/manual/release-notes/rl-2405.section.md b/nixpkgs/nixos/doc/manual/release-notes/rl-2405.section.md
index 510019b58658..665e8590fc42 100644
--- a/nixpkgs/nixos/doc/manual/release-notes/rl-2405.section.md
+++ b/nixpkgs/nixos/doc/manual/release-notes/rl-2405.section.md
@@ -78,9 +78,15 @@ In addition to numerous new and upgraded packages, this release has the followin
 
 - [hebbot](https://github.com/haecker-felix/hebbot), a Matrix bot to generate "This Week in X" like blog posts. Available as [services.hebbot](#opt-services.hebbot.enable).
 
+- [Python Matter Server](https://github.com/home-assistant-libs/python-matter-server), a
+  Matter Controller Server exposing websocket connections for use with other services, notably Home Assistant.
+  Available as [services.matter-server](#opt-services.matter-server.enable)
+
 - [Anki Sync Server](https://docs.ankiweb.net/sync-server.html), the official sync server built into recent versions of Anki. Available as [services.anki-sync-server](#opt-services.anki-sync-server.enable).
 The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been marked deprecated and will be dropped after 24.05 due to lack of maintenance of the anki-sync-server softwares.
 
+- [transfer-sh](https://github.com/dutchcoders/transfer.sh), a tool that supports easy and fast file sharing from the command-line. Available as [services.transfer-sh](#opt-services.transfer-sh.enable).
+
 - [Suwayomi Server](https://github.com/Suwayomi/Suwayomi-Server), a free and open source manga reader server that runs extensions built for [Tachiyomi](https://tachiyomi.org). Available as [services.suwayomi-server](#opt-services.suwayomi-server.enable).
 
 - [ping_exporter](https://github.com/czerwonk/ping_exporter), a Prometheus exporter for ICMP echo requests. Available as [services.prometheus.exporters.ping](#opt-services.prometheus.exporters.ping.enable).
@@ -115,12 +121,19 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - The `power.ups` module now generates `upsd.conf`, `upsd.users` and `upsmon.conf` automatically from a set of new configuration options. This breaks compatibility with existing `power.ups` setups where these files were created manually. Back up these files before upgrading NixOS.
 
+- `k3s` was updated to [v1.29](https://github.com/k3s-io/k3s/releases/tag/v1.29.1%2Bk3s2). See [changelog and upgrade notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.29.md#urgent-upgrade-notes) for more information.
+
 - `k9s` was updated to v0.31. There have been various breaking changes in the config file format,
   check out the changelog of [v0.29](https://github.com/derailed/k9s/releases/tag/v0.29.0),
   [v0.30](https://github.com/derailed/k9s/releases/tag/v0.30.0) and
   [v0.31](https://github.com/derailed/k9s/releases/tag/v0.31.0) for details. It is recommended
   to back up your current configuration and let k9s recreate the new base configuration.
 
+- The option `services.postgresql.ensureUsers._.ensurePermissions` has been removed as it's
+  not declarative and is broken with newer postgresql versions. Consider using
+  [](#opt-services.postgresql.ensureUsers._.ensureDBOwnership)
+  instead or a tool that's more suited for managing the data inside a postgresql database.
+
 - `idris2` was updated to v0.7.0. This version introduces breaking changes. Check out the [changelog](https://github.com/idris-lang/Idris2/blob/v0.7.0/CHANGELOG.md#v070) for details.
 
 - `neo4j` has been updated to 5, you may want to read the [release notes for Neo4j 5](https://neo4j.com/release-notes/database/neo4j-5/)
@@ -144,6 +157,10 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - `paperless`' `services.paperless.extraConfig` setting has been removed and converted to the freeform type and option named `services.paperless.settings`.
 
+- `services.homepage-dashboard` now takes it's configuration using native Nix expressions, rather than dumping templated configurations into `/var/lib/homepage-dashboard` where they were previously managed manually. There are now new options which allow the configuration of bookmarks, services, widgets and custom CSS/JS natively in Nix.
+
+- `hare` may now be cross-compiled. For that to work, however, `haredoc` needed to stop being built together with it. Thus, the latter is now its own package with the name of `haredoc`.
+
 - The legacy and long deprecated systemd target `network-interfaces.target` has been removed. Use `network.target` instead.
 
 - `services.frp.settings` now generates the frp configuration file in TOML format as [recommended by upstream](https://github.com/fatedier/frp#configuration-files), instead of the legacy INI format. This has also introduced other changes in the configuration file structure and options.
@@ -156,6 +173,10 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
   release notes of [v19](https://github.com/systemd/mkosi/releases/tag/v19) and
   [v20](https://github.com/systemd/mkosi/releases/tag/v20) for a list of changes.
 
+- The `services.vikunja` systemd service now uses `vikunja` as dynamic user instead of `vikunja-api`. Database users might need to be changed.
+
+- The `services.vikunja.setupNginx` setting has been removed. Users now need to setup the webserver configuration on their own with a proxy pass to the vikunja service.
+
 - The `woodpecker-*` packages have been updated to v2 which includes [breaking changes](https://woodpecker-ci.org/docs/next/migrations#200).
 
 - `services.nginx` will no longer advertise HTTP/3 availability automatically. This must now be manually added, preferably to each location block.
@@ -338,6 +359,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - A new hardening flag, `zerocallusedregs` was made available, corresponding to the gcc/clang option `-fzero-call-used-regs=used-gpr`.
 
+- A new hardening flag, `trivialautovarinit` was made available, corresponding to the gcc/clang option `-ftrivial-auto-var-init=pattern`.
+
 - New options were added to the dnsdist module to enable and configure a DNSCrypt endpoint (see `services.dnsdist.dnscrypt.enable`, etc.).
   The module can generate the DNSCrypt provider key pair, certificates and also performs their rotation automatically with no downtime.
 
diff --git a/nixpkgs/nixos/lib/make-disk-image.nix b/nixpkgs/nixos/lib/make-disk-image.nix
index da94ef16654c..9bdbf4e0713d 100644
--- a/nixpkgs/nixos/lib/make-disk-image.nix
+++ b/nixpkgs/nixos/lib/make-disk-image.nix
@@ -609,6 +609,13 @@ let format' = format; in let
         ''}
 
         # Set up core system link, bootloader (sd-boot, GRUB, uboot, etc.), etc.
+
+        # NOTE: systemd-boot-builder.py calls nix-env --list-generations which
+        # clobbers $HOME/.nix-defexpr/channels/nixos This would cause a  folder
+        # /homeless-shelter to show up in the final image which  in turn breaks
+        # nix builds in the target image if sandboxing is turned off (through
+        # __noChroot for example).
+        export HOME=$TMPDIR
         NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root $mountPoint -- /nix/var/nix/profiles/system/bin/switch-to-configuration boot
 
         # The above scripts will generate a random machine-id and we don't want to bake a single ID into all our images
diff --git a/nixpkgs/nixos/lib/test-driver/test_driver/driver.py b/nixpkgs/nixos/lib/test-driver/test_driver/driver.py
index 72a33e0b2d57..f792c0459199 100644
--- a/nixpkgs/nixos/lib/test-driver/test_driver/driver.py
+++ b/nixpkgs/nixos/lib/test-driver/test_driver/driver.py
@@ -7,6 +7,8 @@ from contextlib import contextmanager
 from pathlib import Path
 from typing import Any, Callable, ContextManager, Dict, Iterator, List, Optional, Union
 
+from colorama import Fore, Style
+
 from test_driver.logger import rootlog
 from test_driver.machine import Machine, NixStartScript, retry
 from test_driver.polling_condition import PollingCondition
@@ -226,7 +228,10 @@ class Driver:
                 )
 
             rootlog.warning(
-                "Using create_machine with a single dictionary argument is deprecated, and will be removed in NixOS 24.11"
+                Fore.YELLOW
+                + Style.BRIGHT
+                + "WARNING: Using create_machine with a single dictionary argument is deprecated and will be removed in NixOS 24.11"
+                + Style.RESET_ALL
             )
         # End legacy args handling
 
diff --git a/nixpkgs/nixos/lib/test-driver/test_driver/logger.py b/nixpkgs/nixos/lib/test-driver/test_driver/logger.py
index 116244b5e4ae..0b0623bddfa1 100644
--- a/nixpkgs/nixos/lib/test-driver/test_driver/logger.py
+++ b/nixpkgs/nixos/lib/test-driver/test_driver/logger.py
@@ -1,6 +1,3 @@
-# mypy: disable-error-code="no-untyped-call"
-# drop the above line when mypy is upgraded to include
-# https://github.com/python/typeshed/commit/49b717ca52bf0781a538b04c0d76a5513f7119b8
 import codecs
 import os
 import sys
@@ -10,6 +7,7 @@ from contextlib import contextmanager
 from queue import Empty, Queue
 from typing import Any, Dict, Iterator
 from xml.sax.saxutils import XMLGenerator
+from xml.sax.xmlreader import AttributesImpl
 
 from colorama import Fore, Style
 
@@ -22,7 +20,7 @@ class Logger:
         self.queue: "Queue[Dict[str, str]]" = Queue()
 
         self.xml.startDocument()
-        self.xml.startElement("logfile", attrs={})
+        self.xml.startElement("logfile", attrs=AttributesImpl({}))
 
         self._print_serial_logs = True
 
@@ -44,7 +42,7 @@ class Logger:
         return message
 
     def log_line(self, message: str, attributes: Dict[str, str]) -> None:
-        self.xml.startElement("line", attributes)
+        self.xml.startElement("line", attrs=AttributesImpl(attributes))
         self.xml.characters(message)
         self.xml.endElement("line")
 
@@ -89,8 +87,8 @@ class Logger:
             )
         )
 
-        self.xml.startElement("nest", attrs={})
-        self.xml.startElement("head", attributes)
+        self.xml.startElement("nest", attrs=AttributesImpl({}))
+        self.xml.startElement("head", attrs=AttributesImpl(attributes))
         self.xml.characters(message)
         self.xml.endElement("head")
 
diff --git a/nixpkgs/nixos/lib/testing/nodes.nix b/nixpkgs/nixos/lib/testing/nodes.nix
index 73e6d386fd1d..7941d69e38d2 100644
--- a/nixpkgs/nixos/lib/testing/nodes.nix
+++ b/nixpkgs/nixos/lib/testing/nodes.nix
@@ -14,6 +14,25 @@ let
     types
     ;
 
+  inherit (hostPkgs) hostPlatform;
+
+  guestSystem =
+    if hostPlatform.isLinux
+    then hostPlatform.system
+    else
+      let
+        hostToGuest = {
+          "x86_64-darwin" = "x86_64-linux";
+          "aarch64-darwin" = "aarch64-linux";
+        };
+
+        supportedHosts = lib.concatStringsSep ", " (lib.attrNames hostToGuest);
+
+        message =
+          "NixOS Test: don't know which VM guest system to pair with VM host system: ${hostPlatform.system}. Perhaps you intended to run the tests on a Linux host, or one of the following systems that may run NixOS tests: ${supportedHosts}";
+      in
+        hostToGuest.${hostPlatform.system} or (throw message);
+
   baseOS =
     import ../eval-config.nix {
       inherit lib;
@@ -27,13 +46,14 @@ let
           ({ config, ... }:
             {
               virtualisation.qemu.package = testModuleArgs.config.qemu.package;
+              virtualisation.host.pkgs = hostPkgs;
             })
           ({ options, ... }: {
             key = "nodes.nix-pkgs";
             config = optionalAttrs (!config.node.pkgsReadOnly) (
               mkIf (!options.nixpkgs.pkgs.isDefined) {
                 # TODO: switch to nixpkgs.hostPlatform and make sure containers-imperative test still evaluates.
-                nixpkgs.system = hostPkgs.stdenv.hostPlatform.system;
+                nixpkgs.system = guestSystem;
               }
             );
           })
diff --git a/nixpkgs/nixos/lib/testing/pkgs.nix b/nixpkgs/nixos/lib/testing/pkgs.nix
index 22dd586868e3..46d82c65d26a 100644
--- a/nixpkgs/nixos/lib/testing/pkgs.nix
+++ b/nixpkgs/nixos/lib/testing/pkgs.nix
@@ -2,7 +2,11 @@
 {
   config = {
     # default pkgs for use in VMs
-    _module.args.pkgs = hostPkgs;
+    _module.args.pkgs =
+      # TODO: deprecate it everywhere; not just on darwin. Throw on darwin?
+      lib.warnIf hostPkgs.stdenv.hostPlatform.isDarwin
+        "Do not use the `pkgs` module argument in tests you want to run on darwin. It is ambiguous, and many tests are broken because of it. If you need to use a package on the VM host, use `hostPkgs`. Otherwise, use `config.node.pkgs`, or `config.nodes.<name>.nixpkgs.pkgs`."
+        hostPkgs;
 
     defaults = {
       # TODO: a module to set a shared pkgs, if options.nixpkgs.* is untouched by user (highestPrio) */
diff --git a/nixpkgs/nixos/lib/testing/run.nix b/nixpkgs/nixos/lib/testing/run.nix
index 9440c1acdfd8..de5a9b97e61d 100644
--- a/nixpkgs/nixos/lib/testing/run.nix
+++ b/nixpkgs/nixos/lib/testing/run.nix
@@ -41,7 +41,9 @@ in
     rawTestDerivation = hostPkgs.stdenv.mkDerivation {
       name = "vm-test-run-${config.name}";
 
-      requiredSystemFeatures = [ "kvm" "nixos-test" ];
+      requiredSystemFeatures = [ "nixos-test" ]
+        ++ lib.optionals hostPkgs.stdenv.hostPlatform.isLinux [ "kvm" ]
+        ++ lib.optionals hostPkgs.stdenv.hostPlatform.isDarwin [ "apple-virt" ];
 
       buildCommand = ''
         mkdir -p $out
diff --git a/nixpkgs/nixos/modules/config/users-groups.nix b/nixpkgs/nixos/modules/config/users-groups.nix
index dd34771c0b42..02cd1a17f538 100644
--- a/nixpkgs/nixos/modules/config/users-groups.nix
+++ b/nixpkgs/nixos/modules/config/users-groups.nix
@@ -704,6 +704,11 @@ in {
     in stringAfter [ "users" ] ''
       if [ -e ${lingerDir} ] ; then
         cd ${lingerDir}
+        for user in ${lingerDir}/*; do
+          if ! id "$user" >/dev/null 2>&1; then
+            rm --force -- "$user"
+          fi
+        done
         ls ${lingerDir} | sort | comm -3 -1 ${lingeringUsersFile} - | xargs -r ${pkgs.systemd}/bin/loginctl disable-linger
         ls ${lingerDir} | sort | comm -3 -2 ${lingeringUsersFile} - | xargs -r ${pkgs.systemd}/bin/loginctl  enable-linger
       fi
diff --git a/nixpkgs/nixos/modules/i18n/input-method/fcitx5.nix b/nixpkgs/nixos/modules/i18n/input-method/fcitx5.nix
index 530727f3f292..ee8d2652b1c7 100644
--- a/nixpkgs/nixos/modules/i18n/input-method/fcitx5.nix
+++ b/nixpkgs/nixos/modules/i18n/input-method/fcitx5.nix
@@ -5,7 +5,10 @@ with lib;
 let
   im = config.i18n.inputMethod;
   cfg = im.fcitx5;
-  fcitx5Package = pkgs.fcitx5-with-addons.override { inherit (cfg) addons; };
+  fcitx5Package =
+    if cfg.plasma6Support
+    then pkgs.qt6Packages.fcitx5-with-addons.override { inherit (cfg) addons; }
+    else pkgs.libsForQt5.fcitx5-with-addons.override { inherit (cfg) addons; };
   settingsFormat = pkgs.formats.ini { };
 in
 {
@@ -27,6 +30,15 @@ in
           See [Using Fcitx 5 on Wayland](https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland).
         '';
       };
+      plasma6Support = mkOption {
+        type = types.bool;
+        default = config.services.xserver.desktopManager.plasma6.enable;
+        defaultText = literalExpression "config.services.xserver.desktopManager.plasma6.enable";
+        description = lib.mdDoc ''
+          Use qt6 versions of fcitx5 packages.
+          Required for configuring fcitx5 in KDE System Settings.
+        '';
+      };
       quickPhrase = mkOption {
         type = with types; attrsOf str;
         default = { };
diff --git a/nixpkgs/nixos/modules/misc/nixpkgs.nix b/nixpkgs/nixos/modules/misc/nixpkgs.nix
index da321a923449..10f800cd741a 100644
--- a/nixpkgs/nixos/modules/misc/nixpkgs.nix
+++ b/nixpkgs/nixos/modules/misc/nixpkgs.nix
@@ -208,7 +208,11 @@ in
       example = { system = "x86_64-linux"; };
       # Make sure that the final value has all fields for sake of other modules
       # referring to this.
-      apply = lib.systems.elaborate;
+      apply = inputBuildPlatform:
+        let elaborated = lib.systems.elaborate inputBuildPlatform;
+        in if lib.systems.equals elaborated cfg.hostPlatform
+          then cfg.hostPlatform  # make identical, so that `==` equality works; see https://github.com/NixOS/nixpkgs/issues/278001
+          else elaborated;
       defaultText = literalExpression
         ''config.nixpkgs.hostPlatform'';
       description = lib.mdDoc ''
diff --git a/nixpkgs/nixos/modules/misc/nixpkgs/test.nix b/nixpkgs/nixos/modules/misc/nixpkgs/test.nix
index 0536cfc9624a..be9a88a07788 100644
--- a/nixpkgs/nixos/modules/misc/nixpkgs/test.nix
+++ b/nixpkgs/nixos/modules/misc/nixpkgs/test.nix
@@ -12,6 +12,10 @@ let
     nixpkgs.hostPlatform = "aarch64-linux";
     nixpkgs.buildPlatform = "aarch64-darwin";
   };
+  withSameHostAndBuild = eval {
+    nixpkgs.hostPlatform = "aarch64-linux";
+    nixpkgs.buildPlatform = "aarch64-linux";
+  };
   ambiguous = {
     _file = "ambiguous.nix";
     nixpkgs.hostPlatform = "aarch64-linux";
@@ -81,6 +85,8 @@ lib.recurseIntoAttrs {
     assert withHost._module.args.pkgs.stdenv.buildPlatform.system == "aarch64-linux";
     assert withHostAndBuild._module.args.pkgs.stdenv.hostPlatform.system == "aarch64-linux";
     assert withHostAndBuild._module.args.pkgs.stdenv.buildPlatform.system == "aarch64-darwin";
+    assert withSameHostAndBuild.config.nixpkgs.buildPlatform == withSameHostAndBuild.config.nixpkgs.hostPlatform;
+    assert withSameHostAndBuild._module.args.pkgs.stdenv.buildPlatform == withSameHostAndBuild._module.args.pkgs.stdenv.hostPlatform;
     assert builtins.trace (lib.head (getErrors ambiguous))
       getErrors ambiguous ==
         [''
diff --git a/nixpkgs/nixos/modules/module-list.nix b/nixpkgs/nixos/modules/module-list.nix
index 08144140b830..bbca2fa76855 100644
--- a/nixpkgs/nixos/modules/module-list.nix
+++ b/nixpkgs/nixos/modules/module-list.nix
@@ -163,6 +163,7 @@
   ./programs/clash-verge.nix
   ./programs/cnping.nix
   ./programs/command-not-found/command-not-found.nix
+  ./programs/coolercontrol.nix
   ./programs/criu.nix
   ./programs/darling.nix
   ./programs/dconf.nix
@@ -586,6 +587,7 @@
   ./services/home-automation/govee2mqtt.nix
   ./services/home-automation/home-assistant.nix
   ./services/home-automation/homeassistant-satellite.nix
+  ./services/home-automation/matter-server.nix
   ./services/home-automation/zigbee2mqtt.nix
   ./services/home-automation/zwave-js.nix
   ./services/logging/SystemdJournal2Gelf.nix
@@ -719,6 +721,7 @@
   ./services/misc/libreddit.nix
   ./services/misc/lidarr.nix
   ./services/misc/lifecycled.nix
+  ./services/misc/llama-cpp.nix
   ./services/misc/logkeys.nix
   ./services/misc/mame.nix
   ./services/misc/mbpfan.nix
@@ -781,12 +784,14 @@
   ./services/misc/svnserve.nix
   ./services/misc/synergy.nix
   ./services/misc/sysprof.nix
+  ./services/misc/tabby.nix
   ./services/misc/tandoor-recipes.nix
   ./services/misc/taskserver
   ./services/misc/tautulli.nix
   ./services/misc/tiddlywiki.nix
   ./services/misc/tp-auto-kbbl.nix
   ./services/misc/tuxclocker.nix
+  ./services/misc/transfer-sh.nix
   ./services/misc/tzupdate.nix
   ./services/misc/uhub.nix
   ./services/misc/weechat.nix
diff --git a/nixpkgs/nixos/modules/programs/chromium.nix b/nixpkgs/nixos/modules/programs/chromium.nix
index 45a9e9e2a689..5e8983730048 100644
--- a/nixpkgs/nixos/modules/programs/chromium.nix
+++ b/nixpkgs/nixos/modules/programs/chromium.nix
@@ -98,6 +98,24 @@ in
           }
         '';
       };
+
+      initialPrefs = mkOption {
+        type = types.attrs;
+        description = lib.mdDoc ''
+          Initial preferences are used to configure the browser for the first run.
+          Unlike {option}`programs.chromium.extraOpts`, initialPrefs can be changed by users in the browser settings.
+          More information can be found in the Chromium documentation:
+          <https://www.chromium.org/administrators/configuring-other-preferences/>
+        '';
+        default = {};
+        example = literalExpression ''
+          {
+            "first_run_tabs" = [
+              "https://nixos.org/"
+            ];
+          }
+        '';
+      };
     };
   };
 
@@ -110,6 +128,7 @@ in
         { source = "${cfg.plasmaBrowserIntegrationPackage}/etc/chromium/native-messaging-hosts/org.kde.plasma.browser_integration.json"; };
       "chromium/policies/managed/default.json" = lib.mkIf (defaultProfile != {}) { text = builtins.toJSON defaultProfile; };
       "chromium/policies/managed/extra.json" = lib.mkIf (cfg.extraOpts != {}) { text = builtins.toJSON cfg.extraOpts; };
+      "chromium/initial_preferences" = lib.mkIf (cfg.initialPrefs != {}) { text = builtins.toJSON cfg.initialPrefs; };
       # for google-chrome https://www.chromium.org/administrators/linux-quick-start
       "opt/chrome/native-messaging-hosts/org.kde.plasma.browser_integration.json" = lib.mkIf cfg.enablePlasmaBrowserIntegration
         { source = "${cfg.plasmaBrowserIntegrationPackage}/etc/opt/chrome/native-messaging-hosts/org.kde.plasma.browser_integration.json"; };
diff --git a/nixpkgs/nixos/modules/programs/coolercontrol.nix b/nixpkgs/nixos/modules/programs/coolercontrol.nix
new file mode 100644
index 000000000000..6e7299ad16b7
--- /dev/null
+++ b/nixpkgs/nixos/modules/programs/coolercontrol.nix
@@ -0,0 +1,37 @@
+{ config
+, lib
+, pkgs
+, ...
+}:
+
+let
+  cfg = config.programs.coolercontrol;
+in
+{
+  ##### interface
+  options = {
+    programs.coolercontrol.enable = lib.mkEnableOption (lib.mdDoc "CoolerControl GUI & its background services");
+  };
+
+  ##### implementation
+  config = lib.mkIf cfg.enable {
+    environment.systemPackages = with pkgs.coolercontrol; [
+      coolercontrol-gui
+    ];
+
+    systemd = {
+      packages = with pkgs.coolercontrol; [
+        coolercontrol-liqctld
+        coolercontrold
+      ];
+
+      # https://github.com/NixOS/nixpkgs/issues/81138
+      services = {
+        coolercontrol-liqctld.wantedBy = [ "multi-user.target" ];
+        coolercontrold.wantedBy = [ "multi-user.target" ];
+      };
+    };
+  };
+
+  meta.maintainers = with lib.maintainers; [ OPNA2608 codifryed ];
+}
diff --git a/nixpkgs/nixos/modules/programs/kdeconnect.nix b/nixpkgs/nixos/modules/programs/kdeconnect.nix
index a16fad03eefe..8cdf1eb4e645 100644
--- a/nixpkgs/nixos/modules/programs/kdeconnect.nix
+++ b/nixpkgs/nixos/modules/programs/kdeconnect.nix
@@ -20,7 +20,10 @@ with lib;
       cfg = config.programs.kdeconnect;
     in
       mkIf cfg.enable {
-        environment.systemPackages = [ cfg.package ];
+        environment.systemPackages = [
+          cfg.package
+          pkgs.sshfs
+        ];
         networking.firewall = rec {
           allowedTCPPortRanges = [ { from = 1714; to = 1764; } ];
           allowedUDPPortRanges = allowedTCPPortRanges;
diff --git a/nixpkgs/nixos/modules/programs/steam.nix b/nixpkgs/nixos/modules/programs/steam.nix
index c7f1e622f7ba..31803f061dce 100644
--- a/nixpkgs/nixos/modules/programs/steam.nix
+++ b/nixpkgs/nixos/modules/programs/steam.nix
@@ -43,6 +43,9 @@ in {
         }
       '';
       apply = steam: steam.override (prev: {
+        extraEnv = (lib.optionalAttrs (cfg.extraCompatPackages != [ ]) {
+            STEAM_EXTRA_COMPAT_TOOLS_PATHS = makeBinPath cfg.extraCompatPackages;
+          }) // (prev.extraEnv or {});
         extraLibraries = pkgs: let
           prevLibs = if prev ? extraLibraries then prev.extraLibraries pkgs else [ ];
           additionalLibs = with config.hardware.opengl;
@@ -56,6 +59,8 @@ in {
           # use the setuid wrapped bubblewrap
           bubblewrap = "${config.security.wrapperDir}/..";
         };
+      } // optionalAttrs cfg.extest.enable {
+        extraEnv.LD_PRELOAD = "${pkgs.pkgsi686Linux.extest}/lib/libextest.so";
       });
       description = lib.mdDoc ''
         The Steam package to use. Additional libraries are added from the system
@@ -66,6 +71,16 @@ in {
       '';
     };
 
+    extraCompatPackages = mkOption {
+      type = types.listOf types.package;
+      default = [ ];
+      description = lib.mdDoc ''
+        Extra packages to be used as compatibility tools for Steam on Linux. Packages will be included
+        in the `STEAM_EXTRA_COMPAT_TOOLS_PATHS` environmental variable. For more information see
+        <https://github.com/ValveSoftware/steam-for-linux/issues/6310">.
+      '';
+    };
+
     remotePlay.openFirewall = mkOption {
       type = types.bool;
       default = false;
@@ -114,6 +129,11 @@ in {
         };
       };
     };
+
+    extest.enable = mkEnableOption (lib.mdDoc ''
+      Load the extest library into Steam, to translate X11 input events to
+      uinput events (e.g. for using Steam Input on Wayland)
+    '');
   };
 
   config = mkIf cfg.enable {
@@ -167,5 +187,5 @@ in {
     ];
   };
 
-  meta.maintainers = with maintainers; [ mkg20001 ];
+  meta.maintainers = teams.steam;
 }
diff --git a/nixpkgs/nixos/modules/security/pam.nix b/nixpkgs/nixos/modules/security/pam.nix
index b87e22b23980..560e5eff5c39 100644
--- a/nixpkgs/nixos/modules/security/pam.nix
+++ b/nixpkgs/nixos/modules/security/pam.nix
@@ -1465,9 +1465,9 @@ in
         '';
       }
       {
-        assertion = config.security.pam.zfs.enable -> (config.boot.zfs.enabled || config.boot.zfs.enableUnstable);
+        assertion = config.security.pam.zfs.enable -> config.boot.zfs.enabled;
         message = ''
-          `security.pam.zfs.enable` requires enabling ZFS (`boot.zfs.enabled` or `boot.zfs.enableUnstable`).
+          `security.pam.zfs.enable` requires enabling ZFS (`boot.zfs.enabled`).
         '';
       }
       {
diff --git a/nixpkgs/nixos/modules/services/backup/syncoid.nix b/nixpkgs/nixos/modules/services/backup/syncoid.nix
index 7b8d3b431309..4a04f0aa1622 100644
--- a/nixpkgs/nixos/modules/services/backup/syncoid.nix
+++ b/nixpkgs/nixos/modules/services/backup/syncoid.nix
@@ -134,7 +134,7 @@ in
     localSourceAllow = mkOption {
       type = types.listOf types.str;
       # Permissions snapshot and destroy are in case --no-sync-snap is not used
-      default = [ "bookmark" "hold" "send" "snapshot" "destroy" ];
+      default = [ "bookmark" "hold" "send" "snapshot" "destroy" "mount" ];
       description = lib.mdDoc ''
         Permissions granted for the {option}`services.syncoid.user` user
         for local source datasets. See
diff --git a/nixpkgs/nixos/modules/services/databases/memcached.nix b/nixpkgs/nixos/modules/services/databases/memcached.nix
index 542c80ab2e67..fd943c20091a 100644
--- a/nixpkgs/nixos/modules/services/databases/memcached.nix
+++ b/nixpkgs/nixos/modules/services/databases/memcached.nix
@@ -37,7 +37,7 @@ in
         description = lib.mdDoc "The port to bind to.";
       };
 
-      enableUnixSocket = mkEnableOption (lib.mdDoc "unix socket at /run/memcached/memcached.sock");
+      enableUnixSocket = mkEnableOption (lib.mdDoc "Unix Domain Socket at /run/memcached/memcached.sock instead of listening on an IP address and port. The `listen` and `port` options are ignored.");
 
       maxMemory = mkOption {
         type = types.ints.unsigned;
diff --git a/nixpkgs/nixos/modules/services/databases/postgresql.nix b/nixpkgs/nixos/modules/services/databases/postgresql.nix
index ed5915735730..c4e76c82ba5c 100644
--- a/nixpkgs/nixos/modules/services/databases/postgresql.nix
+++ b/nixpkgs/nixos/modules/services/databases/postgresql.nix
@@ -161,33 +161,6 @@ in
               '';
             };
 
-            ensurePermissions = mkOption {
-              type = types.attrsOf types.str;
-              default = {};
-              visible = false; # This option has been deprecated.
-              description = lib.mdDoc ''
-                This option is DEPRECATED and should not be used in nixpkgs anymore,
-                use `ensureDBOwnership` instead. It can also break with newer
-                versions of PostgreSQL (≥ 15).
-
-                Permissions to ensure for the user, specified as an attribute set.
-                The attribute names specify the database and tables to grant the permissions for.
-                The attribute values specify the permissions to grant. You may specify one or
-                multiple comma-separated SQL privileges here.
-
-                For more information on how to specify the target
-                and on which privileges exist, see the
-                [GRANT syntax](https://www.postgresql.org/docs/current/sql-grant.html).
-                The attributes are used as `GRANT ''${attrValue} ON ''${attrName}`.
-              '';
-              example = literalExpression ''
-                {
-                  "DATABASE \"nextcloud\"" = "ALL PRIVILEGES";
-                  "ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES";
-                }
-              '';
-            };
-
             ensureDBOwnership = mkOption {
               type = types.bool;
               default = false;
@@ -460,16 +433,6 @@ in
         Offender: ${name} has not been found among databases.
       '';
     }) cfg.ensureUsers;
-    # `ensurePermissions` is now deprecated, let's avoid it.
-    warnings = lib.optional (any ({ ensurePermissions, ... }: ensurePermissions != {}) cfg.ensureUsers) "
-      `services.postgresql.ensureUsers.*.ensurePermissions` is used in your expressions,
-      this option is known to be broken with newer PostgreSQL versions,
-      consider migrating to `services.postgresql.ensureUsers.*.ensureDBOwnership` or
-      consult the release notes or manual for more migration guidelines.
-
-      This option will be removed in NixOS 24.05 unless it sees significant
-      maintenance improvements.
-    ";
 
     services.postgresql.settings =
       {
@@ -583,11 +546,6 @@ in
               concatMapStrings
               (user:
               let
-                  userPermissions = concatStringsSep "\n"
-                    (mapAttrsToList
-                      (database: permission: ''$PSQL -tAc 'GRANT ${permission} ON ${database} TO "${user.name}"' '')
-                      user.ensurePermissions
-                    );
                   dbOwnershipStmt = optionalString
                     user.ensureDBOwnership
                     ''$PSQL -tAc 'ALTER DATABASE "${user.name}" OWNER TO "${user.name}";' '';
@@ -599,7 +557,6 @@ in
                   userClauses = ''$PSQL -tAc 'ALTER ROLE "${user.name}" ${concatStringsSep " " clauseSqlStatements}' '';
                 in ''
                   $PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname='${user.name}'" | grep -q 1 || $PSQL -tAc 'CREATE USER "${user.name}"'
-                  ${userPermissions}
                   ${userClauses}
 
                   ${dbOwnershipStmt}
diff --git a/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix b/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix
index 8f3ad78d50ce..09448833620c 100644
--- a/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix
+++ b/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix
@@ -246,6 +246,9 @@ in {
         description = lib.mdDoc ''
           List of packages that provide PipeWire configuration, in the form of
           `share/pipewire/*/*.conf` files.
+
+          LV2 dependencies will be picked up from config packages automatically
+          via `passthru.requiredLv2Packages`.
         '';
       };
 
@@ -258,7 +261,8 @@ in {
           be made available to PipeWire for [filter chains][wiki-filter-chain].
 
           Config packages have their required LV2 plugins added automatically,
-          so they don't need to be specified here.
+          so they don't need to be specified here. Config packages need to set
+          `passthru.requiredLv2Packages` for this to work.
 
           [wiki-filter-chain]: https://docs.pipewire.org/page_module_filter_chain.html
         '';
diff --git a/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix b/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix
index 99aea8facb16..009d68bd4f28 100644
--- a/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix
+++ b/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix
@@ -30,6 +30,9 @@ in
         description = lib.mdDoc ''
           List of packages that provide WirePlumber configuration, in the form of
           `share/wireplumber/*/*.lua` files.
+
+          LV2 dependencies will be picked up from config packages automatically
+          via `passthru.requiredLv2Packages`.
         '';
       };
 
@@ -42,7 +45,8 @@ in
           be made available to WirePlumber for [filter chains][wiki-filter-chain].
 
           Config packages have their required LV2 plugins added automatically,
-          so they don't need to be specified here.
+          so they don't need to be specified here. Config packages need to set
+          `passthru.requiredLv2Packages` for this to work.
 
           [wiki-filter-chain]: https://docs.pipewire.org/page_module_filter_chain.html
         '';
@@ -108,7 +112,7 @@ in
                   )
                   config.environment.etc
               )) == 1;
-          message = "Using `environment.etc.\"wireplumber<...>\"` directly is no longer supported in 24.05. Use `services.wireplumber.configPackages` instead.";
+          message = "Using `environment.etc.\"wireplumber<...>\"` directly is no longer supported in 24.05. Use `services.pipewire.wireplumber.configPackages` instead.";
         }
       ];
 
diff --git a/nixpkgs/nixos/modules/services/development/nixseparatedebuginfod.nix b/nixpkgs/nixos/modules/services/development/nixseparatedebuginfod.nix
index daf85153d339..a2ec0d2c80e1 100644
--- a/nixpkgs/nixos/modules/services/development/nixseparatedebuginfod.nix
+++ b/nixpkgs/nixos/modules/services/development/nixseparatedebuginfod.nix
@@ -90,7 +90,9 @@ in
 
     users.groups.nixseparatedebuginfod = { };
 
-    nix.settings.extra-allowed-users = [ "nixseparatedebuginfod" ];
+    nix.settings = lib.optionalAttrs (lib.versionAtLeast config.nix.package.version "2.4") {
+      extra-allowed-users = [ "nixseparatedebuginfod" ];
+    };
 
     environment.variables.DEBUGINFOD_URLS = "http://${url}";
 
diff --git a/nixpkgs/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/cdi-generate.nix b/nixpkgs/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/cdi-generate.nix
index a90d234f65c0..1aaa2d07b9bd 100644
--- a/nixpkgs/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/cdi-generate.nix
+++ b/nixpkgs/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/cdi-generate.nix
@@ -1,37 +1,58 @@
-{ config, lib, pkgs }: let
+{
+  addDriverRunpath,
+  glibc,
+  jq,
+  lib,
+  nvidia-container-toolkit,
+  nvidia-driver,
+  runtimeShell,
+  writeScriptBin,
+}:
+let
   mountOptions = { options = ["ro" "nosuid" "nodev" "bind"]; };
   mounts = [
-    { hostPath = "${lib.getBin config.hardware.nvidia.package}/bin/nvidia-cuda-mps-control";
+    # FIXME: Making /usr mounts optional
+    { hostPath = lib.getExe' nvidia-driver "nvidia-cuda-mps-control";
       containerPath = "/usr/bin/nvidia-cuda-mps-control"; }
-    { hostPath = "${lib.getBin config.hardware.nvidia.package}/bin/nvidia-cuda-mps-server";
+    { hostPath = lib.getExe' nvidia-driver "nvidia-cuda-mps-server";
       containerPath = "/usr/bin/nvidia-cuda-mps-server"; }
-    { hostPath = "${lib.getBin config.hardware.nvidia.package}/bin/nvidia-debugdump";
+    { hostPath = lib.getExe' nvidia-driver "nvidia-debugdump";
       containerPath = "/usr/bin/nvidia-debugdump"; }
-    { hostPath = "${lib.getBin config.hardware.nvidia.package}/bin/nvidia-powerd";
+    { hostPath = lib.getExe' nvidia-driver "nvidia-powerd";
       containerPath = "/usr/bin/nvidia-powerd"; }
-    { hostPath = "${lib.getBin config.hardware.nvidia.package}/bin/nvidia-smi";
+    { hostPath = lib.getExe' nvidia-driver "nvidia-smi";
       containerPath = "/usr/bin/nvidia-smi"; }
-    { hostPath = "${pkgs.nvidia-container-toolkit}/bin/nvidia-ctk";
+    { hostPath = lib.getExe' nvidia-container-toolkit "nvidia-ctk";
       containerPath = "/usr/bin/nvidia-ctk"; }
-    { hostPath = "${pkgs.glibc}/lib";
-      containerPath = "${pkgs.glibc}/lib"; }
-    { hostPath = "${pkgs.glibc}/lib64";
-      containerPath = "${pkgs.glibc}/lib64"; }
+    { hostPath = "${lib.getLib glibc}/lib";
+      containerPath = "${lib.getLib glibc}/lib"; }
+
+    # FIXME: use closureinfo
+    {
+      hostPath = addDriverRunpath.driverLink;
+      containerPath = addDriverRunpath.driverLink;
+    }
+    { hostPath = "${lib.getLib glibc}/lib";
+      containerPath = "${lib.getLib glibc}/lib"; }
+    { hostPath = "${lib.getLib glibc}/lib64";
+      containerPath = "${lib.getLib glibc}/lib64"; }
   ];
   jqAddMountExpression = ".containerEdits.mounts[.containerEdits.mounts | length] |= . +";
   mountsToJq = lib.concatMap
     (mount:
-      ["${pkgs.jq}/bin/jq '${jqAddMountExpression} ${builtins.toJSON (mount // mountOptions)}'"])
+      ["${lib.getExe jq} '${jqAddMountExpression} ${builtins.toJSON (mount // mountOptions)}'"])
     mounts;
-in ''
-#! ${pkgs.runtimeShell}
+in
+writeScriptBin "nvidia-cdi-generator"
+''
+#! ${runtimeShell}
 
 function cdiGenerate {
-  ${pkgs.nvidia-container-toolkit}/bin/nvidia-ctk cdi generate \
+  ${lib.getExe' nvidia-container-toolkit "nvidia-ctk"} cdi generate \
     --format json \
-    --ldconfig-path ${pkgs.glibc.bin}/bin/ldconfig \
-    --library-search-path ${config.hardware.nvidia.package}/lib \
-    --nvidia-ctk-path ${pkgs.nvidia-container-toolkit}/bin/nvidia-ctk
+    --ldconfig-path ${lib.getExe' glibc "ldconfig"} \
+    --library-search-path ${lib.getLib nvidia-driver}/lib \
+    --nvidia-ctk-path ${lib.getExe' nvidia-container-toolkit "nvidia-ctk"}
 }
 
 cdiGenerate | \
diff --git a/nixpkgs/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/default.nix b/nixpkgs/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/default.nix
index 3c96e9c41be5..b95bdf191fad 100644
--- a/nixpkgs/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/default.nix
+++ b/nixpkgs/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/default.nix
@@ -26,9 +26,11 @@
       serviceConfig = {
         RuntimeDirectory = "cdi";
         RemainAfterExit = true;
-        ExecStart = let
-          script = (pkgs.writeScriptBin "nvidia-cdi-generator"
-            (import ./cdi-generate.nix { inherit config lib pkgs; })); in (lib.getExe script);
+        ExecStart =
+          let
+            script = pkgs.callPackage ./cdi-generate.nix { nvidia-driver = config.hardware.nvidia.package; };
+          in
+          lib.getExe script;
         Type = "oneshot";
       };
     };
diff --git a/nixpkgs/nixos/modules/services/home-automation/ebusd.nix b/nixpkgs/nixos/modules/services/home-automation/ebusd.nix
index 519d116e0e55..f68a8bdb6bfa 100644
--- a/nixpkgs/nixos/modules/services/home-automation/ebusd.nix
+++ b/nixpkgs/nixos/modules/services/home-automation/ebusd.nix
@@ -15,12 +15,12 @@ let
     "--port=${toString cfg.port}"
     "--configpath=${cfg.configpath}"
     "--scanconfig=${cfg.scanconfig}"
+    "--log=all:${cfg.logs.all}"
     "--log=main:${cfg.logs.main}"
     "--log=network:${cfg.logs.network}"
     "--log=bus:${cfg.logs.bus}"
     "--log=update:${cfg.logs.update}"
     "--log=other:${cfg.logs.other}"
-    "--log=all:${cfg.logs.all}"
   ] ++ lib.optionals cfg.readonly [
     "--readonly"
   ] ++ lib.optionals cfg.mqtt.enable [
diff --git a/nixpkgs/nixos/modules/services/home-automation/matter-server.nix b/nixpkgs/nixos/modules/services/home-automation/matter-server.nix
new file mode 100644
index 000000000000..864ef9e20083
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/home-automation/matter-server.nix
@@ -0,0 +1,125 @@
+{ lib
+, pkgs
+, config
+, ...
+}:
+
+with lib;
+
+let
+  cfg = config.services.matter-server;
+  storageDir = "matter-server";
+  storagePath = "/var/lib/${storageDir}";
+  vendorId = "4939"; # home-assistant vendor ID
+in
+
+{
+  meta.maintainers = with lib.maintainers; [ leonm1 ];
+
+  options.services.matter-server = with types; {
+    enable = mkEnableOption (lib.mdDoc "Matter-server");
+
+    package = mkPackageOptionMD pkgs "python-matter-server" { };
+
+    port = mkOption {
+      type = types.port;
+      default = 5580;
+      description = "Port to expose the matter-server service on.";
+    };
+
+    logLevel = mkOption {
+      type = types.enum [ "critical" "error" "warning" "info" "debug" ];
+      default = "info";
+      description = "Verbosity of logs from the matter-server";
+    };
+
+    extraArgs = mkOption {
+      type = listOf str;
+      default = [];
+      description = ''
+        Extra arguments to pass to the matter-server executable.
+        See https://github.com/home-assistant-libs/python-matter-server?tab=readme-ov-file#running-the-development-server for options.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.matter-server = {
+      after = [ "network-online.target" ];
+      before = [ "home-assistant.service" ];
+      wants = [ "network-online.target" ];
+      wantedBy = [ "multi-user.target" ];
+      description = "Matter Server";
+      environment.HOME = storagePath;
+      serviceConfig = {
+        ExecStart = (concatStringsSep " " [
+          "${cfg.package}/bin/matter-server"
+          "--port" (toString cfg.port)
+          "--vendorid" vendorId
+          "--storage-path" storagePath
+          "--log-level" "${cfg.logLevel}"
+          "${escapeShellArgs cfg.extraArgs}"
+        ]);
+        # Start with a clean root filesystem, and allowlist what the container
+        # is permitted to access.
+        TemporaryFileSystem = "/";
+        # Allowlist /nix/store (to allow the binary to find its dependencies)
+        # and dbus.
+        ReadOnlyPaths = "/nix/store /run/dbus";
+        # Let systemd manage `/var/lib/matter-server` for us inside the
+        # ephemeral TemporaryFileSystem.
+        StateDirectory = storageDir;
+        # `python-matter-server` writes to /data even when a storage-path is
+        # specified. This bind-mount points /data at the systemd-managed
+        # /var/lib/matter-server, so all files get dropped into the state
+        # directory.
+        BindPaths = "${storagePath}:/data";
+
+        # Hardening bits
+        AmbientCapabilities = "";
+        CapabilityBoundingSet = "";
+        DevicePolicy = "closed";
+        DynamicUser = true;
+        LockPersonality = true;
+        MemoryDenyWriteExecute = true;
+        NoNewPrivileges = true;
+        PrivateDevices = true;
+        PrivateTmp = true;
+        PrivateUsers = true;
+        ProcSubset = "pid";
+        ProtectClock = true;
+        ProtectControlGroups = true;
+        ProtectHome = true;
+        ProtectHostname = true;
+        ProtectKernelLogs = true;
+        ProtectKernelModules = true;
+        ProtectKernelTunables = true;
+        ProtectProc = "invisible";
+        RestrictAddressFamilies = [
+          "AF_INET"
+          "AF_INET6"
+          "AF_NETLINK"
+        ];
+        RestrictNamespaces = true;
+        RestrictRealtime = true;
+        RestrictSUIDSGID = true;
+        SystemCallFilter = concatStringsSep " " [
+          "~" # Blocklist
+          "@clock"
+          "@cpu-emulation"
+          "@debug"
+          "@module"
+          "@mount"
+          "@obsolete"
+          "@privileged"
+          "@raw-io"
+          "@reboot"
+          "@resources"
+          "@swap"
+        ];
+        UMask = "0077";
+      };
+    };
+  };
+}
+
diff --git a/nixpkgs/nixos/modules/services/mail/listmonk.nix b/nixpkgs/nixos/modules/services/mail/listmonk.nix
index 945eb436c1f2..d6399304cc10 100644
--- a/nixpkgs/nixos/modules/services/mail/listmonk.nix
+++ b/nixpkgs/nixos/modules/services/mail/listmonk.nix
@@ -187,7 +187,11 @@ in {
           # Indeed, it will try to create all the folders and realize one of them already exist.
           # Therefore, we have to create it ourselves.
           ''${pkgs.coreutils}/bin/mkdir -p "''${STATE_DIRECTORY}/listmonk/uploads"''
-          "${cfg.package}/bin/listmonk --config ${cfgFile} --idempotent --install --upgrade --yes"
+          # setup database if not already done
+          "${cfg.package}/bin/listmonk --config ${cfgFile} --idempotent --install --yes"
+          # apply db migrations (setup and migrations can not be done in one step
+          # with "--install --upgrade" listmonk ignores the upgrade)
+          "${cfg.package}/bin/listmonk --config ${cfgFile} --upgrade --yes"
           "${updateDatabaseConfigScript}/bin/update-database-config.sh"
         ];
         ExecStart = "${cfg.package}/bin/listmonk --config ${cfgFile}";
diff --git a/nixpkgs/nixos/modules/services/misc/docker-registry.nix b/nixpkgs/nixos/modules/services/misc/docker-registry.nix
index e8fbc05423d3..78d1d6339ed6 100644
--- a/nixpkgs/nixos/modules/services/misc/docker-registry.nix
+++ b/nixpkgs/nixos/modules/services/misc/docker-registry.nix
@@ -63,6 +63,12 @@ in {
       type = types.port;
     };
 
+    openFirewall = mkOption {
+      type = types.bool;
+      default = false;
+      description = lib.mdDoc "Opens the port used by the firewall.";
+    };
+
     storagePath = mkOption {
       type = types.nullOr types.path;
       default = "/var/lib/docker-registry";
@@ -154,5 +160,9 @@ in {
         isSystemUser = true;
       };
     users.groups.docker-registry = {};
+
+    networking.firewall = mkIf cfg.openFirewall {
+      allowedTCPPorts = [ cfg.port ];
+    };
   };
 }
diff --git a/nixpkgs/nixos/modules/services/misc/etebase-server.nix b/nixpkgs/nixos/modules/services/misc/etebase-server.nix
index 045048a1a2e3..f5a5e8a780d4 100644
--- a/nixpkgs/nixos/modules/services/misc/etebase-server.nix
+++ b/nixpkgs/nixos/modules/services/misc/etebase-server.nix
@@ -5,9 +5,6 @@ with lib;
 let
   cfg = config.services.etebase-server;
 
-  pythonEnv = pkgs.python3.withPackages (ps: with ps;
-    [ etebase-server daphne ]);
-
   iniFmt = pkgs.formats.ini {};
 
   configIni = iniFmt.generate "etebase-server.ini" cfg.settings;
@@ -46,6 +43,13 @@ in
         '';
       };
 
+      package = mkOption {
+        type = types.package;
+        default = pkgs.python3.pkgs.etebase-server;
+        defaultText = literalExpression "pkgs.python3.pkgs.etebase-server";
+        description = lib.mdDoc "etebase-server package to use.";
+      };
+
       dataDir = mkOption {
         type = types.str;
         default = "/var/lib/etebase-server";
@@ -164,7 +168,7 @@ in
       (runCommand "etebase-server" {
         nativeBuildInputs = [ makeWrapper ];
       } ''
-        makeWrapper ${pythonEnv}/bin/etebase-server \
+        makeWrapper ${cfg.package}/bin/etebase-server \
           $out/bin/etebase-server \
           --chdir ${escapeShellArg cfg.dataDir} \
           --prefix ETEBASE_EASY_CONFIG_PATH : "${configIni}"
@@ -178,8 +182,8 @@ in
     systemd.services.etebase-server = {
       description = "An Etebase (EteSync 2.0) server";
       after = [ "network.target" "systemd-tmpfiles-setup.service" ];
+      path = [ cfg.package ];
       wantedBy = [ "multi-user.target" ];
-      path = [ pythonEnv ];
       serviceConfig = {
         User = cfg.user;
         Restart = "always";
@@ -187,24 +191,26 @@ in
       };
       environment = {
         ETEBASE_EASY_CONFIG_PATH = configIni;
+        PYTHONPATH = cfg.package.pythonPath;
       };
       preStart = ''
         # Auto-migrate on first run or if the package has changed
         versionFile="${cfg.dataDir}/src-version"
-        if [[ $(cat "$versionFile" 2>/dev/null) != ${pkgs.etebase-server} ]]; then
+        if [[ $(cat "$versionFile" 2>/dev/null) != ${cfg.package} ]]; then
           etebase-server migrate --no-input
           etebase-server collectstatic --no-input --clear
-          echo ${pkgs.etebase-server} > "$versionFile"
+          echo ${cfg.package} > "$versionFile"
         fi
       '';
       script =
         let
+          python = cfg.package.python;
           networking = if cfg.unixSocket != null
-          then "-u ${cfg.unixSocket}"
-          else "-b 0.0.0.0 -p ${toString cfg.port}";
+          then "--uds ${cfg.unixSocket}"
+          else "--host 0.0.0.0 --port ${toString cfg.port}";
         in ''
-          cd "${pythonEnv}/lib/etebase-server";
-          daphne ${networking} \
+          ${python.pkgs.uvicorn}/bin/uvicorn ${networking} \
+            --app-dir ${cfg.package}/${cfg.package.python.sitePackages} \
             etebase_server.asgi:application
         '';
     };
diff --git a/nixpkgs/nixos/modules/services/misc/homepage-dashboard.nix b/nixpkgs/nixos/modules/services/misc/homepage-dashboard.nix
index 07a09e2b6bbf..02f1378cb0d5 100644
--- a/nixpkgs/nixos/modules/services/misc/homepage-dashboard.nix
+++ b/nixpkgs/nixos/modules/services/misc/homepage-dashboard.nix
@@ -6,6 +6,8 @@
 
 let
   cfg = config.services.homepage-dashboard;
+  # Define the settings format used for this program
+  settingsFormat = pkgs.formats.yaml { };
 in
 {
   options = {
@@ -25,31 +27,217 @@ in
         default = 8082;
         description = lib.mdDoc "Port for Homepage to bind to.";
       };
+
+      environmentFile = lib.mkOption {
+        type = lib.types.str;
+        description = ''
+          The path to an environment file that contains environment variables to pass
+          to the homepage-dashboard service, for the purpose of passing secrets to
+          the service.
+
+          See the upstream documentation:
+
+          https://gethomepage.dev/latest/installation/docker/#using-environment-secrets
+        '';
+        default = "";
+      };
+
+      customCSS = lib.mkOption {
+        type = lib.types.lines;
+        description = lib.mdDoc ''
+          Custom CSS for styling Homepage.
+
+          See https://gethomepage.dev/latest/configs/custom-css-js/.
+        '';
+        default = "";
+      };
+
+      customJS = lib.mkOption {
+        type = lib.types.lines;
+        description = lib.mdDoc ''
+          Custom Javascript for Homepage.
+
+          See https://gethomepage.dev/latest/configs/custom-css-js/.
+        '';
+        default = "";
+      };
+
+      bookmarks = lib.mkOption {
+        inherit (settingsFormat) type;
+        description = lib.mdDoc ''
+          Homepage bookmarks configuration.
+
+          See https://gethomepage.dev/latest/configs/bookmarks/.
+        '';
+        # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/bookmarks.yaml
+        example = [
+          {
+            Developer = [
+              { Github = [{ abbr = "GH"; href = "https://github.com/"; }]; }
+            ];
+          }
+          {
+            Entertainment = [
+              { YouTube = [{ abbr = "YT"; href = "https://youtube.com/"; }]; }
+            ];
+          }
+        ];
+        default = [ ];
+      };
+
+      services = lib.mkOption {
+        inherit (settingsFormat) type;
+        description = lib.mdDoc ''
+          Homepage services configuration.
+
+          See https://gethomepage.dev/latest/configs/services/.
+        '';
+        # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/services.yaml
+        example = [
+          {
+            "My First Group" = [
+              {
+                "My First Service" = {
+                  href = "http://localhost/";
+                  description = "Homepage is awesome";
+                };
+              }
+            ];
+          }
+          {
+            "My Second Group" = [
+              {
+                "My Second Service" = {
+                  href = "http://localhost/";
+                  description = "Homepage is the best";
+                };
+              }
+            ];
+          }
+        ];
+        default = [ ];
+      };
+
+      widgets = lib.mkOption {
+        inherit (settingsFormat) type;
+        description = lib.mdDoc ''
+          Homepage widgets configuration.
+
+          See https://gethomepage.dev/latest/configs/service-widgets/.
+        '';
+        # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/widgets.yaml
+        example = [
+          {
+            resources = {
+              cpu = true;
+              memory = true;
+              disk = "/";
+            };
+          }
+          {
+            search = {
+              provider = "duckduckgo";
+              target = "_blank";
+            };
+          }
+        ];
+        default = [ ];
+      };
+
+      kubernetes = lib.mkOption {
+        inherit (settingsFormat) type;
+        description = lib.mdDoc ''
+          Homepage kubernetes configuration.
+
+          See https://gethomepage.dev/latest/configs/kubernetes/.
+        '';
+        default = { };
+      };
+
+      docker = lib.mkOption {
+        inherit (settingsFormat) type;
+        description = lib.mdDoc ''
+          Homepage docker configuration.
+
+          See https://gethomepage.dev/latest/configs/docker/.
+        '';
+        default = { };
+      };
+
+      settings = lib.mkOption {
+        inherit (settingsFormat) type;
+        description = lib.mdDoc ''
+          Homepage settings.
+
+          See https://gethomepage.dev/latest/configs/settings/.
+        '';
+        # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/settings.yaml
+        default = { };
+      };
     };
   };
 
-  config = lib.mkIf cfg.enable {
-    systemd.services.homepage-dashboard = {
-      description = "Homepage Dashboard";
-      after = [ "network.target" ];
-      wantedBy = [ "multi-user.target" ];
+  config =
+    let
+      # If homepage-dashboard is enabled, but none of the configuration values have been updated,
+      # then default to "unmanaged" configuration which is manually updated in
+      # var/lib/homepage-dashboard. This is to maintain backwards compatibility, and should be
+      # deprecated in a future release.
+      managedConfig = !(
+        cfg.bookmarks == [ ] &&
+        cfg.customCSS == "" &&
+        cfg.customJS == "" &&
+        cfg.docker == { } &&
+        cfg.kubernetes == { } &&
+        cfg.services == [ ] &&
+        cfg.settings == { } &&
+        cfg.widgets == [ ]
+      );
+
+      configDir = if managedConfig then "/etc/homepage-dashboard" else "/var/lib/homepage-dashboard";
+
+      msg = "using unmanaged configuration for homepage-dashboard is deprecated and will be removed"
+        + " in 24.05. please see the NixOS documentation for `services.homepage-dashboard' and add"
+        + " your bookmarks, services, widgets, and other configuration using the options provided.";
+    in
+    lib.mkIf cfg.enable {
+      warnings = lib.optional (!managedConfig) msg;
 
-      environment = {
-        HOMEPAGE_CONFIG_DIR = "/var/lib/homepage-dashboard";
-        PORT = "${toString cfg.listenPort}";
+      environment.etc = lib.mkIf managedConfig {
+        "homepage-dashboard/custom.css".text = cfg.customCSS;
+        "homepage-dashboard/custom.js".text = cfg.customJS;
+
+        "homepage-dashboard/bookmarks.yaml".source = settingsFormat.generate "bookmarks.yaml" cfg.bookmarks;
+        "homepage-dashboard/docker.yaml".source = settingsFormat.generate "docker.yaml" cfg.docker;
+        "homepage-dashboard/kubernetes.yaml".source = settingsFormat.generate "kubernetes.yaml" cfg.kubernetes;
+        "homepage-dashboard/services.yaml".source = settingsFormat.generate "services.yaml" cfg.services;
+        "homepage-dashboard/settings.yaml".source = settingsFormat.generate "settings.yaml" cfg.settings;
+        "homepage-dashboard/widgets.yaml".source = settingsFormat.generate "widgets.yaml" cfg.widgets;
       };
 
-      serviceConfig = {
-        Type = "simple";
-        DynamicUser = true;
-        StateDirectory = "homepage-dashboard";
-        ExecStart = "${lib.getExe cfg.package}";
-        Restart = "on-failure";
+      systemd.services.homepage-dashboard = {
+        description = "Homepage Dashboard";
+        after = [ "network.target" ];
+        wantedBy = [ "multi-user.target" ];
+
+        environment = {
+          HOMEPAGE_CONFIG_DIR = configDir;
+          PORT = toString cfg.listenPort;
+          LOG_TARGETS = lib.mkIf managedConfig "stdout";
+        };
+
+        serviceConfig = {
+          Type = "simple";
+          DynamicUser = true;
+          EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
+          StateDirectory = lib.mkIf (!managedConfig) "homepage-dashboard";
+          ExecStart = lib.getExe cfg.package;
+          Restart = "on-failure";
+        };
       };
-    };
 
-    networking.firewall = lib.mkIf cfg.openFirewall {
-      allowedTCPPorts = [ cfg.listenPort ];
+      networking.firewall = lib.mkIf cfg.openFirewall {
+        allowedTCPPorts = [ cfg.listenPort ];
+      };
     };
-  };
 }
diff --git a/nixpkgs/nixos/modules/services/misc/paperless.nix b/nixpkgs/nixos/modules/services/misc/paperless.nix
index ab042e4b6ee2..9314c4f3848d 100644
--- a/nixpkgs/nixos/modules/services/misc/paperless.nix
+++ b/nixpkgs/nixos/modules/services/misc/paperless.nix
@@ -342,6 +342,7 @@ in
         User = cfg.user;
         Restart = "on-failure";
 
+        LimitNOFILE = 65536;
         # gunicorn needs setuid, liblapack needs mbind
         SystemCallFilter = defaultServiceConfig.SystemCallFilter ++ [ "@setuid mbind" ];
         # Needs to serve web page
diff --git a/nixpkgs/nixos/modules/services/misc/tabby.nix b/nixpkgs/nixos/modules/services/misc/tabby.nix
new file mode 100644
index 000000000000..a3072e5df75e
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/misc/tabby.nix
@@ -0,0 +1,203 @@
+{ config, lib, pkgs, ... }:
+let
+  inherit (lib) types;
+
+  cfg = config.services.tabby;
+  format = pkgs.formats.toml { };
+  tabbyPackage = cfg.package.override {
+    inherit (cfg) acceleration;
+  };
+in
+{
+  options = {
+    services.tabby = {
+      enable = lib.mkEnableOption (
+        lib.mdDoc "Self-hosted AI coding assistant using large language models"
+      );
+
+      package = lib.mkPackageOption pkgs "tabby" { };
+
+      port = lib.mkOption {
+        type = types.port;
+        default = 11029;
+        description = lib.mdDoc ''
+          Specifies the bind port on which the tabby server HTTP interface listens.
+        '';
+      };
+
+      model = lib.mkOption {
+        type = types.str;
+        default = "TabbyML/StarCoder-1B";
+        description = lib.mdDoc ''
+          Specify the model that tabby will use to generate completions.
+
+          This model will be downloaded automatically if it is not already present.
+
+          If you want to utilize an existing model that you've already
+          downloaded you'll need to move it into tabby's state directory which
+          lives in `/var/lib/tabby`. Because the tabby.service is configured to
+          use a DyanmicUser the service will need to have been started at least
+          once before you can move the locally existing model into
+          `/var/lib/tabby`. You can set the model to 'none' and tabby will
+          startup and fail to download a model, but will have created the
+          `/var/lib/tabby` directory. You can then copy over the model manually
+          into `/var/lib/tabby`, update the model option to the name you just
+          downloaded and copied over then `nixos-rebuild switch` to start using
+          it.
+
+          $ tabby download --model TabbyML/DeepseekCoder-6.7B
+          $ find ~/.tabby/ | tail -n1
+          /home/ghthor/.tabby/models/TabbyML/DeepseekCoder-6.7B/ggml/q8_0.v2.gguf
+          $ sudo rsync -r ~/.tabby/models/ /var/lib/tabby/models/
+          $ sudo chown -R tabby:tabby /var/lib/tabby/models/
+
+          See for Model Options:
+          > https://github.com/TabbyML/registry-tabby
+        '';
+      };
+
+      acceleration = lib.mkOption {
+        type = types.nullOr (types.enum [ "cpu" "rocm" "cuda" "metal" ]);
+        default = null;
+        example = "rocm";
+        description = lib.mdDoc ''
+          Specifies the device to use for hardware acceleration.
+
+          -   `cpu`: no acceleration just use the CPU
+          -  `rocm`: supported by modern AMD GPUs
+          -  `cuda`: supported by modern NVIDIA GPUs
+          - `metal`: supported on darwin aarch64 machines
+
+          Tabby will try and determine what type of acceleration that is
+          already enabled in your configuration when `acceleration = null`.
+
+          - nixpkgs.config.cudaSupport
+          - nixpkgs.config.rocmSupport
+          - if stdenv.isDarwin && stdenv.isAarch64
+
+          IFF multiple acceleration methods are found to be enabled or if you
+          haven't set either `cudaSupport or rocmSupport` you will have to
+          specify the device type manually here otherwise it will default to
+          the first from the list above or to cpu.
+        '';
+      };
+
+      settings = lib.mkOption {
+        inherit (format) type;
+        default = { };
+        description = lib.mdDoc ''
+          Tabby scheduler configuration
+
+          See for more details:
+          > https://tabby.tabbyml.com/docs/configuration/#repository-context-for-code-completion
+        '';
+        example = lib.literalExpression ''
+          settings = {
+            repositories = [
+              { name = "tabby"; git_url = "https://github.com/TabbyML/tabby.git"; }
+              { name = "CTranslate2"; git_url = "git@github.com:OpenNMT/CTranslate2.git"; }
+
+              # local directory is also supported, but limited by systemd DynamicUser=1
+              # adding local repositories will need to be done manually
+              { name = "repository_a"; git_url = "file:///var/lib/tabby/repository_a"; }
+            ];
+          };
+        '';
+      };
+
+      usageCollection = lib.mkOption {
+        type = types.bool;
+        default = false;
+        description = lib.mdDoc ''
+          Enable sending anonymous usage data.
+
+          See for more details:
+          > https://tabby.tabbyml.com/docs/configuration#usage-collection
+        '';
+      };
+
+      indexInterval = lib.mkOption {
+        type = types.str;
+        default = "5hours";
+        example = "5hours";
+        description = lib.mdDoc ''
+          Run tabby scheduler to generate the index database at this interval.
+          Updates by default every 5 hours. This value applies to
+          `OnUnitInactiveSec`
+
+          The format is described in
+          {manpage}`systemd.time(7)`.
+
+          To disable running `tabby scheduler --now` updates, set to `"never"`
+        '';
+      };
+    };
+  };
+
+  # TODO(ghthor): firewall config
+
+  config = lib.mkIf cfg.enable {
+    environment = {
+      etc."tabby/config.toml".source = format.generate "config.toml" cfg.settings;
+      systemPackages = [ tabbyPackage ];
+    };
+
+
+    systemd = let
+      serviceUser = {
+        WorkingDirectory = "/var/lib/tabby";
+        StateDirectory = [ "tabby" ];
+        ConfigurationDirectory = [ "tabby" ];
+        DynamicUser = true;
+        User = "tabby";
+        Group = "tabby";
+      };
+
+      serviceEnv = lib.mkMerge [
+        {
+          TABBY_ROOT = "%S/tabby";
+        }
+        (lib.mkIf (!cfg.usageCollection) {
+          TABBY_DISABLE_USAGE_COLLECTION = "1";
+        })
+      ];
+    in {
+      services.tabby = {
+        wantedBy = [ "multi-user.target" ];
+        description = "Self-hosted AI coding assistant using large language models";
+        after = [ "network.target" ];
+        environment = serviceEnv;
+        serviceConfig = lib.mkMerge [
+          serviceUser
+          {
+            ExecStart =
+              "${lib.getExe tabbyPackage} serve --model ${cfg.model} --port ${toString cfg.port} --device ${tabbyPackage.featureDevice}";
+          }
+        ];
+      };
+
+      services.tabby-scheduler = lib.mkIf (cfg.indexInterval != "never") {
+        wantedBy = [ "multi-user.target" ];
+        description = "Tabby repository indexing service";
+        after = [ "network.target" ];
+        environment = serviceEnv;
+        preStart = "cp -f /etc/tabby/config.toml \${TABBY_ROOT}/config.toml";
+        serviceConfig = lib.mkMerge [
+          serviceUser
+          {
+            # Type = "oneshot";
+            ExecStart = "${lib.getExe tabbyPackage} scheduler --now";
+          }
+        ];
+      };
+      timers.tabby-scheduler = lib.mkIf (cfg.indexInterval != "never") {
+        description = "Update timer for tabby-scheduler";
+        partOf = [ "tabby-scheduler.service" ];
+        wantedBy = [ "timers.target" ];
+        timerConfig.OnUnitInactiveSec = cfg.indexInterval;
+      };
+    };
+  };
+
+  meta.maintainers = with lib.maintainers; [ ghthor ];
+}
diff --git a/nixpkgs/nixos/modules/services/misc/transfer-sh.nix b/nixpkgs/nixos/modules/services/misc/transfer-sh.nix
new file mode 100644
index 000000000000..899d9dfc3c10
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/misc/transfer-sh.nix
@@ -0,0 +1,102 @@
+{ config, lib, pkgs, ... }:
+
+let
+  cfg = config.services.transfer-sh;
+  inherit (lib)
+    mkDefault mkEnableOption mkPackageOption mkIf mkOption
+    types mapAttrs isBool getExe boolToString mdDoc optionalAttrs;
+in
+{
+  options.services.transfer-sh = {
+    enable = mkEnableOption (mdDoc "Easy and fast file sharing from the command-line");
+
+    package = mkPackageOption pkgs "transfer-sh" { };
+
+    settings = mkOption {
+      type = types.submodule { freeformType = with types; attrsOf (oneOf [ bool int str ]); };
+      default = { };
+      example = {
+        LISTENER = ":8080";
+        BASEDIR = "/var/lib/transfer.sh";
+        TLS_LISTENER_ONLY = false;
+      };
+      description = mdDoc ''
+        Additional configuration for transfer-sh, see
+        <https://github.com/dutchcoders/transfer.sh#usage-1>
+        for supported values.
+
+        For secrets use secretFile option instead.
+      '';
+    };
+
+    provider = mkOption {
+      type = types.enum [ "local" "s3" "storj" "gdrive" ];
+      default = "local";
+      description = mdDoc "Storage providers to use";
+    };
+
+    secretFile = mkOption {
+      type = types.nullOr types.path;
+      default = null;
+      example = "/run/secrets/transfer-sh.env";
+      description = mdDoc ''
+        Path to file containing environment variables.
+        Useful for passing down secrets.
+        Some variables that can be considered secrets are:
+         - AWS_ACCESS_KEY
+         - AWS_ACCESS_KEY
+         - TLS_PRIVATE_KEY
+         - HTTP_AUTH_HTPASSWD
+      '';
+    };
+  };
+
+  config =
+    let
+      localProvider = (cfg.provider == "local");
+      stateDirectory = "/var/lib/transfer.sh";
+    in
+    mkIf cfg.enable
+      {
+        services.transfer-sh.settings = {
+          LISTENER = mkDefault ":8080";
+        } // optionalAttrs localProvider {
+          BASEDIR = mkDefault stateDirectory;
+        };
+
+        systemd.services.transfer-sh = {
+          after = [ "network.target" ];
+          wantedBy = [ "multi-user.target" ];
+          environment = mapAttrs (_: v: if isBool v then boolToString v else toString v) cfg.settings;
+          serviceConfig = {
+            CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
+            DevicePolicy = "closed";
+            DynamicUser = true;
+            ExecStart = "${getExe cfg.package} --provider ${cfg.provider}";
+            LockPersonality = true;
+            MemoryDenyWriteExecute = true;
+            PrivateDevices = true;
+            PrivateUsers = true;
+            ProtectClock = true;
+            ProtectControlGroups = true;
+            ProtectHostname = true;
+            ProtectKernelLogs = true;
+            ProtectKernelModules = true;
+            ProtectKernelTunables = true;
+            ProtectProc = "invisible";
+            RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
+            RestrictNamespaces = true;
+            RestrictRealtime = true;
+            SystemCallArchitectures = [ "native" ];
+            SystemCallFilter = [ "@system-service" ];
+            StateDirectory = baseNameOf stateDirectory;
+          } // optionalAttrs (cfg.secretFile != null) {
+            EnvironmentFile = cfg.secretFile;
+          } // optionalAttrs localProvider {
+            ReadWritePaths = cfg.settings.BASEDIR;
+          };
+        };
+      };
+
+  meta.maintainers = with lib.maintainers; [ ocfox ];
+}
diff --git a/nixpkgs/nixos/modules/services/monitoring/mackerel-agent.nix b/nixpkgs/nixos/modules/services/monitoring/mackerel-agent.nix
index 5915634ed26f..d1e84c0359dc 100644
--- a/nixpkgs/nixos/modules/services/monitoring/mackerel-agent.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/mackerel-agent.nix
@@ -81,7 +81,7 @@ in {
       include = mkDefault "/etc/mackerel-agent/conf.d/*.conf";
     };
 
-    # upstream service file in https://git.io/JUt4Q
+    # upstream service file in https://github.com/mackerelio/mackerel-agent/blob/master/packaging/rpm/src/mackerel-agent.service
     systemd.services.mackerel-agent = {
       description = "mackerel.io agent";
       wants = [ "network-online.target" ];
diff --git a/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/restic.nix b/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/restic.nix
index 5b32c93a666d..977bd42e9812 100644
--- a/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/restic.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/restic.nix
@@ -93,12 +93,14 @@ in
   };
 
   serviceOpts = {
+    script = ''
+      export RESTIC_PASSWORD_FILE=$CREDENTIALS_DIRECTORY/RESTIC_PASSWORD_FILE
+      ${pkgs.prometheus-restic-exporter}/bin/restic-exporter.py \
+        ${concatStringsSep " \\\n  " cfg.extraFlags}
+    '';
     serviceConfig = {
-      ExecStart = ''
-        ${pkgs.prometheus-restic-exporter}/bin/restic-exporter.py \
-          ${concatStringsSep " \\\n  " cfg.extraFlags}
-      '';
       EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
+      LoadCredential = [ "RESTIC_PASSWORD_FILE:${cfg.passwordFile}" ];
     };
     environment =
       let
@@ -108,8 +110,7 @@ in
         toRcloneVal = v: if lib.isBool v then lib.boolToString v else v;
       in
       {
-        RESTIC_REPO_URL = cfg.repository;
-        RESTIC_REPO_PASSWORD_FILE = cfg.passwordFile;
+        RESTIC_REPOSITORY = cfg.repository;
         LISTEN_ADDRESS = cfg.listenAddress;
         LISTEN_PORT = toString cfg.port;
         REFRESH_INTERVAL = toString cfg.refreshInterval;
diff --git a/nixpkgs/nixos/modules/services/monitoring/scrutiny.nix b/nixpkgs/nixos/modules/services/monitoring/scrutiny.nix
index 454668a9a128..aef924ef840c 100644
--- a/nixpkgs/nixos/modules/services/monitoring/scrutiny.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/scrutiny.nix
@@ -1,5 +1,11 @@
 { config, lib, pkgs, ... }:
 let
+  inherit (lib) maintainers;
+  inherit (lib.meta) getExe;
+  inherit (lib.modules) mkIf;
+  inherit (lib.options) literalExpression mkEnableOption mkOption mkPackageOption;
+  inherit (lib.types) bool enum nullOr port str submodule;
+
   cfg = config.services.scrutiny;
   # Define the settings format used for this program
   settingsFormat = pkgs.formats.yaml { };
@@ -7,20 +13,16 @@ in
 {
   options = {
     services.scrutiny = {
-      enable = lib.mkEnableOption "Enables the scrutiny web application.";
+      enable = mkEnableOption "Scrutiny, a web application for drive monitoring";
 
-      package = lib.mkPackageOptionMD pkgs "scrutiny" { };
+      package = mkPackageOption pkgs "scrutiny" { };
 
-      openFirewall = lib.mkOption {
-        type = lib.types.bool;
-        default = false;
-        description = "Open the default ports in the firewall for Scrutiny.";
-      };
+      openFirewall = mkEnableOption "opening the default ports in the firewall for Scrutiny";
 
-      influxdb.enable = lib.mkOption {
-        type = lib.types.bool;
+      influxdb.enable = mkOption {
+        type = bool;
         default = true;
-        description = lib.mdDoc ''
+        description = ''
           Enables InfluxDB on the host system using the `services.influxdb2` NixOS module
           with default options.
 
@@ -29,127 +31,124 @@ in
         '';
       };
 
-      settings = lib.mkOption {
-        description = lib.mdDoc ''
+      settings = mkOption {
+        description = ''
           Scrutiny settings to be rendered into the configuration file.
 
           See https://github.com/AnalogJ/scrutiny/blob/master/example.scrutiny.yaml.
         '';
         default = { };
-        type = lib.types.submodule {
+        type = submodule {
           freeformType = settingsFormat.type;
 
-          options.web.listen.port = lib.mkOption {
-            type = lib.types.port;
+          options.web.listen.port = mkOption {
+            type = port;
             default = 8080;
-            description = lib.mdDoc "Port for web application to listen on.";
+            description = "Port for web application to listen on.";
           };
 
-          options.web.listen.host = lib.mkOption {
-            type = lib.types.str;
+          options.web.listen.host = mkOption {
+            type = str;
             default = "0.0.0.0";
-            description = lib.mdDoc "Interface address for web application to bind to.";
+            description = "Interface address for web application to bind to.";
           };
 
-          options.web.listen.basepath = lib.mkOption {
-            type = lib.types.str;
+          options.web.listen.basepath = mkOption {
+            type = str;
             default = "";
             example = "/scrutiny";
-            description = lib.mdDoc ''
+            description = ''
               If Scrutiny will be behind a path prefixed reverse proxy, you can override this
               value to serve Scrutiny on a subpath.
             '';
           };
 
-          options.log.level = lib.mkOption {
-            type = lib.types.enum [ "INFO" "DEBUG" ];
+          options.log.level = mkOption {
+            type = enum [ "INFO" "DEBUG" ];
             default = "INFO";
-            description = lib.mdDoc "Log level for Scrutiny.";
+            description = "Log level for Scrutiny.";
           };
 
-          options.web.influxdb.scheme = lib.mkOption {
-            type = lib.types.str;
+          options.web.influxdb.scheme = mkOption {
+            type = str;
             default = "http";
-            description = lib.mdDoc "URL scheme to use when connecting to InfluxDB.";
+            description = "URL scheme to use when connecting to InfluxDB.";
           };
 
-          options.web.influxdb.host = lib.mkOption {
-            type = lib.types.str;
+          options.web.influxdb.host = mkOption {
+            type = str;
             default = "0.0.0.0";
-            description = lib.mdDoc "IP or hostname of the InfluxDB instance.";
+            description = "IP or hostname of the InfluxDB instance.";
           };
 
-          options.web.influxdb.port = lib.mkOption {
-            type = lib.types.port;
+          options.web.influxdb.port = mkOption {
+            type = port;
             default = 8086;
-            description = lib.mdDoc "The port of the InfluxDB instance.";
+            description = "The port of the InfluxDB instance.";
           };
 
-          options.web.influxdb.tls.insecure_skip_verify = lib.mkOption {
-            type = lib.types.bool;
-            default = false;
-            description = lib.mdDoc "Skip TLS verification when connecting to InfluxDB.";
-          };
+          options.web.influxdb.tls.insecure_skip_verify = mkEnableOption "skipping TLS verification when connecting to InfluxDB";
 
-          options.web.influxdb.token = lib.mkOption {
-            type = lib.types.nullOr lib.types.str;
+          options.web.influxdb.token = mkOption {
+            type = nullOr str;
             default = null;
-            description = lib.mdDoc "Authentication token for connecting to InfluxDB.";
+            description = "Authentication token for connecting to InfluxDB.";
           };
 
-          options.web.influxdb.org = lib.mkOption {
-            type = lib.types.nullOr lib.types.str;
+          options.web.influxdb.org = mkOption {
+            type = nullOr str;
             default = null;
-            description = lib.mdDoc "InfluxDB organisation under which to store data.";
+            description = "InfluxDB organisation under which to store data.";
           };
 
-          options.web.influxdb.bucket = lib.mkOption {
-            type = lib.types.nullOr lib.types.str;
+          options.web.influxdb.bucket = mkOption {
+            type = nullOr str;
             default = null;
-            description = lib.mdDoc "InfluxDB bucket in which to store data.";
+            description = "InfluxDB bucket in which to store data.";
           };
         };
       };
 
       collector = {
-        enable = lib.mkEnableOption "Enables the scrutiny metrics collector.";
+        enable = mkEnableOption "the Scrutiny metrics collector";
 
-        package = lib.mkPackageOptionMD pkgs "scrutiny-collector" { };
+        package = mkPackageOption pkgs "scrutiny-collector" { };
 
-        schedule = lib.mkOption {
-          type = lib.types.str;
+        schedule = mkOption {
+          type = str;
           default = "*:0/15";
-          description = lib.mdDoc ''
+          description = ''
             How often to run the collector in systemd calendar format.
           '';
         };
 
-        settings = lib.mkOption {
-          description = lib.mdDoc ''
+        settings = mkOption {
+          description = ''
             Collector settings to be rendered into the collector configuration file.
 
             See https://github.com/AnalogJ/scrutiny/blob/master/example.collector.yaml.
           '';
           default = { };
-          type = lib.types.submodule {
+          type = submodule {
             freeformType = settingsFormat.type;
 
-            options.host.id = lib.mkOption {
-              type = lib.types.nullOr lib.types.str;
+            options.host.id = mkOption {
+              type = nullOr str;
               default = null;
-              description = lib.mdDoc "Host ID for identifying/labelling groups of disks";
+              description = "Host ID for identifying/labelling groups of disks";
             };
 
-            options.api.endpoint = lib.mkOption {
-              type = lib.types.str;
-              default = "http://localhost:8080";
-              description = lib.mdDoc "Scrutiny app API endpoint for sending metrics to.";
+            options.api.endpoint = mkOption {
+              type = str;
+              default = "http://localhost:${toString cfg.settings.web.listen.port}";
+              defaultText = literalExpression ''"http://localhost:''${config.services.scrutiny.settings.web.listen.port}"'';
+              description = "Scrutiny app API endpoint for sending metrics to.";
             };
 
-            options.log.level = lib.mkOption {
-              type = lib.types.enum [ "INFO" "DEBUG" ];
+            options.log.level = mkOption {
+              type = enum [ "INFO" "DEBUG" ];
               default = "INFO";
-              description = lib.mdDoc "Log level for Scrutiny collector.";
+              description = "Log level for Scrutiny collector.";
             };
           };
         };
@@ -157,14 +156,14 @@ in
     };
   };
 
-  config = lib.mkIf (cfg.enable || cfg.collector.enable) {
+  config = mkIf (cfg.enable || cfg.collector.enable) {
     services.influxdb2.enable = cfg.influxdb.enable;
 
-    networking.firewall = lib.mkIf cfg.openFirewall {
+    networking.firewall = mkIf cfg.openFirewall {
       allowedTCPPorts = [ cfg.settings.web.listen.port ];
     };
 
-    services.smartd = lib.mkIf cfg.collector.enable {
+    services.smartd = mkIf cfg.collector.enable {
       enable = true;
       extraOptions = [
         "-A /var/log/smartd/"
@@ -174,7 +173,7 @@ in
 
     systemd = {
       services = {
-        scrutiny = lib.mkIf cfg.enable {
+        scrutiny = mkIf cfg.enable {
           description = "Hard Drive S.M.A.R.T Monitoring, Historical Trends & Real World Failure Thresholds";
           wantedBy = [ "multi-user.target" ];
           after = [ "network.target" ];
@@ -185,14 +184,14 @@ in
           };
           serviceConfig = {
             DynamicUser = true;
-            ExecStart = "${lib.getExe cfg.package} start --config ${settingsFormat.generate "scrutiny.yaml" cfg.settings}";
+            ExecStart = "${getExe cfg.package} start --config ${settingsFormat.generate "scrutiny.yaml" cfg.settings}";
             Restart = "always";
             StateDirectory = "scrutiny";
             StateDirectoryMode = "0750";
           };
         };
 
-        scrutiny-collector = lib.mkIf cfg.collector.enable {
+        scrutiny-collector = mkIf cfg.collector.enable {
           description = "Scrutiny Collector Service";
           environment = {
             COLLECTOR_VERSION = "1";
@@ -200,12 +199,12 @@ in
           };
           serviceConfig = {
             Type = "oneshot";
-            ExecStart = "${lib.getExe cfg.collector.package} run --config ${settingsFormat.generate "scrutiny-collector.yaml" cfg.collector.settings}";
+            ExecStart = "${getExe cfg.collector.package} run --config ${settingsFormat.generate "scrutiny-collector.yaml" cfg.collector.settings}";
           };
         };
       };
 
-      timers = lib.mkIf cfg.collector.enable {
+      timers = mkIf cfg.collector.enable {
         scrutiny-collector = {
           timerConfig = {
             OnCalendar = cfg.collector.schedule;
@@ -217,5 +216,5 @@ in
     };
   };
 
-  meta.maintainers = [ lib.maintainers.jnsgruk ];
+  meta.maintainers = [ maintainers.jnsgruk ];
 }
diff --git a/nixpkgs/nixos/modules/services/networking/bird-lg.nix b/nixpkgs/nixos/modules/services/networking/bird-lg.nix
index be9f4101e6ab..1c59f7a6ae7c 100644
--- a/nixpkgs/nixos/modules/services/networking/bird-lg.nix
+++ b/nixpkgs/nixos/modules/services/networking/bird-lg.nix
@@ -194,8 +194,8 @@ in
         allowedIPs = mkOption {
           type = types.listOf types.str;
           default = [ ];
-          example = [ "192.168.25.52" "192.168.25.53" ];
-          description = lib.mdDoc "List of IPs to allow (default all allowed).";
+          example = [ "192.168.25.52" "192.168.25.53" "192.168.0.0/24" ];
+          description = lib.mdDoc "List of IPs or networks to allow (default all allowed).";
         };
 
         birdSocket = mkOption {
diff --git a/nixpkgs/nixos/modules/services/networking/tailscale.nix b/nixpkgs/nixos/modules/services/networking/tailscale.nix
index f11fe57d6ce5..972299a4697a 100644
--- a/nixpkgs/nixos/modules/services/networking/tailscale.nix
+++ b/nixpkgs/nixos/modules/services/networking/tailscale.nix
@@ -66,6 +66,13 @@ in {
       default = [];
       example = ["--ssh"];
     };
+
+    extraDaemonFlags = mkOption {
+      description = lib.mdDoc "Extra flags to pass to {command}`tailscaled`.";
+      type = types.listOf types.str;
+      default = [];
+      example = ["--no-logs-no-support"];
+    };
   };
 
   config = mkIf cfg.enable {
@@ -80,7 +87,7 @@ in {
       ] ++ lib.optional config.networking.resolvconf.enable config.networking.resolvconf.package;
       serviceConfig.Environment = [
         "PORT=${toString cfg.port}"
-        ''"FLAGS=--tun ${lib.escapeShellArg cfg.interfaceName}"''
+        ''"FLAGS=--tun ${lib.escapeShellArg cfg.interfaceName} ${lib.concatStringsSep " " cfg.extraDaemonFlags}"''
       ] ++ (lib.optionals (cfg.permitCertUid != null) [
         "TS_PERMIT_CERT_UID=${cfg.permitCertUid}"
       ]);
diff --git a/nixpkgs/nixos/modules/services/security/vaultwarden/default.nix b/nixpkgs/nixos/modules/services/security/vaultwarden/default.nix
index 470db735bf64..60d8015d0cee 100644
--- a/nixpkgs/nixos/modules/services/security/vaultwarden/default.nix
+++ b/nixpkgs/nixos/modules/services/security/vaultwarden/default.nix
@@ -180,7 +180,6 @@ in {
     users.groups.vaultwarden = { };
 
     systemd.services.vaultwarden = {
-      aliases = [ "bitwarden_rs.service" ];
       after = [ "network.target" ];
       path = with pkgs; [ openssl ];
       serviceConfig = {
@@ -202,7 +201,6 @@ in {
     };
 
     systemd.services.backup-vaultwarden = mkIf (cfg.backupDir != null) {
-      aliases = [ "backup-bitwarden_rs.service" ];
       description = "Backup vaultwarden";
       environment = {
         DATA_FOLDER = "/var/lib/bitwarden_rs";
@@ -222,7 +220,6 @@ in {
     };
 
     systemd.timers.backup-vaultwarden = mkIf (cfg.backupDir != null) {
-      aliases = [ "backup-bitwarden_rs.timer" ];
       description = "Backup vaultwarden on time";
       timerConfig = {
         OnCalendar = mkDefault "23:00";
@@ -240,6 +237,9 @@ in {
     };
   };
 
-  # uses attributes of the linked package
-  meta.buildDocsInSandbox = false;
+  meta = {
+    # uses attributes of the linked package
+    buildDocsInSandbox = false;
+    maintainers = with lib.maintainers; [ dotlambda SuperSandro2000 ];
+  };
 }
diff --git a/nixpkgs/nixos/modules/services/web-apps/miniflux.nix b/nixpkgs/nixos/modules/services/web-apps/miniflux.nix
index 1a5b7d0c24e9..16b6fb0d655d 100644
--- a/nixpkgs/nixos/modules/services/web-apps/miniflux.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/miniflux.nix
@@ -16,10 +16,20 @@ in
 {
   options = {
     services.miniflux = {
-      enable = mkEnableOption (lib.mdDoc "miniflux and creates a local postgres database for it");
+      enable = mkEnableOption (lib.mdDoc "miniflux");
 
       package = mkPackageOption pkgs "miniflux" { };
 
+      createDatabaseLocally = lib.mkOption {
+        type = lib.types.bool;
+        default = true;
+        description = ''
+          Whether a PostgreSQL database should be automatically created and
+          configured on the local host. If set to `false`, you need provision a
+          database yourself and make sure to create the hstore extension in it.
+        '';
+      };
+
       config = mkOption {
         type = with types; attrsOf (oneOf [ str int ]);
         example = literalExpression ''
@@ -38,7 +48,7 @@ in
         '';
       };
 
-      adminCredentialsFile = mkOption  {
+      adminCredentialsFile = mkOption {
         type = types.path;
         description = lib.mdDoc ''
           File containing the ADMIN_USERNAME and
@@ -51,14 +61,14 @@ in
   };
 
   config = mkIf cfg.enable {
-    services.miniflux.config =  {
+    services.miniflux.config = {
       LISTEN_ADDR = mkDefault defaultAddress;
-      DATABASE_URL = "user=miniflux host=/run/postgresql dbname=miniflux";
+      DATABASE_URL = lib.mkIf cfg.createDatabaseLocally "user=miniflux host=/run/postgresql dbname=miniflux";
       RUN_MIGRATIONS = 1;
       CREATE_ADMIN = 1;
     };
 
-    services.postgresql = {
+    services.postgresql = lib.mkIf cfg.createDatabaseLocally {
       enable = true;
       ensureUsers = [ {
         name = "miniflux";
@@ -67,7 +77,7 @@ in
       ensureDatabases = [ "miniflux" ];
     };
 
-    systemd.services.miniflux-dbsetup = {
+    systemd.services.miniflux-dbsetup = lib.mkIf cfg.createDatabaseLocally {
       description = "Miniflux database setup";
       requires = [ "postgresql.service" ];
       after = [ "network.target" "postgresql.service" ];
@@ -81,8 +91,9 @@ in
     systemd.services.miniflux = {
       description = "Miniflux service";
       wantedBy = [ "multi-user.target" ];
-      requires = [ "miniflux-dbsetup.service" ];
-      after = [ "network.target" "postgresql.service" "miniflux-dbsetup.service" ];
+      requires = lib.optional cfg.createDatabaseLocally "miniflux-dbsetup.service";
+      after = [ "network.target" ]
+        ++ lib.optionals cfg.createDatabaseLocally [ "postgresql.service" "miniflux-dbsetup.service" ];
 
       serviceConfig = {
         ExecStart = "${cfg.package}/bin/miniflux";
@@ -129,6 +140,7 @@ in
         include "${pkgs.apparmorRulesFromClosure { name = "miniflux"; } cfg.package}"
         r ${cfg.package}/bin/miniflux,
         r @{sys}/kernel/mm/transparent_hugepage/hpage_pmd_size,
+        rw /run/miniflux/**,
       }
     '';
   };
diff --git a/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix b/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
index 08f90dcf59d8..5cda4a00a9de 100644
--- a/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
@@ -45,7 +45,7 @@ let
     };
   };
 
-  webroot = pkgs.runCommand
+  webroot = pkgs.runCommandLocal
     "${cfg.package.name or "nextcloud"}-with-apps"
     { }
     ''
diff --git a/nixpkgs/nixos/modules/services/web-apps/photoprism.nix b/nixpkgs/nixos/modules/services/web-apps/photoprism.nix
index ccf995fccf3e..39eb7c65c635 100644
--- a/nixpkgs/nixos/modules/services/web-apps/photoprism.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/photoprism.nix
@@ -104,6 +104,7 @@ in
         StateDirectory = "photoprism";
         WorkingDirectory = "/var/lib/photoprism";
         RuntimeDirectory = "photoprism";
+        ReadWritePaths = [ cfg.originalsPath cfg.importPath cfg.storagePath ];
 
         LoadCredential = lib.optionalString (cfg.passwordFile != null)
           "PHOTOPRISM_ADMIN_PASSWORD:${cfg.passwordFile}";
diff --git a/nixpkgs/nixos/modules/services/web-apps/vikunja.nix b/nixpkgs/nixos/modules/services/web-apps/vikunja.nix
index b893f2c1f33c..efa9c676d9a5 100644
--- a/nixpkgs/nixos/modules/services/web-apps/vikunja.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/vikunja.nix
@@ -9,10 +9,13 @@ let
   useMysql = cfg.database.type == "mysql";
   usePostgresql = cfg.database.type == "postgres";
 in {
+  imports = [
+    (mkRemovedOptionModule [ "services" "vikunja" "setupNginx" ] "services.vikunja no longer supports the automatic set up of a nginx virtual host. Set up your own webserver config with a proxy pass to the vikunja service.")
+  ];
+
   options.services.vikunja = with lib; {
     enable = mkEnableOption (lib.mdDoc "vikunja service");
-    package-api = mkPackageOption pkgs "vikunja-api" { };
-    package-frontend = mkPackageOption pkgs "vikunja-frontend" { };
+    package = mkPackageOption pkgs "vikunja" { };
     environmentFiles = mkOption {
       type = types.listOf types.path;
       default = [ ];
@@ -21,25 +24,10 @@ in {
         For example passwords should be set in one of these files.
       '';
     };
-    setupNginx = mkOption {
-      type = types.bool;
-      default = config.services.nginx.enable;
-      defaultText = literalExpression "config.services.nginx.enable";
-      description = lib.mdDoc ''
-        Whether to setup NGINX.
-        Further nginx configuration can be done by changing
-        {option}`services.nginx.virtualHosts.<frontendHostname>`.
-        This does not enable TLS or ACME by default. To enable this, set the
-        {option}`services.nginx.virtualHosts.<frontendHostname>.enableACME` to
-        `true` and if appropriate do the same for
-        {option}`services.nginx.virtualHosts.<frontendHostname>.forceSSL`.
-      '';
-    };
     frontendScheme = mkOption {
       type = types.enum [ "http" "https" ];
       description = lib.mdDoc ''
         Whether the site is available via http or https.
-        This does not configure https or ACME in nginx!
       '';
     };
     frontendHostname = mkOption {
@@ -104,42 +92,27 @@ in {
       };
     };
 
-    systemd.services.vikunja-api = {
-      description = "vikunja-api";
+    systemd.services.vikunja = {
+      description = "vikunja";
       after = [ "network.target" ] ++ lib.optional usePostgresql "postgresql.service" ++ lib.optional useMysql "mysql.service";
       wantedBy = [ "multi-user.target" ];
-      path = [ cfg.package-api ];
+      path = [ cfg.package ];
       restartTriggers = [ configFile ];
 
       serviceConfig = {
         Type = "simple";
         DynamicUser = true;
         StateDirectory = "vikunja";
-        ExecStart = "${cfg.package-api}/bin/vikunja";
+        ExecStart = "${cfg.package}/bin/vikunja";
         Restart = "always";
         EnvironmentFile = cfg.environmentFiles;
       };
     };
 
-    services.nginx.virtualHosts."${cfg.frontendHostname}" = mkIf cfg.setupNginx {
-      locations = {
-        "/" = {
-          root = cfg.package-frontend;
-          tryFiles = "try_files $uri $uri/ /";
-        };
-        "~* ^/(api|dav|\\.well-known)/" = {
-          proxyPass = "http://localhost:${toString cfg.port}";
-          extraConfig = ''
-            client_max_body_size 20M;
-          '';
-        };
-      };
-    };
-
     environment.etc."vikunja/config.yaml".source = configFile;
 
     environment.systemPackages = [
-      cfg.package-api # for admin `vikunja` CLI
+      cfg.package # for admin `vikunja` CLI
     ];
   };
 }
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma6.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma6.nix
index bc246b1af278..1237261e0af7 100644
--- a/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma6.nix
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma6.nix
@@ -10,6 +10,11 @@
 
   inherit (pkgs) kdePackages;
   inherit (lib) literalExpression mkDefault mkIf mkOption mkPackageOptionMD types;
+
+  activationScript = ''
+    # will be rebuilt automatically
+    rm -fv $HOME/.cache/ksycoca*
+  '';
 in {
   options = {
     services.xserver.desktopManager.plasma6 = {
@@ -127,6 +132,7 @@ in {
 
         spectacle
         systemsettings
+        kcmutils
 
         # Gear
         baloo
@@ -272,5 +278,14 @@ in {
     };
 
     programs.kdeconnect.package = kdePackages.kdeconnect-kde;
+
+    # FIXME: ugly hack. See #292632 for details.
+    system.userActivationScripts.rebuildSycoca = activationScript;
+    systemd.user.services.nixos-rebuild-sycoca = {
+      description = "Rebuild KDE system configuration cache";
+      wantedBy = [ "graphical-session-pre.target" ];
+      serviceConfig.Type = "oneshot";
+      script = activationScript;
+    };
   };
 }
diff --git a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
index 258cf622a894..03bff1dee5b9 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
+++ b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
@@ -43,6 +43,7 @@ class BootSpec:
     system: str
     toplevel: str
     specialisations: Dict[str, "BootSpec"]
+    sortKey: str
     initrdSecrets: str | None = None
 
 
@@ -73,6 +74,7 @@ def system_dir(profile: str | None, generation: int, specialisation: str | None)
         return d
 
 BOOT_ENTRY = """title {title}
+sort-key {sort_key}
 version Generation {generation} {description}
 linux {kernel}
 initrd {initrd}
@@ -123,7 +125,13 @@ def get_bootspec(profile: str | None, generation: int) -> BootSpec:
 def bootspec_from_json(bootspec_json: Dict) -> BootSpec:
     specialisations = bootspec_json['org.nixos.specialisation.v1']
     specialisations = {k: bootspec_from_json(v) for k, v in specialisations.items()}
-    return BootSpec(**bootspec_json['org.nixos.bootspec.v1'], specialisations=specialisations)
+    systemdBootExtension = bootspec_json.get('org.nixos.systemd-boot', {})
+    sortKey = systemdBootExtension.get('sortKey', 'nixos')
+    return BootSpec(
+        **bootspec_json['org.nixos.bootspec.v1'],
+        specialisations=specialisations,
+        sortKey=sortKey
+    )
 
 
 def copy_from_file(file: str, dry_run: bool = False) -> str:
@@ -170,6 +178,7 @@ def write_entry(profile: str | None, generation: int, specialisation: str | None
 
     with open(tmp_path, 'w') as f:
         f.write(BOOT_ENTRY.format(title=title,
+                    sort_key=bootspec.sortKey,
                     generation=generation,
                     kernel=kernel,
                     initrd=initrd,
diff --git a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
index 645b764760da..ba07506266e2 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
+++ b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
@@ -87,6 +87,16 @@ in {
 
   imports =
     [ (mkRenamedOptionModule [ "boot" "loader" "gummiboot" "enable" ] [ "boot" "loader" "systemd-boot" "enable" ])
+      (lib.mkChangedOptionModule
+        [ "boot" "loader" "systemd-boot" "memtest86" "entryFilename" ]
+        [ "boot" "loader" "systemd-boot" "memtest86" "sortKey" ]
+        (config: lib.strings.removeSuffix ".conf" config.boot.loader.systemd-boot.memtest86.entryFilename)
+      )
+      (lib.mkChangedOptionModule
+        [ "boot" "loader" "systemd-boot" "netbootxyz" "entryFilename" ]
+        [ "boot" "loader" "systemd-boot" "netbootxyz" "sortKey" ]
+        (config: lib.strings.removeSuffix ".conf" config.boot.loader.systemd-boot.netbootxyz.entryFilename)
+      )
     ];
 
   options.boot.loader.systemd-boot = {
@@ -102,6 +112,35 @@ in {
       '';
     };
 
+    sortKey = mkOption {
+      default = "nixos";
+      type = lib.types.str;
+      description = ''
+        The sort key used for the NixOS bootloader entries.
+        This key determines sorting relative to non-NixOS entries.
+        See also https://uapi-group.org/specifications/specs/boot_loader_specification/#sorting
+
+        This option can also be used to control the sorting of NixOS specialisations.
+
+        By default, specialisations inherit the sort key of their parent generation
+        and will have the same value for both the sort-key and the version (i.e. the generation number),
+        systemd-boot will therefore sort them based on their file name, meaning that
+        in your boot menu you will have each main generation directly followed by
+        its specialisations sorted alphabetically by their names.
+
+        If you want a different ordering for a specialisation, you can override
+        its sort-key which will cause the specialisation to be uncoupled from its
+        parent generation. It will then be sorted by its new sort-key just like
+        any other boot entry.
+
+        The sort-key is stored in the generation's bootspec, which means that
+        generations keep their sort-keys even if the original definition of the
+        generation was removed from the NixOS configuration.
+        It also means that updating the sort-key will only affect new generations,
+        while old ones will keep the sort-key that they were originally built with.
+      '';
+    };
+
     editor = mkOption {
       default = true;
 
@@ -184,13 +223,15 @@ in {
         '';
       };
 
-      entryFilename = mkOption {
-        default = "memtest86.conf";
+      sortKey = mkOption {
+        default = "o_memtest86";
         type = types.str;
         description = lib.mdDoc ''
-          `systemd-boot` orders the menu entries by the config file names,
+          `systemd-boot` orders the menu entries by their sort keys,
           so if you want something to appear after all the NixOS entries,
           it should start with {file}`o` or onwards.
+
+          See also {option}`boot.loader.systemd-boot.sortKey`.
         '';
       };
     };
@@ -207,13 +248,15 @@ in {
         '';
       };
 
-      entryFilename = mkOption {
-        default = "o_netbootxyz.conf";
+      sortKey = mkOption {
+        default = "o_netbootxyz";
         type = types.str;
         description = lib.mdDoc ''
-          `systemd-boot` orders the menu entries by the config file names,
+          `systemd-boot` orders the menu entries by their sort keys,
           so if you want something to appear after all the NixOS entries,
           it should start with {file}`o` or onwards.
+
+          See also {option}`boot.loader.systemd-boot.sortKey`.
         '';
       };
     };
@@ -225,6 +268,7 @@ in {
         { "memtest86.conf" = '''
           title Memtest86+
           efi /efi/memtest86/memtest.efi
+          sort-key z_memtest
         '''; }
       '';
       description = lib.mdDoc ''
@@ -233,9 +277,10 @@ in {
         Each attribute name denotes the destination file name,
         and the corresponding attribute value is the contents of the entry.
 
-        `systemd-boot` orders the menu entries by the config file names,
-        so if you want something to appear after all the NixOS entries,
-        it should start with {file}`o` or onwards.
+        To control the ordering of the entry in the boot menu, use the sort-key
+        field, see
+        https://uapi-group.org/specifications/specs/boot_loader_specification/#sorting
+        and {option}`boot.loader.systemd-boot.sortKey`.
       '';
     };
 
@@ -328,19 +373,25 @@ in {
 
     boot.loader.systemd-boot.extraEntries = mkMerge [
       (mkIf cfg.memtest86.enable {
-        "${cfg.memtest86.entryFilename}" = ''
+        "memtest86.conf" = ''
           title  Memtest86+
           efi    /efi/memtest86/memtest.efi
+          sort-key ${cfg.memtest86.sortKey}
         '';
       })
       (mkIf cfg.netbootxyz.enable {
-        "${cfg.netbootxyz.entryFilename}" = ''
+        "netbootxyz.conf" = ''
           title  netboot.xyz
           efi    /efi/netbootxyz/netboot.xyz.efi
+          sort-key ${cfg.netbootxyz.sortKey}
         '';
       })
     ];
 
+    boot.bootspec.extensions."org.nixos.systemd-boot" = {
+      inherit (config.boot.loader.systemd-boot) sortKey;
+    };
+
     system = {
       build.installBootLoader = finalSystemdBootBuilder;
 
diff --git a/nixpkgs/nixos/modules/system/boot/systemd.nix b/nixpkgs/nixos/modules/system/boot/systemd.nix
index e29fa49ea23b..49090423e078 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd.nix
@@ -97,6 +97,7 @@ let
 
       # Maintaining state across reboots.
       "systemd-random-seed.service"
+      "systemd-boot-random-seed.service"
       "systemd-backlight@.service"
       "systemd-rfkill.service"
       "systemd-rfkill.socket"
@@ -667,7 +668,6 @@ in
 
     # Don't bother with certain units in containers.
     systemd.services.systemd-remount-fs.unitConfig.ConditionVirtualization = "!container";
-    systemd.services.systemd-random-seed.unitConfig.ConditionVirtualization = "!container";
 
     # Increase numeric PID range (set directly instead of copying a one-line file from systemd)
     # https://github.com/systemd/systemd/pull/12226
diff --git a/nixpkgs/nixos/modules/tasks/filesystems.nix b/nixpkgs/nixos/modules/tasks/filesystems.nix
index e72a1e37759e..191b46271194 100644
--- a/nixpkgs/nixos/modules/tasks/filesystems.nix
+++ b/nixpkgs/nixos/modules/tasks/filesystems.nix
@@ -105,7 +105,7 @@ let
         type = types.bool;
         description = lib.mdDoc ''
           If the device does not currently contain a filesystem (as
-          determined by {command}`blkid`, then automatically
+          determined by {command}`blkid`), then automatically
           format it with the filesystem type specified in
           {option}`fsType`.  Use with caution.
         '';
diff --git a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix
index 58aca3fdbd4f..d11424c11c81 100644
--- a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix
@@ -211,6 +211,7 @@ in
 
   imports = [
     (mkRemovedOptionModule [ "boot" "zfs" "enableLegacyCrypto" ] "The corresponding package was removed from nixpkgs.")
+    (mkRemovedOptionModule [ "boot" "zfs" "enableUnstable" ] "Instead set `boot.zfs.package = pkgs.zfs_unstable;`")
   ];
 
   ###### interface
@@ -219,9 +220,9 @@ in
     boot.zfs = {
       package = mkOption {
         type = types.package;
-        default = if cfgZfs.enableUnstable then pkgs.zfsUnstable else pkgs.zfs;
-        defaultText = literalExpression "if zfsUnstable is enabled then pkgs.zfsUnstable else pkgs.zfs";
-        description = lib.mdDoc "Configured ZFS userland tools package, use `pkgs.zfsUnstable` if you want to track the latest staging ZFS branch.";
+        default = pkgs.zfs;
+        defaultText = literalExpression "pkgs.zfs";
+        description = lib.mdDoc "Configured ZFS userland tools package, use `pkgs.zfs_unstable` if you want to track the latest staging ZFS branch.";
       };
 
       modulePackage = mkOption {
@@ -239,19 +240,6 @@ in
         description = lib.mdDoc "True if ZFS filesystem support is enabled";
       };
 
-      enableUnstable = mkOption {
-        type = types.bool;
-        default = false;
-        description = lib.mdDoc ''
-          Use the unstable zfs package. This might be an option, if the latest
-          kernel is not yet supported by a published release of ZFS. Enabling
-          this option will install a development version of ZFS on Linux. The
-          version will have already passed an extensive test suite, but it is
-          more likely to hit an undiscovered bug compared to running a released
-          version of ZFS on Linux.
-          '';
-      };
-
       allowHibernation = mkOption {
         type = types.bool;
         default = false;
diff --git a/nixpkgs/nixos/modules/virtualisation/incus.nix b/nixpkgs/nixos/modules/virtualisation/incus.nix
index 3bbe0ba45851..a561c5682ae5 100644
--- a/nixpkgs/nixos/modules/virtualisation/incus.nix
+++ b/nixpkgs/nixos/modules/virtualisation/incus.nix
@@ -107,6 +107,13 @@ in
   };
 
   config = lib.mkIf cfg.enable {
+    assertions = [
+      {
+        assertion = !(config.networking.firewall.enable && !config.networking.nftables.enable && config.virtualisation.incus.enable);
+        message = "Incus on NixOS is unsupported using iptables. Set `networking.nftables.enable = true;`";
+      }
+    ];
+
     # https://github.com/lxc/incus/blob/f145309929f849b9951658ad2ba3b8f10cbe69d1/doc/reference/server_settings.md
     boot.kernel.sysctl = {
       "fs.aio-max-nr" = lib.mkDefault 524288;
diff --git a/nixpkgs/nixos/modules/virtualisation/oci-containers.nix b/nixpkgs/nixos/modules/virtualisation/oci-containers.nix
index a88715587d65..5bffb3f04716 100644
--- a/nixpkgs/nixos/modules/virtualisation/oci-containers.nix
+++ b/nixpkgs/nixos/modules/virtualisation/oci-containers.nix
@@ -312,7 +312,7 @@ let
 
     preStop = if cfg.backend == "podman"
       then "podman stop --ignore --cidfile=/run/podman-${escapedName}.ctr-id"
-      else "${cfg.backend} stop ${name}";
+      else "${cfg.backend} stop ${name} || true";
 
     postStop = if cfg.backend == "podman"
       then "podman rm -f --ignore --cidfile=/run/podman-${escapedName}.ctr-id"
diff --git a/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix b/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix
index 75ba6dacc122..b5a8b08eee70 100644
--- a/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix
+++ b/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix
@@ -877,11 +877,9 @@ in
         type = types.package;
         default = (pkgs.OVMF.override {
           secureBoot = cfg.useSecureBoot;
-          systemManagementModeRequired = cfg.useSecureBoot;
         }).fd;
         defaultText = ''(pkgs.OVMF.override {
           secureBoot = cfg.useSecureBoot;
-          systemManagementModeRequired = cfg.useSecureBoot;
         }).fd'';
         description =
         lib.mdDoc "OVMF firmware package, defaults to OVMF configured with secure boot if needed.";
@@ -1185,7 +1183,7 @@ in
         "-tpmdev emulator,id=tpm_dev_0,chardev=chrtpm"
         "-device ${cfg.tpm.deviceModel},tpmdev=tpm_dev_0"
       ])
-      (mkIf (cfg.efi.OVMF.systemManagementModeRequired or false) [
+      (mkIf (pkgs.stdenv.hostPlatform.isx86 && cfg.efi.OVMF.systemManagementModeRequired) [
         "-machine" "q35,smm=on"
         "-global" "driver=cfi.pflash01,property=secure,value=on"
       ])
diff --git a/nixpkgs/nixos/modules/virtualisation/virtualbox-host.nix b/nixpkgs/nixos/modules/virtualisation/virtualbox-host.nix
index 50a8f8189590..0ecf7f490cf6 100644
--- a/nixpkgs/nixos/modules/virtualisation/virtualbox-host.nix
+++ b/nixpkgs/nixos/modules/virtualisation/virtualbox-host.nix
@@ -6,7 +6,7 @@ let
   cfg = config.virtualisation.virtualbox.host;
 
   virtualbox = cfg.package.override {
-    inherit (cfg) enableHardening headless enableWebService;
+    inherit (cfg) enableHardening headless enableWebService enableKvm;
     extensionPack = if cfg.enableExtensionPack then pkgs.virtualboxExtpack else null;
   };
 
@@ -81,13 +81,24 @@ in
         Build VirtualBox web service tool (vboxwebsrv) to allow managing VMs via other webpage frontend tools. Useful for headless servers.
       '';
     };
+
+    enableKvm = mkOption {
+      type = types.bool;
+      default = false;
+      description = lib.mdDoc ''
+        Enable KVM support for VirtualBox. This increases compatibility with Linux kernel versions, because the VirtualBox kernel modules
+        are not required.
+
+        This option is incompatible with `enableHardening` and `addNetworkInterface`.
+
+        Note: This is experimental. Please check https://github.com/cyberus-technology/virtualbox-kvm/issues.
+      '';
+    };
   };
 
   config = mkIf cfg.enable (mkMerge [{
     warnings = mkIf (pkgs.config.virtualbox.enableExtensionPack or false)
       ["'nixpkgs.virtualbox.enableExtensionPack' has no effect, please use 'virtualisation.virtualbox.host.enableExtensionPack'"];
-    boot.kernelModules = [ "vboxdrv" "vboxnetadp" "vboxnetflt" ];
-    boot.extraModulePackages = [ kernelModules ];
     environment.systemPackages = [ virtualbox ];
 
     security.wrappers = let
@@ -114,17 +125,43 @@ in
 
     services.udev.extraRules =
       ''
-        KERNEL=="vboxdrv",    OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
-        KERNEL=="vboxdrvu",   OWNER="root", GROUP="root",      MODE="0666", TAG+="systemd"
-        KERNEL=="vboxnetctl", OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
         SUBSYSTEM=="usb_device", ACTION=="add", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
         SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
         SUBSYSTEM=="usb_device", ACTION=="remove", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor"
         SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor"
       '';
+  } (mkIf cfg.enableKvm {
+    assertions = [
+      {
+        assertion = !cfg.addNetworkInterface;
+        message = "VirtualBox KVM only supports standard NAT networking for VMs. Please turn off virtualisation.virtualbox.host.addNetworkInferface.";
+      }
+
+      {
+        assertion = !cfg.enableHardening;
+        message = "VirtualBox KVM is not compatible with hardening: Please turn off virtualisation.virtualbox.host.enableHardening.";
+      }
+    ];
+
+    warnings = [
+      ''
+        KVM support in VirtualBox is experimental. Not all security features are available yet.
+        See: https://github.com/cyberus-technology/virtualbox-kvm/issues/12
+      ''
+    ];
+  }) (mkIf (!cfg.enableKvm) {
+    boot.kernelModules = [ "vboxdrv" "vboxnetadp" "vboxnetflt" ];
+    boot.extraModulePackages = [ kernelModules ];
+
+    services.udev.extraRules =
+      ''
+        KERNEL=="vboxdrv",    OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
+        KERNEL=="vboxdrvu",   OWNER="root", GROUP="root",      MODE="0666", TAG+="systemd"
+        KERNEL=="vboxnetctl", OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
+     '';
 
     # Since we lack the right setuid/setcap binaries, set up a host-only network by default.
-  } (mkIf cfg.addNetworkInterface {
+  }) (mkIf cfg.addNetworkInterface {
     systemd.services.vboxnet0 =
       { description = "VirtualBox vboxnet0 Interface";
         requires = [ "dev-vboxnetctl.device" ];
diff --git a/nixpkgs/nixos/tests/acme.nix b/nixpkgs/nixos/tests/acme.nix
index 272782dc2f62..d63a77fcdd23 100644
--- a/nixpkgs/nixos/tests/acme.nix
+++ b/nixpkgs/nixos/tests/acme.nix
@@ -1,4 +1,7 @@
-{ pkgs, lib, ... }: let
+{ config, lib, ... }: let
+
+  pkgs = config.node.pkgs;
+
   commonConfig = ./common/acme/client;
 
   dnsServerIP = nodes: nodes.dnsserver.networking.primaryIPAddress;
diff --git a/nixpkgs/nixos/tests/akkoma.nix b/nixpkgs/nixos/tests/akkoma.nix
index 287e2d485999..2907017ee3d5 100644
--- a/nixpkgs/nixos/tests/akkoma.nix
+++ b/nixpkgs/nixos/tests/akkoma.nix
@@ -31,16 +31,12 @@ let
 
     export REQUESTS_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt"
 
-    echo '${userPassword}' | ${pkgs.toot}/bin/toot login_cli -i "akkoma.nixos.test" -e "jamy@nixos.test"
-    echo "y" | ${pkgs.toot}/bin/toot post "hello world Jamy here"
-
-    # Retrieving timeline with toot currently broken due to incompatible timestamp format
-    # cf. <https://akkoma.dev/AkkomaGang/akkoma/issues/637> and <https://github.com/ihabunek/toot/issues/399>
-    #echo "y" | ${pkgs.toot}/bin/toot timeline | grep -F -q "hello world Jamy here"
+    ${pkgs.toot}/bin/toot login_cli -i "akkoma.nixos.test" -e "jamy@nixos.test" -p '${userPassword}'
+    ${pkgs.toot}/bin/toot post "hello world Jamy here"
+    ${pkgs.toot}/bin/toot timeline -1 | grep -F -q "hello world Jamy here"
 
     # Test file upload
-    echo "y" | ${pkgs.toot}/bin/toot upload <(dd if=/dev/zero bs=1024 count=1024 status=none) \
-      | grep -F -q "https://akkoma.nixos.test/media"
+    ${pkgs.toot}/bin/toot upload <(dd if=/dev/zero bs=1024 count=1024 status=none)
   '';
 
   checkFe = pkgs.writers.writeBashBin "checkFe" ''
diff --git a/nixpkgs/nixos/tests/all-tests.nix b/nixpkgs/nixos/tests/all-tests.nix
index 231767ca2b97..7376cd40b910 100644
--- a/nixpkgs/nixos/tests/all-tests.nix
+++ b/nixpkgs/nixos/tests/all-tests.nix
@@ -78,8 +78,9 @@ let
     #       it with `allowAliases = false`?
     # warnIf pkgs.config.allowAliases "nixosTests: pkgs includes aliases."
     {
+      _file = "${__curPos.file} readOnlyPkgs";
       _class = "nixosTest";
-      node.pkgs = pkgs;
+      node.pkgs = pkgs.pkgsLinux;
     };
 
 in {
@@ -512,6 +513,7 @@ in {
   mastodon = discoverTests (import ./web-apps/mastodon { inherit handleTestOn; });
   pixelfed = discoverTests (import ./web-apps/pixelfed { inherit handleTestOn; });
   mate = handleTest ./mate.nix {};
+  matter-server = handleTest ./matter-server.nix {};
   matomo = handleTest ./matomo.nix {};
   matrix-appservice-irc = handleTest ./matrix/appservice-irc.nix {};
   matrix-conduit = handleTest ./matrix/conduit.nix {};
@@ -916,6 +918,7 @@ in {
   tor = handleTest ./tor.nix {};
   traefik = handleTestOn ["aarch64-linux" "x86_64-linux"] ./traefik.nix {};
   trafficserver = handleTest ./trafficserver.nix {};
+  transfer-sh = handleTest ./transfer-sh.nix {};
   transmission = handleTest ./transmission.nix { transmission = pkgs.transmission; };
   transmission_4 = handleTest ./transmission.nix { transmission = pkgs.transmission_4; };
   # tracee requires bpf
diff --git a/nixpkgs/nixos/tests/docker-registry.nix b/nixpkgs/nixos/tests/docker-registry.nix
index db20cb52c3e3..3969ef3f0226 100644
--- a/nixpkgs/nixos/tests/docker-registry.nix
+++ b/nixpkgs/nixos/tests/docker-registry.nix
@@ -13,7 +13,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
       services.dockerRegistry.port = 8080;
       services.dockerRegistry.listenAddress = "0.0.0.0";
       services.dockerRegistry.enableGarbageCollect = true;
-      networking.firewall.allowedTCPPorts = [ 8080 ];
+      services.dockerRegistry.openFirewall = true;
     };
 
     client1 = { ... }: {
diff --git a/nixpkgs/nixos/tests/homepage-dashboard.nix b/nixpkgs/nixos/tests/homepage-dashboard.nix
index 56e077f5ff6d..dd36473e8ac0 100644
--- a/nixpkgs/nixos/tests/homepage-dashboard.nix
+++ b/nixpkgs/nixos/tests/homepage-dashboard.nix
@@ -2,13 +2,35 @@ import ./make-test-python.nix ({ lib, ... }: {
   name = "homepage-dashboard";
   meta.maintainers = with lib.maintainers; [ jnsgruk ];
 
-  nodes.machine = { pkgs, ... }: {
+  nodes.unmanaged_conf = { pkgs, ... }: {
     services.homepage-dashboard.enable = true;
   };
 
+  nodes.managed_conf = { pkgs, ... }: {
+    services.homepage-dashboard = {
+      enable = true;
+      settings.title = "custom";
+    };
+  };
+
   testScript = ''
-    machine.wait_for_unit("homepage-dashboard.service")
-    machine.wait_for_open_port(8082)
-    machine.succeed("curl --fail http://localhost:8082/")
+    # Ensure the services are started on unmanaged machine
+    unmanaged_conf.wait_for_unit("homepage-dashboard.service")
+    unmanaged_conf.wait_for_open_port(8082)
+    unmanaged_conf.succeed("curl --fail http://localhost:8082/")
+
+    # Ensure that /etc/homepage-dashboard doesn't exist, and boilerplate
+    # configs are copied into place.
+    unmanaged_conf.fail("test -d /etc/homepage-dashboard")
+    unmanaged_conf.succeed("test -f /var/lib/private/homepage-dashboard/settings.yaml")
+
+    # Ensure the services are started on managed machine
+    managed_conf.wait_for_unit("homepage-dashboard.service")
+    managed_conf.wait_for_open_port(8082)
+    managed_conf.succeed("curl --fail http://localhost:8082/")
+
+    # Ensure /etc/homepage-dashboard is created and unmanaged conf location isn't.
+    managed_conf.succeed("test -d /etc/homepage-dashboard")
+    managed_conf.fail("test -f /var/lib/private/homepage-dashboard/settings.yaml")
   '';
 })
diff --git a/nixpkgs/nixos/tests/knot.nix b/nixpkgs/nixos/tests/knot.nix
index c5af8bf1edcc..eec94a22f2fa 100644
--- a/nixpkgs/nixos/tests/knot.nix
+++ b/nixpkgs/nixos/tests/knot.nix
@@ -66,6 +66,10 @@ in {
             "0.0.0.0@53"
             "::@53"
            ];
+          listen-quic = [
+            "0.0.0.0@853"
+            "::@853"
+           ];
           automatic-acl = true;
         };
 
@@ -129,8 +133,13 @@ in {
           key = "xfr_key";
         };
 
+        remote.primary-quic = {
+          address = "192.168.0.1@853";
+          key = "xfr_key";
+          quic = true;
+        };
+
         template.default = {
-          master = "primary";
           # zonefileless setup
           # https://www.knot-dns.cz/docs/2.8/html/operation.html#example-2
           zonefile-sync = "-1";
@@ -139,8 +148,14 @@ in {
         };
 
         zone = {
-          "example.com".file = "example.com.zone";
-          "sub.example.com".file = "sub.example.com.zone";
+          "example.com" = {
+            master = "primary";
+            file = "example.com.zone";
+          };
+          "sub.example.com" = {
+            master = "primary-quic";
+            file = "sub.example.com.zone";
+          };
         };
 
         log.syslog.any = "debug";
diff --git a/nixpkgs/nixos/tests/matter-server.nix b/nixpkgs/nixos/tests/matter-server.nix
new file mode 100644
index 000000000000..c646e9840d19
--- /dev/null
+++ b/nixpkgs/nixos/tests/matter-server.nix
@@ -0,0 +1,45 @@
+import ./make-test-python.nix ({ pkgs, lib, ...} :
+
+let
+  chipVersion = pkgs.python311Packages.home-assistant-chip-core.version;
+in
+
+{
+  name = "matter-server";
+  meta.maintainers = with lib.maintainers; [ leonm1 ];
+
+  nodes = {
+    machine = { config, ... }: {
+      services.matter-server = {
+        enable = true;
+        port = 1234;
+      };
+    };
+  };
+
+  testScript = /* python */ ''
+    start_all()
+
+    machine.wait_for_unit("matter-server.service")
+    machine.wait_for_open_port(1234)
+
+    with subtest("Check websocket server initialized"):
+        output = machine.succeed("echo \"\" | ${pkgs.websocat}/bin/websocat ws://localhost:1234/ws")
+        machine.log(output)
+
+    assert '"sdk_version": "${chipVersion}"' in output, (
+      'CHIP version \"${chipVersion}\" not present in websocket message'
+    )
+
+    assert '"fabric_id": 1' in output, (
+      "fabric_id not propagated to server"
+    )
+
+    with subtest("Check storage directory is created"):
+        machine.succeed("ls /var/lib/matter-server/chip.json")
+
+    with subtest("Check systemd hardening"):
+        _, output = machine.execute("systemd-analyze security matter-server.service | grep -v '✓'")
+        machine.log(output)
+  '';
+})
diff --git a/nixpkgs/nixos/tests/miniflux.nix b/nixpkgs/nixos/tests/miniflux.nix
index a3af53db0e7a..6d38224448ed 100644
--- a/nixpkgs/nixos/tests/miniflux.nix
+++ b/nixpkgs/nixos/tests/miniflux.nix
@@ -15,6 +15,10 @@ let
             ADMIN_USERNAME=${username}
             ADMIN_PASSWORD=${password}
           '';
+  postgresPassword = "correcthorsebatterystaple";
+  postgresPasswordFile = pkgs.writeText "pgpass" ''
+    *:*:*:*:${postgresPassword}
+  '';
 
 in
 {
@@ -56,32 +60,62 @@ in
           adminCredentialsFile = customAdminCredentialsFile;
         };
       };
+
+    postgresTcp = { config, pkgs, lib, ... }: {
+      services.postgresql = {
+        enable = true;
+        initialScript = pkgs.writeText "init-postgres" ''
+          CREATE USER miniflux WITH PASSWORD '${postgresPassword}';
+          CREATE DATABASE miniflux WITH OWNER miniflux;
+        '';
+        enableTCPIP = true;
+        authentication = ''
+          host sameuser miniflux samenet scram-sha-256
+        '';
+      };
+      systemd.services.postgresql.postStart = lib.mkAfter ''
+        $PSQL -tAd miniflux -c 'CREATE EXTENSION hstore;'
+      '';
+      networking.firewall.allowedTCPPorts = [ config.services.postgresql.port ];
+    };
+    externalDb = { ... }: {
+      security.apparmor.enable = true;
+      services.miniflux = {
+        enable = true;
+        createDatabaseLocally = false;
+        inherit adminCredentialsFile;
+        config = {
+          DATABASE_URL = "user=miniflux host=postgresTcp dbname=miniflux sslmode=disable";
+          PGPASSFILE = "/run/miniflux/pgpass";
+        };
+      };
+      systemd.services.miniflux.preStart = ''
+        cp ${postgresPasswordFile} /run/miniflux/pgpass
+        chmod 600 /run/miniflux/pgpass
+      '';
+    };
   };
   testScript = ''
-    start_all()
+    def runTest(machine, port, user):
+      machine.wait_for_unit("miniflux.service")
+      machine.wait_for_open_port(port)
+      machine.succeed(f"curl --fail 'http://localhost:{port}/healthcheck' | grep OK")
+      machine.succeed(
+          f"curl 'http://localhost:{port}/v1/me' -u '{user}' -H Content-Type:application/json | grep '\"is_admin\":true'"
+      )
+      machine.fail('journalctl -b --no-pager --grep "^audit: .*apparmor=\\"DENIED\\""')
 
-    default.wait_for_unit("miniflux.service")
-    default.wait_for_open_port(${toString defaultPort})
-    default.succeed("curl --fail 'http://localhost:${toString defaultPort}/healthcheck' | grep OK")
-    default.succeed(
-        "curl 'http://localhost:${toString defaultPort}/v1/me' -u '${defaultUsername}:${defaultPassword}' -H Content-Type:application/json | grep '\"is_admin\":true'"
-    )
-    default.fail('journalctl -b --no-pager --grep "^audit: .*apparmor=\\"DENIED\\""')
+    default.start()
+    withoutSudo.start()
+    customized.start()
+    postgresTcp.start()
 
-    withoutSudo.wait_for_unit("miniflux.service")
-    withoutSudo.wait_for_open_port(${toString defaultPort})
-    withoutSudo.succeed("curl --fail 'http://localhost:${toString defaultPort}/healthcheck' | grep OK")
-    withoutSudo.succeed(
-        "curl 'http://localhost:${toString defaultPort}/v1/me' -u '${defaultUsername}:${defaultPassword}' -H Content-Type:application/json | grep '\"is_admin\":true'"
-    )
-    withoutSudo.fail('journalctl -b --no-pager --grep "^audit: .*apparmor=\\"DENIED\\""')
+    runTest(default, ${toString defaultPort}, "${defaultUsername}:${defaultPassword}")
+    runTest(withoutSudo, ${toString defaultPort}, "${defaultUsername}:${defaultPassword}")
+    runTest(customized, ${toString port}, "${username}:${password}")
 
-    customized.wait_for_unit("miniflux.service")
-    customized.wait_for_open_port(${toString port})
-    customized.succeed("curl --fail 'http://localhost:${toString port}/healthcheck' | grep OK")
-    customized.succeed(
-        "curl 'http://localhost:${toString port}/v1/me' -u '${username}:${password}' -H Content-Type:application/json | grep '\"is_admin\":true'"
-    )
-    customized.fail('journalctl -b --no-pager --grep "^audit: .*apparmor=\\"DENIED\\""')
+    postgresTcp.wait_for_unit("postgresql.service")
+    externalDb.start()
+    runTest(externalDb, ${toString defaultPort}, "${defaultUsername}:${defaultPassword}")
   '';
 })
diff --git a/nixpkgs/nixos/tests/minio.nix b/nixpkgs/nixos/tests/minio.nix
index ece4864f771c..67eb0cd88440 100644
--- a/nixpkgs/nixos/tests/minio.nix
+++ b/nixpkgs/nixos/tests/minio.nix
@@ -43,17 +43,17 @@ import ./make-test-python.nix ({ pkgs, ... }:
 
         # Minio requires at least 1GiB of free disk space to run.
         virtualisation.diskSize = 4 * 1024;
+
+        # Minio pre allocates 2GiB or memory, reserve some more
+        virtualisation.memorySize = 4096;
       };
     };
 
     testScript = ''
-      import time
 
       start_all()
       # simulate manually editing root credentials file
       machine.wait_for_unit("multi-user.target")
-      machine.copy_from_host("${credsPartial}", "${rootCredentialsFile}")
-      time.sleep(3)
       machine.copy_from_host("${credsFull}", "${rootCredentialsFile}")
 
       machine.wait_for_unit("minio.service")
diff --git a/nixpkgs/nixos/tests/nixops/default.nix b/nixpkgs/nixos/tests/nixops/default.nix
index 6501d13a2ed3..8477e5059fca 100644
--- a/nixpkgs/nixos/tests/nixops/default.nix
+++ b/nixpkgs/nixos/tests/nixops/default.nix
@@ -9,7 +9,7 @@ let
     #  - Alternatively, blocked on a NixOps 2 release
     #    https://github.com/NixOS/nixops/issues/1242
     # stable = testsLegacyNetwork { nixopsPkg = pkgs.nixops; };
-    unstable = testsForPackage { nixopsPkg = pkgs.nixops_unstable; };
+    unstable = testsForPackage { nixopsPkg = pkgs.nixops_unstable_minimal; };
 
     # inherit testsForPackage;
   };
@@ -32,6 +32,7 @@ let
           pkgs.hello
           pkgs.figlet
         ];
+        virtualisation.memorySize = 2048;
 
         # TODO: make this efficient, https://github.com/NixOS/nixpkgs/issues/180529
         system.includeBuildDependencies = true;
diff --git a/nixpkgs/nixos/tests/qemu-vm-external-disk-image.nix b/nixpkgs/nixos/tests/qemu-vm-external-disk-image.nix
index a229fc5e3963..c481159511a0 100644
--- a/nixpkgs/nixos/tests/qemu-vm-external-disk-image.nix
+++ b/nixpkgs/nixos/tests/qemu-vm-external-disk-image.nix
@@ -69,5 +69,8 @@ in
     os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name
 
     machine.succeed("findmnt --kernel --source ${rootFsDevice} --target /")
+
+    # Make sure systemd boot didn't clobber this
+    machine.succeed("[ ! -e /homeless-shelter ]")
   '';
 }
diff --git a/nixpkgs/nixos/tests/sanoid.nix b/nixpkgs/nixos/tests/sanoid.nix
index 411ebcead9f6..1575634e6284 100644
--- a/nixpkgs/nixos/tests/sanoid.nix
+++ b/nixpkgs/nixos/tests/sanoid.nix
@@ -115,8 +115,11 @@ in {
     source.systemctl("start --wait syncoid-pool-sanoid.service")
     target.succeed("cat /mnt/pool/sanoid/test.txt")
     source.systemctl("start --wait syncoid-pool-syncoid.service")
+    source.systemctl("start --wait syncoid-pool-syncoid.service")
     target.succeed("cat /mnt/pool/syncoid/test.txt")
 
+    assert(len(source.succeed("zfs list -H -t snapshot pool/syncoid").splitlines()) == 1), "Syncoid should only retain one sync snapshot"
+
     source.systemctl("start --wait syncoid-pool.service")
     target.succeed("[[ -d /mnt/pool/full-pool/syncoid ]]")
 
diff --git a/nixpkgs/nixos/tests/systemd-boot.nix b/nixpkgs/nixos/tests/systemd-boot.nix
index 1b7e83253e59..54c380602bd4 100644
--- a/nixpkgs/nixos/tests/systemd-boot.nix
+++ b/nixpkgs/nixos/tests/systemd-boot.nix
@@ -93,6 +93,7 @@ in
       machine.wait_for_unit("multi-user.target")
 
       machine.succeed("test -e /boot/loader/entries/nixos-generation-1.conf")
+      machine.succeed("grep 'sort-key nixos' /boot/loader/entries/nixos-generation-1.conf")
 
       # Ensure we actually booted using systemd-boot
       # Magic number is the vendor UUID used by systemd-boot.
@@ -115,15 +116,17 @@ in
       virtualisation.useSecureBoot = true;
     };
 
-    testScript = ''
+    testScript = let
+      efiArch = pkgs.stdenv.hostPlatform.efiArch;
+    in { nodes, ... }: ''
       machine.start(allow_reboot=True)
       machine.wait_for_unit("multi-user.target")
 
       machine.succeed("sbctl create-keys")
       machine.succeed("sbctl enroll-keys --yes-this-might-brick-my-machine")
-      machine.succeed('sbctl sign /boot/EFI/systemd/systemd-bootx64.efi')
-      machine.succeed('sbctl sign /boot/EFI/BOOT/BOOTX64.EFI')
-      machine.succeed('sbctl sign /boot/EFI/nixos/*bzImage.efi')
+      machine.succeed('sbctl sign /boot/EFI/systemd/systemd-boot${efiArch}.efi')
+      machine.succeed('sbctl sign /boot/EFI/BOOT/BOOT${toUpper efiArch}.EFI')
+      machine.succeed('sbctl sign /boot/EFI/nixos/*${nodes.machine.system.boot.loader.kernelFile}.efi')
 
       machine.reboot()
 
@@ -164,7 +167,9 @@ in
 
     nodes.machine = { pkgs, lib, ... }: {
       imports = [ common ];
-      specialisation.something.configuration = {};
+      specialisation.something.configuration = {
+        boot.loader.systemd-boot.sortKey = "something";
+      };
     };
 
     testScript = ''
@@ -177,6 +182,9 @@ in
       machine.succeed(
           "grep -q 'title NixOS (something)' /boot/loader/entries/nixos-generation-1-specialisation-something.conf"
       )
+      machine.succeed(
+          "grep 'sort-key something' /boot/loader/entries/nixos-generation-1-specialisation-something.conf"
+      )
     '';
   };
 
@@ -254,25 +262,25 @@ in
     };
 
     testScript = ''
-      machine.succeed("test -e /boot/loader/entries/o_netbootxyz.conf")
+      machine.succeed("test -e /boot/loader/entries/netbootxyz.conf")
       machine.succeed("test -e /boot/efi/netbootxyz/netboot.xyz.efi")
     '';
   };
 
-  entryFilename = makeTest {
-    name = "systemd-boot-entry-filename";
+  memtestSortKey = makeTest {
+    name = "systemd-boot-memtest-sortkey";
     meta.maintainers = with pkgs.lib.maintainers; [ Enzime julienmalka ];
 
     nodes.machine = { pkgs, lib, ... }: {
       imports = [ common ];
       boot.loader.systemd-boot.memtest86.enable = true;
-      boot.loader.systemd-boot.memtest86.entryFilename = "apple.conf";
+      boot.loader.systemd-boot.memtest86.sortKey = "apple";
     };
 
     testScript = ''
-      machine.fail("test -e /boot/loader/entries/memtest86.conf")
-      machine.succeed("test -e /boot/loader/entries/apple.conf")
+      machine.succeed("test -e /boot/loader/entries/memtest86.conf")
       machine.succeed("test -e /boot/efi/memtest86/memtest.efi")
+      machine.succeed("grep 'sort-key apple' /boot/loader/entries/memtest86.conf")
     '';
   };
 
@@ -283,7 +291,6 @@ in
     nodes.machine = { pkgs, lib, ... }: {
       imports = [ commonXbootldr ];
       boot.loader.systemd-boot.memtest86.enable = true;
-      boot.loader.systemd-boot.memtest86.entryFilename = "apple.conf";
     };
 
     testScript = { nodes, ... }: ''
@@ -293,8 +300,7 @@ in
       machine.wait_for_unit("multi-user.target")
 
       machine.succeed("test -e /efi/EFI/systemd/systemd-bootx64.efi")
-      machine.fail("test -e /boot/loader/entries/memtest86.conf")
-      machine.succeed("test -e /boot/loader/entries/apple.conf")
+      machine.succeed("test -e /boot/loader/entries/memtest86.conf")
       machine.succeed("test -e /boot/EFI/memtest86/memtest.efi")
     '';
   };
@@ -386,9 +392,9 @@ in
           machine.succeed("${finalSystem}/bin/switch-to-configuration boot")
           machine.fail("test -e /boot/efi/fruits/tomato.efi")
           machine.fail("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi")
-          machine.succeed("test -e /boot/loader/entries/o_netbootxyz.conf")
+          machine.succeed("test -e /boot/loader/entries/netbootxyz.conf")
           machine.succeed("test -e /boot/efi/netbootxyz/netboot.xyz.efi")
-          machine.succeed("test -e /boot/efi/nixos/.extra-files/loader/entries/o_netbootxyz.conf")
+          machine.succeed("test -e /boot/efi/nixos/.extra-files/loader/entries/netbootxyz.conf")
           machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/netbootxyz/netboot.xyz.efi")
     '';
   };
diff --git a/nixpkgs/nixos/tests/transfer-sh.nix b/nixpkgs/nixos/tests/transfer-sh.nix
new file mode 100644
index 000000000000..f4ab7d28858e
--- /dev/null
+++ b/nixpkgs/nixos/tests/transfer-sh.nix
@@ -0,0 +1,20 @@
+import ./make-test-python.nix ({ pkgs, lib, ... }: {
+  name = "transfer-sh";
+
+  meta = {
+    maintainers = with lib.maintainers; [ ocfox ];
+  };
+
+  nodes.machine = { pkgs, ... }: {
+    services.transfer-sh = {
+      enable = true;
+      settings.LISTENER = ":1234";
+    };
+  };
+
+  testScript = ''
+    machine.wait_for_unit("transfer-sh.service")
+    machine.wait_for_open_port(1234)
+    machine.succeed("curl --fail http://localhost:1234/")
+  '';
+})
diff --git a/nixpkgs/nixos/tests/vikunja.nix b/nixpkgs/nixos/tests/vikunja.nix
index 60fd5ce13854..4e2bf166a7b6 100644
--- a/nixpkgs/nixos/tests/vikunja.nix
+++ b/nixpkgs/nixos/tests/vikunja.nix
@@ -13,15 +13,20 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
         frontendScheme = "http";
         frontendHostname = "localhost";
       };
-      services.nginx.enable = true;
+      services.nginx = {
+        enable = true;
+        virtualHosts."http://localhost" = {
+          locations."/".proxyPass = "http://localhost:3456";
+        };
+      };
     };
     vikunjaPostgresql = { pkgs, ... }: {
       services.vikunja = {
         enable = true;
         database = {
           type = "postgres";
-          user = "vikunja-api";
-          database = "vikunja-api";
+          user = "vikunja";
+          database = "vikunja";
           host = "/run/postgresql";
         };
         frontendScheme = "http";
@@ -30,20 +35,25 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
       };
       services.postgresql = {
         enable = true;
-        ensureDatabases = [ "vikunja-api" ];
+        ensureDatabases = [ "vikunja" ];
         ensureUsers = [
-          { name = "vikunja-api";
+          { name = "vikunja";
             ensureDBOwnership = true;
           }
         ];
       };
-      services.nginx.enable = true;
+      services.nginx = {
+        enable = true;
+        virtualHosts."http://localhost" = {
+          locations."/".proxyPass = "http://localhost:9090";
+        };
+      };
     };
   };
 
   testScript =
     ''
-      vikunjaSqlite.wait_for_unit("vikunja-api.service")
+      vikunjaSqlite.wait_for_unit("vikunja.service")
       vikunjaSqlite.wait_for_open_port(3456)
       vikunjaSqlite.succeed("curl --fail http://localhost:3456/api/v1/info")
 
@@ -52,7 +62,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
       vikunjaSqlite.succeed("curl --fail http://localhost/api/v1/info")
       vikunjaSqlite.succeed("curl --fail http://localhost")
 
-      vikunjaPostgresql.wait_for_unit("vikunja-api.service")
+      vikunjaPostgresql.wait_for_unit("vikunja.service")
       vikunjaPostgresql.wait_for_open_port(9090)
       vikunjaPostgresql.succeed("curl --fail http://localhost:9090/api/v1/info")
 
diff --git a/nixpkgs/nixos/tests/virtualbox.nix b/nixpkgs/nixos/tests/virtualbox.nix
index e522d0679e15..3c2a391233db 100644
--- a/nixpkgs/nixos/tests/virtualbox.nix
+++ b/nixpkgs/nixos/tests/virtualbox.nix
@@ -3,6 +3,7 @@
   pkgs ? import ../.. { inherit system config; },
   debug ? false,
   enableUnfree ? false,
+  enableKvm ? false,
   use64bitGuest ? true
 }:
 
@@ -340,7 +341,7 @@ let
     testExtensionPack.vmFlags = enableExtensionPackVMFlags;
   };
 
-  mkVBoxTest = useExtensionPack: vms: name: testScript: makeTest {
+  mkVBoxTest = vboxHostConfig: vms: name: testScript: makeTest {
     name = "virtualbox-${name}";
 
     nodes.machine = { lib, config, ... }: {
@@ -349,14 +350,23 @@ let
         vmConfigs = mapAttrsToList mkVMConf vms;
       in [ ./common/user-account.nix ./common/x11.nix ] ++ vmConfigs;
       virtualisation.memorySize = 2048;
-      virtualisation.qemu.options = ["-cpu" "kvm64,svm=on,vmx=on"];
-      virtualisation.virtualbox.host.enable = true;
+
+      virtualisation.qemu.options = let
+        # IvyBridge is reasonably ancient to be compatible with recent
+        # Intel/AMD hosts and sufficient for the KVM flavor.
+        guestCpu = if config.virtualisation.virtualbox.host.enableKvm then "IvyBridge" else "kvm64";
+      in ["-cpu" "${guestCpu},svm=on,vmx=on"];
+
       test-support.displayManager.auto.user = "alice";
       users.users.alice.extraGroups = let
         inherit (config.virtualisation.virtualbox.host) enableHardening;
-      in lib.mkIf enableHardening (lib.singleton "vboxusers");
-      virtualisation.virtualbox.host.enableExtensionPack = useExtensionPack;
-      nixpkgs.config.allowUnfree = useExtensionPack;
+      in lib.mkIf enableHardening [ "vboxusers" ];
+
+      virtualisation.virtualbox.host = {
+        enable = true;
+      } // vboxHostConfig;
+
+      nixpkgs.config.allowUnfree = config.virtualisation.virtualbox.host.enableExtensionPack;
     };
 
     testScript = ''
@@ -390,7 +400,7 @@ let
     };
   };
 
-  unfreeTests = mapAttrs (mkVBoxTest true vboxVMsWithExtpack) {
+  unfreeTests = mapAttrs (mkVBoxTest { enableExtensionPack = true; } vboxVMsWithExtpack) {
     enable-extension-pack = ''
       create_vm_testExtensionPack()
       vbm("startvm testExtensionPack")
@@ -409,7 +419,24 @@ let
     '';
   };
 
-in mapAttrs (mkVBoxTest false vboxVMs) {
+  kvmTests = mapAttrs (mkVBoxTest {
+    enableKvm = true;
+
+    # Once the KVM version supports these, we can enable them.
+    addNetworkInterface = false;
+    enableHardening = false;
+  } vboxVMs) {
+    kvm-headless = ''
+      create_vm_headless()
+      machine.succeed(ru("VBoxHeadless --startvm headless >&2 & disown %1"))
+      wait_for_startup_headless()
+      wait_for_vm_boot_headless()
+      shutdown_vm_headless()
+      destroy_vm_headless()
+    '';
+  };
+
+in mapAttrs (mkVBoxTest {} vboxVMs) {
   simple-gui = ''
     # Home to select Tools, down to move to the VM, enter to start it.
     def send_vm_startup():
@@ -519,4 +546,6 @@ in mapAttrs (mkVBoxTest false vboxVMs) {
     destroy_vm_test1()
     destroy_vm_test2()
   '';
-} // (optionalAttrs enableUnfree unfreeTests)
+}
+// (optionalAttrs enableKvm kvmTests)
+// (optionalAttrs enableUnfree unfreeTests)
diff --git a/nixpkgs/nixos/tests/zfs.nix b/nixpkgs/nixos/tests/zfs.nix
index 0b411b0b9d8a..851fced2c5e1 100644
--- a/nixpkgs/nixos/tests/zfs.nix
+++ b/nixpkgs/nixos/tests/zfs.nix
@@ -7,14 +7,14 @@ with import ../lib/testing-python.nix { inherit system pkgs; };
 
 let
 
-  makeZfsTest = name:
+  makeZfsTest =
     { kernelPackages
     , enableSystemdStage1 ? false
     , zfsPackage
     , extraTest ? ""
     }:
     makeTest {
-      name = "zfs-" + name;
+      name = zfsPackage.kernelModuleAttribute;
       meta = with pkgs.lib.maintainers; {
         maintainers = [ elvishjerricco ];
       };
@@ -192,23 +192,23 @@ let
 in {
 
   # maintainer: @raitobezarius
-  series_2_1 = makeZfsTest "2.1-series" {
+  series_2_1 = makeZfsTest {
     zfsPackage = pkgs.zfs_2_1;
     kernelPackages = pkgs.linuxPackages;
   };
 
-  stable = makeZfsTest "stable" {
-    zfsPackage = pkgs.zfsStable;
+  series_2_2 = makeZfsTest {
+    zfsPackage = pkgs.zfs_2_2;
     kernelPackages = pkgs.linuxPackages;
   };
 
-  unstable = makeZfsTest "unstable" rec {
-    zfsPackage = pkgs.zfsUnstable;
+  unstable = makeZfsTest rec {
+    zfsPackage = pkgs.zfs_unstable;
     kernelPackages = zfsPackage.latestCompatibleLinuxPackages;
   };
 
-  unstableWithSystemdStage1 = makeZfsTest "unstable" rec {
-    zfsPackage = pkgs.zfsUnstable;
+  unstableWithSystemdStage1 = makeZfsTest rec {
+    zfsPackage = pkgs.zfs_unstable;
     kernelPackages = zfsPackage.latestCompatibleLinuxPackages;
     enableSystemdStage1 = true;
   };