diff options
author | Alyssa Ross <hi@alyssa.is> | 2024-03-01 11:40:12 +0100 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2024-03-01 11:40:12 +0100 |
commit | bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86 (patch) | |
tree | 8eb035cbab19794f6415cc460fac7226f7a58afc /nixpkgs/nixos/modules | |
parent | 66f707d69f1e423db5a35c2fe43b32781125a9af (diff) | |
parent | 09c1497ce5d4ed4a0edfdd44450d3048074cb300 (diff) | |
download | nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.tar nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.tar.gz nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.tar.bz2 nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.tar.lz nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.tar.xz nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.tar.zst nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.zip |
Merge branch 'nixos-unstable-small' of https://github.com/NixOS/nixpkgs
Diffstat (limited to 'nixpkgs/nixos/modules')
31 files changed, 1121 insertions, 155 deletions
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-calamares-plasma6.nix b/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-calamares-plasma6.nix new file mode 100644 index 000000000000..11118db3aae2 --- /dev/null +++ b/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-calamares-plasma6.nix @@ -0,0 +1,46 @@ +# This module defines a NixOS installation CD that contains Plasma 6. + +{ pkgs, ... }: + +{ + imports = [ ./installation-cd-graphical-calamares.nix ]; + + isoImage.edition = "plasma6"; + + services.xserver = { + desktopManager.plasma6.enable = true; + + # Automatically login as nixos. + displayManager = { + sddm.enable = true; + autoLogin = { + enable = true; + user = "nixos"; + }; + }; + }; + + environment.systemPackages = [ + # FIXME: using Qt5 builds of Maliit as upstream has not ported to Qt6 yet + pkgs.maliit-framework + pkgs.maliit-keyboard + ]; + + system.activationScripts.installerDesktop = let + + # Comes from documentation.nix when xserver and nixos.enable are true. + manualDesktopFile = "/run/current-system/sw/share/applications/nixos-manual.desktop"; + + homeDir = "/home/nixos/"; + desktopDir = homeDir + "Desktop/"; + + in '' + mkdir -p ${desktopDir} + chown nixos ${homeDir} ${desktopDir} + + ln -sfT ${manualDesktopFile} ${desktopDir + "nixos-manual.desktop"} + ln -sfT ${pkgs.gparted}/share/applications/gparted.desktop ${desktopDir + "gparted.desktop"} + ln -sfT ${pkgs.calamares-nixos}/share/applications/io.calamares.calamares.desktop ${desktopDir + "io.calamares.calamares.desktop"} + ''; + +} diff --git a/nixpkgs/nixos/modules/installer/netboot/netboot.nix b/nixpkgs/nixos/modules/installer/netboot/netboot.nix index a50f22cbe471..028a2d74041e 100644 --- a/nixpkgs/nixos/modules/installer/netboot/netboot.nix +++ b/nixpkgs/nixos/modules/installer/netboot/netboot.nix @@ -62,19 +62,12 @@ with lib; }; fileSystems."/nix/store" = mkImageMediaOverride - { fsType = "overlay"; - device = "overlay"; - options = [ - "lowerdir=/nix/.ro-store" - "upperdir=/nix/.rw-store/store" - "workdir=/nix/.rw-store/work" - ]; - - depends = [ - "/nix/.ro-store" - "/nix/.rw-store/store" - "/nix/.rw-store/work" - ]; + { overlay = { + lowerdir = [ "/nix/.ro-store" ]; + upperdir = "/nix/.rw-store/store"; + workdir = "/nix/.rw-store/work"; + }; + neededForBoot = true; }; boot.initrd.availableKernelModules = [ "squashfs" "overlay" ]; diff --git a/nixpkgs/nixos/modules/module-list.nix b/nixpkgs/nixos/modules/module-list.nix index 5d82c6de77e2..08144140b830 100644 --- a/nixpkgs/nixos/modules/module-list.nix +++ b/nixpkgs/nixos/modules/module-list.nix @@ -512,6 +512,7 @@ ./services/editors/infinoted.nix ./services/finance/odoo.nix ./services/games/archisteamfarm.nix + ./services/games/armagetronad.nix ./services/games/crossfire-server.nix ./services/games/deliantra-server.nix ./services/games/factorio.nix @@ -549,6 +550,7 @@ ./services/hardware/lcd.nix ./services/hardware/lirc.nix ./services/hardware/nvidia-container-toolkit-cdi-generator + ./services/hardware/monado.nix ./services/hardware/nvidia-optimus.nix ./services/hardware/openrgb.nix ./services/hardware/pcscd.nix @@ -1324,6 +1326,7 @@ ./services/web-apps/mastodon.nix ./services/web-apps/matomo.nix ./services/web-apps/mattermost.nix + ./services/web-apps/mealie.nix ./services/web-apps/mediawiki.nix ./services/web-apps/meme-bingo-web.nix ./services/web-apps/microbin.nix diff --git a/nixpkgs/nixos/modules/programs/gnupg.nix b/nixpkgs/nixos/modules/programs/gnupg.nix index 8f82de033666..179d2de87cc5 100644 --- a/nixpkgs/nixos/modules/programs/gnupg.nix +++ b/nixpkgs/nixos/modules/programs/gnupg.nix @@ -15,6 +15,7 @@ let defaultPinentryFlavor = if xserverCfg.desktopManager.lxqt.enable || xserverCfg.desktopManager.plasma5.enable + || xserverCfg.desktopManager.plasma6.enable || xserverCfg.desktopManager.deepin.enable then "qt" else if xserverCfg.desktopManager.xfce.enable then diff --git a/nixpkgs/nixos/modules/programs/wayland/sway.nix b/nixpkgs/nixos/modules/programs/wayland/sway.nix index 57ee629b2881..ca2503ae5da7 100644 --- a/nixpkgs/nixos/modules/programs/wayland/sway.nix +++ b/nixpkgs/nixos/modules/programs/wayland/sway.nix @@ -119,10 +119,10 @@ in { extraPackages = mkOption { type = with types; listOf package; default = with pkgs; [ - swaylock swayidle foot dmenu + swaylock swayidle foot dmenu wmenu ]; defaultText = literalExpression '' - with pkgs; [ swaylock swayidle foot dmenu ]; + with pkgs; [ swaylock swayidle foot dmenu wmenu ]; ''; example = literalExpression '' with pkgs; [ diff --git a/nixpkgs/nixos/modules/security/pam.nix b/nixpkgs/nixos/modules/security/pam.nix index ed03254cb5ee..b87e22b23980 100644 --- a/nixpkgs/nixos/modules/security/pam.nix +++ b/nixpkgs/nixos/modules/security/pam.nix @@ -96,6 +96,10 @@ let pamOpts = { config, name, ... }: let cfg = config; in let config = parentConfig; in { + imports = [ + (lib.mkRenamedOptionModule [ "enableKwallet" ] [ "kwallet" "enable" ]) + ]; + options = { name = mkOption { @@ -462,16 +466,23 @@ let ''; }; - enableKwallet = mkOption { - default = false; - type = types.bool; - description = lib.mdDoc '' - If enabled, pam_wallet will attempt to automatically unlock the - user's default KDE wallet upon login. If the user has no wallet named - "kdewallet", or the login password does not match their wallet - password, KDE will prompt separately after login. - ''; + kwallet = { + enable = mkOption { + default = false; + type = types.bool; + description = lib.mdDoc '' + If enabled, pam_wallet will attempt to automatically unlock the + user's default KDE wallet upon login. If the user has no wallet named + "kdewallet", or the login password does not match their wallet + password, KDE will prompt separately after login. + ''; + }; + + package = mkPackageOption pkgs.plasma5Packages "kwallet-pam" { + pkgsText = "pkgs.plasma5Packages"; + }; }; + sssdStrictAccess = mkOption { default = false; type = types.bool; @@ -686,7 +697,7 @@ let (config.security.pam.enableEcryptfs || config.security.pam.enableFscrypt || cfg.pamMount - || cfg.enableKwallet + || cfg.kwallet.enable || cfg.enableGnomeKeyring || config.services.intune.enable || cfg.googleAuthenticator.enable @@ -711,9 +722,7 @@ let { name = "mount"; enable = cfg.pamMount; control = "optional"; modulePath = "${pkgs.pam_mount}/lib/security/pam_mount.so"; settings = { disable_interactive = true; }; } - { name = "kwallet5"; enable = cfg.enableKwallet; control = "optional"; modulePath = "${pkgs.plasma5Packages.kwallet-pam}/lib/security/pam_kwallet5.so"; settings = { - kwalletd = "${pkgs.plasma5Packages.kwallet.bin}/bin/kwalletd5"; - }; } + { name = "kwallet"; enable = cfg.kwallet.enable; control = "optional"; modulePath = "${cfg.kwallet.package}/lib/security/pam_kwallet5.so"; } { name = "gnome_keyring"; enable = cfg.enableGnomeKeyring; control = "optional"; modulePath = "${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so"; } { name = "intune"; enable = config.services.intune.enable; control = "optional"; modulePath = "${pkgs.intune-portal}/lib/security/pam_intune.so"; } { name = "gnupg"; enable = cfg.gnupg.enable; control = "optional"; modulePath = "${pkgs.pam_gnupg}/lib/security/pam_gnupg.so"; settings = { @@ -848,9 +857,7 @@ let order = "user,group,default"; debug = true; }; } - { name = "kwallet5"; enable = cfg.enableKwallet; control = "optional"; modulePath = "${pkgs.plasma5Packages.kwallet-pam}/lib/security/pam_kwallet5.so"; settings = { - kwalletd = "${pkgs.plasma5Packages.kwallet.bin}/bin/kwalletd5"; - }; } + { name = "kwallet"; enable = cfg.kwallet.enable; control = "optional"; modulePath = "${cfg.kwallet.package}/lib/security/pam_kwallet5.so"; } { name = "gnome_keyring"; enable = cfg.enableGnomeKeyring; control = "optional"; modulePath = "${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so"; settings = { auto_start = true; }; } diff --git a/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix b/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix index aa24c0842bab..8f3ad78d50ce 100644 --- a/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix +++ b/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix @@ -293,6 +293,18 @@ in { assertion = (cfg.alsa.enable || cfg.pulse.enable) -> cfg.audio.enable; message = "Using PipeWire's ALSA/PulseAudio compatibility layers requires running PipeWire as the sound server. Set `services.pipewire.audio.enable` to true."; } + { + assertion = builtins.length + (builtins.attrNames + ( + lib.filterAttrs + (name: value: + lib.hasPrefix "pipewire/" name || name == "pipewire" + ) + config.environment.etc + )) == 1; + message = "Using `environment.etc.\"pipewire<...>\"` directly is no longer supported in 24.05. Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` instead."; + } ]; environment.systemPackages = [ cfg.package ] diff --git a/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix b/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix index dc4d726d7632..99aea8facb16 100644 --- a/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix +++ b/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix @@ -56,13 +56,13 @@ in -- PipeWire is not used for audio, so prevent it from grabbing audio devices alsa_monitor.enable = function() end ''; - systemwideConfigPkg = pkgs.writeTextDir "wireplumber/main.lua.d/80-systemwide.lua" '' + systemwideConfigPkg = pkgs.writeTextDir "share/wireplumber/main.lua.d/80-systemwide.lua" '' -- When running system-wide, these settings need to be disabled (they -- use functions that aren't available on the system dbus). alsa_monitor.properties["alsa.reserve"] = false default_access.properties["enable-flatpak-portal"] = false ''; - systemwideBluetoothConfigPkg = pkgs.writeTextDir "wireplumber/bluetooth.lua.d/80-systemwide.lua" '' + systemwideBluetoothConfigPkg = pkgs.writeTextDir "share/wireplumber/bluetooth.lua.d/80-systemwide.lua" '' -- When running system-wide, logind-integration needs to be disabled. bluez_monitor.properties["with-logind"] = false ''; @@ -98,6 +98,18 @@ in assertion = !config.hardware.bluetooth.hsphfpd.enable; message = "Using WirePlumber conflicts with hsphfpd, as it provides the same functionality. `hardware.bluetooth.hsphfpd.enable` needs be set to false"; } + { + assertion = builtins.length + (builtins.attrNames + ( + lib.filterAttrs + (name: value: + lib.hasPrefix "wireplumber/" name || name == "wireplumber" + ) + config.environment.etc + )) == 1; + message = "Using `environment.etc.\"wireplumber<...>\"` directly is no longer supported in 24.05. Use `services.wireplumber.configPackages` instead."; + } ]; environment.systemPackages = [ cfg.package ]; diff --git a/nixpkgs/nixos/modules/services/games/armagetronad.nix b/nixpkgs/nixos/modules/services/games/armagetronad.nix new file mode 100644 index 000000000000..f79818e0e53b --- /dev/null +++ b/nixpkgs/nixos/modules/services/games/armagetronad.nix @@ -0,0 +1,268 @@ +{ config, lib, pkgs, ... }: +let + inherit (lib) mkEnableOption mkIf mkOption mkMerge literalExpression; + inherit (lib) mapAttrsToList filterAttrs unique recursiveUpdate types; + + mkValueStringArmagetron = with lib; v: + if isInt v then toString v + else if isFloat v then toString v + else if isString v then v + else if true == v then "1" + else if false == v then "0" + else if null == v then "" + else throw "unsupported type: ${builtins.typeOf v}: ${(lib.generators.toPretty {} v)}"; + + settingsFormat = pkgs.formats.keyValue { + mkKeyValue = lib.generators.mkKeyValueDefault + { + mkValueString = mkValueStringArmagetron; + } " "; + listsAsDuplicateKeys = true; + }; + + cfg = config.services.armagetronad; + enabledServers = lib.filterAttrs (n: v: v.enable) cfg.servers; + nameToId = serverName: "armagetronad-${serverName}"; + getStateDirectory = serverName: "armagetronad/${serverName}"; + getServerRoot = serverName: "/var/lib/${getStateDirectory serverName}"; +in +{ + options = { + services.armagetronad = { + servers = mkOption { + description = lib.mdDoc "Armagetron server definitions."; + default = { }; + type = types.attrsOf (types.submodule { + options = { + enable = mkEnableOption (lib.mdDoc "armagetronad"); + + package = lib.mkPackageOptionMD pkgs "armagetronad-dedicated" { + example = '' + pkgs.armagetronad."0.2.9-sty+ct+ap".dedicated + ''; + extraDescription = '' + Ensure that you use a derivation which contains the path `bin/armagetronad-dedicated`. + ''; + }; + + host = mkOption { + type = types.str; + default = "0.0.0.0"; + description = lib.mdDoc "Host to listen on. Used for SERVER_IP."; + }; + + port = mkOption { + type = types.port; + default = 4534; + description = lib.mdDoc "Port to listen on. Used for SERVER_PORT."; + }; + + dns = mkOption { + type = types.nullOr types.str; + default = null; + description = lib.mdDoc "DNS address to use for this server. Optional."; + }; + + openFirewall = mkOption { + type = types.bool; + default = true; + description = lib.mdDoc "Set to true to open the configured UDP port for Armagetron Advanced."; + }; + + name = mkOption { + type = types.str; + description = "The name of this server."; + }; + + settings = mkOption { + type = settingsFormat.type; + default = { }; + description = lib.mdDoc '' + Armagetron Advanced server rules configuration. Refer to: + <https://wiki.armagetronad.org/index.php?title=Console_Commands> + or `armagetronad-dedicated --doc` for a list. + + This attrset is used to populate `settings_custom.cfg`; see: + <https://wiki.armagetronad.org/index.php/Configuration_Files> + ''; + example = literalExpression '' + { + CYCLE_RUBBER = 40; + } + ''; + }; + + roundSettings = mkOption { + type = settingsFormat.type; + default = { }; + description = lib.mdDoc '' + Armagetron Advanced server per-round configuration. Refer to: + <https://wiki.armagetronad.org/index.php?title=Console_Commands> + or `armagetronad-dedicated --doc` for a list. + + This attrset is used to populate `everytime.cfg`; see: + <https://wiki.armagetronad.org/index.php/Configuration_Files> + ''; + example = literalExpression '' + { + SAY = [ + "Hosted on NixOS" + "https://nixos.org" + "iD Tech High Rubber rul3z!! Happy New Year 2008!!1" + ]; + } + ''; + }; + }; + }); + }; + }; + }; + + config = mkIf (enabledServers != { }) { + systemd.tmpfiles.settings = mkMerge (mapAttrsToList + (serverName: serverCfg: + let + serverId = nameToId serverName; + serverRoot = getServerRoot serverName; + serverInfo = ( + { + SERVER_IP = serverCfg.host; + SERVER_PORT = serverCfg.port; + SERVER_NAME = serverCfg.name; + } // (lib.optionalAttrs (serverCfg.dns != null) { SERVER_DNS = serverCfg.dns; }) + ); + customSettings = serverCfg.settings; + everytimeSettings = serverCfg.roundSettings; + + serverInfoCfg = settingsFormat.generate "server_info.${serverName}.cfg" serverInfo; + customSettingsCfg = settingsFormat.generate "settings_custom.${serverName}.cfg" customSettings; + everytimeSettingsCfg = settingsFormat.generate "everytime.${serverName}.cfg" everytimeSettings; + in + { + "10-armagetronad-${serverId}" = { + "${serverRoot}/data" = { + d = { + group = serverId; + user = serverId; + mode = "0750"; + }; + }; + "${serverRoot}/settings" = { + d = { + group = serverId; + user = serverId; + mode = "0750"; + }; + }; + "${serverRoot}/var" = { + d = { + group = serverId; + user = serverId; + mode = "0750"; + }; + }; + "${serverRoot}/resource" = { + d = { + group = serverId; + user = serverId; + mode = "0750"; + }; + }; + "${serverRoot}/input" = { + "f+" = { + group = serverId; + user = serverId; + mode = "0640"; + }; + }; + "${serverRoot}/settings/server_info.cfg" = { + "L+" = { + argument = "${serverInfoCfg}"; + }; + }; + "${serverRoot}/settings/settings_custom.cfg" = { + "L+" = { + argument = "${customSettingsCfg}"; + }; + }; + "${serverRoot}/settings/everytime.cfg" = { + "L+" = { + argument = "${everytimeSettingsCfg}"; + }; + }; + }; + } + ) + enabledServers + ); + + systemd.services = mkMerge (mapAttrsToList + (serverName: serverCfg: + let + serverId = nameToId serverName; + in + { + "armagetronad-${serverName}" = { + description = "Armagetron Advanced Dedicated Server for ${serverName}"; + wants = [ "basic.target" ]; + after = [ "basic.target" "network.target" "multi-user.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = + let + serverRoot = getServerRoot serverName; + in + { + Type = "simple"; + StateDirectory = getStateDirectory serverName; + ExecStart = "${lib.getExe serverCfg.package} --daemon --input ${serverRoot}/input --userdatadir ${serverRoot}/data --userconfigdir ${serverRoot}/settings --vardir ${serverRoot}/var --autoresourcedir ${serverRoot}/resource"; + Restart = "on-failure"; + CapabilityBoundingSet = ""; + LockPersonality = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RestrictNamespaces = true; + RestrictSUIDSGID = true; + User = serverId; + Group = serverId; + }; + }; + }) + enabledServers + ); + + networking.firewall.allowedUDPPorts = + unique (mapAttrsToList (serverName: serverCfg: serverCfg.port) (filterAttrs (serverName: serverCfg: serverCfg.openFirewall) enabledServers)); + + users.users = mkMerge (mapAttrsToList + (serverName: serverCfg: + { + ${nameToId serverName} = { + group = nameToId serverName; + description = "Armagetron Advanced dedicated user for server ${serverName}"; + isSystemUser = true; + }; + }) + enabledServers + ); + + users.groups = mkMerge (mapAttrsToList + (serverName: serverCfg: + { + ${nameToId serverName} = { }; + }) + enabledServers + ); + }; +} diff --git a/nixpkgs/nixos/modules/services/hardware/monado.nix b/nixpkgs/nixos/modules/services/hardware/monado.nix new file mode 100644 index 000000000000..9f9c6c39a0b4 --- /dev/null +++ b/nixpkgs/nixos/modules/services/hardware/monado.nix @@ -0,0 +1,102 @@ +{ config +, lib +, pkgs +, ... +}: +let + inherit (lib) mkDefault mkEnableOption mkIf mkOption mkPackageOption types; + + cfg = config.services.monado; + +in +{ + options.services.monado = { + enable = mkEnableOption "Monado user service"; + + package = mkPackageOption pkgs "monado" { }; + + defaultRuntime = mkOption { + type = types.bool; + description = '' + Whether to enable Monado as the default OpenXR runtime on the system. + + Note that applications can bypass this option by setting an active + runtime in a writable XDG_CONFIG_DIRS location like `~/.config`. + ''; + default = false; + example = true; + }; + + highPriority = mkEnableOption "high priority capability for monado-service" + // mkOption { default = true; }; + }; + + config = mkIf cfg.enable { + security.wrappers."monado-service" = mkIf cfg.highPriority { + setuid = false; + owner = "root"; + group = "root"; + # cap_sys_nice needed for asynchronous reprojection + capabilities = "cap_sys_nice+eip"; + source = lib.getExe' cfg.package "monado-service"; + }; + + services.udev.packages = with pkgs; [ xr-hardware ]; + + systemd.user = { + services.monado = { + description = "Monado XR runtime service module"; + requires = [ "monado.socket" ]; + conflicts = [ "monado-dev.service" ]; + + unitConfig.ConditionUser = "!root"; + + environment = { + # Default options + # https://gitlab.freedesktop.org/monado/monado/-/blob/4548e1738591d0904f8db4df8ede652ece889a76/src/xrt/targets/service/monado.in.service#L12 + XRT_COMPOSITOR_LOG = mkDefault "debug"; + XRT_PRINT_OPTIONS = mkDefault "on"; + IPC_EXIT_ON_DISCONNECT = mkDefault "off"; + }; + + serviceConfig = { + ExecStart = + if cfg.highPriority + then "${config.security.wrapperDir}/monado-service" + else lib.getExe' cfg.package "monado-service"; + Restart = "no"; + }; + + restartTriggers = [ cfg.package ]; + }; + + sockets.monado = { + description = "Monado XR service module connection socket"; + conflicts = [ "monado-dev.service" ]; + + unitConfig.ConditionUser = "!root"; + + socketConfig = { + ListenStream = "%t/monado_comp_ipc"; + RemoveOnStop = true; + + # If Monado crashes while starting up, we want to close incoming OpenXR connections + FlushPending = true; + }; + + restartTriggers = [ cfg.package ]; + + wantedBy = [ "sockets.target" ]; + }; + }; + + environment.systemPackages = [ cfg.package ]; + environment.pathsToLink = [ "/share/openxr" ]; + + environment.etc."xdg/openxr/1/active_runtime.json" = mkIf cfg.defaultRuntime { + source = "${cfg.package}/share/openxr/1/openxr_monado.json"; + }; + }; + + meta.maintainers = with lib.maintainers; [ Scrumplex ]; +} diff --git a/nixpkgs/nixos/modules/services/misc/ollama.nix b/nixpkgs/nixos/modules/services/misc/ollama.nix index d9359d2b5cd4..3ac3beb4de07 100644 --- a/nixpkgs/nixos/modules/services/misc/ollama.nix +++ b/nixpkgs/nixos/modules/services/misc/ollama.nix @@ -1,27 +1,44 @@ -{ config, lib, pkgs, ... }: let +{ config, lib, pkgs, ... }: +let + inherit (lib) types; cfg = config.services.ollama; - -in { - + ollamaPackage = cfg.package.override { + inherit (cfg) acceleration; + linuxPackages = config.boot.kernelPackages // { + nvidia_x11 = config.hardware.nvidia.package; + }; + }; +in +{ options = { services.ollama = { enable = lib.mkEnableOption ( lib.mdDoc "Server for local large language models" ); listenAddress = lib.mkOption { - type = lib.types.str; + type = types.str; default = "127.0.0.1:11434"; description = lib.mdDoc '' Specifies the bind address on which the ollama server HTTP interface listens. ''; }; + acceleration = lib.mkOption { + type = types.nullOr (types.enum [ "rocm" "cuda" ]); + default = null; + example = "rocm"; + description = lib.mdDoc '' + Specifies the interface to use for hardware acceleration. + + - `rocm`: supported by modern AMD GPUs + - `cuda`: supported by modern NVIDIA GPUs + ''; + }; package = lib.mkPackageOption pkgs "ollama" { }; }; }; config = lib.mkIf cfg.enable { - systemd = { services.ollama = { wantedBy = [ "multi-user.target" ]; @@ -33,7 +50,7 @@ in { OLLAMA_HOST = cfg.listenAddress; }; serviceConfig = { - ExecStart = "${lib.getExe cfg.package} serve"; + ExecStart = "${lib.getExe ollamaPackage} serve"; WorkingDirectory = "/var/lib/ollama"; StateDirectory = [ "ollama" ]; DynamicUser = true; @@ -41,10 +58,8 @@ in { }; }; - environment.systemPackages = [ cfg.package ]; - + environment.systemPackages = [ ollamaPackage ]; }; - meta.maintainers = with lib.maintainers; [ onny ]; - + meta.maintainers = with lib.maintainers; [ abysssol onny ]; } diff --git a/nixpkgs/nixos/modules/services/misc/paperless.nix b/nixpkgs/nixos/modules/services/misc/paperless.nix index 1256d8315c8b..ab042e4b6ee2 100644 --- a/nixpkgs/nixos/modules/services/misc/paperless.nix +++ b/nixpkgs/nixos/modules/services/misc/paperless.nix @@ -307,6 +307,9 @@ in Restart = "on-failure"; }; environment = env; + # Allow the consumer to access the private /tmp directory of the server. + # This is required to support consuming files via a local folder. + unitConfig.JoinsNamespaceOf = "paperless-task-queue.service"; }; systemd.services.paperless-web = { diff --git a/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/nut.nix b/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/nut.nix index 1c86b48b4509..e58a394456a3 100644 --- a/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/nut.nix +++ b/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/nut.nix @@ -36,6 +36,17 @@ in provisioned outside of Nix store. ''; }; + nutVariables = mkOption { + type = types.listOf types.str; + default = [ ]; + description = '' + List of NUT variable names to monitor. + + If no variables are set, all numeric variables will be exported automatically. + See the [upstream docs](https://github.com/DRuggeri/nut_exporter?tab=readme-ov-file#variables-and-information) + for more information. + ''; + }; }; serviceOpts = { script = '' @@ -44,7 +55,9 @@ in ${pkgs.prometheus-nut-exporter}/bin/nut_exporter \ --nut.server=${cfg.nutServer} \ --web.listen-address="${cfg.listenAddress}:${toString cfg.port}" \ - ${optionalString (cfg.nutUser != "") "--nut.username=${cfg.nutUser}"} + ${optionalString (cfg.nutUser != "") "--nut.username=${cfg.nutUser}"} \ + ${optionalString (cfg.nutVariables != []) "--nut.vars_enable=${concatStringsSep "," cfg.nutVariables}"} \ + ${concatStringsSep " " cfg.extraFlags} ''; }; } diff --git a/nixpkgs/nixos/modules/services/networking/dhcpcd.nix b/nixpkgs/nixos/modules/services/networking/dhcpcd.nix index 266a7ea1435e..8d5ac02ba88b 100644 --- a/nixpkgs/nixos/modules/services/networking/dhcpcd.nix +++ b/nixpkgs/nixos/modules/services/networking/dhcpcd.nix @@ -13,6 +13,8 @@ let enableDHCP = config.networking.dhcpcd.enable && (config.networking.useDHCP || any (i: i.useDHCP == true) interfaces); + enableNTPService = (config.services.ntp.enable || config.services.ntpd-rs.enable || config.services.openntpd.enable || config.services.chrony.enable); + # Don't start dhcpcd on explicitly configured interfaces or on # interfaces that are part of a bridge, bond or sit device. ignoredInterfaces = @@ -89,20 +91,22 @@ let ${cfg.extraConfig} ''; - exitHook = pkgs.writeText "dhcpcd.exit-hook" - '' + exitHook = pkgs.writeText "dhcpcd.exit-hook" '' + ${optionalString enableNTPService '' if [ "$reason" = BOUND -o "$reason" = REBOOT ]; then - # Restart ntpd. We need to restart it to make sure that it - # will actually do something: if ntpd cannot resolve the - # server hostnames in its config file, then it will never do - # anything ever again ("couldn't resolve ..., giving up on - # it"), so we silently lose time synchronisation. This also - # applies to openntpd. - /run/current-system/systemd/bin/systemctl try-reload-or-restart ntpd.service openntpd.service chronyd.service ntpd-rs.service || true + # Restart ntpd. We need to restart it to make sure that it will actually do something: + # if ntpd cannot resolve the server hostnames in its config file, then it will never do + # anything ever again ("couldn't resolve ..., giving up on it"), so we silently lose + # time synchronisation. This also applies to openntpd. + ${optionalString config.services.ntp.enable "/run/current-system/systemd/bin/systemctl try-reload-or-restart ntpd.service || true"} + ${optionalString config.services.ntpd-rs.enable "/run/current-system/systemd/bin/systemctl try-reload-or-restart ntpd-rs.service || true"} + ${optionalString config.services.openntpd.enable "/run/current-system/systemd/bin/systemctl try-reload-or-restart openntpd.service || true"} + ${optionalString config.services.chrony.enable "/run/current-system/systemd/bin/systemctl try-reload-or-restart chronyd.service || true"} fi + ''} - ${cfg.runHook} - ''; + ${cfg.runHook} + ''; in @@ -232,7 +236,7 @@ in wants = [ "network.target" ]; before = [ "network-online.target" ]; - restartTriggers = [ exitHook ]; + restartTriggers = optional (enableNTPService || cfg.runHook != "") [ exitHook ]; # Stopping dhcpcd during a reconfiguration is undesirable # because it brings down the network interfaces configured by @@ -261,7 +265,9 @@ in environment.systemPackages = [ dhcpcd ]; - environment.etc."dhcpcd.exit-hook".source = exitHook; + environment.etc."dhcpcd.exit-hook" = mkIf (enableNTPService || cfg.runHook != "") { + source = exitHook; + }; powerManagement.resumeCommands = mkIf config.systemd.services.dhcpcd.enable '' diff --git a/nixpkgs/nixos/modules/services/networking/mosquitto.nix b/nixpkgs/nixos/modules/services/networking/mosquitto.nix index ad9eefb42252..4a08f5ed2370 100644 --- a/nixpkgs/nixos/modules/services/networking/mosquitto.nix +++ b/nixpkgs/nixos/modules/services/networking/mosquitto.nix @@ -177,17 +177,6 @@ let '' ++ hashedLines)); - makeACLFile = idx: users: supplement: - pkgs.writeText "mosquitto-acl-${toString idx}.conf" - (concatStringsSep - "\n" - (flatten [ - supplement - (mapAttrsToList - (n: u: [ "user ${n}" ] ++ map (t: "topic ${t}") u.acl) - users) - ])); - authPluginOptions = with types; submodule { options = { plugin = mkOption { @@ -342,7 +331,7 @@ let formatListener = idx: listener: [ "listener ${toString listener.port} ${toString listener.address}" - "acl_file ${makeACLFile idx listener.users listener.acl}" + "acl_file /etc/mosquitto/acl-${toString idx}.conf" ] ++ optional (! listener.omitPasswordAuth) "password_file ${cfg.dataDir}/passwd-${toString idx}" ++ formatFreeform {} listener.settings @@ -698,6 +687,27 @@ in cfg.listeners); }; + environment.etc = listToAttrs ( + imap0 + (idx: listener: { + name = "mosquitto/acl-${toString idx}.conf"; + value = { + user = config.users.users.mosquitto.name; + group = config.users.users.mosquitto.group; + mode = "0400"; + text = (concatStringsSep + "\n" + (flatten [ + listener.acl + (mapAttrsToList + (n: u: [ "user ${n}" ] ++ map (t: "topic ${t}") u.acl) + listener.users) + ])); + }; + }) + cfg.listeners + ); + users.users.mosquitto = { description = "Mosquitto MQTT Broker Daemon owner"; group = "mosquitto"; diff --git a/nixpkgs/nixos/modules/services/networking/searx.nix b/nixpkgs/nixos/modules/services/networking/searx.nix index 938d585e3179..5bbf875f0d57 100644 --- a/nixpkgs/nixos/modules/services/networking/searx.nix +++ b/nixpkgs/nixos/modules/services/networking/searx.nix @@ -213,7 +213,7 @@ in serviceConfig = { User = "searx"; Group = "searx"; - ExecStart = "${cfg.package}/bin/searx-run"; + ExecStart = lib.getExe cfg.package; } // optionalAttrs (cfg.environmentFile != null) { EnvironmentFile = builtins.toPath cfg.environmentFile; }; environment = { diff --git a/nixpkgs/nixos/modules/services/networking/unbound.nix b/nixpkgs/nixos/modules/services/networking/unbound.nix index 616b32f11797..8438e472e11e 100644 --- a/nixpkgs/nixos/modules/services/networking/unbound.nix +++ b/nixpkgs/nixos/modules/services/networking/unbound.nix @@ -24,12 +24,24 @@ let confNoServer = concatStringsSep "\n" ((mapAttrsToList (toConf "") (builtins.removeAttrs cfg.settings [ "server" ])) ++ [""]); confServer = concatStringsSep "\n" (mapAttrsToList (toConf " ") (builtins.removeAttrs cfg.settings.server [ "define-tag" ])); - confFile = pkgs.writeText "unbound.conf" '' + confFileUnchecked = pkgs.writeText "unbound.conf" '' server: ${optionalString (cfg.settings.server.define-tag != "") (toOption " " "define-tag" cfg.settings.server.define-tag)} ${confServer} ${confNoServer} ''; + confFile = if cfg.checkconf then pkgs.runCommandLocal "unbound-checkconf" { } '' + cp ${confFileUnchecked} unbound.conf + + # fake stateDir which is not accesible in the sandbox + mkdir -p $PWD/state + sed -i unbound.conf \ + -e '/auto-trust-anchor-file/d' \ + -e "s|${cfg.stateDir}|$PWD/state|" + ${cfg.package}/bin/unbound-checkconf unbound.conf + + cp ${confFileUnchecked} $out + '' else confFileUnchecked; rootTrustAnchorFile = "${cfg.stateDir}/root.key"; @@ -62,6 +74,17 @@ in { description = lib.mdDoc "Directory holding all state for unbound to run."; }; + checkconf = mkOption { + type = types.bool; + default = !cfg.settings ? include; + defaultText = "!config.services.unbound.settings ? include"; + description = lib.mdDoc '' + Wether to check the resulting config file with unbound checkconf for syntax errors. + + If settings.include is used, then this options is disabled, as the import can likely not be resolved at build time. + ''; + }; + resolveLocalQueries = mkOption { type = types.bool; default = true; diff --git a/nixpkgs/nixos/modules/services/security/kanidm.nix b/nixpkgs/nixos/modules/services/security/kanidm.nix index c659d93b4087..9d074c3027d0 100644 --- a/nixpkgs/nixos/modules/services/security/kanidm.nix +++ b/nixpkgs/nixos/modules/services/security/kanidm.nix @@ -132,6 +132,28 @@ in default = "WriteReplica"; type = lib.types.enum [ "WriteReplica" "WriteReplicaNoUI" "ReadOnlyReplica" ]; }; + online_backup = { + path = lib.mkOption { + description = lib.mdDoc "Path to the output directory for backups."; + type = lib.types.path; + default = "/var/lib/kanidm/backups"; + }; + schedule = lib.mkOption { + description = lib.mdDoc "The schedule for backups in cron format."; + type = lib.types.str; + default = "00 22 * * *"; + }; + versions = lib.mkOption { + description = lib.mdDoc '' + Number of backups to keep. + + The default is set to `0`, in order to disable backups by default. + ''; + type = lib.types.ints.unsigned; + default = 0; + example = 7; + }; + }; }; }; default = { }; @@ -233,6 +255,14 @@ in environment.systemPackages = lib.mkIf cfg.enableClient [ cfg.package ]; + systemd.tmpfiles.settings."10-kanidm" = { + ${cfg.serverSettings.online_backup.path}.d = { + mode = "0700"; + user = "kanidm"; + group = "kanidm"; + }; + }; + systemd.services.kanidm = lib.mkIf cfg.enableServer { description = "kanidm identity management daemon"; wantedBy = [ "multi-user.target" ]; @@ -253,6 +283,8 @@ in BindPaths = [ # To create the socket "/run/kanidmd:/run/kanidmd" + # To store backups + cfg.serverSettings.online_backup.path ]; AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; diff --git a/nixpkgs/nixos/modules/services/web-apps/mealie.nix b/nixpkgs/nixos/modules/services/web-apps/mealie.nix new file mode 100644 index 000000000000..8bb7542c6b56 --- /dev/null +++ b/nixpkgs/nixos/modules/services/web-apps/mealie.nix @@ -0,0 +1,79 @@ +{ config, lib, pkgs, ...}: +let + cfg = config.services.mealie; + pkg = cfg.package; +in +{ + options.services.mealie = { + enable = lib.mkEnableOption "Mealie, a recipe manager and meal planner"; + + package = lib.mkPackageOption pkgs "mealie" { }; + + listenAddress = lib.mkOption { + type = lib.types.str; + default = "0.0.0.0"; + description = "Address on which the service should listen."; + }; + + port = lib.mkOption { + type = lib.types.port; + default = 9000; + description = "Port on which to serve the Mealie service."; + }; + + settings = lib.mkOption { + type = with lib.types; attrsOf anything; + default = {}; + description = lib.mdDoc '' + Configuration of the Mealie service. + + See [the mealie documentation](https://nightly.mealie.io/documentation/getting-started/installation/backend-config/) for available options and default values. + + In addition to the official documentation, you can set {env}`MEALIE_LOG_FILE`. + ''; + example = { + ALLOW_SIGNUP = "false"; + }; + }; + + credentialsFile = lib.mkOption { + type = with lib.types; nullOr path; + default = null; + example = "/run/secrets/mealie-credentials.env"; + description = '' + File containing credentials used in mealie such as {env}`POSTGRES_PASSWORD` + or sensitive LDAP options. + + Expects the format of an `EnvironmentFile=`, as described by {manpage}`systemd.exec(5)`. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.mealie = { + description = "Mealie, a self hosted recipe manager and meal planner"; + + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + + environment = { + PRODUCTION = "true"; + ALEMBIC_CONFIG_FILE="${pkg}/config/alembic.ini"; + API_PORT = toString cfg.port; + DATA_DIR = "/var/lib/mealie"; + CRF_MODEL_PATH = "/var/lib/mealie/model.crfmodel"; + } // (builtins.mapAttrs (_: val: toString val) cfg.settings); + + serviceConfig = { + DynamicUser = true; + User = "mealie"; + ExecStartPre = "${pkg}/libexec/init_db"; + ExecStart = "${lib.getExe pkg} -b ${cfg.listenAddress}:${builtins.toString cfg.port}"; + EnvironmentFile = lib.mkIf (cfg.credentialsFile != null) cfg.credentialsFile; + StateDirectory = "mealie"; + StandardOutput="journal"; + }; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix index 66cb4ee29c0a..ecb8d1e91bde 100644 --- a/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix @@ -18,7 +18,7 @@ in # determines the default: later modules (if enabled) are preferred. # E.g., if Plasma 5 is enabled, it supersedes xterm. imports = [ - ./none.nix ./xterm.nix ./phosh.nix ./xfce.nix ./plasma5.nix ./lumina.nix + ./none.nix ./xterm.nix ./phosh.nix ./xfce.nix ./plasma5.nix ./plasma6.nix ./lumina.nix ./lxqt.nix ./enlightenment.nix ./gnome.nix ./retroarch.nix ./kodi.nix ./mate.nix ./pantheon.nix ./surf-display.nix ./cde.nix ./cinnamon.nix ./budgie.nix ./deepin.nix diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix index 0eb492ce4684..7645b3070369 100644 --- a/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix @@ -362,7 +362,7 @@ in security.pam.services.kde = { allowNullPassword = true; }; - security.pam.services.login.enableKwallet = true; + security.pam.services.login.kwallet.enable = true; systemd.user.services = { plasma-early-setup = mkIf cfg.runUsingSystemd { diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma6.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma6.nix new file mode 100644 index 000000000000..bc246b1af278 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma6.nix @@ -0,0 +1,276 @@ +{ + config, + lib, + pkgs, + utils, + ... +}: let + xcfg = config.services.xserver; + cfg = xcfg.desktopManager.plasma6; + + inherit (pkgs) kdePackages; + inherit (lib) literalExpression mkDefault mkIf mkOption mkPackageOptionMD types; +in { + options = { + services.xserver.desktopManager.plasma6 = { + enable = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Enable the Plasma 6 (KDE 6) desktop environment."; + }; + + enableQt5Integration = mkOption { + type = types.bool; + default = true; + description = lib.mdDoc "Enable Qt 5 integration (theming, etc). Disable for a pure Qt 6 system."; + }; + + notoPackage = mkPackageOptionMD pkgs "Noto fonts - used for UI by default" { + default = ["noto-fonts"]; + example = "noto-fonts-lgc-plus"; + }; + }; + + environment.plasma6.excludePackages = mkOption { + description = lib.mdDoc "List of default packages to exclude from the configuration"; + type = types.listOf types.package; + default = []; + example = literalExpression "[ pkgs.kdePackages.elisa ]"; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + { + assertion = cfg.enable -> !config.services.xserver.desktopManager.plasma5.enable; + message = "Cannot enable plasma5 and plasma6 at the same time!"; + } + ]; + + qt.enable = true; + environment.systemPackages = with kdePackages; let + requiredPackages = [ + # Hack? To make everything run on Wayland + qtwayland + # Needed to render SVG icons + qtsvg + + # Frameworks with globally loadable bits + frameworkintegration # provides Qt plugin + kauth # provides helper service + kcoreaddons # provides extra mime type info + kded # provides helper service + kfilemetadata # provides Qt plugins + kguiaddons # provides geo URL handlers + kiconthemes # provides Qt plugins + kimageformats # provides Qt plugins + kio # provides helper service + a bunch of other stuff + kpackage # provides kpackagetool tool + kservice # provides kbuildsycoca6 tool + kwallet # provides helper service + kwallet-pam # provides helper service + kwalletmanager # provides KCMs and stuff + plasma-activities # provides plasma-activities-cli tool + solid # provides solid-hardware6 tool + phonon-vlc # provides Phonon plugin + + # Core Plasma parts + kwin + pkgs.xwayland + + kscreen + libkscreen + + kscreenlocker + + kactivitymanagerd + kde-cli-tools + kglobalacceld + kwrited # wall message proxy, not to be confused with kwrite + + milou + polkit-kde-agent-1 + + plasma-desktop + plasma-workspace + + # Crash handler + drkonqi + + # Application integration + libplasma # provides Kirigami platform theme + plasma-integration # provides Qt platform theme + kde-gtk-config + + # Artwork + themes + breeze + breeze-icons + breeze-gtk + ocean-sound-theme + plasma-workspace-wallpapers + pkgs.hicolor-icon-theme # fallback icons + qqc2-breeze-style + qqc2-desktop-style + + # misc Plasma extras + kdeplasma-addons + + pkgs.xdg-user-dirs # recommended upstream + + # Plasma utilities + kmenuedit + + kinfocenter + plasma-systemmonitor + ksystemstats + libksysguard + + spectacle + systemsettings + + # Gear + baloo + dolphin + dolphin-plugins + ffmpegthumbs + kdegraphics-thumbnailers + kde-inotify-survey + kio-admin + kio-extras + kio-fuse + ]; + optionalPackages = [ + plasma-browser-integration + konsole + (lib.getBin qttools) # Expose qdbus in PATH + + ark + elisa + gwenview + okular + kate + khelpcenter + print-manager + ]; + in + requiredPackages + ++ utils.removePackagesByName optionalPackages config.environment.plasma6.excludePackages + ++ lib.optionals config.services.xserver.desktopManager.plasma6.enableQt5Integration [ + breeze.qt5 + plasma-integration.qt5 + pkgs.plasma5Packages.kwayland-integration + kio-extras-kf5 + ] + # Optional hardware support features + ++ lib.optionals config.hardware.bluetooth.enable [bluedevil bluez-qt pkgs.openobex pkgs.obexftp] + ++ lib.optional config.networking.networkmanager.enable plasma-nm + ++ lib.optional config.hardware.pulseaudio.enable plasma-pa + ++ lib.optional config.services.pipewire.pulse.enable plasma-pa + ++ lib.optional config.powerManagement.enable powerdevil + ++ lib.optional config.services.colord.enable colord-kde + ++ lib.optional config.services.hardware.bolt.enable plasma-thunderbolt + ++ lib.optionals config.services.samba.enable [kdenetwork-filesharing pkgs.samba] + ++ lib.optional config.services.xserver.wacom.enable wacomtablet + ++ lib.optional config.services.flatpak.enable flatpak-kcm; + + environment.pathsToLink = [ + # FIXME: modules should link subdirs of `/share` rather than relying on this + "/share" + "/libexec" # for drkonqi + ]; + + environment.etc."X11/xkb".source = xcfg.xkb.dir; + + # Add ~/.config/kdedefaults to XDG_CONFIG_DIRS for shells, since Plasma sets that. + # FIXME: maybe we should append to XDG_CONFIG_DIRS in /etc/set-environment instead? + environment.sessionVariables.XDG_CONFIG_DIRS = ["$HOME/.config/kdedefaults"]; + + # Needed for things that depend on other store.kde.org packages to install correctly, + # notably Plasma look-and-feel packages (a.k.a. Global Themes) + # + # FIXME: this is annoyingly impure and should really be fixed at source level somehow, + # but kpackage is a library so we can't just wrap the one thing invoking it and be done. + # This also means things won't work for people not on Plasma, but at least this way it + # works for SOME people. + environment.sessionVariables.KPACKAGE_DEP_RESOLVERS_PATH = "${kdePackages.frameworkintegration.out}/libexec/kf6/kpackagehandlers"; + + # Enable GTK applications to load SVG icons + services.xserver.gdk-pixbuf.modulePackages = [pkgs.librsvg]; + + fonts.packages = [cfg.notoPackage pkgs.hack-font]; + fonts.fontconfig.defaultFonts = { + monospace = ["Hack" "Noto Sans Mono"]; + sansSerif = ["Noto Sans"]; + serif = ["Noto Serif"]; + }; + + programs.ssh.askPassword = mkDefault "${kdePackages.ksshaskpass.out}/bin/ksshaskpass"; + + # Enable helpful DBus services. + services.accounts-daemon.enable = true; + # when changing an account picture the accounts-daemon reads a temporary file containing the image which systemsettings5 may place under /tmp + systemd.services.accounts-daemon.serviceConfig.PrivateTmp = false; + + services.power-profiles-daemon.enable = mkDefault true; + services.system-config-printer.enable = mkIf config.services.printing.enable (mkDefault true); + services.udisks2.enable = true; + services.upower.enable = config.powerManagement.enable; + services.xserver.libinput.enable = mkDefault true; + + # Extra UDEV rules used by Solid + services.udev.packages = [ + # libmtp has "bin", "dev", "out" outputs. UDEV rules file is in "out". + pkgs.libmtp.out + pkgs.media-player-info + ]; + + # Set up Dr. Konqi as crash handler + systemd.packages = [kdePackages.drkonqi]; + systemd.services."drkonqi-coredump-processor@".wantedBy = ["systemd-coredump@.service"]; + + xdg.portal.enable = true; + xdg.portal.extraPortals = [kdePackages.xdg-desktop-portal-kde]; + xdg.portal.configPackages = mkDefault [kdePackages.xdg-desktop-portal-kde]; + services.pipewire.enable = mkDefault true; + + services.xserver.displayManager = { + sessionPackages = [kdePackages.plasma-workspace]; + defaultSession = mkDefault "plasma"; + }; + services.xserver.displayManager.sddm = { + package = kdePackages.sddm; + theme = mkDefault "breeze"; + extraPackages = with kdePackages; [ + breeze-icons + kirigami + plasma5support + qtsvg + qtvirtualkeyboard + ]; + }; + + security.pam.services = { + login.kwallet = { + enable = true; + package = kdePackages.kwallet-pam; + }; + kde.kwallet = { + enable = true; + package = kdePackages.kwallet-pam; + }; + kde-fingerprint = lib.mkIf config.services.fprintd.enable { fprintAuth = true; }; + kde-smartcard = lib.mkIf config.security.pam.p11.enable { p11Auth = true; }; + }; + + programs.dconf.enable = true; + + programs.firefox.nativeMessagingHosts.packages = [kdePackages.plasma-browser-integration]; + + programs.chromium = { + enablePlasmaBrowserIntegration = true; + plasmaBrowserIntegrationPackage = pkgs.kdePackages.plasma-browser-integration; + }; + + programs.kdeconnect.package = kdePackages.kdeconnect-kde; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/sddm.nix b/nixpkgs/nixos/modules/services/x11/display-managers/sddm.nix index 0576619cc8d2..5b7f4bc58d80 100644 --- a/nixpkgs/nixos/modules/services/x11/display-managers/sddm.nix +++ b/nixpkgs/nixos/modules/services/x11/display-managers/sddm.nix @@ -7,7 +7,10 @@ let cfg = dmcfg.sddm; xEnv = config.systemd.services.display-manager.environment; - sddm = cfg.package; + sddm = cfg.package.override(old: { + withWayland = cfg.wayland.enable; + extraPackages = old.extraPackages or [] ++ cfg.extraPackages; + }); iniFmt = pkgs.formats.ini { }; @@ -140,6 +143,15 @@ in ''; }; + extraPackages = mkOption { + type = types.listOf types.package; + default = []; + defaultText = "[]"; + description = lib.mdDoc '' + Extra Qt plugins / QML libraries to add to the environment. + ''; + }; + autoNumlock = mkOption { type = types.bool; default = false; @@ -211,7 +223,7 @@ in keymap_variant = xcfg.xkb.variant; keymap_options = xcfg.xkb.options; }; - }; in "${pkgs.weston}/bin/weston --shell=fullscreen-shell.so -c ${westonIni}"; + }; in "${pkgs.weston}/bin/weston --shell=kiosk -c ${westonIni}"; description = lib.mdDoc "Command used to start the selected compositor"; }; }; @@ -235,15 +247,7 @@ in } ]; - services.xserver.displayManager.job = { - environment = { - # Load themes from system environment - QT_PLUGIN_PATH = "/run/current-system/sw/" + pkgs.qt5.qtbase.qtPluginPrefix; - QML2_IMPORT_PATH = "/run/current-system/sw/" + pkgs.qt5.qtbase.qtQmlPrefix; - }; - - execCmd = "exec /run/current-system/sw/bin/sddm"; - }; + services.xserver.displayManager.job.execCmd = "exec /run/current-system/sw/bin/sddm"; security.pam.services = { sddm.text = '' diff --git a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py index a9978d7adf80..258cf622a894 100644 --- a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py +++ b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py @@ -17,6 +17,9 @@ from dataclasses import dataclass # These values will be replaced with actual values during the package build EFI_SYS_MOUNT_POINT = "@efiSysMountPoint@" +BOOT_MOUNT_POINT = "@bootMountPoint@" +LOADER_CONF = f"{EFI_SYS_MOUNT_POINT}/loader/loader.conf" # Always stored on the ESP +NIXOS_DIR = "@nixosDir@" TIMEOUT = "@timeout@" EDITOR = "@editor@" == "1" CONSOLE_MODE = "@consoleMode@" @@ -28,6 +31,7 @@ CONFIGURATION_LIMIT = int("@configurationLimit@") CAN_TOUCH_EFI_VARIABLES = "@canTouchEfiVariables@" GRACEFUL = "@graceful@" COPY_EXTRA_FILES = "@copyExtraFiles@" +CHECK_MOUNTPOINTS = "@checkMountpoints@" @dataclass class BootSpec: @@ -87,7 +91,7 @@ def generation_conf_filename(profile: str | None, generation: int, specialisatio def write_loader_conf(profile: str | None, generation: int, specialisation: str | None) -> None: - with open(f"{EFI_SYS_MOUNT_POINT}/loader/loader.conf.tmp", 'w') as f: + with open(f"{LOADER_CONF}.tmp", 'w') as f: if TIMEOUT != "": f.write(f"timeout {TIMEOUT}\n") f.write("default %s\n" % generation_conf_filename(profile, generation, specialisation)) @@ -96,7 +100,7 @@ def write_loader_conf(profile: str | None, generation: int, specialisation: str f.write(f"console-mode {CONSOLE_MODE}\n") f.flush() os.fsync(f.fileno()) - os.rename(f"{EFI_SYS_MOUNT_POINT}/loader/loader.conf.tmp", f"{EFI_SYS_MOUNT_POINT}/loader/loader.conf") + os.rename(f"{LOADER_CONF}.tmp", LOADER_CONF) def get_bootspec(profile: str | None, generation: int) -> BootSpec: @@ -126,9 +130,9 @@ def copy_from_file(file: str, dry_run: bool = False) -> str: store_file_path = os.path.realpath(file) suffix = os.path.basename(store_file_path) store_dir = os.path.basename(os.path.dirname(store_file_path)) - efi_file_path = "/efi/nixos/%s-%s.efi" % (store_dir, suffix) + efi_file_path = f"{NIXOS_DIR}/{store_dir}-{suffix}.efi" if not dry_run: - copy_if_not_exists(store_file_path, f"{EFI_SYS_MOUNT_POINT}%s" % (efi_file_path)) + copy_if_not_exists(store_file_path, f"{BOOT_MOUNT_POINT}{efi_file_path}") return efi_file_path def write_entry(profile: str | None, generation: int, specialisation: str | None, @@ -145,7 +149,7 @@ def write_entry(profile: str | None, generation: int, specialisation: str | None try: if bootspec.initrdSecrets is not None: - subprocess.check_call([bootspec.initrdSecrets, f"{EFI_SYS_MOUNT_POINT}%s" % (initrd)]) + subprocess.check_call([bootspec.initrdSecrets, f"{BOOT_MOUNT_POINT}%s" % (initrd)]) except subprocess.CalledProcessError: if current: print("failed to create initrd secrets!", file=sys.stderr) @@ -155,7 +159,7 @@ def write_entry(profile: str | None, generation: int, specialisation: str | None f'for "{title} - Configuration {generation}", an older generation', file=sys.stderr) print("note: this is normal after having removed " "or renamed a file in `boot.initrd.secrets`", file=sys.stderr) - entry_file = f"{EFI_SYS_MOUNT_POINT}/loader/entries/%s" % ( + entry_file = f"{BOOT_MOUNT_POINT}/loader/entries/%s" % ( generation_conf_filename(profile, generation, specialisation)) tmp_path = "%s.tmp" % (entry_file) kernel_params = "init=%s " % bootspec.init @@ -202,14 +206,14 @@ def get_generations(profile: str | None = None) -> list[SystemIdentifier]: def remove_old_entries(gens: list[SystemIdentifier]) -> None: - rex_profile = re.compile(r"^" + re.escape(EFI_SYS_MOUNT_POINT) + "/loader/entries/nixos-(.*)-generation-.*\.conf$") - rex_generation = re.compile(r"^" + re.escape(EFI_SYS_MOUNT_POINT) + "/loader/entries/nixos.*-generation-([0-9]+)(-specialisation-.*)?\.conf$") + rex_profile = re.compile(r"^" + re.escape(BOOT_MOUNT_POINT) + "/loader/entries/nixos-(.*)-generation-.*\.conf$") + rex_generation = re.compile(r"^" + re.escape(BOOT_MOUNT_POINT) + "/loader/entries/nixos.*-generation-([0-9]+)(-specialisation-.*)?\.conf$") known_paths = [] for gen in gens: bootspec = get_bootspec(gen.profile, gen.generation) known_paths.append(copy_from_file(bootspec.kernel, True)) known_paths.append(copy_from_file(bootspec.initrd, True)) - for path in glob.iglob(f"{EFI_SYS_MOUNT_POINT}/loader/entries/nixos*-generation-[1-9]*.conf"): + for path in glob.iglob(f"{BOOT_MOUNT_POINT}/loader/entries/nixos*-generation-[1-9]*.conf"): if rex_profile.match(path): prof = rex_profile.sub(r"\1", path) else: @@ -220,11 +224,18 @@ def remove_old_entries(gens: list[SystemIdentifier]) -> None: continue if not (prof, gen_number, None) in gens: os.unlink(path) - for path in glob.iglob(f"{EFI_SYS_MOUNT_POINT}/efi/nixos/*"): + for path in glob.iglob(f"{BOOT_MOUNT_POINT}/{NIXOS_DIR}/*"): if not path in known_paths and not os.path.isdir(path): os.unlink(path) +def cleanup_esp() -> None: + for path in glob.iglob(f"{EFI_SYS_MOUNT_POINT}/loader/entries/nixos*"): + os.unlink(path) + if os.path.isdir(f"{EFI_SYS_MOUNT_POINT}/{NIXOS_DIR}"): + shutil.rmtree(f"{EFI_SYS_MOUNT_POINT}/{NIXOS_DIR}") + + def get_profiles() -> list[str]: if os.path.isdir("/nix/var/nix/profiles/system-profiles/"): return [x @@ -255,6 +266,9 @@ def install_bootloader(args: argparse.Namespace) -> None: # flags to pass to bootctl install/update bootctl_flags = [] + if BOOT_MOUNT_POINT != EFI_SYS_MOUNT_POINT: + bootctl_flags.append(f"--boot-path={BOOT_MOUNT_POINT}") + if CAN_TOUCH_EFI_VARIABLES != "1": bootctl_flags.append("--no-variables") @@ -263,8 +277,8 @@ def install_bootloader(args: argparse.Namespace) -> None: if os.getenv("NIXOS_INSTALL_BOOTLOADER") == "1": # bootctl uses fopen() with modes "wxe" and fails if the file exists. - if os.path.exists(f"{EFI_SYS_MOUNT_POINT}/loader/loader.conf"): - os.unlink(f"{EFI_SYS_MOUNT_POINT}/loader/loader.conf") + if os.path.exists(LOADER_CONF): + os.unlink(LOADER_CONF) subprocess.check_call([f"{SYSTEMD}/bin/bootctl", f"--esp-path={EFI_SYS_MOUNT_POINT}"] + bootctl_flags + ["install"]) else: @@ -291,13 +305,15 @@ def install_bootloader(args: argparse.Namespace) -> None: print("updating systemd-boot from %s to %s" % (installed_version, available_version)) subprocess.check_call([f"{SYSTEMD}/bin/bootctl", f"--esp-path={EFI_SYS_MOUNT_POINT}"] + bootctl_flags + ["update"]) - os.makedirs(f"{EFI_SYS_MOUNT_POINT}/efi/nixos", exist_ok=True) - os.makedirs(f"{EFI_SYS_MOUNT_POINT}/loader/entries", exist_ok=True) + os.makedirs(f"{BOOT_MOUNT_POINT}/{NIXOS_DIR}", exist_ok=True) + os.makedirs(f"{BOOT_MOUNT_POINT}/loader/entries", exist_ok=True) gens = get_generations() for profile in get_profiles(): gens += get_generations(profile) + remove_old_entries(gens) + for gen in gens: try: bootspec = get_bootspec(gen.profile, gen.generation) @@ -315,9 +331,15 @@ def install_bootloader(args: argparse.Namespace) -> None: else: raise e - for root, _, files in os.walk(f"{EFI_SYS_MOUNT_POINT}/efi/nixos/.extra-files", topdown=False): - relative_root = root.removeprefix(f"{EFI_SYS_MOUNT_POINT}/efi/nixos/.extra-files").removeprefix("/") - actual_root = os.path.join(f"{EFI_SYS_MOUNT_POINT}", relative_root) + if BOOT_MOUNT_POINT != EFI_SYS_MOUNT_POINT: + # Cleanup any entries in ESP if xbootldrMountPoint is set. + # If the user later unsets xbootldrMountPoint, entries in XBOOTLDR will not be cleaned up + # automatically, as we don't have information about the mount point anymore. + cleanup_esp() + + for root, _, files in os.walk(f"{BOOT_MOUNT_POINT}/{NIXOS_DIR}/.extra-files", topdown=False): + relative_root = root.removeprefix(f"{BOOT_MOUNT_POINT}/{NIXOS_DIR}/.extra-files").removeprefix("/") + actual_root = os.path.join(f"{BOOT_MOUNT_POINT}", relative_root) for file in files: actual_file = os.path.join(actual_root, file) @@ -330,7 +352,7 @@ def install_bootloader(args: argparse.Namespace) -> None: os.rmdir(actual_root) os.rmdir(root) - os.makedirs(f"{EFI_SYS_MOUNT_POINT}/efi/nixos/.extra-files", exist_ok=True) + os.makedirs(f"{BOOT_MOUNT_POINT}/{NIXOS_DIR}/.extra-files", exist_ok=True) subprocess.check_call(COPY_EXTRA_FILES) @@ -340,6 +362,8 @@ def main() -> None: parser.add_argument('default_config', metavar='DEFAULT-CONFIG', help=f"The default {DISTRO_NAME} config to boot") args = parser.parse_args() + subprocess.check_call(CHECK_MOUNTPOINTS) + try: install_bootloader(args) finally: @@ -347,9 +371,14 @@ def main() -> None: # it can leave the system in an unbootable state, when a crash/outage # happens shortly after an update. To decrease the likelihood of this # event sync the efi filesystem after each update. - rc = libc.syncfs(os.open(f"{EFI_SYS_MOUNT_POINT}", os.O_RDONLY)) + rc = libc.syncfs(os.open(f"{BOOT_MOUNT_POINT}", os.O_RDONLY)) if rc != 0: - print(f"could not sync {EFI_SYS_MOUNT_POINT}: {os.strerror(rc)}", file=sys.stderr) + print(f"could not sync {BOOT_MOUNT_POINT}: {os.strerror(rc)}", file=sys.stderr) + + if BOOT_MOUNT_POINT != EFI_SYS_MOUNT_POINT: + rc = libc.syncfs(os.open(EFI_SYS_MOUNT_POINT, os.O_RDONLY)) + if rc != 0: + print(f"could not sync {EFI_SYS_MOUNT_POINT}: {os.strerror(rc)}", file=sys.stderr) if __name__ == '__main__': 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 ea4553b8208f..645b764760da 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 @@ -7,7 +7,7 @@ let efi = config.boot.loader.efi; - systemdBootBuilder = pkgs.substituteAll { + systemdBootBuilder = pkgs.substituteAll rec { src = ./systemd-boot-builder.py; isExecutable = true; @@ -28,33 +28,48 @@ let inherit (efi) efiSysMountPoint canTouchEfiVariables; + bootMountPoint = if cfg.xbootldrMountPoint != null + then cfg.xbootldrMountPoint + else efi.efiSysMountPoint; + + nixosDir = "/EFI/nixos"; + inherit (config.system.nixos) distroName; memtest86 = optionalString cfg.memtest86.enable pkgs.memtest86plus; netbootxyz = optionalString cfg.netbootxyz.enable pkgs.netbootxyz-efi; + checkMountpoints = pkgs.writeShellScript "check-mountpoints" '' + fail() { + echo "$1 = '$2' is not a mounted partition. Is the path configured correctly?" >&2 + exit 1 + } + ${pkgs.util-linuxMinimal}/bin/findmnt ${efiSysMountPoint} > /dev/null || fail efiSysMountPoint ${efiSysMountPoint} + ${lib.optionalString + (cfg.xbootldrMountPoint != null) + "${pkgs.util-linuxMinimal}/bin/findmnt ${cfg.xbootldrMountPoint} > /dev/null || fail xbootldrMountPoint ${cfg.xbootldrMountPoint}"} + ''; + copyExtraFiles = pkgs.writeShellScript "copy-extra-files" '' empty_file=$(${pkgs.coreutils}/bin/mktemp) ${concatStrings (mapAttrsToList (n: v: '' - ${pkgs.coreutils}/bin/install -Dp "${v}" "${efi.efiSysMountPoint}/"${escapeShellArg n} - ${pkgs.coreutils}/bin/install -D $empty_file "${efi.efiSysMountPoint}/efi/nixos/.extra-files/"${escapeShellArg n} + ${pkgs.coreutils}/bin/install -Dp "${v}" "${bootMountPoint}/"${escapeShellArg n} + ${pkgs.coreutils}/bin/install -D $empty_file "${bootMountPoint}/${nixosDir}/.extra-files/"${escapeShellArg n} '') cfg.extraFiles)} ${concatStrings (mapAttrsToList (n: v: '' - ${pkgs.coreutils}/bin/install -Dp "${pkgs.writeText n v}" "${efi.efiSysMountPoint}/loader/entries/"${escapeShellArg n} - ${pkgs.coreutils}/bin/install -D $empty_file "${efi.efiSysMountPoint}/efi/nixos/.extra-files/loader/entries/"${escapeShellArg n} + ${pkgs.coreutils}/bin/install -Dp "${pkgs.writeText n v}" "${bootMountPoint}/loader/entries/"${escapeShellArg n} + ${pkgs.coreutils}/bin/install -D $empty_file "${bootMountPoint}/${nixosDir}/.extra-files/loader/entries/"${escapeShellArg n} '') cfg.extraEntries)} ''; }; - checkedSystemdBootBuilder = pkgs.runCommand "systemd-boot" { - nativeBuildInputs = [ pkgs.mypy ]; - } '' + checkedSystemdBootBuilder = pkgs.runCommand "systemd-boot" { } '' mkdir -p $out/bin install -m755 ${systemdBootBuilder} $out/bin/systemd-boot-builder - mypy \ + ${lib.getExe pkgs.buildPackages.mypy} \ --no-implicit-optional \ --disallow-untyped-calls \ --disallow-untyped-defs \ @@ -101,6 +116,18 @@ in { ''; }; + xbootldrMountPoint = mkOption { + default = null; + type = types.nullOr types.str; + description = lib.mdDoc '' + Where the XBOOTLDR partition is mounted. + + If set, this partition will be used as $BOOT to store boot loader entries and extra files + instead of the EFI partition. As per the bootloader specification, it is recommended that + the EFI and XBOOTLDR partitions be mounted at `/efi` and `/boot`, respectively. + ''; + }; + configurationLimit = mkOption { default = null; example = 120; @@ -110,7 +137,7 @@ in { Useful to prevent boot partition running out of disk space. `null` means no limit i.e. all generations - that were not garbage collected yet. + that have not been garbage collected yet. ''; }; @@ -202,7 +229,7 @@ in { ''; description = lib.mdDoc '' Any additional entries you want added to the `systemd-boot` menu. - These entries will be copied to {file}`/boot/loader/entries`. + These entries will be copied to {file}`$BOOT/loader/entries`. Each attribute name denotes the destination file name, and the corresponding attribute value is the contents of the entry. @@ -219,9 +246,9 @@ in { { "efi/memtest86/memtest.efi" = "''${pkgs.memtest86plus}/memtest.efi"; } ''; description = lib.mdDoc '' - A set of files to be copied to {file}`/boot`. + A set of files to be copied to {file}`$BOOT`. Each attribute name denotes the destination file name in - {file}`/boot`, while the corresponding + {file}`$BOOT`, while the corresponding attribute value specifies the source file. ''; }; @@ -246,6 +273,18 @@ in { config = mkIf cfg.enable { assertions = [ { + assertion = (hasPrefix "/" efi.efiSysMountPoint); + message = "The ESP mount point '${efi.efiSysMountPoint}' must be an absolute path"; + } + { + assertion = cfg.xbootldrMountPoint == null || (hasPrefix "/" cfg.xbootldrMountPoint); + message = "The XBOOTLDR mount point '${cfg.xbootldrMountPoint}' must be an absolute path"; + } + { + assertion = cfg.xbootldrMountPoint != efi.efiSysMountPoint; + message = "The XBOOTLDR mount point '${cfg.xbootldrMountPoint}' cannot be the same as the ESP mount point '${efi.efiSysMountPoint}'"; + } + { assertion = (config.boot.kernelPackages.kernel.features or { efiBootStub = true; }) ? efiBootStub; message = "This kernel does not support the EFI boot stub"; } diff --git a/nixpkgs/nixos/modules/system/boot/networkd.nix b/nixpkgs/nixos/modules/system/boot/networkd.nix index a7399bd55e77..88d6a2ded873 100644 --- a/nixpkgs/nixos/modules/system/boot/networkd.nix +++ b/nixpkgs/nixos/modules/system/boot/networkd.nix @@ -647,9 +647,9 @@ let "BatmanAdvanced" ]) # Note: For DHCP the values both, none, v4, v6 are deprecated - (assertValueOneOf "DHCP" ["yes" "no" "ipv4" "ipv6"]) + (assertValueOneOf "DHCP" (boolValues ++ ["ipv4" "ipv6"])) (assertValueOneOf "DHCPServer" boolValues) - (assertValueOneOf "LinkLocalAddressing" ["yes" "no" "ipv4" "ipv6" "fallback" "ipv4-fallback"]) + (assertValueOneOf "LinkLocalAddressing" (boolValues ++ ["ipv4" "ipv6" "fallback" "ipv4-fallback"])) (assertValueOneOf "IPv6LinkLocalAddressGenerationMode" ["eui64" "none" "stable-privacy" "random"]) (assertValueOneOf "IPv4LLRoute" boolValues) (assertValueOneOf "DefaultRouteOnDevice" boolValues) diff --git a/nixpkgs/nixos/modules/system/boot/plymouth.nix b/nixpkgs/nixos/modules/system/boot/plymouth.nix index b041b8951fa3..16bca40993ae 100644 --- a/nixpkgs/nixos/modules/system/boot/plymouth.nix +++ b/nixpkgs/nixos/modules/system/boot/plymouth.nix @@ -186,6 +186,8 @@ in # module might come from a theme cp ${themesEnv}/lib/plymouth/*.so $out cp ${plymouth}/lib/plymouth/renderers/*.so $out/renderers + # useless in the initrd, and adds several megabytes to the closure + rm $out/renderers/x11.so ''; "/etc/plymouth/themes".source = pkgs.runCommand "plymouth-initrd-themes" {} '' # Check if the actual requested theme is here @@ -271,6 +273,8 @@ in # module might come from a theme cp ${themesEnv}/lib/plymouth/*.so $out/lib/plymouth cp ${plymouth}/lib/plymouth/renderers/*.so $out/lib/plymouth/renderers + # useless in the initrd, and adds several megabytes to the closure + rm $out/lib/plymouth/renderers/x11.so mkdir -p $out/share/plymouth/themes cp ${plymouth}/share/plymouth/plymouthd.defaults $out/share/plymouth diff --git a/nixpkgs/nixos/modules/system/boot/systemd/coredump.nix b/nixpkgs/nixos/modules/system/boot/systemd/coredump.nix index 03ef00e5683c..271d8f86d0e6 100644 --- a/nixpkgs/nixos/modules/system/boot/systemd/coredump.nix +++ b/nixpkgs/nixos/modules/system/boot/systemd/coredump.nix @@ -52,7 +52,7 @@ in { # See: https://github.com/NixOS/nixpkgs/issues/213408 pkgs.substitute { src = "${systemd}/example/sysctl.d/50-coredump.conf"; - replacements = [ + substitutions = [ "--replace" "${systemd}" "${pkgs.symlinkJoin { name = "systemd"; paths = [ systemd ]; }}" diff --git a/nixpkgs/nixos/modules/system/boot/systemd/repart.nix b/nixpkgs/nixos/modules/system/boot/systemd/repart.nix index 3be744acd0b3..6cc387cb6f43 100644 --- a/nixpkgs/nixos/modules/system/boot/systemd/repart.nix +++ b/nixpkgs/nixos/modules/system/boot/systemd/repart.nix @@ -10,6 +10,20 @@ let "repart.d" format (lib.mapAttrs (_n: v: { Partition = v; }) cfg.partitions); + + partitionAssertions = lib.mapAttrsToList (fileName: definition: + let + maxLabelLength = 36; # GPT_LABEL_MAX defined in systemd's gpt.h + labelLength = builtins.stringLength definition.Label; + in + { + assertion = definition ? Label -> maxLabelLength >= labelLength; + message = '' + The partition label '${definition.Label}' defined for '${fileName}' is ${toString labelLength} + characters long, but the maximum label length supported by systemd is ${toString maxLabelLength}. + ''; + } + ) cfg.partitions; in { options = { @@ -81,7 +95,7 @@ in 'boot.initrd.systemd.repart.enable' requires 'boot.initrd.systemd.enable' to be enabled. ''; } - ]; + ] ++ partitionAssertions; # systemd-repart uses loopback devices for partition creation boot.initrd.availableKernelModules = lib.optional initrdCfg.enable "loop"; diff --git a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix index 98df6a40e8a1..58aca3fdbd4f 100644 --- a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix @@ -347,24 +347,12 @@ in removeLinuxDRM = lib.mkOption { type = types.bool; default = false; - description = lib.mdDoc '' - Linux 6.2 dropped some kernel symbols required on aarch64 required by zfs. - Enabling this option will bring them back to allow this kernel version. - Note that in some jurisdictions this may be illegal as it might be considered - removing copyright protection from the code. - See https://www.ifross.org/?q=en/artikel/ongoing-dispute-over-value-exportsymbolgpl-function for further information. - - If configure your kernel package with `zfs.latestCompatibleLinuxPackages`, you will need to also pass removeLinuxDRM to that package like this: + description = '' + Patch the kernel to change symbols needed by ZFS from + EXPORT_SYMBOL_GPL to EXPORT_SYMBOL. - ``` - { pkgs, ... }: { - boot.kernelPackages = (pkgs.zfs.override { - removeLinuxDRM = pkgs.hostPlatform.isAarch64; - }).latestCompatibleLinuxPackages; - - boot.zfs.removeLinuxDRM = true; - } - ``` + Currently has no effect, but may again in future if a kernel + update breaks ZFS due to symbols being newly changed to GPL. ''; }; }; @@ -588,7 +576,7 @@ in kernelParams = lib.optionals (!config.boot.zfs.allowHibernation) [ "nohibernate" ]; extraModulePackages = [ - (cfgZfs.modulePackage.override { inherit (cfgZfs) removeLinuxDRM; }) + cfgZfs.modulePackage ]; }; @@ -725,21 +713,6 @@ in services.udev.packages = [ cfgZfs.package ]; # to hook zvol naming, etc. systemd.packages = [ cfgZfs.package ]; - # Export kernel_neon_* symbols again. - # This change is necessary until ZFS figures out a solution - # with upstream or in their build system to fill the gap for - # this symbol. - # In the meantime, we restore what was once a working piece of code - # in the kernel. - boot.kernelPatches = lib.optional (cfgZfs.removeLinuxDRM && pkgs.stdenv.hostPlatform.system == "aarch64-linux") { - name = "export-neon-symbols-as-gpl"; - patch = pkgs.fetchpatch { - url = "https://github.com/torvalds/linux/commit/aaeca98456431a8d9382ecf48ac4843e252c07b3.patch"; - hash = "sha256-L2g4G1tlWPIi/QRckMuHDcdWBcKpObSWSRTvbHRIwIk="; - revert = true; - }; - }; - systemd.services = let createImportService' = pool: createImportService { inherit pool; diff --git a/nixpkgs/nixos/modules/virtualisation/podman/default.nix b/nixpkgs/nixos/modules/virtualisation/podman/default.nix index 5a99dc8a1bb9..a97739054216 100644 --- a/nixpkgs/nixos/modules/virtualisation/podman/default.nix +++ b/nixpkgs/nixos/modules/virtualisation/podman/default.nix @@ -216,9 +216,11 @@ in requires = [ "podman.service" ]; }; + systemd.services.podman.environment = config.networking.proxy.envVars; systemd.sockets.podman.wantedBy = [ "sockets.target" ]; systemd.sockets.podman.socketConfig.SocketGroup = "podman"; + systemd.user.services.podman.environment = config.networking.proxy.envVars; systemd.user.sockets.podman.wantedBy = [ "sockets.target" ]; systemd.timers.podman-prune.timerConfig = lib.mkIf cfg.autoPrune.enable { |