|
7 | 7 | }: |
8 | 8 | let |
9 | 9 | cfg = config.services.sonarr; |
10 | | - |
11 | | - settingsEnvVars = lib.pipe cfg.settings [ |
12 | | - (lib.mapAttrsRecursive ( |
13 | | - path: value: |
14 | | - lib.optionalAttrs (value != null) { |
15 | | - name = lib.toUpper "SONARR__${lib.concatStringsSep "__" path}"; |
16 | | - value = toString (if lib.isBool value then lib.boolToString value else value); |
17 | | - } |
18 | | - )) |
19 | | - (lib.collect (x: lib.isString x.name or false && lib.isString x.value or false)) |
20 | | - lib.listToAttrs |
21 | | - ]; |
22 | 10 | in |
23 | 11 | { |
24 | 12 | options = { |
|
39 | 27 | ''; |
40 | 28 | }; |
41 | 29 |
|
42 | | - apiKeyFile = lib.mkOption { |
43 | | - type = lib.types.nullOr lib.types.path; |
44 | | - description = '' |
45 | | - Path to the file containing the API key for Sonarr (32 chars). |
46 | | - This will overwrite the API key in the config file. |
47 | | - ''; |
48 | | - example = "/run/secrets/sonarr-apikey"; |
49 | | - default = null; |
50 | | - }; |
51 | | - |
52 | | - environmentFiles = lib.mkOption { |
53 | | - type = lib.types.listOf lib.types.path; |
54 | | - default = [ ]; |
55 | | - description = '' |
56 | | - Environment file to pass secret configuration values. |
57 | | -
|
58 | | - Each line must follow the `SONARR__SECTION__KEY=value` pattern. |
59 | | - Please consult the documentation at the [wiki](https://wiki.servarr.com/useful-tools#using-environment-variables-for-config). |
60 | | - ''; |
61 | | - }; |
62 | | - |
63 | | - settings = lib.mkOption { |
64 | | - type = lib.types.submodule { |
65 | | - freeformType = (pkgs.formats.ini { }).type; |
66 | | - options = { |
67 | | - update = { |
68 | | - mechanism = lib.mkOption { |
69 | | - type = |
70 | | - with lib.types; |
71 | | - nullOr (enum [ |
72 | | - "external" |
73 | | - "builtIn" |
74 | | - "script" |
75 | | - ]); |
76 | | - description = "which update mechanism to use"; |
77 | | - default = "external"; |
78 | | - }; |
79 | | - automatically = lib.mkOption { |
80 | | - type = lib.types.bool; |
81 | | - description = "Automatically download and install updates."; |
82 | | - default = false; |
83 | | - }; |
84 | | - }; |
85 | | - server = { |
86 | | - port = lib.mkOption { |
87 | | - type = lib.types.int; |
88 | | - description = "Port Number"; |
89 | | - default = 8989; |
90 | | - }; |
91 | | - }; |
92 | | - log = { |
93 | | - analyticsEnabled = lib.mkOption { |
94 | | - type = lib.types.bool; |
95 | | - description = "Send Anonymous Usage Data"; |
96 | | - default = false; |
97 | | - }; |
98 | | - }; |
99 | | - }; |
100 | | - }; |
101 | | - example = lib.options.literalExpression '' |
102 | | - { |
103 | | - update.mechanism = "internal"; |
104 | | - server = { |
105 | | - urlbase = "localhost"; |
106 | | - port = 8989; |
107 | | - bindaddress = "*"; |
108 | | - }; |
109 | | - } |
110 | | - ''; |
111 | | - default = { }; |
112 | | - description = '' |
113 | | - Attribute set of arbitrary config options. |
114 | | - Please consult the documentation at the [wiki](https://wiki.servarr.com/useful-tools#using-environment-variables-for-config). |
115 | | -
|
116 | | - WARNING: this configuration is stored in the world-readable Nix store! |
117 | | - Use [](#opt-services.sonarr.environmentFiles) if it contains a secret. |
118 | | - ''; |
119 | | - }; |
120 | | - |
121 | 30 | user = lib.mkOption { |
122 | 31 | type = lib.types.str; |
123 | 32 | default = "sonarr"; |
|
135 | 44 | }; |
136 | 45 |
|
137 | 46 | config = lib.mkIf cfg.enable { |
138 | | - assertions = [ |
139 | | - { |
140 | | - assertion = !(cfg.settings ? auth && cfg.settings.auth ? apikey); |
141 | | - message = '' |
142 | | - The `services.sonarr.settings` attribute set must not contain `ApiKey`, you should instead use `services.sonarr.apiKeyFile` to avoid storing secrets in the Nix store. |
143 | | - ''; |
144 | | - } |
145 | | - ]; |
146 | | - |
147 | 47 | systemd.tmpfiles.rules = [ |
148 | 48 | "d '${cfg.dataDir}' 0700 ${cfg.user} ${cfg.group} - -" |
149 | 49 | ]; |
|
152 | 52 | description = "Sonarr"; |
153 | 53 | after = [ "network.target" ]; |
154 | 54 | wantedBy = [ "multi-user.target" ]; |
155 | | - environment = settingsEnvVars; |
| 55 | + |
156 | 56 | serviceConfig = { |
157 | 57 | Type = "simple"; |
158 | 58 | User = cfg.user; |
159 | 59 | Group = cfg.group; |
160 | | - EnvironmentFile = cfg.environmentFiles; |
161 | | - LoadCredential = lib.optional (cfg.apiKeyFile != null) "SONARR__AUTH__APIKEY:${cfg.apiKeyFile}"; |
162 | | - ExecStartPre = lib.optionalString (cfg.apiKeyFile != null) pkgs.writeShellScript "sonarr-apikey" '' |
163 | | - if [ ! -s config.xml ]; then |
164 | | - echo '<?xml version="1.0" encoding="UTF-8"?><Config><ApiKey></ApiKey></Config>' > "${cfg.dataDir}/config.xml" |
165 | | - fi |
166 | | - ${lib.getExe pkgs.xmlstarlet} ed -L -u "/Config/ApiKey" -v "@API_KEY@" "${cfg.dataDir}/config.xml" |
167 | | - ${lib.getExe pkgs.replace-secret} '@API_KEY@' ''${CREDENTIALS_DIRECTORY}/SONARR__AUTH__APIKEY "${cfg.dataDir}/config.xml" |
168 | | - ''; |
169 | 60 | ExecStart = utils.escapeSystemdExecArgs [ |
170 | 61 | (lib.getExe cfg.package) |
171 | 62 | "-nobrowser" |
|
176 | 67 | }; |
177 | 68 |
|
178 | 69 | networking.firewall = lib.mkIf cfg.openFirewall { |
179 | | - allowedTCPPorts = [ cfg.settings.server.port ]; |
| 70 | + allowedTCPPorts = [ 8989 ]; |
180 | 71 | }; |
181 | 72 |
|
182 | 73 | users.users = lib.mkIf (cfg.user == "sonarr") { |
|
0 commit comments