servarr: add configXml option with preStart hook
Adds services.arrInit.<name>.configXml for declaratively ensuring XML elements exist in a Servarr config.xml before the service starts. Generates a preStart hook on the main service that runs a Python helper to patch or create config.xml. Undeclared elements are preserved; declared elements are written with exact values. Primary use case: preventing recurring Prowlarr 'not listening on port' failures when config.xml loses the <Port> element — now guaranteed to exist before Prowlarr starts. Hardening: - Atomic writes (tmp + rename): power loss cannot corrupt config.xml - Malformed XML recovery: fresh <Config> root instead of blocking boot - Secure default mode (0600) for new files containing ApiKey - Preserves existing file mode on rewrite - Assertion against duplicate serviceName targeting Tests (10 subtests): creates-from-missing, patches-existing, preserves- undeclared, corrects-tampered, idempotent, malformed-recovery, ownership-preserved, not-world-readable.
This commit is contained in:
@@ -1,30 +1,40 @@
|
||||
{ pkgs, lib, self }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
self,
|
||||
}:
|
||||
pkgs.testers.runNixOSTest {
|
||||
name = "arr-init-naming";
|
||||
nodes.machine = { pkgs, lib, ... }: {
|
||||
imports = [ self.nixosModules.default ];
|
||||
system.stateVersion = "24.11";
|
||||
virtualisation.memorySize = 4096;
|
||||
environment.systemPackages = with pkgs; [ curl jq gnugrep ];
|
||||
nodes.machine =
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
imports = [ self.nixosModules.default ];
|
||||
system.stateVersion = "24.11";
|
||||
virtualisation.memorySize = 4096;
|
||||
environment.systemPackages = with pkgs; [
|
||||
curl
|
||||
jq
|
||||
gnugrep
|
||||
];
|
||||
|
||||
services.sonarr = {
|
||||
enable = true;
|
||||
dataDir = "/var/lib/sonarr/.config/NzbDrone";
|
||||
settings.server.port = lib.mkDefault 8989;
|
||||
};
|
||||
services.sonarr = {
|
||||
enable = true;
|
||||
dataDir = "/var/lib/sonarr/.config/NzbDrone";
|
||||
settings.server.port = lib.mkDefault 8989;
|
||||
};
|
||||
|
||||
services.arrInit.sonarr = {
|
||||
enable = true;
|
||||
serviceName = "sonarr";
|
||||
dataDir = "/var/lib/sonarr/.config/NzbDrone";
|
||||
port = 8989;
|
||||
naming = {
|
||||
renameEpisodes = true;
|
||||
standardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Quality Full}";
|
||||
seasonFolderFormat = "Season {season}";
|
||||
services.arrInit.sonarr = {
|
||||
enable = true;
|
||||
serviceName = "sonarr";
|
||||
dataDir = "/var/lib/sonarr/.config/NzbDrone";
|
||||
port = 8989;
|
||||
naming = {
|
||||
renameEpisodes = true;
|
||||
standardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Quality Full}";
|
||||
seasonFolderFormat = "Season {season}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
start_all()
|
||||
machine.wait_for_unit("sonarr.service")
|
||||
|
||||
Reference in New Issue
Block a user