diff options
Diffstat (limited to 'nixos')
62 files changed, 651 insertions, 193 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md index 984862d5af9e7..ee4fac49be8c2 100644 --- a/nixos/doc/manual/release-notes/rl-2411.section.md +++ b/nixos/doc/manual/release-notes/rl-2411.section.md @@ -23,6 +23,8 @@ - [wg-access-server](https://github.com/freifunkMUC/wg-access-server/), an all-in-one WireGuard VPN solution with a web ui for connecting devices. Available at [services.wg-access-server](#opt-services.wg-access-server.enable). +- [Playerctld](https://github.com/altdesktop/playerctl), a daemon to track media player activity. Available as [services.playerctld](option.html#opt-services.playerctld). + ## Backward Incompatibilities {#sec-release-24.11-incompatibilities} - `transmission` package has been aliased with a `trace` warning to `transmission_3`. Since [Transmission 4 has been released last year](https://github.com/transmission/transmission/releases/tag/4.0.0), and Transmission 3 will eventually go away, it was decided perform this warning alias to make people aware of the new version. The `services.transmission.package` defaults to `transmission_3` as well because the upgrade can cause data loss in certain specific usage patterns (examples: [#5153](https://github.com/transmission/transmission/issues/5153), [#6796](https://github.com/transmission/transmission/issues/6796)). Please make sure to back up to your data directory per your usage: @@ -45,6 +47,8 @@ - For convenience, the top-level `clang-tools` attribute remains and is now bound to `llvmPackages.clang-tools`. - Top-level `clang_tools_<version>` attributes are now aliases; these will be removed in a future release. +- `buildbot` was updated to 4.0, the AngularJS frontend has been replaced by a React frontend, see the [upstream release notes](https://docs.buildbot.net/current/manual/upgrading/4.0-upgrade.html). + - `nginx` package no longer includes `gd` and `geoip` dependencies. For enabling it, override `nginx` package with the optionals `withImageFilter` and `withGeoIP`. - `openssh` and `openssh_hpn` are now compiled without Kerberos 5 / GSSAPI support in an effort to reduce the attack surface of the components for the majority of users. Users needing this support can @@ -58,6 +62,8 @@ nvimpager settings: user commands in `-c` and `--cmd` now override the respective default settings because they are executed later. +- `pkgs.nextcloud27` has been removed since it's EOL. + - `services.forgejo.mailerPasswordFile` has been deprecated by the drop-in replacement `services.forgejo.secrets.mailer.PASSWD`, which is part of the new free-form `services.forgejo.secrets` option. `services.forgejo.secrets` is a small wrapper over systemd's `LoadCredential=`. It has the same structure (sections/keys) as @@ -140,14 +146,25 @@ <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. --> +- The `zerocallusedregs` hardening flag is enabled by default on compilers that support it. + +- The `stackclashprotection` hardening flag has been added, though disabled by default. + - `hareHook` has been added as the language framework for Hare. From now on, it, not the `hare` package, should be added to `nativeBuildInputs` when building Hare programs. +- [`lib.options.mkPackageOptionMD`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.options.mkPackageOptionMD) is now obsolete; use the identical [`lib.options.mkPackageOption`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.options.mkPackageOption) instead. + - To facilitate dependency injection, the `imgui` package now builds a static archive using vcpkg' CMake rules. The derivation now installs "impl" headers selectively instead of by a wildcard. Use `imgui.src` if you just want to access the unpacked sources. +- Cinnamon has been updated to 6.2. + - Following Mint 22 defaults, the Cinnamon module no longer ships geary and hexchat by default. + - Nemo is now built with gtk-layer-shell support, note that for now it will be expected to see nemo-desktop + listed as a regular entry in Cinnamon Wayland session's window list applet. + - Support for *runner registration tokens* has been [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/380872) in `gitlab-runner` 15.6 and is expected to be removed in `gitlab-runner` 18.0. Configuration of existing runners should be changed to using *runner authentication tokens* by configuring diff --git a/nixos/modules/config/fonts/ghostscript.nix b/nixos/modules/config/fonts/ghostscript.nix index a5508b948990c..5db7c0ac71799 100644 --- a/nixos/modules/config/fonts/ghostscript.nix +++ b/nixos/modules/config/fonts/ghostscript.nix @@ -18,6 +18,6 @@ with lib; }; config = mkIf config.fonts.enableGhostscriptFonts { - fonts.packages = [ "${pkgs.ghostscript}/share/ghostscript/fonts" ]; + fonts.packages = [ pkgs.ghostscript.fonts ]; }; } diff --git a/nixos/modules/hardware/video/nvidia.nix b/nixos/modules/hardware/video/nvidia.nix index 0274dfcaa70f9..e38050e637b1c 100644 --- a/nixos/modules/hardware/video/nvidia.nix +++ b/nixos/modules/hardware/video/nvidia.nix @@ -46,8 +46,6 @@ in 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"; - DATABASE_PATH = "${nvidia_x11.fabricmanager}/share/nvidia-fabricmanager/nvidia/nvswitch"; }; defaultText = lib.literalExpression '' { @@ -69,8 +67,6 @@ in 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"; - DATABASE_PATH="''${nvidia_x11.fabricmanager}/share/nvidia-fabricmanager/nvidia/nvswitch"; } ''; description = '' @@ -628,7 +624,14 @@ in TimeoutStartSec = 240; ExecStart = let - nv-fab-conf = settingsFormat.generate "fabricmanager.conf" cfg.datacenter.settings; + # Since these rely on the `nvidia_x11.fabricmanager` derivation, they're + # unsuitable to be mentioned in the configuration defaults, but they _can_ + # be overridden in `cfg.datacenter.settings` if needed. + fabricManagerConfDefaults = { + TOPOLOGY_FILE_PATH = "${nvidia_x11.fabricmanager}/share/nvidia-fabricmanager/nvidia/nvswitch"; + DATABASE_PATH = "${nvidia_x11.fabricmanager}/share/nvidia-fabricmanager/nvidia/nvswitch"; + }; + nv-fab-conf = settingsFormat.generate "fabricmanager.conf" (fabricManagerConfDefaults // cfg.datacenter.settings); in "${lib.getExe nvidia_x11.fabricmanager} -c ${nv-fab-conf}"; LimitCORE = "infinity"; diff --git a/nixos/modules/image/repart-image.nix b/nixos/modules/image/repart-image.nix index e404067299004..de03beeafc0b7 100644 --- a/nixos/modules/image/repart-image.nix +++ b/nixos/modules/image/repart-image.nix @@ -90,8 +90,8 @@ let }."${compression.algorithm}"; compressionCommand = { - "zstd" = "zstd --no-progress --threads=0 -${toString compression.level}"; - "xz" = "xz --keep --verbose --threads=0 -${toString compression.level}"; + "zstd" = "zstd --no-progress --threads=$NIX_BUILD_CORES -${toString compression.level}"; + "xz" = "xz --keep --verbose --threads=$NIX_BUILD_CORES -${toString compression.level}"; }."${compression.algorithm}"; in stdenvNoCC.mkDerivation (finalAttrs: diff --git a/nixos/modules/installer/tools/nix-fallback-paths.nix b/nixos/modules/installer/tools/nix-fallback-paths.nix index 9669ec5e37f3c..54d3a107d6276 100644 --- a/nixos/modules/installer/tools/nix-fallback-paths.nix +++ b/nixos/modules/installer/tools/nix-fallback-paths.nix @@ -1,7 +1,7 @@ { - x86_64-linux = "/nix/store/yrsmzlw2lgbknzwic1gy1gmv3l2w1ax8-nix-2.18.3"; - i686-linux = "/nix/store/ds9381l9mlwfaclvqnkzn3jl4qb8m3y1-nix-2.18.3"; - aarch64-linux = "/nix/store/hw1zny3f8520zyskmp1qaybv1ir5ilxh-nix-2.18.3"; - x86_64-darwin = "/nix/store/z08yc4sl1fr65q53wz6pw30h67qafaln-nix-2.18.3"; - aarch64-darwin = "/nix/store/p57m7m0wrz8sqxiwinzpwzqzak82zn75-nix-2.18.3"; + x86_64-linux = "/nix/store/1w4b47zhp33md29wjhgg549pc281vv02-nix-2.18.4"; + i686-linux = "/nix/store/hz02kn0ffn3wdi2xs7lndpr88v4v4fp2-nix-2.18.4"; + aarch64-linux = "/nix/store/90zwqa9z2fgldc7ki1p5gfvglchjh9r6-nix-2.18.4"; + x86_64-darwin = "/nix/store/bd1ix5mj9lj2yh7bqnmdjc24zlg5jivk-nix-2.18.4"; + aarch64-darwin = "/nix/store/5hvsmklhqiay5i4q5vdkg60p8qpc69rz-nix-2.18.4"; } diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 8f5d8ecd1ce30..4d227916c499c 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -243,6 +243,7 @@ ./programs/nh.nix ./programs/nix-index.nix ./programs/nix-ld.nix + ./programs/nix-required-mounts.nix ./programs/nm-applet.nix ./programs/nncp.nix ./programs/noisetorch.nix @@ -486,6 +487,7 @@ ./services/desktops/espanso.nix ./services/desktops/flatpak.nix ./services/desktops/geoclue2.nix + ./services/desktops/playerctld.nix ./services/desktops/gnome/at-spi2-core.nix ./services/desktops/gnome/evolution-data-server.nix ./services/desktops/gnome/glib-networking.nix diff --git a/nixos/modules/programs/nix-required-mounts.nix b/nixos/modules/programs/nix-required-mounts.nix new file mode 100644 index 0000000000000..5d25958a7698d --- /dev/null +++ b/nixos/modules/programs/nix-required-mounts.nix @@ -0,0 +1,118 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.programs.nix-required-mounts; + package = pkgs.nix-required-mounts; + + Mount = + with lib; + types.submodule { + options.host = mkOption { + type = types.str; + description = "Host path to mount"; + }; + options.guest = mkOption { + type = types.str; + description = "Location in the sandbox to mount the host path at"; + }; + }; + Pattern = + with lib.types; + types.submodule ( + { config, name, ... }: + { + options.onFeatures = lib.mkOption { + type = listOf types.str; + description = "Which requiredSystemFeatures should trigger relaxation of the sandbox"; + default = [ name ]; + }; + options.paths = lib.mkOption { + type = listOf (oneOf [ + path + Mount + ]); + description = "A list of glob patterns, indicating which paths to expose to the sandbox"; + }; + options.unsafeFollowSymlinks = lib.mkEnableOption '' + Instructs the hook to mount the symlink targets as well, when any of + the `paths` contain symlinks. This may not work correctly with glob + patterns. + ''; + } + ); + + driverPaths = [ + pkgs.addOpenGLRunpath.driverLink + + # mesa: + config.hardware.opengl.package + + # nvidia_x11, etc: + ] ++ config.hardware.opengl.extraPackages; # nvidia_x11 + + defaults = { + nvidia-gpu.onFeatures = package.allowedPatterns.nvidia-gpu.onFeatures; + nvidia-gpu.paths = package.allowedPatterns.nvidia-gpu.paths ++ driverPaths; + nvidia-gpu.unsafeFollowSymlinks = false; + }; +in +{ + meta.maintainers = with lib.maintainers; [ SomeoneSerge ]; + options.programs.nix-required-mounts = { + enable = lib.mkEnableOption "Expose extra paths to the sandbox depending on derivations' requiredSystemFeatures"; + presets.nvidia-gpu.enable = lib.mkEnableOption '' + Declare the support for derivations that require an Nvidia GPU to be + available, e.g. derivations with `requiredSystemFeatures = [ "cuda" ]`. + This mounts the corresponding userspace drivers and device nodes in the + sandbox, but only for derivations that request these special features. + + You may extend or override the exposed paths via the + `programs.nix-required-mounts.allowedPatterns.nvidia-gpu.paths` option. + ''; + allowedPatterns = + with lib.types; + lib.mkOption rec { + type = attrsOf Pattern; + description = "The hook config, describing which paths to mount for which system features"; + default = { }; + defaultText = lib.literalExpression '' + { + opengl.paths = config.hardware.opengl.extraPackages ++ [ + config.hardware.opengl.package + pkgs.addOpenGLRunpath.driverLink + "/dev/dri" + ]; + } + ''; + example.require-ipfs.paths = [ "/ipfs" ]; + example.require-ipfs.onFeatures = [ "ifps" ]; + }; + extraWrapperArgs = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + description = "List of extra arguments (such as `--add-flags -v`) to pass to the hook's wrapper"; + }; + package = lib.mkOption { + type = lib.types.package; + default = package.override { inherit (cfg) allowedPatterns extraWrapperArgs; }; + description = "The final package with the final config applied"; + internal = true; + }; + }; + config = lib.mkIf cfg.enable ( + lib.mkMerge [ + { nix.settings.pre-build-hook = lib.getExe cfg.package; } + (lib.mkIf cfg.presets.nvidia-gpu.enable { + nix.settings.system-features = cfg.allowedPatterns.nvidia-gpu.onFeatures; + programs.nix-required-mounts.allowedPatterns = { + inherit (defaults) nvidia-gpu; + }; + }) + ] + ); +} diff --git a/nixos/modules/programs/screen.nix b/nixos/modules/programs/screen.nix index 4f3cd9fcf9a56..63bfe6576cc02 100644 --- a/nixos/modules/programs/screen.nix +++ b/nixos/modules/programs/screen.nix @@ -9,7 +9,7 @@ in programs.screen = { enable = lib.mkEnableOption "screen, a basic terminal multiplexer"; - package = lib.mkPackageOptionMD pkgs "screen" { }; + package = lib.mkPackageOption pkgs "screen" { }; screenrc = lib.mkOption { type = lib.types.lines; diff --git a/nixos/modules/programs/wayland/hyprland.nix b/nixos/modules/programs/wayland/hyprland.nix index 575adc79cf10b..6e69c1730e57b 100644 --- a/nixos/modules/programs/wayland/hyprland.nix +++ b/nixos/modules/programs/wayland/hyprland.nix @@ -38,12 +38,13 @@ in xwayland.enable = lib.mkEnableOption "XWayland" // { default = true; }; systemd.setPath.enable = lib.mkEnableOption null // { - default = true; + default = lib.versionOlder cfg.package.version "0.41.2"; + defaultText = lib.literalExpression ''lib.versionOlder cfg.package.version "0.41.2"''; example = false; description = '' Set environment path of systemd to include the current system's bin directory. This is needed in Hyprland setups, where opening links in applications do not work. - Enabled by default. + Enabled by default for Hyprland versions older than 0.41.2. ''; }; }; diff --git a/nixos/modules/security/polkit.nix b/nixos/modules/security/polkit.nix index f7ee4f0068dde..76f623096fb76 100644 --- a/nixos/modules/security/polkit.nix +++ b/nixos/modules/security/polkit.nix @@ -14,6 +14,8 @@ in security.polkit.enable = mkEnableOption "polkit"; + security.polkit.package = mkPackageOption pkgs "polkit" { }; + security.polkit.debug = mkEnableOption "debug logs from polkit. This is required in order to see log messages from rule definitions"; security.polkit.extraConfig = mkOption { @@ -57,13 +59,13 @@ in config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.polkit.bin pkgs.polkit.out ]; + environment.systemPackages = [ cfg.package.bin cfg.package.out ]; - systemd.packages = [ pkgs.polkit.out ]; + systemd.packages = [ cfg.package.out ]; systemd.services.polkit.serviceConfig.ExecStart = [ "" - "${pkgs.polkit.out}/lib/polkit-1/polkitd ${optionalString (!cfg.debug) "--no-debug"}" + "${cfg.package.out}/lib/polkit-1/polkitd ${optionalString (!cfg.debug) "--no-debug"}" ]; systemd.services.polkit.restartTriggers = [ config.system.path ]; @@ -82,7 +84,7 @@ in ${cfg.extraConfig} ''; #TODO: validation on compilation (at least against typos) - services.dbus.packages = [ pkgs.polkit.out ]; + services.dbus.packages = [ cfg.package.out ]; security.pam.services.polkit-1 = {}; @@ -91,13 +93,13 @@ in { setuid = true; owner = "root"; group = "root"; - source = "${pkgs.polkit.bin}/bin/pkexec"; + source = "${cfg.package.bin}/bin/pkexec"; }; polkit-agent-helper-1 = { setuid = true; owner = "root"; group = "root"; - source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1"; + source = "${cfg.package.out}/lib/polkit-1/polkit-agent-helper-1"; }; }; diff --git a/nixos/modules/services/admin/pgadmin.nix b/nixos/modules/services/admin/pgadmin.nix index b3dd3c78874c2..9c430bd05e712 100644 --- a/nixos/modules/services/admin/pgadmin.nix +++ b/nixos/modules/services/admin/pgadmin.nix @@ -35,7 +35,7 @@ in default = 5050; }; - package = mkPackageOptionMD pkgs "pgadmin4" { }; + package = mkPackageOption pkgs "pgadmin4" { }; initialEmail = mkOption { description = "Initial email for the pgAdmin account"; diff --git a/nixos/modules/services/desktop-managers/plasma6.nix b/nixos/modules/services/desktop-managers/plasma6.nix index 796e24286f9e4..01a5bfa1dee27 100644 --- a/nixos/modules/services/desktop-managers/plasma6.nix +++ b/nixos/modules/services/desktop-managers/plasma6.nix @@ -8,7 +8,7 @@ cfg = config.services.desktopManager.plasma6; inherit (pkgs) kdePackages; - inherit (lib) literalExpression mkDefault mkIf mkOption mkPackageOptionMD types; + inherit (lib) literalExpression mkDefault mkIf mkOption mkPackageOption types; activationScript = '' # will be rebuilt automatically @@ -29,7 +29,7 @@ in { description = "Enable Qt 5 integration (theming, etc). Disable for a pure Qt 6 system."; }; - notoPackage = mkPackageOptionMD pkgs "Noto fonts - used for UI by default" { + notoPackage = mkPackageOption pkgs "Noto fonts - used for UI by default" { default = ["noto-fonts"]; example = "noto-fonts-lgc-plus"; }; diff --git a/nixos/modules/services/desktops/playerctld.nix b/nixos/modules/services/desktops/playerctld.nix new file mode 100644 index 0000000000000..ef4866d75715d --- /dev/null +++ b/nixos/modules/services/desktops/playerctld.nix @@ -0,0 +1,32 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.services.playerctld; +in +{ + options.services.playerctld = { + enable = lib.mkEnableOption "the playerctld daemon"; + + package = lib.mkPackageOption pkgs "playerctl" { }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + systemd.user.services.playerctld = { + description = "Playerctld daemon to track media player activity"; + wantedBy = [ "default.target" ]; + + serviceConfig = { + Type = "exec"; + ExecStart = "${cfg.package}/bin/playerctld"; + }; + }; + }; + + meta.maintainers = with lib.maintainers; [ aacebedo ]; +} diff --git a/nixos/modules/services/games/armagetronad.nix b/nixos/modules/services/games/armagetronad.nix index 71c8528a9f6ea..dfeadb19026f7 100644 --- a/nixos/modules/services/games/armagetronad.nix +++ b/nixos/modules/services/games/armagetronad.nix @@ -36,7 +36,7 @@ in options = { enable = mkEnableOption "armagetronad"; - package = lib.mkPackageOptionMD pkgs "armagetronad-dedicated" { + package = lib.mkPackageOption pkgs "armagetronad-dedicated" { example = '' pkgs.armagetronad."0.2.9-sty+ct+ap".dedicated ''; diff --git a/nixos/modules/services/games/teeworlds.nix b/nixos/modules/services/games/teeworlds.nix index 1958fd4141788..b9ed49937a7f7 100644 --- a/nixos/modules/services/games/teeworlds.nix +++ b/nixos/modules/services/games/teeworlds.nix @@ -95,7 +95,7 @@ in services.teeworlds = { enable = mkEnableOption "Teeworlds Server"; - package = mkPackageOptionMD pkgs "teeworlds-server" { }; + package = mkPackageOption pkgs "teeworlds-server" { }; openPorts = mkOption { type = types.bool; diff --git a/nixos/modules/services/hardware/auto-epp.nix b/nixos/modules/services/hardware/auto-epp.nix index b568dec26f4c9..1d939a98142e0 100644 --- a/nixos/modules/services/hardware/auto-epp.nix +++ b/nixos/modules/services/hardware/auto-epp.nix @@ -10,7 +10,7 @@ in { services.auto-epp = { enable = lib.mkEnableOption "auto-epp for amd active pstate"; - package = lib.mkPackageOptionMD pkgs "auto-epp" {}; + package = lib.mkPackageOption pkgs "auto-epp" {}; settings = mkOption { type = types.submodule { diff --git a/nixos/modules/services/home-automation/ebusd.nix b/nixos/modules/services/home-automation/ebusd.nix index f5c5479e8eaff..97d1e2796adab 100644 --- a/nixos/modules/services/home-automation/ebusd.nix +++ b/nixos/modules/services/home-automation/ebusd.nix @@ -11,7 +11,7 @@ in options.services.ebusd = { enable = mkEnableOption "ebusd, a daemon for communication with eBUS heating systems"; - package = mkPackageOptionMD pkgs "ebusd" { }; + package = mkPackageOption pkgs "ebusd" { }; device = mkOption { type = types.str; diff --git a/nixos/modules/services/home-automation/matter-server.nix b/nixos/modules/services/home-automation/matter-server.nix index 7bf1cfe54d17b..08a68db71386e 100644 --- a/nixos/modules/services/home-automation/matter-server.nix +++ b/nixos/modules/services/home-automation/matter-server.nix @@ -19,7 +19,7 @@ in options.services.matter-server = with types; { enable = mkEnableOption "Matter-server"; - package = mkPackageOptionMD pkgs "python-matter-server" { }; + package = mkPackageOption pkgs "python-matter-server" { }; port = mkOption { type = types.port; diff --git a/nixos/modules/services/misc/ollama.nix b/nixos/modules/services/misc/ollama.nix index 1467c3f93bc85..c460514783efc 100644 --- a/nixos/modules/services/misc/ollama.nix +++ b/nixos/modules/services/misc/ollama.nix @@ -1,6 +1,6 @@ { config, lib, pkgs, ... }: let - inherit (lib) types; + inherit (lib) types mkBefore; cfg = config.services.ollama; ollamaPackage = cfg.package.override { @@ -132,6 +132,14 @@ in Since `ollama run` is mostly a shell around the ollama server, this is usually sufficient. ''; }; + loadModels = lib.mkOption { + type = types.listOf types.str; + default = [ ]; + description = '' + The models to download as soon as the service starts. + Search for models of your choice from: https://ollama.com/library + ''; + }; openFirewall = lib.mkOption { type = types.bool; default = false; @@ -161,6 +169,14 @@ in DynamicUser = cfg.sandbox; ReadWritePaths = cfg.writablePaths; }; + postStart = mkBefore '' + set -x + export OLLAMA_HOST=${lib.escapeShellArg cfg.host}:${builtins.toString cfg.port} + for model in ${lib.escapeShellArgs cfg.loadModels} + do + ${lib.escapeShellArg (lib.getExe ollamaPackage)} pull "$model" + done + ''; }; networking.firewall = lib.mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; diff --git a/nixos/modules/services/monitoring/nezha-agent.nix b/nixos/modules/services/monitoring/nezha-agent.nix index 8312a425d28fc..7ebbc7f2f3297 100644 --- a/nixos/modules/services/monitoring/nezha-agent.nix +++ b/nixos/modules/services/monitoring/nezha-agent.nix @@ -24,6 +24,13 @@ in Enable SSL/TLS encryption. ''; }; + gpu = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Enable GPU monitoring. + ''; + }; disableCommandExecute = lib.mkOption { type = lib.types.bool; default = true; @@ -46,7 +53,12 @@ in ''; }; reportDelay = lib.mkOption { - type = lib.types.enum [ 1 2 3 4 ]; + type = lib.types.enum [ + 1 + 2 + 3 + 4 + ]; default = 1; description = '' The interval between system status reportings. @@ -96,6 +108,7 @@ in ++ lib.optional cfg.skipConnection "--skip-conn" ++ lib.optional cfg.skipProcess "--skip-procs" ++ lib.optional cfg.tls "--tls" + ++ lib.optional cfg.gpu "--gpu" ); wantedBy = [ "multi-user.target" ]; }; diff --git a/nixos/modules/services/monitoring/smartd.nix b/nixos/modules/services/monitoring/smartd.nix index 2c05eaad25ace..6fd3b5707ab67 100644 --- a/nixos/modules/services/monitoring/smartd.nix +++ b/nixos/modules/services/monitoring/smartd.nix @@ -10,6 +10,7 @@ let opt = options.services.smartd; nm = cfg.notifications.mail; + ns = cfg.notifications.systembus-notify; nw = cfg.notifications.wall; nx = cfg.notifications.x11; @@ -28,6 +29,12 @@ let ${pkgs.smartmontools}/sbin/smartctl -a -d "$SMARTD_DEVICETYPE" "$SMARTD_DEVICE" } | ${nm.mailer} -i "${nm.recipient}" ''} + ${optionalString ns.enable '' + ${pkgs.dbus}/bin/dbus-send --system \ + / net.nuetzlich.SystemNotifications.Notify \ + "string:Problem detected with disk: $SMARTD_DEVICESTRING" \ + "string:Warning message from smartd is: $SMARTD_MESSAGE" + ''} ${optionalString nw.enable '' { ${pkgs.coreutils}/bin/cat << EOF @@ -159,6 +166,24 @@ in }; }; + systembus-notify = { + enable = mkOption { + default = false; + type = types.bool; + description = '' + Whenever to send systembus-notify notifications. + + WARNING: enabling this option (while convenient) should *not* be done on a + machine where you do not trust the other users as it allows any other + local user to DoS your session by spamming notifications. + + To actually see the notifications in your GUI session, you need to have + `systembus-notify` running as your user, which this + option handles by enabling {option}`services.systembus-notify`. + ''; + }; + }; + wall = { enable = mkOption { default = true; @@ -247,6 +272,8 @@ in serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd ${lib.concatStringsSep " " cfg.extraOptions} --no-fork --configfile=${smartdConf}"; }; + services.systembus-notify.enable = mkDefault ns.enable; + }; } diff --git a/nixos/modules/services/networking/gns3-server.nix b/nixos/modules/services/networking/gns3-server.nix index b2f25b158bbbc..ec6a53dddc709 100644 --- a/nixos/modules/services/networking/gns3-server.nix +++ b/nixos/modules/services/networking/gns3-server.nix @@ -16,7 +16,7 @@ in { services.gns3-server = { enable = lib.mkEnableOption "GNS3 Server daemon"; - package = lib.mkPackageOptionMD pkgs "gns3-server" { }; + package = lib.mkPackageOption pkgs "gns3-server" { }; auth = { enable = lib.mkEnableOption "password based HTTP authentication to access the GNS3 Server"; @@ -88,17 +88,17 @@ in { dynamips = { enable = lib.mkEnableOption ''Dynamips support''; - package = lib.mkPackageOptionMD pkgs "dynamips" { }; + package = lib.mkPackageOption pkgs "dynamips" { }; }; ubridge = { enable = lib.mkEnableOption ''uBridge support''; - package = lib.mkPackageOptionMD pkgs "ubridge" { }; + package = lib.mkPackageOption pkgs "ubridge" { }; }; vpcs = { enable = lib.mkEnableOption ''VPCS support''; - package = lib.mkPackageOptionMD pkgs "vpcs" { }; + package = lib.mkPackageOption pkgs "vpcs" { }; }; }; }; diff --git a/nixos/modules/services/networking/oink.nix b/nixos/modules/services/networking/oink.nix index cd0fdf172331d..3497ca9220a80 100644 --- a/nixos/modules/services/networking/oink.nix +++ b/nixos/modules/services/networking/oink.nix @@ -77,6 +77,7 @@ in config = mkIf cfg.enable { systemd.services.oink = { description = "Dynamic DNS client for Porkbun"; + after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; script = "${cfg.package}/bin/oink -c ${oinkConfig}"; }; diff --git a/nixos/modules/services/networking/scion/scion-control.nix b/nixos/modules/services/networking/scion/scion-control.nix index c3a22039aa524..95d78a87ac859 100644 --- a/nixos/modules/services/networking/scion/scion-control.nix +++ b/nixos/modules/services/networking/scion/scion-control.nix @@ -12,19 +12,19 @@ let reconnect_to_dispatcher = true; }; beacon_db = { - connection = "/var/lib/scion-control/control.beacon.db"; + connection = "/run/scion-control/control.beacon.db"; }; path_db = { - connection = "/var/lib/scion-control/control.path.db"; + connection = "/run/scion-control/control.path.db"; }; trust_db = { - connection = "/var/lib/scion-control/control.trust.db"; + connection = "/run/scion-control/control.trust.db"; }; log.console = { level = "info"; }; }; - configFile = toml.generate "scion-control.toml" (defaultConfig // cfg.settings); + configFile = toml.generate "scion-control.toml" (recursiveUpdate defaultConfig cfg.settings); in { options.services.scion.scion-control = { @@ -35,7 +35,7 @@ in example = literalExpression '' { path_db = { - connection = "/var/lib/scion-control/control.path.db"; + connection = "/run/scion-control/control.path.db"; }; log.console = { level = "info"; @@ -62,7 +62,7 @@ in DynamicUser = true; Restart = "on-failure"; BindPaths = [ "/dev/shm:/run/shm" ]; - StateDirectory = "scion-control"; + RuntimeDirectory = "scion-control"; }; }; }; diff --git a/nixos/modules/services/networking/scion/scion-daemon.nix b/nixos/modules/services/networking/scion/scion-daemon.nix index 53b56841c3929..8528bec1d52eb 100644 --- a/nixos/modules/services/networking/scion/scion-daemon.nix +++ b/nixos/modules/services/networking/scion/scion-daemon.nix @@ -12,16 +12,16 @@ let reconnect_to_dispatcher = true; }; path_db = { - connection = "/var/lib/scion-daemon/sd.path.db"; + connection = "/run/scion-daemon/sd.path.db"; }; trust_db = { - connection = "/var/lib/scion-daemon/sd.trust.db"; + connection = "/run/scion-daemon/sd.trust.db"; }; log.console = { level = "info"; }; }; - configFile = toml.generate "scion-daemon.toml" (defaultConfig // cfg.settings); + configFile = toml.generate "scion-daemon.toml" (recursiveUpdate defaultConfig cfg.settings); in { options.services.scion.scion-daemon = { @@ -32,7 +32,7 @@ in example = literalExpression '' { path_db = { - connection = "/var/lib/scion-daemon/sd.path.db"; + connection = "/run/scion-daemon/sd.path.db"; }; log.console = { level = "info"; @@ -57,7 +57,7 @@ in ExecStart = "${pkgs.scion}/bin/scion-daemon --config ${configFile}"; Restart = "on-failure"; DynamicUser = true; - StateDirectory = "scion-daemon"; + RuntimeDirectory = "scion-daemon"; }; }; }; diff --git a/nixos/modules/services/networking/scion/scion-dispatcher.nix b/nixos/modules/services/networking/scion/scion-dispatcher.nix index 05d1fd0782af5..7c9f5e6a385ee 100644 --- a/nixos/modules/services/networking/scion/scion-dispatcher.nix +++ b/nixos/modules/services/networking/scion/scion-dispatcher.nix @@ -15,7 +15,7 @@ let level = "info"; }; }; - configFile = toml.generate "scion-dispatcher.toml" (defaultConfig // cfg.settings); + configFile = toml.generate "scion-dispatcher.toml" (recursiveUpdate defaultConfig cfg.settings); in { options.services.scion.scion-dispatcher = { @@ -66,7 +66,7 @@ in ExecStartPre = "${pkgs.coreutils}/bin/rm -rf /run/shm/dispatcher"; ExecStart = "${pkgs.scion}/bin/scion-dispatcher --config ${configFile}"; Restart = "on-failure"; - StateDirectory = "scion-dispatcher"; + RuntimeDirectory = "scion-dispatcher"; }; }; }; diff --git a/nixos/modules/services/networking/scion/scion-router.nix b/nixos/modules/services/networking/scion/scion-router.nix index 488dfd12b3a57..2cac44ab767ef 100644 --- a/nixos/modules/services/networking/scion/scion-router.nix +++ b/nixos/modules/services/networking/scion/scion-router.nix @@ -11,7 +11,7 @@ let config_dir = "/etc/scion"; }; }; - configFile = toml.generate "scion-router.toml" (defaultConfig // cfg.settings); + configFile = toml.generate "scion-router.toml" (recursiveUpdate defaultConfig cfg.settings); in { options.services.scion.scion-router = { @@ -42,7 +42,7 @@ in ExecStart = "${pkgs.scion}/bin/scion-router --config ${configFile}"; Restart = "on-failure"; DynamicUser = true; - StateDirectory = "scion-router"; + RuntimeDirectory = "scion-router"; }; }; }; diff --git a/nixos/modules/services/networking/scion/scion.nix b/nixos/modules/services/networking/scion/scion.nix index 5e3445edbb89a..b8bfef8b93b58 100644 --- a/nixos/modules/services/networking/scion/scion.nix +++ b/nixos/modules/services/networking/scion/scion.nix @@ -1,4 +1,4 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: with lib; @@ -17,6 +17,9 @@ in }; }; config = mkIf cfg.enable { + environment.systemPackages = [ + pkgs.scion + ]; services.scion = { scion-dispatcher.enable = true; scion-daemon.enable = true; diff --git a/nixos/modules/services/networking/xrdp.nix b/nixos/modules/services/networking/xrdp.nix index 884325d13159b..d571c6e4d88d7 100644 --- a/nixos/modules/services/networking/xrdp.nix +++ b/nixos/modules/services/networking/xrdp.nix @@ -51,11 +51,11 @@ in enable = mkEnableOption "xrdp, the Remote Desktop Protocol server"; - package = mkPackageOptionMD pkgs "xrdp" { }; + package = mkPackageOption pkgs "xrdp" { }; audio = { enable = mkEnableOption "audio support for xrdp sessions. So far it only works with PulseAudio sessions on the server side. No PipeWire support yet"; - package = mkPackageOptionMD pkgs "pulseaudio-module-xrdp" {}; + package = mkPackageOption pkgs "pulseaudio-module-xrdp" {}; }; port = mkOption { diff --git a/nixos/modules/services/search/hound.nix b/nixos/modules/services/search/hound.nix index e3f9c8da3752a..7aca1adc19b08 100644 --- a/nixos/modules/services/search/hound.nix +++ b/nixos/modules/services/search/hound.nix @@ -1,71 +1,66 @@ { config, lib, pkgs, ... }: -with lib; let cfg = config.services.hound; + settingsFormat = pkgs.formats.json { }; in { imports = [ (lib.mkRemovedOptionModule [ "services" "hound" "extraGroups" ] "Use users.users.hound.extraGroups instead") + (lib.mkChangedOptionModule [ "services" "hound" "config" ] [ "services" "hound" "settings" ] (config: builtins.fromJSON config.services.hound.config)) ]; - meta.maintainers = with maintainers; [ SuperSandro2000 ]; + meta.maintainers = with lib.maintainers; [ SuperSandro2000 ]; options = { services.hound = { - enable = mkOption { - type = types.bool; - default = false; - description = '' - Whether to enable the hound code search daemon. - ''; - }; + enable = lib.mkEnableOption "hound"; - package = mkPackageOptionMD pkgs "hound" { }; + package = lib.mkPackageOption pkgs "hound" { }; - user = mkOption { + user = lib.mkOption { default = "hound"; - type = types.str; + type = lib.types.str; description = '' User the hound daemon should execute under. ''; }; - group = mkOption { + group = lib.mkOption { default = "hound"; - type = types.str; + type = lib.types.str; description = '' Group the hound daemon should execute under. ''; }; - home = mkOption { + home = lib.mkOption { default = "/var/lib/hound"; - type = types.path; + type = lib.types.path; description = '' The path to use as hound's $HOME. If the default user "hound" is configured then this is the home of the "hound" user. ''; }; - config = mkOption { - type = types.str; - description = '' - The full configuration of the Hound daemon. Note the dbpath - should be an absolute path to a writable location on disk. - ''; - example = literalExpression '' + settings = lib.mkOption { + type = settingsFormat.type; + example = lib.literalExpression '' { - "max-concurrent-indexers" : 2, - "repos" : { - "nixpkgs": { - "url" : "https://www.github.com/NixOS/nixpkgs.git" - } - } + max-concurrent-indexers = 2; + repos.nixpkgs.url = "https://www.github.com/NixOS/nixpkgs.git"; } ''; + description = '' + The full configuration of the Hound daemon. + See the upstream documentation <https://github.com/hound-search/hound/blob/main/docs/config-options.md> for details. + + :::{.note} + The `dbpath` should be an absolute path to a writable directory. + :::.com/hound-search/hound/blob/main/docs/config-options.md>. + ''; }; - listen = mkOption { - type = types.str; + listen = lib.mkOption { + type = lib.types.str; default = "0.0.0.0:6080"; example = ":6080"; description = '' @@ -75,7 +70,7 @@ in { }; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { users.groups = lib.mkIf (cfg.group == "hound") { hound = { }; }; @@ -89,16 +84,19 @@ in { }; }; - systemd.services.hound = let - configFile = pkgs.writeTextFile { - name = "hound.json"; - text = cfg.config; - checkPhase = '' - # check if the supplied text is valid json - ${lib.getExe pkgs.jq} . $target > /dev/null - ''; - }; - in { + environment.etc."hound/config.json".source = pkgs.writeTextFile { + name = "hound-config"; + text = builtins.toJSON cfg.settings; + checkPhase = '' + ${cfg.package}/bin/houndd -check-conf -conf $out + ''; + }; + + services.hound.settings = { + dbpath = "${config.services.hound.home}/data"; + }; + + systemd.services.hound = { description = "Hound Code Search"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; @@ -107,7 +105,7 @@ in { Group = cfg.group; WorkingDirectory = cfg.home; ExecStartPre = "${pkgs.git}/bin/git config --global --replace-all http.sslCAinfo /etc/ssl/certs/ca-certificates.crt"; - ExecStart = "${cfg.package}/bin/houndd -addr ${cfg.listen} -conf ${configFile}"; + ExecStart = "${cfg.package}/bin/houndd -addr ${cfg.listen} -conf /etc/hound/config.json"; }; }; }; diff --git a/nixos/modules/services/search/quickwit.nix b/nixos/modules/services/search/quickwit.nix index 6b2db935cf0bf..c4cc0c2427dff 100644 --- a/nixos/modules/services/search/quickwit.nix +++ b/nixos/modules/services/search/quickwit.nix @@ -160,7 +160,7 @@ in ProtectProc = "invisible"; ProtectSystem = "strict"; ReadWritePaths = [ - "/var/lib/quickwit" + cfg.dataDir ]; RestrictAddressFamilies = [ "AF_NETLINK" diff --git a/nixos/modules/services/system/localtimed.nix b/nixos/modules/services/system/localtimed.nix index 8af22892a117c..bd83d227aa35c 100644 --- a/nixos/modules/services/system/localtimed.nix +++ b/nixos/modules/services/system/localtimed.nix @@ -18,6 +18,8 @@ in { geoclue2 to determine the current location. ''; }; + package = mkPackageOption pkgs "localtime" { }; + geoclue2Package = mkPackageOption pkgs "geoclue2-with-demo-agent" { }; }; }; @@ -29,14 +31,14 @@ in { }; # Install the polkit rules. - environment.systemPackages = [ pkgs.localtime ]; + environment.systemPackages = [ cfg.package ]; systemd.services.localtimed = { wantedBy = [ "multi-user.target" ]; partOf = [ "localtimed-geoclue-agent.service" ]; after = [ "localtimed-geoclue-agent.service" ]; serviceConfig = { - ExecStart = "${pkgs.localtime}/bin/localtimed"; + ExecStart = "${cfg.package}/bin/localtimed"; Restart = "on-failure"; Type = "exec"; User = "localtimed"; @@ -48,7 +50,7 @@ in { partOf = [ "geoclue.service" ]; after = [ "geoclue.service" ]; serviceConfig = { - ExecStart = "${pkgs.geoclue2-with-demo-agent}/libexec/geoclue-2.0/demos/agent"; + ExecStart = "${cfg.geoclue2Package}/libexec/geoclue-2.0/demos/agent"; Restart = "on-failure"; Type = "exec"; User = "localtimed"; diff --git a/nixos/modules/services/ttys/kmscon.nix b/nixos/modules/services/ttys/kmscon.nix index 031c5bbb383e1..b8e9330498c0c 100644 --- a/nixos/modules/services/ttys/kmscon.nix +++ b/nixos/modules/services/ttys/kmscon.nix @@ -41,6 +41,12 @@ in { }; in nullOr (nonEmptyListOf fontType); }; + useXkbConfig = mkOption { + description = "Configure keymap from xserver keyboard settings."; + type = types.bool; + default = false; + }; + extraConfig = mkOption { description = "Extra contents of the kmscon.conf file."; type = types.lines; @@ -67,45 +73,39 @@ in { }; config = mkIf cfg.enable { - # Largely copied from unit provided with kmscon source - systemd.units."kmsconvt@.service".text = '' - [Unit] - Description=KMS System Console on %I - Documentation=man:kmscon(1) - After=systemd-user-sessions.service - After=plymouth-quit-wait.service - After=systemd-logind.service - After=systemd-vconsole-setup.service - Requires=systemd-logind.service - Before=getty.target - Conflicts=getty@%i.service - OnFailure=getty@%i.service - IgnoreOnIsolate=yes - ConditionPathExists=/dev/tty0 - - [Service] - ExecStart= - ExecStart=${pkgs.kmscon}/bin/kmscon "--vt=%I" ${cfg.extraOptions} --seats=seat0 --no-switchvt --configdir ${configDir} --login -- ${pkgs.shadow}/bin/login -p ${autologinArg} - UtmpIdentifier=%I - TTYPath=/dev/%I - TTYReset=yes - TTYVHangup=yes - TTYVTDisallocate=yes - - X-RestartIfChanged=false - ''; + systemd.packages = [ pkgs.kmscon ]; + + systemd.services."kmsconvt@" = { + after = [ "systemd-logind.service" "systemd-vconsole-setup.service" ]; + requires = [ "systemd-logind.service" ]; + + serviceConfig.ExecStart = [ + "" + '' + ${pkgs.kmscon}/bin/kmscon "--vt=%I" ${cfg.extraOptions} --seats=seat0 --no-switchvt --configdir ${configDir} --login -- ${pkgs.shadow}/bin/login -p ${autologinArg} + '' + ]; + + restartIfChanged = false; + aliases = [ "autovt@.service" ]; + }; systemd.suppressedSystemUnits = [ "autovt@.service" ]; - systemd.units."kmsconvt@.service".aliases = [ "autovt@.service" ]; systemd.services.systemd-vconsole-setup.enable = false; systemd.services.reload-systemd-vconsole-setup.enable = false; services.kmscon.extraConfig = let + xkb = optionals cfg.useXkbConfig + lib.mapAttrsToList (n: v: "xkb-${n}=${v}") ( + lib.filterAttrs + (n: v: builtins.elem n ["layout" "model" "options" "variant"] && v != "") + config.services.xserver.xkb + ); render = optionals cfg.hwRender [ "drm" "hwaccel" ]; fonts = optional (cfg.fonts != null) "font-name=${lib.concatMapStringsSep ", " (f: f.name) cfg.fonts}"; - in lib.concatStringsSep "\n" (render ++ fonts); + in lib.concatStringsSep "\n" (xkb ++ render ++ fonts); hardware.graphics.enable = mkIf cfg.hwRender true; diff --git a/nixos/modules/services/web-apps/code-server.nix b/nixos/modules/services/web-apps/code-server.nix index abb5be50d353e..f94a1a8b53fa4 100644 --- a/nixos/modules/services/web-apps/code-server.nix +++ b/nixos/modules/services/web-apps/code-server.nix @@ -9,7 +9,7 @@ in { services.code-server = { enable = lib.mkEnableOption "code-server"; - package = lib.mkPackageOptionMD pkgs "code-server" { + package = lib.mkPackageOption pkgs "code-server" { example = '' pkgs.vscode-with-extensions.override { vscode = pkgs.code-server; diff --git a/nixos/modules/services/web-apps/healthchecks.nix b/nixos/modules/services/web-apps/healthchecks.nix index 5562b37e502c6..c7db999a62c21 100644 --- a/nixos/modules/services/web-apps/healthchecks.nix +++ b/nixos/modules/services/web-apps/healthchecks.nix @@ -11,7 +11,7 @@ let environment = { PYTHONPATH = pkg.pythonPath; STATIC_ROOT = cfg.dataDir + "/static"; - } // cfg.settings; + } // lib.filterAttrs (_: v: !builtins.isNull v) cfg.settings; environmentFile = pkgs.writeText "healthchecks-environment" (lib.generators.toKeyValue { } environment); @@ -21,6 +21,7 @@ let sudo='exec /run/wrappers/bin/sudo -u ${cfg.user} --preserve-env --preserve-env=PYTHONPATH' fi export $(cat ${environmentFile} | xargs) + ${lib.optionalString (cfg.settingsFile != null) "export $(cat ${cfg.settingsFile} | xargs)"} $sudo ${pkg}/opt/healthchecks/manage.py "$@" ''; in @@ -89,6 +90,12 @@ in ''; }; + settingsFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = opt.settings.description; + }; + settings = lib.mkOption { description = '' Environment variables which are read by healthchecks `(local)_settings.py`. @@ -109,6 +116,8 @@ in 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. + + If the same variable is set in both `settings` and `settingsFile` the value from `settingsFile` has priority. ''; type = types.submodule (settings: { freeformType = types.attrsOf types.str; @@ -121,8 +130,9 @@ in }; SECRET_KEY_FILE = mkOption { - type = types.path; + type = types.nullOr types.path; description = "Path to a file containing the secret key."; + default = null; }; DEBUG = mkOption { @@ -186,7 +196,9 @@ in WorkingDirectory = cfg.dataDir; User = cfg.user; Group = cfg.group; - EnvironmentFile = [ environmentFile ]; + EnvironmentFile = [ + environmentFile + ] ++ lib.optional (cfg.settingsFile != null) cfg.settingsFile; StateDirectory = mkIf (cfg.dataDir == "/var/lib/healthchecks") "healthchecks"; StateDirectoryMode = mkIf (cfg.dataDir == "/var/lib/healthchecks") "0750"; }; diff --git a/nixos/modules/services/web-apps/invidious.nix b/nixos/modules/services/web-apps/invidious.nix index f0e860383a62c..7997ea1f36308 100644 --- a/nixos/modules/services/web-apps/invidious.nix +++ b/nixos/modules/services/web-apps/invidious.nix @@ -390,7 +390,7 @@ in ''; }; - package = lib.mkPackageOptionMD pkgs "http3-ytproxy" { }; + package = lib.mkPackageOption pkgs "http3-ytproxy" { }; }; }; diff --git a/nixos/modules/services/web-apps/keycloak.nix b/nixos/modules/services/web-apps/keycloak.nix index 36bae2575974e..5d429675bafcf 100644 --- a/nixos/modules/services/web-apps/keycloak.nix +++ b/nixos/modules/services/web-apps/keycloak.nix @@ -328,7 +328,7 @@ in }; hostname = mkOption { - type = str; + type = nullOr str; example = "keycloak.example.com"; description = '' The hostname part of the public URL used as base for @@ -478,6 +478,10 @@ in message = "Setting up a local PostgreSQL db for Keycloak requires `standard_conforming_strings` turned on to work reliably"; } { + assertion = cfg.settings.hostname != null || ! cfg.settings.hostname-strict or true; + message = "Setting the Keycloak hostname is required, see `services.keycloak.settings.hostname`"; + } + { assertion = cfg.settings.hostname-url or null == null; message = '' The option `services.keycloak.settings.hostname-url' has been removed. diff --git a/nixos/modules/services/web-apps/limesurvey.nix b/nixos/modules/services/web-apps/limesurvey.nix index cdd60f572b990..dbcd9eae2d29a 100644 --- a/nixos/modules/services/web-apps/limesurvey.nix +++ b/nixos/modules/services/web-apps/limesurvey.nix @@ -18,7 +18,15 @@ let limesurveyConfig = pkgs.writeText "config.php" '' <?php - return json_decode('${builtins.toJSON cfg.config}', true); + return \array_merge( + \json_decode('${builtins.toJSON cfg.config}', true), + [ + 'config' => [ + 'encryptionnonce' => \trim(\file_get_contents(\getenv('CREDENTIALS_DIRECTORY') . DIRECTORY_SEPARATOR . 'encryption_nonce')), + 'encryptionsecretboxkey' => \trim(\file_get_contents(\getenv('CREDENTIALS_DIRECTORY') . DIRECTORY_SEPARATOR . 'encryption_key')), + ] + ] + ); ?> ''; @@ -35,8 +43,9 @@ in package = mkPackageOption pkgs "limesurvey" { }; encryptionKey = mkOption { - type = types.str; - default = "E17687FC77CEE247F0E22BB3ECF27FDE8BEC310A892347EC13013ABA11AA7EB5"; + type = types.nullOr types.str; + default = null; + visible = false; description = '' This is a 32-byte key used to encrypt variables in the database. You _must_ change this from the default value. @@ -44,14 +53,35 @@ in }; encryptionNonce = mkOption { - type = types.str; - default = "1ACC8555619929DB91310BE848025A427B0F364A884FFA77"; + type = types.nullOr types.str; + default = null; + visible = false; description = '' This is a 24-byte nonce used to encrypt variables in the database. You _must_ change this from the default value. ''; }; + encryptionKeyFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + 32-byte key used to encrypt variables in the database. + + Note: It should be string not a store path in order to prevent the password from being world readable + ''; + }; + + encryptionNonceFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + 24-byte used to encrypt variables in the database. + + Note: It should be string not a store path in order to prevent the password from being world readable + ''; + }; + database = { type = mkOption { type = types.enum [ "mysql" "pgsql" "odbc" "mssql" ]; @@ -183,6 +213,22 @@ in { assertion = cfg.database.createLocally -> cfg.database.passwordFile == null; message = "a password cannot be specified if services.limesurvey.database.createLocally is set to true"; } + { assertion = cfg.encryptionKey != null || cfg.encryptionKeyFile != null; + message = '' + You must set `services.limesurvey.encryptionKeyFile` to a file containing a 32-character uppercase hex string. + + If this message appears when updating your system, please turn off encryption + in the LimeSurvey interface and create backups before filling the key. + ''; + } + { assertion = cfg.encryptionNonce != null || cfg.encryptionNonceFile != null; + message = '' + You must set `services.limesurvey.encryptionNonceFile` to a file containing a 24-character uppercase hex string. + + If this message appears when updating your system, please turn off encryption + in the LimeSurvey interface and create backups before filling the nonce. + ''; + } ]; services.limesurvey.config = mapAttrs (name: mkDefault) { @@ -204,8 +250,6 @@ in config = { tempdir = "${stateDir}/tmp"; uploaddir = "${stateDir}/upload"; - encryptionnonce = cfg.encryptionNonce; - encryptionsecretboxkey = cfg.encryptionKey; force_ssl = mkIf (cfg.virtualHost.addSSL || cfg.virtualHost.forceSSL || cfg.virtualHost.onlySSL) "on"; config.defaultlang = "en"; }; @@ -229,11 +273,26 @@ in phpPackage = pkgs.php81; phpEnv.DBENGINE = "${cfg.database.dbEngine}"; phpEnv.LIMESURVEY_CONFIG = "${limesurveyConfig}"; + # App code cannot access credentials directly since the service starts + # with the root user so we copy the credentials to a place accessible to Limesurvey + phpEnv.CREDENTIALS_DIRECTORY = "${stateDir}/credentials"; settings = { "listen.owner" = config.services.httpd.user; "listen.group" = config.services.httpd.group; } // cfg.poolConfig; }; + systemd.services.phpfpm-limesurvey.serviceConfig = { + ExecStartPre = pkgs.writeShellScript "limesurvey-phpfpm-exec-pre" '' + cp -f "''${CREDENTIALS_DIRECTORY}"/encryption_key "${stateDir}/credentials/encryption_key" + chown ${user}:${group} "${stateDir}/credentials/encryption_key" + cp -f "''${CREDENTIALS_DIRECTORY}"/encryption_nonce "${stateDir}/credentials/encryption_nonce" + chown ${user}:${group} "${stateDir}/credentials/encryption_nonce" + ''; + LoadCredential = [ + "encryption_key:${if cfg.encryptionKeyFile != null then cfg.encryptionKeyFile else pkgs.writeText "key" cfg.encryptionKey}" + "encryption_nonce:${if cfg.encryptionNonceFile != null then cfg.encryptionNonceFile else pkgs.writeText "nonce" cfg.encryptionKey}" + ]; + }; services.httpd = { enable = true; @@ -277,6 +336,7 @@ in "d ${stateDir}/tmp/assets 0750 ${user} ${group} - -" "d ${stateDir}/tmp/runtime 0750 ${user} ${group} - -" "d ${stateDir}/tmp/upload 0750 ${user} ${group} - -" + "d ${stateDir}/credentials 0700 ${user} ${group} - -" "C ${stateDir}/upload 0750 ${user} ${group} - ${cfg.package}/share/limesurvey/upload" ]; @@ -295,6 +355,10 @@ in User = user; Group = group; Type = "oneshot"; + LoadCredential = [ + "encryption_key:${if cfg.encryptionKeyFile != null then cfg.encryptionKeyFile else pkgs.writeText "key" cfg.encryptionKey}" + "encryption_nonce:${if cfg.encryptionNonceFile != null then cfg.encryptionNonceFile else pkgs.writeText "nonce" cfg.encryptionKey}" + ]; }; }; diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix index a4a1f399f4e22..bfb3e73e65102 100644 --- a/nixos/modules/services/web-apps/nextcloud.nix +++ b/nixos/modules/services/web-apps/nextcloud.nix @@ -300,7 +300,7 @@ in { package = mkOption { type = types.package; description = "Which package to use for the Nextcloud instance."; - relatedPackages = [ "nextcloud26" "nextcloud27" "nextcloud28" ]; + relatedPackages = [ "nextcloud28" "nextcloud29" ]; }; phpPackage = mkPackageOption pkgs "php" { example = "php82"; @@ -861,8 +861,6 @@ in { nextcloud defined in an overlay, please set `services.nextcloud.package` to `pkgs.nextcloud`. '' - else if versionOlder stateVersion "23.05" then nextcloud25 - else if versionOlder stateVersion "23.11" then nextcloud26 else if versionOlder stateVersion "24.05" then nextcloud27 else nextcloud29 ); diff --git a/nixos/modules/services/web-apps/peering-manager.nix b/nixos/modules/services/web-apps/peering-manager.nix index c85cb76e5ea11..acdc393745293 100644 --- a/nixos/modules/services/web-apps/peering-manager.nix +++ b/nixos/modules/services/web-apps/peering-manager.nix @@ -16,6 +16,8 @@ let ln -s ${configFile} $out/opt/peering-manager/peering_manager/configuration.py '' + lib.optionalString cfg.enableLdap '' ln -s ${cfg.ldapConfigPath} $out/opt/peering-manager/peering_manager/ldap_config.py + '' + lib.optionalString cfg.enableOidc '' + ln -s ${cfg.oidcConfigPath} $out/opt/peering-manager/peering_manager/oidc_config.py ''; })).override { inherit (cfg) plugins; @@ -139,6 +141,24 @@ in { See the [documentation](https://peering-manager.readthedocs.io/en/stable/setup/6-ldap/#configuration) for possible options. ''; }; + + enableOidc = mkOption { + type = types.bool; + default = false; + description = '' + Enable OIDC-Authentication for Peering Manager. + + This requires a configuration file being pass through `oidcConfigPath`. + ''; + }; + + oidcConfigPath = mkOption { + type = types.path; + description = '' + Path to the Configuration-File for OIDC-Authentication, will be loaded as `oidc_config.py`. + See the [documentation](https://peering-manager.readthedocs.io/en/stable/setup/6b-oidc/#configuration) for possible options. + ''; + }; }; config = lib.mkIf cfg.enable { @@ -173,7 +193,10 @@ in { PEERINGDB_API_KEY = file.readline() ''; - plugins = lib.mkIf cfg.enableLdap (ps: [ ps.django-auth-ldap ]); + plugins = (ps: + (lib.optionals cfg.enableLdap [ ps.django-auth-ldap ]) ++ + (lib.optionals cfg.enableOidc (with ps; [ mozilla-django-oidc pyopenssl josepy ])) + ); }; system.build.peeringManagerPkg = pkg; diff --git a/nixos/modules/services/web-apps/pretalx.nix b/nixos/modules/services/web-apps/pretalx.nix index 1411d11982c87..2280d9165b40b 100644 --- a/nixos/modules/services/web-apps/pretalx.nix +++ b/nixos/modules/services/web-apps/pretalx.nix @@ -35,7 +35,7 @@ in options.services.pretalx = { enable = lib.mkEnableOption "pretalx"; - package = lib.mkPackageOptionMD pkgs "pretalx" {}; + package = lib.mkPackageOption pkgs "pretalx" {}; group = lib.mkOption { type = lib.types.str; diff --git a/nixos/modules/services/web-apps/silverbullet.nix b/nixos/modules/services/web-apps/silverbullet.nix index 5d5f950a9a661..a6a830e674b49 100644 --- a/nixos/modules/services/web-apps/silverbullet.nix +++ b/nixos/modules/services/web-apps/silverbullet.nix @@ -14,7 +14,7 @@ in services.silverbullet = { enable = lib.mkEnableOption "Silverbullet, an open-source, self-hosted, offline-capable Personal Knowledge Management (PKM) web application"; - package = lib.mkPackageOptionMD pkgs "silverbullet" { }; + package = lib.mkPackageOption pkgs "silverbullet" { }; openFirewall = lib.mkOption { type = lib.types.bool; diff --git a/nixos/modules/services/web-apps/slskd.nix b/nixos/modules/services/web-apps/slskd.nix index 6254fe294eeed..7d4bc66c73998 100644 --- a/nixos/modules/services/web-apps/slskd.nix +++ b/nixos/modules/services/web-apps/slskd.nix @@ -7,7 +7,7 @@ in { options.services.slskd = with lib; with types; { enable = mkEnableOption "slskd"; - package = mkPackageOptionMD pkgs "slskd" { }; + package = mkPackageOption pkgs "slskd" { }; user = mkOption { type = types.str; diff --git a/nixos/modules/services/web-apps/suwayomi-server.nix b/nixos/modules/services/web-apps/suwayomi-server.nix index ba2352d0e693f..caa091685d2fb 100644 --- a/nixos/modules/services/web-apps/suwayomi-server.nix +++ b/nixos/modules/services/web-apps/suwayomi-server.nix @@ -11,7 +11,7 @@ in services.suwayomi-server = { enable = mkEnableOption "Suwayomi, a free and open source manga reader server that runs extensions built for Tachiyomi"; - package = lib.mkPackageOptionMD pkgs "suwayomi-server" { }; + package = lib.mkPackageOption pkgs "suwayomi-server" { }; dataDir = mkOption { type = types.path; diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix index 69a83ecb72065..aee2f5b35db2e 100644 --- a/nixos/modules/services/x11/desktop-managers/xfce.nix +++ b/nixos/modules/services/x11/desktop-managers/xfce.nix @@ -165,6 +165,7 @@ in services.tumbler.enable = true; services.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true)); services.libinput.enable = mkDefault true; # used in xfce4-settings-manager + services.colord.enable = mkDefault true; # Enable default programs programs.dconf.enable = true; diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix index 107a2f1647925..51ab08e74f864 100644 --- a/nixos/modules/services/x11/display-managers/gdm.nix +++ b/nixos/modules/services/x11/display-managers/gdm.nix @@ -321,6 +321,22 @@ in session include login ''; + login.fprintAuth = mkIf config.services.fprintd.enable false; + gdm-fingerprint.text = mkIf config.services.fprintd.enable '' + auth required pam_shells.so + auth requisite pam_nologin.so + auth requisite pam_faillock.so preauth + auth required ${pkgs.fprintd}/lib/security/pam_fprintd.so + auth optional pam_permit.so + auth required pam_env.so + auth [success=ok default=1] ${pkgs.gnome.gdm}/lib/security/pam_gdm.so + + account include login + + password required pam_deny.so + + session include login + ''; }; }; diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 14a4ab596b52c..76a6751b05708 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -489,7 +489,7 @@ in system.nssModules = [ cfg.package.out ]; system.nssDatabases = { hosts = (mkMerge [ - (mkOrder 400 ["mymachines"]) # 400 to ensure it comes before resolve (which is mkBefore'd) + (mkOrder 400 ["mymachines"]) # 400 to ensure it comes before resolve (which is 501) (mkOrder 999 ["myhostname"]) # after files (which is 998), but before regular nss modules ]); passwd = (mkMerge [ diff --git a/nixos/modules/system/etc/etc.nix b/nixos/modules/system/etc/etc.nix index 80ca69e495e9d..87932075f3679 100644 --- a/nixos/modules/system/etc/etc.nix +++ b/nixos/modules/system/etc/etc.nix @@ -64,14 +64,6 @@ let etcHardlinks = filter (f: f.mode != "symlink" && f.mode != "direct-symlink") etc'; - build-composefs-dump = pkgs.runCommand "build-composefs-dump.py" - { - buildInputs = [ pkgs.python3 ]; - } '' - install ${./build-composefs-dump.py} $out - patchShebangs --host $out - ''; - in { @@ -295,10 +287,12 @@ in system.build.etcMetadataImage = let etcJson = pkgs.writeText "etc-json" (builtins.toJSON etc'); - etcDump = pkgs.runCommand "etc-dump" { } "${build-composefs-dump} ${etcJson} > $out"; + etcDump = pkgs.runCommand "etc-dump" { } '' + ${lib.getExe pkgs.buildPackages.python3} ${./build-composefs-dump.py} ${etcJson} > $out + ''; in pkgs.runCommand "etc-metadata.erofs" { - nativeBuildInputs = [ pkgs.composefs pkgs.erofs-utils ]; + nativeBuildInputs = with pkgs.buildPackages; [ composefs erofs-utils ]; } '' mkcomposefs --from-file ${etcDump} $out fsck.erofs $out diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix index 9fbb126738a93..72c2a2ef5551c 100644 --- a/nixos/modules/virtualisation/libvirtd.nix +++ b/nixos/modules/virtualisation/libvirtd.nix @@ -545,9 +545,10 @@ in }; system.nssModules = optional (cfg.nss.enable or cfg.nss.enableGuest) cfg.package; - system.nssDatabases.hosts = builtins.concatLists [ - (optional cfg.nss.enable "libvirt") - (optional cfg.nss.enableGuest "libvirt_guest") + system.nssDatabases.hosts = mkMerge [ + # ensure that the NSS modules come between mymachines (which is 400) and resolve (which is 501) + (mkIf cfg.nss.enable (mkOrder 430 [ "libvirt" ])) + (mkIf cfg.nss.enableGuest (mkOrder 432 [ "libvirt_guest" ])) ]; }; } diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix index a34fe132ba7e1..4808652a542ad 100644 --- a/nixos/modules/virtualisation/virtualbox-host.nix +++ b/nixos/modules/virtualisation/virtualbox-host.nix @@ -89,7 +89,7 @@ in Enable KVM support for VirtualBox. This increases compatibility with Linux kernel versions, because the VirtualBox kernel modules are not required. - This option is incompatible with `enableHardening` and `addNetworkInterface`. + This option is incompatible with `addNetworkInterface`. Note: This is experimental. Please check https://github.com/cyberus-technology/virtualbox-kvm/issues. ''; @@ -136,18 +136,6 @@ in assertion = !cfg.addNetworkInterface; message = "VirtualBox KVM only supports standard NAT networking for VMs. Please turn off virtualisation.virtualbox.host.addNetworkInterface."; } - - { - assertion = !cfg.enableHardening; - message = "VirtualBox KVM is not compatible with hardening: Please turn off virtualisation.virtualbox.host.enableHardening."; - } - ]; - - warnings = [ - '' - KVM support in VirtualBox is experimental. Not all security features are available yet. - See: https://github.com/cyberus-technology/virtualbox-kvm/issues/12 - '' ]; }) (mkIf (!cfg.enableKvm) { boot.kernelModules = [ "vboxdrv" "vboxnetadp" "vboxnetflt" ]; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index ad9025a917c38..d16b747bfa95e 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -651,6 +651,7 @@ in { nix-config = handleTest ./nix-config.nix {}; nix-ld = handleTest ./nix-ld.nix {}; nix-misc = handleTest ./nix/misc.nix {}; + nix-required-mounts = runTest ./nix-required-mounts; nix-serve = handleTest ./nix-serve.nix {}; nix-serve-ssh = handleTest ./nix-serve-ssh.nix {}; nixops = handleTest ./nixops/default.nix {}; diff --git a/nixos/tests/buildbot.nix b/nixos/tests/buildbot.nix index 149d73bba09c5..0f65ac21c83d6 100644 --- a/nixos/tests/buildbot.nix +++ b/nixos/tests/buildbot.nix @@ -14,7 +14,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { "steps.ShellCommand(command=['bash', 'fakerepo.sh'])" ]; changeSource = [ - "changes.GitPoller('git://gitrepo/fakerepo.git', workdir='gitpoller-workdir', branch='master', pollinterval=300)" + "changes.GitPoller('git://gitrepo/fakerepo.git', workdir='gitpoller-workdir', branch='master', pollInterval=300)" ]; }; networking.firewall.allowedTCPPorts = [ 8010 8011 9989 ]; diff --git a/nixos/tests/kafka.nix b/nixos/tests/kafka.nix index f4f9827ab7b5f..8f843e1fc37da 100644 --- a/nixos/tests/kafka.nix +++ b/nixos/tests/kafka.nix @@ -103,13 +103,8 @@ let }) { inherit system; }); in with pkgs; { - kafka_2_8 = makeKafkaTest "kafka_2_8" { kafkaPackage = apacheKafka_2_8; }; - kafka_3_0 = makeKafkaTest "kafka_3_0" { kafkaPackage = apacheKafka_3_0; }; - kafka_3_1 = makeKafkaTest "kafka_3_1" { kafkaPackage = apacheKafka_3_1; }; - kafka_3_2 = makeKafkaTest "kafka_3_2" { kafkaPackage = apacheKafka_3_2; }; - kafka_3_3 = makeKafkaTest "kafka_3_3" { kafkaPackage = apacheKafka_3_3; }; - kafka_3_4 = makeKafkaTest "kafka_3_4" { kafkaPackage = apacheKafka_3_4; }; - kafka_3_5 = makeKafkaTest "kafka_3_5" { kafkaPackage = apacheKafka_3_5; }; + kafka_3_6 = makeKafkaTest "kafka_3_6" { kafkaPackage = apacheKafka_3_6; }; + kafka_3_7 = makeKafkaTest "kafka_3_7" { kafkaPackage = apacheKafka_3_7; }; kafka = makeKafkaTest "kafka" { kafkaPackage = apacheKafka; }; kafka_kraft = makeKafkaTest "kafka_kraft" { kafkaPackage = apacheKafka; mode = "kraft"; }; } diff --git a/nixos/tests/kernel-generic.nix b/nixos/tests/kernel-generic.nix index 6a8633808702f..e22c7d735a238 100644 --- a/nixos/tests/kernel-generic.nix +++ b/nixos/tests/kernel-generic.nix @@ -47,6 +47,9 @@ in mapAttrs (_: lP: testsForLinuxPackages lP) kernels // { passthru = { inherit testsForLinuxPackages; + # Useful for development testing of all Kernel configs without building full Kernel + configfiles = mapAttrs (_: lP: lP.kernel.configfile) kernels; + testsForKernel = kernel: testsForLinuxPackages (pkgs.linuxPackagesFor kernel); }; } diff --git a/nixos/tests/limesurvey.nix b/nixos/tests/limesurvey.nix index 9a3193991f352..87e9fe1cdc149 100644 --- a/nixos/tests/limesurvey.nix +++ b/nixos/tests/limesurvey.nix @@ -1,6 +1,6 @@ -import ./make-test-python.nix ({ pkgs, ... }: { +import ./make-test-python.nix ({ lib, pkgs, ... }: { name = "limesurvey"; - meta.maintainers = [ pkgs.lib.maintainers.aanderse ]; + meta.maintainers = [ lib.maintainers.aanderse ]; nodes.machine = { ... }: { services.limesurvey = { @@ -9,6 +9,8 @@ import ./make-test-python.nix ({ pkgs, ... }: { hostName = "example.local"; adminAddr = "root@example.local"; }; + encryptionKeyFile = pkgs.writeText "key" (lib.strings.replicate 32 "0"); + encryptionNonceFile = pkgs.writeText "nonce" (lib.strings.replicate 24 "0"); }; # limesurvey won't work without a dot in the hostname diff --git a/nixos/tests/lomiri.nix b/nixos/tests/lomiri.nix index e9134a202cd17..d1fbab7aba082 100644 --- a/nixos/tests/lomiri.nix +++ b/nixos/tests/lomiri.nix @@ -230,7 +230,7 @@ in { # morph-browser has a separate VM test, there isn't anything new we could test here - # Keep it running, we're using it to check content-hub communication from LSS + machine.send_key("alt-f4") # LSS provides DE settings with subtest("system settings open"): @@ -282,9 +282,7 @@ in { # Testing any more would require more applications & setup, the fact that it's already being attempted is a good sign machine.send_key("esc") - machine.send_key("alt-f4") # LSS - machine.sleep(2) # focus is slow to switch to second window, closing it *really* helps with OCR afterwards - machine.send_key("alt-f4") # Morph + machine.send_key("alt-f4") # The ayatana indicators are an important part of the experience, and they hold the only graphical way of exiting the session. # There's a test app we could use that also displays their contents, but it's abit inconsistent. diff --git a/nixos/tests/nextcloud/default.nix b/nixos/tests/nextcloud/default.nix index 33aa227d2b032..9f8b06561b074 100644 --- a/nixos/tests/nextcloud/default.nix +++ b/nixos/tests/nextcloud/default.nix @@ -109,4 +109,4 @@ let ./with-objectstore.nix ]; in -listToAttrs (concatMap genTests [ 27 28 29 ]) +listToAttrs (concatMap genTests [ 28 29 ]) diff --git a/nixos/tests/nix-required-mounts/default.nix b/nixos/tests/nix-required-mounts/default.nix new file mode 100644 index 0000000000000..60f894ce0bcc6 --- /dev/null +++ b/nixos/tests/nix-required-mounts/default.nix @@ -0,0 +1,58 @@ +{ pkgs, ... }: + +let + inherit (pkgs) lib; +in + +{ + name = "nix-required-mounts"; + meta.maintainers = with lib.maintainers; [ SomeoneSerge ]; + nodes.machine = + { config, pkgs, ... }: + { + virtualisation.writableStore = true; + system.extraDependencies = [ (pkgs.runCommand "deps" { } "mkdir $out").inputDerivation ]; + nix.nixPath = [ "nixpkgs=${../../..}" ]; + nix.settings.substituters = lib.mkForce [ ]; + nix.settings.system-features = [ "supported-feature" ]; + nix.settings.experimental-features = [ "nix-command" ]; + programs.nix-required-mounts.enable = true; + programs.nix-required-mounts.allowedPatterns.supported-feature = { + onFeatures = [ "supported-feature" ]; + paths = [ + "/supported-feature-files" + { + host = "/usr/lib/imaginary-fhs-drivers"; + guest = "/run/opengl-driver/lib"; + } + ]; + unsafeFollowSymlinks = true; + }; + users.users.person.isNormalUser = true; + systemd.tmpfiles.rules = [ + "d /supported-feature-files 0755 person users -" + "f /usr/lib/libcuda.so 0444 root root - fakeContent" + "L /usr/lib/imaginary-fhs-drivers/libcuda.so 0444 root root - /usr/lib/libcuda.so" + ]; + }; + testScript = '' + import shlex + + def person_do(cmd, succeed=True): + cmd = shlex.quote(cmd) + cmd = f"su person -l -c {cmd} &>/dev/console" + + if succeed: + return machine.succeed(cmd) + else: + return machine.fail(cmd) + + start_all() + + person_do("nix-build ${./ensure-path-not-present.nix} --argstr feature supported-feature") + person_do("nix-build ${./test-require-feature.nix} --argstr feature supported-feature") + person_do("nix-build ${./test-require-feature.nix} --argstr feature unsupported-feature", succeed=False) + person_do("nix-build ${./test-structured-attrs.nix} --argstr feature supported-feature") + person_do("nix-build ${./test-structured-attrs-empty.nix}") + ''; +} diff --git a/nixos/tests/nix-required-mounts/ensure-path-not-present.nix b/nixos/tests/nix-required-mounts/ensure-path-not-present.nix new file mode 100644 index 0000000000000..270c268fcbd9e --- /dev/null +++ b/nixos/tests/nix-required-mounts/ensure-path-not-present.nix @@ -0,0 +1,13 @@ +{ + pkgs ? import <nixpkgs> { }, + feature, +}: + +pkgs.runCommandNoCC "${feature}-not-present" { } '' + if [[ -e /${feature}-files ]]; then + echo "No ${feature} in requiredSystemFeatures, but /${feature}-files was mounted anyway" + exit 1 + else + touch $out + fi +'' diff --git a/nixos/tests/nix-required-mounts/test-require-feature.nix b/nixos/tests/nix-required-mounts/test-require-feature.nix new file mode 100644 index 0000000000000..447fd49a300aa --- /dev/null +++ b/nixos/tests/nix-required-mounts/test-require-feature.nix @@ -0,0 +1,26 @@ +{ + pkgs ? import <nixpkgs> { }, + feature, +}: + +pkgs.runCommandNoCC "${feature}-present" { requiredSystemFeatures = [ feature ]; } '' + if [[ ! -e /${feature}-files ]]; then + echo "The host declares ${feature} support, but doesn't expose /${feature}-files" >&2 + exit 1 + fi + libcudaLocation=/run/opengl-driver/lib/libcuda.so + if [[ -e "$libcudaLocation" || -h "$libcudaLocation" ]] ; then + true # we're good + else + echo "The host declares ${feature} support, but it the hook fails to handle the hostPath != guestPath cases" >&2 + exit 1 + fi + if cat "$libcudaLocation" | xargs test fakeContent = ; then + true # we're good + else + echo "The host declares ${feature} support, but it seems to fail to follow symlinks" >&2 + echo "The content of /run/opengl-driver/lib/libcuda.so is: $(cat /run/opengl-driver/lib/libcuda.so)" >&2 + exit 1 + fi + touch $out +'' diff --git a/nixos/tests/nix-required-mounts/test-structured-attrs-empty.nix b/nixos/tests/nix-required-mounts/test-structured-attrs-empty.nix new file mode 100644 index 0000000000000..86f2753309368 --- /dev/null +++ b/nixos/tests/nix-required-mounts/test-structured-attrs-empty.nix @@ -0,0 +1,8 @@ +{ + pkgs ? import <nixpkgs> { }, +}: + +pkgs.runCommandNoCC "nix-required-mounts-structured-attrs-no-features" { __structuredAttrs = true; } + '' + touch $out + '' diff --git a/nixos/tests/nix-required-mounts/test-structured-attrs.nix b/nixos/tests/nix-required-mounts/test-structured-attrs.nix new file mode 100644 index 0000000000000..874910eee7bb3 --- /dev/null +++ b/nixos/tests/nix-required-mounts/test-structured-attrs.nix @@ -0,0 +1,18 @@ +{ + pkgs ? import <nixpkgs> { }, + feature, +}: + +pkgs.runCommandNoCC "${feature}-present-structured" + { + __structuredAttrs = true; + requiredSystemFeatures = [ feature ]; + } + '' + if [[ -e /${feature}-files ]]; then + touch $out + else + echo "The host declares ${feature} support, but doesn't expose /${feature}-files" >&2 + echo "Do we fail to parse __structuredAttrs=true derivations?" >&2 + fi + '' |