From 98180aead23d0551b2288d336c01235a456d9dda Mon Sep 17 00:00:00 2001 From: glyph Date: Sat, 28 Mar 2026 21:42:57 +0100 Subject: [PATCH 1/5] sabnzbd: ensure config file exists initially --- .../modules/services/networking/sabnzbd/default.nix | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/nixos/modules/services/networking/sabnzbd/default.nix b/nixos/modules/services/networking/sabnzbd/default.nix index 4d16ddfd9a22..11221d393be5 100644 --- a/nixos/modules/services/networking/sabnzbd/default.nix +++ b/nixos/modules/services/networking/sabnzbd/default.nix @@ -514,10 +514,7 @@ in systemd.services.sabnzbd = let files = - if cfg.configFile != null then - [ sabnzbdIniPath ] - else - (lib.optional cfg.allowConfigWrite sabnzbdIniPath) ++ [ publicSettingsIni ] ++ cfg.secretFiles; + (lib.optional cfg.allowConfigWrite sabnzbdIniPath) ++ [ publicSettingsIni ] ++ cfg.secretFiles; iniPathQuoted = lib.escapeShellArg sabnzbdIniPath; in { @@ -532,11 +529,18 @@ in StateDirectory = cfg.stateDir; ExecStart = "${lib.getExe cfg.package} -d -f ${iniPathQuoted}"; }; + } + // lib.optionalAttrs (cfg.configFile == null) { preStart = '' set -euo pipefail ${lib.toShellVar "files" files} + # We overwrite this immediately, but the merge script requires that + # all files exist + # See also: nixpkgs #504224 + (touch ${iniPathQuoted} 2>/dev/null || true) + tmpfile=$(mktemp) ${lib.getExe (pkgs.python3.withPackages (py: [ py.configobj ]))} \ From dcefbcbc0d7a63b6bedaa7c3f265f8f19eb6d225 Mon Sep 17 00:00:00 2001 From: glyph Date: Sat, 28 Mar 2026 21:51:29 +0100 Subject: [PATCH 2/5] sabnzbd: regression test for #504224 --- nixos/tests/sabnzbd-module.nix | 77 ++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 9 deletions(-) diff --git a/nixos/tests/sabnzbd-module.nix b/nixos/tests/sabnzbd-module.nix index fd9f48ae35d0..1918bf965091 100644 --- a/nixos/tests/sabnzbd-module.nix +++ b/nixos/tests/sabnzbd-module.nix @@ -1,12 +1,7 @@ { lib, ... }: -{ - name = "sabnzbd"; - meta.maintainers = with lib.maintainers; [ jojosch ]; - - node.pkgsReadOnly = false; - - nodes.machine = - { pkgs, lib, ... }: +let + common-config = + { pkgs, ... }: { services.sabnzbd = { enable = true; @@ -62,14 +57,78 @@ # unrar is unfree nixpkgs.config.allowUnfreePackages = [ "unrar" ]; }; +in +{ + name = "sabnzbd"; + meta.maintainers = with lib.maintainers; [ jojosch ]; + + node.pkgsReadOnly = false; + + nodes.machine = + { ... }: + { + imports = [ common-config ]; + }; + nodes.with_writeable_config = + { ... }: + { + imports = [ common-config ]; + config.services.sabnzbd.allowConfigWrite = true; + }; + nodes.with_raw_config_file = + { pkgs, ... }: + { + imports = [ common-config ]; + config = { + services.sabnzbd = { + configFile = builtins.toFile "config.ini" '' + [misc] + inet_exposure = 2 + html_login = 0 + api_key = abcdef + log_dir = /var/lib/sabnzbd + admin_dir = /var/lib/sabnzbd + ''; + }; + + environment.systemPackages = [ + pkgs.jq + (pkgs.writeScriptBin "do_test_2" '' + set -euxo pipefail + + misc_url="http://127.0.0.1:8080/api?mode=get_config§ion=misc&output=json&apikey=abcdef" + + [[ $(curl $misc_url | jq .config.misc.inet_exposure) == 2 ]] + [[ $(curl $misc_url | jq .config.misc.html_login) == "false" ]] + '') + ]; + }; + }; testScript = '' - machine.wait_for_unit("sabnzbd.service") machine.wait_until_succeeds( "curl --fail -L http://localhost:8080/" ) machine.succeed("do_test") + + + + with_writeable_config.wait_for_unit("sabnzbd.service") + with_writeable_config.wait_until_succeeds( + "curl --fail -L http://localhost:8080/" + ) + + with_writeable_config.succeed("do_test") + + + + with_raw_config_file.wait_for_unit("sabnzbd.service") + with_raw_config_file.wait_until_succeeds( + "curl --fail -L http://localhost:8080/" + ) + + with_raw_config_file.succeed("do_test_2") ''; } From ecf281d03f8d008eb42b177d512f0f641a802fee Mon Sep 17 00:00:00 2001 From: glyph Date: Sun, 29 Mar 2026 00:11:19 +0100 Subject: [PATCH 3/5] ids: fix incorrect comment --- nixos/modules/misc/ids.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index ecc3b3c355dc..346fe03471eb 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -84,7 +84,7 @@ in tor = 35; cups = 36; foldingathome = 37; - #sabnzbd = 38; # dropped in 25.11 + #sabnzbd = 38; # dropped in 26.05 #kdm = 39; # dropped in 17.03 #ghostone = 40; # dropped in 18.03 git = 41; @@ -570,7 +570,7 @@ in lambdabot = 191; asterisk = 192; plex = 193; - #sabnzbd = 194; # dropped in 25.11 + #sabnzbd = 194; # dropped in 26.05 #grafana = 196; #unused #skydns = 197; #unused # ripple-rest = 198; # unused, removed 2017-08-12 From 345604f0137dd7ffa536e8e5db91165897b3e728 Mon Sep 17 00:00:00 2001 From: glyph Date: Sun, 29 Mar 2026 00:18:25 +0100 Subject: [PATCH 4/5] sabnzbd: allow overriding of config schema version and encoding --- nixos/modules/services/networking/sabnzbd/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/services/networking/sabnzbd/default.nix b/nixos/modules/services/networking/sabnzbd/default.nix index 11221d393be5..d4a894faf96f 100644 --- a/nixos/modules/services/networking/sabnzbd/default.nix +++ b/nixos/modules/services/networking/sabnzbd/default.nix @@ -33,7 +33,7 @@ let "__version__" = 19; "__encoding__" = "utf-8"; }; - allSettings = cfg.settings // mandatoryGlobalSettings; + allSettings = mandatoryGlobalSettings // cfg.settings; # sabnzbd uses configobj type inis, which support # nested sections specified by increasing numbers From 8717b642a9ce3a76a5b10bf7d85634da13a6d6cb Mon Sep 17 00:00:00 2001 From: glyph Date: Sun, 29 Mar 2026 12:51:09 +0200 Subject: [PATCH 5/5] sabnzbd: clean up test script --- nixos/tests/sabnzbd-module.nix | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/nixos/tests/sabnzbd-module.nix b/nixos/tests/sabnzbd-module.nix index 1918bf965091..3eb9bd21e2ff 100644 --- a/nixos/tests/sabnzbd-module.nix +++ b/nixos/tests/sabnzbd-module.nix @@ -106,29 +106,16 @@ in }; testScript = '' - machine.wait_for_unit("sabnzbd.service") - machine.wait_until_succeeds( - "curl --fail -L http://localhost:8080/" - ) + def wait_for_up(m): + m.wait_for_unit("sabnzbd.service") + m.wait_until_succeeds("curl --fail -L http://localhost:8080") + + wait_for_up(machine) + wait_for_up(with_writeable_config) + wait_for_up(with_raw_config_file) machine.succeed("do_test") - - - - with_writeable_config.wait_for_unit("sabnzbd.service") - with_writeable_config.wait_until_succeeds( - "curl --fail -L http://localhost:8080/" - ) - with_writeable_config.succeed("do_test") - - - - with_raw_config_file.wait_for_unit("sabnzbd.service") - with_raw_config_file.wait_until_succeeds( - "curl --fail -L http://localhost:8080/" - ) - with_raw_config_file.succeed("do_test_2") ''; }