From fdb2ccba9d5e1238d32e0c4a3ec1a277efa80c1d Mon Sep 17 00:00:00 2001 From: cinereal Date: Tue, 5 May 2026 11:24:43 +0200 Subject: [PATCH] modular-services: document ghostunnel as a service that was not written for use as a user-level service Signed-off-by: cinereal --- docs/manual/usage/modular-services.md | 16 ++++++++++++++++ tests/modules/services-modular/ghostunnel.nix | 11 +++++++---- tests/modules/services-modular/tunnel.service | 16 ++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 tests/modules/services-modular/tunnel.service diff --git a/docs/manual/usage/modular-services.md b/docs/manual/usage/modular-services.md index ff0270a5f..aa79cb59b 100644 --- a/docs/manual/usage/modular-services.md +++ b/docs/manual/usage/modular-services.md @@ -62,6 +62,22 @@ For example, `pkgs.php`'s [`php-fpm`]: } ``` +Some packages ship modules written for system services that include +directives the user-session manager cannot honour (`DynamicUser`, +`AmbientCapabilities`, ...). The unit is still generated with those +directives -- user systemd silently ignores what it cannot apply. +`WantedBy=multi-user.target` is automatically normalized to +`WantedBy=default.target`. Other directives can be overridden per +service: + +```nix +home.services."tunnel" = { + imports = [ pkgs.ghostunnel.passthru.services.default ]; + # ... + systemd.services."tunnel".serviceConfig.DynamicUser = lib.mkForce false; +}; +``` + ## Configuration data {#sec-usage-modular-services-configdata} Each service can declare configuration files via `configData.`. diff --git a/tests/modules/services-modular/ghostunnel.nix b/tests/modules/services-modular/ghostunnel.nix index 2465f8e35..eadeafc31 100644 --- a/tests/modules/services-modular/ghostunnel.nix +++ b/tests/modules/services-modular/ghostunnel.nix @@ -1,3 +1,9 @@ +# Smoke test that an upstream system-shape portable service module drops in +# unchanged. The generated unit intentionally contains system-oriented +# directives (`AmbientCapabilities`, `DynamicUser`) inherited from the upstream +# ghostunnel module; user systemd silently ignores the ones it cannot honour. +# `WantedBy=multi-user.target` is normalized to `default.target` by the +# translator. For a service meant to run as a user see `php-fpm.nix`. { pkgs, ... }: { home.services.tunnel = { @@ -12,9 +18,6 @@ }; nmt.script = '' - assertFileExists home-files/.config/systemd/user/tunnel.service - assertFileContains home-files/.config/systemd/user/tunnel.service '/bin/ghostunnel' - assertFileContains home-files/.config/systemd/user/tunnel.service 'allow-all' - assertFileContains home-files/.config/systemd/user/tunnel.service 'LoadCredential=cert:/run/secrets/cert.pem' + assertFileContent home-files/.config/systemd/user/tunnel.service ${./tunnel.service} ''; } diff --git a/tests/modules/services-modular/tunnel.service b/tests/modules/services-modular/tunnel.service new file mode 100644 index 000000000..49a2cc991 --- /dev/null +++ b/tests/modules/services-modular/tunnel.service @@ -0,0 +1,16 @@ +[Install] +WantedBy=default.target + +[Service] +AmbientCapabilities=CAP_NET_BIND_SERVICE +DynamicUser=true +ExecStart="@ghostunnel@/bin/ghostunnel" "server" "--listen" "127.0.0.1:8443" "--target" "127.0.0.1:8080" "--allow-all" --cert=${CREDENTIALS_DIRECTORY}/cert --key=${CREDENTIALS_DIRECTORY}/key +LoadCredential=cert:/run/secrets/cert.pem +LoadCredential=key:/run/secrets/key.pem +Restart=always +RestartSec=5 +Type=simple + +[Unit] +After=network.target +Wants=network.target