about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/configuration/abstractions.section.md2
-rw-r--r--nixos/doc/manual/default.nix8
-rw-r--r--nixos/doc/manual/release-notes/rl-2405.section.md94
-rw-r--r--nixos/lib/systemd-lib.nix3
-rw-r--r--nixos/modules/config/no-x-libs.nix2
-rw-r--r--nixos/modules/config/terminfo.nix2
-rw-r--r--nixos/modules/config/xdg/terminal-exec.nix54
-rw-r--r--nixos/modules/hardware/openrazer.nix61
-rw-r--r--nixos/modules/hardware/video/intel-gpu-tools.nix25
-rw-r--r--nixos/modules/module-list.nix8
-rw-r--r--nixos/modules/profiles/perlless.nix2
-rw-r--r--nixos/modules/programs/evince.nix15
-rw-r--r--nixos/modules/programs/file-roller.nix15
-rw-r--r--nixos/modules/programs/fish.nix10
-rw-r--r--nixos/modules/programs/gnome-disks.nix17
-rw-r--r--nixos/modules/programs/gnome-terminal.nix15
-rw-r--r--nixos/modules/programs/gpaste.nix15
-rw-r--r--nixos/modules/programs/seahorse.nix16
-rw-r--r--nixos/modules/programs/wayland/hyprland.nix18
-rw-r--r--nixos/modules/services/backup/restic.nix19
-rw-r--r--nixos/modules/services/backup/znapzend.nix10
-rw-r--r--nixos/modules/services/databases/postgresql.nix35
-rw-r--r--nixos/modules/services/desktop-managers/plasma6.nix9
-rw-r--r--nixos/modules/services/desktops/gnome/at-spi2-core.nix23
-rw-r--r--nixos/modules/services/desktops/gnome/evolution-data-server.nix36
-rw-r--r--nixos/modules/services/desktops/gnome/glib-networking.nix16
-rw-r--r--nixos/modules/services/desktops/gnome/gnome-browser-connector.nix13
-rw-r--r--nixos/modules/services/desktops/gnome/gnome-initial-setup.nix18
-rw-r--r--nixos/modules/services/desktops/gnome/gnome-keyring.nix18
-rw-r--r--nixos/modules/services/desktops/gnome/gnome-online-accounts.nix18
-rw-r--r--nixos/modules/services/desktops/gnome/gnome-online-miners.nix18
-rw-r--r--nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix30
-rw-r--r--nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix20
-rw-r--r--nixos/modules/services/desktops/gnome/gnome-user-share.nix16
-rw-r--r--nixos/modules/services/desktops/gnome/rygel.nix18
-rw-r--r--nixos/modules/services/desktops/gnome/sushi.nix18
-rw-r--r--nixos/modules/services/desktops/gnome/tracker-miners.nix18
-rw-r--r--nixos/modules/services/desktops/gnome/tracker.nix22
-rw-r--r--nixos/modules/services/desktops/gvfs.nix17
-rw-r--r--nixos/modules/services/display-managers/default.nix31
-rw-r--r--nixos/modules/services/hardware/kanata.nix53
-rw-r--r--nixos/modules/services/home-automation/ebusd.nix159
-rw-r--r--nixos/modules/services/logging/logrotate.nix2
-rw-r--r--nixos/modules/services/logging/promtail.nix4
-rw-r--r--nixos/modules/services/mail/mailman.nix11
-rw-r--r--nixos/modules/services/matrix/conduit.nix2
-rw-r--r--nixos/modules/services/misc/gitlab.nix46
-rw-r--r--nixos/modules/services/misc/heisenbridge.nix2
-rw-r--r--nixos/modules/services/misc/wastebin.nix2
-rw-r--r--nixos/modules/services/misc/zoneminder.nix2
-rw-r--r--nixos/modules/services/monitoring/parsedmarc.nix8
-rw-r--r--nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix4
-rw-r--r--nixos/modules/services/networking/clatd.nix81
-rw-r--r--nixos/modules/services/networking/jotta-cli.md27
-rw-r--r--nixos/modules/services/networking/jotta-cli.nix43
-rw-r--r--nixos/modules/services/networking/networkmanager.nix2
-rw-r--r--nixos/modules/services/networking/ssh/sshd.nix13
-rw-r--r--nixos/modules/services/networking/sunshine.nix6
-rw-r--r--nixos/modules/services/networking/trust-dns.nix6
-rw-r--r--nixos/modules/services/security/oauth2-proxy-nginx.nix (renamed from nixos/modules/services/security/oauth2_proxy_nginx.nix)55
-rw-r--r--nixos/modules/services/security/oauth2-proxy.nix (renamed from nixos/modules/services/security/oauth2_proxy.nix)251
-rw-r--r--nixos/modules/services/security/step-ca.nix2
-rw-r--r--nixos/modules/services/security/vault.nix4
-rw-r--r--nixos/modules/services/system/dbus.nix12
-rw-r--r--nixos/modules/services/web-apps/keycloak.nix2
-rw-r--r--nixos/modules/services/web-apps/nextcloud.md5
-rw-r--r--nixos/modules/services/web-apps/nextcloud.nix4
-rw-r--r--nixos/modules/services/web-apps/plausible.nix9
-rw-r--r--nixos/modules/services/web-servers/caddy/default.nix3
-rw-r--r--nixos/modules/services/web-servers/nginx/default.nix3
-rw-r--r--nixos/modules/services/web-servers/traefik.nix2
-rw-r--r--nixos/modules/services/x11/desktop-managers/cinnamon.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/default.nix20
-rw-r--r--nixos/modules/services/x11/desktop-managers/gnome.nix101
-rw-r--r--nixos/modules/services/x11/display-managers/default.nix30
-rw-r--r--nixos/modules/services/x11/window-managers/default.nix14
-rwxr-xr-xnixos/modules/system/activation/switch-to-configuration.pl3
-rw-r--r--nixos/modules/system/activation/test.nix4
-rw-r--r--nixos/modules/system/activation/top-level.nix23
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix5
-rw-r--r--nixos/modules/virtualisation/containers.nix13
-rw-r--r--nixos/modules/virtualisation/incus.nix17
-rw-r--r--nixos/modules/virtualisation/podman/default.nix10
-rw-r--r--nixos/release-combined.nix4
-rw-r--r--nixos/tests/all-tests.nix3
-rw-r--r--nixos/tests/clatd.nix189
-rw-r--r--nixos/tests/fish.nix2
-rw-r--r--nixos/tests/installed-tests/default.nix2
-rw-r--r--nixos/tests/installed-tests/gnome-photos.nix2
-rw-r--r--nixos/tests/jotta-cli.nix25
-rw-r--r--nixos/tests/k3s/single-node.nix12
-rw-r--r--nixos/tests/kanidm.nix19
-rw-r--r--nixos/tests/libreswan.nix6
-rw-r--r--nixos/tests/openssh.nix38
-rw-r--r--nixos/tests/patroni.nix2
-rw-r--r--nixos/tests/postgresql-jit.nix15
-rw-r--r--nixos/tests/postgresql-wal-receiver.nix202
-rw-r--r--nixos/tests/ssh-keys.nix12
98 files changed, 1332 insertions, 1072 deletions
diff --git a/nixos/doc/manual/configuration/abstractions.section.md b/nixos/doc/manual/configuration/abstractions.section.md
index 06356c472ba94..3ff8ac885b653 100644
--- a/nixos/doc/manual/configuration/abstractions.section.md
+++ b/nixos/doc/manual/configuration/abstractions.section.md
@@ -10,14 +10,12 @@ If you find yourself repeating yourself over and over, it’s time to abstract.
         adminAddr = "alice@example.org";
         forceSSL = true;
         enableACME = true;
-        enablePHP = true;
       };
       "wiki.example.org" = {
         documentRoot = "/webroot/wiki.example.org";
         adminAddr = "alice@example.org";
         forceSSL = true;
         enableACME = true;
-        enablePHP = true;
       };
     };
 }
diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix
index 558fec4cab923..80916e9733c5c 100644
--- a/nixos/doc/manual/default.nix
+++ b/nixos/doc/manual/default.nix
@@ -80,17 +80,17 @@ let
     cp -r --no-preserve=all $inputs/* .
 
     substituteInPlace ./manual.md \
-      --replace '@NIXOS_VERSION@' "${version}"
+      --replace-fail '@NIXOS_VERSION@' "${version}"
     substituteInPlace ./configuration/configuration.md \
-      --replace \
+      --replace-fail \
           '@MODULE_CHAPTERS@' \
           ${escapeShellArg (concatMapStringsSep "\n" (p: "${p.value}") config.meta.doc)}
     substituteInPlace ./nixos-options.md \
-      --replace \
+      --replace-fail \
         '@NIXOS_OPTIONS_JSON@' \
         ${optionsDoc.optionsJSON}/${common.outputPath}/options.json
     substituteInPlace ./development/writing-nixos-tests.section.md \
-      --replace \
+      --replace-fail \
         '@NIXOS_TEST_OPTIONS_JSON@' \
         ${testOptionsDoc.optionsJSON}/${common.outputPath}/options.json
     sed -e '/@PYTHON_MACHINE_METHODS@/ {' -e 'r ${testDriverMachineDocstrings}/machine-methods.md' -e 'd' -e '}' \
diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md
index 82bf551c1fe98..bf40faac3a83a 100644
--- a/nixos/doc/manual/release-notes/rl-2405.section.md
+++ b/nixos/doc/manual/release-notes/rl-2405.section.md
@@ -10,13 +10,13 @@ In addition to numerous new and upgraded packages, this release has the followin
 
 - `cryptsetup` has been upgraded from 2.6.1 to 2.7.0. Cryptsetup is a critical component enabling LUKS-based (but not only) full disk encryption.
   Take the time to review [the release notes](https://gitlab.com/cryptsetup/cryptsetup/-/raw/v2.7.0/docs/v2.7.0-ReleaseNotes).
-  One of the highlight is that it is now possible to use hardware OPAL-based encryption of your disk with `cryptsetup`, it has a lot of caveats, see the above notes for the full details.
+  One of the highlights is that it is now possible to use hardware OPAL-based encryption of your disk with `cryptsetup`. It has a lot of caveats, see the above notes for the full details.
 
 - `screen`'s module has been cleaned, and will now require you to set `programs.screen.enable` in order to populate `screenrc` and add the program to the environment.
 
 - `linuxPackages_testing_bcachefs` is now fully deprecated by `linuxPackages_latest`, and is therefore no longer available.
 
-- The default kernel package has been updated from 6.1 to 6.6. All supported kernels remain available.
+- (TODO not sure what path to use here) The default kernel package has been updated from 6.1 to 6.6. All supported kernels remain available.
 
 - NixOS now installs a stub ELF loader that prints an informative error message when users attempt to run binaries not made for NixOS.
    - This can be disabled through the `environment.stub-ld.enable` option.
@@ -34,9 +34,9 @@ In addition to numerous new and upgraded packages, this release has the followin
   - `nixVersions.git` which tracks the latest Nix master and is roughly updated once a week. This is intended to enable people to easily test unreleased changes of Nix to catch regressions earlier.
   - `nixVersions.latest` which points to the latest Nix version packaged in nixpkgs.
 
-- Julia environments can now be built with arbitrary packages from the ecosystem using the `.withPackages` function. For example: `julia.withPackages ["Plots"]`.
+- `julia` environments can now be built with arbitrary packages from the ecosystem using the `.withPackages` function. For example: `julia.withPackages ["Plots"]`.
 
-- The PipeWire and WirePlumber modules have removed support for using
+- `pipewire` and `wireplumber` modules have removed support for using
 `environment.etc."pipewire/..."` and `environment.etc."wireplumber/..."`.
 Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for PipeWire and
 `services.pipewire.wireplumber.configPackages` for WirePlumber instead."
@@ -45,7 +45,7 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi
   Refer to upstream [upgrade instructions](https://goteleport.com/docs/management/operations/upgrading/)
   and release notes for [v15](https://goteleport.com/docs/changelog/#1500-013124).
 
-- A new option `systemd.sysusers.enable` was added. If enabled, users and
+- `systemd.sysusers.enable` option was added. If enabled, users and
   groups are created with systemd-sysusers instead of with a custom perl script.
 
 - `virtualisation.docker.enableNvidia` and `virtualisation.podman.enableNvidia` options are deprecated. `hardware.nvidia-container-toolkit.enable` should be used instead. This option will expose GPUs on containers with the `--device` CLI option. This is supported by Docker 25, Podman 3.2.0 and Singularity 4. Any container runtime that supports the CDI specification will take advantage of this feature.
@@ -69,16 +69,16 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi
   }
   ```
 
-- The initial Incus LTS release (v6.0.x) is now available through `virtualisation.incus` as the default. Users who wish to continue using the non-LTS release will need to set `virtualisation.incus.package = pkgs.incus`. Stable release users are encouraged to stay on the LTS release as non-LTS releases will by default not be backported.
+- `virtialisation.incus` now defaults to the newly-added `incus-lts` release (v6.0.x). Users who wish to continue using the non-LTS release will need to set `virtualisation.incus.package = pkgs.incus`. Stable release users are encouraged to stay on the LTS release as non-LTS releases will by default not be backported.
 
-- Canonical LXD has been upgraded to v5.21.x, an LTS release. The LTS release is now the only supported LXD release. Users are encouraged to [migrate to Incus](https://linuxcontainers.org/incus/docs/main/howto/server_migrate_lxd/) for better support on NixOS.
+- Canonical `lxd` has been upgraded to v5.21.x, an LTS release. The LTS release is now the only supported LXD release. Users are encouraged to [migrate to Incus](https://linuxcontainers.org/incus/docs/main/howto/server_migrate_lxd/) for better support on NixOS.
 
-- lua interpreters default LUA_PATH and LUA_CPATH are not overriden by nixpkgs
+- `lua` interpreters default LUA_PATH and LUA_CPATH are not overriden by nixpkgs
   anymore, we patch LUA_ROOT instead which is more respectful to upstream.
 
-- Plasma 6 is now available and can be installed with `services.xserver.desktopManager.plasma6.enable = true;`. Plasma 5 will likely be deprecated in the next release (24.11). Note that Plasma 6 runs as Wayland by default, and the X11 session needs to be explicitly selected if necessary.
+- `plasma6` is now available and can be installed with `services.xserver.desktopManager.plasma6.enable = true;`. Plasma 5 will likely be deprecated in the next release (24.11). Note that Plasma 6 runs as Wayland by default, and the X11 session needs to be explicitly selected if necessary.
 
-- The desktop mode of Lomiri (formerly known as Unity8), using Mir 2.x to function as a Wayland compositor, is now available and can be installed with `services.desktopManager.lomiri.enable = true`. Note that some core applications, services and indicators have yet to be packaged, and some functions may remain incomplete, but the base experience should be there.
+- `lomiri` (formerly known as Unity8) desktop mode, using Mir 2.x to function as a Wayland compositor, is now available and can be installed with `services.desktopManager.lomiri.enable = true`. Note that some core applications, services and indicators have yet to be packaged, and some functions may remain incomplete, but the base experience should be there.
 
 ## New Services {#sec-release-24.05-new-services}
 
@@ -92,6 +92,8 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi
 
 - [PhotonVision](https://photonvision.org/), a free, fast, and easy-to-use computer vision solution for the FIRST® Robotics Competition.
 
+- [clatd](https://github.com/toreanderson/clatd), a CLAT / SIIT-DC Edge Relay implementation for Linux.
+
 - [pyLoad](https://pyload.net/), a FOSS download manager written in Python. Available as [services.pyload](#opt-services.pyload.enable)
 
 - [maubot](https://github.com/maubot/maubot), a plugin-based Matrix bot framework. Available as [services.maubot](#opt-services.maubot.enable).
@@ -100,7 +102,7 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi
 
 - [ryzen-smu](https://gitlab.com/leogx9r/ryzen_smu), Linux kernel driver to expose the SMU (System Management Unit) for certain AMD Ryzen Processors. Includes the userspace program `monitor_cpu`. Available at [hardward.cpu.amd.ryzen-smu](#opt-hardware.cpu.amd.ryzen-smu.enable)
 
-- systemd's gateway, upload, and remote services, which provides ways of sending journals across the network. Enable using [services.journald.gateway](#opt-services.journald.gateway.enable), [services.journald.upload](#opt-services.journald.upload.enable), and [services.journald.remote](#opt-services.journald.remote.enable).
+- `systemd`'s `gateway`, `upload`, and `remote` services, which provide ways of sending journals across the network. Enable using [services.journald.gateway](#opt-services.journald.gateway.enable), [services.journald.upload](#opt-services.journald.upload.enable), and [services.journald.remote](#opt-services.journald.remote.enable).
 
 - [GNS3](https://www.gns3.com/), a network software emulator. Available as [services.gns3-server](#opt-services.gns3-server.enable).
 
@@ -127,10 +129,12 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi
 - [db-rest](https://github.com/derhuerst/db-rest), a wrapper around Deutsche Bahn's internal API for public transport data. Available as [services.db-rest](#opt-services.db-rest.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.
+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 software.
 
 - [mautrix-meta](https://github.com/mautrix/meta), a Matrix <-> Facebook and Matrix <-> Instagram hybrid puppeting/relaybot bridge. Available as services.mautrix-meta
 
+- [Jottacloud Command-line Tool](https://docs.jottacloud.com/en/articles/1436834-jottacloud-command-line-tool), a CLI for the [Jottacloud](https://jottacloud.com/) cloud storage provider. Available as [services.jotta-cli](#opt-services.jotta-cli.enable).
+
 - [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).
 
 - [FCast Receiver](https://fcast.org), an open-source alternative to Chromecast and AirPlay. Available as [programs.fcast-receiver](#opt-programs.fcast-receiver.enable).
@@ -139,7 +143,7 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - [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).
 
-- A self-hosted management server for the [Netbird](https://netbird.io). Available as [services.netbird.server](#opt-services.netbird.server.enable).
+- [Netbird](https://netbird.io), an open-source VPN management platform, now has a self-hosted management server. Available as [services.netbird.server](#opt-services.netbird.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).
 
@@ -151,9 +155,11 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - [Monado](https://monado.freedesktop.org/), an open source XR runtime. Available as [services.monado](#opt-services.monado.enable).
 
-- [Pretix](https://pretix.eu/about/en/), an open source ticketing software for events. Available as [services.pretix]($opt-services-pretix.enable).
+- [intel-gpu-tools](https://drm.pages.freedesktop.org/igt-gpu-tools), tools for development and testing of the Intel DRM driver. Available as [hardware.intel-gpu-tools](#opt-hardware.intel-gpu-tools.enable)
 
-- [microsocks](https://github.com/rofl0r/microsocks), a tiny, portable SOCKS5 server with very moderate resource usage. Available as [services.microsocks]($opt-services-microsocks.enable).
+- [Pretix](https://pretix.eu/about/en/), an open source ticketing software for events. Available as [services.pretix](#opt-services.pretix.enable).
+
+- [microsocks](https://github.com/rofl0r/microsocks), a tiny, portable SOCKS5 server with very moderate resource usage. Available as [services.microsocks](#opt-services.microsocks.enable).
 
 - [inadyn](https://github.com/troglobit/inadyn), a Dynamic DNS client with built-in support for multiple providers. Available as [services.inadyn](#opt-services.inadyn.enable).
 
@@ -163,21 +169,23 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - [armagetronad](https://wiki.armagetronad.org), a mid-2000s 3D lightcycle game widely played at iD Tech Camps. You can define multiple servers using `services.armagetronad.<server>.enable`.
 
-- [wyoming-satellite](https://github.com/rhasspy/wyoming-satellite), a voice assistant satellite for Home Assistant using the Wyoming protocol. Available as [services.wyoming.satellite]($opt-services.wyoming.satellite.enable).
+- [wyoming-satellite](https://github.com/rhasspy/wyoming-satellite), a voice assistant satellite for Home Assistant using the Wyoming protocol. Available as [services.wyoming.satellite](#opt-services.wyoming.satellite.enable).
 
 - [TuxClocker](https://github.com/Lurkki14/tuxclocker), a hardware control and monitoring program. Available as [programs.tuxclocker](#opt-programs.tuxclocker.enable).
 
-- binfmt option for AppImage-run to support running [AppImage](https://appimage.org/)'s seamlessly on NixOS.. Available as [programs.appimage.binfmt](#opt-programs.appimage.binfmt).
+- [AppImage](https://appimage.org/), a tool to package desktop applications, now has a `binfmt` option to support running AppImages seamlessly on NixOS. Available as [programs.appimage.binfmt](#opt-programs.appimage.binfmt).
 
 - [nh](https://github.com/viperML/nh), yet another Nix CLI helper. Available as [programs.nh](#opt-programs.nh.enable).
 
 - [ALVR](https://github.com/alvr-org/alvr), a VR desktop streamer. Available as [programs.alvr](#opt-programs.alvr.enable)
 
-- [RustDesk](https://rustdesk.com), a full-featured open source remote control alternative for self-hosting and security with minimal configuration. Alternative to TeamViewer.
+- [xdg-terminal-exec](https://github.com/Vladimir-csp/xdg-terminal-exec), the proposed Default Terminal Execution Specification.
+
+- [RustDesk](https://rustdesk.com), a full-featured open source remote control alternative for self-hosting and security with minimal configuration. Alternative to TeamViewer. Available as [services.rustdesk-server](#opt-services.rustdesk-server.enable).
 
-- [Scrutiny](https://github.com/AnalogJ/scrutiny), a S.M.A.R.T monitoring tool for hard disks with a web frontend.
+- [Scrutiny](https://github.com/AnalogJ/scrutiny), a S.M.A.R.T monitoring tool for hard disks with a web frontend. Available as [services.scrutiny](#opt-services.scrutiny.enable).
 
-- [davis](https://github.com/tchapi/davis), a simple CardDav and CalDav server inspired by Baïkal. Available as [services.davis]($opt-services-davis.enable).
+- [davis](https://github.com/tchapi/davis), a simple CardDav and CalDav server inspired by Baïkal. Available as [services.davis](#opt-services.davis.enable).
 
 - [Firefly-iii](https://www.firefly-iii.org), a free and open source personal finance manager. Available as [services.firefly-iii](#opt-services.firefly-iii.enable)
 
@@ -208,7 +216,7 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
   defaulting to `/etc/ssh/authorized_keys.d/%u`.
   ::: {.warning}
   Users of {manpage}`pam_ssh_agent_auth(8)` must take care that the pubkeys they use (for instance with `sudo`)
-  are listed in [`sshAgentAuth.authorizedKeysFiles`]..
+  are listed in [`sshAgentAuth.authorizedKeysFiles`].
   :::
   ::: {.note}
   Previously, all `services.openssh.authorizedKeysFiles` were trusted, including `~/.ssh/authorized_keys`,
@@ -226,7 +234,7 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - `cudaPackages.autoFixElfFiles` has been deprecated for `pkgs.autoFixElfFiles`. Functionality has not changed, but the setuphook has been renamed and moved to the top-level package scope.
 
-- `appimageTools.wrapAppImage` now create the binary at `$out/bin/${pname}` rather than `$out/bin/${pname}-${version}`, which will break downstream workarounds.
+- `appimageTools.wrapAppImage` now creates the binary at `$out/bin/${pname}` rather than `$out/bin/${pname}-${version}`, which will break downstream workarounds.
 
 - `pdns` was updated to version [v4.9.x](https://doc.powerdns.com/authoritative/changelog/4.9.html), which introduces breaking changes. Check out the [Upgrade Notes](https://doc.powerdns.com/authoritative/upgrading.html#to-4-9-0) for details.
 
@@ -246,16 +254,16 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
   The list in `nixos/modules/virtualisation/amazon-ec2-amis.nix` will stop
   being updated and will be removed in the future.
 
-- The option `services.postgresql.ensureUsers._.ensurePermissions` has been removed as it's
+- The option `services.postgresql.ensureUsers._.ensurePermissions` has been removed as it is
   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.
+  instead or a tool that is 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.
 
 - `nvtop` family of packages was reorganized into nested attrset. `nvtop` has been renamed to `nvtopPackages.full`, and all `nvtop-{amd,nvidia,intel,msm}` packages are now named as `nvtopPackages.{amd,nvidia,intel,msm}`
 
-- `neo4j` has been updated to version 5, you may want to read the [release notes for Neo4j 5](https://neo4j.com/release-notes/database/neo4j-5/)
+- `neo4j` has been updated to version 5. You may want to read the [release notes for Neo4j 5](https://neo4j.com/release-notes/database/neo4j-5/).
 
 - `services.neo4j.allowUpgrade` was removed and no longer has any effect. Neo4j 5 supports automatic rolling upgrades.
 
@@ -263,6 +271,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - `mongodb-4_4` has been removed as it has reached end of life. Consequently, `unifi7` and `unifi8` now use MongoDB 5.0 by default.
 
+- `mongodb-5_0` and newer requires a cpu with the avx instruction set to run.
+
 - `nitter` requires a `guest_accounts.jsonl` to be provided as a path or loaded into the default location at `/var/lib/nitter/guest_accounts.jsonl`. See [Guest Account Branch Deployment](https://github.com/zedeus/nitter/wiki/Guest-Account-Branch-Deployment) for details.
 
 - `boot.supportedFilesystems` and `boot.initrd.supportedFilesystems` are now attribute sets instead of lists. Assignment from lists as done previously is still supported, but checking whether a filesystem is enabled must now by done using `supportedFilesystems.fs or false` instead of using `lib.elem "fs" supportedFilesystems` as was done previously.
@@ -274,6 +284,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
   "mysecret"` becomes `services.aria2.rpcSecretFile = "/path/to/secret_file"`
   where the file `secret_file` contains the string `mysecret`.
 
+- The `system.forbiddenDependenciesRegex` option has been renamed to `system.forbiddenDependenciesRegexes` and now has the type of `listOf string` instead of `string` to accept multiple regexes.
+
 - `openssh`, `openssh_hpn` and `openssh_gssapi` are now compiled without support for the DSA signature algorithm as it is being deprecated upstream. Users still relying on DSA keys should consider upgrading
   to another signature algorithm. However, for the time being it is possible to restore DSA key support using `override` to set `dsaKeysSupport = true`.
 
@@ -313,9 +325,11 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
   - Proxies are now defined with a new option `settings.proxies` which takes a list of proxies.
   - Consult the [upstream documentation](https://github.com/fatedier/frp#example-usage) for more details on the changes.
 
-- `mkosi` was updated to v20. Parts of the user interface have changed. Consult the
-  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.
+- `mkosi` was updated to v22. Parts of the user interface have changed. Consult the
+  release notes of [v19](https://github.com/systemd/mkosi/releases/tag/v19),
+  [v20](https://github.com/systemd/mkosi/releases/tag/v20),
+  [v21](https://github.com/systemd/mkosi/releases/tag/v21) and
+  [v22](https://github.com/systemd/mkosi/releases/tag/v22) for a list of changes.
 
 - `gonic` has been updated to v0.16.4. Config now requires `playlists-path` to be set. See the rest of the [v0.16.0 release notes](https://github.com/sentriz/gonic/releases/tag/v0.16.0) for more details.
 
@@ -345,7 +359,7 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - `optparse-bash` is now dropped due to upstream inactivity. Alternatives available in Nixpkgs include [`argc`](https://github.com/sigoden/argc), [`argbash`](https://github.com/matejak/argbash), [`bashly`](https://github.com/DannyBen/bashly) and [`gum`](https://github.com/charmbracelet/gum), to name a few.
 
-- `kanata` package has been updated to v1.6.0, which includes breaking changes.  Check out the changelog of [v1.5.0](https://github.com/jtroo/kanata/releases/tag/v1.5.0) and [v1.6.0](https://github.com/jtroo/kanata/releases/tag/v1.6.0) for details.
+- `kanata` package has been updated to v1.6.1, which includes breaking changes.  Check out the changelog of [v1.5.0](https://github.com/jtroo/kanata/releases/tag/v1.5.0) and [v1.6.0](https://github.com/jtroo/kanata/releases/tag/v1.6.0) for details.
 
 - `craftos-pc` package has been updated to v2.8, which includes [breaking changes](https://github.com/MCJack123/craftos2/releases/tag/v2.8).
   - Files are now handled in binary mode; this could break programs with embedded UTF-8 characters.
@@ -362,7 +376,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
   - If [`system.stateVersion`](#opt-system.stateVersion) is >=24.05, `pkgs.nextcloud29` will be installed by default.
   - If [`system.stateVersion`](#opt-system.stateVersion) is >=23.11, `pkgs.nextcloud27` will be installed by default.
   - Please note that an upgrade from v27 (or older) to v29 directly is not possible. Please upgrade to `nextcloud28` (or earlier) first. Nextcloud prohibits skipping major versions while upgrading. You can upgrade by declaring [`services.nextcloud.package = pkgs.nextcloud28;`](options.html#opt-services.nextcloud.package).
-  - Known warnings after the upgrade are documented in [](#module-services-nextcloud-known-warnings).
+  - Known warnings after the upgrade are documented in [](#module-services-nextcloud-known-warnings) from now on.
+  - The "Photos" app only displays Media from inside the `Photos` directory. This can be changed manually in the "Photos" tab below "Photos settings".
 
 - The vendored third party libraries have been mostly removed from `cudaPackages.nsight_systems`, which we now only ship for `cudaPackages_11_8` and later due to outdated dependencies. Users comfortable with the vendored dependencies may use `overrideAttrs` to amend the `postPatch` phase and the `meta.broken` correspondingly. Alternatively, one could package the deprecated `boost170` locally, as required for `cudaPackages_11_4.nsight_systems`.
 
@@ -376,6 +391,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - `halloy` package was updated past 2024.5 which introduced a breaking change by switching the config format from YAML to TOML. See https://github.com/squidowl/halloy/releases/tag/2024.5 for details.
 
+- The `wpaperd` package has a breaking change moving to 1.0.1, previous version 0.3.0 had 2 different configuration files, one for wpaperd and one for the wallpapers. Remove the former and move the latter (`wallpaper.toml`) to `config.toml`.
+
 - Ada packages (libraries and tools) have been moved into the `gnatPackages` scope. `gnatPackages` uses the default GNAT compiler, `gnat12Packages` and `gnat13Packages` use the respective matching compiler version.
 
 - Paths provided as `restartTriggers` and `reloadTriggers` for systemd units will now be copied into the nix store to make the behavior consistent.
@@ -398,6 +415,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - `services.zope2` has been removed as `zope2` is unmaintained and was relying on Python2.
 
+- `services.oauth2_proxy` was renamed to `services.oauth2-proxy`. Also the corresponding service, user and group were renamed.
+
 - `services.avahi.nssmdns` got split into `services.avahi.nssmdns4` and `services.avahi.nssmdns6` which enable the mDNS NSS switch for IPv4 and IPv6 respectively.
   Since most mDNS responders only register IPv4 addresses, most users want to keep the IPv6 support disabled to avoid long timeouts.
 
@@ -497,6 +516,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - `erlang-ls` package no longer ships the `els_dap` binary as of v0.51.0.
 
+- `icu` no longer includes `install-sh` and `mkinstalldirs` in the shared folder.
+
 ## Other Notable Changes {#sec-release-24.05-notable-changes}
 
 <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
@@ -519,6 +540,17 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 - `services.postgresql.extraPlugins` changed its type from just a list of packages to also a function that returns such a list.
   For example a config line like ``services.postgresql.extraPlugins = with pkgs.postgresql_11.pkgs; [ postgis ];`` is recommended to be changed to ``services.postgresql.extraPlugins = ps: with ps; [ postgis ];``;
 
+- `services.openssh` now has an option `authorizedKeysInHomedir`, controlling whether `~/.ssh/authorizedKeys` is
+  added to `authorizedKeysFiles`.
+  ::: {.note}
+  This option currently defaults to `true` for NixOS 24.05, preserving the previous behaviour.
+  This is expected to change in NixOS 24.11.
+  :::
+  ::: {.warning}
+  Users should check that their SSH keys are in `users.users.*.openssh`, or that they have another way to access
+  and administer the system, before setting this option to `false`.
+  :::
+
 - [`matrix-synapse`](https://element-hq.github.io/synapse/) homeserver module now supports configuring UNIX domain socket [`listeners`](#opt-services.matrix-synapse.settings.listeners) through the `path` option.
   The default replication worker on the main instance has been migrated away from TCP sockets to UNIX domain sockets.
 
@@ -664,3 +696,5 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
   This enables mandoc to find manual pages in Nix profiles. To set the manual search paths via the `mandoc.conf` configuration file like before, use `documentation.man.mandoc.settings.manpath` instead.
 
 - `grafana-loki` package was updated to 3.0.0 which includes [breaking changes](https://github.com/grafana/loki/releases/tag/v3.0.0)
+
+- `programs.fish.package` now allows you to override the package used in the `fish` module
diff --git a/nixos/lib/systemd-lib.nix b/nixos/lib/systemd-lib.nix
index eef49f8c4ef38..0641da8e77517 100644
--- a/nixos/lib/systemd-lib.nix
+++ b/nixos/lib/systemd-lib.nix
@@ -18,6 +18,7 @@ let
     flip
     head
     isInt
+    isFloat
     isList
     isPath
     length
@@ -152,7 +153,7 @@ in rec {
       "Systemd ${group} field `${name}' is outside the range [${toString min},${toString max}]";
 
   assertRangeOrOneOf = name: min: max: values: group: attr:
-    optional (attr ? ${name} && !((min <= attr.${name} && max >= attr.${name}) || elem attr.${name} values))
+    optional (attr ? ${name} && !(((isInt attr.${name} || isFloat attr.${name}) && min <= attr.${name} && max >= attr.${name}) || elem attr.${name} values))
       "Systemd ${group} field `${name}' is not a value in range [${toString min},${toString max}], or one of ${toString values}";
 
   assertMinimum = name: min: group: attr:
diff --git a/nixos/modules/config/no-x-libs.nix b/nixos/modules/config/no-x-libs.nix
index b811823d698a1..1d7976cef36a2 100644
--- a/nixos/modules/config/no-x-libs.nix
+++ b/nixos/modules/config/no-x-libs.nix
@@ -47,7 +47,7 @@ with lib;
       gst_all_1 = super.gst_all_1 // {
         gst-plugins-bad = super.gst_all_1.gst-plugins-bad.override { guiSupport = false; };
         gst-plugins-base = super.gst_all_1.gst-plugins-base.override { enableWayland = false; enableX11 = false; };
-        gst-plugins-good = super.gst_all_1.gst-plugins-good.override { enableX11 = false; };
+        gst-plugins-good = super.gst_all_1.gst-plugins-good.override { enableWayland = false; enableX11 = false; gtkSupport = false; qt5Support = false; qt6Support = false; };
       };
       imagemagick = super.imagemagick.override { libX11Support = false; libXtSupport = false; };
       imagemagickBig = super.imagemagickBig.override { libX11Support = false; libXtSupport = false; };
diff --git a/nixos/modules/config/terminfo.nix b/nixos/modules/config/terminfo.nix
index 4b58605aa7f1a..b538d749ffcbf 100644
--- a/nixos/modules/config/terminfo.nix
+++ b/nixos/modules/config/terminfo.nix
@@ -31,7 +31,7 @@ with lib;
     # attrNames (filterAttrs
     #  (_: drv: (builtins.tryEval (isDerivation drv && drv ? terminfo)).value)
     #  pkgs)
-    environment.systemPackages = mkIf config.environment.enableAllTerminfo (map (x: x.terminfo) (with pkgs; [
+    environment.systemPackages = mkIf config.environment.enableAllTerminfo (map (x: x.terminfo) (with pkgs.pkgsBuildBuild; [
       alacritty
       contour
       foot
diff --git a/nixos/modules/config/xdg/terminal-exec.nix b/nixos/modules/config/xdg/terminal-exec.nix
new file mode 100644
index 0000000000000..daf2055d2e906
--- /dev/null
+++ b/nixos/modules/config/xdg/terminal-exec.nix
@@ -0,0 +1,54 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}:
+
+let
+  cfg = config.xdg.terminal-exec;
+  inherit (lib) mkIf mkEnableOption mkOption mkPackageOption types;
+in
+{
+  meta.maintainers = with lib.maintainers; [ Cryolitia ];
+
+  ###### interface
+
+  options = {
+    xdg.terminal-exec = {
+      enable = mkEnableOption "xdg-terminal-exec, the [proposed](https://gitlab.freedesktop.org/xdg/xdg-specs/-/merge_requests/46) Default Terminal Execution Specification";
+      package = mkPackageOption pkgs "xdg-terminal-exec" { };
+      settings = mkOption {
+        type = with types; attrsOf (listOf str);
+        default = { };
+        description = ''
+          Configuration options for the Default Terminal Execution Specification.
+
+          The keys are the desktop environments that are matched (case-insensitively) against `$XDG_CURRENT_DESKTOP`,
+          or `default` which is used when the current desktop environment is not found in the configuration.
+          The values are a list of terminals' [desktop file IDs](https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s02.html#desktop-file-id) to try in order of decreasing priority.
+        '';
+        example = {
+          default = [ "kitty.desktop" ];
+          GNOME = [ "com.raggesilver.BlackBox.desktop" "org.gnome.Terminal.desktop" ];
+        };
+      };
+    };
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+    environment = {
+      systemPackages = [ cfg.package ];
+
+      etc = lib.mapAttrs' (
+        desktop: terminals:
+        # map desktop name such as GNOME to `xdg/gnome-xdg-terminals.list`, default to `xdg/xdg-terminals.list`
+        lib.nameValuePair (
+          "xdg/${if desktop == "default" then "" else "${lib.toLower desktop}-"}xdg-terminals.list"
+        ) { text = lib.concatLines terminals; }
+      ) cfg.settings;
+    };
+  };
+}
diff --git a/nixos/modules/hardware/openrazer.nix b/nixos/modules/hardware/openrazer.nix
index 99b5510543233..6f61254a60c1f 100644
--- a/nixos/modules/hardware/openrazer.nix
+++ b/nixos/modules/hardware/openrazer.nix
@@ -19,7 +19,9 @@ let
       [Startup]
       sync_effects_enabled = ${toPyBoolStr cfg.syncEffectsEnabled}
       devices_off_on_screensaver = ${toPyBoolStr cfg.devicesOffOnScreensaver}
-      mouse_battery_notifier = ${toPyBoolStr cfg.mouseBatteryNotifier}
+      battery_notifier = ${toPyBoolStr cfg.batteryNotifier.enable}
+      battery_notifier_freq = ${builtins.toString cfg.batteryNotifier.frequency}
+      battery_notifier_percent = ${builtins.toString cfg.batteryNotifier.percentage}
 
       [Statistics]
       key_statistics = ${toPyBoolStr cfg.keyStatistics}
@@ -78,12 +80,39 @@ in
         '';
       };
 
-      mouseBatteryNotifier = mkOption {
-        type = types.bool;
-        default = true;
+      batteryNotifier = mkOption {
         description = ''
-          Mouse battery notifier.
+          Settings for device battery notifications.
         '';
+        default = {};
+        type = types.submodule {
+          options = {
+            enable = mkOption {
+              type = types.bool;
+              default = true;
+              description = ''
+                Mouse battery notifier.
+              '';
+            };
+            frequency = mkOption {
+              type = types.int;
+              default = 600;
+              description = ''
+                How often battery notifications should be shown (in seconds).
+                A value of 0 disables notifications.
+              '';
+            };
+
+            percentage = mkOption {
+              type = types.int;
+              default = 33;
+              description = ''
+                At what battery percentage the device should reach before
+                sending notifications.
+              '';
+            };
+          };
+        };
       };
 
       keyStatistics = mkOption {
@@ -106,6 +135,10 @@ in
     };
   };
 
+  imports = [
+    (mkRenamedOptionModule [ "hardware" "openrazer" "mouseBatteryNotifier" ] [ "hardware" "openrazer" "batteryNotifier" "enable" ])
+  ];
+
   config = mkIf cfg.enable {
     boot.extraModulePackages = [ kernelPackages.openrazer ];
     boot.kernelModules = drivers;
@@ -127,15 +160,15 @@ in
     systemd.user.services.openrazer-daemon = {
       description = "Daemon to manage razer devices in userspace";
       unitConfig.Documentation = "man:openrazer-daemon(8)";
-        # Requires a graphical session so the daemon knows when the screensaver
-        # starts. See the 'devicesOffOnScreensaver' option.
-        wantedBy = [ "graphical-session.target" ];
-        partOf = [ "graphical-session.target" ];
-        serviceConfig = {
-          Type = "dbus";
-          BusName = "org.razer";
-          ExecStart = "${daemonExe} --foreground";
-          Restart = "always";
+      # Requires a graphical session so the daemon knows when the screensaver
+      # starts. See the 'devicesOffOnScreensaver' option.
+      wantedBy = [ "graphical-session.target" ];
+      partOf = [ "graphical-session.target" ];
+      serviceConfig = {
+        Type = "dbus";
+        BusName = "org.razer";
+        ExecStart = "${daemonExe} --foreground";
+        Restart = "always";
       };
     };
   };
diff --git a/nixos/modules/hardware/video/intel-gpu-tools.nix b/nixos/modules/hardware/video/intel-gpu-tools.nix
new file mode 100644
index 0000000000000..b69fefcae1184
--- /dev/null
+++ b/nixos/modules/hardware/video/intel-gpu-tools.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+let
+  cfg = config.hardware.intel-gpu-tools;
+in
+{
+  options = {
+    hardware.intel-gpu-tools = {
+      enable = lib.mkEnableOption "a setcap wrapper for intel-gpu-tools";
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    security.wrappers.intel_gpu_top = {
+      owner = "root";
+      group = "root";
+      source = "${pkgs.intel-gpu-tools}/bin/intel_gpu_top";
+      capabilities = "cap_perfmon+ep";
+    };
+  };
+
+  meta = {
+    maintainers = with lib.maintainers; [ kira-bruneau ];
+  };
+}
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index ef25a7f3e75a2..4ee71ac692392 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -45,6 +45,7 @@
   ./config/xdg/portals/lxqt.nix
   ./config/xdg/portals/wlr.nix
   ./config/xdg/sounds.nix
+  ./config/xdg/terminal-exec.nix
   ./config/zram.nix
   ./hardware/acpilight.nix
   ./hardware/all-firmware.nix
@@ -106,6 +107,7 @@
   ./hardware/video/bumblebee.nix
   ./hardware/video/capture/mwprocapture.nix
   ./hardware/video/displaylink.nix
+  ./hardware/video/intel-gpu-tools.nix
   ./hardware/video/nvidia.nix
   ./hardware/video/switcheroo-control.nix
   ./hardware/video/uvcvideo/default.nix
@@ -946,6 +948,7 @@
   ./services/networking/charybdis.nix
   ./services/networking/chisel-server.nix
   ./services/networking/cjdns.nix
+  ./services/networking/clatd.nix
   ./services/networking/cloudflare-dyndns.nix
   ./services/networking/cloudflared.nix
   ./services/networking/cntlm.nix
@@ -1029,6 +1032,7 @@
   ./services/networking/jigasi.nix
   ./services/networking/jitsi-videobridge.nix
   ./services/networking/jool.nix
+  ./services/networking/jotta-cli.nix
   ./services/networking/kea.nix
   ./services/networking/keepalived/default.nix
   ./services/networking/keybase.nix
@@ -1256,8 +1260,8 @@
   ./services/security/kanidm.nix
   ./services/security/munge.nix
   ./services/security/nginx-sso.nix
-  ./services/security/oauth2_proxy.nix
-  ./services/security/oauth2_proxy_nginx.nix
+  ./services/security/oauth2-proxy.nix
+  ./services/security/oauth2-proxy-nginx.nix
   ./services/security/opensnitch.nix
   ./services/security/pass-secret-service.nix
   ./services/security/physlock.nix
diff --git a/nixos/modules/profiles/perlless.nix b/nixos/modules/profiles/perlless.nix
index 90abd14f077e4..010e4f8f2a28e 100644
--- a/nixos/modules/profiles/perlless.nix
+++ b/nixos/modules/profiles/perlless.nix
@@ -26,6 +26,6 @@
 
   # Check that the system does not contain a Nix store path that contains the
   # string "perl".
-  system.forbiddenDependenciesRegex = "perl";
+  system.forbiddenDependenciesRegexes = ["perl"];
 
 }
diff --git a/nixos/modules/programs/evince.nix b/nixos/modules/programs/evince.nix
index cffc5127f10a8..a27e75e6626de 100644
--- a/nixos/modules/programs/evince.nix
+++ b/nixos/modules/programs/evince.nix
@@ -2,28 +2,19 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 let cfg = config.programs.evince;
 
 in {
 
-  # Added 2019-08-09
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "evince" "enable" ]
-      [ "programs" "evince" "enable" ])
-  ];
-
   ###### interface
 
   options = {
 
     programs.evince = {
 
-      enable = mkEnableOption "Evince, the GNOME document viewer";
+      enable = lib.mkEnableOption "Evince, the GNOME document viewer";
 
-      package = mkPackageOption pkgs "evince" { };
+      package = lib.mkPackageOption pkgs "evince" { };
 
     };
 
@@ -32,7 +23,7 @@ in {
 
   ###### implementation
 
-  config = mkIf config.programs.evince.enable {
+  config = lib.mkIf config.programs.evince.enable {
 
     environment.systemPackages = [ cfg.package ];
 
diff --git a/nixos/modules/programs/file-roller.nix b/nixos/modules/programs/file-roller.nix
index 4799f42d630b1..f64bd732855bf 100644
--- a/nixos/modules/programs/file-roller.nix
+++ b/nixos/modules/programs/file-roller.nix
@@ -2,28 +2,19 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 let cfg = config.programs.file-roller;
 
 in {
 
-  # Added 2019-08-09
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "file-roller" "enable" ]
-      [ "programs" "file-roller" "enable" ])
-  ];
-
   ###### interface
 
   options = {
 
     programs.file-roller = {
 
-      enable = mkEnableOption "File Roller, an archive manager for GNOME";
+      enable = lib.mkEnableOption "File Roller, an archive manager for GNOME";
 
-      package = mkPackageOption pkgs [ "gnome" "file-roller" ] { };
+      package = lib.mkPackageOption pkgs [ "gnome" "file-roller" ] { };
 
     };
 
@@ -32,7 +23,7 @@ in {
 
   ###### implementation
 
-  config = mkIf cfg.enable {
+  config = lib.mkIf cfg.enable {
 
     environment.systemPackages = [ cfg.package ];
 
diff --git a/nixos/modules/programs/fish.nix b/nixos/modules/programs/fish.nix
index 2102a07cd0bca..ebc16f6ff0129 100644
--- a/nixos/modules/programs/fish.nix
+++ b/nixos/modules/programs/fish.nix
@@ -55,6 +55,8 @@ in
         type = types.bool;
       };
 
+      package = mkPackageOption pkgs "fish" { };
+
       useBabelfish = mkOption {
         type = types.bool;
         default = false;
@@ -244,8 +246,8 @@ in
           patchedGenerator = pkgs.stdenv.mkDerivation {
             name = "fish_patched-completion-generator";
             srcs = [
-              "${pkgs.fish}/share/fish/tools/create_manpage_completions.py"
-              "${pkgs.fish}/share/fish/tools/deroff.py"
+              "${cfg.package}/share/fish/tools/create_manpage_completions.py"
+              "${cfg.package}/share/fish/tools/deroff.py"
             ];
             unpackCmd = "cp $curSrc $(basename $curSrc)";
             sourceRoot = ".";
@@ -287,12 +289,12 @@ in
         ++ optional cfg.vendor.functions.enable "/share/fish/vendor_functions.d";
       }
 
-      { systemPackages = [ pkgs.fish ]; }
+      { systemPackages = [ cfg.package ]; }
 
       {
         shells = [
           "/run/current-system/sw/bin/fish"
-          "${pkgs.fish}/bin/fish"
+          (lib.getExe cfg.package)
         ];
       }
     ];
diff --git a/nixos/modules/programs/gnome-disks.nix b/nixos/modules/programs/gnome-disks.nix
index 4b128b4712650..954f1fd9bc078 100644
--- a/nixos/modules/programs/gnome-disks.nix
+++ b/nixos/modules/programs/gnome-disks.nix
@@ -2,29 +2,20 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  # Added 2019-08-09
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "gnome-disks" "enable" ]
-      [ "programs" "gnome-disks" "enable" ])
-  ];
-
   ###### interface
 
   options = {
 
     programs.gnome-disks = {
 
-      enable = mkOption {
-        type = types.bool;
+      enable = lib.mkOption {
+        type = lib.types.bool;
         default = false;
         description = ''
           Whether to enable GNOME Disks daemon, a program designed to
@@ -39,7 +30,7 @@ with lib;
 
   ###### implementation
 
-  config = mkIf config.programs.gnome-disks.enable {
+  config = lib.mkIf config.programs.gnome-disks.enable {
 
     environment.systemPackages = [ pkgs.gnome.gnome-disk-utility ];
 
diff --git a/nixos/modules/programs/gnome-terminal.nix b/nixos/modules/programs/gnome-terminal.nix
index 71a6b217880c5..a5dda83edd11f 100644
--- a/nixos/modules/programs/gnome-terminal.nix
+++ b/nixos/modules/programs/gnome-terminal.nix
@@ -2,8 +2,6 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 let
 
   cfg = config.programs.gnome-terminal;
@@ -13,21 +11,14 @@ in
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  # Added 2019-08-19
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "gnome-terminal-server" "enable" ]
-      [ "programs" "gnome-terminal" "enable" ])
-  ];
-
   options = {
-    programs.gnome-terminal.enable = mkEnableOption "GNOME Terminal";
+    programs.gnome-terminal.enable = lib.mkEnableOption "GNOME Terminal";
   };
 
-  config = mkIf cfg.enable {
+  config = lib.mkIf cfg.enable {
     environment.systemPackages = [ pkgs.gnome.gnome-terminal ];
     services.dbus.packages = [ pkgs.gnome.gnome-terminal ];
     systemd.packages = [ pkgs.gnome.gnome-terminal ];
diff --git a/nixos/modules/programs/gpaste.nix b/nixos/modules/programs/gpaste.nix
index 1c34c86eb853f..32b81434bdd94 100644
--- a/nixos/modules/programs/gpaste.nix
+++ b/nixos/modules/programs/gpaste.nix
@@ -1,22 +1,13 @@
 # GPaste.
 { config, lib, pkgs, ... }:
 
-with lib;
-
 {
 
-  # Added 2019-08-09
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "gpaste" "enable" ]
-      [ "programs" "gpaste" "enable" ])
-  ];
-
   ###### interface
   options = {
      programs.gpaste = {
-      enable = mkOption {
-        type = types.bool;
+      enable = lib.mkOption {
+        type = lib.types.bool;
         default = false;
         description = ''
           Whether to enable GPaste, a clipboard manager.
@@ -26,7 +17,7 @@ with lib;
   };
 
   ###### implementation
-  config = mkIf config.programs.gpaste.enable {
+  config = lib.mkIf config.programs.gpaste.enable {
     environment.systemPackages = [ pkgs.gnome.gpaste ];
     services.dbus.packages = [ pkgs.gnome.gpaste ];
     systemd.packages = [ pkgs.gnome.gpaste ];
diff --git a/nixos/modules/programs/seahorse.nix b/nixos/modules/programs/seahorse.nix
index c0a356bff57c1..53fff50e0a8b9 100644
--- a/nixos/modules/programs/seahorse.nix
+++ b/nixos/modules/programs/seahorse.nix
@@ -2,25 +2,15 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 {
 
- # Added 2019-08-27
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "seahorse" "enable" ]
-      [ "programs" "seahorse" "enable" ])
-  ];
-
-
   ###### interface
 
   options = {
 
     programs.seahorse = {
 
-      enable = mkEnableOption "Seahorse, a GNOME application for managing encryption keys and passwords in the GNOME Keyring";
+      enable = lib.mkEnableOption "Seahorse, a GNOME application for managing encryption keys and passwords in the GNOME Keyring";
 
     };
 
@@ -29,9 +19,9 @@ with lib;
 
   ###### implementation
 
-  config = mkIf config.programs.seahorse.enable {
+  config = lib.mkIf config.programs.seahorse.enable {
 
-    programs.ssh.askPassword = mkDefault "${pkgs.gnome.seahorse}/libexec/seahorse/ssh-askpass";
+    programs.ssh.askPassword = lib.mkDefault "${pkgs.gnome.seahorse}/libexec/seahorse/ssh-askpass";
 
     environment.systemPackages = [
       pkgs.gnome.seahorse
diff --git a/nixos/modules/programs/wayland/hyprland.nix b/nixos/modules/programs/wayland/hyprland.nix
index e648eaa1b68e4..5891ff25e4375 100644
--- a/nixos/modules/programs/wayland/hyprland.nix
+++ b/nixos/modules/programs/wayland/hyprland.nix
@@ -42,15 +42,6 @@ in
 
     xwayland.enable = mkEnableOption ("XWayland") // { default = true; };
 
-    envVars.enable = mkEnableOption null // {
-      default = true;
-      example = false;
-      description = ''
-        Set environment variables for Hyprland to work properly.
-        Enabled by default.
-      '';
-    };
-
     systemd.setPath.enable = mkEnableOption null // {
       default = true;
       example = false;
@@ -83,15 +74,6 @@ in
       configPackages = mkDefault [ cfg.finalPackage ];
     };
 
-    environment.sessionVariables = mkIf cfg.envVars.enable {
-      XDG_CURRENT_DESKTOP = "Hyprland";
-      XDG_SESSION_DESKTOP = "Hyprland";
-      XDG_SESSION_TYPE = "wayland";
-      GDK_BACKEND = "wayland,x11";
-      QT_QPA_PLATFORM = "wayland;xcb";
-      _JAVA_AWT_WM_NONREPARENTING = "1"; # Fix for Java applications on tiling window managers
-    };
-
     systemd = mkIf cfg.systemd.setPath.enable {
       user.extraConfig = ''
         DefaultEnvironment="PATH=$PATH:/run/current-system/sw/bin:/etc/profiles/per-user/%u/bin:/run/wrappers/bin"
diff --git a/nixos/modules/services/backup/restic.nix b/nixos/modules/services/backup/restic.nix
index 8b56636c79695..8be2649189b95 100644
--- a/nixos/modules/services/backup/restic.nix
+++ b/nixos/modules/services/backup/restic.nix
@@ -11,7 +11,7 @@ in
     description = ''
       Periodic backups to create with Restic.
     '';
-    type = types.attrsOf (types.submodule ({ config, name, ... }: {
+    type = types.attrsOf (types.submodule ({ name, ... }: {
       options = {
         passwordFile = mkOption {
           type = types.str;
@@ -206,12 +206,19 @@ in
           ];
         };
 
+        runCheck = mkOption {
+          type = types.bool;
+          default = (builtins.length config.services.restic.backups.${name}.checkOpts > 0);
+          defaultText = literalExpression ''builtins.length config.services.backups.${name}.checkOpts > 0'';
+          description = "Whether to run the `check` command with the provided `checkOpts` options.";
+          example = true;
+        };
+
         checkOpts = mkOption {
           type = types.listOf types.str;
           default = [ ];
           description = ''
-            A list of options for 'restic check', which is run after
-            pruning.
+            A list of options for 'restic check'.
           '';
           example = [
             "--with-cache"
@@ -298,7 +305,9 @@ in
             doBackup = (backup.dynamicFilesFrom != null) || (backup.paths != null && backup.paths != []);
             pruneCmd = optionals (builtins.length backup.pruneOpts > 0) [
               (resticCmd + " forget --prune " + (concatStringsSep " " backup.pruneOpts))
-              (resticCmd + " check " + (concatStringsSep " " backup.checkOpts))
+            ];
+            checkCmd = optionals backup.runCheck [
+                (resticCmd + " check " + (concatStringsSep " " backup.checkOpts))
             ];
             # Helper functions for rclone remotes
             rcloneRemoteName = builtins.elemAt (splitString ":" backup.repository) 1;
@@ -331,7 +340,7 @@ in
             serviceConfig = {
               Type = "oneshot";
               ExecStart = (optionals doBackup [ "${resticCmd} backup ${concatStringsSep " " (backup.extraBackupArgs ++ excludeFlags)} --files-from=${filesFromTmpFile}" ])
-                ++ pruneCmd;
+                ++ pruneCmd ++ checkCmd;
               User = backup.user;
               RuntimeDirectory = "restic-backups-${name}";
               CacheDirectory = "restic-backups-${name}";
diff --git a/nixos/modules/services/backup/znapzend.nix b/nixos/modules/services/backup/znapzend.nix
index 71e5977c44640..7f2c89edbf374 100644
--- a/nixos/modules/services/backup/znapzend.nix
+++ b/nixos/modules/services/backup/znapzend.nix
@@ -315,6 +315,14 @@ in
         '';
       };
 
+      mailErrorSummaryTo = mkOption {
+        type = singleLineStr;
+        default = "";
+        description = ''
+          Email address to send a summary to if "send task(s) failed".
+        '';
+      };
+
       noDestroy = mkOption {
         type = bool;
         default = false;
@@ -455,6 +463,8 @@ in
               "--loglevel=${cfg.logLevel}"
               (optionalString cfg.noDestroy "--nodestroy")
               (optionalString cfg.autoCreation "--autoCreation")
+              (optionalString (cfg.mailErrorSummaryTo != "")
+                "--mailErrorSummaryTo=${cfg.mailErrorSummaryTo}")
               (optionalString (enabledFeatures != [])
                 "--features=${concatStringsSep "," enabledFeatures}")
             ]; in "${pkgs.znapzend}/bin/znapzend ${args}";
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index 8a386b4848b91..8a9d8c210b34d 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -1,8 +1,31 @@
 { config, lib, pkgs, ... }:
 
-with lib;
-
 let
+  inherit (lib)
+    attrValues
+    concatMapStrings
+    concatStringsSep
+    const
+    elem
+    filterAttrs
+    isString
+    literalExpression
+    mapAttrs
+    mapAttrsToList
+    mkAfter
+    mkBefore
+    mkDefault
+    mkEnableOption
+    mkIf
+    mkMerge
+    mkOption
+    mkPackageOption
+    mkRemovedOptionModule
+    mkRenamedOptionModule
+    optionalString
+    types
+    versionAtLeast
+    ;
 
   cfg = config.services.postgresql;
 
@@ -14,7 +37,7 @@ let
       #     package = pkgs.postgresql_<major>;
       #   };
       # works.
-      base = if cfg.enableJIT then cfg.package.withJIT else cfg.package;
+      base = if cfg.enableJIT then cfg.package.withJIT else cfg.package.withoutJIT;
     in
     if cfg.extraPlugins == []
       then base
@@ -24,7 +47,7 @@ let
     if true == value then "yes"
     else if false == value then "no"
     else if isString value then "'${lib.replaceStrings ["'"] ["''"] value}'"
-    else toString value;
+    else builtins.toString value;
 
   # The main PostgreSQL configuration file.
   configFile = pkgs.writeTextDir "postgresql.conf" (concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${toStr v}") (filterAttrs (const (x: x != null)) cfg.settings)));
@@ -439,7 +462,7 @@ in
   config = mkIf cfg.enable {
 
     assertions = map ({ name, ensureDBOwnership, ... }: {
-      assertion = ensureDBOwnership -> builtins.elem name cfg.ensureDatabases;
+      assertion = ensureDBOwnership -> elem name cfg.ensureDatabases;
       message = ''
         For each database user defined with `services.postgresql.ensureUsers` and
         `ensureDBOwnership = true;`, a database with the same name must be defined
@@ -537,7 +560,7 @@ in
         # Wait for PostgreSQL to be ready to accept connections.
         postStart =
           ''
-            PSQL="psql --port=${toString cfg.settings.port}"
+            PSQL="psql --port=${builtins.toString cfg.settings.port}"
 
             while ! $PSQL -d postgres -c "" 2> /dev/null; do
                 if ! kill -0 "$MAINPID"; then exit 1; fi
diff --git a/nixos/modules/services/desktop-managers/plasma6.nix b/nixos/modules/services/desktop-managers/plasma6.nix
index 08507b4d370a7..842b0716b928d 100644
--- a/nixos/modules/services/desktop-managers/plasma6.nix
+++ b/nixos/modules/services/desktop-managers/plasma6.nix
@@ -286,6 +286,15 @@ in {
       kde-smartcard = lib.mkIf config.security.pam.p11.enable { p11Auth = true; };
     };
 
+    security.wrappers = {
+      kwin_wayland = {
+        owner = "root";
+        group = "root";
+        capabilities = "cap_sys_nice+ep";
+        source = "${lib.getBin pkgs.kdePackages.kwin}/bin/kwin_wayland";
+      };
+    };
+
     programs.dconf.enable = true;
 
     programs.firefox.nativeMessagingHosts.packages = [kdePackages.plasma-browser-integration];
diff --git a/nixos/modules/services/desktops/gnome/at-spi2-core.nix b/nixos/modules/services/desktops/gnome/at-spi2-core.nix
index 446f363fce83f..6ed5b198fe4f8 100644
--- a/nixos/modules/services/desktops/gnome/at-spi2-core.nix
+++ b/nixos/modules/services/desktops/gnome/at-spi2-core.nix
@@ -2,30 +2,19 @@
 
 { config, lib, pkgs, ... }:
 
-with lib;
-
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
   ###### interface
-
-  # Added 2021-05-07
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "at-spi2-core" "enable" ]
-      [ "services" "gnome" "at-spi2-core" "enable" ]
-    )
-  ];
-
   options = {
 
     services.gnome.at-spi2-core = {
 
-      enable = mkOption {
-        type = types.bool;
+      enable = lib.mkOption {
+        type = lib.types.bool;
         default = false;
         description = ''
           Whether to enable at-spi2-core, a service for the Assistive Technologies
@@ -43,14 +32,14 @@ with lib;
 
   ###### implementation
 
-  config = mkMerge [
-    (mkIf config.services.gnome.at-spi2-core.enable {
+  config = lib.mkMerge [
+    (lib.mkIf config.services.gnome.at-spi2-core.enable {
       environment.systemPackages = [ pkgs.at-spi2-core ];
       services.dbus.packages = [ pkgs.at-spi2-core ];
       systemd.packages = [ pkgs.at-spi2-core ];
     })
 
-    (mkIf (!config.services.gnome.at-spi2-core.enable) {
+    (lib.mkIf (!config.services.gnome.at-spi2-core.enable) {
       environment.sessionVariables = {
         NO_AT_BRIDGE = "1";
         GTK_A11Y = "none";
diff --git a/nixos/modules/services/desktops/gnome/evolution-data-server.nix b/nixos/modules/services/desktops/gnome/evolution-data-server.nix
index 34a91170d424f..a43e8dadb4212 100644
--- a/nixos/modules/services/desktops/gnome/evolution-data-server.nix
+++ b/nixos/modules/services/desktops/gnome/evolution-data-server.nix
@@ -2,44 +2,30 @@
 
 { config, lib, pkgs, ... }:
 
-with lib;
-
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  # Added 2021-05-07
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "evolution-data-server" "enable" ]
-      [ "services" "gnome" "evolution-data-server" "enable" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "evolution-data-server" "plugins" ]
-      [ "services" "gnome" "evolution-data-server" "plugins" ]
-    )
-  ];
-
   ###### interface
 
   options = {
 
     services.gnome.evolution-data-server = {
-      enable = mkEnableOption "Evolution Data Server, a collection of services for storing addressbooks and calendars";
-      plugins = mkOption {
-        type = types.listOf types.package;
+      enable = lib.mkEnableOption "Evolution Data Server, a collection of services for storing addressbooks and calendars";
+      plugins = lib.mkOption {
+        type = lib.types.listOf lib.types.package;
         default = [ ];
         description = "Plugins for Evolution Data Server.";
       };
     };
     programs.evolution = {
-      enable = mkEnableOption "Evolution, a Personal information management application that provides integrated mail, calendaring and address book functionality";
-      plugins = mkOption {
-        type = types.listOf types.package;
+      enable = lib.mkEnableOption "Evolution, a Personal information management application that provides integrated mail, calendaring and address book functionality";
+      plugins = lib.mkOption {
+        type = lib.types.listOf lib.types.package;
         default = [ ];
-        example = literalExpression "[ pkgs.evolution-ews ]";
+        example = lib.literalExpression "[ pkgs.evolution-ews ]";
         description = "Plugins for Evolution.";
       };
 
@@ -52,15 +38,15 @@ with lib;
     let
       bundle = pkgs.evolutionWithPlugins.override { inherit (config.services.gnome.evolution-data-server) plugins; };
     in
-    mkMerge [
-      (mkIf config.services.gnome.evolution-data-server.enable {
+    lib.mkMerge [
+      (lib.mkIf config.services.gnome.evolution-data-server.enable {
         environment.systemPackages = [ bundle ];
 
         services.dbus.packages = [ bundle ];
 
         systemd.packages = [ bundle ];
       })
-      (mkIf config.programs.evolution.enable {
+      (lib.mkIf config.programs.evolution.enable {
         services.gnome.evolution-data-server = {
           enable = true;
           plugins = [ pkgs.evolution ] ++ config.programs.evolution.plugins;
diff --git a/nixos/modules/services/desktops/gnome/glib-networking.nix b/nixos/modules/services/desktops/gnome/glib-networking.nix
index 1039605391ab6..905901f470841 100644
--- a/nixos/modules/services/desktops/gnome/glib-networking.nix
+++ b/nixos/modules/services/desktops/gnome/glib-networking.nix
@@ -2,29 +2,19 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  # Added 2021-05-07
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "glib-networking" "enable" ]
-      [ "services" "gnome" "glib-networking" "enable" ]
-    )
-  ];
-
   ###### interface
 
   options = {
 
     services.gnome.glib-networking = {
 
-      enable = mkEnableOption "network extensions for GLib";
+      enable = lib.mkEnableOption "network extensions for GLib";
 
     };
 
@@ -32,7 +22,7 @@ with lib;
 
   ###### implementation
 
-  config = mkIf config.services.gnome.glib-networking.enable {
+  config = lib.mkIf config.services.gnome.glib-networking.enable {
 
     services.dbus.packages = [ pkgs.glib-networking ];
 
diff --git a/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix b/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix
index 34fc24f7d5746..4f0c36883a3f5 100644
--- a/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix
+++ b/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix
@@ -9,19 +9,6 @@ in
     maintainers = teams.gnome.members;
   };
 
-  imports = [
-    # Added 2021-05-07
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "chrome-gnome-shell" "enable" ]
-      [ "services" "gnome" "gnome-browser-connector" "enable" ]
-    )
-    # Added 2022-07-25
-    (mkRenamedOptionModule
-      [ "services" "gnome" "chrome-gnome-shell" "enable" ]
-      [ "services" "gnome" "gnome-browser-connector" "enable" ]
-    )
-  ];
-
   options = {
     services.gnome.gnome-browser-connector.enable = mkEnableOption ''
       native host connector for the GNOME Shell browser extension, a DBus service
diff --git a/nixos/modules/services/desktops/gnome/gnome-initial-setup.nix b/nixos/modules/services/desktops/gnome/gnome-initial-setup.nix
index ceda49337472f..8deb12ec18bf3 100644
--- a/nixos/modules/services/desktops/gnome/gnome-initial-setup.nix
+++ b/nixos/modules/services/desktops/gnome/gnome-initial-setup.nix
@@ -2,8 +2,6 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 let
 
   # GNOME initial setup's run is conditioned on whether
@@ -45,24 +43,16 @@ in
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  # Added 2021-05-07
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "gnome-initial-setup" "enable" ]
-      [ "services" "gnome" "gnome-initial-setup" "enable" ]
-    )
-  ];
-
   ###### interface
 
   options = {
 
     services.gnome.gnome-initial-setup = {
 
-      enable = mkEnableOption "GNOME Initial Setup, a Simple, easy, and safe way to prepare a new system";
+      enable = lib.mkEnableOption "GNOME Initial Setup, a Simple, easy, and safe way to prepare a new system";
 
     };
 
@@ -71,12 +61,12 @@ in
 
   ###### implementation
 
-  config = mkIf config.services.gnome.gnome-initial-setup.enable {
+  config = lib.mkIf config.services.gnome.gnome-initial-setup.enable {
 
     environment.systemPackages = [
       pkgs.gnome.gnome-initial-setup
     ]
-    ++ optional (versionOlder config.system.stateVersion "20.03") createGisStampFilesAutostart
+    ++ lib.optional (lib.versionOlder config.system.stateVersion "20.03") createGisStampFilesAutostart
     ;
 
     systemd.packages = [
diff --git a/nixos/modules/services/desktops/gnome/gnome-keyring.nix b/nixos/modules/services/desktops/gnome/gnome-keyring.nix
index d821da164beb1..79bce0ade2fc5 100644
--- a/nixos/modules/services/desktops/gnome/gnome-keyring.nix
+++ b/nixos/modules/services/desktops/gnome/gnome-keyring.nix
@@ -2,30 +2,20 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  # Added 2021-05-07
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "gnome-keyring" "enable" ]
-      [ "services" "gnome" "gnome-keyring" "enable" ]
-    )
-  ];
-
   ###### interface
 
   options = {
 
     services.gnome.gnome-keyring = {
 
-      enable = mkOption {
-        type = types.bool;
+      enable = lib.mkOption {
+        type = lib.types.bool;
         default = false;
         description = ''
           Whether to enable GNOME Keyring daemon, a service designed to
@@ -41,7 +31,7 @@ with lib;
 
   ###### implementation
 
-  config = mkIf config.services.gnome.gnome-keyring.enable {
+  config = lib.mkIf config.services.gnome.gnome-keyring.enable {
 
     environment.systemPackages = [ pkgs.gnome.gnome-keyring ];
 
diff --git a/nixos/modules/services/desktops/gnome/gnome-online-accounts.nix b/nixos/modules/services/desktops/gnome/gnome-online-accounts.nix
index 01f7e3695cf04..de3c3789594a8 100644
--- a/nixos/modules/services/desktops/gnome/gnome-online-accounts.nix
+++ b/nixos/modules/services/desktops/gnome/gnome-online-accounts.nix
@@ -2,30 +2,20 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  # Added 2021-05-07
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "gnome-online-accounts" "enable" ]
-      [ "services" "gnome" "gnome-online-accounts" "enable" ]
-    )
-  ];
-
   ###### interface
 
   options = {
 
     services.gnome.gnome-online-accounts = {
 
-      enable = mkOption {
-        type = types.bool;
+      enable = lib.mkOption {
+        type = lib.types.bool;
         default = false;
         description = ''
           Whether to enable GNOME Online Accounts daemon, a service that provides
@@ -40,7 +30,7 @@ with lib;
 
   ###### implementation
 
-  config = mkIf config.services.gnome.gnome-online-accounts.enable {
+  config = lib.mkIf config.services.gnome.gnome-online-accounts.enable {
 
     environment.systemPackages = [ pkgs.gnome-online-accounts ];
 
diff --git a/nixos/modules/services/desktops/gnome/gnome-online-miners.nix b/nixos/modules/services/desktops/gnome/gnome-online-miners.nix
index 5f9039f68c4ee..9496752ed3a24 100644
--- a/nixos/modules/services/desktops/gnome/gnome-online-miners.nix
+++ b/nixos/modules/services/desktops/gnome/gnome-online-miners.nix
@@ -2,30 +2,20 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  # Added 2021-05-07
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "gnome-online-miners" "enable" ]
-      [ "services" "gnome" "gnome-online-miners" "enable" ]
-    )
-  ];
-
   ###### interface
 
   options = {
 
     services.gnome.gnome-online-miners = {
 
-      enable = mkOption {
-        type = types.bool;
+      enable = lib.mkOption {
+        type = lib.types.bool;
         default = false;
         description = ''
           Whether to enable GNOME Online Miners, a service that
@@ -40,7 +30,7 @@ with lib;
 
   ###### implementation
 
-  config = mkIf config.services.gnome.gnome-online-miners.enable {
+  config = lib.mkIf config.services.gnome.gnome-online-miners.enable {
 
     environment.systemPackages = [ pkgs.gnome.gnome-online-miners ];
 
diff --git a/nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix b/nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix
index b5573d2fc21bc..d81a9edfa1266 100644
--- a/nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix
+++ b/nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix
@@ -1,32 +1,36 @@
 # Remote desktop daemon using Pipewire.
 { config, lib, pkgs, ... }:
 
-with lib;
-
 {
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  # Added 2021-05-07
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "gnome-remote-desktop" "enable" ]
-      [ "services" "gnome" "gnome-remote-desktop" "enable" ]
-    )
-  ];
-
   ###### interface
   options = {
     services.gnome.gnome-remote-desktop = {
-      enable = mkEnableOption "Remote Desktop support using Pipewire";
+      enable = lib.mkEnableOption "Remote Desktop support using Pipewire";
     };
   };
 
   ###### implementation
-  config = mkIf config.services.gnome.gnome-remote-desktop.enable {
+  config = lib.mkIf config.services.gnome.gnome-remote-desktop.enable {
     services.pipewire.enable = true;
+    services.dbus.packages = [ pkgs.gnome.gnome-remote-desktop ];
+
+    environment.systemPackages = [ pkgs.gnome.gnome-remote-desktop ];
 
     systemd.packages = [ pkgs.gnome.gnome-remote-desktop ];
+    systemd.tmpfiles.packages = [ pkgs.gnome.gnome-remote-desktop ];
+
+    # TODO: if possible, switch to using provided g-r-d sysusers.d
+    users = {
+      users.gnome-remote-desktop = {
+        isSystemUser = true;
+        group = "gnome-remote-desktop";
+        home = "/var/lib/gnome-remote-desktop";
+      };
+      groups.gnome-remote-desktop = { };
+    };
   };
 }
diff --git a/nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix b/nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix
index 9c68c9b76e9ee..30b35f6690921 100644
--- a/nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix
+++ b/nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix
@@ -2,8 +2,6 @@
 
 { config, lib, pkgs, ... }:
 
-with lib;
-
 let
 
   cfg = config.services.gnome.gnome-settings-daemon;
@@ -13,28 +11,16 @@ in
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  imports = [
-    (mkRemovedOptionModule
-      ["services" "gnome3" "gnome-settings-daemon" "package"]
-      "")
-
-    # Added 2021-05-07
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "gnome-settings-daemon" "enable" ]
-      [ "services" "gnome" "gnome-settings-daemon" "enable" ]
-    )
-  ];
-
   ###### interface
 
   options = {
 
     services.gnome.gnome-settings-daemon = {
 
-      enable = mkEnableOption "GNOME Settings Daemon";
+      enable = lib.mkEnableOption "GNOME Settings Daemon";
 
     };
 
@@ -43,7 +29,7 @@ in
 
   ###### implementation
 
-  config = mkIf cfg.enable {
+  config = lib.mkIf cfg.enable {
 
     environment.systemPackages = [
       pkgs.gnome.gnome-settings-daemon
diff --git a/nixos/modules/services/desktops/gnome/gnome-user-share.nix b/nixos/modules/services/desktops/gnome/gnome-user-share.nix
index 38256af309cc5..2c6d94b7bdfc6 100644
--- a/nixos/modules/services/desktops/gnome/gnome-user-share.nix
+++ b/nixos/modules/services/desktops/gnome/gnome-user-share.nix
@@ -2,29 +2,19 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  imports = [
-    # Added 2021-05-07
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "gnome-user-share" "enable" ]
-      [ "services" "gnome" "gnome-user-share" "enable" ]
-    )
-  ];
-
   ###### interface
 
   options = {
 
     services.gnome.gnome-user-share = {
 
-      enable = mkEnableOption "GNOME User Share, a user-level file sharing service for GNOME";
+      enable = lib.mkEnableOption "GNOME User Share, a user-level file sharing service for GNOME";
 
     };
 
@@ -33,7 +23,7 @@ with lib;
 
   ###### implementation
 
-  config = mkIf config.services.gnome.gnome-user-share.enable {
+  config = lib.mkIf config.services.gnome.gnome-user-share.enable {
 
     environment.systemPackages = [
       pkgs.gnome.gnome-user-share
diff --git a/nixos/modules/services/desktops/gnome/rygel.nix b/nixos/modules/services/desktops/gnome/rygel.nix
index 8932d438cf1ec..c980b239d521e 100644
--- a/nixos/modules/services/desktops/gnome/rygel.nix
+++ b/nixos/modules/services/desktops/gnome/rygel.nix
@@ -1,38 +1,28 @@
 # rygel service.
 { config, lib, pkgs, ... }:
 
-with lib;
-
 {
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  imports = [
-    # Added 2021-05-07
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "rygel" "enable" ]
-      [ "services" "gnome" "rygel" "enable" ]
-    )
-  ];
-
   ###### interface
   options = {
     services.gnome.rygel = {
-      enable = mkOption {
+      enable = lib.mkOption {
         default = false;
         description = ''
           Whether to enable Rygel UPnP Mediaserver.
 
           You will need to also allow UPnP connections in firewall, see the following [comment](https://github.com/NixOS/nixpkgs/pull/45045#issuecomment-416030795).
         '';
-        type = types.bool;
+        type = lib.types.bool;
       };
     };
   };
 
   ###### implementation
-  config = mkIf config.services.gnome.rygel.enable {
+  config = lib.mkIf config.services.gnome.rygel.enable {
     environment.systemPackages = [ pkgs.gnome.rygel ];
 
     services.dbus.packages = [ pkgs.gnome.rygel ];
diff --git a/nixos/modules/services/desktops/gnome/sushi.nix b/nixos/modules/services/desktops/gnome/sushi.nix
index 3133a3a0d9854..946030e4bb229 100644
--- a/nixos/modules/services/desktops/gnome/sushi.nix
+++ b/nixos/modules/services/desktops/gnome/sushi.nix
@@ -2,30 +2,20 @@
 
 { config, lib, pkgs, ... }:
 
-with lib;
-
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  imports = [
-    # Added 2021-05-07
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "sushi" "enable" ]
-      [ "services" "gnome" "sushi" "enable" ]
-    )
-  ];
-
   ###### interface
 
   options = {
 
     services.gnome.sushi = {
 
-      enable = mkOption {
-        type = types.bool;
+      enable = lib.mkOption {
+        type = lib.types.bool;
         default = false;
         description = ''
           Whether to enable Sushi, a quick previewer for nautilus.
@@ -39,7 +29,7 @@ with lib;
 
   ###### implementation
 
-  config = mkIf config.services.gnome.sushi.enable {
+  config = lib.mkIf config.services.gnome.sushi.enable {
 
     environment.systemPackages = [ pkgs.gnome.sushi ];
 
diff --git a/nixos/modules/services/desktops/gnome/tracker-miners.nix b/nixos/modules/services/desktops/gnome/tracker-miners.nix
index 9351007d30b5d..d5d42cee9f8b4 100644
--- a/nixos/modules/services/desktops/gnome/tracker-miners.nix
+++ b/nixos/modules/services/desktops/gnome/tracker-miners.nix
@@ -2,30 +2,20 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  imports = [
-    # Added 2021-05-07
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "tracker-miners" "enable" ]
-      [ "services" "gnome" "tracker-miners" "enable" ]
-    )
-  ];
-
   ###### interface
 
   options = {
 
     services.gnome.tracker-miners = {
 
-      enable = mkOption {
-        type = types.bool;
+      enable = lib.mkOption {
+        type = lib.types.bool;
         default = false;
         description = ''
           Whether to enable Tracker miners, indexing services for Tracker
@@ -39,7 +29,7 @@ with lib;
 
   ###### implementation
 
-  config = mkIf config.services.gnome.tracker-miners.enable {
+  config = lib.mkIf config.services.gnome.tracker-miners.enable {
 
     environment.systemPackages = [ pkgs.tracker-miners ];
 
diff --git a/nixos/modules/services/desktops/gnome/tracker.nix b/nixos/modules/services/desktops/gnome/tracker.nix
index fef399d0112e4..45b679571c707 100644
--- a/nixos/modules/services/desktops/gnome/tracker.nix
+++ b/nixos/modules/services/desktops/gnome/tracker.nix
@@ -2,33 +2,23 @@
 
 { config, pkgs, lib, ... }:
 
-with lib;
-
 let
   cfg = config.services.gnome.tracker;
 in
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  imports = [
-    # Added 2021-05-07
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "tracker" "enable" ]
-      [ "services" "gnome" "tracker" "enable" ]
-    )
-  ];
-
   ###### interface
 
   options = {
 
     services.gnome.tracker = {
 
-      enable = mkOption {
-        type = types.bool;
+      enable = lib.mkOption {
+        type = lib.types.bool;
         default = false;
         description = ''
           Whether to enable Tracker services, a search engine,
@@ -36,8 +26,8 @@ in
         '';
       };
 
-      subcommandPackages = mkOption {
-        type = types.listOf types.package;
+      subcommandPackages = lib.mkOption {
+        type = lib.types.listOf lib.types.package;
         default = [ ];
         internal = true;
         description = ''
@@ -52,7 +42,7 @@ in
 
   ###### implementation
 
-  config = mkIf cfg.enable {
+  config = lib.mkIf cfg.enable {
 
     environment.systemPackages = [ pkgs.tracker ];
 
diff --git a/nixos/modules/services/desktops/gvfs.nix b/nixos/modules/services/desktops/gvfs.nix
index 09ac06d9f6fe0..8a02cdd4a6508 100644
--- a/nixos/modules/services/desktops/gvfs.nix
+++ b/nixos/modules/services/desktops/gvfs.nix
@@ -2,8 +2,6 @@
 
 { config, lib, pkgs, ... }:
 
-with lib;
-
 let
 
   cfg = config.services.gvfs;
@@ -13,26 +11,19 @@ in
 {
 
   meta = {
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  # Added 2019-08-19
-  imports = [
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "gvfs" "enable" ]
-      [ "services" "gvfs" "enable" ])
-  ];
-
   ###### interface
 
   options = {
 
     services.gvfs = {
 
-      enable = mkEnableOption "GVfs, a userspace virtual filesystem";
+      enable = lib.mkEnableOption "GVfs, a userspace virtual filesystem";
 
       # gvfs can be built with multiple configurations
-      package = mkPackageOption pkgs [ "gnome" "gvfs" ] { };
+      package = lib.mkPackageOption pkgs [ "gnome" "gvfs" ] { };
 
     };
 
@@ -41,7 +32,7 @@ in
 
   ###### implementation
 
-  config = mkIf cfg.enable {
+  config = lib.mkIf cfg.enable {
 
     environment.systemPackages = [ cfg.package ];
 
diff --git a/nixos/modules/services/display-managers/default.nix b/nixos/modules/services/display-managers/default.nix
index de3feb500f33b..6fa8556e39bee 100644
--- a/nixos/modules/services/display-managers/default.nix
+++ b/nixos/modules/services/display-managers/default.nix
@@ -29,12 +29,6 @@ let
         fi
       '') cfg.sessionPackages}
     '';
-
-  dmDefault = config.services.xserver.desktopManager.default;
-  # fallback default for cases when only default wm is set
-  dmFallbackDefault = if dmDefault != null then dmDefault else "none";
-  wmDefault = config.services.xserver.windowManager.default;
-  defaultSessionFromLegacyOptions = dmFallbackDefault + lib.optionalString (wmDefault != null && wmDefault != "none") "+${wmDefault}";
 in
 {
   options = {
@@ -122,17 +116,10 @@ in
             lib.assertMsg (d != null -> (lib.types.str.check d && lib.elem d config.services.displayManager.sessionData.sessionNames)) ''
                 Default graphical session, '${d}', not found.
                 Valid names for 'services.displayManager.defaultSession' are:
-                  ${lib.concatStringsSep "\n  " cfg.displayManager.sessionData.sessionNames}
+                  ${lib.concatStringsSep "\n  " cfg.sessionData.sessionNames}
               '';
         };
-        default =
-          if dmDefault != null || wmDefault != null then
-            defaultSessionFromLegacyOptions
-          else
-            null;
-        defaultText = lib.literalMD ''
-          Taken from display manager settings or window manager settings, if either is set.
-        '';
+        default = null;
         example = "gnome";
         description = ''
           Graphical session to pre-select in the session chooser (only effective for GDM, LightDM and SDDM).
@@ -192,20 +179,6 @@ in
       }
     ];
 
-    warnings =
-      lib.mkIf (dmDefault != null || wmDefault != null) [
-        ''
-          The following options are deprecated:
-            ${lib.concatStringsSep "\n  " (map ({c, t}: t) (lib.filter ({c, t}: c != null) [
-            { c = dmDefault; t = "- services.xserver.desktopManager.default"; }
-            { c = wmDefault; t = "- services.xserver.windowManager.default"; }
-            ]))}
-          Please use
-            services.displayManager.defaultSession = "${defaultSessionFromLegacyOptions}";
-          instead.
-        ''
-      ];
-
     # Make xsessions and wayland sessions available in XDG_DATA_DIRS
     # as some programs have behavior that depends on them being present
     environment.sessionVariables.XDG_DATA_DIRS = lib.mkIf (cfg.sessionPackages != [ ]) [
diff --git a/nixos/modules/services/hardware/kanata.nix b/nixos/modules/services/hardware/kanata.nix
index 333b2d2a88a55..46af3e36b9859 100644
--- a/nixos/modules/services/hardware/kanata.nix
+++ b/nixos/modules/services/hardware/kanata.nix
@@ -5,6 +5,8 @@ with lib;
 let
   cfg = config.services.kanata;
 
+  upstreamDoc = "See [the upstream documentation](https://github.com/jtroo/kanata/blob/main/docs/config.adoc) and [example config files](https://github.com/jtroo/kanata/tree/main/cfg_samples) for more information.";
+
   keyboard = {
     options = {
       devices = mkOption {
@@ -22,28 +24,16 @@ let
         type = types.lines;
         example = ''
           (defsrc
-            grv  1    2    3    4    5    6    7    8    9    0    -    =    bspc
-            tab  q    w    e    r    t    y    u    i    o    p    [    ]    \
-            caps a    s    d    f    g    h    j    k    l    ;    '    ret
-            lsft z    x    c    v    b    n    m    ,    .    /    rsft
-            lctl lmet lalt           spc            ralt rmet rctl)
-
-          (deflayer qwerty
-            grv  1    2    3    4    5    6    7    8    9    0    -    =    bspc
-            tab  q    w    e    r    t    y    u    i    o    p    [    ]    \
-            @cap a    s    d    f    g    h    j    k    l    ;    '    ret
-            lsft z    x    c    v    b    n    m    ,    .    /    rsft
-            lctl lmet lalt           spc            ralt rmet rctl)
-
-          (defalias
-            ;; tap within 100ms for capslk, hold more than 100ms for lctl
-            cap (tap-hold 100 100 caps lctl))
+            caps)
+
+          (deflayermap (default-layer)
+            ;; tap caps lock as caps lock, hold caps lock as left control
+            caps (tap-hold 100 100 caps lctl))
         '';
         description = ''
           Configuration other than `defcfg`.
 
-          See [example config files](https://github.com/jtroo/kanata)
-          for more information.
+          ${upstreamDoc}
         '';
       };
       extraDefCfg = mkOption {
@@ -55,8 +45,7 @@ let
           from the devices option) and
           `linux-continue-if-no-devs-found` (hardcoded to be yes).
 
-          See [example config files](https://github.com/jtroo/kanata)
-          for more information.
+          ${upstreamDoc}
         '';
       };
       extraArgs = mkOption {
@@ -86,14 +75,20 @@ let
     in
     optionalString ((length devices) > 0) "linux-dev (${devicesString})";
 
-  mkConfig = name: keyboard: pkgs.writeText "${mkName name}-config.kdb" ''
-    (defcfg
-      ${keyboard.extraDefCfg}
-      ${mkDevices keyboard.devices}
-      linux-continue-if-no-devs-found yes)
-
-    ${keyboard.config}
-  '';
+  mkConfig = name: keyboard: pkgs.writeTextFile {
+    name = "${mkName name}-config.kdb";
+    text = ''
+      (defcfg
+        ${keyboard.extraDefCfg}
+        ${mkDevices keyboard.devices}
+        linux-continue-if-no-devs-found yes)
+
+      ${keyboard.config}
+    '';
+    checkPhase = ''
+      ${getExe cfg.package} --cfg "$target" --check --debug
+    '';
+  };
 
   mkService = name: keyboard: nameValuePair (mkName name) {
     wantedBy = [ "multi-user.target" ];
@@ -153,7 +148,7 @@ in
   options.services.kanata = {
     enable = mkEnableOption "kanata, a tool to improve keyboard comfort and usability with advanced customization";
     package = mkPackageOption pkgs "kanata" {
-      example = "kanata-with-cmd";
+      example = [ "kanata-with-cmd" ];
       extraDescription = ''
         ::: {.note}
         If {option}`danger-enable-cmd` is enabled in any of the keyboards, the
diff --git a/nixos/modules/services/home-automation/ebusd.nix b/nixos/modules/services/home-automation/ebusd.nix
index aaf2ca1d775d5..ac9ec06639c13 100644
--- a/nixos/modules/services/home-automation/ebusd.nix
+++ b/nixos/modules/services/home-automation/ebusd.nix
@@ -4,41 +4,6 @@ with lib;
 
 let
   cfg = config.services.ebusd;
-
-  package = pkgs.ebusd;
-
-  arguments = [
-    "${package}/bin/ebusd"
-    "--foreground"
-    "--updatecheck=off"
-    "--device=${cfg.device}"
-    "--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}"
-  ] ++ lib.optionals cfg.readonly [
-    "--readonly"
-  ] ++ lib.optionals cfg.mqtt.enable [
-    "--mqtthost=${cfg.mqtt.host}"
-    "--mqttport=${toString cfg.mqtt.port}"
-    "--mqttuser=${cfg.mqtt.user}"
-    "--mqttpass=${cfg.mqtt.password}"
-  ] ++ lib.optionals cfg.mqtt.home-assistant [
-    "--mqttint=${package}/etc/ebusd/mqtt-hassio.cfg"
-    "--mqttjson"
-  ] ++ lib.optionals cfg.mqtt.retain [
-    "--mqttretain"
-  ] ++ cfg.extraArguments;
-
-  usesDev = hasPrefix "/" cfg.device;
-
-  command = concatStringsSep " " arguments;
-
 in
 {
   meta.maintainers = with maintainers; [ nathan-gs ];
@@ -46,6 +11,8 @@ in
   options.services.ebusd = {
     enable = mkEnableOption "ebusd, a daemon for communication with eBUS heating systems";
 
+    package = mkPackageOptionMD pkgs "ebusd" { };
+
     device = mkOption {
       type = types.str;
       default = "";
@@ -57,7 +24,8 @@ in
           ens:DEVICE for enhanced high speed serial device (only adapter v3 and newer with firmware since 20220731),
           DEVICE for serial device (normal speed, for all other serial adapters like adapter v2 as well as adapter v3 in non-enhanced mode), or
           [udp:]IP:PORT for network device.
-        https://github.com/john30/ebusd/wiki/2.-Run#device-options
+
+        Source: <https://github.com/john30/ebusd/wiki/2.-Run#device-options>
       '';
     };
 
@@ -81,7 +49,7 @@ in
       type = types.str;
       default = "https://cfg.ebusd.eu/";
       description = ''
-        Read CSV config files from PATH (local folder or HTTPS URL) [https://cfg.ebusd.eu/]
+        Directory to read CSV config files from. This can be a local folder or a URL.
       '';
     };
 
@@ -95,65 +63,21 @@ in
       '';
     };
 
-    logs = {
-      main = mkOption {
-        type = types.enum [ "error" "notice" "info" "debug"];
-        default = "info";
-        description = ''
-          Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice].
-        '';
-      };
-
-      network = mkOption {
-        type = types.enum [ "error" "notice" "info" "debug"];
-        default = "info";
-        description = ''
-          Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice].
-        '';
-      };
-
-      bus = mkOption {
-        type = types.enum [ "error" "notice" "info" "debug"];
-        default = "info";
-        description = ''
-          Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice].
-        '';
-      };
-
-      update = mkOption {
-        type = types.enum [ "error" "notice" "info" "debug"];
-        default = "info";
-        description = ''
-          Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice].
-        '';
-      };
-
-      other = mkOption {
-        type = types.enum [ "error" "notice" "info" "debug"];
-        default = "info";
-        description = ''
-          Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice].
-        '';
-      };
-
-      all = mkOption {
-        type = types.enum [ "error" "notice" "info" "debug"];
-        default = "info";
-        description = ''
-          Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice].
-        '';
-      };
-    };
+    logs = let
+      # "all" must come first so it can be overridden by more specific areas
+      areas = [ "all" "main" "network" "bus" "update" "other" ];
+      levels = [ "none" "error" "notice" "info" "debug" ];
+    in listToAttrs (map (area: nameValuePair area (mkOption {
+      type = types.enum levels;
+      default = "notice";
+      example = "debug";
+      description = ''
+        Only write log for matching `AREA`s (${concatStringsSep "|" areas}) below or equal to `LEVEL` (${concatStringsSep "|" levels})
+      '';
+    })) areas);
 
     mqtt = {
-
-      enable = mkOption {
-        type = types.bool;
-        default = false;
-        description = ''
-          Adds support for MQTT
-        '';
-      };
+      enable = mkEnableOption "support for MQTT";
 
       host = mkOption {
         type = types.str;
@@ -179,13 +103,7 @@ in
         '';
       };
 
-      retain = mkOption {
-        type = types.bool;
-        default = false;
-        description = ''
-          Set the retain flag on all topics instead of only selected global ones
-        '';
-      };
+      retain = mkEnableOption "set the retain flag on all topics instead of only selected global ones";
 
       user = mkOption {
         type = types.str;
@@ -200,7 +118,6 @@ in
           The MQTT password.
         '';
       };
-
     };
 
     extraArguments = mkOption {
@@ -210,25 +127,44 @@ in
         Extra arguments to the ebus daemon
       '';
     };
-
   };
 
-  config = mkIf (cfg.enable) {
-
+  config = let
+    usesDev = hasPrefix "/" cfg.device;
+  in mkIf cfg.enable {
     systemd.services.ebusd = {
       description = "EBUSd Service";
       wantedBy = [ "multi-user.target" ];
       after = [ "network.target" ];
       serviceConfig = {
-        ExecStart = command;
+        ExecStart = let
+          args = cli.toGNUCommandLineShell { } (foldr (a: b: a // b) { } [
+            {
+              inherit (cfg) device port configpath scanconfig readonly;
+              foreground = true;
+              updatecheck = "off";
+              log = mapAttrsToList (name: value: "${name}:${value}") cfg.logs;
+              mqttretain = cfg.mqtt.retain;
+            }
+            (optionalAttrs cfg.mqtt.enable {
+              mqtthost  = cfg.mqtt.host;
+              mqttport  = cfg.mqtt.port;
+              mqttuser  = cfg.mqtt.user;
+              mqttpass  = cfg.mqtt.password;
+            })
+            (optionalAttrs cfg.mqtt.home-assistant {
+              mqttint = "${cfg.package}/etc/ebusd/mqtt-hassio.cfg";
+              mqttjson = true;
+            })
+          ]);
+        in "${cfg.package}/bin/ebusd ${args} ${escapeShellArgs cfg.extraArguments}";
+
         DynamicUser = true;
         Restart = "on-failure";
 
         # Hardening
         CapabilityBoundingSet = "";
-        DeviceAllow = lib.optionals usesDev [
-          cfg.device
-        ] ;
+        DeviceAllow = optionals usesDev [ cfg.device ];
         DevicePolicy = "closed";
         LockPersonality = true;
         MemoryDenyWriteExecute = false;
@@ -254,9 +190,7 @@ in
         RestrictNamespaces = true;
         RestrictRealtime = true;
         RestrictSUIDSGID = true;
-        SupplementaryGroups = [
-          "dialout"
-        ];
+        SupplementaryGroups = [ "dialout" ];
         SystemCallArchitectures = "native";
         SystemCallFilter = [
           "@system-service @pkey"
@@ -265,6 +199,5 @@ in
         UMask = "0077";
       };
     };
-
   };
 }
diff --git a/nixos/modules/services/logging/logrotate.nix b/nixos/modules/services/logging/logrotate.nix
index 3e29828eba2f2..9344277fc1e02 100644
--- a/nixos/modules/services/logging/logrotate.nix
+++ b/nixos/modules/services/logging/logrotate.nix
@@ -224,7 +224,7 @@ in
           and users are replaced by dummy users), so tests are complemented by a
           logrotate-checkconf service that is enabled by default.
           This extra check can be disabled by disabling it at the systemd level with the
-          {option}`services.systemd.services.logrotate-checkconf.enable` option.
+          {option}`systemd.services.logrotate-checkconf.enable` option.
 
           Conversely there are still things that might make this check fail incorrectly
           (e.g. a file path where we don't have access to intermediate directories):
diff --git a/nixos/modules/services/logging/promtail.nix b/nixos/modules/services/logging/promtail.nix
index a34bc07b6ab2f..9eccd34cef234 100644
--- a/nixos/modules/services/logging/promtail.nix
+++ b/nixos/modules/services/logging/promtail.nix
@@ -41,6 +41,10 @@ in {
       wantedBy = [ "multi-user.target" ];
       stopIfChanged = false;
 
+      preStart = ''
+        ${lib.getExe pkgs.promtail} -config.file=${prettyJSON cfg.configuration} -check-syntax
+      '';
+
       serviceConfig = {
         Restart = "on-failure";
         TimeoutStopSec = 10;
diff --git a/nixos/modules/services/mail/mailman.nix b/nixos/modules/services/mail/mailman.nix
index 7e7ca7e4060ec..180c9800d7345 100644
--- a/nixos/modules/services/mail/mailman.nix
+++ b/nixos/modules/services/mail/mailman.nix
@@ -534,14 +534,11 @@ in {
               hyperkittyApiKey=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64)
               secretKey=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64)
 
-              mailmanWebCfgTmp=$(mktemp)
-              jq -n '.MAILMAN_ARCHIVER_KEY=$archiver_key | .SECRET_KEY=$secret_key' \
+              install -m 0440 -o root -g mailman \
+                <(jq -n '.MAILMAN_ARCHIVER_KEY=$archiver_key | .SECRET_KEY=$secret_key' \
                   --arg archiver_key "$hyperkittyApiKey" \
-                  --arg secret_key "$secretKey" \
-                  >"$mailmanWebCfgTmp"
-              chown root:mailman "$mailmanWebCfgTmp"
-              chmod 440 "$mailmanWebCfgTmp"
-              mv -n "$mailmanWebCfgTmp" "$mailmanWebCfg"
+                  --arg secret_key "$secretKey") \
+                "$mailmanWebCfg"
           fi
 
           hyperkittyApiKey="$(jq -r .MAILMAN_ARCHIVER_KEY "$mailmanWebCfg")"
diff --git a/nixos/modules/services/matrix/conduit.nix b/nixos/modules/services/matrix/conduit.nix
index 9b8a4f45c268f..b1d9b04242956 100644
--- a/nixos/modules/services/matrix/conduit.nix
+++ b/nixos/modules/services/matrix/conduit.nix
@@ -9,7 +9,7 @@ let
   configFile = format.generate "conduit.toml" cfg.settings;
 in
   {
-    meta.maintainers = with maintainers; [ pstn piegames ];
+    meta.maintainers = with maintainers; [ pstn ];
     options.services.matrix-conduit = {
       enable = mkEnableOption "matrix-conduit";
 
diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix
index 43568f29dd376..7b96a182f0d94 100644
--- a/nixos/modules/services/misc/gitlab.nix
+++ b/nixos/modules/services/misc/gitlab.nix
@@ -18,6 +18,8 @@ let
   gitalySocket = "${cfg.statePath}/tmp/sockets/gitaly.socket";
   pathUrlQuote = url: replaceStrings ["/"] ["%2F"] url;
 
+  gitlabVersionAtLeast = version: lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) version;
+
   databaseConfig = let
     val = {
       adapter = "postgresql";
@@ -27,10 +29,16 @@ let
       encoding = "utf8";
       pool = cfg.databasePool;
     } // cfg.extraDatabaseConfig;
-  in if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.0" then {
-    production.main = val;
-  } else {
-    production = val;
+  in {
+    production = (
+      if (gitlabVersionAtLeast "15.0")
+      then { main = val; }
+      else val
+    ) // lib.optionalAttrs (gitlabVersionAtLeast "15.9") {
+      ci = val // {
+        database_tasks = false;
+      };
+    };
   };
 
   # We only want to create a database if we're actually going to connect to it.
@@ -1168,7 +1176,7 @@ in {
         set -eu
 
         PSQL() {
-            psql --port=${toString pgsql.port} "$@"
+            psql --port=${toString pgsql.settings.port} "$@"
         }
 
         PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = '${cfg.databaseName}'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "${cfg.databaseName}" OWNER "${cfg.databaseUsername}"'
@@ -1348,7 +1356,7 @@ in {
 
             rm -f '${cfg.statePath}/config/database.yml'
 
-            ${if cfg.databasePasswordFile != null then ''
+            ${lib.optionalString (cfg.databasePasswordFile != null) ''
                 db_password="$(<'${cfg.databasePasswordFile}')"
                 export db_password
 
@@ -1356,16 +1364,24 @@ in {
                   >&2 echo "Database password was an empty string!"
                   exit 1
                 fi
+            ''}
 
-                jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \
-                   '.${if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.0" then "production.main" else "production"}.password = $ENV.db_password' \
-                   >'${cfg.statePath}/config/database.yml'
-              ''
-              else ''
-                jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \
-                   >'${cfg.statePath}/config/database.yml'
-              ''
-            }
+            # GitLab expects the `production.main` section to be the first entry in the file.
+            jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} '{
+              production: [
+                ${lib.optionalString (cfg.databasePasswordFile != null) (
+                  builtins.concatStringsSep "\n      " (
+                    [ ".production${lib.optionalString (gitlabVersionAtLeast "15.0") ".main"}.password = $ENV.db_password" ]
+                    ++ lib.optional (gitlabVersionAtLeast "15.9") "| .production.ci.password = $ENV.db_password"
+                    ++ [ "|" ]
+                  )
+                )} .production
+                | to_entries[]
+              ]
+              | sort_by(.key)
+              | reverse
+              | from_entries
+            }' >'${cfg.statePath}/config/database.yml'
 
             ${utils.genJqSecretsReplacementSnippet
                 gitlabConfig
diff --git a/nixos/modules/services/misc/heisenbridge.nix b/nixos/modules/services/misc/heisenbridge.nix
index de109e726633f..54c298f1b5602 100644
--- a/nixos/modules/services/misc/heisenbridge.nix
+++ b/nixos/modules/services/misc/heisenbridge.nix
@@ -210,5 +210,5 @@ in
     };
   };
 
-  meta.maintainers = [ lib.maintainers.piegames ];
+  meta.maintainers = [ ];
 }
diff --git a/nixos/modules/services/misc/wastebin.nix b/nixos/modules/services/misc/wastebin.nix
index 3d0af2862683d..f24bf94fa52bb 100644
--- a/nixos/modules/services/misc/wastebin.nix
+++ b/nixos/modules/services/misc/wastebin.nix
@@ -10,7 +10,7 @@ in
 
   options.services.wastebin = {
 
-    enable = mkEnableOption "Wastenbin pastebin service";
+    enable = mkEnableOption "Wastebin, a pastebin service";
 
     package = mkPackageOption pkgs "wastebin" { };
 
diff --git a/nixos/modules/services/misc/zoneminder.nix b/nixos/modules/services/misc/zoneminder.nix
index 84c3a6710c0db..d09cd87febfff 100644
--- a/nixos/modules/services/misc/zoneminder.nix
+++ b/nixos/modules/services/misc/zoneminder.nix
@@ -350,7 +350,7 @@ in {
           RestartSec = "10s";
           CacheDirectory = dirs cacheDirs;
           RuntimeDirectory = dirName;
-          ReadWriteDirectories = lib.mkIf useCustomDir [ cfg.storageDir ];
+          ReadWritePaths = lib.mkIf useCustomDir [ cfg.storageDir ];
           StateDirectory = dirs (lib.optionals (!useCustomDir) libDirs);
           LogsDirectory = dirName;
           PrivateTmp = true;
diff --git a/nixos/modules/services/monitoring/parsedmarc.nix b/nixos/modules/services/monitoring/parsedmarc.nix
index 9191a4a697e0b..a14ade59c29eb 100644
--- a/nixos/modules/services/monitoring/parsedmarc.nix
+++ b/nixos/modules/services/monitoring/parsedmarc.nix
@@ -301,7 +301,7 @@ in
               description = ''
                 The addresses to send outgoing mail to.
               '';
-              apply = x: if x == [] then null else lib.concatStringsSep "," x;
+              apply = x: if x == [] || x == null then null else lib.concatStringsSep "," x;
             };
           };
 
@@ -438,7 +438,7 @@ in
             ];
         dashboards.settings.providers = lib.mkIf cfg.provision.grafana.dashboard [{
           name = "parsedmarc";
-          options.path = "${pkgs.python3Packages.parsedmarc.dashboard}";
+          options.path = "${pkgs.parsedmarc.dashboard}";
         }];
       };
     };
@@ -446,7 +446,7 @@ in
     services.parsedmarc.settings = lib.mkMerge [
       (lib.mkIf cfg.provision.elasticsearch {
         elasticsearch = {
-          hosts = [ "localhost:9200" ];
+          hosts = [ "http://localhost:9200" ];
           ssl = false;
         };
       })
@@ -530,7 +530,7 @@ in
             MemoryDenyWriteExecute = true;
             LockPersonality = true;
             SystemCallArchitectures = "native";
-            ExecStart = "${pkgs.python3Packages.parsedmarc}/bin/parsedmarc -c /run/parsedmarc/parsedmarc.ini";
+            ExecStart = "${lib.getExe pkgs.parsedmarc} -c /run/parsedmarc/parsedmarc.ini";
           };
         };
 
diff --git a/nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix b/nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix
index e44140b1f51a0..e1b7dc91a0d77 100644
--- a/nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix
+++ b/nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix
@@ -7,6 +7,8 @@ in
 {
   port = 9332;
   extraOpts = {
+    package = lib.mkPackageOption pkgs "prometheus-bitcoin-exporter" { };
+
     rpcUser = mkOption {
       type = types.str;
       default = "bitcoinrpc";
@@ -65,7 +67,7 @@ in
   serviceOpts = {
     script = ''
       export BITCOIN_RPC_PASSWORD=$(cat ${cfg.rpcPasswordFile})
-      exec ${pkgs.prometheus-bitcoin-exporter}/bin/bitcoind-monitor.py
+      exec ${cfg.package}/bin/bitcoind-monitor.py
     '';
 
     environment = {
diff --git a/nixos/modules/services/networking/clatd.nix b/nixos/modules/services/networking/clatd.nix
new file mode 100644
index 0000000000000..de6cde4e979c0
--- /dev/null
+++ b/nixos/modules/services/networking/clatd.nix
@@ -0,0 +1,81 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.services.clatd;
+
+  settingsFormat = pkgs.formats.keyValue {};
+
+  configFile = settingsFormat.generate "clatd.conf" cfg.settings;
+in
+{
+  options = {
+    services.clatd = {
+      enable = mkEnableOption "clatd";
+
+      package = mkPackageOption pkgs "clatd" { };
+
+      settings = mkOption {
+        type = types.submodule ({ name, ... }: {
+          freeformType = settingsFormat.type;
+        });
+        default = { };
+        example = literalExpression ''
+          {
+            plat-prefix = "64:ff9b::/96";
+          }
+        '';
+        description = ''
+          Configuration of clatd. See [clatd Documentation](https://github.com/toreanderson/clatd/blob/master/README.pod#configuration).
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.clatd = {
+      description = "464XLAT CLAT daemon";
+      documentation = [ "man:clatd(8)" ];
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network-online.target" ];
+      wants = [ "network-online.target" ];
+      startLimitIntervalSec = 0;
+
+      serviceConfig = {
+        ExecStart = "${cfg.package}/bin/clatd -c ${configFile}";
+
+        # Hardening
+        CapabilityBoundingSet = [
+          "CAP_NET_ADMIN"
+        ];
+        LockPersonality = true;
+        MemoryDenyWriteExecute = true;
+        NoNewPrivileges = true;
+        PrivateTmp = true;
+        ProtectClock = true;
+        ProtectControlGroups = true;
+        ProtectHome = true;
+        ProtectHostname = true;
+        ProtectKernelLogs = true;
+        ProtectKernelModules = true;
+        ProtectProc = "invisible";
+        ProtectSystem = true;
+        RestrictAddressFamilies = [
+          "AF_INET"
+          "AF_INET6"
+          "AF_NETLINK"
+        ];
+        RestrictNamespaces = true;
+        RestrictRealtime = true;
+        RestrictSUIDSGID = true;
+        SystemCallArchitectures = "native";
+        SystemCallFilter = [
+          "@network-io"
+          "@system-service"
+          "~@privileged"
+          "~@resources"
+        ];
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/networking/jotta-cli.md b/nixos/modules/services/networking/jotta-cli.md
new file mode 100644
index 0000000000000..335e5c8e38563
--- /dev/null
+++ b/nixos/modules/services/networking/jotta-cli.md
@@ -0,0 +1,27 @@
+# Jottacloud Command-line Tool {#module-services-jotta-cli}
+
+The [Jottacloud Command-line Tool](https://docs.jottacloud.com/en/articles/1436834-jottacloud-command-line-tool) is a headless [Jottacloud](https://jottacloud.com) client.
+
+## Quick Start {#module-services-jotta-cli-quick-start}
+
+```nix
+{
+  services.jotta-cli.enable = true;
+}
+```
+
+This adds `jotta-cli` to `environment.systemPackages` and starts a user service that runs `jottad` with the default options.
+
+## Example Configuration {#module-services-jotta-cli-example-configuration}
+
+```nix
+services.jotta-cli = {
+  enable = true;
+  options = [ "slow" ];
+  package = pkgs.jotta-cli;
+};
+```
+
+This uses `jotta-cli` and `jottad` from the `pkgs.jotta-cli` package and starts `jottad` in low memory mode.
+
+`jottad` is also added to `environment.systemPackages`, so `jottad --help` can be used to explore options.
diff --git a/nixos/modules/services/networking/jotta-cli.nix b/nixos/modules/services/networking/jotta-cli.nix
new file mode 100644
index 0000000000000..e0fa1ef332fe6
--- /dev/null
+++ b/nixos/modules/services/networking/jotta-cli.nix
@@ -0,0 +1,43 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let cfg = config.services.jotta-cli;
+in {
+  options = {
+    services.jotta-cli = {
+
+      enable = mkEnableOption "Jottacloud Command-line Tool";
+
+      options = mkOption {
+        default = [ "stdoutlog" "datadir" "%h/.jottad/" ];
+        example = [ ];
+        type = with types; listOf str;
+        description = "Command-line options passed to jottad.";
+      };
+
+      package = lib.mkPackageOption pkgs "jotta-cli" { };
+    };
+  };
+  config = mkIf cfg.enable {
+    systemd.user.services.jottad = {
+
+      description = "Jottacloud Command-line Tool daemon";
+
+      serviceConfig = {
+        Type = "notify";
+        EnvironmentFile = "-%h/.config/jotta-cli/jotta-cli.env";
+        ExecStart = "${lib.getExe' cfg.package "jottad"} ${concatStringsSep " " cfg.options}";
+        Restart = "on-failure";
+      };
+
+      wantedBy = [ "default.target" ];
+      wants = [ "network-online.target" ];
+      after = [ "network-online.target" ];
+    };
+    environment.systemPackages = [ pkgs.jotta-cli ];
+  };
+
+  meta.maintainers = with lib.maintainers; [ evenbrenden ];
+  meta.doc = ./jotta-cli.md;
+}
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index e33bbb2af178f..b7143cf520f96 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -470,7 +470,7 @@ in
       -      [main]
       -      no-auto-default=*
       -    '''
-      +    extraConfig.main.no-auto-default = "*";
+      +    settings.main.no-auto-default = "*";
          };
       ```
     ''
diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix
index c62bccd462d33..0fdb708bf052f 100644
--- a/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixos/modules/services/networking/ssh/sshd.nix
@@ -296,6 +296,17 @@ in
         '';
       };
 
+      authorizedKeysInHomedir = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Enables the use of the `~/.ssh/authorized_keys` file.
+
+          Otherwise, the only files trusted by default are those in `/etc/ssh/authorized_keys.d`,
+          *i.e.* SSH keys from [](#opt-users.users._name_.openssh.authorizedKeys.keys).
+        '';
+      };
+
       authorizedKeysCommand = mkOption {
         type = types.str;
         default = "none";
@@ -635,7 +646,7 @@ in
     # https://github.com/NixOS/nixpkgs/pull/10155
     # https://github.com/NixOS/nixpkgs/pull/41745
     services.openssh.authorizedKeysFiles =
-      [ "%h/.ssh/authorized_keys" "/etc/ssh/authorized_keys.d/%u" ];
+      lib.optional cfg.authorizedKeysInHomedir "%h/.ssh/authorized_keys" ++ [ "/etc/ssh/authorized_keys.d/%u" ];
 
     services.openssh.settings.AuthorizedPrincipalsFile = mkIf (authPrincipalsFiles != {}) "/etc/ssh/authorized_principals.d/%u";
 
diff --git a/nixos/modules/services/networking/sunshine.nix b/nixos/modules/services/networking/sunshine.nix
index 0749eaee95d8a..ec78db1f3f8e9 100644
--- a/nixos/modules/services/networking/sunshine.nix
+++ b/nixos/modules/services/networking/sunshine.nix
@@ -1,6 +1,6 @@
 { config, lib, pkgs, utils, ... }:
 let
-  inherit (lib) mkEnableOption mkPackageOption mkOption mkIf mkDefault types optionals getExe;
+  inherit (lib) mkEnableOption mkPackageOption mkOption literalExpression mkIf mkDefault types optionals getExe;
   inherit (utils) escapeSystemdExecArgs;
   cfg = config.services.sunshine;
 
@@ -46,7 +46,7 @@ in
 
         See https://docs.lizardbyte.dev/projects/sunshine/en/latest/about/advanced_usage.html#configuration for syntax.
       '';
-      example = ''
+      example = literalExpression ''
         {
           sunshine_name = "nixos";
         }
@@ -67,7 +67,7 @@ in
       description = ''
         Configuration for applications to be exposed to Moonlight. If this is set, no configuration is possible from the web UI, and must be by the `settings` option.
       '';
-      example = ''
+      example = literalExpression ''
         {
           env = {
             PATH = "$(PATH):$(HOME)/.local/bin";
diff --git a/nixos/modules/services/networking/trust-dns.nix b/nixos/modules/services/networking/trust-dns.nix
index e6f8cc15819f6..039b7de263504 100644
--- a/nixos/modules/services/networking/trust-dns.nix
+++ b/nixos/modules/services/networking/trust-dns.nix
@@ -51,7 +51,7 @@ in
       package = mkPackageOption pkgs "trust-dns" {
         extraDescription = ''
           ::: {.note}
-          The package must provide `meta.mainProgram` which names the server binayr; any other utilities (client, resolver) are not needed.
+          The package must provide `meta.mainProgram` which names the server binary; any other utilities (client, resolver) are not needed.
           :::
         '';
       };
@@ -86,7 +86,7 @@ in
               type = types.listOf types.str;
               default = [ "0.0.0.0" ];
               description = ''
-              List of ipv4 addresses on which to listen for DNS queries.
+                List of ipv4 addresses on which to listen for DNS queries.
               '';
             };
             listen_addrs_ipv6 = mkOption {
@@ -114,7 +114,7 @@ in
             };
             zones = mkOption {
               description = "List of zones to serve.";
-              default = {};
+              default = [];
               type = types.listOf (types.coercedTo types.str (zone: { inherit zone; }) zoneType);
             };
           };
diff --git a/nixos/modules/services/security/oauth2_proxy_nginx.nix b/nixos/modules/services/security/oauth2-proxy-nginx.nix
index 91d846abb36e6..c05bd304752d1 100644
--- a/nixos/modules/services/security/oauth2_proxy_nginx.nix
+++ b/nixos/modules/services/security/oauth2-proxy-nginx.nix
@@ -1,56 +1,55 @@
 { config, lib, ... }:
-with lib;
 let
-  cfg = config.services.oauth2_proxy.nginx;
+  cfg = config.services.oauth2-proxy.nginx;
 in
 {
-  options.services.oauth2_proxy.nginx = {
-    proxy = mkOption {
-      type = types.str;
-      default = config.services.oauth2_proxy.httpAddress;
-      defaultText = literalExpression "config.services.oauth2_proxy.httpAddress";
+  options.services.oauth2-proxy.nginx = {
+    proxy = lib.mkOption {
+      type = lib.types.str;
+      default = config.services.oauth2-proxy.httpAddress;
+      defaultText = lib.literalExpression "config.services.oauth2-proxy.httpAddress";
       description = ''
-        The address of the reverse proxy endpoint for oauth2_proxy
+        The address of the reverse proxy endpoint for oauth2-proxy
       '';
     };
 
-    domain = mkOption {
-      type = types.str;
+    domain = lib.mkOption {
+      type = lib.types.str;
       description = ''
-        The domain under which the oauth2_proxy will be accesible and the path of cookies are set to.
+        The domain under which the oauth2-proxy will be accesible and the path of cookies are set to.
         This setting must be set to ensure back-redirects are working properly
-        if oauth2-proxy is configured with {option}`services.oauth2_proxy.cookie.domain`
-        or multiple {option}`services.oauth2_proxy.nginx.virtualHosts` that are not on the same domain.
+        if oauth2-proxy is configured with {option}`services.oauth2-proxy.cookie.domain`
+        or multiple {option}`services.oauth2-proxy.nginx.virtualHosts` that are not on the same domain.
       '';
     };
 
-    virtualHosts = mkOption {
+    virtualHosts = lib.mkOption {
       type = let
-        vhostSubmodule = types.submodule {
+        vhostSubmodule = lib.types.submodule {
           options = {
-            allowed_groups = mkOption {
-              type = types.nullOr (types.listOf types.str);
+            allowed_groups = lib.mkOption {
+              type = lib.types.nullOr (lib.types.listOf lib.types.str);
               description = "List of groups to allow access to this vhost, or null to allow all.";
               default = null;
             };
-            allowed_emails = mkOption {
-              type = types.nullOr (types.listOf types.str);
+            allowed_emails = lib.mkOption {
+              type = lib.types.nullOr (lib.types.listOf lib.types.str);
               description = "List of emails to allow access to this vhost, or null to allow all.";
               default = null;
             };
-            allowed_email_domains = mkOption {
-              type = types.nullOr (types.listOf types.str);
+            allowed_email_domains = lib.mkOption {
+              type = lib.types.nullOr (lib.types.listOf lib.types.str);
               description = "List of email domains to allow access to this vhost, or null to allow all.";
               default = null;
             };
           };
         };
-        oldType = types.listOf types.str;
+        oldType = lib.types.listOf lib.types.str;
         convertFunc = x:
-          lib.warn "services.oauth2_proxy.nginx.virtualHosts should be an attrset, found ${lib.generators.toPretty {} x}"
+          lib.warn "services.oauth2-proxy.nginx.virtualHosts should be an attrset, found ${lib.generators.toPretty {} x}"
           lib.genAttrs x (_: {});
-        newType = types.attrsOf vhostSubmodule;
-      in types.coercedTo oldType convertFunc newType;
+        newType = lib.types.attrsOf vhostSubmodule;
+      in lib.types.coercedTo oldType convertFunc newType;
       default = {};
       example = {
         "protected.foo.com" = {
@@ -65,11 +64,11 @@ in
     };
   };
 
-  config.services.oauth2_proxy = mkIf (cfg.virtualHosts != [] && (hasPrefix "127.0.0.1:" cfg.proxy)) {
+  config.services.oauth2-proxy = lib.mkIf (cfg.virtualHosts != [] && (lib.hasPrefix "127.0.0.1:" cfg.proxy)) {
     enable = true;
   };
 
-  config.services.nginx = mkIf (cfg.virtualHosts != [] && config.services.oauth2_proxy.enable) (mkMerge ([
+  config.services.nginx = lib.mkIf (cfg.virtualHosts != [] && config.services.oauth2-proxy.enable) (lib.mkMerge ([
     {
       virtualHosts.${cfg.domain}.locations."/oauth2/" = {
         proxyPass = cfg.proxy;
@@ -79,7 +78,7 @@ in
         '';
       };
     }
-  ] ++ optional (cfg.virtualHosts != []) {
+  ] ++ lib.optional (cfg.virtualHosts != []) {
     recommendedProxySettings = true; # needed because duplicate headers
   } ++ (lib.mapAttrsToList (vhost: conf: {
     virtualHosts.${vhost} = {
diff --git a/nixos/modules/services/security/oauth2_proxy.nix b/nixos/modules/services/security/oauth2-proxy.nix
index d2992a196bf87..78a772845a352 100644
--- a/nixos/modules/services/security/oauth2_proxy.nix
+++ b/nixos/modules/services/security/oauth2-proxy.nix
@@ -1,15 +1,12 @@
-# NixOS module for oauth2_proxy.
-
 { config, lib, pkgs, ... }:
 
-with lib;
 let
-  cfg = config.services.oauth2_proxy;
+  cfg = config.services.oauth2-proxy;
 
-  # oauth2_proxy provides many options that are only relevant if you are using
+  # oauth2-proxy provides many options that are only relevant if you are using
   # a certain provider. This set maps from provider name to a function that
   # takes the configuration and returns a string that can be inserted into the
-  # command-line to launch oauth2_proxy.
+  # command-line to launch oauth2-proxy.
   providerSpecificOptions = {
     azure = cfg: {
       azure-tenant = cfg.azure.tenant;
@@ -20,7 +17,7 @@ let
       inherit (cfg.github) org team;
     }; };
 
-    google = cfg: { google = with cfg.google; optionalAttrs (groups != []) {
+    google = cfg: { google = with cfg.google; lib.optionalAttrs (groups != []) {
       admin-email = adminEmail;
       service-account = serviceAccountJSON;
       group = groups;
@@ -73,28 +70,28 @@ let
   } // (getProviderOptions cfg cfg.provider) // cfg.extraConfig;
 
   mapConfig = key: attr:
-  optionalString (attr != null && attr != []) (
-    if isDerivation attr then mapConfig key (toString attr) else
-    if (builtins.typeOf attr) == "set" then concatStringsSep " "
-      (mapAttrsToList (name: value: mapConfig (key + "-" + name) value) attr) else
-    if (builtins.typeOf attr) == "list" then concatMapStringsSep " " (mapConfig key) attr else
-    if (builtins.typeOf attr) == "bool" then "--${key}=${boolToString attr}" else
+  lib.optionalString (attr != null && attr != []) (
+    if lib.isDerivation attr then mapConfig key (toString attr) else
+    if (builtins.typeOf attr) == "set" then lib.concatStringsSep " "
+      (lib.mapAttrsToList (name: value: mapConfig (key + "-" + name) value) attr) else
+    if (builtins.typeOf attr) == "list" then lib.concatMapStringsSep " " (mapConfig key) attr else
+    if (builtins.typeOf attr) == "bool" then "--${key}=${lib.boolToString attr}" else
     if (builtins.typeOf attr) == "string" then "--${key}='${attr}'" else
     "--${key}=${toString attr}");
 
-  configString = concatStringsSep " " (mapAttrsToList mapConfig allConfig);
+  configString = lib.concatStringsSep " " (lib.mapAttrsToList mapConfig allConfig);
 in
 {
-  options.services.oauth2_proxy = {
-    enable = mkEnableOption "oauth2_proxy";
+  options.services.oauth2-proxy = {
+    enable = lib.mkEnableOption "oauth2-proxy";
 
-    package = mkPackageOption pkgs "oauth2-proxy" { };
+    package = lib.mkPackageOption pkgs "oauth2-proxy" { };
 
     ##############################################
     # PROVIDER configuration
     # Taken from: https://github.com/oauth2-proxy/oauth2-proxy/blob/master/providers/providers.go
-    provider = mkOption {
-      type = types.enum [
+    provider = lib.mkOption {
+      type = lib.types.enum [
         "adfs"
         "azure"
         "bitbucket"
@@ -116,24 +113,24 @@ in
       '';
     };
 
-    approvalPrompt = mkOption {
-      type = types.enum ["force" "auto"];
+    approvalPrompt = lib.mkOption {
+      type = lib.types.enum ["force" "auto"];
       default = "force";
       description = ''
         OAuth approval_prompt.
       '';
     };
 
-    clientID = mkOption {
-      type = types.nullOr types.str;
+    clientID = lib.mkOption {
+      type = lib.types.nullOr lib.types.str;
       description = ''
         The OAuth Client ID.
       '';
       example = "123456.apps.googleusercontent.com";
     };
 
-    oidcIssuerUrl = mkOption {
-      type = types.nullOr types.str;
+    oidcIssuerUrl = lib.mkOption {
+      type = lib.types.nullOr lib.types.str;
       default = null;
       description = ''
         The OAuth issuer URL.
@@ -141,15 +138,15 @@ in
       example = "https://login.microsoftonline.com/{TENANT_ID}/v2.0";
     };
 
-    clientSecret = mkOption {
-      type = types.nullOr types.str;
+    clientSecret = lib.mkOption {
+      type = lib.types.nullOr lib.types.str;
       description = ''
         The OAuth Client Secret.
       '';
     };
 
-    skipAuthRegexes = mkOption {
-     type = types.listOf types.str;
+    skipAuthRegexes = lib.mkOption {
+     type = lib.types.listOf lib.types.str;
      default = [];
      description = ''
        Skip authentication for requests matching any of these regular
@@ -159,8 +156,8 @@ in
 
     # XXX: Not clear whether these two options are mutually exclusive or not.
     email = {
-      domains = mkOption {
-        type = types.listOf types.str;
+      domains = lib.mkOption {
+        type = lib.types.listOf lib.types.str;
         default = [];
         description = ''
           Authenticate emails with the specified domains. Use
@@ -168,8 +165,8 @@ in
         '';
       };
 
-      addresses = mkOption {
-        type = types.nullOr types.lines;
+      addresses = lib.mkOption {
+        type = lib.types.nullOr lib.types.lines;
         default = null;
         description = ''
           Line-separated email addresses that are allowed to authenticate.
@@ -177,8 +174,8 @@ in
       };
     };
 
-    loginURL = mkOption {
-      type = types.nullOr types.str;
+    loginURL = lib.mkOption {
+      type = lib.types.nullOr lib.types.str;
       default = null;
       description = ''
         Authentication endpoint.
@@ -190,8 +187,8 @@ in
       example = "https://provider.example.com/oauth/authorize";
     };
 
-    redeemURL = mkOption {
-      type = types.nullOr types.str;
+    redeemURL = lib.mkOption {
+      type = lib.types.nullOr lib.types.str;
       default = null;
       description = ''
         Token redemption endpoint.
@@ -203,8 +200,8 @@ in
       example = "https://provider.example.com/oauth/token";
     };
 
-    validateURL = mkOption {
-      type = types.nullOr types.str;
+    validateURL = lib.mkOption {
+      type = lib.types.nullOr lib.types.str;
       default = null;
       description = ''
         Access token validation endpoint.
@@ -216,10 +213,10 @@ in
       example = "https://provider.example.com/user/emails";
     };
 
-    redirectURL = mkOption {
+    redirectURL = lib.mkOption {
       # XXX: jml suspects this is always necessary, but the command-line
       # doesn't require it so making it optional.
-      type = types.nullOr types.str;
+      type = lib.types.nullOr lib.types.str;
       default = null;
       description = ''
         The OAuth2 redirect URL.
@@ -228,16 +225,16 @@ in
     };
 
     azure = {
-      tenant = mkOption {
-        type = types.str;
+      tenant = lib.mkOption {
+        type = lib.types.str;
         default = "common";
         description = ''
           Go to a tenant-specific or common (tenant-independent) endpoint.
         '';
       };
 
-      resource = mkOption {
-        type = types.str;
+      resource = lib.mkOption {
+        type = lib.types.str;
         description = ''
           The resource that is protected.
         '';
@@ -245,8 +242,8 @@ in
     };
 
     google = {
-      adminEmail = mkOption {
-        type = types.str;
+      adminEmail = lib.mkOption {
+        type = lib.types.str;
         description = ''
           The Google Admin to impersonate for API calls.
 
@@ -258,16 +255,16 @@ in
         '';
       };
 
-      groups = mkOption {
-        type = types.listOf types.str;
+      groups = lib.mkOption {
+        type = lib.types.listOf lib.types.str;
         default = [];
         description = ''
           Restrict logins to members of these Google groups.
         '';
       };
 
-      serviceAccountJSON = mkOption {
-        type = types.path;
+      serviceAccountJSON = lib.mkOption {
+        type = lib.types.path;
         description = ''
           The path to the service account JSON credentials.
         '';
@@ -275,16 +272,16 @@ in
     };
 
     github = {
-      org = mkOption {
-        type = types.nullOr types.str;
+      org = lib.mkOption {
+        type = lib.types.nullOr lib.types.str;
         default = null;
         description = ''
           Restrict logins to members of this organisation.
         '';
       };
 
-      team = mkOption {
-        type = types.nullOr types.str;
+      team = lib.mkOption {
+        type = lib.types.nullOr lib.types.str;
         default = null;
         description = ''
           Restrict logins to members of this team.
@@ -295,8 +292,8 @@ in
 
     ####################################################
     # UPSTREAM Configuration
-    upstream = mkOption {
-      type = with types; coercedTo str (x: [x]) (listOf str);
+    upstream = lib.mkOption {
+      type = with lib.types; coercedTo str (x: [x]) (listOf str);
       default = [];
       description = ''
         The http url(s) of the upstream endpoint or `file://`
@@ -304,40 +301,40 @@ in
       '';
     };
 
-    passAccessToken = mkOption {
-      type = types.bool;
+    passAccessToken = lib.mkOption {
+      type = lib.types.bool;
       default = false;
       description = ''
         Pass OAuth access_token to upstream via X-Forwarded-Access-Token header.
       '';
     };
 
-    passBasicAuth = mkOption {
-      type = types.bool;
+    passBasicAuth = lib.mkOption {
+      type = lib.types.bool;
       default = true;
       description = ''
         Pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream.
       '';
     };
 
-    basicAuthPassword = mkOption {
-      type = types.nullOr types.str;
+    basicAuthPassword = lib.mkOption {
+      type = lib.types.nullOr lib.types.str;
       default = null;
       description = ''
         The password to set when passing the HTTP Basic Auth header.
       '';
     };
 
-    passHostHeader = mkOption {
-      type = types.bool;
+    passHostHeader = lib.mkOption {
+      type = lib.types.bool;
       default = true;
       description = ''
         Pass the request Host Header to upstream.
       '';
     };
 
-    signatureKey = mkOption {
-      type = types.nullOr types.str;
+    signatureKey = lib.mkOption {
+      type = lib.types.nullOr lib.types.str;
       default = null;
       description = ''
         GAP-Signature request signature key.
@@ -346,8 +343,8 @@ in
     };
 
     cookie = {
-      domain = mkOption {
-        type = types.nullOr types.str;
+      domain = lib.mkOption {
+        type = lib.types.nullOr lib.types.str;
         default = null;
         description = ''
           Optional cookie domains to force cookies to (ie: `.yourcompany.com`).
@@ -357,33 +354,33 @@ in
         example = ".yourcompany.com";
       };
 
-      expire = mkOption {
-        type = types.str;
+      expire = lib.mkOption {
+        type = lib.types.str;
         default = "168h0m0s";
         description = ''
           Expire timeframe for cookie.
         '';
       };
 
-      httpOnly = mkOption {
-        type = types.bool;
+      httpOnly = lib.mkOption {
+        type = lib.types.bool;
         default = true;
         description = ''
           Set HttpOnly cookie flag.
         '';
       };
 
-      name = mkOption {
-        type = types.str;
+      name = lib.mkOption {
+        type = lib.types.str;
         default = "_oauth2_proxy";
         description = ''
           The name of the cookie that the oauth_proxy creates.
         '';
       };
 
-      refresh = mkOption {
+      refresh = lib.mkOption {
         # XXX: Unclear what the behavior is when this is not specified.
-        type = types.nullOr types.str;
+        type = lib.types.nullOr lib.types.str;
         default = null;
         description = ''
           Refresh the cookie after this duration; 0 to disable.
@@ -391,15 +388,15 @@ in
         example = "168h0m0s";
       };
 
-      secret = mkOption {
-        type = types.nullOr types.str;
+      secret = lib.mkOption {
+        type = lib.types.nullOr lib.types.str;
         description = ''
           The seed string for secure cookies.
         '';
       };
 
-      secure = mkOption {
-        type = types.bool;
+      secure = lib.mkOption {
+        type = lib.types.bool;
         default = true;
         description = ''
           Set secure (HTTPS) cookie flag.
@@ -410,8 +407,8 @@ in
     ####################################################
     # OAUTH2 PROXY configuration
 
-    httpAddress = mkOption {
-      type = types.str;
+    httpAddress = lib.mkOption {
+      type = lib.types.str;
       default = "http://127.0.0.1:4180";
       description = ''
         HTTPS listening address.  This module does not expose the port by
@@ -421,8 +418,8 @@ in
     };
 
     htpasswd = {
-      file = mkOption {
-        type = types.nullOr types.path;
+      file = lib.mkOption {
+        type = lib.types.nullOr lib.types.path;
         default = null;
         description = ''
           Additionally authenticate against a htpasswd file. Entries must be
@@ -430,8 +427,8 @@ in
         '';
       };
 
-      displayForm = mkOption {
-        type = types.bool;
+      displayForm = lib.mkOption {
+        type = lib.types.bool;
         default = true;
         description = ''
           Display username / password login form if an htpasswd file is provided.
@@ -439,16 +436,16 @@ in
       };
     };
 
-    customTemplatesDir = mkOption {
-      type = types.nullOr types.path;
+    customTemplatesDir = lib.mkOption {
+      type = lib.types.nullOr lib.types.path;
       default = null;
       description = ''
         Path to custom HTML templates.
       '';
     };
 
-    reverseProxy = mkOption {
-      type = types.bool;
+    reverseProxy = lib.mkOption {
+      type = lib.types.bool;
       default = false;
       description = ''
         In case when running behind a reverse proxy, controls whether headers
@@ -458,8 +455,8 @@ in
       '';
     };
 
-    proxyPrefix = mkOption {
-      type = types.str;
+    proxyPrefix = lib.mkOption {
+      type = lib.types.str;
       default = "/oauth2";
       description = ''
         The url root path that this proxy should be nested under.
@@ -467,30 +464,30 @@ in
     };
 
     tls = {
-      enable = mkOption {
-        type = types.bool;
+      enable = lib.mkOption {
+        type = lib.types.bool;
         default = false;
         description = ''
           Whether to serve over TLS.
         '';
       };
 
-      certificate = mkOption {
-        type = types.path;
+      certificate = lib.mkOption {
+        type = lib.types.path;
         description = ''
           Path to certificate file.
         '';
       };
 
-      key = mkOption {
-        type = types.path;
+      key = lib.mkOption {
+        type = lib.types.path;
         description = ''
           Path to private key file.
         '';
       };
 
-      httpsAddress = mkOption {
-        type = types.str;
+      httpsAddress = lib.mkOption {
+        type = lib.types.str;
         default = ":443";
         description = ''
           `addr:port` to listen on for HTTPS clients.
@@ -502,8 +499,8 @@ in
       };
     };
 
-    requestLogging = mkOption {
-      type = types.bool;
+    requestLogging = lib.mkOption {
+      type = lib.types.bool;
       default = true;
       description = ''
         Log requests to stdout.
@@ -514,42 +511,42 @@ in
     # UNKNOWN
 
     # XXX: Is this mandatory? Is it part of another group? Is it part of the provider specification?
-    scope = mkOption {
+    scope = lib.mkOption {
       # XXX: jml suspects this is always necessary, but the command-line
       # doesn't require it so making it optional.
-      type = types.nullOr types.str;
+      type = lib.types.nullOr lib.types.str;
       default = null;
       description = ''
         OAuth scope specification.
       '';
     };
 
-    profileURL = mkOption {
-      type = types.nullOr types.str;
+    profileURL = lib.mkOption {
+      type = lib.types.nullOr lib.types.str;
       default = null;
       description = ''
         Profile access endpoint.
       '';
     };
 
-    setXauthrequest = mkOption {
-      type = types.nullOr types.bool;
+    setXauthrequest = lib.mkOption {
+      type = lib.types.nullOr lib.types.bool;
       default = false;
       description = ''
         Set X-Auth-Request-User and X-Auth-Request-Email response headers (useful in Nginx auth_request mode). Setting this to 'null' means using the upstream default (false).
       '';
     };
 
-    extraConfig = mkOption {
+    extraConfig = lib.mkOption {
       default = {};
-      type = types.attrsOf types.anything;
+      type = lib.types.attrsOf lib.types.anything;
       description = ''
         Extra config to pass to oauth2-proxy.
       '';
     };
 
-    keyFile = mkOption {
-      type = types.nullOr types.path;
+    keyFile = lib.mkOption {
+      type = lib.types.nullOr lib.types.path;
       default = null;
       description = ''
         oauth2-proxy allows passing sensitive configuration via environment variables.
@@ -557,28 +554,30 @@ in
         OAUTH2_PROXY_CLIENT_SECRET=asdfasdfasdf.apps.googleuserscontent.com
         and specify the path here.
       '';
-      example = "/run/keys/oauth2_proxy";
+      example = "/run/keys/oauth2-proxy";
     };
-
   };
 
-  config = mkIf cfg.enable {
+  imports = [
+    (lib.mkRenamedOptionModule [ "services" "oauth2_proxy" ] [ "services" "oauth2-proxy" ])
+  ];
 
-    services.oauth2_proxy = mkIf (cfg.keyFile != null) {
-      clientID = mkDefault null;
-      clientSecret = mkDefault null;
-      cookie.secret = mkDefault null;
+  config = lib.mkIf cfg.enable {
+    services.oauth2-proxy = lib.mkIf (cfg.keyFile != null) {
+      clientID = lib.mkDefault null;
+      clientSecret = lib.mkDefault null;
+      cookie.secret = lib.mkDefault null;
     };
 
-    users.users.oauth2_proxy = {
+    users.users.oauth2-proxy = {
       description = "OAuth2 Proxy";
       isSystemUser = true;
-      group = "oauth2_proxy";
+      group = "oauth2-proxy";
     };
 
-    users.groups.oauth2_proxy = {};
+    users.groups.oauth2-proxy = {};
 
-    systemd.services.oauth2_proxy = {
+    systemd.services.oauth2-proxy = {
       description = "OAuth2 Proxy";
       path = [ cfg.package ];
       wantedBy = [ "multi-user.target" ];
@@ -586,10 +585,10 @@ in
       after = [ "network-online.target" ];
 
       serviceConfig = {
-        User = "oauth2_proxy";
+        User = "oauth2-proxy";
         Restart = "always";
         ExecStart = "${cfg.package}/bin/oauth2-proxy ${configString}";
-        EnvironmentFile = mkIf (cfg.keyFile != null) cfg.keyFile;
+        EnvironmentFile = lib.mkIf (cfg.keyFile != null) cfg.keyFile;
       };
     };
 
diff --git a/nixos/modules/services/security/step-ca.nix b/nixos/modules/services/security/step-ca.nix
index c708cb2b8910d..e9195fbd51608 100644
--- a/nixos/modules/services/security/step-ca.nix
+++ b/nixos/modules/services/security/step-ca.nix
@@ -107,7 +107,7 @@ in
           UMask = "0077";
           Environment = "HOME=%S/step-ca";
           WorkingDirectory = ""; # override upstream
-          ReadWriteDirectories = ""; # override upstream
+          ReadWritePaths = ""; # override upstream
 
           # LocalCredential handles file permission problems arising from the use of DynamicUser.
           LoadCredential = "intermediate_password:${cfg.intermediatePasswordFile}";
diff --git a/nixos/modules/services/security/vault.nix b/nixos/modules/services/security/vault.nix
index ab86da47b2e1c..650f9bda99c33 100644
--- a/nixos/modules/services/security/vault.nix
+++ b/nixos/modules/services/security/vault.nix
@@ -56,8 +56,8 @@ in
       };
 
       devRootTokenID = mkOption {
-        type = types.str;
-        default = false;
+        type = types.nullOr types.str;
+        default = null;
         description = ''
           Initial root token. This only applies when {option}`services.vault.dev` is true
         '';
diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix
index 8dba0aca64337..26f4eba707f92 100644
--- a/nixos/modules/services/system/dbus.nix
+++ b/nixos/modules/services/system/dbus.nix
@@ -147,6 +147,10 @@ in
       };
 
       systemd.services.dbus = {
+        aliases = [
+          # hack aiding to prevent dbus from restarting when switching from dbus-broker back to dbus
+          "dbus-broker.service"
+        ];
         # Don't restart dbus-daemon. Bad things tend to happen if we do.
         reloadIfChanged = true;
         restartTriggers = [
@@ -158,6 +162,10 @@ in
       };
 
       systemd.user.services.dbus = {
+        aliases = [
+          # hack aiding to prevent dbus from restarting when switching from dbus-broker back to dbus
+          "dbus-broker.service"
+        ];
         # Don't restart dbus-daemon. Bad things tend to happen if we do.
         reloadIfChanged = true;
         restartTriggers = [
@@ -184,6 +192,8 @@ in
       # https://github.com/NixOS/nixpkgs/issues/108643
       systemd.services.dbus-broker = {
         aliases = [
+          # allow other services to just depend on dbus,
+          # but also a hack aiding to prevent dbus from restarting when switching from dbus-broker back to dbus
           "dbus.service"
         ];
         unitConfig = {
@@ -203,6 +213,8 @@ in
 
       systemd.user.services.dbus-broker = {
         aliases = [
+          # allow other services to just depend on dbus,
+          # but also a hack aiding to prevent dbus from restarting when switching from dbus-broker back to dbus
           "dbus.service"
         ];
         # Don't restart dbus. Bad things tend to happen if we do.
diff --git a/nixos/modules/services/web-apps/keycloak.nix b/nixos/modules/services/web-apps/keycloak.nix
index cf1282b3d4cf4..201085daa74a8 100644
--- a/nixos/modules/services/web-apps/keycloak.nix
+++ b/nixos/modules/services/web-apps/keycloak.nix
@@ -663,7 +663,7 @@ in
             '' + ''
               export KEYCLOAK_ADMIN=admin
               export KEYCLOAK_ADMIN_PASSWORD=${escapeShellArg cfg.initialAdminPassword}
-              kc.sh start --optimized
+              kc.sh --verbose start --optimized
             '';
           };
 
diff --git a/nixos/modules/services/web-apps/nextcloud.md b/nixos/modules/services/web-apps/nextcloud.md
index ec860d307b381..0b615deae44be 100644
--- a/nixos/modules/services/web-apps/nextcloud.md
+++ b/nixos/modules/services/web-apps/nextcloud.md
@@ -205,11 +205,6 @@ it complains loudly now. So nothing actionable here by default. Alternatively yo
 * set [](#opt-services.nextcloud.settings.log_type) to "file" to be able to view logs
   from the admin panel.
 
-### Your web server is not properly set up to resolve `.well-known` URLs, failed on: `/.well-known/caldav` {#module-services-nextcloud-warning-wellknown-caldav}
-
-This warning appearing seems to be an upstream issue and is being sorted out
-in [nextcloud/server#45033](https://github.com/nextcloud/server/issues/45033).
-
 ## Maintainer information {#module-services-nextcloud-maintainer-info}
 
 As stated in the previous paragraph, we must provide a clean upgrade-path for Nextcloud
diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix
index e155c3f1ff76c..36c8d2ed6dbd4 100644
--- a/nixos/modules/services/web-apps/nextcloud.nix
+++ b/nixos/modules/services/web-apps/nextcloud.nix
@@ -1120,10 +1120,10 @@ in {
             extraConfig = ''
               absolute_redirect off;
               location = /.well-known/carddav {
-                return 301 /remote.php/dav;
+                return 301 /remote.php/dav/;
               }
               location = /.well-known/caldav {
-                return 301 /remote.php/dav;
+                return 301 /remote.php/dav/;
               }
               location ~ ^/\.well-known/(?!acme-challenge|pki-validation) {
                 return 301 /index.php$request_uri;
diff --git a/nixos/modules/services/web-apps/plausible.nix b/nixos/modules/services/web-apps/plausible.nix
index 8e49e591f75cd..1f909bbd67a36 100644
--- a/nixos/modules/services/web-apps/plausible.nix
+++ b/nixos/modules/services/web-apps/plausible.nix
@@ -276,8 +276,11 @@ in {
             ${lib.optionalString (cfg.mail.smtp.passwordFile != null)
               ''export SMTP_USER_PWD="$(< $CREDENTIALS_DIRECTORY/SMTP_USER_PWD )"''}
 
-            # setup
-            ${cfg.package}/createdb.sh
+            ${lib.optionalString cfg.database.postgres.setup ''
+              # setup
+              ${cfg.package}/createdb.sh
+            ''}
+
             ${cfg.package}/migrate.sh
             export IP_GEOLOCATION_DB=${pkgs.dbip-country-lite}/share/dbip/dbip-country-lite.mmdb
             ${cfg.package}/bin/plausible eval "(Plausible.Release.prepare() ; Plausible.Auth.create_user(\"$ADMIN_USER_NAME\", \"$ADMIN_USER_EMAIL\", \"$ADMIN_USER_PWD\"))"
@@ -326,6 +329,6 @@ in {
     ];
   };
 
-  meta.maintainers = with maintainers; [ ];
+  meta.maintainers = with maintainers; [ xanderio ];
   meta.doc = ./plausible.md;
 }
diff --git a/nixos/modules/services/web-servers/caddy/default.nix b/nixos/modules/services/web-servers/caddy/default.nix
index 08ce50bff62c0..1cd1448c7d567 100644
--- a/nixos/modules/services/web-servers/caddy/default.nix
+++ b/nixos/modules/services/web-servers/caddy/default.nix
@@ -360,6 +360,7 @@ in
       serviceConfig = let
         runOptions = ''--config ${configPath} ${optionalString (cfg.adapter != null) "--adapter ${cfg.adapter}"}'';
       in {
+        # Override the `ExecStart` line from upstream's systemd unit file by our own:
         # https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=
         # If the empty string is assigned to this option, the list of commands to start is reset, prior assignments of this option will have no effect.
         ExecStart = [ "" ''${cfg.package}/bin/caddy run ${runOptions} ${optionalString cfg.resume "--resume"}'' ];
@@ -367,7 +368,7 @@ in
         ExecReload = [ "" ''${cfg.package}/bin/caddy reload ${runOptions} --force'' ];
         User = cfg.user;
         Group = cfg.group;
-        ReadWriteDirectories = cfg.dataDir;
+        ReadWritePaths = [ cfg.dataDir ];
         StateDirectory = mkIf (cfg.dataDir == "/var/lib/caddy") [ "caddy" ];
         LogsDirectory = mkIf (cfg.logDir == "/var/log/caddy") [ "caddy" ];
         Restart = "on-failure";
diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix
index 337d53e869efe..08fab09e1e559 100644
--- a/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixos/modules/services/web-servers/nginx/default.nix
@@ -352,7 +352,8 @@ let
 
         # The acme-challenge location doesn't need to be added if we are not using any automated
         # certificate provisioning and can also be omitted when we use a certificate obtained via a DNS-01 challenge
-        acmeLocation = optionalString (vhost.enableACME || (vhost.useACMEHost != null && config.security.acme.certs.${vhost.useACMEHost}.dnsProvider == null))
+        acmeName = if vhost.useACMEHost != null then vhost.useACMEHost else vhostName;
+        acmeLocation = optionalString ((vhost.enableACME || vhost.useACMEHost != null) && config.security.acme.certs.${acmeName}.dnsProvider == null)
           # Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx)
           # We use ^~ here, so that we don't check any regexes (which could
           # otherwise easily override this intended match accidentally).
diff --git a/nixos/modules/services/web-servers/traefik.nix b/nixos/modules/services/web-servers/traefik.nix
index 9c53455bcf3d7..1a65ce21112ee 100644
--- a/nixos/modules/services/web-servers/traefik.nix
+++ b/nixos/modules/services/web-servers/traefik.nix
@@ -170,7 +170,7 @@ in {
         PrivateDevices = true;
         ProtectHome = true;
         ProtectSystem = "full";
-        ReadWriteDirectories = cfg.dataDir;
+        ReadWritePaths = [ cfg.dataDir ];
         RuntimeDirectory = "traefik";
       };
     };
diff --git a/nixos/modules/services/x11/desktop-managers/cinnamon.nix b/nixos/modules/services/x11/desktop-managers/cinnamon.nix
index 482527d1e8ad5..2e0eef67c0b3e 100644
--- a/nixos/modules/services/x11/desktop-managers/cinnamon.nix
+++ b/nixos/modules/services/x11/desktop-managers/cinnamon.nix
@@ -157,6 +157,7 @@ in
 
         # packages
         nemo-with-extensions
+        gnome-online-accounts-gtk
         cinnamon-control-center
         cinnamon-settings-daemon
         libgnomekbd
diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix
index 6fe606f92267b..42e66e86e1a35 100644
--- a/nixos/modules/services/x11/desktop-managers/default.nix
+++ b/nixos/modules/services/x11/desktop-managers/default.nix
@@ -1,8 +1,7 @@
 { config, lib, pkgs, ... }:
 
-with lib;
-
 let
+  inherit (lib) mkOption types;
 
   xcfg = config.services.xserver;
   cfg = xcfg.desktopManager;
@@ -59,7 +58,7 @@ in
       session = mkOption {
         internal = true;
         default = [];
-        example = singleton
+        example = lib.singleton
           { name = "kde";
             bgSupport = true;
             start = "...";
@@ -73,26 +72,15 @@ in
           manage = "desktop";
           start = d.start
           # literal newline to ensure d.start's last line is not appended to
-          + optionalString (needBGCond d) ''
+          + lib.optionalString (needBGCond d) ''
 
             if [ -e $HOME/.background-image ]; then
-              ${pkgs.feh}/bin/feh --bg-${cfg.wallpaper.mode} ${optionalString cfg.wallpaper.combineScreens "--no-xinerama"} $HOME/.background-image
+              ${pkgs.feh}/bin/feh --bg-${cfg.wallpaper.mode} ${lib.optionalString cfg.wallpaper.combineScreens "--no-xinerama"} $HOME/.background-image
             fi
           '';
         });
       };
 
-      default = mkOption {
-        type = types.nullOr types.str;
-        default = null;
-        example = "none";
-        description = ''
-          **Deprecated**, please use [](#opt-services.displayManager.defaultSession) instead.
-
-          Default desktop manager loaded if none have been chosen.
-        '';
-      };
-
     };
 
   };
diff --git a/nixos/modules/services/x11/desktop-managers/gnome.nix b/nixos/modules/services/x11/desktop-managers/gnome.nix
index a0cf56e7a920d..fe50d930b5af0 100644
--- a/nixos/modules/services/x11/desktop-managers/gnome.nix
+++ b/nixos/modules/services/x11/desktop-managers/gnome.nix
@@ -1,8 +1,7 @@
 { config, lib, pkgs, utils, ... }:
 
-with lib;
-
 let
+  inherit (lib) mkOption types mkDefault mkEnableOption literalExpression;
 
   cfg = config.services.xserver.desktopManager.gnome;
   serviceCfg = config.services.gnome;
@@ -51,8 +50,8 @@ let
     destination = "/share/gnome-background-properties/nixos.xml";
   };
 
-  flashbackEnabled = cfg.flashback.enableMetacity || length cfg.flashback.customSessions > 0;
-  flashbackWms = optional cfg.flashback.enableMetacity {
+  flashbackEnabled = cfg.flashback.enableMetacity || lib.length cfg.flashback.customSessions > 0;
+  flashbackWms = lib.optional cfg.flashback.enableMetacity {
     wmName = "metacity";
     wmLabel = "Metacity";
     wmCommand = "${pkgs.gnome.metacity}/bin/metacity";
@@ -67,73 +66,9 @@ in
 
   meta = {
     doc = ./gnome.md;
-    maintainers = teams.gnome.members;
+    maintainers = lib.teams.gnome.members;
   };
 
-  imports = [
-    # Added 2021-05-07
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "core-os-services" "enable" ]
-      [ "services" "gnome" "core-os-services" "enable" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "core-shell" "enable" ]
-      [ "services" "gnome" "core-shell" "enable" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "core-utilities" "enable" ]
-      [ "services" "gnome" "core-utilities" "enable" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "core-developer-tools" "enable" ]
-      [ "services" "gnome" "core-developer-tools" "enable" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "games" "enable" ]
-      [ "services" "gnome" "games" "enable" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "gnome3" "experimental-features" "realtime-scheduling" ]
-      [ "services" "gnome" "experimental-features" "realtime-scheduling" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "xserver" "desktopManager" "gnome3" "enable" ]
-      [ "services" "xserver" "desktopManager" "gnome" "enable" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "xserver" "desktopManager" "gnome3" "sessionPath" ]
-      [ "services" "xserver" "desktopManager" "gnome" "sessionPath" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "xserver" "desktopManager" "gnome3" "favoriteAppsOverride" ]
-      [ "services" "xserver" "desktopManager" "gnome" "favoriteAppsOverride" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "xserver" "desktopManager" "gnome3" "extraGSettingsOverrides" ]
-      [ "services" "xserver" "desktopManager" "gnome" "extraGSettingsOverrides" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "xserver" "desktopManager" "gnome3" "extraGSettingsOverridePackages" ]
-      [ "services" "xserver" "desktopManager" "gnome" "extraGSettingsOverridePackages" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "xserver" "desktopManager" "gnome3" "debug" ]
-      [ "services" "xserver" "desktopManager" "gnome" "debug" ]
-    )
-    (mkRenamedOptionModule
-      [ "services" "xserver" "desktopManager" "gnome3" "flashback" ]
-      [ "services" "xserver" "desktopManager" "gnome" "flashback" ]
-    )
-    (mkRenamedOptionModule
-      [ "environment" "gnome3" "excludePackages" ]
-      [ "environment" "gnome" "excludePackages" ]
-    )
-    (mkRemovedOptionModule
-      [ "services" "gnome" "experimental-features" "realtime-scheduling" ]
-      "Set `security.rtkit.enable = true;` to make realtime scheduling possible. (Still needs to be enabled using GSettings.)"
-    )
-  ];
-
   options = {
 
     services.gnome = {
@@ -248,8 +183,8 @@ in
 
   };
 
-  config = mkMerge [
-    (mkIf (cfg.enable || flashbackEnabled) {
+  config = lib.mkMerge [
+    (lib.mkIf (cfg.enable || flashbackEnabled) {
       # Seed our configuration into nixos-generate-config
       system.nixos-generate-config.desktopConfiguration = [''
         # Enable the GNOME Desktop Environment.
@@ -264,7 +199,7 @@ in
       services.displayManager.sessionPackages = [ pkgs.gnome.gnome-session.sessions ];
 
       environment.extraInit = ''
-        ${concatMapStrings (p: ''
+        ${lib.concatMapStrings (p: ''
           if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then
             export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name}
           fi
@@ -278,19 +213,19 @@ in
 
       environment.systemPackages = cfg.sessionPath;
 
-      environment.sessionVariables.GNOME_SESSION_DEBUG = mkIf cfg.debug "1";
+      environment.sessionVariables.GNOME_SESSION_DEBUG = lib.mkIf cfg.debug "1";
 
       # Override GSettings schemas
       environment.sessionVariables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
     })
 
-    (mkIf flashbackEnabled {
+    (lib.mkIf flashbackEnabled {
       services.displayManager.sessionPackages =
         let
           wmNames = map (wm: wm.wmName) flashbackWms;
           namesAreUnique = lib.unique wmNames == wmNames;
         in
-          assert (assertMsg namesAreUnique "Flashback WM names must be unique.");
+          assert (lib.assertMsg namesAreUnique "Flashback WM names must be unique.");
           map
             (wm:
               pkgs.gnome.gnome-flashback.mkSessionForWm {
@@ -318,7 +253,7 @@ in
       ++ (map (wm: gnome-flashback.mkGnomeSession { inherit (wm) wmName wmLabel enableGnomePanel; }) flashbackWms);
     })
 
-    (mkIf serviceCfg.core-os-services.enable {
+    (lib.mkIf serviceCfg.core-os-services.enable {
       hardware.bluetooth.enable = mkDefault true;
       hardware.pulseaudio.enable = mkDefault true;
       programs.dconf.enable = true;
@@ -371,7 +306,7 @@ in
       ];
     })
 
-    (mkIf serviceCfg.core-shell.enable {
+    (lib.mkIf serviceCfg.core-shell.enable {
       services.xserver.desktopManager.gnome.sessionPath =
         let
           mandatoryPackages = [
@@ -393,7 +328,7 @@ in
       services.gnome.gnome-user-share.enable = mkDefault true;
       services.gnome.rygel.enable = mkDefault true;
       services.gvfs.enable = true;
-      services.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true));
+      services.system-config-printer.enable = (lib.mkIf config.services.printing.enable (mkDefault true));
 
       systemd.packages = with pkgs.gnome; [
         gnome-session
@@ -408,10 +343,6 @@ in
 
       services.avahi.enable = mkDefault true;
 
-      xdg.portal.extraPortals = [
-        pkgs.gnome.gnome-shell
-      ];
-
       services.geoclue2.enable = mkDefault true;
       services.geoclue2.enableDemoAgent = false; # GNOME has its own geoclue agent
 
@@ -463,7 +394,7 @@ in
     })
 
     # Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/-/blob/gnome-45/elements/core/meta-gnome-core-utilities.bst
-    (mkIf serviceCfg.core-utilities.enable {
+    (lib.mkIf serviceCfg.core-utilities.enable {
       environment.systemPackages =
         with pkgs.gnome;
         utils.removePackagesByName
@@ -524,7 +455,7 @@ in
       ];
     })
 
-    (mkIf serviceCfg.games.enable {
+    (lib.mkIf serviceCfg.games.enable {
       environment.systemPackages = with pkgs.gnome; utils.removePackagesByName [
         aisleriot
         atomix
@@ -550,7 +481,7 @@ in
     })
 
     # Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/-/blob/3.38.0/elements/core/meta-gnome-core-developer-tools.bst
-    (mkIf serviceCfg.core-developer-tools.enable {
+    (lib.mkIf serviceCfg.core-developer-tools.enable {
       environment.systemPackages = with pkgs.gnome; utils.removePackagesByName [
         dconf-editor
         devhelp
diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix
index 0f9b712c6df53..87331a6658d34 100644
--- a/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixos/modules/services/x11/display-managers/default.nix
@@ -9,9 +9,8 @@
 
 { config, lib, options, pkgs, ... }:
 
-with lib;
-
 let
+  inherit (lib) mkOption types literalExpression optionalString;
 
   cfg = config.services.xserver;
   xorg = pkgs.xorg;
@@ -91,7 +90,7 @@ let
       # Import environment variables into the systemd user environment.
       ${optionalString (cfg.displayManager.importedVariables != []) (
         "/run/current-system/systemd/bin/systemctl --user import-environment "
-          + toString (unique cfg.displayManager.importedVariables)
+          + toString (lib.unique cfg.displayManager.importedVariables)
       )}
 
       # Speed up application start by 50-150ms according to
@@ -222,13 +221,6 @@ in
   };
 
   config = {
-    assertions = [
-      {
-        assertion = cfg.desktopManager.default != null || cfg.windowManager.default != null -> cfg.displayManager.defaultSession == defaultSessionFromLegacyOptions;
-        message = "You cannot use both services.displayManager.defaultSession option and legacy options (services.xserver.desktopManager.default and services.xserver.windowManager.default).";
-      }
-    ];
-
     services.displayManager.sessionData.wrapper = xsessionWrapper;
 
     services.xserver.displayManager.xserverBin = "${xorg.xorgserver.out}/bin/X";
@@ -254,8 +246,8 @@ in
     # that do not have upstream session files (those defined using services.{display,desktop,window}Manager.session options).
     services.displayManager.sessionPackages =
       let
-        dms = filter (s: s.manage == "desktop") cfg.displayManager.session;
-        wms = filter (s: s.manage == "window") cfg.displayManager.session;
+        dms = lib.filter (s: s.manage == "desktop") cfg.displayManager.session;
+        wms = lib.filter (s: s.manage == "window") cfg.displayManager.session;
 
         # Script responsible for starting the window manager and the desktop manager.
         xsession = dm: wm: pkgs.writeScript "xsession" ''
@@ -283,16 +275,16 @@ in
         '';
       in
         # We will generate every possible pair of WM and DM.
-        concatLists (
+        lib.concatLists (
             lib.mapCartesianProduct
             ({dm, wm}: let
               sessionName = "${dm.name}${optionalString (wm.name != "none") ("+" + wm.name)}";
               script = xsession dm wm;
               desktopNames = if dm ? desktopNames
-                             then concatStringsSep ";" dm.desktopNames
+                             then lib.concatStringsSep ";" dm.desktopNames
                              else sessionName;
             in
-              optional (dm.name != "none" || wm.name != "none")
+              lib.optional (dm.name != "none" || wm.name != "none")
                 (pkgs.writeTextFile {
                   name = "${sessionName}-xsession";
                   destination = "/share/xsessions/${sessionName}.desktop";
@@ -317,11 +309,11 @@ in
   };
 
   imports = [
-    (mkRemovedOptionModule [ "services" "xserver" "displayManager" "desktopManagerHandlesLidAndPower" ]
+    (lib.mkRemovedOptionModule [ "services" "xserver" "displayManager" "desktopManagerHandlesLidAndPower" ]
      "The option is no longer necessary because all display managers have already delegated lid management to systemd.")
-    (mkRenamedOptionModule [ "services" "xserver" "displayManager" "job" "logsXsession" ] [ "services" "displayManager" "logToFile" ])
-    (mkRenamedOptionModule [ "services" "xserver" "displayManager" "logToJournal" ] [ "services" "displayManager" "logToJournal" ])
-    (mkRenamedOptionModule [ "services" "xserver" "displayManager" "extraSessionFilesPackages" ] [ "services" "displayManager" "sessionPackages" ])
+    (lib.mkRenamedOptionModule [ "services" "xserver" "displayManager" "job" "logsXsession" ] [ "services" "displayManager" "logToFile" ])
+    (lib.mkRenamedOptionModule [ "services" "xserver" "displayManager" "logToJournal" ] [ "services" "displayManager" "logToJournal" ])
+    (lib.mkRenamedOptionModule [ "services" "xserver" "displayManager" "extraSessionFilesPackages" ] [ "services" "displayManager" "sessionPackages" ])
   ];
 
 }
diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix
index ec54e4cc12a9e..85eb4c6614d94 100644
--- a/nixos/modules/services/x11/window-managers/default.nix
+++ b/nixos/modules/services/x11/window-managers/default.nix
@@ -1,8 +1,7 @@
 { config, lib, ... }:
 
-with lib;
-
 let
+  inherit (lib) mkOption types;
   cfg = config.services.xserver.windowManager;
 in
 
@@ -72,17 +71,6 @@ in
         });
       };
 
-      default = mkOption {
-        type = types.nullOr types.str;
-        default = null;
-        example = "wmii";
-        description = ''
-          **Deprecated**, please use [](#opt-services.displayManager.defaultSession) instead.
-
-          Default window manager loaded if none have been chosen.
-        '';
-      };
-
     };
 
   };
diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl
index ba45231465fb4..cabc1dcc2d65a 100755
--- a/nixos/modules/system/activation/switch-to-configuration.pl
+++ b/nixos/modules/system/activation/switch-to-configuration.pl
@@ -472,6 +472,9 @@ sub handle_modified_unit { ## no critic(Subroutines::ProhibitManyArgs, Subroutin
             $units_to_reload->{$unit} = 1;
             record_unit($reload_list_file, $unit);
         }
+        elsif ($unit eq "dbus.service" || $unit eq "dbus-broker.service") {
+            # dbus service should only ever be reloaded, not started/stoped/restarted as that would break the system.
+        }
         elsif (!parse_systemd_bool(\%new_unit_info, "Service", "X-RestartIfChanged", 1) || parse_systemd_bool(\%new_unit_info, "Unit", "RefuseManualStop", 0) || parse_systemd_bool(\%new_unit_info, "Unit", "X-OnlyManualStart", 0)) {
             $units_to_skip->{$unit} = 1;
         } else {
diff --git a/nixos/modules/system/activation/test.nix b/nixos/modules/system/activation/test.nix
index 8cf000451c6e3..fd251d5289579 100644
--- a/nixos/modules/system/activation/test.nix
+++ b/nixos/modules/system/activation/test.nix
@@ -5,7 +5,7 @@
 }:
 let
   node-forbiddenDependencies-fail = nixos ({ ... }: {
-    system.forbiddenDependenciesRegex = "-dev$";
+    system.forbiddenDependenciesRegexes = ["-dev$"];
     environment.etc."dev-dependency" = {
       text = "${expect.dev}";
     };
@@ -14,7 +14,7 @@ let
     boot.loader.grub.enable = false;
   });
   node-forbiddenDependencies-succeed = nixos ({ ... }: {
-    system.forbiddenDependenciesRegex = "-dev$";
+    system.forbiddenDependenciesRegexes = ["-dev$"];
     system.extraDependencies = [ expect.dev ];
     documentation.enable = false;
     fileSystems."/".device = "ignore-root-device";
diff --git a/nixos/modules/system/activation/top-level.nix b/nixos/modules/system/activation/top-level.nix
index 4cf3012646fa3..ed0ece19f2fa2 100644
--- a/nixos/modules/system/activation/top-level.nix
+++ b/nixos/modules/system/activation/top-level.nix
@@ -86,6 +86,7 @@ in
     ../build.nix
     (mkRemovedOptionModule [ "nesting" "clone" ] "Use `specialisation.«name» = { inheritParentConfig = true; configuration = { ... }; }` instead.")
     (mkRemovedOptionModule [ "nesting" "children" ] "Use `specialisation.«name».configuration = { ... }` instead.")
+    (mkRenamedOptionModule [ "system" "forbiddenDependenciesRegex" ] [ "system" "forbiddenDependenciesRegexes" ])
   ];
 
   options = {
@@ -160,12 +161,12 @@ in
       '';
     };
 
-    system.forbiddenDependenciesRegex = mkOption {
-      default = "";
-      example = "-dev$";
-      type = types.str;
+    system.forbiddenDependenciesRegexes = mkOption {
+      default = [];
+      example = ["-dev$"];
+      type = types.listOf types.str;
       description = ''
-        A POSIX Extended Regular Expression that matches store paths that
+        POSIX Extended Regular Expressions that match store paths that
         should not appear in the system closure, with the exception of {option}`system.extraDependencies`, which is not checked.
       '';
     };
@@ -289,15 +290,14 @@ in
             "$out/configuration.nix"
         '' +
       optionalString
-        (config.system.forbiddenDependenciesRegex != "")
-        ''
-          if [[ $forbiddenDependenciesRegex != "" && -n $closureInfo ]]; then
-            if forbiddenPaths="$(grep -E -- "$forbiddenDependenciesRegex" $closureInfo/store-paths)"; then
+        (config.system.forbiddenDependenciesRegexes != []) (lib.concatStringsSep "\n" (map (regex: ''
+          if [[ ${regex} != "" && -n $closureInfo ]]; then
+            if forbiddenPaths="$(grep -E -- "${regex}" $closureInfo/store-paths)"; then
               echo -e "System closure $out contains the following disallowed paths:\n$forbiddenPaths"
               exit 1
             fi
           fi
-        '';
+        '') config.system.forbiddenDependenciesRegexes));
 
     system.systemBuilderArgs = {
 
@@ -319,8 +319,7 @@ in
       # option, as opposed to `system.extraDependencies`.
       passedChecks = concatStringsSep " " config.system.checks;
     }
-    // lib.optionalAttrs (config.system.forbiddenDependenciesRegex != "") {
-      inherit (config.system) forbiddenDependenciesRegex;
+    // lib.optionalAttrs (config.system.forbiddenDependenciesRegexes != []) {
       closureInfo = pkgs.closureInfo { rootPaths = [
         # override to avoid  infinite recursion (and to allow using extraDependencies to add forbidden dependencies)
         (config.system.build.toplevel.overrideAttrs (_: { extraDependencies = []; closureInfo = null; }))
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index fe340cfaedb67..9c36651d68747 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -6,7 +6,6 @@ let
     concatMap
     concatMapStrings
     concatStrings
-    concatStringsSep
     escapeShellArg
     flip
     foldr
@@ -491,10 +490,10 @@ in
 
       theme = mkOption {
         type = types.nullOr types.path;
-        example = literalExpression "pkgs.nixos-grub2-theme";
+        example = literalExpression ''"''${pkgs.libsForQt5.breeze-grub}/grub/themes/breeze"'';
         default = null;
         description = ''
-          Grub theme to be used.
+          Path to the grub theme to be used.
         '';
       };
 
diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix
index 65620dd3935b8..c3639f660dfe3 100644
--- a/nixos/modules/virtualisation/containers.nix
+++ b/nixos/modules/virtualisation/containers.nix
@@ -53,13 +53,6 @@ in
 
     storage.settings = mkOption {
       type = toml.type;
-      default = {
-        storage = {
-          driver = "overlay";
-          graphroot = "/var/lib/containers/storage";
-          runroot = "/run/containers/storage";
-        };
-      };
       description = "storage.conf configuration";
     };
 
@@ -124,6 +117,12 @@ in
       };
     };
 
+    virtualisation.containers.storage.settings.storage = {
+      driver = lib.mkDefault "overlay";
+      graphroot = lib.mkDefault "/var/lib/containers/storage";
+      runroot = lib.mkDefault "/run/containers/storage";
+    };
+
     environment.etc = {
       "containers/containers.conf".source =
         toml.generate "containers.conf" cfg.containersConf.settings;
diff --git a/nixos/modules/virtualisation/incus.nix b/nixos/modules/virtualisation/incus.nix
index 2d7ccac7d92c8..4d04853d20a56 100644
--- a/nixos/modules/virtualisation/incus.nix
+++ b/nixos/modules/virtualisation/incus.nix
@@ -9,7 +9,7 @@ let
   cfg = config.virtualisation.incus;
   preseedFormat = pkgs.formats.yaml { };
 
-  serverBinPath = ''${pkgs.qemu_kvm}/libexec:${
+  serverBinPath = ''/run/wrappers/bin:${pkgs.qemu_kvm}/libexec:${
     lib.makeBinPath (
       with pkgs;
       [
@@ -33,30 +33,41 @@ let
         gzip
         iproute2
         iptables
+        iw
         kmod
+        libnvidia-container
+        libxfs
         lvm2
         minio
+        minio-client
         nftables
-        qemu_kvm
         qemu-utils
+        qemu_kvm
         rsync
+        squashfs-tools-ng
         squashfsTools
+        sshfs
         swtpm
         systemd
         thin-provisioning-tools
         util-linux
         virtiofsd
+        xdelta
         xz
+      ]
+      ++ lib.optionals config.security.apparmor.enable [
+        apparmor-bin-utils
 
         (writeShellScriptBin "apparmor_parser" ''
           exec '${apparmor-parser}/bin/apparmor_parser' -I '${apparmor-profiles}/etc/apparmor.d' "$@"
         '')
       ]
+      ++ lib.optionals config.services.ceph.client.enable [ ceph-client ]
+      ++ lib.optionals config.virtualisation.vswitch.enable [ config.virtualisation.vswitch.package ]
       ++ lib.optionals config.boot.zfs.enabled [
         config.boot.zfs.package
         "${config.boot.zfs.package}/lib/udev"
       ]
-      ++ lib.optionals config.virtualisation.vswitch.enable [ config.virtualisation.vswitch.package ]
     )
   }'';
 
diff --git a/nixos/modules/virtualisation/podman/default.nix b/nixos/modules/virtualisation/podman/default.nix
index 4b1b67ac9444e..deb0b4d2c5bd7 100644
--- a/nixos/modules/virtualisation/podman/default.nix
+++ b/nixos/modules/virtualisation/podman/default.nix
@@ -219,6 +219,11 @@ in
       systemd.services.podman.environment = config.networking.proxy.envVars;
       systemd.sockets.podman.wantedBy = [ "sockets.target" ];
       systemd.sockets.podman.socketConfig.SocketGroup = "podman";
+      # Podman does not support multiple sockets, as of podman 5.0.2, so we use
+      # a symlink. Unfortunately this does not let us use an alternate group,
+      # such as `docker`.
+      systemd.sockets.podman.socketConfig.Symlinks =
+        lib.mkIf cfg.dockerSocket.enable [ "/run/docker.sock" ];
 
       systemd.user.services.podman.environment = config.networking.proxy.envVars;
       systemd.user.sockets.podman.wantedBy = [ "sockets.target" ];
@@ -239,11 +244,6 @@ in
         '')
       ];
 
-      systemd.tmpfiles.rules =
-        lib.optionals cfg.dockerSocket.enable [
-          "L! /run/docker.sock - - - - /run/podman/podman.sock"
-        ];
-
       users.groups.podman = { };
 
       assertions = [
diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix
index 39cbe85579ae9..d1773da9afa6f 100644
--- a/nixos/release-combined.nix
+++ b/nixos/release-combined.nix
@@ -82,7 +82,9 @@ in rec {
         (onFullSupported "nixos.tests.gitlab")
         (onFullSupported "nixos.tests.gnome")
         (onFullSupported "nixos.tests.gnome-xorg")
-        (onSystems ["x86_64-linux"] "nixos.tests.hibernate")
+        # FIXME: broken by QEMU 8.2.3 upgrade, reenable when fixed
+        # Upstream issue: https://gitlab.com/qemu-project/qemu/-/issues/2321
+        # (onSystems ["x86_64-linux"] "nixos.tests.hibernate")
         (onFullSupported "nixos.tests.i3wm")
         (onSystems ["x86_64-linux"] "nixos.tests.installer.btrfsSimple")
         (onSystems ["x86_64-linux"] "nixos.tests.installer.btrfsSubvolDefault")
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 6ef1d8d537980..ba876fe31fc04 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -193,6 +193,7 @@ in {
   cinnamon = handleTest ./cinnamon.nix {};
   cinnamon-wayland = handleTest ./cinnamon-wayland.nix {};
   cjdns = handleTest ./cjdns.nix {};
+  clatd = handleTest ./clatd.nix {};
   clickhouse = handleTest ./clickhouse.nix {};
   cloud-init = handleTest ./cloud-init.nix {};
   cloud-init-hostname = handleTest ./cloud-init-hostname.nix {};
@@ -451,6 +452,7 @@ in {
   jirafeau = handleTest ./jirafeau.nix {};
   jitsi-meet = handleTest ./jitsi-meet.nix {};
   jool = import ./jool.nix { inherit pkgs runTest; };
+  jotta-cli = handleTest ./jotta-cli.nix {};
   k3s = handleTest ./k3s {};
   kafka = handleTest ./kafka.nix {};
   kanidm = handleTest ./kanidm.nix {};
@@ -992,6 +994,7 @@ in {
   v2ray = handleTest ./v2ray.nix {};
   varnish60 = handleTest ./varnish.nix { package = pkgs.varnish60; };
   varnish74 = handleTest ./varnish.nix { package = pkgs.varnish74; };
+  varnish75 = handleTest ./varnish.nix { package = pkgs.varnish75; };
   vault = handleTest ./vault.nix {};
   vault-agent = handleTest ./vault-agent.nix {};
   vault-dev = handleTest ./vault-dev.nix {};
diff --git a/nixos/tests/clatd.nix b/nixos/tests/clatd.nix
new file mode 100644
index 0000000000000..00021d87ba5f4
--- /dev/null
+++ b/nixos/tests/clatd.nix
@@ -0,0 +1,189 @@
+# This test verifies that we can ping an IPv4-only server from an IPv6-only
+# client via a NAT64 router using CLAT on the client. The hosts and networks
+# are configured as follows:
+#
+#        +------
+# Client | clat    Address: 192.0.0.1/32  (configured via clatd)
+#        |         Route:   default
+#        |
+#        | eth1    Address: 2001:db8::2/64
+#        |  |      Route:   default via 2001:db8::1
+#        +--|---
+#           | VLAN 3
+#        +--|---
+#        | eth2    Address: 2001:db8::1/64
+# Router |
+#        | nat64   Address: 64:ff9b::1/128
+#        |         Route:   64:ff9b::/96
+#        |         Address: 192.0.2.0/32
+#        |         Route:   192.0.2.0/24
+#        |
+#        | eth1    Address: 100.64.0.1/24
+#        +--|---
+#           | VLAN 2
+#        +--|---
+# Server | eth1    Address: 100.64.0.2/24
+#        |         Route:   192.0.2.0/24 via 100.64.0.1
+#        +------
+
+import ./make-test-python.nix ({ pkgs, lib, ... }:
+
+{
+  name = "clatd";
+  meta = with pkgs.lib.maintainers; {
+    maintainers = [ hax404 ];
+  };
+
+  nodes = {
+    # The server is configured with static IPv4 addresses. RFC 6052 Section 3.1
+    # disallows the mapping of non-global IPv4 addresses like RFC 1918 into the
+    # Well-Known Prefix 64:ff9b::/96. TAYGA also does not allow the mapping of
+    # documentation space (RFC 5737). To circumvent this, 100.64.0.2/24 from
+    # RFC 6589 (Carrier Grade NAT) is used here.
+    # To reach the IPv4 address pool of the NAT64 gateway, there is a static
+    # route configured. In normal cases, where the router would also source NAT
+    # the pool addresses to one IPv4 addresses, this would not be needed.
+    server = {
+      virtualisation.vlans = [
+        2 # towards router
+      ];
+      networking = {
+        useDHCP = false;
+        interfaces.eth1 = lib.mkForce {};
+      };
+      systemd.network = {
+        enable = true;
+        networks."vlan1" = {
+          matchConfig.Name = "eth1";
+          address = [
+            "100.64.0.2/24"
+          ];
+          routes = [
+            { routeConfig = { Destination = "192.0.2.0/24"; Gateway = "100.64.0.1"; }; }
+          ];
+        };
+      };
+    };
+
+    # The router is configured with static IPv4 addresses towards the server
+    # and IPv6 addresses towards the client. For NAT64, the Well-Known prefix
+    # 64:ff9b::/96 is used. NAT64 is done with TAYGA which provides the
+    # tun-interface nat64 and does the translation over it. The IPv6 packets
+    # are sent to this interfaces and received as IPv4 packets and vice versa.
+    # As TAYGA only translates IPv6 addresses to dedicated IPv4 addresses, it
+    # needs a pool of IPv4 addresses which must be at least as big as the
+    # expected amount of clients. In this test, the packets from the pool are
+    # directly routed towards the client. In normal cases, there would be a
+    # second source NAT44 to map all clients behind one IPv4 address.
+    router = {
+      boot.kernel.sysctl = {
+        "net.ipv4.ip_forward" = 1;
+        "net.ipv6.conf.all.forwarding" = 1;
+      };
+
+      virtualisation.vlans = [
+        2 # towards server
+        3 # towards client
+      ];
+
+      networking = {
+        useDHCP = false;
+        useNetworkd = true;
+        firewall.enable = false;
+        interfaces.eth1 = lib.mkForce {
+          ipv4 = {
+            addresses = [ { address = "100.64.0.1"; prefixLength = 24; } ];
+          };
+        };
+        interfaces.eth2 = lib.mkForce {
+          ipv6 = {
+            addresses = [ { address = "2001:db8::1"; prefixLength = 64; } ];
+          };
+        };
+      };
+
+      services.tayga = {
+        enable = true;
+        ipv4 = {
+          address = "192.0.2.0";
+          router = {
+            address = "192.0.2.1";
+          };
+          pool = {
+            address = "192.0.2.0";
+            prefixLength = 24;
+          };
+        };
+        ipv6 = {
+          address = "2001:db8::1";
+          router = {
+            address = "64:ff9b::1";
+          };
+          pool = {
+            address = "64:ff9b::";
+            prefixLength = 96;
+          };
+        };
+      };
+    };
+
+    # The client is configured with static IPv6 addresses. It has also a static
+    # default route towards the router. To reach the IPv4-only server, the
+    # client starts the clat daemon which starts and configures the local
+    # IPv4 -> IPv6 translation via Tayga.
+    client = {
+      virtualisation.vlans = [
+        3 # towards router
+      ];
+
+      networking = {
+        useDHCP = false;
+        interfaces.eth1 = lib.mkForce {};
+      };
+
+      systemd.network = {
+        enable = true;
+        networks."vlan1" = {
+          matchConfig.Name = "eth1";
+          address = [
+            "2001:db8::2/64"
+          ];
+          routes = [
+            { routeConfig = { Destination = "::/0"; Gateway = "2001:db8::1"; }; }
+          ];
+        };
+      };
+
+      services.clatd = {
+        enable = true;
+        settings.plat-prefix = "64:ff9b::/96";
+      };
+
+      environment.systemPackages = [ pkgs.mtr ];
+    };
+  };
+
+  testScript = ''
+    start_all()
+
+    # wait for all machines to start up
+    for machine in client, router, server:
+      machine.wait_for_unit("network-online.target")
+
+    with subtest("Wait for tayga and clatd"):
+      router.wait_for_unit("tayga.service")
+      client.wait_for_unit("clatd.service")
+      # clatd checks if this system has IPv4 connectivity for 10 seconds
+      client.wait_until_succeeds(
+        'journalctl -u clatd -e | grep -q "Starting up TAYGA, using config file"'
+      )
+
+    with subtest("Test ICMP"):
+      client.wait_until_succeeds("ping -c 3 100.64.0.2 >&2")
+
+    with subtest("Test ICMP and show a traceroute"):
+      client.wait_until_succeeds("mtr --show-ips --report-wide 100.64.0.2 >&2")
+
+    client.log(client.execute("systemd-analyze security clatd.service")[1])
+  '';
+})
diff --git a/nixos/tests/fish.nix b/nixos/tests/fish.nix
index 3d9b13c6af70a..c9a1bef51478e 100644
--- a/nixos/tests/fish.nix
+++ b/nixos/tests/fish.nix
@@ -10,6 +10,8 @@ import ./make-test-python.nix ({ pkgs, ... }: {
         coreutils
         procps # kill collides with coreutils' to test https://github.com/NixOS/nixpkgs/issues/56432
       ];
+      # TODO: remove if/when #267880 is merged and this is a default
+      services.logrotate.enable = false;
     };
 
   testScript =
diff --git a/nixos/tests/installed-tests/default.nix b/nixos/tests/installed-tests/default.nix
index e87edb2007e93..b1ddfe3dcbd80 100644
--- a/nixos/tests/installed-tests/default.nix
+++ b/nixos/tests/installed-tests/default.nix
@@ -1,5 +1,5 @@
 # NixOS tests for gnome-desktop-testing-runner using software
-# See https://wiki.gnome.org/Initiatives/GnomeGoals/InstalledTests
+# See https://github.com/NixOS/nixpkgs/issues/34987
 
 { system ? builtins.currentSystem,
   config ? {},
diff --git a/nixos/tests/installed-tests/gnome-photos.nix b/nixos/tests/installed-tests/gnome-photos.nix
index bcb6479ee89c6..010ad97024026 100644
--- a/nixos/tests/installed-tests/gnome-photos.nix
+++ b/nixos/tests/installed-tests/gnome-photos.nix
@@ -13,7 +13,7 @@ makeInstalledTest {
       (stdenv.mkDerivation {
         name = "desktop-gsettings";
         dontUnpack = true;
-        nativeBuildInputs = [ glib wrapGAppsHook ];
+        nativeBuildInputs = [ glib wrapGAppsHook3 ];
         buildInputs = [ gsettings-desktop-schemas ];
         installPhase = ''
           runHook preInstall
diff --git a/nixos/tests/jotta-cli.nix b/nixos/tests/jotta-cli.nix
new file mode 100644
index 0000000000000..0df23ee2cba5c
--- /dev/null
+++ b/nixos/tests/jotta-cli.nix
@@ -0,0 +1,25 @@
+import ./make-test-python.nix ({ pkgs, ... }: {
+
+  name = "jotta-cli";
+  meta.maintainers = with pkgs.lib.maintainers; [ evenbrenden ];
+
+  nodes.machine = { pkgs, ... }: {
+    services.jotta-cli.enable = true;
+    imports = [ ./common/user-account.nix ];
+  };
+
+  testScript = { nodes, ... }:
+    let uid = toString nodes.machine.users.users.alice.uid;
+    in ''
+      machine.start()
+
+      machine.succeed("loginctl enable-linger alice")
+      machine.wait_for_unit("user@${uid}.service")
+
+      machine.wait_for_unit("jottad.service", "alice")
+      machine.wait_for_open_unix_socket("/run/user/${uid}/jottad/jottad.socket")
+
+      # "jotta-cli version" should fail if jotta-cli cannot connect to jottad
+      machine.succeed('XDG_RUNTIME_DIR=/run/user/${uid} su alice -c "jotta-cli version"')
+    '';
+})
diff --git a/nixos/tests/k3s/single-node.nix b/nixos/tests/k3s/single-node.nix
index fd64a050e61ef..b7ac5d9eeeac7 100644
--- a/nixos/tests/k3s/single-node.nix
+++ b/nixos/tests/k3s/single-node.nix
@@ -78,6 +78,18 @@ import ../make-test-python.nix ({ pkgs, lib, k3s, ... }:
       # regression test for #176445
       machine.fail("journalctl -o cat -u k3s.service | grep 'ipset utility not found'")
 
+      with subtest("Run k3s-killall"):
+          # Call the killall script with a clean path to assert that
+          # all required commands are wrapped
+          output = machine.succeed("PATH= ${k3s}/bin/k3s-killall.sh 2>&1 | tee /dev/stderr")
+          assert "command not found" not in output, "killall script contains unknown command"
+
+          # Check that killall cleaned up properly
+          machine.fail("systemctl is-active k3s.service")
+          machine.fail("systemctl list-units | grep containerd")
+          machine.fail("ip link show | awk -F': ' '{print $2}' | grep -e flannel -e cni0")
+          machine.fail("ip netns show | grep cni-")
+
       machine.shutdown()
     '';
   })
diff --git a/nixos/tests/kanidm.nix b/nixos/tests/kanidm.nix
index fa24d4a8a5e13..8ed9af63f1d41 100644
--- a/nixos/tests/kanidm.nix
+++ b/nixos/tests/kanidm.nix
@@ -76,14 +76,17 @@ import ./make-test-python.nix ({ pkgs, ... }:
         with subtest("Test LDAP interface"):
             server.succeed("ldapsearch -H ldaps://${serverDomain}:636 -b '${ldapBaseDN}' -x '(name=test)'")
 
-        with subtest("Test CLI login"):
-            client.succeed("kanidm login -D anonymous")
-            client.succeed("kanidm self whoami | grep anonymous@${serverDomain}")
-            client.succeed("kanidm logout")
-
         with subtest("Recover idm_admin account"):
             idm_admin_password = server.succeed("su - kanidm -c 'kanidmd recover-account -c ${serverConfigFile} idm_admin 2>&1 | rg -o \'[A-Za-z0-9]{48}\' '").strip().removeprefix("'").removesuffix("'")
 
+        with subtest("Test CLI login"):
+            client.wait_until_tty_matches("1", "login: ")
+            client.send_chars("root\n")
+            client.send_chars("kanidm login -D idm_admin\n")
+            client.wait_until_tty_matches("1", "Enter password: ")
+            client.send_chars(f"{idm_admin_password}\n")
+            client.wait_until_tty_matches("1", "Login Success for idm_admin")
+
         with subtest("Test unixd connection"):
             client.wait_for_unit("kanidm-unixd.service")
             client.wait_for_file("/run/kanidm-unixd/sock")
@@ -92,12 +95,6 @@ import ./make-test-python.nix ({ pkgs, ... }:
         with subtest("Test user creation"):
             client.wait_for_unit("getty@tty1.service")
             client.wait_until_succeeds("pgrep -f 'agetty.*tty1'")
-            client.wait_until_tty_matches("1", "login: ")
-            client.send_chars("root\n")
-            client.send_chars("kanidm login -D idm_admin\n")
-            client.wait_until_tty_matches("1", "Enter password: ")
-            client.send_chars(f"{idm_admin_password}\n")
-            client.wait_until_tty_matches("1", "Login Success for idm_admin")
             client.succeed("kanidm person create testuser TestUser")
             client.succeed("kanidm person posix set --shell \"$SHELL\" testuser")
             client.send_chars("kanidm person posix set-password testuser\n")
diff --git a/nixos/tests/libreswan.nix b/nixos/tests/libreswan.nix
index aadba941fab17..c798a04645bc0 100644
--- a/nixos/tests/libreswan.nix
+++ b/nixos/tests/libreswan.nix
@@ -119,11 +119,11 @@ in
       with subtest("Libreswan is ready"):
           alice.wait_for_unit("ipsec")
           bob.wait_for_unit("ipsec")
-          alice.succeed("ipsec verify 1>&2")
+          alice.succeed("ipsec checkconfig")
 
       with subtest("Alice and Bob can start the tunnel"):
-          alice.execute("ipsec auto --start tunnel >&2 &")
-          bob.succeed("ipsec auto --start tunnel")
+          alice.execute("ipsec start tunnel >&2 &")
+          bob.succeed("ipsec start tunnel")
           # apparently this is needed to "wake" the tunnel
           bob.execute("ping -c1 alice")
 
diff --git a/nixos/tests/openssh.nix b/nixos/tests/openssh.nix
index a039986621cab..2684b6f45e84e 100644
--- a/nixos/tests/openssh.nix
+++ b/nixos/tests/openssh.nix
@@ -1,7 +1,7 @@
 import ./make-test-python.nix ({ pkgs, ... }:
 
 let inherit (import ./ssh-keys.nix pkgs)
-      snakeOilPrivateKey snakeOilPublicKey;
+      snakeOilPrivateKey snakeOilPublicKey snakeOilEd25519PrivateKey snakeOilEd25519PublicKey;
 in {
   name = "openssh";
   meta = with pkgs.lib.maintainers; {
@@ -108,6 +108,31 @@ in {
         };
       };
 
+    server-no-openssl =
+      { ... }:
+      {
+        programs.ssh.package = pkgs.opensshPackages.openssh.override {
+          linkOpenssl = false;
+        };
+        services.openssh = {
+          enable = true;
+          hostKeys = [
+            { type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
+          ];
+          settings = {
+            # Must not specify the OpenSSL provided algorithms.
+            Ciphers = [ "chacha20-poly1305@openssh.com" ];
+            KexAlgorithms = [
+              "curve25519-sha256"
+              "curve25519-sha256@libssh.org"
+            ];
+          };
+        };
+        users.users.root.openssh.authorizedKeys.keys = [
+          snakeOilEd25519PublicKey
+        ];
+      };
+
     server-no-pam =
       { pkgs, ... }:
       {
@@ -139,6 +164,7 @@ in {
     server_allowed_users.wait_for_unit("sshd", timeout=30)
     server_localhost_only.wait_for_unit("sshd", timeout=30)
     server_match_rule.wait_for_unit("sshd", timeout=30)
+    server_no_openssl.wait_for_unit("sshd", timeout=30)
     server_no_pam.wait_for_unit("sshd", timeout=30)
 
     server_lazy.wait_for_unit("sshd.socket", timeout=30)
@@ -230,6 +256,16 @@ in {
             timeout=30
         )
 
+    with subtest("no-openssl"):
+        client.succeed(
+            "cat ${snakeOilEd25519PrivateKey} > privkey.snakeoil"
+        )
+        client.succeed("chmod 600 privkey.snakeoil")
+        client.succeed(
+            "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server-no-openssl true",
+            timeout=30
+        )
+
     with subtest("no-pam"):
         client.succeed(
             "cat ${snakeOilPrivateKey} > privkey.snakeoil"
diff --git a/nixos/tests/patroni.nix b/nixos/tests/patroni.nix
index 1f15cd59677ad..68fce4051553e 100644
--- a/nixos/tests/patroni.nix
+++ b/nixos/tests/patroni.nix
@@ -155,7 +155,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
               print(node.succeed("patronictl list cluster1"))
               node.wait_until_succeeds(f"[ $(patronictl list -f json cluster1 | jq 'length') == {expected_replicas + 1} ]")
               node.wait_until_succeeds("[ $(patronictl list -f json cluster1 | jq 'map(select(.Role | test(\"^Leader$\"))) | map(select(.State | test(\"^running$\"))) | length') == 1 ]")
-              node.wait_until_succeeds(f"[ $(patronictl list -f json cluster1 | jq 'map(select(.Role | test(\"^Replica$\"))) | map(select(.State | test(\"^running$\"))) | length') == {expected_replicas} ]")
+              node.wait_until_succeeds(f"[ $(patronictl list -f json cluster1 | jq 'map(select(.Role | test(\"^Replica$\"))) | map(select(.State | test(\"^streaming$\"))) | length') == {expected_replicas} ]")
               print(node.succeed("patronictl list cluster1"))
           client.wait_until_succeeds("psql -h 127.0.0.1 -U postgres --command='select 1;'")
 
diff --git a/nixos/tests/postgresql-jit.nix b/nixos/tests/postgresql-jit.nix
index baf26b8da2b39..f4b1d07a7faf8 100644
--- a/nixos/tests/postgresql-jit.nix
+++ b/nixos/tests/postgresql-jit.nix
@@ -1,6 +1,7 @@
 { system ? builtins.currentSystem
 , config ? {}
 , pkgs ? import ../.. { inherit system config; }
+, package ? null
 }:
 
 with import ../lib/testing-python.nix { inherit system pkgs; };
@@ -9,14 +10,17 @@ let
   inherit (pkgs) lib;
   packages = builtins.attrNames (import ../../pkgs/servers/sql/postgresql pkgs);
 
-  mkJitTest = packageName: makeTest {
-    name = "${packageName}";
+  mkJitTestFromName = name:
+    mkJitTest pkgs.${name};
+
+  mkJitTest = package: makeTest {
+    name = package.name;
     meta.maintainers = with lib.maintainers; [ ma27 ];
     nodes.machine = { pkgs, lib, ... }: {
       services.postgresql = {
+        inherit package;
         enable = true;
         enableJIT = true;
-        package = pkgs.${packageName};
         initialScript = pkgs.writeText "init.sql" ''
           create table demo (id int);
           insert into demo (id) select generate_series(1, 5);
@@ -45,4 +49,7 @@ let
     '';
   };
 in
-lib.genAttrs packages mkJitTest
+if package == null then
+  lib.genAttrs packages mkJitTestFromName
+else
+  mkJitTest package
diff --git a/nixos/tests/postgresql-wal-receiver.nix b/nixos/tests/postgresql-wal-receiver.nix
index b0bd7711dbcd9..ab2ab4ad0d4fa 100644
--- a/nixos/tests/postgresql-wal-receiver.nix
+++ b/nixos/tests/postgresql-wal-receiver.nix
@@ -1,6 +1,7 @@
 { system ? builtins.currentSystem,
   config ? {},
-  pkgs ? import ../.. { inherit system config; }
+  pkgs ? import ../.. { inherit system config; },
+  package ? null
 }:
 
 with import ../lib/testing-python.nix { inherit system pkgs; };
@@ -9,111 +10,110 @@ let
   lib = pkgs.lib;
 
   # Makes a test for a PostgreSQL package, given by name and looked up from `pkgs`.
-  makePostgresqlWalReceiverTest = postgresqlPackage:
+  makeTestAttribute = name:
   {
-    name = postgresqlPackage;
-    value =
-      let
-        pkg = pkgs."${postgresqlPackage}";
-        postgresqlDataDir = "/var/lib/postgresql/${pkg.psqlSchema}";
-        replicationUser = "wal_receiver_user";
-        replicationSlot = "wal_receiver_slot";
-        replicationConn = "postgresql://${replicationUser}@localhost";
-        baseBackupDir = "/tmp/pg_basebackup";
-        walBackupDir = "/tmp/pg_wal";
-        atLeast12 = lib.versionAtLeast pkg.version "12.0";
-
-        recoveryFile = if atLeast12
-            then pkgs.writeTextDir "recovery.signal" ""
-            else pkgs.writeTextDir "recovery.conf" "restore_command = 'cp ${walBackupDir}/%f %p'";
-
-      in makeTest {
-        name = "postgresql-wal-receiver-${postgresqlPackage}";
-        meta.maintainers = with lib.maintainers; [ pacien ];
-
-        nodes.machine = { ... }: {
-          services.postgresql = {
-            package = pkg;
-            enable = true;
-            settings = lib.mkMerge [
-              {
-                wal_level = "archive"; # alias for replica on pg >= 9.6
-                max_wal_senders = 10;
-                max_replication_slots = 10;
-              }
-              (lib.mkIf atLeast12 {
-                restore_command = "cp ${walBackupDir}/%f %p";
-                recovery_end_command = "touch recovery.done";
-              })
-            ];
-            authentication = ''
-              host replication ${replicationUser} all trust
-            '';
-            initialScript = pkgs.writeText "init.sql" ''
-              create user ${replicationUser} replication;
-              select * from pg_create_physical_replication_slot('${replicationSlot}');
-            '';
-          };
+    inherit name;
+    value = makePostgresqlWalReceiverTest pkgs."${name}";
+  };
+
+  makePostgresqlWalReceiverTest = pkg:
+    let
+      postgresqlDataDir = "/var/lib/postgresql/${pkg.psqlSchema}";
+      replicationUser = "wal_receiver_user";
+      replicationSlot = "wal_receiver_slot";
+      replicationConn = "postgresql://${replicationUser}@localhost";
+      baseBackupDir = "/tmp/pg_basebackup";
+      walBackupDir = "/tmp/pg_wal";
+
+      recoveryFile = pkgs.writeTextDir "recovery.signal" "";
 
-          services.postgresqlWalReceiver.receivers.main = {
-            postgresqlPackage = pkg;
-            connection = replicationConn;
-            slot = replicationSlot;
-            directory = walBackupDir;
+    in makeTest {
+      name = "postgresql-wal-receiver-${pkg.name}";
+      meta.maintainers = with lib.maintainers; [ pacien ];
+
+      nodes.machine = { ... }: {
+        services.postgresql = {
+          package = pkg;
+          enable = true;
+          settings = {
+            max_replication_slots = 10;
+            max_wal_senders = 10;
+            recovery_end_command = "touch recovery.done";
+            restore_command = "cp ${walBackupDir}/%f %p";
+            wal_level = "archive"; # alias for replica on pg >= 9.6
           };
-          # This is only to speedup test, it isn't time racing. Service is set to autorestart always,
-          # default 60sec is fine for real system, but is too much for a test
-          systemd.services.postgresql-wal-receiver-main.serviceConfig.RestartSec = lib.mkForce 5;
+          authentication = ''
+            host replication ${replicationUser} all trust
+          '';
+          initialScript = pkgs.writeText "init.sql" ''
+            create user ${replicationUser} replication;
+            select * from pg_create_physical_replication_slot('${replicationSlot}');
+          '';
         };
 
-        testScript = ''
-          # make an initial base backup
-          machine.wait_for_unit("postgresql")
-          machine.wait_for_unit("postgresql-wal-receiver-main")
-          # WAL receiver healthchecks PG every 5 seconds, so let's be sure they have connected each other
-          # required only for 9.4
-          machine.sleep(5)
-          machine.succeed(
-              "${pkg}/bin/pg_basebackup --dbname=${replicationConn} --pgdata=${baseBackupDir}"
-          )
-
-          # create a dummy table with 100 records
-          machine.succeed(
-              "sudo -u postgres psql --command='create table dummy as select * from generate_series(1, 100) as val;'"
-          )
-
-          # stop postgres and destroy data
-          machine.systemctl("stop postgresql")
-          machine.systemctl("stop postgresql-wal-receiver-main")
-          machine.succeed("rm -r ${postgresqlDataDir}/{base,global,pg_*}")
-
-          # restore the base backup
-          machine.succeed(
-              "cp -r ${baseBackupDir}/* ${postgresqlDataDir} && chown postgres:postgres -R ${postgresqlDataDir}"
-          )
-
-          # prepare WAL and recovery
-          machine.succeed("chmod a+rX -R ${walBackupDir}")
-          machine.execute(
-              "for part in ${walBackupDir}/*.partial; do mv $part ''${part%%.*}; done"
-          )  # make use of partial segments too
-          machine.succeed(
-              "cp ${recoveryFile}/* ${postgresqlDataDir}/ && chmod 666 ${postgresqlDataDir}/recovery*"
-          )
-
-          # replay WAL
-          machine.systemctl("start postgresql")
-          machine.wait_for_file("${postgresqlDataDir}/recovery.done")
-          machine.systemctl("restart postgresql")
-          machine.wait_for_unit("postgresql")
-
-          # check that our records have been restored
-          machine.succeed(
-              "test $(sudo -u postgres psql --pset='pager=off' --tuples-only --command='select count(distinct val) from dummy;') -eq 100"
-          )
-        '';
+        services.postgresqlWalReceiver.receivers.main = {
+          postgresqlPackage = pkg;
+          connection = replicationConn;
+          slot = replicationSlot;
+          directory = walBackupDir;
+        };
+        # This is only to speedup test, it isn't time racing. Service is set to autorestart always,
+        # default 60sec is fine for real system, but is too much for a test
+        systemd.services.postgresql-wal-receiver-main.serviceConfig.RestartSec = lib.mkForce 5;
       };
+
+      testScript = ''
+        # make an initial base backup
+        machine.wait_for_unit("postgresql")
+        machine.wait_for_unit("postgresql-wal-receiver-main")
+        # WAL receiver healthchecks PG every 5 seconds, so let's be sure they have connected each other
+        # required only for 9.4
+        machine.sleep(5)
+        machine.succeed(
+            "${pkg}/bin/pg_basebackup --dbname=${replicationConn} --pgdata=${baseBackupDir}"
+        )
+
+        # create a dummy table with 100 records
+        machine.succeed(
+            "sudo -u postgres psql --command='create table dummy as select * from generate_series(1, 100) as val;'"
+        )
+
+        # stop postgres and destroy data
+        machine.systemctl("stop postgresql")
+        machine.systemctl("stop postgresql-wal-receiver-main")
+        machine.succeed("rm -r ${postgresqlDataDir}/{base,global,pg_*}")
+
+        # restore the base backup
+        machine.succeed(
+            "cp -r ${baseBackupDir}/* ${postgresqlDataDir} && chown postgres:postgres -R ${postgresqlDataDir}"
+        )
+
+        # prepare WAL and recovery
+        machine.succeed("chmod a+rX -R ${walBackupDir}")
+        machine.execute(
+            "for part in ${walBackupDir}/*.partial; do mv $part ''${part%%.*}; done"
+        )  # make use of partial segments too
+        machine.succeed(
+            "cp ${recoveryFile}/* ${postgresqlDataDir}/ && chmod 666 ${postgresqlDataDir}/recovery*"
+        )
+
+        # replay WAL
+        machine.systemctl("start postgresql")
+        machine.wait_for_file("${postgresqlDataDir}/recovery.done")
+        machine.systemctl("restart postgresql")
+        machine.wait_for_unit("postgresql")
+
+        # check that our records have been restored
+        machine.succeed(
+            "test $(sudo -u postgres psql --pset='pager=off' --tuples-only --command='select count(distinct val) from dummy;') -eq 100"
+        )
+      '';
     };
 
-# Maps the generic function over all attributes of PostgreSQL packages
-in builtins.listToAttrs (map makePostgresqlWalReceiverTest (builtins.attrNames (import ../../pkgs/servers/sql/postgresql pkgs)))
+in
+if package == null then
+  # all-tests.nix: Maps the generic function over all attributes of PostgreSQL packages
+  builtins.listToAttrs (map makeTestAttribute (builtins.attrNames (import ../../pkgs/servers/sql/postgresql pkgs)))
+else
+  # Called directly from <package>.tests
+  makePostgresqlWalReceiverTest package
diff --git a/nixos/tests/ssh-keys.nix b/nixos/tests/ssh-keys.nix
index df9ff38a3b22a..675f3a0b43947 100644
--- a/nixos/tests/ssh-keys.nix
+++ b/nixos/tests/ssh-keys.nix
@@ -12,4 +12,16 @@ pkgs:
     "yNTYAAABBBChdA2BmwcG49OrQN33f/sj+OHL5sJhwVl2Qim0vkUJQCry1zFpKTa"
     "9ZcDMiWaEhoAR6FGoaGI04ff7CS+1yybQ= snakeoil"
   ];
+
+  snakeOilEd25519PrivateKey = pkgs.writeText "privkey.snakeoil" ''
+    -----BEGIN OPENSSH PRIVATE KEY-----
+    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+    QyNTUxOQAAACAYBTIWo1J4PkY4/7AhVyPT8xvAUI67tp+yYFFRdSm7+QAAAJC89yCivPcg
+    ogAAAAtzc2gtZWQyNTUxOQAAACAYBTIWo1J4PkY4/7AhVyPT8xvAUI67tp+yYFFRdSm7+Q
+    AAAEDJmKp3lX6Pz0unTc0QZwrHb8Eyr9fJUopE9d2/+q+eCxgFMhajUng+Rjj/sCFXI9Pz
+    G8BQjru2n7JgUVF1Kbv5AAAACnRvbUBvemRlc2sBAgM=
+    -----END OPENSSH PRIVATE KEY-----
+  '';
+
+  snakeOilEd25519PublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBgFMhajUng+Rjj/sCFXI9PzG8BQjru2n7JgUVF1Kbv5 snakeoil";
 }