diff options
Diffstat (limited to 'nixpkgs/nixos/modules/services/misc')
22 files changed, 837 insertions, 219 deletions
diff --git a/nixpkgs/nixos/modules/services/misc/amazon-ssm-agent.nix b/nixpkgs/nixos/modules/services/misc/amazon-ssm-agent.nix index 9ab4a7f96d08..0da10621d0a0 100644 --- a/nixpkgs/nixos/modules/services/misc/amazon-ssm-agent.nix +++ b/nixpkgs/nixos/modules/services/misc/amazon-ssm-agent.nix @@ -28,13 +28,7 @@ in { options.services.amazon-ssm-agent = { enable = mkEnableOption "Amazon SSM agent"; - - package = mkOption { - type = types.path; - description = "The Amazon SSM agent package to use"; - default = pkgs.amazon-ssm-agent.override { overrideEtc = false; }; - defaultText = literalExpression "pkgs.amazon-ssm-agent.override { overrideEtc = false; }"; - }; + package = mkPackageOption pkgs "amazon-ssm-agent" {}; }; config = mkIf cfg.enable { diff --git a/nixpkgs/nixos/modules/services/misc/anki-sync-server.md b/nixpkgs/nixos/modules/services/misc/anki-sync-server.md index f58d3d8ad0da..5482a4aa0e5f 100644 --- a/nixpkgs/nixos/modules/services/misc/anki-sync-server.md +++ b/nixpkgs/nixos/modules/services/misc/anki-sync-server.md @@ -52,7 +52,7 @@ following options: ```nix { - services.anki-sync-server.host = "0.0.0.0"; + services.anki-sync-server.address = "0.0.0.0"; services.anki-sync-server.openFirewall = true; } ``` diff --git a/nixpkgs/nixos/modules/services/misc/devpi-server.nix b/nixpkgs/nixos/modules/services/misc/devpi-server.nix index 0234db4bc2c5..92c0c6206c8b 100644 --- a/nixpkgs/nixos/modules/services/misc/devpi-server.nix +++ b/nixpkgs/nixos/modules/services/misc/devpi-server.nix @@ -74,8 +74,9 @@ in # have 0600 permissions. preStart = '' - cp ${cfg.secretFile} ${runtimeDir}/${secretsFileName} - chmod 0600 ${runtimeDir}/*${secretsFileName} + ${optionalString (!isNull cfg.secretFile) + "install -Dm 0600 \${CREDENTIALS_DIRECTORY}/devpi-secret ${runtimeDir}/${secretsFileName}" + } if [ -f ${serverDir}/.nodeinfo ]; then # already initialized the package index, exit gracefully @@ -85,6 +86,9 @@ in + strings.optionalString cfg.replica "--role=replica --master-url=${cfg.primaryUrl}"; serviceConfig = { + LoadCredential = lib.mkIf (! isNull cfg.secretFile) [ + "devpi-secret:${cfg.secretFile}" + ]; Restart = "always"; ExecStart = let diff --git a/nixpkgs/nixos/modules/services/misc/forgejo.nix b/nixpkgs/nixos/modules/services/misc/forgejo.nix index babed2d5acd4..9a102918f35e 100644 --- a/nixpkgs/nixos/modules/services/misc/forgejo.nix +++ b/nixpkgs/nixos/modules/services/misc/forgejo.nix @@ -12,6 +12,15 @@ let usePostgresql = cfg.database.type == "postgres"; useSqlite = cfg.database.type == "sqlite3"; + secrets = let + mkSecret = section: values: lib.mapAttrsToList (key: value: { + env = envEscape "FORGEJO__${section}__${key}__FILE"; + path = value; + }) values; + # https://codeberg.org/forgejo/forgejo/src/tag/v7.0.2/contrib/environment-to-ini/environment-to-ini.go + envEscape = string: lib.replaceStrings [ "." "-" ] [ "_0X2E_" "_0X2D_" ] (lib.strings.toUpper string); + in lib.flatten (lib.mapAttrsToList mkSecret cfg.secrets); + inherit (lib) literalExpression mkChangedOptionModule @@ -34,6 +43,7 @@ in (mkRenamedOptionModule [ "services" "forgejo" "appName" ] [ "services" "forgejo" "settings" "DEFAULT" "APP_NAME" ]) (mkRemovedOptionModule [ "services" "forgejo" "extraConfig" ] "services.forgejo.extraConfig has been removed. Please use the freeform services.forgejo.settings option instead") (mkRemovedOptionModule [ "services" "forgejo" "database" "password" ] "services.forgejo.database.password has been removed. Please use services.forgejo.database.passwordFile instead") + (mkRenamedOptionModule [ "services" "forgejo" "mailerPasswordFile" ] [ "services" "forgejo" "secrets" "mailer" "PASSWD" ]) # copied from services.gitea; remove at some point (mkRenamedOptionModule [ "services" "forgejo" "cookieSecure" ] [ "services" "forgejo" "settings" "session" "COOKIE_SECURE" ]) @@ -224,13 +234,6 @@ in description = "Path to the git repositories."; }; - mailerPasswordFile = mkOption { - type = types.nullOr types.str; - default = null; - example = "/run/keys/forgejo-mailpw"; - description = "Path to a file containing the SMTP password."; - }; - settings = mkOption { default = { }; description = '' @@ -347,6 +350,44 @@ in }; }; }; + + secrets = mkOption { + default = { }; + description = '' + This is a small wrapper over systemd's `LoadCredential`. + + It takes the same sections and keys as {option}`services.forgejo.settings`, + but the value of each key is a path instead of a string or bool. + + The path is then loaded as credential, exported as environment variable + and then feed through + <https://codeberg.org/forgejo/forgejo/src/branch/forgejo/contrib/environment-to-ini/environment-to-ini.go>. + + It does the required environment variable escaping for you. + + ::: {.note} + Keys specified here take priority over the ones in {option}`services.forgejo.settings`! + ::: + ''; + example = literalExpression '' + { + metrics = { + TOKEN = "/run/keys/forgejo-metrics-token"; + }; + camo = { + HMAC_KEY = "/run/keys/forgejo-camo-hmac"; + }; + service = { + HCAPTCHA_SECRET = "/run/keys/forgejo-hcaptcha-secret"; + HCAPTCHA_SITEKEY = "/run/keys/forgejo-hcaptcha-sitekey"; + }; + } + ''; + type = types.submodule { + freeformType = with types; attrsOf (attrsOf path); + options = { }; + }; + }; }; }; @@ -381,7 +422,6 @@ in HOST = if cfg.database.socket != null then cfg.database.socket else cfg.database.host + ":" + toString cfg.database.port; NAME = cfg.database.name; USER = cfg.database.user; - PASSWD = "#dbpass#"; }) (mkIf useSqlite { PATH = cfg.database.path; @@ -397,7 +437,6 @@ in server = mkIf cfg.lfs.enable { LFS_START_SERVER = true; - LFS_JWT_SECRET = "#lfsjwtsecret#"; }; session = { @@ -405,21 +444,30 @@ in }; security = { - SECRET_KEY = "#secretkey#"; - INTERNAL_TOKEN = "#internaltoken#"; INSTALL_LOCK = true; }; - mailer = mkIf (cfg.mailerPasswordFile != null) { - PASSWD = "#mailerpass#"; + lfs = mkIf cfg.lfs.enable { + PATH = cfg.lfs.contentDir; + }; + }; + + services.forgejo.secrets = { + security = { + SECRET_KEY = "${cfg.customDir}/conf/secret_key"; + INTERNAL_TOKEN = "${cfg.customDir}/conf/internal_token"; }; oauth2 = { - JWT_SECRET = "#oauth2jwtsecret#"; + JWT_SECRET = "${cfg.customDir}/conf/oauth2_jwt_secret"; }; - lfs = mkIf cfg.lfs.enable { - PATH = cfg.lfs.contentDir; + database = mkIf (cfg.database.passwordFile != null) { + PASSWD = cfg.database.passwordFile; + }; + + server = mkIf cfg.lfs.enable { + LFS_JWT_SECRET = "${cfg.customDir}/conf/lfs_jwt_secret"; }; }; @@ -476,6 +524,37 @@ in "z '${cfg.lfs.contentDir}' 0750 ${cfg.user} ${cfg.group} - -" ]; + systemd.services.forgejo-secrets = mkIf (!cfg.useWizard) { + description = "Forgejo secret bootstrap helper"; + script = '' + if [ ! -s '${cfg.secrets.security.SECRET_KEY}' ]; then + ${exe} generate secret SECRET_KEY > '${cfg.secrets.security.SECRET_KEY}' + fi + + if [ ! -s '${cfg.secrets.oauth2.JWT_SECRET}' ]; then + ${exe} generate secret JWT_SECRET > '${cfg.secrets.oauth2.JWT_SECRET}' + fi + + ${optionalString cfg.lfs.enable '' + if [ ! -s '${cfg.secrets.server.LFS_JWT_SECRET}' ]; then + ${exe} generate secret LFS_JWT_SECRET > '${cfg.secrets.server.LFS_JWT_SECRET}' + fi + ''} + + if [ ! -s '${cfg.secrets.security.INTERNAL_TOKEN}' ]; then + ${exe} generate secret INTERNAL_TOKEN > '${cfg.secrets.security.INTERNAL_TOKEN}' + fi + ''; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + User = cfg.user; + Group = cfg.group; + ReadWritePaths = [ cfg.customDir ]; + UMask = "0077"; + }; + }; + systemd.services.forgejo = { description = "Forgejo (Beyond coding. We forge.)"; after = [ @@ -484,11 +563,15 @@ in "postgresql.service" ] ++ optionals useMysql [ "mysql.service" + ] ++ optionals (!cfg.useWizard) [ + "forgejo-secrets.service" ]; requires = optionals (cfg.database.createDatabase && usePostgresql) [ "postgresql.service" ] ++ optionals (cfg.database.createDatabase && useMysql) [ "mysql.service" + ] ++ optionals (!cfg.useWizard) [ + "forgejo-secrets.service" ]; wantedBy = [ "multi-user.target" ]; path = [ cfg.package pkgs.git pkgs.gnupg ]; @@ -501,61 +584,15 @@ in # lfs_jwt_secret. # We have to consider this to stay compatible with older installations. preStart = - let - runConfig = "${cfg.customDir}/conf/app.ini"; - secretKey = "${cfg.customDir}/conf/secret_key"; - oauth2JwtSecret = "${cfg.customDir}/conf/oauth2_jwt_secret"; - oldLfsJwtSecret = "${cfg.customDir}/conf/jwt_secret"; # old file for LFS_JWT_SECRET - lfsJwtSecret = "${cfg.customDir}/conf/lfs_jwt_secret"; # new file for LFS_JWT_SECRET - internalToken = "${cfg.customDir}/conf/internal_token"; - replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret"; - in '' - # copy custom configuration and generate random secrets if needed - ${lib.optionalString (!cfg.useWizard) '' + ${optionalString (!cfg.useWizard) '' function forgejo_setup { - cp -f '${format.generate "app.ini" cfg.settings}' '${runConfig}' - - if [ ! -s '${secretKey}' ]; then - ${exe} generate secret SECRET_KEY > '${secretKey}' - fi - - # Migrate LFS_JWT_SECRET filename - if [[ -s '${oldLfsJwtSecret}' && ! -s '${lfsJwtSecret}' ]]; then - mv '${oldLfsJwtSecret}' '${lfsJwtSecret}' - fi - - if [ ! -s '${oauth2JwtSecret}' ]; then - ${exe} generate secret JWT_SECRET > '${oauth2JwtSecret}' - fi - - ${optionalString cfg.lfs.enable '' - if [ ! -s '${lfsJwtSecret}' ]; then - ${exe} generate secret LFS_JWT_SECRET > '${lfsJwtSecret}' - fi - ''} - - if [ ! -s '${internalToken}' ]; then - ${exe} generate secret INTERNAL_TOKEN > '${internalToken}' - fi - - chmod u+w '${runConfig}' - ${replaceSecretBin} '#secretkey#' '${secretKey}' '${runConfig}' - ${replaceSecretBin} '#oauth2jwtsecret#' '${oauth2JwtSecret}' '${runConfig}' - ${replaceSecretBin} '#internaltoken#' '${internalToken}' '${runConfig}' - - ${optionalString cfg.lfs.enable '' - ${replaceSecretBin} '#lfsjwtsecret#' '${lfsJwtSecret}' '${runConfig}' - ''} - - ${optionalString (cfg.database.passwordFile != null) '' - ${replaceSecretBin} '#dbpass#' '${cfg.database.passwordFile}' '${runConfig}' - ''} - - ${optionalString (cfg.mailerPasswordFile != null) '' - ${replaceSecretBin} '#mailerpass#' '${cfg.mailerPasswordFile}' '${runConfig}' - ''} - chmod u-w '${runConfig}' + config='${cfg.customDir}/conf/app.ini' + cp -f '${format.generate "app.ini" cfg.settings}' "$config" + + chmod u+w "$config" + ${lib.getExe' cfg.package "environment-to-ini"} --config "$config" + chmod u-w "$config" } (umask 027; forgejo_setup) ''} @@ -616,6 +653,8 @@ in # System Call Filtering SystemCallArchitectures = "native"; SystemCallFilter = [ "~@cpu-emulation @debug @keyring @mount @obsolete @privileged @setuid" "setrlimit" ]; + # cfg.secrets + LoadCredential = map (e: "${e.env}:${e.path}") secrets; }; environment = { @@ -625,7 +664,7 @@ in # is resolved. GITEA_WORK_DIR = cfg.stateDir; GITEA_CUSTOM = cfg.customDir; - }; + } // lib.listToAttrs (map (e: lib.nameValuePair e.env "%d/${e.env}") secrets); }; services.openssh.settings.AcceptEnv = mkIf (!cfg.settings.START_SSH_SERVER or false) "GIT_PROTOCOL"; diff --git a/nixpkgs/nixos/modules/services/misc/gitea.nix b/nixpkgs/nixos/modules/services/misc/gitea.nix index a8526688b074..d43250c88268 100644 --- a/nixpkgs/nixos/modules/services/misc/gitea.nix +++ b/nixpkgs/nixos/modules/services/misc/gitea.nix @@ -722,5 +722,5 @@ in timerConfig.OnCalendar = cfg.dump.interval; }; }; - meta.maintainers = with lib.maintainers; [ srhb ma27 pyrox0 ]; + meta.maintainers = with lib.maintainers; [ ma27 techknowlogick SuperSandro2000 ]; } diff --git a/nixpkgs/nixos/modules/services/misc/gollum.nix b/nixpkgs/nixos/modules/services/misc/gollum.nix index 3966ef036bec..f320e78a9106 100644 --- a/nixpkgs/nixos/modules/services/misc/gollum.nix +++ b/nixpkgs/nixos/modules/services/misc/gollum.nix @@ -110,7 +110,7 @@ in users.groups."${cfg.group}" = { }; systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' - ${config.users.users.gollum.name} ${config.users.groups.gollum.name} - -" + "d '${cfg.stateDir}' - ${cfg.user} ${cfg.group} - -" ]; systemd.services.gollum = { diff --git a/nixpkgs/nixos/modules/services/misc/graphical-desktop.nix b/nixpkgs/nixos/modules/services/misc/graphical-desktop.nix index a88c02e610bf..c8fe0d921c6a 100644 --- a/nixpkgs/nixos/modules/services/misc/graphical-desktop.nix +++ b/nixpkgs/nixos/modules/services/misc/graphical-desktop.nix @@ -38,7 +38,7 @@ in fonts.enableDefaultPackages = lib.mkDefault true; - hardware.opengl.enable = lib.mkDefault true; + hardware.graphics.enable = lib.mkDefault true; programs.gnupg.agent.pinentryPackage = lib.mkOverride 1100 pkgs.pinentry-gnome3; diff --git a/nixpkgs/nixos/modules/services/misc/invidious-router.nix b/nixpkgs/nixos/modules/services/misc/invidious-router.nix index 33da7e96b523..7a90c6ab9ddc 100644 --- a/nixpkgs/nixos/modules/services/misc/invidious-router.nix +++ b/nixpkgs/nixos/modules/services/misc/invidious-router.nix @@ -8,10 +8,10 @@ settingsFormat = pkgs.formats.yaml {}; configFile = settingsFormat.generate "config.yaml" cfg.settings; in { - meta.maintainers = [lib.maintainers.s1ls]; + meta.maintainers = [lib.maintainers.sils]; options.services.invidious-router = { - enable = lib.mkEnableOption "Enables the invidious-router service"; + enable = lib.mkEnableOption "the invidious-router service"; port = lib.mkOption { type = lib.types.port; default = 8050; diff --git a/nixpkgs/nixos/modules/services/misc/jellyfin.nix b/nixpkgs/nixos/modules/services/misc/jellyfin.nix index a1d3910bd93b..a00609087842 100644 --- a/nixpkgs/nixos/modules/services/misc/jellyfin.nix +++ b/nixpkgs/nixos/modules/services/misc/jellyfin.nix @@ -160,5 +160,5 @@ in }; - meta.maintainers = with maintainers; [ minijackson nu-nu-ko ]; + meta.maintainers = with maintainers; [ minijackson fsnkty ]; } diff --git a/nixpkgs/nixos/modules/services/misc/mqtt2influxdb.nix b/nixpkgs/nixos/modules/services/misc/mqtt2influxdb.nix index a2d6a2b34a23..d07ce1e66ba3 100644 --- a/nixpkgs/nixos/modules/services/misc/mqtt2influxdb.nix +++ b/nixpkgs/nixos/modules/services/misc/mqtt2influxdb.nix @@ -124,7 +124,8 @@ let in { options = { services.mqtt2influxdb = { - enable = mkEnableOption "BigClown MQTT to InfluxDB bridge."; + enable = mkEnableOption "BigClown MQTT to InfluxDB bridge"; + package = mkPackageOption pkgs ["python3Packages" "mqtt2influxdb"] {}; environmentFiles = mkOption { type = types.listOf types.path; default = []; @@ -245,7 +246,7 @@ in { ''; serviceConfig = { EnvironmentFile = cfg.environmentFiles; - ExecStart = "${cfg.package}/bin/mqtt2influxdb -dc ${finalConfig}"; + ExecStart = "${lib.getExe cfg.package} -dc ${finalConfig}"; RuntimeDirectory = "mqtt2influxdb"; }; }; diff --git a/nixpkgs/nixos/modules/services/misc/ollama.nix b/nixpkgs/nixos/modules/services/misc/ollama.nix index c0341984aa35..c460514783ef 100644 --- a/nixpkgs/nixos/modules/services/misc/ollama.nix +++ b/nixpkgs/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 { @@ -11,6 +11,11 @@ let }; in { + imports = [ + (lib.mkRemovedOptionModule [ "services" "ollama" "listenAddress" ] + "Use `services.ollama.host` and `services.ollama.port` instead.") + ]; + options = { services.ollama = { enable = lib.mkEnableOption "ollama server for local large language models"; @@ -64,12 +69,20 @@ in See also `services.ollama.sandbox`. ''; }; - listenAddress = lib.mkOption { + host = lib.mkOption { type = types.str; - default = "127.0.0.1:11434"; - example = "0.0.0.0:11111"; + default = "127.0.0.1"; + example = "0.0.0.0"; description = '' - The address which the ollama server HTTP interface binds and listens to. + The host address which the ollama server HTTP interface listens to. + ''; + }; + port = lib.mkOption { + type = types.port; + default = 11434; + example = 11111; + description = '' + Which port the ollama server listens to. ''; }; acceleration = lib.mkOption { @@ -80,14 +93,30 @@ in What interface to use for hardware acceleration. - `null`: default behavior - if `nixpkgs.config.rocmSupport` is enabled, uses `"rocm"` - if `nixpkgs.config.cudaSupport` is enabled, uses `"cuda"` - otherwise defaults to `false` + - if `nixpkgs.config.rocmSupport` is enabled, uses `"rocm"` + - if `nixpkgs.config.cudaSupport` is enabled, uses `"cuda"` + - otherwise defaults to `false` - `false`: disable GPU, only use CPU - `"rocm"`: supported by most modern AMD GPUs + - may require overriding gpu type with `services.ollama.rocmOverrideGfx` + if rocm doesn't detect your AMD gpu - `"cuda"`: supported by most modern NVIDIA GPUs ''; }; + rocmOverrideGfx = lib.mkOption { + type = types.nullOr types.str; + default = null; + example = "10.3.0"; + description = '' + Override what rocm will detect your gpu model as. + For example, make rocm treat your RX 5700 XT (or any other model) + as an RX 6900 XT using a value of `"10.3.0"` (gfx 1030). + + This sets the value of `HSA_OVERRIDE_GFX_VERSION`. See [ollama's docs]( + https://github.com/ollama/ollama/blob/main/docs/gpu.md#amd-radeon + ) for details. + ''; + }; environmentVariables = lib.mkOption { type = types.attrsOf types.str; default = { }; @@ -103,6 +132,22 @@ 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; + description = '' + Whether to open the firewall for ollama. + This adds `services.ollama.port` to `networking.firewall.allowedTCPPorts`. + ''; + }; }; }; @@ -114,7 +159,8 @@ in environment = cfg.environmentVariables // { HOME = cfg.home; OLLAMA_MODELS = cfg.models; - OLLAMA_HOST = cfg.listenAddress; + OLLAMA_HOST = "${cfg.host}:${toString cfg.port}"; + HSA_OVERRIDE_GFX_VERSION = lib.mkIf (cfg.rocmOverrideGfx != null) cfg.rocmOverrideGfx; }; serviceConfig = { ExecStart = "${lib.getExe ollamaPackage} serve"; @@ -123,8 +169,18 @@ 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 ]; }; + environment.systemPackages = [ ollamaPackage ]; }; diff --git a/nixpkgs/nixos/modules/services/misc/open-webui.nix b/nixpkgs/nixos/modules/services/misc/open-webui.nix new file mode 100644 index 000000000000..b4016d03f675 --- /dev/null +++ b/nixpkgs/nixos/modules/services/misc/open-webui.nix @@ -0,0 +1,114 @@ +{ + config, + lib, + pkgs, + ... +}: +let + inherit (lib) types; + + cfg = config.services.open-webui; +in +{ + options = { + services.open-webui = { + enable = lib.mkEnableOption "Open-WebUI server"; + package = lib.mkPackageOption pkgs "open-webui" { }; + + stateDir = lib.mkOption { + type = types.path; + default = "/var/lib/open-webui"; + example = "/home/foo"; + description = "State directory of Open-WebUI."; + }; + + host = lib.mkOption { + type = types.str; + default = "127.0.0.1"; + example = "0.0.0.0"; + description = '' + The host address which the Open-WebUI server HTTP interface listens to. + ''; + }; + + port = lib.mkOption { + type = types.port; + default = 8080; + example = 11111; + description = '' + Which port the Open-WebUI server listens to. + ''; + }; + + environment = lib.mkOption { + type = types.attrsOf types.str; + default = { + SCARF_NO_ANALYTICS = "True"; + DO_NOT_TRACK = "True"; + ANONYMIZED_TELEMETRY = "False"; + }; + example = '' + { + OLLAMA_API_BASE_URL = "http://127.0.0.1:11434"; + # Disable authentication + WEBUI_AUTH = "False"; + } + ''; + description = "Extra environment variables for Open-WebUI"; + }; + + openFirewall = lib.mkOption { + type = types.bool; + default = false; + description = '' + Whether to open the firewall for Open-WebUI. + This adds `services.open-webui.port` to `networking.firewall.allowedTCPPorts`. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.open-webui = { + description = "User-friendly WebUI for LLMs"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + environment = { + STATIC_DIR = "."; + DATA_DIR = "."; + HF_HOME = "."; + SENTENCE_TRANSFORMERS_HOME = "."; + } // cfg.environment; + + serviceConfig = { + ExecStart = "${lib.getExe cfg.package} serve --host ${cfg.host} --port ${toString cfg.port}"; + WorkingDirectory = cfg.stateDir; + StateDirectory = "open-webui"; + RuntimeDirectory = "open-webui"; + RuntimeDirectoryMode = "0755"; + PrivateTmp = true; + DynamicUser = true; + DevicePolicy = "closed"; + LockPersonality = true; + MemoryDenyWriteExecute = false; # onnxruntime/capi/onnxruntime_pybind11_state.so: cannot enable executable stack as shared object requires: Permission Denied + PrivateUsers = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectControlGroups = true; + ProcSubset = "all"; # Error in cpuinfo: failed to parse processor information from /proc/cpuinfo + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = "native"; + UMask = "0077"; + }; + }; + + networking.firewall = lib.mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; + }; + + meta.maintainers = with lib.maintainers; [ shivaraj-bh ]; +} diff --git a/nixpkgs/nixos/modules/services/misc/paperless.nix b/nixpkgs/nixos/modules/services/misc/paperless.nix index e564fe3b8317..6d6a49c10bdd 100644 --- a/nixpkgs/nixos/modules/services/misc/paperless.nix +++ b/nixpkgs/nixos/modules/services/misc/paperless.nix @@ -225,7 +225,7 @@ in effectively never complete due to running into timeouts. This sets `OMP_NUM_THREADS` to `1` in order to mitigate the issue. See - https://github.com/NixOS/nixpkgs/issues/240591 for more information. + https://github.com/NixOS/nixpkgs/issues/240591 for more information '' // mkOption { default = true; }; }; diff --git a/nixpkgs/nixos/modules/services/misc/pghero.nix b/nixpkgs/nixos/modules/services/misc/pghero.nix new file mode 100644 index 000000000000..39515f10c8e1 --- /dev/null +++ b/nixpkgs/nixos/modules/services/misc/pghero.nix @@ -0,0 +1,142 @@ +{ config, pkgs, lib, utils, ... }: +let + cfg = config.services.pghero; + settingsFormat = pkgs.formats.yaml { }; + settingsFile = settingsFormat.generate "pghero.yaml" cfg.settings; +in +{ + options.services.pghero = { + enable = lib.mkEnableOption "PgHero service"; + package = lib.mkPackageOption pkgs "pghero" { }; + + listenAddress = lib.mkOption { + type = lib.types.str; + example = "[::1]:3000"; + description = '' + `hostname:port` to listen for HTTP traffic. + + This is bound using the systemd socket activation. + ''; + }; + + extraArgs = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = '' + Additional command-line arguments for the systemd service. + + Refer to the [Puma web server documentation] for available arguments. + + [Puma web server documentation]: https://puma.io/puma#configuration + ''; + }; + + settings = lib.mkOption { + type = settingsFormat.type; + default = { }; + example = { + databases = { + primary = { + url = "<%= ENV['PRIMARY_DATABASE_URL'] %>"; + }; + }; + }; + description = '' + PgHero configuration. Refer to the [PgHero documentation] for more + details. + + [PgHero documentation]: https://github.com/ankane/pghero/blob/master/guides/Linux.md#multiple-databases + ''; + }; + + environment = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + default = { }; + description = '' + Environment variables to set for the service. Secrets should be + specified using {option}`environmentFile`. + ''; + }; + + environmentFiles = lib.mkOption { + type = lib.types.listOf lib.types.path; + default = [ ]; + description = '' + File to load environment variables from. Loaded variables override + values set in {option}`environment`. + ''; + }; + + extraGroups = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + example = [ "tlskeys" ]; + description = '' + Additional groups for the systemd service. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.sockets.pghero = { + unitConfig.Description = "PgHero HTTP socket"; + wantedBy = [ "sockets.target" ]; + listenStreams = [ cfg.listenAddress ]; + }; + + systemd.services.pghero = { + description = "PgHero performance dashboard for PostgreSQL"; + wantedBy = [ "multi-user.target" ]; + requires = [ "pghero.socket" ]; + after = [ "pghero.socket" "network.target" ]; + + environment = { + RAILS_ENV = "production"; + PGHERO_CONFIG_PATH = settingsFile; + } // cfg.environment; + + serviceConfig = { + Type = "notify"; + WatchdogSec = "10"; + + ExecStart = utils.escapeSystemdExecArgs ([ + (lib.getExe cfg.package) + "--bind-to-activated-sockets" + "only" + ] ++ cfg.extraArgs); + Restart = "always"; + + WorkingDirectory = "${cfg.package}/share/pghero"; + + EnvironmentFile = cfg.environmentFiles; + SupplementaryGroups = cfg.extraGroups; + + DynamicUser = true; + UMask = "0077"; + + ProtectHome = true; + ProtectProc = "invisible"; + ProcSubset = "pid"; + ProtectClock = true; + ProtectHostname = true; + ProtectControlGroups = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + PrivateUsers = true; + PrivateDevices = true; + RestrictRealtime = true; + RestrictNamespaces = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; + DeviceAllow = [ "" ]; + DevicePolicy = "closed"; + CapabilityBoundingSet = [ "" ]; + MemoryDenyWriteExecute = true; + LockPersonality = true; + SystemCallArchitectures = "native"; + SystemCallErrorNumber = "EPERM"; + SystemCallFilter = [ "@system-service" ]; + }; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/misc/plex.nix b/nixpkgs/nixos/modules/services/misc/plex.nix index fcd8ebbac6ed..212abda5d1e0 100644 --- a/nixpkgs/nixos/modules/services/misc/plex.nix +++ b/nixpkgs/nixos/modules/services/misc/plex.nix @@ -93,6 +93,17 @@ in ''; }; + accelerationDevices = mkOption { + type = types.listOf types.str; + default = ["*"]; + example = [ "/dev/dri/renderD128" ]; + description = '' + A list of device paths to hardware acceleration devices that Plex should + have access to. This is useful when transcoding media files. + The special value `"*"` will allow all devices. + ''; + }; + package = mkPackageOption pkgs "plex" { extraDescription = '' Plex subscribers may wish to use their own package here, @@ -133,6 +144,24 @@ in KillSignal = "SIGQUIT"; PIDFile = "${cfg.dataDir}/Plex Media Server/plexmediaserver.pid"; Restart = "on-failure"; + + # Hardening + NoNewPrivileges = true; + PrivateTmp = true; + PrivateDevices = cfg.accelerationDevices == []; + DeviceAllow = mkIf (cfg.accelerationDevices != [] && !lib.elem "*" cfg.accelerationDevices) cfg.accelerationDevices; + ProtectSystem = true; + ProtectHome = true; + ProtectControlGroups = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK"]; + # This could be made to work if the namespaces needed were known + # RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + MemoryDenyWriteExecute = true; + LockPersonality = true; }; environment = { diff --git a/nixpkgs/nixos/modules/services/misc/portunus.nix b/nixpkgs/nixos/modules/services/misc/portunus.nix index bdb35da788e3..a9a069b0c055 100644 --- a/nixpkgs/nixos/modules/services/misc/portunus.nix +++ b/nixpkgs/nixos/modules/services/misc/portunus.nix @@ -70,7 +70,7 @@ in To activate dex, first a search user must be created in the Portunus web ui and then the password must to be set as the `DEX_SEARCH_USER_PASSWORD` environment variable - in the [](#opt-services.dex.environmentFile) setting. + in the [](#opt-services.dex.environmentFile) setting ''; oidcClients = mkOption { @@ -98,6 +98,10 @@ in The OIDC secret must be set as the `DEX_CLIENT_''${id}` environment variable in the [](#opt-services.dex.environmentFile) setting. + + ::: {.note} + Make sure the id only contains characters that are allowed in an environment variable name, e.g. no -. + ::: ''; }; @@ -111,10 +115,7 @@ in ldap = { package = mkOption { type = types.package; - # needs openldap built with a libxcrypt that support crypt sha256 until users have had time to migrate to newer hashes - # Ref: <https://github.com/majewsky/portunus/issues/2> - # TODO: remove in NixOS 24.11 (cf. same note on pkgs/servers/portunus/default.nix) - default = pkgs.openldap.override { libxcrypt = pkgs.libxcrypt-legacy; }; + default = pkgs.openldap; defaultText = lib.literalExpression "pkgs.openldap.override { libxcrypt = pkgs.libxcrypt-legacy; }"; description = "The OpenLDAP package to use."; }; diff --git a/nixpkgs/nixos/modules/services/misc/private-gpt.nix b/nixpkgs/nixos/modules/services/misc/private-gpt.nix index 9a3e5317cdb1..ad9b6f5ffa80 100644 --- a/nixpkgs/nixos/modules/services/misc/private-gpt.nix +++ b/nixpkgs/nixos/modules/services/misc/private-gpt.nix @@ -117,5 +117,5 @@ in }; }; - meta.maintainers = with lib.maintainers; [ drupol ]; + meta.maintainers = with lib.maintainers; [ ]; } diff --git a/nixpkgs/nixos/modules/services/misc/renovate.nix b/nixpkgs/nixos/modules/services/misc/renovate.nix new file mode 100644 index 000000000000..25a719c91cbd --- /dev/null +++ b/nixpkgs/nixos/modules/services/misc/renovate.nix @@ -0,0 +1,153 @@ +{ + config, + lib, + pkgs, + ... +}: +let + inherit (lib) + mkEnableOption + mkPackageOption + mkOption + types + mkIf + ; + json = pkgs.formats.json { }; + cfg = config.services.renovate; + generateValidatedConfig = + name: value: + pkgs.callPackage ( + { runCommand, jq }: + runCommand name + { + nativeBuildInputs = [ + jq + cfg.package + ]; + value = builtins.toJSON value; + passAsFile = [ "value" ]; + preferLocalBuild = true; + } + '' + jq . "$valuePath"> $out + renovate-config-validator $out + '' + ) { }; + generateConfig = if cfg.validateSettings then generateValidatedConfig else json.generate; +in +{ + meta.maintainers = with lib.maintainers; [ marie natsukium ]; + + options.services.renovate = { + enable = mkEnableOption "renovate"; + package = mkPackageOption pkgs "renovate" { }; + schedule = mkOption { + type = with types; nullOr str; + description = "How often to run renovate. See {manpage}`systemd.time(7)` for the format."; + example = "*:0/10"; + default = null; + }; + credentials = mkOption { + type = with types; attrsOf path; + description = '' + Allows configuring environment variable credentials for renovate, read from files. + This should always be used for passing confidential data to renovate. + ''; + example = { + RENOVATE_TOKEN = "/etc/renovate/token"; + }; + default = { }; + }; + runtimePackages = mkOption { + type = with types; listOf package; + description = "Packages available to renovate."; + default = [ ]; + }; + validateSettings = mkOption { + type = types.bool; + default = true; + description = "Weither to run renovate's config validator on the built configuration."; + }; + settings = mkOption { + type = json.type; + default = { }; + example = { + platform = "gitea"; + endpoint = "https://git.example.com"; + gitAuthor = "Renovate <renovate@example.com>"; + }; + description = '' + Renovate's global configuration. + If you want to pass secrets to renovate, please use {option}`services.renovate.credentials` for that. + ''; + }; + }; + + config = mkIf cfg.enable { + services.renovate.settings = { + cacheDir = "/var/cache/renovate"; + baseDir = "/var/lib/renovate"; + }; + + systemd.services.renovate = { + description = "Renovate dependency updater"; + documentation = [ "https://docs.renovatebot.com/" ]; + after = [ "network.target" ]; + startAt = lib.optional (cfg.schedule != null) cfg.schedule; + path = [ + config.systemd.package + pkgs.git + ] ++ cfg.runtimePackages; + + serviceConfig = { + Type = "oneshot"; + User = "renovate"; + Group = "renovate"; + DynamicUser = true; + LoadCredential = lib.mapAttrsToList (name: value: "SECRET-${name}:${value}") cfg.credentials; + RemainAfterExit = false; + Restart = "on-failure"; + CacheDirectory = "renovate"; + StateDirectory = "renovate"; + + # Hardening + CapabilityBoundingSet = [ "" ]; + DeviceAllow = [ "" ]; + LockPersonality = true; + PrivateDevices = true; + PrivateUsers = true; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = "native"; + UMask = "0077"; + }; + + script = '' + ${lib.concatStringsSep "\n" ( + builtins.map (name: "export ${name}=$(systemd-creds cat 'SECRET-${name}')") ( + lib.attrNames cfg.credentials + ) + )} + exec ${lib.escapeShellArg (lib.getExe cfg.package)} + ''; + + environment = { + RENOVATE_CONFIG_FILE = generateConfig "renovate-config.json" cfg.settings; + HOME = "/var/lib/renovate"; + }; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/misc/snapper.nix b/nixpkgs/nixos/modules/services/misc/snapper.nix index 33207ac2b5bd..1b16ef7958ad 100644 --- a/nixpkgs/nixos/modules/services/misc/snapper.nix +++ b/nixpkgs/nixos/modules/services/misc/snapper.nix @@ -1,16 +1,32 @@ -{ config, pkgs, lib, ... }: +{ + config, + pkgs, + lib, + ... +}: with lib; let cfg = config.services.snapper; - mkValue = v: - if isList v then "\"${concatMapStringsSep " " (escape [ "\\" " " ]) v}\"" - else if v == true then "yes" - else if v == false then "no" - else if isString v then "\"${v}\"" - else builtins.toJSON v; + mkValue = + v: + if isList v then + "\"${ + concatMapStringsSep " " (escape [ + "\\" + " " + ]) v + }\"" + else if v == true then + "yes" + else if v == false then + "no" + else if isString v then + "\"${v}\"" + else + builtins.toJSON v; mkKeyValue = k: v: "${k}=${mkValue v}"; @@ -43,7 +59,7 @@ let ALLOW_GROUPS = mkOption { type = types.listOf safeStr; - default = []; + default = [ ]; description = '' List of groups allowed to operate with the config. @@ -53,7 +69,7 @@ let ALLOW_USERS = mkOption { type = types.listOf safeStr; - default = []; + default = [ ]; example = [ "alice" ]; description = '' List of users allowed to operate with the config. "root" is always @@ -78,6 +94,54 @@ let Defines whether hourly snapshots should be created. ''; }; + + TIMELINE_LIMIT_HOURLY = mkOption { + type = types.str; + default = "10"; + description = '' + Limits for timeline cleanup. + ''; + }; + + TIMELINE_LIMIT_DAILY = mkOption { + type = types.str; + default = "10"; + description = '' + Limits for timeline cleanup. + ''; + }; + + TIMELINE_LIMIT_WEEKLY = mkOption { + type = types.str; + default = "0"; + description = '' + Limits for timeline cleanup. + ''; + }; + + TIMELINE_LIMIT_MONTHLY = mkOption { + type = types.str; + default = "10"; + description = '' + Limits for timeline cleanup. + ''; + }; + + TIMELINE_LIMIT_QUARTERLY = mkOption { + type = types.str; + default = "0"; + description = '' + Limits for timeline cleanup. + ''; + }; + + TIMELINE_LIMIT_YEARLY = mkOption { + type = types.str; + default = "10"; + description = '' + Limits for timeline cleanup. + ''; + }; }; in @@ -108,7 +172,7 @@ in type = types.bool; example = true; description = '' - Set the `persistentTimer` option for the + Set the `Persistent` option for the {manpage}`systemd.timer(5)` which triggers the snapshot immediately if the last trigger was missed (e.g. if the system was powered down). @@ -152,112 +216,129 @@ in is valid here, even if NixOS doesn't document it. ''; - type = types.attrsOf (types.submodule { - freeformType = types.attrsOf (types.oneOf [ (types.listOf safeStr) types.bool safeStr types.number ]); - - options = configOptions; - }); + type = types.attrsOf ( + types.submodule { + freeformType = types.attrsOf ( + types.oneOf [ + (types.listOf safeStr) + types.bool + safeStr + types.number + ] + ); + + options = configOptions; + } + ); }; }; - config = mkIf (cfg.configs != {}) (let - documentation = [ "man:snapper(8)" "man:snapper-configs(5)" ]; - in { - - environment = { - - systemPackages = [ pkgs.snapper ]; - - # Note: snapper/config-templates/default is only needed for create-config - # which is not the NixOS way to configure. - etc = { - - "sysconfig/snapper".text = '' - SNAPPER_CONFIGS="${lib.concatStringsSep " " (builtins.attrNames cfg.configs)}" - ''; - - } - // (mapAttrs' (name: subvolume: nameValuePair "snapper/configs/${name}" ({ - text = lib.generators.toKeyValue { inherit mkKeyValue; } (filterAttrs (k: v: v != defaultOf k) subvolume); - })) cfg.configs) - // (lib.optionalAttrs (cfg.filters != null) { - "snapper/filters/default.txt".text = cfg.filters; - }); - - }; + config = mkIf (cfg.configs != { }) ( + let + documentation = [ + "man:snapper(8)" + "man:snapper-configs(5)" + ]; + in + { + environment = { + + systemPackages = [ pkgs.snapper ]; + + # Note: snapper/config-templates/default is only needed for create-config + # which is not the NixOS way to configure. + etc = + { + + "sysconfig/snapper".text = '' + SNAPPER_CONFIGS="${lib.concatStringsSep " " (builtins.attrNames cfg.configs)}" + ''; + } + // (mapAttrs' ( + name: subvolume: + nameValuePair "snapper/configs/${name}" ({ + text = lib.generators.toKeyValue { inherit mkKeyValue; } ( + filterAttrs (k: v: v != defaultOf k) subvolume + ); + }) + ) cfg.configs) + // (lib.optionalAttrs (cfg.filters != null) { "snapper/filters/default.txt".text = cfg.filters; }); + }; - services.dbus.packages = [ pkgs.snapper ]; - - systemd.services.snapperd = { - description = "DBus interface for snapper"; - inherit documentation; - serviceConfig = { - Type = "dbus"; - BusName = "org.opensuse.Snapper"; - ExecStart = "${pkgs.snapper}/bin/snapperd"; - CapabilityBoundingSet = "CAP_DAC_OVERRIDE CAP_FOWNER CAP_CHOWN CAP_FSETID CAP_SETFCAP CAP_SYS_ADMIN CAP_SYS_MODULE CAP_IPC_LOCK CAP_SYS_NICE"; - LockPersonality = true; - NoNewPrivileges = false; - PrivateNetwork = true; - ProtectHostname = true; - RestrictAddressFamilies = "AF_UNIX"; - RestrictRealtime = true; + services.dbus.packages = [ pkgs.snapper ]; + + systemd.services.snapperd = { + description = "DBus interface for snapper"; + inherit documentation; + serviceConfig = { + Type = "dbus"; + BusName = "org.opensuse.Snapper"; + ExecStart = "${pkgs.snapper}/bin/snapperd"; + CapabilityBoundingSet = "CAP_DAC_OVERRIDE CAP_FOWNER CAP_CHOWN CAP_FSETID CAP_SETFCAP CAP_SYS_ADMIN CAP_SYS_MODULE CAP_IPC_LOCK CAP_SYS_NICE"; + LockPersonality = true; + NoNewPrivileges = false; + PrivateNetwork = true; + ProtectHostname = true; + RestrictAddressFamilies = "AF_UNIX"; + RestrictRealtime = true; + }; }; - }; - systemd.services.snapper-timeline = { - description = "Timeline of Snapper Snapshots"; - inherit documentation; - requires = [ "local-fs.target" ]; - serviceConfig.ExecStart = "${pkgs.snapper}/lib/snapper/systemd-helper --timeline"; - }; + systemd.services.snapper-timeline = { + description = "Timeline of Snapper Snapshots"; + inherit documentation; + requires = [ "local-fs.target" ]; + serviceConfig.ExecStart = "${pkgs.snapper}/lib/snapper/systemd-helper --timeline"; + }; - systemd.timers.snapper-timeline = { - wantedBy = [ "timers.target" ]; - timerConfig = { - Persistent = cfg.persistentTimer; - OnCalendar = cfg.snapshotInterval; + systemd.timers.snapper-timeline = { + wantedBy = [ "timers.target" ]; + timerConfig = { + Persistent = cfg.persistentTimer; + OnCalendar = cfg.snapshotInterval; + }; }; - }; - systemd.services.snapper-cleanup = { - description = "Cleanup of Snapper Snapshots"; - inherit documentation; - serviceConfig.ExecStart = "${pkgs.snapper}/lib/snapper/systemd-helper --cleanup"; - }; + systemd.services.snapper-cleanup = { + description = "Cleanup of Snapper Snapshots"; + inherit documentation; + serviceConfig.ExecStart = "${pkgs.snapper}/lib/snapper/systemd-helper --cleanup"; + }; - systemd.timers.snapper-cleanup = { - description = "Cleanup of Snapper Snapshots"; - inherit documentation; - wantedBy = [ "timers.target" ]; - requires = [ "local-fs.target" ]; - timerConfig.OnBootSec = "10m"; - timerConfig.OnUnitActiveSec = cfg.cleanupInterval; - }; + systemd.timers.snapper-cleanup = { + description = "Cleanup of Snapper Snapshots"; + inherit documentation; + wantedBy = [ "timers.target" ]; + requires = [ "local-fs.target" ]; + timerConfig.OnBootSec = "10m"; + timerConfig.OnUnitActiveSec = cfg.cleanupInterval; + }; - systemd.services.snapper-boot = lib.optionalAttrs cfg.snapshotRootOnBoot { - description = "Take snapper snapshot of root on boot"; - inherit documentation; - serviceConfig.ExecStart = "${pkgs.snapper}/bin/snapper --config root create --cleanup-algorithm number --description boot"; - serviceConfig.Type = "oneshot"; - requires = [ "local-fs.target" ]; - wantedBy = [ "multi-user.target" ]; - unitConfig.ConditionPathExists = "/etc/snapper/configs/root"; - }; + systemd.services.snapper-boot = lib.mkIf cfg.snapshotRootOnBoot { + description = "Take snapper snapshot of root on boot"; + inherit documentation; + serviceConfig.ExecStart = "${pkgs.snapper}/bin/snapper --config root create --cleanup-algorithm number --description boot"; + serviceConfig.Type = "oneshot"; + requires = [ "local-fs.target" ]; + wantedBy = [ "multi-user.target" ]; + unitConfig.ConditionPathExists = "/etc/snapper/configs/root"; + }; - assertions = - concatMap - (name: - let - sub = cfg.configs.${name}; - in - [ { assertion = !(sub ? extraConfig); - message = '' - The option definition `services.snapper.configs.${name}.extraConfig' no longer has any effect; please remove it. - The contents of this option should be migrated to attributes on `services.snapper.configs.${name}'. - ''; - } - ] ++ + assertions = concatMap ( + name: + let + sub = cfg.configs.${name}; + in + [ + { + assertion = !(sub ? extraConfig); + message = '' + The option definition `services.snapper.configs.${name}.extraConfig' no longer has any effect; please remove it. + The contents of this option should be migrated to attributes on `services.snapper.configs.${name}'. + ''; + } + ] + ++ map (attr: { assertion = !(hasAttr attr sub); @@ -265,8 +346,11 @@ in The option definition `services.snapper.configs.${name}.${attr}' has been renamed to `services.snapper.configs.${name}.${toUpper attr}'. ''; }) - [ "fstype" "subvolume" ] - ) - (attrNames cfg.configs); - }); + [ + "fstype" + "subvolume" + ] + ) (attrNames cfg.configs); + } + ); } diff --git a/nixpkgs/nixos/modules/services/misc/sourcehut/service.nix b/nixpkgs/nixos/modules/services/misc/sourcehut/service.nix index ce5a0e78627c..3507a49ea13a 100644 --- a/nixpkgs/nixos/modules/services/misc/sourcehut/service.nix +++ b/nixpkgs/nixos/modules/services/misc/sourcehut/service.nix @@ -324,7 +324,8 @@ in }; preStart = let - version = pkgs.sourcehut.${srvsrht}.version; + package = pkgs.sourcehut.${srvsrht}; + version = package.version; stateDir = "/var/lib/sourcehut/${srvsrht}"; in mkBefore '' @@ -336,14 +337,14 @@ in if test ! -e ${stateDir}/db; then # Setup the initial database. # Note that it stamps the alembic head afterward - ${cfg.python}/bin/${srvsrht}-initdb + ${package}/bin/${srvsrht}-initdb echo ${version} >${stateDir}/db fi ${optionalString cfg.settings.${iniKey}.migrate-on-upgrade '' if [ "$(cat ${stateDir}/db)" != "${version}" ]; then # Manage schema migrations using alembic - ${cfg.python}/bin/${srvsrht}-migrate -a upgrade head + ${package}/bin/${srvsrht}-migrate -a upgrade head echo ${version} >${stateDir}/db fi ''} @@ -389,7 +390,7 @@ in after = [ "network.target" "${srvsrht}.service" ]; serviceConfig = { Type = "oneshot"; - ExecStart = "${cfg.python}/bin/${timerName}"; + ExecStart = "${pkgs.sourcehut.${srvsrht}}/bin/${timerName}"; }; } (timer.service or { }) diff --git a/nixpkgs/nixos/modules/services/misc/spice-autorandr.nix b/nixpkgs/nixos/modules/services/misc/spice-autorandr.nix index 0d58d2865717..92b8a15e93c5 100644 --- a/nixpkgs/nixos/modules/services/misc/spice-autorandr.nix +++ b/nixpkgs/nixos/modules/services/misc/spice-autorandr.nix @@ -6,7 +6,7 @@ in { options = { services.spice-autorandr = { - enable = lib.mkEnableOption "spice-autorandr service that will automatically resize display to match SPICE client window size."; + enable = lib.mkEnableOption "spice-autorandr service that will automatically resize display to match SPICE client window size"; package = lib.mkPackageOption pkgs "spice-autorandr" { }; }; }; diff --git a/nixpkgs/nixos/modules/services/misc/tandoor-recipes.nix b/nixpkgs/nixos/modules/services/misc/tandoor-recipes.nix index a2210f3d7db5..1c903d280378 100644 --- a/nixpkgs/nixos/modules/services/misc/tandoor-recipes.nix +++ b/nixpkgs/nixos/modules/services/misc/tandoor-recipes.nix @@ -22,7 +22,7 @@ let ${lib.toShellVars env} eval "$(${config.systemd.package}/bin/systemctl show -pUID,GID,MainPID tandoor-recipes.service)" exec ${pkgs.util-linux}/bin/nsenter \ - -t $MainPID -m -S $UID -G $GID \ + -t $MainPID -m -S $UID -G $GID --wdns=${env.MEDIA_ROOT} \ ${pkg}/bin/tandoor-recipes "$@" ''; in @@ -88,7 +88,7 @@ in Group = "tandoor_recipes"; DynamicUser = true; StateDirectory = "tandoor-recipes"; - WorkingDirectory = "/var/lib/tandoor-recipes"; + WorkingDirectory = env.MEDIA_ROOT; RuntimeDirectory = "tandoor-recipes"; BindReadOnlyPaths = [ |