about summary refs log tree commit diff
path: root/nixpkgs/nixos
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2023-09-15 07:58:52 +0000
committerAlyssa Ross <hi@alyssa.is>2023-09-15 07:58:52 +0000
commit9d1daa60832979d5d361dfdac136fb9e5a1af2c5 (patch)
tree5192dd85903cb092cf7dff0e3403387b3b683d84 /nixpkgs/nixos
parent67cdfc7d42f721bf85814af5a0095fb9f9ea455d (diff)
parentf2ea252d23ebc9a5336bf6a61e0644921f64e67c (diff)
downloadnixlib-9d1daa60832979d5d361dfdac136fb9e5a1af2c5.tar
nixlib-9d1daa60832979d5d361dfdac136fb9e5a1af2c5.tar.gz
nixlib-9d1daa60832979d5d361dfdac136fb9e5a1af2c5.tar.bz2
nixlib-9d1daa60832979d5d361dfdac136fb9e5a1af2c5.tar.lz
nixlib-9d1daa60832979d5d361dfdac136fb9e5a1af2c5.tar.xz
nixlib-9d1daa60832979d5d361dfdac136fb9e5a1af2c5.tar.zst
nixlib-9d1daa60832979d5d361dfdac136fb9e5a1af2c5.zip
Merge branch 'nixos-unstable' of https://github.com/NixOS/nixpkgs
Diffstat (limited to 'nixpkgs/nixos')
-rw-r--r--nixpkgs/nixos/doc/manual/release-notes/rl-2205.section.md3
-rw-r--r--nixpkgs/nixos/doc/manual/release-notes/rl-2311.section.md12
-rw-r--r--nixpkgs/nixos/modules/config/fonts/packages.nix2
-rw-r--r--nixpkgs/nixos/modules/config/terminfo.nix10
-rw-r--r--nixpkgs/nixos/modules/config/update-users-groups.pl8
-rw-r--r--nixpkgs/nixos/modules/config/users-groups.nix40
-rw-r--r--nixpkgs/nixos/modules/hardware/video/nvidia.nix550
-rw-r--r--nixpkgs/nixos/modules/module-list.nix3
-rw-r--r--nixpkgs/nixos/modules/programs/bash/bash.nix2
-rw-r--r--nixpkgs/nixos/modules/programs/clash-verge.nix14
-rw-r--r--nixpkgs/nixos/modules/programs/direnv.nix18
-rw-r--r--nixpkgs/nixos/modules/programs/yazi.nix6
-rw-r--r--nixpkgs/nixos/modules/security/acme/default.md4
-rw-r--r--nixpkgs/nixos/modules/security/acme/default.nix43
-rw-r--r--nixpkgs/nixos/modules/security/pam.nix2
-rw-r--r--nixpkgs/nixos/modules/services/audio/tts.nix1
-rw-r--r--nixpkgs/nixos/modules/services/misc/forgejo.nix668
-rw-r--r--nixpkgs/nixos/modules/services/networking/adguardhome.nix5
-rw-r--r--nixpkgs/nixos/modules/services/networking/networkmanager.nix121
-rw-r--r--nixpkgs/nixos/modules/services/networking/ssh/sshd.nix3
-rw-r--r--nixpkgs/nixos/modules/services/networking/trust-dns.nix5
-rw-r--r--nixpkgs/nixos/modules/services/networking/websockify.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/healthchecks.nix45
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/meme-bingo-web.nix93
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix6
-rw-r--r--nixpkgs/nixos/modules/system/boot/networkd.nix3
-rw-r--r--nixpkgs/nixos/modules/tasks/filesystems/zfs.nix5
-rw-r--r--nixpkgs/nixos/tests/acme.nix2
-rw-r--r--nixpkgs/nixos/tests/adguardhome.nix1
-rw-r--r--nixpkgs/nixos/tests/all-tests.nix2
-rw-r--r--nixpkgs/nixos/tests/fontconfig-default-fonts.nix2
-rw-r--r--nixpkgs/nixos/tests/forgejo.nix157
-rw-r--r--nixpkgs/nixos/tests/noto-fonts.nix2
-rw-r--r--nixpkgs/nixos/tests/postgis.nix2
-rw-r--r--nixpkgs/nixos/tests/shadow.nix2
35 files changed, 1490 insertions, 354 deletions
diff --git a/nixpkgs/nixos/doc/manual/release-notes/rl-2205.section.md b/nixpkgs/nixos/doc/manual/release-notes/rl-2205.section.md
index d4581fe9441c..6f5a807f478a 100644
--- a/nixpkgs/nixos/doc/manual/release-notes/rl-2205.section.md
+++ b/nixpkgs/nixos/doc/manual/release-notes/rl-2205.section.md
@@ -935,8 +935,7 @@ In addition to numerous new and upgraded packages, this release has the followin
   using the `pomerium-cli` command, you should now install the `pomerium-cli`
   package.
 
