diff options
Diffstat (limited to 'nixos')
25 files changed, 354 insertions, 149 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index 27dd9a3d8cb29..9c5813904b77e 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -67,6 +67,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [RustDesk](https://rustdesk.com), a full-featured open source remote control alternative for self-hosting and security with minimal configuration. Alternative to TeamViewer. +- [systemd-lock-handler](https://git.sr.ht/~whynothugo/systemd-lock-handler/), a bridge between logind D-Bus events and systemd targets. Available as [services.systemd-lock-handler.enable](#opt-services.systemd-lock-handler.enable). + ## Backward Incompatibilities {#sec-release-24.05-incompatibilities} <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. --> @@ -85,6 +87,13 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `nitter` requires a `guest_accounts.jsonl` to be provided as a path or loaded into the default location at `/var/lib/nitter/guest_accounts.jsonl`. See [Guest Account Branch Deployment](https://github.com/zedeus/nitter/wiki/Guest-Account-Branch-Deployment) for details. +- `services.aria2.rpcSecret` has been replaced with `services.aria2.rpcSecretFile`. + This was done so that secrets aren't stored in the world-readable nix store. + To migrate, you will have create a file with the same exact string, and change + your module options to point to that file. For example, `services.aria2.rpcSecret = + "mysecret"` becomes `services.aria2.rpcSecretFile = "/path/to/secret_file"` + where the file `secret_file` contains the string `mysecret`. + - Invidious has changed its default database username from `kemal` to `invidious`. Setups involving an externally provisioned database (i.e. `services.invidious.database.createLocally == false`) should adjust their configuration accordingly. The old `kemal` user will not be removed automatically even when the database is provisioned automatically.(https://github.com/NixOS/nixpkgs/pull/265857) - `inetutils` now has a lower priority to avoid shadowing the commonly used `util-linux`. If one wishes to restore the default priority, simply use `lib.setPrio 5 inetutils` or override with `meta.priority = 5`. @@ -202,6 +211,13 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `nomad_1_4` has been removed, as it is now unsupported upstream. +- The `livebook` package is now built as a `mix release` instead of an `escript`. + This means that configuration now has to be done using [environment variables](https://hexdocs.pm/livebook/readme.html#environment-variables) instead of command line arguments. + This has the further implication that the `livebook` service configuration has changed: + + - The `erlang_node_short_name`, `erlang_node_name`, `port` and `options` configuration parameters are gone, and have been replaced with an `environment` parameter. + Use the appropriate [environment variables](https://hexdocs.pm/livebook/readme.html#environment-variables) inside `environment` to configure the service instead. + ## Other Notable Changes {#sec-release-24.05-notable-changes} <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. --> @@ -226,15 +242,15 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [Lilypond](https://lilypond.org/index.html) and [Denemo](https://www.denemo.org) are now compiled with Guile 3.0. -- The following options of the Nextcloud module were moved into [`services.nextcloud.extraOptions`](#opt-services.nextcloud.extraOptions) and renamed to match the name from Nextcloud's `config.php`: - - `logLevel` -> [`loglevel`](#opt-services.nextcloud.extraOptions.loglevel), - - `logType` -> [`log_type`](#opt-services.nextcloud.extraOptions.log_type), - - `defaultPhoneRegion` -> [`default_phone_region`](#opt-services.nextcloud.extraOptions.default_phone_region), - - `overwriteProtocol` -> [`overwriteprotocol`](#opt-services.nextcloud.extraOptions.overwriteprotocol), - - `skeletonDirectory` -> [`skeletondirectory`](#opt-services.nextcloud.extraOptions.skeletondirectory), - - `globalProfiles` -> [`profile.enabled`](#opt-services.nextcloud.extraOptions._profile.enabled_), - - `extraTrustedDomains` -> [`trusted_domains`](#opt-services.nextcloud.extraOptions.trusted_domains) and - - `trustedProxies` -> [`trusted_proxies`](#opt-services.nextcloud.extraOptions.trusted_proxies). +- The following options of the Nextcloud module were moved into [`services.nextcloud.settings`](#opt-services.nextcloud.settings) and renamed to match the name from Nextcloud's `config.php`: + - `logLevel` -> [`loglevel`](#opt-services.nextcloud.settings.loglevel), + - `logType` -> [`log_type`](#opt-services.nextcloud.settings.log_type), + - `defaultPhoneRegion` -> [`default_phone_region`](#opt-services.nextcloud.settings.default_phone_region), + - `overwriteProtocol` -> [`overwriteprotocol`](#opt-services.nextcloud.settings.overwriteprotocol), + - `skeletonDirectory` -> [`skeletondirectory`](#opt-services.nextcloud.settings.skeletondirectory), + - `globalProfiles` -> [`profile.enabled`](#opt-services.nextcloud.settings._profile.enabled_), + - `extraTrustedDomains` -> [`trusted_domains`](#opt-services.nextcloud.settings.trusted_domains) and + - `trustedProxies` -> [`trusted_proxies`](#opt-services.nextcloud.settings.trusted_proxies). - The option [`services.nextcloud.config.dbport`] of the Nextcloud module was removed to match upstream. The port can be specified in [`services.nextcloud.config.dbhost`](#opt-services.nextcloud.config.dbhost). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index c2bcb2f780806..71498e397cb65 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -214,6 +214,7 @@ ./programs/minipro.nix ./programs/miriway.nix ./programs/mosh.nix + ./programs/mouse-actions.nix ./programs/msmtp.nix ./programs/mtr.nix ./programs/nano.nix @@ -1235,6 +1236,7 @@ ./services/system/saslauthd.nix ./services/system/self-deploy.nix ./services/system/systembus-notify.nix + ./services/system/systemd-lock-handler.nix ./services/system/uptimed.nix ./services/system/zram-generator.nix ./services/torrent/deluge.nix diff --git a/nixos/modules/programs/gamemode.nix b/nixos/modules/programs/gamemode.nix index 344f392852e2a..2bb92ed8e0efd 100644 --- a/nixos/modules/programs/gamemode.nix +++ b/nixos/modules/programs/gamemode.nix @@ -90,6 +90,8 @@ in ]; }; }; + + users.groups.gamemode = { }; }; meta = { diff --git a/nixos/modules/programs/mouse-actions.nix b/nixos/modules/programs/mouse-actions.nix new file mode 100644 index 0000000000000..fdf39d56d3838 --- /dev/null +++ b/nixos/modules/programs/mouse-actions.nix @@ -0,0 +1,15 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.programs.mouse-actions; +in + { + options.programs.mouse-actions = { + enable = lib.mkEnableOption '' + mouse-actions udev rules. This is a prerequisite for using mouse-actions without being root. + ''; + }; + config = lib.mkIf cfg.enable { + services.udev.packages = [ pkgs.mouse-actions ]; + }; + } diff --git a/nixos/modules/services/audio/navidrome.nix b/nixos/modules/services/audio/navidrome.nix index e44fc822e4add..912edb03aa4c9 100644 --- a/nixos/modules/services/audio/navidrome.nix +++ b/nixos/modules/services/audio/navidrome.nix @@ -53,6 +53,7 @@ in { RuntimeDirectory = "navidrome"; RootDirectory = "/run/navidrome"; ReadWritePaths = ""; + BindPaths = lib.optional (cfg.settings ? DataFolder) cfg.settings.DataFolder; BindReadOnlyPaths = [ # navidrome uses online services to download additional album metadata / covers "${config.environment.etc."ssl/certs/ca-certificates.crt".source}:/etc/ssl/certs/ca-certificates.crt" diff --git a/nixos/modules/services/development/livebook.md b/nixos/modules/services/development/livebook.md index 5012e977a4f7f..5315f2c2755a0 100644 --- a/nixos/modules/services/development/livebook.md +++ b/nixos/modules/services/development/livebook.md @@ -15,11 +15,12 @@ which runs the server. { services.livebook = { enableUserService = true; - port = 20123; + environment = { + LIVEBOOK_PORT = 20123; + LIVEBOOK_PASSWORD = "mypassword"; + }; # See note below about security - environmentFile = pkgs.writeText "livebook.env" '' - LIVEBOOK_PASSWORD = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - ''; + environmentFile = "/var/lib/livebook.env"; }; } ``` @@ -30,14 +31,19 @@ The Livebook server has the ability to run any command as the user it is running under, so securing access to it with a password is highly recommended. -Putting the password in the Nix configuration like above is an easy -way to get started but it is not recommended in the real world because -the `livebook.env` file will be added to the world-readable Nix store. -A better approach would be to put the password in some secure -user-readable location and set `environmentFile = /home/user/secure/livebook.env`. +Putting the password in the Nix configuration like above is an easy way to get +started but it is not recommended in the real world because the resulting +environment variables can be read by unprivileged users. A better approach +would be to put the password in some secure user-readable location and set +`environmentFile = /home/user/secure/livebook.env`. ::: +The [Livebook +documentation](https://hexdocs.pm/livebook/readme.html#environment-variables) +lists all the applicable environment variables. It is recommended to at least +set `LIVEBOOK_PASSWORD` or `LIVEBOOK_TOKEN_ENABLED=false`. + ### Extra dependencies {#module-services-livebook-extra-dependencies} By default, the Livebook service is run with minimum dependencies, but diff --git a/nixos/modules/services/development/livebook.nix b/nixos/modules/services/development/livebook.nix index 75729ff28efaf..df0e6e01e97c7 100644 --- a/nixos/modules/services/development/livebook.nix +++ b/nixos/modules/services/development/livebook.nix @@ -14,58 +14,64 @@ in package = mkPackageOption pkgs "livebook" { }; - environmentFile = mkOption { - type = types.path; + environment = mkOption { + type = with types; attrsOf (nullOr (oneOf [ bool int str ])); + default = { }; description = lib.mdDoc '' - Environment file as defined in {manpage}`systemd.exec(5)` passed to the service. + Environment variables to set. - This must contain at least `LIVEBOOK_PASSWORD` or - `LIVEBOOK_TOKEN_ENABLED=false`. See `livebook server --help` - for other options.''; - }; + Livebook is configured through the use of environment variables. The + available configuration options can be found in the [Livebook + documentation](https://hexdocs.pm/livebook/readme.html#environment-variables). - erlang_node_short_name = mkOption { - type = with types; nullOr str; - default = null; - example = "livebook"; - description = "A short name for the distributed node."; - }; + Note that all environment variables set through this configuration + parameter will be readable by anyone with access to the host + machine. Therefore, sensitive information like {env}`LIVEBOOK_PASSWORD` + or {env}`LIVEBOOK_COOKIE` should never be set using this configuration + option, but should instead use + [](#opt-services.livebook.environmentFile). See the documentation for + that option for more information. - erlang_node_name = mkOption { - type = with types; nullOr str; - default = null; - example = "livebook@127.0.0.1"; - description = "The name for the app distributed node."; - }; - - port = mkOption { - type = types.port; - default = 8080; - description = "The port to start the web application on."; - }; - - address = mkOption { - type = types.str; - default = "127.0.0.1"; - description = lib.mdDoc '' - The address to start the web application on. Must be a valid IPv4 or - IPv6 address. + Any environment variables specified in the + [](#opt-services.livebook.environmentFile) will supersede environment + variables specified in this option. ''; - }; - options = mkOption { - type = with types; attrsOf str; - default = { }; - description = lib.mdDoc '' - Additional options to pass as command-line arguments to the server. - ''; example = literalExpression '' { - cookie = "a value shared by all nodes in this cluster"; + LIVEBOOK_PORT = 8080; } ''; }; + environmentFile = mkOption { + type = with types; nullOr types.path; + default = null; + description = lib.mdDoc '' + Additional dnvironment file as defined in {manpage}`systemd.exec(5)`. + + Secrets like {env}`LIVEBOOK_PASSWORD` (which is used to specify the + password needed to access the livebook site) or {env}`LIVEBOOK_COOKIE` + (which is used to specify the + [cookie](https://www.erlang.org/doc/reference_manual/distributed.html#security) + used to connect to the running Elixir system) may be passed to the + service without making them readable to everyone with access to + systemctl by using this configuration parameter. + + Note that this file needs to be available on the host on which + `livebook` is running. + + For security purposes, this file should contain at least + {env}`LIVEBOOK_PASSWORD` or {env}`LIVEBOOK_TOKEN_ENABLED=false`. + + See the [Livebook + documentation](https://hexdocs.pm/livebook/readme.html#environment-variables) + and the [](#opt-services.livebook.environment) configuration parameter + for further options. + ''; + example = "/var/lib/livebook.env"; + }; + extraPackages = mkOption { type = with types; listOf package; default = [ ]; @@ -81,17 +87,12 @@ in serviceConfig = { Restart = "always"; EnvironmentFile = cfg.environmentFile; - ExecStart = - let - args = lib.cli.toGNUCommandLineShell { } ({ - inherit (cfg) port; - ip = cfg.address; - name = cfg.erlang_node_name; - sname = cfg.erlang_node_short_name; - } // cfg.options); - in - "${cfg.package}/bin/livebook server ${args}"; + ExecStart = "${cfg.package}/bin/livebook start"; + KillMode = "mixed"; }; + environment = mapAttrs (name: value: + if isBool value then boolToString value else toString value) + cfg.environment; path = [ pkgs.bash ] ++ cfg.extraPackages; wantedBy = [ "default.target" ]; }; diff --git a/nixos/modules/services/hardware/ratbagd.nix b/nixos/modules/services/hardware/ratbagd.nix index c939d5e40a24e..5567bcbafd160 100644 --- a/nixos/modules/services/hardware/ratbagd.nix +++ b/nixos/modules/services/hardware/ratbagd.nix @@ -11,6 +11,8 @@ in options = { services.ratbagd = { enable = mkEnableOption (lib.mdDoc "ratbagd for configuring gaming mice"); + + package = mkPackageOption pkgs "libratbag" { }; }; }; @@ -18,10 +20,10 @@ in config = mkIf cfg.enable { # Give users access to the "ratbagctl" tool - environment.systemPackages = [ pkgs.libratbag ]; + environment.systemPackages = [ cfg.package ]; - services.dbus.packages = [ pkgs.libratbag ]; + services.dbus.packages = [ cfg.package ]; - systemd.packages = [ pkgs.libratbag ]; + systemd.packages = [ cfg.package ]; }; } diff --git a/nixos/modules/services/home-automation/esphome.nix b/nixos/modules/services/home-automation/esphome.nix index 4fc007a976838..3c0fd8aed08a4 100644 --- a/nixos/modules/services/home-automation/esphome.nix +++ b/nixos/modules/services/home-automation/esphome.nix @@ -63,6 +63,12 @@ in ''; type = types.listOf types.str; }; + + usePing = mkOption { + default = false; + type = types.bool; + description = lib.mdDoc "Use ping to check online status of devices instead of mDNS"; + }; }; config = mkIf cfg.enable { @@ -74,8 +80,10 @@ in wantedBy = ["multi-user.target"]; path = [cfg.package]; - # platformio fails to determine the home directory when using DynamicUser - environment.PLATFORMIO_CORE_DIR = "${stateDir}/.platformio"; + environment = { + # platformio fails to determine the home directory when using DynamicUser + PLATFORMIO_CORE_DIR = "${stateDir}/.platformio"; + } // lib.optionalAttrs cfg.usePing { ESPHOME_DASHBOARD_USE_PING = "true"; }; serviceConfig = { ExecStart = "${cfg.package}/bin/esphome dashboard ${esphomeParams} ${stateDir}"; diff --git a/nixos/modules/services/misc/portunus.nix b/nixos/modules/services/misc/portunus.nix index 47af24f024cdf..ebb3bc8f08518 100644 --- a/nixos/modules/services/misc/portunus.nix +++ b/nixos/modules/services/misc/portunus.nix @@ -37,6 +37,15 @@ in ''; }; + seedSettings = lib.mkOption { + type = with lib.types; nullOr (attrsOf (listOf (attrsOf anything))); + default = null; + description = lib.mdDoc '' + Seed settings for users and groups. + See upstream for format <https://github.com/majewsky/portunus#seeding-users-and-groups-from-static-configuration> + ''; + }; + stateDir = mkOption { type = types.path; default = "/var/lib/portunus"; @@ -172,49 +181,53 @@ in "127.0.0.1" = [ cfg.domain ]; }; - services.dex = mkIf cfg.dex.enable { - enable = true; - settings = { - issuer = "https://${cfg.domain}/dex"; - web.http = "127.0.0.1:${toString cfg.dex.port}"; - storage = { - type = "sqlite3"; - config.file = "/var/lib/dex/dex.db"; - }; - enablePasswordDB = false; - connectors = [{ - type = "ldap"; - id = "ldap"; - name = "LDAP"; - config = { - host = "${cfg.domain}:636"; - bindDN = "uid=${cfg.ldap.searchUserName},ou=users,${cfg.ldap.suffix}"; - bindPW = "$DEX_SEARCH_USER_PASSWORD"; - userSearch = { - baseDN = "ou=users,${cfg.ldap.suffix}"; - filter = "(objectclass=person)"; - username = "uid"; - idAttr = "uid"; - emailAttr = "mail"; - nameAttr = "cn"; - preferredUsernameAttr = "uid"; - }; - groupSearch = { - baseDN = "ou=groups,${cfg.ldap.suffix}"; - filter = "(objectclass=groupOfNames)"; - nameAttr = "cn"; - userMatchers = [{ userAttr = "DN"; groupAttr = "member"; }]; - }; + services = { + dex = mkIf cfg.dex.enable { + enable = true; + settings = { + issuer = "https://${cfg.domain}/dex"; + web.http = "127.0.0.1:${toString cfg.dex.port}"; + storage = { + type = "sqlite3"; + config.file = "/var/lib/dex/dex.db"; }; - }]; - - staticClients = forEach cfg.dex.oidcClients (client: { - inherit (client) id; - redirectURIs = [ client.callbackURL ]; - name = "OIDC for ${client.id}"; - secretEnv = "DEX_CLIENT_${client.id}"; - }); + enablePasswordDB = false; + connectors = [{ + type = "ldap"; + id = "ldap"; + name = "LDAP"; + config = { + host = "${cfg.domain}:636"; + bindDN = "uid=${cfg.ldap.searchUserName},ou=users,${cfg.ldap.suffix}"; + bindPW = "$DEX_SEARCH_USER_PASSWORD"; + userSearch = { + baseDN = "ou=users,${cfg.ldap.suffix}"; + filter = "(objectclass=person)"; + username = "uid"; + idAttr = "uid"; + emailAttr = "mail"; + nameAttr = "cn"; + preferredUsernameAttr = "uid"; + }; + groupSearch = { + baseDN = "ou=groups,${cfg.ldap.suffix}"; + filter = "(objectclass=groupOfNames)"; + nameAttr = "cn"; + userMatchers = [{ userAttr = "DN"; groupAttr = "member"; }]; + }; + }; + }]; + + staticClients = forEach cfg.dex.oidcClients (client: { + inherit (client) id; + redirectURIs = [ client.callbackURL ]; + name = "OIDC for ${client.id}"; + secretEnv = "DEX_CLIENT_${client.id}"; + }); + }; }; + + portunus.seedPath = lib.mkIf (cfg.seedSettings != null) (pkgs.writeText "seed.json" (builtins.toJSON cfg.seedSettings)); }; systemd.services = { diff --git a/nixos/modules/services/networking/aria2.nix b/nixos/modules/services/networking/aria2.nix index e848869cc0ac1..1fb55b8367981 100644 --- a/nixos/modules/services/networking/aria2.nix +++ b/nixos/modules/services/networking/aria2.nix @@ -18,11 +18,14 @@ let dir=${cfg.downloadDir} listen-port=${concatStringsSep "," (rangesToStringList cfg.listenPortRange)} rpc-listen-port=${toString cfg.rpcListenPort} - rpc-secret=${cfg.rpcSecret} ''; in { + imports = [ + (mkRemovedOptionModule [ "services" "aria2" "rpcSecret" ] "Use services.aria2.rpcSecretFile instead") + ]; + options = { services.aria2 = { enable = mkOption { @@ -65,11 +68,11 @@ in default = 6800; description = lib.mdDoc "Specify a port number for JSON-RPC/XML-RPC server to listen to. Possible Values: 1024-65535"; }; - rpcSecret = mkOption { - type = types.str; - default = "aria2rpc"; + rpcSecretFile = mkOption { + type = types.path; + example = "/run/secrets/aria2-rpc-token.txt"; description = lib.mdDoc '' - Set RPC secret authorization token. + A file containing the RPC secret authorization token. Read https://aria2.github.io/manual/en/html/aria2c.html#rpc-auth to know how this option value is used. ''; }; @@ -117,6 +120,7 @@ in touch "${sessionFile}" fi cp -f "${settingsFile}" "${settingsDir}/aria2.conf" + echo "rpc-secret=$(cat "$CREDENTIALS_DIRECTORY/rpcSecretFile")" >> "${settingsDir}/aria2.conf" ''; serviceConfig = { @@ -125,6 +129,7 @@ in ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; User = "aria2"; Group = "aria2"; + LoadCredential="rpcSecretFile:${cfg.rpcSecretFile}"; }; }; }; diff --git a/nixos/modules/services/networking/tailscale.nix b/nixos/modules/services/networking/tailscale.nix index 1070e4e252967..f11fe57d6ce5e 100644 --- a/nixos/modules/services/networking/tailscale.nix +++ b/nixos/modules/services/networking/tailscale.nix @@ -74,11 +74,10 @@ in { systemd.services.tailscaled = { wantedBy = [ "multi-user.target" ]; path = [ - config.networking.resolvconf.package # for configuring DNS in some configs pkgs.procps # for collecting running services (opt-in feature) pkgs.getent # for `getent` to look up user shells pkgs.kmod # required to pass tailscale's v6nat check - ]; + ] ++ lib.optional config.networking.resolvconf.enable config.networking.resolvconf.package; serviceConfig.Environment = [ "PORT=${toString cfg.port}" ''"FLAGS=--tun ${lib.escapeShellArg cfg.interfaceName}"'' diff --git a/nixos/modules/services/system/systemd-lock-handler.md b/nixos/modules/services/system/systemd-lock-handler.md new file mode 100644 index 0000000000000..ac9ee00ae4bcc --- /dev/null +++ b/nixos/modules/services/system/systemd-lock-handler.md @@ -0,0 +1,47 @@ +# systemd-lock-handler {#module-services-systemd-lock-handler} + +The `systemd-lock-handler` module provides a service that bridges +D-Bus events from `logind` to user-level systemd targets: + + - `lock.target` started by `loginctl lock-session`, + - `unlock.target` started by `loginctl unlock-session` and + - `sleep.target` started by `systemctl suspend`. + +You can create a user service that starts with any of these targets. + +For example, to create a service for `swaylock`: + +```nix +{ + services.systemd-lock-handler.enable = true; + + systemd.user.services.swaylock = { + description = "Screen locker for Wayland"; + documentation = ["man:swaylock(1)"]; + + # If swaylock exits cleanly, unlock the session: + onSuccess = ["unlock.target"]; + + # When lock.target is stopped, stops this too: + partOf = ["lock.target"]; + + # Delay lock.target until this service is ready: + before = ["lock.target"]; + wantedBy = ["lock.target"]; + + serviceConfig = { + # systemd will consider this service started when swaylock forks... + Type = "forking"; + + # ... and swaylock will fork only after it has locked the screen. + ExecStart = "${lib.getExe pkgs.swaylock} -f"; + + # If swaylock crashes, always restart it immediately: + Restart = "on-failure"; + RestartSec = 0; + }; + }; +} +``` + +See [upstream documentation](https://sr.ht/~whynothugo/systemd-lock-handler) for more information. diff --git a/nixos/modules/services/system/systemd-lock-handler.nix b/nixos/modules/services/system/systemd-lock-handler.nix new file mode 100644 index 0000000000000..1ecb13b75bb3e --- /dev/null +++ b/nixos/modules/services/system/systemd-lock-handler.nix @@ -0,0 +1,27 @@ +{ config +, pkgs +, lib +, ... +}: +let + cfg = config.services.systemd-lock-handler; + inherit (lib) mkIf mkEnableOption mkPackageOption; +in +{ + options.services.systemd-lock-handler = { + enable = mkEnableOption (lib.mdDoc "systemd-lock-handler"); + package = mkPackageOption pkgs "systemd-lock-handler" { }; + }; + + config = mkIf cfg.enable { + systemd.packages = [ cfg.package ]; + + # https://github.com/NixOS/nixpkgs/issues/81138 + systemd.user.services.systemd-lock-handler.wantedBy = [ "default.target" ]; + }; + + meta = { + maintainers = with lib.maintainers; [ liff ]; + doc = ./systemd-lock-handler.md; + }; +} diff --git a/nixos/modules/services/web-apps/nextcloud-notify_push.nix b/nixos/modules/services/web-apps/nextcloud-notify_push.nix index 759daa0c50dce..7b90e0bbaa9b6 100644 --- a/nixos/modules/services/web-apps/nextcloud-notify_push.nix +++ b/nixos/modules/services/web-apps/nextcloud-notify_push.nix @@ -116,7 +116,7 @@ in } (lib.mkIf cfg.bendDomainToLocalhost { - nextcloud.extraOptions.trusted_proxies = [ "127.0.0.1" "::1" ]; + nextcloud.settings.trusted_proxies = [ "127.0.0.1" "::1" ]; }) ]; }; diff --git a/nixos/modules/services/web-apps/nextcloud.md b/nixos/modules/services/web-apps/nextcloud.md index ce8f96a6a3896..5db83d7e44634 100644 --- a/nixos/modules/services/web-apps/nextcloud.md +++ b/nixos/modules/services/web-apps/nextcloud.md @@ -51,7 +51,7 @@ to ensure that changes can be applied by changing the module's options. In case the application serves multiple domains (those are checked with [`$_SERVER['HTTP_HOST']`](https://www.php.net/manual/en/reserved.variables.server.php)) it's needed to add them to -[`services.nextcloud.extraOptions.trusted_domains`](#opt-services.nextcloud.extraOptions.trusted_domains). +[`services.nextcloud.settings.trusted_domains`](#opt-services.nextcloud.settings.trusted_domains). Auto updates for Nextcloud apps can be enabled using [`services.nextcloud.autoUpdateApps`](#opt-services.nextcloud.autoUpdateApps.enable). diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix index 0b19265942c03..8669f84b1cbb5 100644 --- a/nixos/modules/services/web-apps/nextcloud.nix +++ b/nixos/modules/services/web-apps/nextcloud.nix @@ -183,8 +183,8 @@ let ]; $CONFIG = array_replace_recursive($CONFIG, nix_decode_json_file( - "${jsonFormat.generate "nextcloud-extraOptions.json" cfg.extraOptions}", - "impossible: this should never happen (decoding generated extraOptions file %s failed)" + "${jsonFormat.generate "nextcloud-settings.json" cfg.settings}", + "impossible: this should never happen (decoding generated settings file %s failed)" )); ${optionalString (cfg.secretFile != null) '' @@ -205,21 +205,22 @@ in { Add port to services.nextcloud.config.dbhost instead. '') (mkRenamedOptionModule - [ "services" "nextcloud" "logLevel" ] [ "services" "nextcloud" "extraOptions" "loglevel" ]) + [ "services" "nextcloud" "logLevel" ] [ "services" "nextcloud" "settings" "loglevel" ]) (mkRenamedOptionModule - [ "services" "nextcloud" "logType" ] [ "services" "nextcloud" "extraOptions" "log_type" ]) + [ "services" "nextcloud" "logType" ] [ "services" "nextcloud" "settings" "log_type" ]) (mkRenamedOptionModule - [ "services" "nextcloud" "config" "defaultPhoneRegion" ] [ "services" "nextcloud" "extraOptions" "default_phone_region" ]) + [ "services" "nextcloud" "config" "defaultPhoneRegion" ] [ "services" "nextcloud" "settings" "default_phone_region" ]) (mkRenamedOptionModule - [ "services" "nextcloud" "config" "overwriteProtocol" ] [ "services" "nextcloud" "extraOptions" "overwriteprotocol" ]) + [ "services" "nextcloud" "config" "overwriteProtocol" ] [ "services" "nextcloud" "settings" "overwriteprotocol" ]) (mkRenamedOptionModule - [ "services" "nextcloud" "skeletonDirectory" ] [ "services" "nextcloud" "extraOptions" "skeletondirectory" ]) + [ "services" "nextcloud" "skeletonDirectory" ] [ "services" "nextcloud" "settings" "skeletondirectory" ]) (mkRenamedOptionModule - [ "services" "nextcloud" "globalProfiles" ] [ "services" "nextcloud" "extraOptions" "profile.enabled" ]) + [ "services" "nextcloud" "globalProfiles" ] [ "services" "nextcloud" "settings" "profile.enabled" ]) (mkRenamedOptionModule - [ "services" "nextcloud" "config" "extraTrustedDomains" ] [ "services" "nextcloud" "extraOptions" "trusted_domains" ]) + [ "services" "nextcloud" "config" "extraTrustedDomains" ] [ "services" "nextcloud" "settings" "trusted_domains" ]) (mkRenamedOptionModule - [ "services" "nextcloud" "config" "trustedProxies" ] [ "services" "nextcloud" "extraOptions" "trusted_proxies" ]) + [ "services" "nextcloud" "config" "trustedProxies" ] [ "services" "nextcloud" "settings" "trusted_proxies" ]) + (mkRenamedOptionModule ["services" "nextcloud" "extraOptions" ] [ "services" "nextcloud" "settings" ]) ]; options.services.nextcloud = { @@ -648,7 +649,7 @@ in { ''; }; - extraOptions = mkOption { + settings = mkOption { type = types.submodule { freeformType = jsonFormat.type; options = { @@ -770,7 +771,7 @@ in { default = null; description = lib.mdDoc '' Secret options which will be appended to Nextcloud's config.php file (written as JSON, in the same - form as the [](#opt-services.nextcloud.extraOptions) option), for example + form as the [](#opt-services.nextcloud.settings) option), for example `{"redis":{"password":"secret"}}`. ''; }; @@ -930,7 +931,7 @@ in { (i: v: '' ${occ}/bin/nextcloud-occ config:system:set trusted_domains \ ${toString i} --value="${toString v}" - '') ([ cfg.hostName ] ++ cfg.extraOptions.trusted_domains)); + '') ([ cfg.hostName ] ++ cfg.settings.trusted_domains)); in { wantedBy = [ "multi-user.target" ]; @@ -1056,7 +1057,7 @@ in { services.nextcloud = { caching.redis = lib.mkIf cfg.configureRedis true; - extraOptions = mkMerge [({ + settings = mkMerge [({ datadirectory = lib.mkDefault "${datadir}/data"; trusted_domains = [ cfg.hostName ]; }) (lib.mkIf cfg.configureRedis { diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix index fc9de2500ba46..38c858aaef053 100644 --- a/nixos/modules/services/x11/desktop-managers/plasma5.nix +++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix @@ -480,7 +480,7 @@ in pkgs.maliit-framework pkgs.maliit-keyboard ] - ++ lib.optionals (cfg.mobile.installRecommendedSoftware) (with libsForQt5.plasmaMobileGear;[ + ++ lib.optionals (cfg.mobile.installRecommendedSoftware) (with pkgs.plasma5Packages.plasmaMobileGear; [ # Additional software made for Plasma Mobile. alligator angelfish diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix index 3b140726c2d6a..a126a6725e1b0 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix @@ -54,17 +54,18 @@ let checkedSystemdBootBuilder = pkgs.runCommand "systemd-boot" { nativeBuildInputs = [ pkgs.mypy ]; } '' - install -m755 ${systemdBootBuilder} $out + mkdir -p $out/bin + install -m755 ${systemdBootBuilder} $out/bin/systemd-boot-builder mypy \ --no-implicit-optional \ --disallow-untyped-calls \ --disallow-untyped-defs \ - $out + $out/bin/systemd-boot-builder ''; finalSystemdBootBuilder = pkgs.writeScript "install-systemd-boot.sh" '' #!${pkgs.runtimeShell} - ${checkedSystemdBootBuilder} "$@" + ${checkedSystemdBootBuilder}/bin/systemd-boot-builder "$@" ${cfg.extraInstallCommands} ''; in { diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 3f9dd173d3bf4..81bd36cf0e345 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -856,6 +856,7 @@ in { systemd-journal = handleTest ./systemd-journal.nix {}; systemd-journal-gateway = handleTest ./systemd-journal-gateway.nix {}; systemd-journal-upload = handleTest ./systemd-journal-upload.nix {}; + systemd-lock-handler = runTestOn ["aarch64-linux" "x86_64-linux"] ./systemd-lock-handler.nix; systemd-machinectl = handleTest ./systemd-machinectl.nix {}; systemd-networkd = handleTest ./systemd-networkd.nix {}; systemd-networkd-dhcpserver = handleTest ./systemd-networkd-dhcpserver.nix {}; diff --git a/nixos/tests/livebook-service.nix b/nixos/tests/livebook-service.nix index 56b4eb932f343..f428412e16448 100644 --- a/nixos/tests/livebook-service.nix +++ b/nixos/tests/livebook-service.nix @@ -9,13 +9,15 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: { services.livebook = { enableUserService = true; - port = 20123; + environment = { + LIVEBOOK_PORT = 20123; + LIVEBOOK_COOKIE = "chocolate chip"; + LIVEBOOK_TOKEN_ENABLED = true; + + }; environmentFile = pkgs.writeText "livebook.env" '' LIVEBOOK_PASSWORD = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ''; - options = { - cookie = "chocolate chip"; - }; }; }; }; diff --git a/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix b/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix index addc898bd7602..b09ee1276a136 100644 --- a/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix +++ b/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix @@ -41,7 +41,7 @@ in { }; secretFile = "/etc/nextcloud-secrets.json"; - extraOptions = { + settings = { allow_local_remote_servers = true; redis = { dbindex = 0; diff --git a/nixos/tests/nextcloud/with-postgresql-and-redis.nix b/nixos/tests/nextcloud/with-postgresql-and-redis.nix index d95af8a89d07a..3c090f0d3c3b7 100644 --- a/nixos/tests/nextcloud/with-postgresql-and-redis.nix +++ b/nixos/tests/nextcloud/with-postgresql-and-redis.nix @@ -41,7 +41,7 @@ in { extraApps = { inherit (pkgs."nextcloud${lib.versions.major config.services.nextcloud.package.version}Packages".apps) notify_push; }; - extraOptions.trusted_proxies = [ "::1" ]; + settings.trusted_proxies = [ "::1" ]; }; services.redis.servers."nextcloud".enable = true; diff --git a/nixos/tests/pomerium.nix b/nixos/tests/pomerium.nix index abaf56c518e05..d0204488e8efd 100644 --- a/nixos/tests/pomerium.nix +++ b/nixos/tests/pomerium.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "pomerium"; meta = with lib.maintainers; { - maintainers = [ lukegb ]; + maintainers = [ lukegb devusb ]; }; nodes = let base = myIP: { pkgs, lib, ... }: { @@ -103,7 +103,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { with subtest("ui"): pomerium.succeed( # check for a string that only appears if the UI is displayed correctly - "chromium --no-sandbox --headless --disable-gpu --dump-dom --host-resolver-rules='MAP login.required 127.0.0.1:80' http://login.required/.pomerium | grep 'contact your administrator'" + "chromium --no-sandbox --headless --disable-gpu --dump-dom --host-resolver-rules='MAP login.required 127.0.0.1:80' http://login.required/.pomerium | grep 'User Details Not Available'" ) ''; }) diff --git a/nixos/tests/systemd-lock-handler.nix b/nixos/tests/systemd-lock-handler.nix new file mode 100644 index 0000000000000..d6fb8f5459004 --- /dev/null +++ b/nixos/tests/systemd-lock-handler.nix @@ -0,0 +1,56 @@ +{ lib, ... }: { + name = "systemd-lock-handler"; + + meta.maintainers = with lib.maintainers; [ liff ]; + + enableOCR = true; + + nodes.machine = { config, pkgs, lib, ... }: + let + touch = "${lib.getBin pkgs.coreutils}/bin/touch"; + in + { + imports = [ common/wayland-cage.nix ]; + + services.systemd-lock-handler.enable = true; + + systemd.user.services = { + test-lock = { + partOf = [ "lock.target" ]; + onSuccess = [ "unlock.target" ]; + before = [ "lock.target" ]; + wantedBy = [ "lock.target" ]; + serviceConfig.ExecStart = "${touch} /tmp/lock.target.activated"; + }; + test-unlock = { + partOf = [ "unlock.target" ]; + after = [ "unlock.target" ]; + wantedBy = [ "unlock.target" ]; + serviceConfig.ExecStart = "${touch} /tmp/unlock.target.activated"; + }; + test-sleep = { + partOf = [ "sleep.target" ]; + before = [ "sleep.target" ]; + wantedBy = [ "sleep.target" ]; + serviceConfig.ExecStart = "${touch} /tmp/sleep.target.activated"; + }; + }; + }; + + testScript = '' + machine.wait_for_unit('graphical.target') + machine.wait_for_text('alice@machine') + + machine.send_chars('loginctl lock-session\n') + machine.wait_for_file('/tmp/lock.target.activated') + machine.wait_for_file('/tmp/unlock.target.activated') + + machine.send_chars('systemctl suspend\n') + # wait_for_file won’t complete before the machine is asleep, + # so we’ll watch the log instead. + machine.wait_for_console_text('Started test-sleep.service.') + + # The VM is asleep, regular shutdown won’t work. + machine.crash() + ''; +} |