-- The option
-  [services.networking.networkmanager.enableFccUnlock](#opt-networking.networkmanager.enableFccUnlock)
+- The option `services.networking.networkmanager.enableFccUnlock`
   was added to support FCC unlock procedures. Since release 1.18.4, the ModemManager
   daemon no longer automatically performs the FCC unlock procedure by default. See
   [the docs](https://modemmanager.org/docs/modemmanager/fcc-unlock/) for more details.
diff --git a/nixpkgs/nixos/doc/manual/release-notes/rl-2311.section.md b/nixpkgs/nixos/doc/manual/release-notes/rl-2311.section.md
index 827e2a579c2e..044d7686ae5c 100644
--- a/nixpkgs/nixos/doc/manual/release-notes/rl-2311.section.md
+++ b/nixpkgs/nixos/doc/manual/release-notes/rl-2311.section.md
@@ -91,6 +91,8 @@
 
 - `getent` has been moved from `glibc`'s `bin` output to its own dedicated output, reducing closure size for many dependents. Dependents using the `getent` alias should not be affected; others should move from using `glibc.bin` or `getBin glibc` to `getent` (which also improves compatibility with non-glibc platforms).
 
+- The `users.users.<name>.passwordFile` has been renamed to `users.users.<name>.hashedPasswordFile` to avoid possible confusions. The option is in fact the file-based version of `hashedPassword`, not `password`, and expects a file containing the {manpage}`crypt(3)` hash of the user password.
+
 - The `services.ananicy.extraRules` option now has the type of `listOf attrs` instead of `string`.
 
 - JACK tools (`jack_*` except `jack_control`) have moved from the `jack2` package to `jack-example-tools`
@@ -185,12 +187,18 @@
 
 - Emacs macport version 29 was introduced.
 
+- The option `services.networking.networkmanager.enableFccUnlock` was removed in favor of `networking.networkmanager.fccUnlockScripts`, which allows specifying unlock scripts explicitly. The previous option simply did enable all unlock scripts bundled with ModemManager, which is risky, and didn't allow using vendor-provided unlock scripts at all.
+
 - The `html-proofer` package has been updated from major version 3 to major version 5, which includes [breaking changes](https://github.com/gjtorikian/html-proofer/blob/v5.0.8/UPGRADING.md).
 
 - `kratos` has been updated from 0.10.1 to the first stable version 1.0.0, please read the [0.10.1 to 0.11.0](https://github.com/ory/kratos/releases/tag/v0.11.0), [0.11.0 to 0.11.1](https://github.com/ory/kratos/releases/tag/v0.11.1), [0.11.1 to 0.13.0](https://github.com/ory/kratos/releases/tag/v0.13.0) and [0.13.0 to 1.0.0](https://github.com/ory/kratos/releases/tag/v1.0.0) upgrade guides. The most notable breaking change is the introduction of one-time passwords (`code`) and update of the default recovery strategy from `link` to `code`.
 
 - The `hail` NixOS module was removed, as `hail` was unmaintained since 2017.
 
+- Package `noto-fonts-emoji` was renamed to `noto-fonts-color-emoji`;
+  see [#221181](https://github.com/NixOS/nixpkgs/issues/221181).
+
+
 ## Other Notable Changes {#sec-release-23.11-notable-changes}
 
 - The Cinnamon module now enables XDG desktop integration by default. If you are experiencing collisions related to xdg-desktop-portal-gtk you can safely remove `xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];` from your NixOS configuration.
@@ -247,6 +255,8 @@ The module update takes care of the new config syntax and the data itself (user
 
 - `programs.gnupg.agent.pinentryFlavor` is now set in `/etc/gnupg/gpg-agent.conf`, and will no longer take precedence over a `pinentry-program` set in `~/.gnupg/gpg-agent.conf`.
 
+- `dockerTools.buildImage`, `dockerTools.buildLayeredImage` and `dockerTools.streamLayeredImage` now use `lib.makeOverridable` to allow `dockerTools`-based images to be customized more efficiently at the nix-level.
+
 - `services.influxdb2` now supports doing an automatic initial setup and provisioning of users, organizations, buckets and authentication tokens, see [#249502](https://github.com/NixOS/nixpkgs/pull/249502) for more details.
 
 - `wrapHelm` now exposes `passthru.pluginsDir` which can be passed to `helmfile`. For convenience, a top-level package `helmfile-wrapped` has been added, which inherits `passthru.pluginsDir` from `kubernetes-helm-wrapped`. See [#217768](https://github.com/NixOS/nixpkgs/issues/217768) for details.
@@ -263,6 +273,8 @@ The module update takes care of the new config syntax and the data itself (user
 
 - The `cawbird` package is dropped from nixpkgs, as it got broken by the Twitter API closing down and has been abandoned upstream.
 
+- `hardware.nvidia` gained `datacenter` options for enabling NVIDIA Data Center drivers and configuration of NVLink/NVSwitch topologies through `nv-fabricmanager`.
+
 - Certificate generation via the `security.acme` now limits the concurrent number of running certificate renewals and generation jobs, to avoid spiking resource usage when processing many certificates at once. The limit defaults to *5* and can be adjusted via `maxConcurrentRenewals`. Setting it to *0* disables the limits altogether.
 
 - New `boot.bcache.enable` (default enabled) allows completely removing `bcache` mount support.
diff --git a/nixpkgs/nixos/modules/config/fonts/packages.nix b/nixpkgs/nixos/modules/config/fonts/packages.nix
index 46907d5411ca..37b705ecb345 100644
--- a/nixpkgs/nixos/modules/config/fonts/packages.nix
+++ b/nixpkgs/nixos/modules/config/fonts/packages.nix
@@ -37,7 +37,7 @@ in
       gyre-fonts # TrueType substitutes for standard PostScript fonts
       liberation_ttf
       unifont
-      noto-fonts-emoji
+      noto-fonts-color-emoji
     ]);
   };
 }
diff --git a/nixpkgs/nixos/modules/config/terminfo.nix b/nixpkgs/nixos/modules/config/terminfo.nix
index 82f9ae48372a..1ae8e82c471e 100644
--- a/nixpkgs/nixos/modules/config/terminfo.nix
+++ b/nixpkgs/nixos/modules/config/terminfo.nix
@@ -16,16 +16,24 @@ with lib;
 
   config = {
 
-    # can be generated with: filter (drv: (builtins.tryEval (drv ? terminfo)).value) (attrValues pkgs)
+    # can be generated with:
+    # attrNames (filterAttrs
+    #  (_: drv: (builtins.tryEval (isDerivation drv && drv ? terminfo)).value)
+    #  pkgs)
     environment.systemPackages = mkIf config.environment.enableAllTerminfo (map (x: x.terminfo) (with pkgs; [
       alacritty
+      contour
       foot
       kitty
       mtm
+      rio
       rxvt-unicode-unwrapped
       rxvt-unicode-unwrapped-emoji
+      st
       termite
+      tmux
       wezterm
+      yaft
     ]));
 
     environment.pathsToLink = [
diff --git a/nixpkgs/nixos/modules/config/update-users-groups.pl b/nixpkgs/nixos/modules/config/update-users-groups.pl
index 4312197a3735..7aee58e697de 100644
--- a/nixpkgs/nixos/modules/config/update-users-groups.pl
+++ b/nixpkgs/nixos/modules/config/update-users-groups.pl
@@ -241,12 +241,12 @@ foreach my $u (@{$spec->{users}}) {
         chmod oct($u->{homeMode}), $u->{home};
     }
 
-    if (defined $u->{passwordFile}) {
-        if (-e $u->{passwordFile}) {
-            $u->{hashedPassword} = read_file($u->{passwordFile});
+    if (defined $u->{hashedPasswordFile}) {
+        if (-e $u->{hashedPasswordFile}) {
+            $u->{hashedPassword} = read_file($u->{hashedPasswordFile});
             chomp $u->{hashedPassword};
         } else {
-            warn "warning: password file ‘$u->{passwordFile}’ does not exist\n";
+            warn "warning: password file ‘$u->{hashedPasswordFile}’ does not exist\n";
         }
     } elsif (defined $u->{password}) {
         $u->{hashedPassword} = hashPassword($u->{password});
diff --git a/nixpkgs/nixos/modules/config/users-groups.nix b/nixpkgs/nixos/modules/config/users-groups.nix
index 684b4bc8fbcc..5158974c27b3 100644
--- a/nixpkgs/nixos/modules/config/users-groups.nix
+++ b/nixpkgs/nixos/modules/config/users-groups.nix
@@ -18,11 +18,11 @@ let
 
   passwordDescription = ''
     The options {option}`hashedPassword`,
-    {option}`password` and {option}`passwordFile`
+    {option}`password` and {option}`hashedPasswordFile`
     controls what password is set for the user.
     {option}`hashedPassword` overrides both
-    {option}`password` and {option}`passwordFile`.
-    {option}`password` overrides {option}`passwordFile`.
+    {option}`password` and {option}`hashedPasswordFile`.
+    {option}`password` overrides {option}`hashedPasswordFile`.
     If none of these three options are set, no password is assigned to
     the user, and the user will not be able to do password logins.
     If the option {option}`users.mutableUsers` is true, the
@@ -250,18 +250,26 @@ let
         '';
       };
 
-      passwordFile = mkOption {
+      hashedPasswordFile = mkOption {
         type = with types; nullOr str;
-        default = null;
+        default = cfg.users.${name}.passwordFile;
+        defaultText = literalExpression "null";
         description = lib.mdDoc ''
-          The full path to a file that contains the user's password. The password
-          file is read on each system activation. The file should contain
-          exactly one line, which should be the password in an encrypted form
-          that is suitable for the `chpasswd -e` command.
+          The full path to a file that contains the hash of the user's
+          password. The password file is read on each system activation. The
+          file should contain exactly one line, which should be the password in
+          an encrypted form that is suitable for the `chpasswd -e` command.
           ${passwordDescription}
         '';
       };
 
+      passwordFile = mkOption {
+        type = with types; nullOr str;
+        default = null;
+        visible = false;
+        description = lib.mdDoc "Deprecated alias of hashedPasswordFile";
+      };
+
       initialHashedPassword = mkOption {
         type = with types; nullOr (passwdEntry str);
         default = null;
@@ -447,7 +455,7 @@ let
     users = mapAttrsToList (_: u:
       { inherit (u)
           name uid group description home homeMode createHome isSystemUser
-          password passwordFile hashedPassword
+          password hashedPasswordFile hashedPassword
           autoSubUidGidRange subUidRanges subGidRanges
           initialPassword initialHashedPassword expires;
         shell = utils.toShellPath u.shell;
@@ -756,7 +764,7 @@ in {
             &&
             (allowsLogin cfg.hashedPassword
              || cfg.password != null
-             || cfg.passwordFile != null
+             || cfg.hashedPasswordFile != null
              || cfg.openssh.authorizedKeys.keys != []
              || cfg.openssh.authorizedKeys.keyFiles != [])
           ) cfg.users ++ [
@@ -845,9 +853,13 @@ in {
           The password hash of user "${user.name}" may be invalid. You must set a
           valid hash or the user will be locked out of their account. Please
           check the value of option `users.users."${user.name}".hashedPassword`.''
-        else null
-      ));
-
+        else null)
+        ++ flip mapAttrsToList cfg.users (name: user:
+          if user.passwordFile != null then
+            ''The option `users.users."${name}".passwordFile' has been renamed '' +
+            ''to `users.users."${name}".hashedPasswordFile'.''
+          else null)
+      );
   };
 
 }
diff --git a/nixpkgs/nixos/modules/hardware/video/nvidia.nix b/nixpkgs/nixos/modules/hardware/video/nvidia.nix
index 67c3afcf320a..0b1238dd888a 100644
--- a/nixpkgs/nixos/modules/hardware/video/nvidia.nix
+++ b/nixpkgs/nixos/modules/hardware/video/nvidia.nix
@@ -4,8 +4,10 @@
   pkgs,
   ...
 }: let
+  x11Enabled = config.services.xserver.enable
+               && (lib.elem "nvidia" config.services.xserver.videoDrivers);
   nvidia_x11 =
-    if (lib.elem "nvidia" config.services.xserver.videoDrivers)
+    if  x11Enabled || cfg.datacenter.enable
     then cfg.package
     else null;
 
@@ -18,9 +20,64 @@
   primeEnabled = syncCfg.enable || reverseSyncCfg.enable || offloadCfg.enable;
   busIDType = lib.types.strMatching "([[:print:]]+[\:\@][0-9]{1,3}\:[0-9]{1,2}\:[0-9])?";
   ibtSupport = cfg.open || (nvidia_x11.ibtSupport or false);
+  settingsFormat = pkgs.formats.keyValue {};
 in {
   options = {
     hardware.nvidia = {
+      datacenter.enable = lib.mkEnableOption (lib.mdDoc ''
+        Data Center drivers for NVIDIA cards on a NVLink topology.
+      '');
+      datacenter.settings = lib.mkOption {
+        type = settingsFormat.type;
+        default = {
+          LOG_LEVEL=4;
+          LOG_FILE_NAME="/var/log/fabricmanager.log";
+          LOG_APPEND_TO_LOG=1;
+          LOG_FILE_MAX_SIZE=1024;
+          LOG_USE_SYSLOG=0;
+          DAEMONIZE=1;
+          BIND_INTERFACE_IP="127.0.0.1";
+          STARTING_TCP_PORT=16000;
+          FABRIC_MODE=0;
+          FABRIC_MODE_RESTART=0;
+          STATE_FILE_NAME="/var/tmp/fabricmanager.state";
+          FM_CMD_BIND_INTERFACE="127.0.0.1";
+          FM_CMD_PORT_NUMBER=6666;
+          FM_STAY_RESIDENT_ON_FAILURES=0;
+          ACCESS_LINK_FAILURE_MODE=0;
+          TRUNK_LINK_FAILURE_MODE=0;
+          NVSWITCH_FAILURE_MODE=0;
+          ABORT_CUDA_JOBS_ON_FM_EXIT=1;
+          TOPOLOGY_FILE_PATH=nvidia_x11.fabricmanager + "/share/nvidia-fabricmanager/nvidia/nvswitch";
+        };
+        defaultText = lib.literalExpression ''
+        {
+          LOG_LEVEL=4;
+          LOG_FILE_NAME="/var/log/fabricmanager.log";
+          LOG_APPEND_TO_LOG=1;
+          LOG_FILE_MAX_SIZE=1024;
+          LOG_USE_SYSLOG=0;
+          DAEMONIZE=1;
+          BIND_INTERFACE_IP="127.0.0.1";
+          STARTING_TCP_PORT=16000;
+          FABRIC_MODE=0;
+          FABRIC_MODE_RESTART=0;
+          STATE_FILE_NAME="/var/tmp/fabricmanager.state";
+          FM_CMD_BIND_INTERFACE="127.0.0.1";
+          FM_CMD_PORT_NUMBER=6666;
+          FM_STAY_RESIDENT_ON_FAILURES=0;
+          ACCESS_LINK_FAILURE_MODE=0;
+          TRUNK_LINK_FAILURE_MODE=0;
+          NVSWITCH_FAILURE_MODE=0;
+          ABORT_CUDA_JOBS_ON_FM_EXIT=1;
+          TOPOLOGY_FILE_PATH=nvidia_x11.fabricmanager + "/share/nvidia-fabricmanager/nvidia/nvswitch";
+        }
+        '';
+        description = lib.mdDoc ''
+          Additional configuration options for fabricmanager.
+        '';
+      };
+
       powerManagement.enable = lib.mkEnableOption (lib.mdDoc ''
         experimental power management through systemd. For more information, see
         the NVIDIA docs, on Chapter 21. Configuring Power Management Support.
@@ -167,9 +224,15 @@ in {
         It also drastically increases the time the driver needs to clock down after load.
       '');
 
-      package = lib.mkPackageOptionMD config.boot.kernelPackages.nvidiaPackages "nvidia_x11" {
-        default = "stable";
+      package = lib.mkOption {
+        default = config.boot.kernelPackages.nvidiaPackages."${if cfg.datacenter.enable then "dc" else "stable"}";
+        defaultText = lib.literalExpression ''
+          config.boot.kernelPackages.nvidiaPackages."\$\{if cfg.datacenter.enable then "dc" else "stable"}"
+        '';
         example = lib.mdDoc "config.boot.kernelPackages.nvidiaPackages.legacy_470";
+        description = lib.mdDoc ''
+          The NVIDIA driver package to use.
+        '';
       };
 
       open = lib.mkEnableOption (lib.mdDoc ''
@@ -188,8 +251,46 @@ in {
       then pCfg.intelBusId
       else pCfg.amdgpuBusId;
   in
-    lib.mkIf (nvidia_x11 != null) {
-      assertions = [
+    lib.mkIf (nvidia_x11 != null) (lib.mkMerge [
+      # Common
+      ({
+        assertions = [
+          {
+            assertion = !(x11Enabled && cfg.datacenter.enable);
+            message = "You cannot configure both X11 and Data Center drivers at the same time.";
+          }
+        ];
+        boot = {
+          blacklistedKernelModules = ["nouveau" "nvidiafb"];
+          kernelModules = [ "nvidia-uvm" ];
+        };
+        systemd.tmpfiles.rules =
+          lib.optional config.virtualisation.docker.enableNvidia
+            "L+ /run/nvidia-docker/bin - - - - ${nvidia_x11.bin}/origBin";
+        services.udev.extraRules =
+        ''
+          # Create /dev/nvidia-uvm when the nvidia-uvm module is loaded.
+          KERNEL=="nvidia", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidiactl c $$(grep nvidia-frontend /proc/devices | cut -d \  -f 1) 255'"
+          KERNEL=="nvidia", RUN+="${pkgs.runtimeShell} -c 'for i in $$(cat /proc/driver/nvidia/gpus/*/information | grep Minor | cut -d \  -f 4); do mknod -m 666 /dev/nvidia$${i} c $$(grep nvidia-frontend /proc/devices | cut -d \  -f 1) $${i}; done'"
+          KERNEL=="nvidia_modeset", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-modeset c $$(grep nvidia-frontend /proc/devices | cut -d \  -f 1) 254'"
+          KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm c $$(grep nvidia-uvm /proc/devices | cut -d \  -f 1) 0'"
+          KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm-tools c $$(grep nvidia-uvm /proc/devices | cut -d \  -f 1) 1'"
+        '';
+        hardware.opengl = {
+          extraPackages = [
+            nvidia_x11.out
+          ];
+          extraPackages32 = [
+            nvidia_x11.lib32
+          ];
+        };
+        environment.systemPackages = [
+          nvidia_x11.bin
+        ];
+      })
+      # X11
+      (lib.mkIf x11Enabled {
+        assertions = [
         {
           assertion = primeEnabled -> pCfg.intelBusId == "" || pCfg.amdgpuBusId == "";
           message = "You cannot configure both an Intel iGPU and an AMD APU. Pick the one corresponding to your processor.";
@@ -248,227 +349,207 @@ in {
         {
           assertion = cfg.dynamicBoost.enable -> lib.versionAtLeast nvidia_x11.version "510.39.01";
           message = "NVIDIA's Dynamic Boost feature only exists on versions >= 510.39.01";
-        }
-      ];
-
-      # If Optimus/PRIME is enabled, we:
-      # - Specify the configured NVIDIA GPU bus ID in the Device section for the
-      #   "nvidia" driver.
-      # - Add the AllowEmptyInitialConfiguration option to the Screen section for the
-      #   "nvidia" driver, in order to allow the X server to start without any outputs.
-      # - Add a separate Device section for the Intel GPU, using the "modesetting"
-      #   driver and with the configured BusID.
-      # - OR add a separate Device section for the AMD APU, using the "amdgpu"
-      #   driver and with the configures BusID.
-      # - Reference that Device section from the ServerLayout section as an inactive
-      #   device.
-      # - Configure the display manager to run specific `xrandr` commands which will
-      #   configure/enable displays connected to the Intel iGPU / AMD APU.
-
-      # reverse sync implies offloading
-      hardware.nvidia.prime.offload.enable = lib.mkDefault reverseSyncCfg.enable;
-
-      services.xserver.drivers =
-        lib.optional primeEnabled {
-          name = igpuDriver;
-          display = offloadCfg.enable;
-          modules = lib.optional (igpuDriver == "amdgpu") pkgs.xorg.xf86videoamdgpu;
-          deviceSection =
-            ''
-              BusID "${igpuBusId}"
-            ''
-            + lib.optionalString (syncCfg.enable && igpuDriver != "amdgpu") ''
-              Option "AccelMethod" "none"
-            '';
-        }
-        ++ lib.singleton {
-          name = "nvidia";
-          modules = [nvidia_x11.bin];
-          display = !offloadCfg.enable;
-          deviceSection =
-            lib.optionalString primeEnabled
-            ''
-              BusID "${pCfg.nvidiaBusId}"
-            ''
-            + lib.optionalString pCfg.allowExternalGpu ''
-              Option "AllowExternalGpus"
-            '';
-          screenSection =
-            ''
-              Option "RandRRotation" "on"
-            ''
-            + lib.optionalString syncCfg.enable ''
-              Option "AllowEmptyInitialConfiguration"
-            ''
-            + lib.optionalString cfg.forceFullCompositionPipeline ''
-              Option         "metamodes" "nvidia-auto-select +0+0 {ForceFullCompositionPipeline=On}"
-              Option         "AllowIndirectGLXProtocol" "off"
-              Option         "TripleBuffer" "on"
-            '';
-        };
-
-      services.xserver.serverLayoutSection =
-        lib.optionalString syncCfg.enable ''
-          Inactive "Device-${igpuDriver}[0]"
-        ''
-        + lib.optionalString reverseSyncCfg.enable ''
-          Inactive "Device-nvidia[0]"
-        ''
-        + lib.optionalString offloadCfg.enable ''
-          Option "AllowNVIDIAGPUScreens"
-        '';
-
-      services.xserver.displayManager.setupCommands = let
-        gpuProviderName =
-          if igpuDriver == "amdgpu"
-          then
-            # find the name of the provider if amdgpu
-            "`${lib.getExe pkgs.xorg.xrandr} --listproviders | ${lib.getExe pkgs.gnugrep} -i AMD | ${lib.getExe pkgs.gnused} -n 's/^.*name://p'`"
-          else igpuDriver;
-        providerCmdParams =
-          if syncCfg.enable
-          then "\"${gpuProviderName}\" NVIDIA-0"
-          else "NVIDIA-G0 \"${gpuProviderName}\"";
-      in
-        lib.optionalString (syncCfg.enable || reverseSyncCfg.enable) ''
-          # Added by nvidia configuration module for Optimus/PRIME.
-          ${lib.getExe pkgs.xorg.xrandr} --setprovideroutputsource ${providerCmdParams}
-          ${lib.getExe pkgs.xorg.xrandr} --auto
-        '';
-
-      environment.etc = {
-        "nvidia/nvidia-application-profiles-rc" = lib.mkIf nvidia_x11.useProfiles {source = "${nvidia_x11.bin}/share/nvidia/nvidia-application-profiles-rc";};
+        }];
+
+        # If Optimus/PRIME is enabled, we:
+        # - Specify the configured NVIDIA GPU bus ID in the Device section for the
+        #   "nvidia" driver.
+        # - Add the AllowEmptyInitialConfiguration option to the Screen section for the
+        #   "nvidia" driver, in order to allow the X server to start without any outputs.
+        # - Add a separate Device section for the Intel GPU, using the "modesetting"
+        #   driver and with the configured BusID.
+        # - OR add a separate Device section for the AMD APU, using the "amdgpu"
+        #   driver and with the configures BusID.
+        # - Reference that Device section from the ServerLayout section as an inactive
+        #   device.
+        # - Configure the display manager to run specific `xrandr` commands which will
+        #   configure/enable displays connected to the Intel iGPU / AMD APU.
+
+        # reverse sync implies offloading
+        hardware.nvidia.prime.offload.enable = lib.mkDefault reverseSyncCfg.enable;
+
+        services.xserver.drivers =
+          lib.optional primeEnabled {
+            name = igpuDriver;
+            display = offloadCfg.enable;
+            modules = lib.optional (igpuDriver == "amdgpu") pkgs.xorg.xf86videoamdgpu;
+            deviceSection =
+              ''
+                BusID "${igpuBusId}"
+              ''
+              + lib.optionalString (syncCfg.enable && igpuDriver != "amdgpu") ''
+                Option "AccelMethod" "none"
+              '';
+          }
+          ++ lib.singleton {
+            name = "nvidia";
+            modules = [nvidia_x11.bin];
+            display = !offloadCfg.enable;
+            deviceSection =
+              lib.optionalString primeEnabled
+              ''
+                BusID "${pCfg.nvidiaBusId}"
+              ''
+              + lib.optionalString pCfg.allowExternalGpu ''
+                Option "AllowExternalGpus"
+              '';
+            screenSection =
+              ''
+                Option "RandRRotation" "on"
+              ''
+              + lib.optionalString syncCfg.enable ''
+                Option "AllowEmptyInitialConfiguration"
+              ''
+              + lib.optionalString cfg.forceFullCompositionPipeline ''
+                Option         "metamodes" "nvidia-auto-select +0+0 {ForceFullCompositionPipeline=On}"
+                Option         "AllowIndirectGLXProtocol" "off"
+                Option         "TripleBuffer" "on"
+              '';
+          };
 
-        # 'nvidia_x11' installs it's files to /run/opengl-driver/...
-        "egl/egl_external_platform.d".source = "/run/opengl-driver/share/egl/egl_external_platform.d/";
-      };
+        services.xserver.serverLayoutSection =
+          lib.optionalString syncCfg.enable ''
+            Inactive "Device-${igpuDriver}[0]"
+          ''
+          + lib.optionalString reverseSyncCfg.enable ''
+            Inactive "Device-nvidia[0]"
+          ''
+          + lib.optionalString offloadCfg.enable ''
+            Option "AllowNVIDIAGPUScreens"
+          '';
+
+        services.xserver.displayManager.setupCommands = let
+          gpuProviderName =
+            if igpuDriver == "amdgpu"
+            then
+              # find the name of the provider if amdgpu
+              "`${lib.getExe pkgs.xorg.xrandr} --listproviders | ${lib.getExe pkgs.gnugrep} -i AMD | ${lib.getExe pkgs.gnused} -n 's/^.*name://p'`"
+            else igpuDriver;
+          providerCmdParams =
+            if syncCfg.enable
+            then "\"${gpuProviderName}\" NVIDIA-0"
+            else "NVIDIA-G0 \"${gpuProviderName}\"";
+        in
+          lib.optionalString (syncCfg.enable || reverseSyncCfg.enable) ''
+            # Added by nvidia configuration module for Optimus/PRIME.
+            ${lib.getExe pkgs.xorg.xrandr} --setprovideroutputsource ${providerCmdParams}
+            ${lib.getExe pkgs.xorg.xrandr} --auto
+          '';
+
+        environment.etc = {
+          "nvidia/nvidia-application-profiles-rc" = lib.mkIf nvidia_x11.useProfiles {source = "${nvidia_x11.bin}/share/nvidia/nvidia-application-profiles-rc";};
+
+          # 'nvidia_x11' installs it's files to /run/opengl-driver/...
+          "egl/egl_external_platform.d".source = "/run/opengl-driver/share/egl/egl_external_platform.d/";
+        };
 
-      hardware.opengl = {
-        extraPackages = [
-          nvidia_x11.out
-          pkgs.nvidia-vaapi-driver
-        ];
-        extraPackages32 = [
-          nvidia_x11.lib32
-          pkgs.pkgsi686Linux.nvidia-vaapi-driver
-        ];
-      };
-      environment.systemPackages =
-        [nvidia_x11.bin]
-        ++ lib.optional cfg.nvidiaSettings nvidia_x11.settings
-        ++ lib.optional cfg.nvidiaPersistenced nvidia_x11.persistenced
-        ++ lib.optional offloadCfg.enableOffloadCmd
-        (pkgs.writeShellScriptBin "nvidia-offload" ''
-          export __NV_PRIME_RENDER_OFFLOAD=1
-          export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0
-          export __GLX_VENDOR_LIBRARY_NAME=nvidia
-          export __VK_LAYER_NV_optimus=NVIDIA_only
-          exec "$@"
-        '');
-
-      systemd.packages = lib.optional cfg.powerManagement.enable nvidia_x11.out;
-
-      systemd.services = let
-        nvidiaService = state: {
-          description = "NVIDIA system ${state} actions";
-          path = [pkgs.kbd];
-          serviceConfig = {
-            Type = "oneshot";
-            ExecStart = "${nvidia_x11.out}/bin/nvidia-sleep.sh '${state}'";
-          };
-          before = ["systemd-${state}.service"];
-          requiredBy = ["systemd-${state}.service"];
+        hardware.opengl = {
+          extraPackages = [
+            pkgs.nvidia-vaapi-driver
+          ];
+          extraPackages32 = [
+            pkgs.pkgsi686Linux.nvidia-vaapi-driver
+          ];
         };
-      in
-        lib.mkMerge [
-          (lib.mkIf cfg.powerManagement.enable {
-            nvidia-suspend = nvidiaService "suspend";
-            nvidia-hibernate = nvidiaService "hibernate";
-            nvidia-resume =
-              (nvidiaService "resume")
-              // {
-                before = [];
-                after = ["systemd-suspend.service" "systemd-hibernate.service"];
-                requiredBy = ["systemd-suspend.service" "systemd-hibernate.service"];
-              };
-          })
-          (lib.mkIf cfg.nvidiaPersistenced {
-            "nvidia-persistenced" = {
-              description = "NVIDIA Persistence Daemon";
-              wantedBy = ["multi-user.target"];
-              serviceConfig = {
-                Type = "forking";
-                Restart = "always";
-                PIDFile = "/var/run/nvidia-persistenced/nvidia-persistenced.pid";
-                ExecStart = "${lib.getExe nvidia_x11.persistenced} --verbose";
-                ExecStopPost = "${pkgs.coreutils}/bin/rm -rf /var/run/nvidia-persistenced";
-              };
+        environment.systemPackages =
+          lib.optional cfg.nvidiaSettings nvidia_x11.settings
+          ++ lib.optional cfg.nvidiaPersistenced nvidia_x11.persistenced
+          ++ lib.optional offloadCfg.enableOffloadCmd
+          (pkgs.writeShellScriptBin "nvidia-offload" ''
+            export __NV_PRIME_RENDER_OFFLOAD=1
+            export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0
+            export __GLX_VENDOR_LIBRARY_NAME=nvidia
+            export __VK_LAYER_NV_optimus=NVIDIA_only
+            exec "$@"
+          '');
+
+        systemd.packages = lib.optional cfg.powerManagement.enable nvidia_x11.out;
+
+        systemd.services = let
+          nvidiaService = state: {
+            description = "NVIDIA system ${state} actions";
+            path = [pkgs.kbd];
+            serviceConfig = {
+              Type = "oneshot";
+              ExecStart = "${nvidia_x11.out}/bin/nvidia-sleep.sh '${state}'";
             };
-          })
-          (lib.mkIf cfg.dynamicBoost.enable {
-            "nvidia-powerd" = {
-              description = "nvidia-powerd service";
-              path = [
-                pkgs.util-linux # nvidia-powerd wants lscpu
-              ];
-              wantedBy = ["multi-user.target"];
-              serviceConfig = {
-                Type = "dbus";
-                BusName = "nvidia.powerd.server";
-                ExecStart = "${nvidia_x11.bin}/bin/nvidia-powerd";
+            before = ["systemd-${state}.service"];
+            requiredBy = ["systemd-${state}.service"];
+          };
+        in
+          lib.mkMerge [
+            (lib.mkIf cfg.powerManagement.enable {
+              nvidia-suspend = nvidiaService "suspend";
+              nvidia-hibernate = nvidiaService "hibernate";
+              nvidia-resume =
+                (nvidiaService "resume")
+                // {
+                  before = [];
+                  after = ["systemd-suspend.service" "systemd-hibernate.service"];
+                  requiredBy = ["systemd-suspend.service" "systemd-hibernate.service"];
+                };
+            })
+            (lib.mkIf cfg.nvidiaPersistenced {
+              "nvidia-persistenced" = {
+                description = "NVIDIA Persistence Daemon";
+                wantedBy = ["multi-user.target"];
+                serviceConfig = {
+                  Type = "forking";
+                  Restart = "always";
+                  PIDFile = "/var/run/nvidia-persistenced/nvidia-persistenced.pid";
+                  ExecStart = "${lib.getExe nvidia_x11.persistenced} --verbose";
+                  ExecStopPost = "${pkgs.coreutils}/bin/rm -rf /var/run/nvidia-persistenced";
+                };
               };
-            };
-          })
-        ];
-
-      services.acpid.enable = true;
-
-      services.dbus.packages = lib.optional cfg.dynamicBoost.enable nvidia_x11.bin;
-
-      hardware.firmware = lib.optional cfg.open nvidia_x11.firmware;
-
-      systemd.tmpfiles.rules =
-        lib.optional config.virtualisation.docker.enableNvidia
-        "L+ /run/nvidia-docker/bin - - - - ${nvidia_x11.bin}/origBin"
-        ++ lib.optional (nvidia_x11.persistenced != null && config.virtualisation.docker.enableNvidia)
-        "L+ /run/nvidia-docker/extras/bin/nvidia-persistenced - - - - ${nvidia_x11.persistenced}/origBin/nvidia-persistenced";
-
-      boot = {
-        blacklistedKernelModules = ["nouveau" "nvidiafb"];
-
-        extraModulePackages =
-          if cfg.open
-          then [nvidia_x11.open]
-          else [nvidia_x11.bin];
-
-        # nvidia-uvm is required by CUDA applications.
-        kernelModules =
-          ["nvidia-uvm"]
-          ++ lib.optionals config.services.xserver.enable ["nvidia" "nvidia_modeset" "nvidia_drm"];
-
-        # If requested enable modesetting via kernel parameter.
-        kernelParams =
-          lib.optional (offloadCfg.enable || cfg.modesetting.enable) "nvidia-drm.modeset=1"
-          ++ lib.optional cfg.powerManagement.enable "nvidia.NVreg_PreserveVideoMemoryAllocations=1"
-          ++ lib.optional cfg.open "nvidia.NVreg_OpenRmEnableUnsupportedGpus=1"
-          ++ lib.optional (config.boot.kernelPackages.kernel.kernelAtLeast "6.2" && !ibtSupport) "ibt=off";
-
-        # enable finegrained power management
-        extraModprobeConfig = lib.optionalString cfg.powerManagement.finegrained ''
-          options nvidia "NVreg_DynamicPowerManagement=0x02"
-        '';
-      };
-
-      services.udev.extraRules =
-        ''
-          # Create /dev/nvidia-uvm when the nvidia-uvm module is loaded.
-          KERNEL=="nvidia", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidiactl c $$(grep nvidia-frontend /proc/devices | cut -d \  -f 1) 255'"
-          KERNEL=="nvidia", RUN+="${pkgs.runtimeShell} -c 'for i in $$(cat /proc/driver/nvidia/gpus/*/information | grep Minor | cut -d \  -f 4); do mknod -m 666 /dev/nvidia$${i} c $$(grep nvidia-frontend /proc/devices | cut -d \  -f 1) $${i}; done'"
-          KERNEL=="nvidia_modeset", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-modeset c $$(grep nvidia-frontend /proc/devices | cut -d \  -f 1) 254'"
-          KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm c $$(grep nvidia-uvm /proc/devices | cut -d \  -f 1) 0'"
-          KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm-tools c $$(grep nvidia-uvm /proc/devices | cut -d \  -f 1) 1'"
-        ''
-        + lib.optionalString cfg.powerManagement.finegrained (
+            })
+            (lib.mkIf cfg.dynamicBoost.enable {
+              "nvidia-powerd" = {
+                description = "nvidia-powerd service";
+                path = [
+                  pkgs.util-linux # nvidia-powerd wants lscpu
+                ];
+                wantedBy = ["multi-user.target"];
+                serviceConfig = {
+                  Type = "dbus";
+                  BusName = "nvidia.powerd.server";
+                  ExecStart = "${nvidia_x11.bin}/bin/nvidia-powerd";
+                };
+              };
+            })
+          ];
+        services.acpid.enable = true;
+
+        services.dbus.packages = lib.optional cfg.dynamicBoost.enable nvidia_x11.bin;
+
+        hardware.firmware = lib.optional cfg.open nvidia_x11.firmware;
+
+        systemd.tmpfiles.rules =
+          lib.optional (nvidia_x11.persistenced != null && config.virtualisation.docker.enableNvidia)
+          "L+ /run/nvidia-docker/extras/bin/nvidia-persistenced - - - - ${nvidia_x11.persistenced}/origBin/nvidia-persistenced";
+
+        boot = {
+          extraModulePackages =
+            if cfg.open
+            then [nvidia_x11.open]
+            else [nvidia_x11.bin];
+          # nvidia-uvm is required by CUDA applications.
+          kernelModules =
+            lib.optionals config.services.xserver.enable ["nvidia" "nvidia_modeset" "nvidia_drm"];
+
+          # If requested enable modesetting via kernel parameter.
+          kernelParams =
+            lib.optional (offloadCfg.enable || cfg.modesetting.enable) "nvidia-drm.modeset=1"
+            ++ lib.optional cfg.powerManagement.enable "nvidia.NVreg_PreserveVideoMemoryAllocations=1"
+            ++ lib.optional cfg.open "nvidia.NVreg_OpenRmEnableUnsupportedGpus=1"
+            ++ lib.optional (config.boot.kernelPackages.kernel.kernelAtLeast "6.2" && !ibtSupport) "ibt=off";
+
+          # enable finegrained power management
+          extraModprobeConfig = lib.optionalString cfg.powerManagement.finegrained ''
+            options nvidia "NVreg_DynamicPowerManagement=0x02"
+          '';
+        };
+        services.udev.extraRules =
+          lib.optionalString cfg.powerManagement.finegrained (
           lib.optionalString (lib.versionOlder config.boot.kernelPackages.kernel.version "5.5") ''
             # Remove NVIDIA USB xHCI Host Controller devices, if present
             ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c0330", ATTR{remove}="1"
@@ -489,5 +570,30 @@ in {
             ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="on"
           ''
         );
-    };
+      })
+      # Data Center
+      (lib.mkIf (cfg.datacenter.enable) {
+        boot.extraModulePackages = [
+          nvidia_x11.bin
+        ];
+        systemd.services.nvidia-fabricmanager = {
+          enable = true;
+          description = "Start NVIDIA NVLink Management";
+          wantedBy = [ "multi-user.target" ];
+          unitConfig.After = [ "network-online.target" ];
+          unitConfig.Requires = [ "network-online.target" ];
+          serviceConfig = {
+            Type = "forking";
+            TimeoutStartSec = 240;
+            ExecStart = let
+              nv-fab-conf = settingsFormat.generate "fabricmanager.conf" cfg.datacenter.settings;
+              in
+                nvidia_x11.fabricmanager + "/bin/nv-fabricmanager -c " + nv-fab-conf;
+            LimitCORE="infinity";
+          };
+        };
+        environment.systemPackages =
+          lib.optional cfg.datacenter.enable nvidia_x11.fabricmanager;
+      })
+    ]);
 }
diff --git a/nixpkgs/nixos/modules/module-list.nix b/nixpkgs/nixos/modules/module-list.nix
index c0abfaa08817..05b0415d8558 100644
--- a/nixpkgs/nixos/modules/module-list.nix
+++ b/nixpkgs/nixos/modules/module-list.nix
@@ -279,6 +279,7 @@
   ./programs/xss-lock.nix
   ./programs/xwayland.nix
   ./programs/yabar.nix
+  ./programs/yazi.nix
   ./programs/zmap.nix
   ./programs/zsh/oh-my-zsh.nix
   ./programs/zsh/zsh-autoenv.nix
@@ -647,6 +648,7 @@
   ./services/misc/etesync-dav.nix
   ./services/misc/evdevremapkeys.nix
   ./services/misc/felix.nix
+  ./services/misc/forgejo.nix
   ./services/misc/freeswitch.nix
   ./services/misc/fstrim.nix
   ./services/misc/gammu-smsd.nix
@@ -1251,6 +1253,7 @@
   ./services/web-apps/matomo.nix
   ./services/web-apps/mattermost.nix
   ./services/web-apps/mediawiki.nix
+  ./services/web-apps/meme-bingo-web.nix
   ./services/web-apps/miniflux.nix
   ./services/web-apps/monica.nix
   ./services/web-apps/moodle.nix
diff --git a/nixpkgs/nixos/modules/programs/bash/bash.nix b/nixpkgs/nixos/modules/programs/bash/bash.nix
index 286faeadc489..7d3322ea5e50 100644
--- a/nixpkgs/nixos/modules/programs/bash/bash.nix
+++ b/nixpkgs/nixos/modules/programs/bash/bash.nix
@@ -81,7 +81,7 @@ in
           if [ "$TERM" != "dumb" ] || [ -n "$INSIDE_EMACS" ]; then
             PROMPT_COLOR="1;31m"
             ((UID)) && PROMPT_COLOR="1;32m"
-            if [ -n "$INSIDE_EMACS" ] || [ "$TERM" = "eterm" ] || [ "$TERM" = "eterm-color" ]; then
+            if [ -n "$INSIDE_EMACS" ]; then
               # Emacs term mode doesn't support xterm title escape sequence (\e]0;)
               PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] "
             else
diff --git a/nixpkgs/nixos/modules/programs/clash-verge.nix b/nixpkgs/nixos/modules/programs/clash-verge.nix
index 29977be3858f..57a1c0377edb 100644
--- a/nixpkgs/nixos/modules/programs/clash-verge.nix
+++ b/nixpkgs/nixos/modules/programs/clash-verge.nix
@@ -2,17 +2,9 @@
 
 {
   options.programs.clash-verge = {
-    enable = lib.mkEnableOption (lib.mdDoc ''
-      Clash Verge.
-    '');
-
-    autoStart = lib.mkEnableOption (lib.mdDoc ''
-      Clash Verge Auto Launch.
-    '');
-
-    tunMode = lib.mkEnableOption (lib.mdDoc ''
-      Clash Verge Tun Mode.
-    '');
+    enable = lib.mkEnableOption (lib.mdDoc "Clash Verge");
+    autoStart = lib.mkEnableOption (lib.mdDoc "Clash Verge auto launch");
+    tunMode = lib.mkEnableOption (lib.mdDoc "Clash Verge TUN mode");
   };
 
   config =
diff --git a/nixpkgs/nixos/modules/programs/direnv.nix b/nixpkgs/nixos/modules/programs/direnv.nix
index 53717fae11a0..1a80cb202806 100644
--- a/nixpkgs/nixos/modules/programs/direnv.nix
+++ b/nixpkgs/nixos/modules/programs/direnv.nix
@@ -32,15 +32,6 @@ in {
       the hiding of direnv logging
     '');
 
-    persistDerivations =
-      (lib.mkEnableOption (lib.mdDoc ''
-        setting keep-derivations and keep-outputs to true
-        to prevent shells from getting garbage collected
-      ''))
-      // {
-        default = true;
-      };
-
     loadInNixShell =
       lib.mkEnableOption (lib.mdDoc ''
         loading direnv in `nix-shell` `nix shell` or `nix develop`
@@ -62,6 +53,10 @@ in {
     };
   };
 
+  imports = [
+    (lib.mkRemovedOptionModule ["programs" "direnv" "persistDerivations"] "persistDerivations was removed as it is on longer necessary")
+  ];
+
   config = lib.mkIf cfg.enable {
 
     programs = {
@@ -87,11 +82,6 @@ in {
       '';
     };
 
-    nix.settings = lib.mkIf cfg.persistDerivations {
-      keep-outputs = true;
-      keep-derivations = true;
-    };
-
     environment = {
       systemPackages =
         if cfg.loadInNixShell then [cfg.package]
diff --git a/nixpkgs/nixos/modules/programs/yazi.nix b/nixpkgs/nixos/modules/programs/yazi.nix
index 3416bca06679..973f5c0122c2 100644
--- a/nixpkgs/nixos/modules/programs/yazi.nix
+++ b/nixpkgs/nixos/modules/programs/yazi.nix
@@ -45,5 +45,9 @@ in
         names);
     };
   };
-  meta.maintainers = with lib.maintainers; [ linsui ];
+  meta = {
+    maintainers = with lib.maintainers; [ linsui ];
+    # The version of the package is used in the doc.
+    buildDocsInSandbox = false;
+  };
 }
diff --git a/nixpkgs/nixos/modules/security/acme/default.md b/nixpkgs/nixos/modules/security/acme/default.md
index 8ff97b55f685..31548ad181a7 100644
--- a/nixpkgs/nixos/modules/security/acme/default.md
+++ b/nixpkgs/nixos/modules/security/acme/default.md
@@ -189,7 +189,7 @@ security.acme.defaults.email = "admin+acme@example.com";
 security.acme.certs."example.com" = {
   domain = "*.example.com";
   dnsProvider = "rfc2136";
-  credentialsFile = "/var/lib/secrets/certs.secret";
+  environmentFile = "/var/lib/secrets/certs.secret";
   # We don't need to wait for propagation since this is a local DNS server
   dnsPropagationCheck = false;
 };
@@ -256,7 +256,7 @@ security.acme.acceptTerms = true;
 security.acme.defaults.email = "admin+acme@example.com";
 security.acme.defaults = {
   dnsProvider = "rfc2136";
-  credentialsFile = "/var/lib/secrets/certs.secret";
+  environmentFile = "/var/lib/secrets/certs.secret";
   # We don't need to wait for propagation since this is a local DNS server
   dnsPropagationCheck = false;
 };
diff --git a/nixpkgs/nixos/modules/security/acme/default.nix b/nixpkgs/nixos/modules/security/acme/default.nix
index 222a25cf11dc..92bed172f452 100644
--- a/nixpkgs/nixos/modules/security/acme/default.nix
+++ b/nixpkgs/nixos/modules/security/acme/default.nix
@@ -362,8 +362,14 @@ let
           "/var/lib/acme/.lego/${cert}/${certDir}:/tmp/certificates"
         ];
 
-        # Only try loading the credentialsFile if the dns challenge is enabled
-        EnvironmentFile = mkIf useDns data.credentialsFile;
+        # Only try loading the environmentFile if the dns challenge is enabled
+        EnvironmentFile = mkIf useDns data.environmentFile;
+
+        Environment = mkIf useDns
+          (mapAttrsToList (k: v: ''"${k}=%d/${k}"'') data.credentialFiles);
+
+        LoadCredential = mkIf useDns
+          (mapAttrsToList (k: v: "${k}:${v}") data.credentialFiles);
 
         # Run as root (Prefixed with +)
         ExecStartPost = "+" + (pkgs.writeShellScript "acme-postrun" ''
@@ -496,6 +502,10 @@ let
       defaultText = if isDefaults then default else literalExpression "config.security.acme.defaults.${name}";
     };
   in {
+    imports = [
+      (mkRenamedOptionModule [ "credentialsFile" ] [ "environmentFile" ])
+    ];
+
     options = {
       validMinDays = mkOption {
         type = types.int;
@@ -607,9 +617,9 @@ let
         '';
       };
 
-      credentialsFile = mkOption {
+      environmentFile = mkOption {
         type = types.nullOr types.path;
-        inherit (defaultAndText "credentialsFile" null) default defaultText;
+        inherit (defaultAndText "environmentFile" null) default defaultText;
         description = lib.mdDoc ''
           Path to an EnvironmentFile for the cert's service containing any required and
           optional environment variables for your selected dnsProvider.
@@ -619,6 +629,24 @@ let
         example = "/var/src/secrets/example.org-route53-api-token";
       };
 
+      credentialFiles = mkOption {
+        type = types.attrsOf (types.path);
+        inherit (defaultAndText "credentialFiles" {}) default defaultText;
+        description = lib.mdDoc ''
+          Environment variables suffixed by "_FILE" to set for the cert's service
+          for your selected dnsProvider.
+          To find out what values you need to set, consult the documentation at
+          <https://go-acme.github.io/lego/dns/> for the corresponding dnsProvider.
+          This allows to securely pass credential files to lego by leveraging systemd
+          credentials.
+        '';
+        example = literalExpression ''
+          {
+            "RFC2136_TSIG_SECRET_FILE" = "/run/secrets/tsig-secret-example.org";
+          }
+        '';
+      };
+
       dnsPropagationCheck = mkOption {
         type = types.bool;
         inherit (defaultAndText "dnsPropagationCheck" true) default defaultText;
@@ -929,6 +957,13 @@ in {
             `security.acme.certs.${cert}.listenHTTP` must be provided.
           '';
         }
+        {
+          assertion = all (hasSuffix "_FILE") (attrNames data.credentialFiles);
+          message = ''
+            Option `security.acme.certs.${cert}.credentialFiles` can only be
+            used for variables suffixed by "_FILE".
+          '';
+        }
       ]) cfg.certs));
 
       users.users.acme = {
diff --git a/nixpkgs/nixos/modules/security/pam.nix b/nixpkgs/nixos/modules/security/pam.nix
index a431817fe1bb..d83259ccbebc 100644
--- a/nixpkgs/nixos/modules/security/pam.nix
+++ b/nixpkgs/nixos/modules/security/pam.nix
@@ -1303,7 +1303,7 @@ in
 
     security.pam.enableEcryptfs = mkEnableOption (lib.mdDoc "eCryptfs PAM module (mounting ecryptfs home directory on login)");
     security.pam.enableFscrypt = mkEnableOption (lib.mdDoc ''
-      Enables fscrypt to automatically unlock directories with the user's login password.
+      fscrypt to automatically unlock directories with the user's login password.
 
       This also enables a service at security.pam.services.fscrypt which is used by
       fscrypt to verify the user's password when setting up a new protector. If you
diff --git a/nixpkgs/nixos/modules/services/audio/tts.nix b/nixpkgs/nixos/modules/services/audio/tts.nix
index 1a355c8ee39f..0d93224ec030 100644
--- a/nixpkgs/nixos/modules/services/audio/tts.nix
+++ b/nixpkgs/nixos/modules/services/audio/tts.nix
@@ -134,6 +134,7 @@ in
           ProtectProc = "invisible";
           ProcSubset = "pid";
           RestrictAddressFamilies = [
+            "AF_UNIX"
             "AF_INET"
             "AF_INET6"
           ];
diff --git a/nixpkgs/nixos/modules/services/misc/forgejo.nix b/nixpkgs/nixos/modules/services/misc/forgejo.nix
new file mode 100644
index 000000000000..f26658b7bcb4
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/misc/forgejo.nix
@@ -0,0 +1,668 @@
+{ config, lib, options, pkgs, ... }:
+
+let
+  cfg = config.services.forgejo;
+  opt = options.services.forgejo;
+  format = pkgs.formats.ini { };
+
+  exe = lib.getExe cfg.package;
+
+  pg = config.services.postgresql;
+  useMysql = cfg.database.type == "mysql";
+  usePostgresql = cfg.database.type == "postgres";
+  useSqlite = cfg.database.type == "sqlite3";
+
+  inherit (lib)
+    literalExpression
+    mdDoc
+    mkChangedOptionModule
+    mkDefault
+    mkEnableOption
+    mkIf
+    mkMerge
+    mkOption
+    mkPackageOptionMD
+    mkRemovedOptionModule
+    mkRenamedOptionModule
+    optionalAttrs
+    optionals
+    optionalString
+    types
+    ;
+in
+{
+  imports = [
+    (mkRenamedOptionModule [ "services" "forgejo" "appName" ] [ "services" "forgejo" "settings" "DEFAULT" "APP_NAME" ])
+    (mkRemovedOptionModule [ "services" "forgejo" "extraConfig" ] "services.forgejo.extraConfig has been removed. Please use the freeform services.forgejo.settings option instead")
+    (mkRemovedOptionModule [ "services" "forgejo" "database" "password" ] "services.forgejo.database.password has been removed. Please use services.forgejo.database.passwordFile instead")
+
+    # copied from services.gitea; remove at some point
+    (mkRenamedOptionModule [ "services" "forgejo" "cookieSecure" ] [ "services" "forgejo" "settings" "session" "COOKIE_SECURE" ])
+    (mkRenamedOptionModule [ "services" "forgejo" "disableRegistration" ] [ "services" "forgejo" "settings" "service" "DISABLE_REGISTRATION" ])
+    (mkRenamedOptionModule [ "services" "forgejo" "domain" ] [ "services" "forgejo" "settings" "server" "DOMAIN" ])
+    (mkRenamedOptionModule [ "services" "forgejo" "httpAddress" ] [ "services" "forgejo" "settings" "server" "HTTP_ADDR" ])
+    (mkRenamedOptionModule [ "services" "forgejo" "httpPort" ] [ "services" "forgejo" "settings" "server" "HTTP_PORT" ])
+    (mkRenamedOptionModule [ "services" "forgejo" "log" "level" ] [ "services" "forgejo" "settings" "log" "LEVEL" ])
+    (mkRenamedOptionModule [ "services" "forgejo" "log" "rootPath" ] [ "services" "forgejo" "settings" "log" "ROOT_PATH" ])
+    (mkRenamedOptionModule [ "services" "forgejo" "rootUrl" ] [ "services" "forgejo" "settings" "server" "ROOT_URL" ])
+    (mkRenamedOptionModule [ "services" "forgejo" "ssh" "clonePort" ] [ "services" "forgejo" "settings" "server" "SSH_PORT" ])
+    (mkRenamedOptionModule [ "services" "forgejo" "staticRootPath" ] [ "services" "forgejo" "settings" "server" "STATIC_ROOT_PATH" ])
+    (mkChangedOptionModule [ "services" "forgejo" "enableUnixSocket" ] [ "services" "forgejo" "settings" "server" "PROTOCOL" ] (
+      config: if config.services.forgejo.enableUnixSocket then "http+unix" else "http"
+    ))
+    (mkRemovedOptionModule [ "services" "forgejo" "ssh" "enable" ] "services.forgejo.ssh.enable has been migrated into freeform setting services.forgejo.settings.server.DISABLE_SSH. Keep in mind that the setting is inverted")
+  ];
+
+  options = {
+    services.forgejo = {
+      enable = mkEnableOption (mdDoc "Forgejo");
+
+      package = mkPackageOptionMD pkgs "forgejo" { };
+
+      useWizard = mkOption {
+        default = false;
+        type = types.bool;
+        description = mdDoc ''
+          Whether to use the built-in installation wizard instead of
+          declaratively managing the {file}`app.ini` config file in nix.
+        '';
+      };
+
+      stateDir = mkOption {
+        default = "/var/lib/forgejo";
+        type = types.str;
+        description = mdDoc "Forgejo data directory.";
+      };
+
+      customDir = mkOption {
+        default = "${cfg.stateDir}/custom";
+        defaultText = literalExpression ''"''${config.${opt.stateDir}}/custom"'';
+        type = types.str;
+        description = mdDoc ''
+          Base directory for custom templates and other options.
+
+          If {option}`${opt.useWizard}` is disabled (default), this directory will also
+          hold secrets and the resulting {file}`app.ini` config at runtime.
+        '';
+      };
+
+      user = mkOption {
+        type = types.str;
+        default = "forgejo";
+        description = mdDoc "User account under which Forgejo runs.";
+      };
+
+      group = mkOption {
+        type = types.str;
+        default = "forgejo";
+        description = mdDoc "Group under which Forgejo runs.";
+      };
+
+      database = {
+        type = mkOption {
+          type = types.enum [ "sqlite3" "mysql" "postgres" ];
+          example = "mysql";
+          default = "sqlite3";
+          description = mdDoc "Database engine to use.";
+        };
+
+        host = mkOption {
+          type = types.str;
+          default = "127.0.0.1";
+          description = mdDoc "Database host address.";
+        };
+
+        port = mkOption {
+          type = types.port;
+          default = if !usePostgresql then 3306 else pg.port;
+          defaultText = literalExpression ''
+            if config.${opt.database.type} != "postgresql"
+            then 3306
+            else config.${options.services.postgresql.port}
+          '';
+          description = mdDoc "Database host port.";
+        };
+
+        name = mkOption {
+          type = types.str;
+          default = "forgejo";
+          description = mdDoc "Database name.";
+        };
+
+        user = mkOption {
+          type = types.str;
+          default = "forgejo";
+          description = mdDoc "Database user.";
+        };
+
+        passwordFile = mkOption {
+          type = types.nullOr types.path;
+          default = null;
+          example = "/run/keys/forgejo-dbpassword";
+          description = mdDoc ''
+            A file containing the password corresponding to
+            {option}`${opt.database.user}`.
+          '';
+        };
+
+        socket = mkOption {
+          type = types.nullOr types.path;
+          default = if (cfg.database.createDatabase && usePostgresql) then "/run/postgresql" else if (cfg.database.createDatabase && useMysql) then "/run/mysqld/mysqld.sock" else null;
+          defaultText = literalExpression "null";
+          example = "/run/mysqld/mysqld.sock";
+          description = mdDoc "Path to the unix socket file to use for authentication.";
+        };
+
+        path = mkOption {
+          type = types.str;
+          default = "${cfg.stateDir}/data/forgejo.db";
+          defaultText = literalExpression ''"''${config.${opt.stateDir}}/data/forgejo.db"'';
+          description = mdDoc "Path to the sqlite3 database file.";
+        };
+
+        createDatabase = mkOption {
+          type = types.bool;
+          default = true;
+          description = mdDoc "Whether to create a local database automatically.";
+        };
+      };
+
+      dump = {
+        enable = mkEnableOption (mdDoc "periodic dumps via the [built-in {command}`dump` command](https://forgejo.org/docs/latest/admin/command-line/#dump)");
+
+        interval = mkOption {
+          type = types.str;
+          default = "04:31";
+          example = "hourly";
+          description = mdDoc ''
+            Run a Forgejo dump at this interval. Runs by default at 04:31 every day.
+
+            The format is described in
+            {manpage}`systemd.time(7)`.
+          '';
+        };
+
+        backupDir = mkOption {
+          type = types.str;
+          default = "${cfg.stateDir}/dump";
+          defaultText = literalExpression ''"''${config.${opt.stateDir}}/dump"'';
+          description = mdDoc "Path to the directory where the dump archives will be stored.";
+        };
+
+        type = mkOption {
+          type = types.enum [ "zip" "tar" "tar.sz" "tar.gz" "tar.xz" "tar.bz2" "tar.br" "tar.lz4" "tar.zst" ];
+          default = "zip";
+          description = mdDoc "Archive format used to store the dump file.";
+        };
+
+        file = mkOption {
+          type = types.nullOr types.str;
+          default = null;
+          description = mdDoc "Filename to be used for the dump. If `null` a default name is chosen by forgejo.";
+          example = "forgejo-dump";
+        };
+      };
+
+      lfs = {
+        enable = mkOption {
+          type = types.bool;
+          default = false;
+          description = mdDoc "Enables git-lfs support.";
+        };
+
+        contentDir = mkOption {
+          type = types.str;
+          default = "${cfg.stateDir}/data/lfs";
+          defaultText = literalExpression ''"''${config.${opt.stateDir}}/data/lfs"'';
+          description = mdDoc "Where to store LFS files.";
+        };
+      };
+
+      repositoryRoot = mkOption {
+        type = types.str;
+        default = "${cfg.stateDir}/repositories";
+        defaultText = literalExpression ''"''${config.${opt.stateDir}}/repositories"'';
+        description = mdDoc "Path to the git repositories.";
+      };
+
+      mailerPasswordFile = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        example = "/run/keys/forgejo-mailpw";
+        description = mdDoc "Path to a file containing the SMTP password.";
+      };
+
+      settings = mkOption {
+        default = { };
+        description = mdDoc ''
+          Free-form settings written directly to the `app.ini` configfile file.
+          Refer to <https://forgejo.org/docs/latest/admin/config-cheat-sheet/> for supported values.
+        '';
+        example = literalExpression ''
+          {
+            DEFAULT = {
+              RUN_MODE = "dev";
+            };
+            "cron.sync_external_users" = {
+              RUN_AT_START = true;
+              SCHEDULE = "@every 24h";
+              UPDATE_EXISTING = true;
+            };
+            mailer = {
+              ENABLED = true;
+              MAILER_TYPE = "sendmail";
+              FROM = "do-not-reply@example.org";
+              SENDMAIL_PATH = "''${pkgs.system-sendmail}/bin/sendmail";
+            };
+            other = {
+              SHOW_FOOTER_VERSION = false;
+            };
+          }
+        '';
+        type = types.submodule {
+          freeformType = format.type;
+          options = {
+            log = {
+              ROOT_PATH = mkOption {
+                default = "${cfg.stateDir}/log";
+                defaultText = literalExpression ''"''${config.${opt.stateDir}}/log"'';
+                type = types.str;
+                description = mdDoc "Root path for log files.";
+              };
+              LEVEL = mkOption {
+                default = "Info";
+                type = types.enum [ "Trace" "Debug" "Info" "Warn" "Error" "Critical" ];
+                description = mdDoc "General log level.";
+              };
+            };
+
+            server = {
+              PROTOCOL = mkOption {
+                type = types.enum [ "http" "https" "fcgi" "http+unix" "fcgi+unix" ];
+                default = "http";
+                description = mdDoc ''Listen protocol. `+unix` means "over unix", not "in addition to."'';
+              };
+
+              HTTP_ADDR = mkOption {
+                type = types.either types.str types.path;
+                default = if lib.hasSuffix "+unix" cfg.settings.server.PROTOCOL then "/run/forgejo/forgejo.sock" else "0.0.0.0";
+                defaultText = literalExpression ''if lib.hasSuffix "+unix" cfg.settings.server.PROTOCOL then "/run/forgejo/forgejo.sock" else "0.0.0.0"'';
+                description = mdDoc "Listen address. Must be a path when using a unix socket.";
+              };
+
+              HTTP_PORT = mkOption {
+                type = types.port;
+                default = 3000;
+                description = mdDoc "Listen port. Ignored when using a unix socket.";
+              };
+
+              DOMAIN = mkOption {
+                type = types.str;
+                default = "localhost";
+                description = mdDoc "Domain name of your server.";
+              };
+
+              ROOT_URL = mkOption {
+                type = types.str;
+                default = "http://${cfg.settings.server.DOMAIN}:${toString cfg.settings.server.HTTP_PORT}/";
+                defaultText = literalExpression ''"http://''${config.services.forgejo.settings.server.DOMAIN}:''${toString config.services.forgejo.settings.server.HTTP_PORT}/"'';
+                description = mdDoc "Full public URL of Forgejo server.";
+              };
+
+              STATIC_ROOT_PATH = mkOption {
+                type = types.either types.str types.path;
+                default = cfg.package.data;
+                defaultText = literalExpression "config.${opt.package}.data";
+                example = "/var/lib/forgejo/data";
+                description = mdDoc "Upper level of template and static files path.";
+              };
+
+              DISABLE_SSH = mkOption {
+                type = types.bool;
+                default = false;
+                description = mdDoc "Disable external SSH feature.";
+              };
+
+              SSH_PORT = mkOption {
+                type = types.port;
+                default = 22;
+                example = 2222;
+                description = mdDoc ''
+                  SSH port displayed in clone URL.
+                  The option is required to configure a service when the external visible port
+                  differs from the local listening port i.e. if port forwarding is used.
+                '';
+              };
+            };
+
+            session = {
+              COOKIE_SECURE = mkOption {
+                type = types.bool;
+                default = false;
+                description = mdDoc ''
+                  Marks session cookies as "secure" as a hint for browsers to only send
+                  them via HTTPS. This option is recommend, if Forgejo is being served over HTTPS.
+                '';
+              };
+            };
+          };
+        };
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    assertions = [
+      {
+        assertion = cfg.database.createDatabase -> useSqlite || cfg.database.user == cfg.user;
+        message = "services.forgejo.database.user must match services.forgejo.user if the database is to be automatically provisioned";
+      }
+    ];
+
+    services.forgejo.settings = {
+      DEFAULT = {
+        RUN_MODE = mkDefault "prod";
+        RUN_USER = mkDefault cfg.user;
+        WORK_PATH = mkDefault cfg.stateDir;
+      };
+
+      database = mkMerge [
+        {
+          DB_TYPE = cfg.database.type;
+        }
+        (mkIf (useMysql || usePostgresql) {
+          HOST = if cfg.database.socket != null then cfg.database.socket else cfg.database.host + ":" + toString cfg.database.port;
+          NAME = cfg.database.name;
+          USER = cfg.database.user;
+          PASSWD = "#dbpass#";
+        })
+        (mkIf useSqlite {
+          PATH = cfg.database.path;
+        })
+        (mkIf usePostgresql {
+          SSL_MODE = "disable";
+        })
+      ];
+
+      repository = {
+        ROOT = cfg.repositoryRoot;
+      };
+
+      server = mkIf cfg.lfs.enable {
+        LFS_START_SERVER = true;
+        LFS_JWT_SECRET = "#lfsjwtsecret#";
+      };
+
+      session = {
+        COOKIE_NAME = mkDefault "session";
+      };
+
+      security = {
+        SECRET_KEY = "#secretkey#";
+        INTERNAL_TOKEN = "#internaltoken#";
+        INSTALL_LOCK = true;
+      };
+
+      mailer = mkIf (cfg.mailerPasswordFile != null) {
+        PASSWD = "#mailerpass#";
+      };
+
+      oauth2 = {
+        JWT_SECRET = "#oauth2jwtsecret#";
+      };
+
+      lfs = mkIf cfg.lfs.enable {
+        PATH = cfg.lfs.contentDir;
+      };
+    };
+
+    services.postgresql = optionalAttrs (usePostgresql && cfg.database.createDatabase) {
+      enable = mkDefault true;
+
+      ensureDatabases = [ cfg.database.name ];
+      ensureUsers = [
+        {
+          name = cfg.database.user;
+          ensurePermissions = { "DATABASE ${cfg.database.name}" = "ALL PRIVILEGES"; };
+        }
+      ];
+    };
+
+    services.mysql = optionalAttrs (useMysql && cfg.database.createDatabase) {
+      enable = mkDefault true;
+      package = mkDefault pkgs.mariadb;
+
+      ensureDatabases = [ cfg.database.name ];
+      ensureUsers = [
+        {
+          name = cfg.database.user;
+          ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
+        }
+      ];
+    };
+
+    systemd.tmpfiles.rules = [
+      "d '${cfg.dump.backupDir}' 0750 ${cfg.user} ${cfg.group} - -"
+      "z '${cfg.dump.backupDir}' 0750 ${cfg.user} ${cfg.group} - -"
+      "d '${cfg.repositoryRoot}' 0750 ${cfg.user} ${cfg.group} - -"
+      "z '${cfg.repositoryRoot}' 0750 ${cfg.user} ${cfg.group} - -"
+      "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -"
+      "d '${cfg.stateDir}/conf' 0750 ${cfg.user} ${cfg.group} - -"
+      "d '${cfg.customDir}' 0750 ${cfg.user} ${cfg.group} - -"
+      "d '${cfg.customDir}/conf' 0750 ${cfg.user} ${cfg.group} - -"
+      "d '${cfg.stateDir}/data' 0750 ${cfg.user} ${cfg.group} - -"
+      "d '${cfg.stateDir}/log' 0750 ${cfg.user} ${cfg.group} - -"
+      "z '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -"
+      "z '${cfg.stateDir}/.ssh' 0700 ${cfg.user} ${cfg.group} - -"
+      "z '${cfg.stateDir}/conf' 0750 ${cfg.user} ${cfg.group} - -"
+      "z '${cfg.customDir}' 0750 ${cfg.user} ${cfg.group} - -"
+      "z '${cfg.customDir}/conf' 0750 ${cfg.user} ${cfg.group} - -"
+      "z '${cfg.stateDir}/data' 0750 ${cfg.user} ${cfg.group} - -"
+      "z '${cfg.stateDir}/log' 0750 ${cfg.user} ${cfg.group} - -"
+
+      # If we have a folder or symlink with Forgejo locales, remove it
+      # And symlink the current Forgejo locales in place
+      "L+ '${cfg.stateDir}/conf/locale' - - - - ${cfg.package.out}/locale"
+
+    ] ++ optionals cfg.lfs.enable [
+      "d '${cfg.lfs.contentDir}' 0750 ${cfg.user} ${cfg.group} - -"
+      "z '${cfg.lfs.contentDir}' 0750 ${cfg.user} ${cfg.group} - -"
+    ];
+
+    systemd.services.forgejo = {
+      description = "Forgejo (Beyond coding. We forge.)";
+      after = [
+        "network.target"
+      ] ++ optionals usePostgresql [
+        "postgresql.service"
+      ] ++ optionals useMysql [
+        "mysql.service"
+      ];
+      requires = optionals (cfg.database.createDatabase && usePostgresql) [
+        "postgresql.service"
+      ] ++ optionals (cfg.database.createDatabase && useMysql) [
+        "mysql.service"
+      ];
+      wantedBy = [ "multi-user.target" ];
+      path = [ cfg.package pkgs.git pkgs.gnupg ];
+
+      # In older versions the secret naming for JWT was kind of confusing.
+      # The file jwt_secret hold the value for LFS_JWT_SECRET and JWT_SECRET
+      # wasn't persistent at all.
+      # To fix that, there is now the file oauth2_jwt_secret containing the
+      # values for JWT_SECRET and the file jwt_secret gets renamed to
+      # lfs_jwt_secret.
+      # We have to consider this to stay compatible with older installations.
+      preStart =
+        let
+          runConfig = "${cfg.customDir}/conf/app.ini";
+          secretKey = "${cfg.customDir}/conf/secret_key";
+          oauth2JwtSecret = "${cfg.customDir}/conf/oauth2_jwt_secret";
+          oldLfsJwtSecret = "${cfg.customDir}/conf/jwt_secret"; # old file for LFS_JWT_SECRET
+          lfsJwtSecret = "${cfg.customDir}/conf/lfs_jwt_secret"; # new file for LFS_JWT_SECRET
+          internalToken = "${cfg.customDir}/conf/internal_token";
+          replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
+        in
+        ''
+          # copy custom configuration and generate random secrets if needed
+          ${lib.optionalString (!cfg.useWizard) ''
+            function forgejo_setup {
+              cp -f '${format.generate "app.ini" cfg.settings}' '${runConfig}'
+
+              if [ ! -s '${secretKey}' ]; then
+                  ${exe} generate secret SECRET_KEY > '${secretKey}'
+              fi
+
+              # Migrate LFS_JWT_SECRET filename
+              if [[ -s '${oldLfsJwtSecret}' && ! -s '${lfsJwtSecret}' ]]; then
+                  mv '${oldLfsJwtSecret}' '${lfsJwtSecret}'
+              fi
+
+              if [ ! -s '${oauth2JwtSecret}' ]; then
+                  ${exe} generate secret JWT_SECRET > '${oauth2JwtSecret}'
+              fi
+
+              ${optionalString cfg.lfs.enable ''
+              if [ ! -s '${lfsJwtSecret}' ]; then
+                  ${exe} generate secret LFS_JWT_SECRET > '${lfsJwtSecret}'
+              fi
+              ''}
+
+              if [ ! -s '${internalToken}' ]; then
+                  ${exe} generate secret INTERNAL_TOKEN > '${internalToken}'
+              fi
+
+              chmod u+w '${runConfig}'
+              ${replaceSecretBin} '#secretkey#' '${secretKey}' '${runConfig}'
+              ${replaceSecretBin} '#oauth2jwtsecret#' '${oauth2JwtSecret}' '${runConfig}'
+              ${replaceSecretBin} '#internaltoken#' '${internalToken}' '${runConfig}'
+
+              ${optionalString cfg.lfs.enable ''
+                ${replaceSecretBin} '#lfsjwtsecret#' '${lfsJwtSecret}' '${runConfig}'
+              ''}
+
+              ${optionalString (cfg.database.passwordFile != null) ''
+                ${replaceSecretBin} '#dbpass#' '${cfg.database.passwordFile}' '${runConfig}'
+              ''}
+
+              ${optionalString (cfg.mailerPasswordFile != null) ''
+                ${replaceSecretBin} '#mailerpass#' '${cfg.mailerPasswordFile}' '${runConfig}'
+              ''}
+              chmod u-w '${runConfig}'
+            }
+            (umask 027; forgejo_setup)
+          ''}
+
+          # run migrations/init the database
+          ${exe} migrate
+
+          # update all hooks' binary paths
+          ${exe} admin regenerate hooks
+
+          # update command option in authorized_keys
+          if [ -r ${cfg.stateDir}/.ssh/authorized_keys ]
+          then
+            ${exe} admin regenerate keys
+          fi
+        '';
+
+      serviceConfig = {
+        Type = "simple";
+        User = cfg.user;
+        Group = cfg.group;
+        WorkingDirectory = cfg.stateDir;
+        ExecStart = "${exe} web --pid /run/forgejo/forgejo.pid";
+        Restart = "always";
+        # Runtime directory and mode
+        RuntimeDirectory = "forgejo";
+        RuntimeDirectoryMode = "0755";
+        # Proc filesystem
+        ProcSubset = "pid";
+        ProtectProc = "invisible";
+        # Access write directories
+        ReadWritePaths = [ cfg.customDir cfg.dump.backupDir cfg.repositoryRoot cfg.stateDir cfg.lfs.contentDir ];
+        UMask = "0027";
+        # Capabilities
+        CapabilityBoundingSet = "";
+        # Security
+        NoNewPrivileges = true;
+        # Sandboxing
+        ProtectSystem = "strict";
+        ProtectHome = true;
+        PrivateTmp = true;
+        PrivateDevices = true;
+        PrivateUsers = true;
+        ProtectHostname = true;
+        ProtectClock = true;
+        ProtectKernelTunables = true;
+        ProtectKernelModules = true;
+        ProtectKernelLogs = true;
+        ProtectControlGroups = true;
+        RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
+        RestrictNamespaces = true;
+        LockPersonality = true;
+        MemoryDenyWriteExecute = true;
+        RestrictRealtime = true;
+        RestrictSUIDSGID = true;
+        RemoveIPC = true;
+        PrivateMounts = true;
+        # System Call Filtering
+        SystemCallArchitectures = "native";
+        SystemCallFilter = [ "~@cpu-emulation @debug @keyring @mount @obsolete @privileged @setuid" "setrlimit" ];
+      };
+
+      environment = {
+        USER = cfg.user;
+        HOME = cfg.stateDir;
+        # `GITEA_` prefix until https://codeberg.org/forgejo/forgejo/issues/497
+        # is resolved.
+        GITEA_WORK_DIR = cfg.stateDir;
+        GITEA_CUSTOM = cfg.customDir;
+      };
+    };
+
+    users.users = mkIf (cfg.user == "forgejo") {
+      forgejo = {
+        home = cfg.stateDir;
+        useDefaultShell = true;
+        group = cfg.group;
+        isSystemUser = true;
+      };
+    };
+
+    users.groups = mkIf (cfg.group == "forgejo") {
+      forgejo = { };
+    };
+
+    systemd.services.forgejo-dump = mkIf cfg.dump.enable {
+      description = "forgejo dump";
+      after = [ "forgejo.service" ];
+      path = [ cfg.package ];
+
+      environment = {
+        USER = cfg.user;
+        HOME = cfg.stateDir;
+        # `GITEA_` prefix until https://codeberg.org/forgejo/forgejo/issues/497
+        # is resolved.
+        GITEA_WORK_DIR = cfg.stateDir;
+        GITEA_CUSTOM = cfg.customDir;
+      };
+
+      serviceConfig = {
+        Type = "oneshot";
+        User = cfg.user;
+        ExecStart = "${exe} dump --type ${cfg.dump.type}" + optionalString (cfg.dump.file != null) " --file ${cfg.dump.file}";
+        WorkingDirectory = cfg.dump.backupDir;
+      };
+    };
+
+    systemd.timers.forgejo-dump = mkIf cfg.dump.enable {
+      description = "Forgejo dump timer";
+      partOf = [ "forgejo-dump.service" ];
+      wantedBy = [ "timers.target" ];
+      timerConfig.OnCalendar = cfg.dump.interval;
+    };
+  };
+
+  meta.maintainers = with lib.maintainers; [ bendlas emilylange ];
+}
diff --git a/nixpkgs/nixos/modules/services/networking/adguardhome.nix b/nixpkgs/nixos/modules/services/networking/adguardhome.nix
index 1701e5b439c1..399d838ccc69 100644
--- a/nixpkgs/nixos/modules/services/networking/adguardhome.nix
+++ b/nixpkgs/nixos/modules/services/networking/adguardhome.nix
@@ -17,6 +17,7 @@ let
     text = builtins.toJSON cfg.settings;
     checkPhase = "${pkgs.adguardhome}/bin/adguardhome -c $out --check-config";
   };
+  defaultBindPort = 3000;
 
 in
 {
@@ -86,7 +87,7 @@ in
             '';
           };
           bind_port = mkOption {
-            default = 3000;
+            default = defaultBindPort;
             type = port;
             description = lib.mdDoc ''
               Port to serve HTTP pages on.
@@ -169,6 +170,6 @@ in
       };
     };
 
-    networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.bind_port ];
+    networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.bind_port or defaultBindPort ];
   };
 }
diff --git a/nixpkgs/nixos/modules/services/networking/networkmanager.nix b/nixpkgs/nixos/modules/services/networking/networkmanager.nix
index e28f96f7a6d6..6bc46a9a90e4 100644
--- a/nixpkgs/nixos/modules/services/networking/networkmanager.nix
+++ b/nixpkgs/nixos/modules/services/networking/networkmanager.nix
@@ -5,7 +5,7 @@ with lib;
 let
   cfg = config.networking.networkmanager;
 
-  delegateWireless = config.networking.wireless.enable == true && cfg.unmanaged != [];
+  delegateWireless = config.networking.wireless.enable == true && cfg.unmanaged != [ ];
 
   enableIwd = cfg.wifi.backend == "iwd";
 
@@ -40,7 +40,7 @@ let
     })
     (mkSection "keyfile" {
       unmanaged-devices =
-        if cfg.unmanaged == [] then null
+        if cfg.unmanaged == [ ] then null
         else lib.concatStringsSep ";" cfg.unmanaged;
     })
     (mkSection "logging" {
@@ -103,7 +103,7 @@ let
   };
 
   macAddressOpt = mkOption {
-    type = types.either types.str (types.enum ["permanent" "preserve" "random" "stable"]);
+    type = types.either types.str (types.enum [ "permanent" "preserve" "random" "stable" ]);
     default = "preserve";
     example = "00:11:22:33:44:55";
     description = lib.mdDoc ''
@@ -126,7 +126,8 @@ let
     pkgs.wpa_supplicant
   ];
 
-in {
+in
+{
 
   meta = {
     maintainers = teams.freedesktop.members;
@@ -156,7 +157,7 @@ in {
           int
           str
         ]));
-        default = {};
+        default = { };
         description = lib.mdDoc ''
           Configuration for the [connection] section of NetworkManager.conf.
           Refer to
@@ -186,7 +187,7 @@ in {
 
       unmanaged = mkOption {
         type = types.listOf types.str;
-        default = [];
+        default = [ ];
         description = lib.mdDoc ''
           List of interfaces that will not be managed by NetworkManager.
           Interface name can be specified here, but if you need more fidelity,
@@ -251,7 +252,7 @@ in {
 
       appendNameservers = mkOption {
         type = types.listOf types.str;
-        default = [];
+        default = [ ];
         description = lib.mdDoc ''
           A list of name servers that should be appended
           to the ones configured in NetworkManager or received by DHCP.
@@ -260,7 +261,7 @@ in {
 
       insertNameservers = mkOption {
         type = types.listOf types.str;
-        default = [];
+        default = [ ];
         description = lib.mdDoc ''
           A list of name servers that should be inserted before
           the ones configured in NetworkManager or received by DHCP.
@@ -336,21 +337,21 @@ in {
             };
           };
         });
-        default = [];
+        default = [ ];
         example = literalExpression ''
-        [ {
-              source = pkgs.writeText "upHook" '''
-
-                if [ "$2" != "up" ]; then
-                    logger "exit: event $2 != up"
-                    exit
-                fi
-
-                # coreutils and iproute are in PATH too
-                logger "Device $DEVICE_IFACE coming up"
-            ''';
-            type = "basic";
-        } ]'';
+          [ {
+                source = pkgs.writeText "upHook" '''
+
+                  if [ "$2" != "up" ]; then
+                      logger "exit: event $2 != up"
+                      exit
+                  fi
+
+                  # coreutils and iproute are in PATH too
+                  logger "Device $DEVICE_IFACE coming up"
+              ''';
+              type = "basic";
+          } ]'';
         description = lib.mdDoc ''
           A list of scripts which will be executed in response to  network  events.
         '';
@@ -369,14 +370,24 @@ in {
         '';
       };
 
-      enableFccUnlock = mkOption {
-        type = types.bool;
-        default = false;
+      fccUnlockScripts = mkOption {
+        type = types.listOf (types.submodule {
+          options = {
+            id = mkOption {
+              type = types.str;
+              description = lib.mdDoc "vid:pid of either the PCI or USB vendor and product ID";
+            };
+            path = mkOption {
+              type = types.path;
+              description = lib.mdDoc "Path to the unlock script";
+            };
+          };
+        });
+        default = [ ];
+        example = literalExpression ''[{ name = "03f0:4e1d"; script = "''${pkgs.modemmanager}/share/ModemManager/fcc-unlock.available.d/03f0:4e1d"; }]'';
         description = lib.mdDoc ''
-          Enable FCC unlock procedures. Since release 1.18.4, the ModemManager daemon no longer
-          automatically performs the FCC unlock procedure by default. See
-          [the docs](https://modemmanager.org/docs/modemmanager/fcc-unlock/)
-          for more details.
+          List of FCC unlock scripts to enable on the system, behaving as described in
+          https://modemmanager.org/docs/modemmanager/fcc-unlock/#integration-with-third-party-fcc-unlock-tools.
         '';
       };
     };
@@ -387,7 +398,14 @@ in {
       [ "networking" "networkmanager" "packages" ]
       [ "networking" "networkmanager" "plugins" ])
     (mkRenamedOptionModule [ "networking" "networkmanager" "useDnsmasq" ] [ "networking" "networkmanager" "dns" ])
-    (mkRemovedOptionModule ["networking" "networkmanager" "dynamicHosts"] ''
+    (mkRemovedOptionModule [ "networking" "networkmanager" "enableFccUnlock" ] ''
+      This option was removed, because using bundled FCC unlock scripts is risky,
+      might conflict with vendor-provided unlock scripts, and should
+      be a conscious decision on a per-device basis.
+      Instead it's recommended to use the
+      `networking.networkmanager.fccUnlockScripts` option.
+    '')
+    (mkRemovedOptionModule [ "networking" "networkmanager" "dynamicHosts" ] ''
       This option was removed because allowing (multiple) regular users to
       override host entries affecting the whole system opens up a huge attack
       vector. There seem to be very rare cases where this might be useful.
@@ -403,7 +421,8 @@ in {
   config = mkIf cfg.enable {
 
     assertions = [
-      { assertion = config.networking.wireless.enable == true -> cfg.unmanaged != [];
+      {
+        assertion = config.networking.wireless.enable == true -> cfg.unmanaged != [ ];
         message = ''
           You can not use networking.networkmanager with networking.wireless.
           Except if you mark some interfaces as <literal>unmanaged</literal> by NetworkManager.
@@ -414,25 +433,29 @@ in {
     hardware.wirelessRegulatoryDatabase = true;
 
     environment.etc = {
-        "NetworkManager/NetworkManager.conf".source = configFile;
-      }
-      // builtins.listToAttrs (map (pkg: nameValuePair "NetworkManager/${pkg.networkManagerPlugin}" {
+      "NetworkManager/NetworkManager.conf".source = configFile;
+    }
+    // builtins.listToAttrs (map
+      (pkg: nameValuePair "NetworkManager/${pkg.networkManagerPlugin}" {
         source = "${pkg}/lib/NetworkManager/${pkg.networkManagerPlugin}";
-      }) cfg.plugins)
-      // optionalAttrs cfg.enableFccUnlock
-         {
-           "ModemManager/fcc-unlock.d".source =
-             "${pkgs.modemmanager}/share/ModemManager/fcc-unlock.available.d/*";
-         }
-      // optionalAttrs (cfg.appendNameservers != [] || cfg.insertNameservers != [])
-         {
-           "NetworkManager/dispatcher.d/02overridedns".source = overrideNameserversScript;
-         }
-      // listToAttrs (lib.imap1 (i: s:
-         {
-            name = "NetworkManager/dispatcher.d/${dispatcherTypesSubdirMap.${s.type}}03userscript${lib.fixedWidthNumber 4 i}";
-            value = { mode = "0544"; inherit (s) source; };
-         }) cfg.dispatcherScripts);
+      })
+      cfg.plugins)
+    // builtins.listToAttrs (map
+      (e: nameValuePair "ModemManager/fcc-unlock.d/${e.id}" {
+        source = e.path;
+      })
+      cfg.fccUnlockScripts)
+    // optionalAttrs (cfg.appendNameservers != [ ] || cfg.insertNameservers != [ ])
+      {
+        "NetworkManager/dispatcher.d/02overridedns".source = overrideNameserversScript;
+      }
+    // listToAttrs (lib.imap1
+      (i: s:
+        {
+          name = "NetworkManager/dispatcher.d/${dispatcherTypesSubdirMap.${s.type}}03userscript${lib.fixedWidthNumber 4 i}";
+          value = { mode = "0544"; inherit (s) source; };
+        })
+      cfg.dispatcherScripts);
 
     environment.systemPackages = packages;
 
diff --git a/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix b/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
index 162267b5a85d..942317f8da74 100644
--- a/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
@@ -33,8 +33,7 @@ let
     ${cfg.extraConfig}
     EOL
 
-    ssh-keygen -q -f mock-hostkey -N ""
-    sshd -t -f $out -h mock-hostkey
+    sshd -G -f $out
   '';
 
   cfg  = config.services.openssh;
diff --git a/nixpkgs/nixos/modules/services/networking/trust-dns.nix b/nixpkgs/nixos/modules/services/networking/trust-dns.nix
index a3b4d12479b4..4196d124a2ab 100644
--- a/nixpkgs/nixos/modules/services/networking/trust-dns.nix
+++ b/nixpkgs/nixos/modules/services/networking/trust-dns.nix
@@ -1,5 +1,4 @@
 { config, lib, pkgs, ... }:
-
 let
   cfg = config.services.trust-dns;
   toml = pkgs.formats.toml { };
@@ -55,7 +54,7 @@ in
         defaultText = "pkgs.trust-dns";
         description = mdDoc ''
           Trust-dns package to use.
-          Only `bin/named` need be provided: the other trust-dns utilities (client and resolver) are not needed.
+          Only `bin/trust-dns` need be provided: the other trust-dns utilities (client and resolver) are not needed.
         '';
       };
       quiet = mkOption {
@@ -136,7 +135,7 @@ in
           flags =  (lib.optional cfg.debug "--debug") ++ (lib.optional cfg.quiet "--quiet");
           flagsStr = builtins.concatStringsSep " " flags;
         in ''
-          ${cfg.package}/bin/named --config ${configFile} ${flagsStr}
+          ${cfg.package}/bin/trust-dns --config ${configFile} ${flagsStr}
         '';
         Type = "simple";
         Restart = "on-failure";
diff --git a/nixpkgs/nixos/modules/services/networking/websockify.nix b/nixpkgs/nixos/modules/services/networking/websockify.nix
index 45a3487bd337..27ad8953d3fa 100644
--- a/nixpkgs/nixos/modules/services/networking/websockify.nix
+++ b/nixpkgs/nixos/modules/services/networking/websockify.nix
@@ -38,7 +38,7 @@ let cfg = config.services.networking.websockify; in {
       description = "Service to forward websocket connections to TCP connections (from port:to port %I)";
       script = ''
         IFS=':' read -a array <<< "$1"
-        ${pkgs.pythonPackages.websockify}/bin/websockify --ssl-only \
+        ${pkgs.python3Packages.websockify}/bin/websockify --ssl-only \
           --cert=${cfg.sslCert} --key=${cfg.sslKey} 0.0.0.0:''${array[0]} 0.0.0.0:''${array[1]}
       '';
       scriptArgs = "%i";
diff --git a/nixpkgs/nixos/modules/services/web-apps/healthchecks.nix b/nixpkgs/nixos/modules/services/web-apps/healthchecks.nix
index b3fdb681e2f3..b92525075541 100644
--- a/nixpkgs/nixos/modules/services/web-apps/healthchecks.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/healthchecks.nix
@@ -1,16 +1,16 @@
-{ config, lib, pkgs, buildEnv, ... }:
+{ config, lib, options, pkgs, buildEnv, ... }:
 
 with lib;
 
 let
   defaultUser = "healthchecks";
   cfg = config.services.healthchecks;
+  opt = options.services.healthchecks;
   pkg = cfg.package;
   boolToPython = b: if b then "True" else "False";
   environment = {
     PYTHONPATH = pkg.pythonPath;
     STATIC_ROOT = cfg.dataDir + "/static";
-    DB_NAME = "${cfg.dataDir}/healthchecks.sqlite";
   } // cfg.settings;
 
   environmentFile = pkgs.writeText "healthchecks-environment" (lib.generators.toKeyValue { } environment);
@@ -98,17 +98,24 @@ in
       description = lib.mdDoc ''
         Environment variables which are read by healthchecks `(local)_settings.py`.
 
-        Settings which are explicitly covered in options bewlow, are type-checked and/or transformed
+        Settings which are explicitly covered in options below, are type-checked and/or transformed
         before added to the environment, everything else is passed as a string.
 
         See <https://healthchecks.io/docs/self_hosted_configuration/>
         for a full documentation of settings.
 
-        We add two variables to this list inside the packages `local_settings.py.`
-        - STATIC_ROOT to set a state directory for dynamically generated static files.
-        - SECRET_KEY_FILE to read SECRET_KEY from a file at runtime and keep it out of /nix/store.
+        We add additional variables to this list inside the packages `local_settings.py.`
+        - `STATIC_ROOT` to set a state directory for dynamically generated static files.
+        - `SECRET_KEY_FILE` to read `SECRET_KEY` from a file at runtime and keep it out of
+          /nix/store.
+        - `_FILE` variants for several values that hold sensitive information in
+          [Healthchecks configuration](https://healthchecks.io/docs/self_hosted_configuration/) so
+          that they also can be read from a file and kept out of /nix/store. To see which values
+          have support for a `_FILE` variant, run:
+          - `nix-instantiate --eval --expr '(import <nixpkgs> {}).healthchecks.secrets'`
+          - or `nix eval 'nixpkgs#healthchecks.secrets'` if the flake support has been enabled.
       '';
-      type = types.submodule {
+      type = types.submodule (settings: {
         freeformType = types.attrsOf types.str;
         options = {
           ALLOWED_HOSTS = lib.mkOption {
@@ -143,8 +150,28 @@ in
             '';
             apply = boolToPython;
           };
+
+          DB = mkOption {
+            type = types.enum [ "sqlite" "postgres" "mysql" ];
+            default = "sqlite";
+            description = lib.mdDoc "Database engine to use.";
+          };
+
+          DB_NAME = mkOption {
+            type = types.str;
+            default =
+              if settings.config.DB == "sqlite"
+              then "${cfg.dataDir}/healthchecks.sqlite"
+              else "hc";
+            defaultText = lib.literalExpression ''
+              if config.${settings.options.DB} == "sqlite"
+              then "''${config.${opt.dataDir}}/healthchecks.sqlite"
+              else "hc"
+            '';
+            description = lib.mdDoc "Database name.";
+          };
         };
-      };
+      });
     };
   };
 
@@ -168,7 +195,7 @@ in
           StateDirectoryMode = mkIf (cfg.dataDir == "/var/lib/healthchecks") "0750";
         };
       in
-        {
+      {
         healthchecks-migration = {
           description = "Healthchecks migrations";
           wantedBy = [ "healthchecks.target" ];
diff --git a/nixpkgs/nixos/modules/services/web-apps/meme-bingo-web.nix b/nixpkgs/nixos/modules/services/web-apps/meme-bingo-web.nix
new file mode 100644
index 000000000000..cb864321ef27
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/web-apps/meme-bingo-web.nix
@@ -0,0 +1,93 @@
+{ config, lib, pkgs, ... }:
+
+let
+  inherit (lib) mkEnableOption mkIf mkOption mdDoc types literalExpression;
+
+  cfg = config.services.meme-bingo-web;
+in {
+  options = {
+    services.meme-bingo-web = {
+      enable = mkEnableOption (mdDoc ''
+        A web app for the meme bingo, rendered entirely on the web server and made interactive with forms.
+
+        Note: The application's author suppose to run meme-bingo-web behind a reverse proxy for SSL and HTTP/3.
+      '');
+
+      package = mkOption {
+        type = types.package;
+        default = pkgs.meme-bingo-web;
+        defaultText = literalExpression "pkgs.meme-bingo-web";
+        description = mdDoc "meme-bingo-web package to use.";
+      };
+
+      baseUrl = mkOption {
+        description = mdDoc ''
+          URL to be used for the HTML <base> element on all HTML routes.
+        '';
+        type = types.str;
+        default = "http://localhost:41678/";
+        example = "https://bingo.example.com/";
+      };
+      port = mkOption {
+        description = mdDoc ''
+          Port to be used for the web server.
+        '';
+        type = types.port;
+        default = 41678;
+        example = 21035;
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.meme-bingo-web = {
+      description = "A web app for playing meme bingos.";
+      wantedBy = [ "multi-user.target" ];
+
+      environment = {
+        MEME_BINGO_BASE = cfg.baseUrl;
+        MEME_BINGO_PORT = toString cfg.port;
+      };
+      path = [ cfg.package ];
+
+      serviceConfig = {
+        User = "meme-bingo-web";
+        Group = "meme-bingo-web";
+
+        DynamicUser = true;
+
+        ExecStart = "${cfg.package}/bin/meme-bingo-web";
+
+        Restart = "always";
+        RestartSec = 1;
+
+        # Hardening
+        CapabilityBoundingSet = [ "" ];
+        DeviceAllow = [ "/dev/random" ];
+        LockPersonality = true;
+        PrivateDevices = true;
+        PrivateUsers = true;
+        ProcSubset = "pid";
+        ProtectSystem = "strict";
+        ProtectClock = true;
+        ProtectControlGroups = true;
+        ProtectHome = true;
+        ProtectHostname = true;
+        ProtectKernelLogs = true;
+        ProtectKernelModules = true;
+        ProtectKernelTunables = true;
+        ProtectProc = "invisible";
+        RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
+        RestrictNamespaces = true;
+        RestrictRealtime = true;
+        SystemCallArchitectures = "native";
+        SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ];
+        UMask = "0077";
+        RestrictSUIDSGID = true;
+        RemoveIPC = true;
+        NoNewPrivileges = true;
+        MemoryDenyWriteExecute = true;
+      };
+    };
+  };
+}
diff --git a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
index 1770f0759434..d9a1535ffc7d 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
+++ b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
@@ -147,7 +147,7 @@ in {
         default = false;
         type = types.bool;
         description = lib.mdDoc ''
-          Make MemTest86+ available from the systemd-boot menu. MemTest86+ is a
+          Make Memtest86+ available from the systemd-boot menu. Memtest86+ is a
           program for testing memory.
         '';
       };
@@ -191,7 +191,7 @@ in {
       default = {};
       example = literalExpression ''
         { "memtest86.conf" = '''
-          title MemTest86+
+          title Memtest86+
           efi /efi/memtest86/memtest.efi
         '''; }
       '';
@@ -285,7 +285,7 @@ in {
     boot.loader.systemd-boot.extraEntries = mkMerge [
       (mkIf cfg.memtest86.enable {
         "${cfg.memtest86.entryFilename}" = ''
-          title  MemTest86
+          title  Memtest86+
           efi    /efi/memtest86/memtest.efi
         '';
       })
diff --git a/nixpkgs/nixos/modules/system/boot/networkd.nix b/nixpkgs/nixos/modules/system/boot/networkd.nix
index 87afc5023253..238c6670ea0f 100644
--- a/nixpkgs/nixos/modules/system/boot/networkd.nix
+++ b/nixpkgs/nixos/modules/system/boot/networkd.nix
@@ -902,6 +902,9 @@ let
           "RelayTarget"
           "RelayAgentCircuitId"
           "RelayAgentRemoteId"
+          "BootServerAddress"
+          "BootServerName"
+          "BootFilename"
         ])
         (assertInt "PoolOffset")
         (assertMinimum "PoolOffset" 0)
diff --git a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix
index 21d604bee6e3..5cf863c87f27 100644
--- a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix
@@ -662,6 +662,11 @@ in
         ];
       };
 
+      # ZFS already has its own scheduler. Without this my(@Artturin) computer froze for a second when I nix build something.
+      services.udev.extraRules = ''
+        ACTION=="add|change", KERNEL=="sd[a-z]*[0-9]*|mmcblk[0-9]*p[0-9]*|nvme[0-9]*n[0-9]*p[0-9]*", ENV{ID_FS_TYPE}=="zfs_member", ATTR{../queue/scheduler}="none"
+      '';
+
       environment.etc = genAttrs
         (map
           (file: "zfs/zed.d/${file}")
diff --git a/nixpkgs/nixos/tests/acme.nix b/nixpkgs/nixos/tests/acme.nix
index f255c655bffc..e5f2d4c7934a 100644
--- a/nixpkgs/nixos/tests/acme.nix
+++ b/nixpkgs/nixos/tests/acme.nix
@@ -18,7 +18,7 @@
   dnsConfig = nodes: {
     dnsProvider = "exec";
     dnsPropagationCheck = false;
-    credentialsFile = pkgs.writeText "wildcard.env" ''
+    environmentFile = pkgs.writeText "wildcard.env" ''
       EXEC_PATH=${dnsScript nodes}
       EXEC_POLLING_INTERVAL=1
       EXEC_PROPAGATION_TIMEOUT=1
diff --git a/nixpkgs/nixos/tests/adguardhome.nix b/nixpkgs/nixos/tests/adguardhome.nix
index 9f8ddc33f57e..a6f790b83f5f 100644
--- a/nixpkgs/nixos/tests/adguardhome.nix
+++ b/nixpkgs/nixos/tests/adguardhome.nix
@@ -7,7 +7,6 @@
     emptyConf = { lib, ... }: {
       services.adguardhome = {
         enable = true;
-        settings = {};
       };
     };
 
diff --git a/nixpkgs/nixos/tests/all-tests.nix b/nixpkgs/nixos/tests/all-tests.nix
index d674d0cdba37..30ea7c70026f 100644
--- a/nixpkgs/nixos/tests/all-tests.nix
+++ b/nixpkgs/nixos/tests/all-tests.nix
@@ -284,7 +284,7 @@ in {
   fluentd = handleTest ./fluentd.nix {};
   fluidd = handleTest ./fluidd.nix {};
   fontconfig-default-fonts = handleTest ./fontconfig-default-fonts.nix {};
-  forgejo = handleTest ./gitea.nix { giteaPackage = pkgs.forgejo; };
+  forgejo = handleTest ./forgejo.nix { };
   freenet = handleTest ./freenet.nix {};
   freeswitch = handleTest ./freeswitch.nix {};
   freshrss-sqlite = handleTest ./freshrss-sqlite.nix {};
diff --git a/nixpkgs/nixos/tests/fontconfig-default-fonts.nix b/nixpkgs/nixos/tests/fontconfig-default-fonts.nix
index d8c6ea0f721b..293dc43f91f3 100644
--- a/nixpkgs/nixos/tests/fontconfig-default-fonts.nix
+++ b/nixpkgs/nixos/tests/fontconfig-default-fonts.nix
@@ -9,7 +9,7 @@ import ./make-test-python.nix ({ lib, ... }:
   nodes.machine = { config, pkgs, ... }: {
     fonts.enableDefaultPackages = true; # Background fonts
     fonts.packages = with pkgs; [
-      noto-fonts-emoji
+      noto-fonts-color-emoji
       cantarell-fonts
       twitter-color-emoji
       source-code-pro
diff --git a/nixpkgs/nixos/tests/forgejo.nix b/nixpkgs/nixos/tests/forgejo.nix
new file mode 100644
index 000000000000..b326819e3190
--- /dev/null
+++ b/nixpkgs/nixos/tests/forgejo.nix
@@ -0,0 +1,157 @@
+{ system ? builtins.currentSystem
+, config ? { }
+, pkgs ? import ../.. { inherit system config; }
+}:
+
+with import ../lib/testing-python.nix { inherit system pkgs; };
+with pkgs.lib;
+
+let
+  ## gpg --faked-system-time='20230301T010000!' --quick-generate-key snakeoil ed25519 sign
+  signingPrivateKey = ''
+    -----BEGIN PGP PRIVATE KEY BLOCK-----
+
+    lFgEY/6jkBYJKwYBBAHaRw8BAQdADXiZRV8RJUyC9g0LH04wLMaJL9WTc+szbMi7
+    5fw4yP8AAQCl8EwGfzSLm/P6fCBfA3I9znFb3MEHGCCJhJ6VtKYyRw7ktAhzbmFr
+    ZW9pbIiUBBMWCgA8FiEE+wUM6VW/NLtAdSixTWQt6LZ4x50FAmP+o5ACGwMFCQPC
+    ZwAECwkIBwQVCgkIBRYCAwEAAh4FAheAAAoJEE1kLei2eMedFTgBAKQs1oGFZrCI
+    TZP42hmBTKxGAI1wg7VSdDEWTZxut/2JAQDGgo2sa4VHMfj0aqYGxrIwfP2B7JHO
+    GCqGCRf9O/hzBA==
+    =9Uy3
+    -----END PGP PRIVATE KEY BLOCK-----
+  '';
+  signingPrivateKeyId = "4D642DE8B678C79D";
+
+  supportedDbTypes = [ "mysql" "postgres" "sqlite3" ];
+  makeGForgejoTest = type: nameValuePair type (makeTest {
+    name = "forgejo-${type}";
+    meta.maintainers = with maintainers; [ bendlas emilylange ];
+
+    nodes = {
+      server = { config, pkgs, ... }: {
+        virtualisation.memorySize = 2047;
+        services.forgejo = {
+          enable = true;
+          database = { inherit type; };
+          settings.service.DISABLE_REGISTRATION = true;
+          settings."repository.signing".SIGNING_KEY = signingPrivateKeyId;
+          settings.actions.ENABLED = true;
+        };
+        environment.systemPackages = [ config.services.forgejo.package pkgs.gnupg pkgs.jq ];
+        services.openssh.enable = true;
+
+        specialisation.runner = {
+          inheritParentConfig = true;
+          configuration.services.gitea-actions-runner.instances."test" = {
+            enable = true;
+            name = "ci";
+            url = "http://localhost:3000";
+            labels = [
+              # don't require docker/podman
+              "native:host"
+            ];
+            tokenFile = "/var/lib/forgejo/runner_token";
+          };
+        };
+      };
+      client1 = { config, pkgs, ... }: {
+        environment.systemPackages = [ pkgs.git ];
+      };
+      client2 = { config, pkgs, ... }: {
+        environment.systemPackages = [ pkgs.git ];
+      };
+    };
+
+    testScript = { nodes, ... }:
+      let
+        inherit (import ./ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey;
+        serverSystem = nodes.server.system.build.toplevel;
+      in
+      ''
+        GIT_SSH_COMMAND = "ssh -i $HOME/.ssh/privk -o StrictHostKeyChecking=no"
+        REPO = "forgejo@server:test/repo"
+        PRIVK = "${snakeOilPrivateKey}"
+
+        start_all()
+
+        client1.succeed("mkdir /tmp/repo")
+        client1.succeed("mkdir -p $HOME/.ssh")
+        client1.succeed(f"cat {PRIVK} > $HOME/.ssh/privk")
+        client1.succeed("chmod 0400 $HOME/.ssh/privk")
+        client1.succeed("git -C /tmp/repo init")
+        client1.succeed("echo hello world > /tmp/repo/testfile")
+        client1.succeed("git -C /tmp/repo add .")
+        client1.succeed("git config --global user.email test@localhost")
+        client1.succeed("git config --global user.name test")
+        client1.succeed("git -C /tmp/repo commit -m 'Initial import'")
+        client1.succeed(f"git -C /tmp/repo remote add origin {REPO}")
+
+        server.wait_for_unit("forgejo.service")
+        server.wait_for_open_port(3000)
+        server.wait_for_open_port(22)
+        server.succeed("curl --fail http://localhost:3000/")
+
+        server.succeed(
+            "su -l forgejo -c 'gpg --homedir /var/lib/forgejo/data/home/.gnupg "
+            + "--import ${toString (pkgs.writeText "forgejo.key" signingPrivateKey)}'"
+        )
+
+        assert "BEGIN PGP PUBLIC KEY BLOCK" in server.succeed("curl http://localhost:3000/api/v1/signing-key.gpg")
+
+        server.succeed(
+            "curl --fail http://localhost:3000/user/sign_up | grep 'Registration is disabled. "
+            + "Please contact your site administrator.'"
+        )
+        server.succeed(
+            "su -l forgejo -c 'GITEA_WORK_DIR=/var/lib/forgejo gitea admin user create "
+            + "--username test --password totallysafe --email test@localhost'"
+        )
+
+        api_token = server.succeed(
+            "curl --fail -X POST http://test:totallysafe@localhost:3000/api/v1/users/test/tokens "
+            + "-H 'Accept: application/json' -H 'Content-Type: application/json' -d "
+            + "'{\"name\":\"token\",\"scopes\":[\"all\"]}' | jq '.sha1' | xargs echo -n"
+        )
+
+        server.succeed(
+            "curl --fail -X POST http://localhost:3000/api/v1/user/repos "
+            + "-H 'Accept: application/json' -H 'Content-Type: application/json' "
+            + f"-H 'Authorization: token {api_token}'"
+            + ' -d \'{"auto_init":false, "description":"string", "license":"mit", "name":"repo", "private":false}\'''
+        )
+
+        server.succeed(
+            "curl --fail -X POST http://localhost:3000/api/v1/user/keys "
+            + "-H 'Accept: application/json' -H 'Content-Type: application/json' "
+            + f"-H 'Authorization: token {api_token}'"
+            + ' -d \'{"key":"${snakeOilPublicKey}","read_only":true,"title":"SSH"}\'''
+        )
+
+        client1.succeed(
+            f"GIT_SSH_COMMAND='{GIT_SSH_COMMAND}' git -C /tmp/repo push origin master"
+        )
+
+        client2.succeed("mkdir -p $HOME/.ssh")
+        client2.succeed(f"cat {PRIVK} > $HOME/.ssh/privk")
+        client2.succeed("chmod 0400 $HOME/.ssh/privk")
+        client2.succeed(f"GIT_SSH_COMMAND='{GIT_SSH_COMMAND}' git clone {REPO}")
+        client2.succeed('test "$(cat repo/testfile | xargs echo -n)" = "hello world"')
+
+        server.wait_until_succeeds(
+            'test "$(curl http://localhost:3000/api/v1/repos/test/repo/commits '
+            + '-H "Accept: application/json" | jq length)" = "1"',
+            timeout=10
+        )
+
+        with subtest("Testing runner registration"):
+            server.succeed(
+                "su -l forgejo -c 'GITEA_WORK_DIR=/var/lib/forgejo gitea actions generate-runner-token' | sed 's/^/TOKEN=/' | tee /var/lib/forgejo/runner_token"
+            )
+            server.succeed("${serverSystem}/specialisation/runner/bin/switch-to-configuration test")
+            server.wait_for_unit("gitea-runner-test.service")
+            server.succeed("journalctl -o cat -u gitea-runner-test.service | grep -q 'Runner registered successfully'")
+      '';
+  });
+in
+
+listToAttrs (map makeGForgejoTest supportedDbTypes)
diff --git a/nixpkgs/nixos/tests/noto-fonts.nix b/nixpkgs/nixos/tests/noto-fonts.nix
index edbb0db4cb7a..b871f5f51729 100644
--- a/nixpkgs/nixos/tests/noto-fonts.nix
+++ b/nixpkgs/nixos/tests/noto-fonts.nix
@@ -11,7 +11,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
         noto-fonts
         noto-fonts-cjk-sans
         noto-fonts-cjk-serif
-        noto-fonts-emoji
+        noto-fonts-color-emoji
       ];
       fontconfig.defaultFonts = {
         serif = [ "Noto Serif" "Noto Serif CJK SC" ];
diff --git a/nixpkgs/nixos/tests/postgis.nix b/nixpkgs/nixos/tests/postgis.nix
index 9d81ebaad85f..d0685abc510c 100644
--- a/nixpkgs/nixos/tests/postgis.nix
+++ b/nixpkgs/nixos/tests/postgis.nix
@@ -9,7 +9,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
       { pkgs, ... }:
 
       {
-        services.postgresql = let mypg = pkgs.postgresql_11; in {
+        services.postgresql = let mypg = pkgs.postgresql; in {
             enable = true;
             package = mypg;
             extraPlugins = with mypg.pkgs; [
diff --git a/nixpkgs/nixos/tests/shadow.nix b/nixpkgs/nixos/tests/shadow.nix
index c9a04088e870..a027af7e450b 100644
--- a/nixpkgs/nixos/tests/shadow.nix
+++ b/nixpkgs/nixos/tests/shadow.nix
@@ -32,7 +32,7 @@ in import ./make-test-python.nix ({ pkgs, ... }: {
       };
       users.berta = {
         isNormalUser = true;
-        hashedPassword = hashed_bcrypt;
+        hashedPasswordFile = (pkgs.writeText "hashed_bcrypt" hashed_bcrypt).outPath;
         shell = pkgs.bash;
       };
       users.yesim = {