Skip to content

Commit 76b9c03

Browse files
committed
feat: recyclarr
Add the recyclarr service. c
1 parent 5e8d870 commit 76b9c03

File tree

3 files changed

+143
-9
lines changed

3 files changed

+143
-9
lines changed

flake.lock

+9-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nixarr/default.nix

+6
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ with lib; let
7575
+ strings.optionalString cfg.jellyseerr.enable ''
7676
chown -R jellyseerr:root "${cfg.jellyseerr.stateDir}"
7777
find "${cfg.jellyseerr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
78+
''
79+
+ strings.optionalString cfg.recyclarr.enable ''
80+
chown -R recyclarr:root "${cfg.recyclarr.stateDir}"
81+
find "${cfg.recyclarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
7882
'';
7983
};
8084
in {
@@ -91,6 +95,7 @@ in {
9195
./prowlarr
9296
./transmission
9397
./sabnzbd
98+
./recyclarr
9499
../util
95100
];
96101

@@ -125,6 +130,7 @@ in {
125130
- [Prowlarr](#nixarr.prowlarr.enable)
126131
- [Radarr](#nixarr.radarr.enable)
127132
- [Readarr](#nixarr.readarr.enable)
133+
- [Recyclarr](#nixarr.recyclarr.enable)
128134
- [Sonarr](#nixarr.sonarr.enable)
129135
- [Transmission](#nixarr.transmission.enable)
130136
- [SABnzbd](#nixarr.sabnzbd.enable)

nixarr/recyclarr/default.nix

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
{ config
2+
, lib
3+
, pkgs
4+
, inputs
5+
, ...
6+
}:
7+
with lib; let
8+
cfg = config.nixarr.recyclarr;
9+
nixarr = config.nixarr;
10+
11+
# Helper function to extract API keys
12+
extractApiKeys = pkgs.writeShellApplication {
13+
name = "extract-recyclarr-api-keys";
14+
runtimeInputs = with pkgs; [ yq ];
15+
text = ''
16+
# Ensure state directory exists with proper permissions
17+
mkdir -p "${cfg.stateDir}"
18+
chown ${config.services.recyclarr.user}:${config.services.recyclarr.group} "${cfg.stateDir}"
19+
chmod 755 "${cfg.stateDir}"
20+
21+
${optionalString nixarr.radarr.enable ''
22+
# Extract Radarr API key
23+
API_KEY_FILE="${cfg.stateDir}/radarr-api-key"
24+
xq -r '.Config.ApiKey' "${nixarr.radarr.stateDir}/config.xml" > "$API_KEY_FILE"
25+
chmod 400 "$API_KEY_FILE"
26+
chown ${config.services.recyclarr.user}:${config.services.recyclarr.group} "$API_KEY_FILE"
27+
echo "RADARR_API_KEY=$(tr -d '\n' < "$API_KEY_FILE")" >> "${cfg.stateDir}/env"
28+
''}
29+
30+
${optionalString nixarr.sonarr.enable ''
31+
# Extract Sonarr API key
32+
API_KEY_FILE="${cfg.stateDir}/sonarr-api-key"
33+
xq -r '.Config.ApiKey' "${nixarr.sonarr.stateDir}/config.xml" > "$API_KEY_FILE"
34+
chmod 400 "$API_KEY_FILE"
35+
chown ${config.services.recyclarr.user}:${config.services.recyclarr.group} "$API_KEY_FILE"
36+
echo "SONARR_API_KEY=$(tr -d '\n' < "$API_KEY_FILE")" >> "${cfg.stateDir}/env"
37+
''}
38+
39+
chmod 400 "${cfg.stateDir}/env"
40+
chown ${config.services.recyclarr.user}:${config.services.recyclarr.group} "${cfg.stateDir}/env"
41+
'';
42+
};
43+
in {
44+
options.nixarr.recyclarr = {
45+
enable = mkOption {
46+
type = types.bool;
47+
default = false;
48+
example = true;
49+
description = ''
50+
Whether or not to enable the Recyclarr service. This service does not need to be run behind a VPN.
51+
52+
**Required options:** [`nixarr.enable`](#nixarr.enable)
53+
'';
54+
};
55+
56+
package = mkPackageOption pkgs "recyclarr" { };
57+
58+
stateDir = mkOption {
59+
type = types.path;
60+
default = "${nixarr.stateDir}/recyclarr";
61+
defaultText = literalExpression ''"''${nixarr.stateDir}/recyclarr"'';
62+
example = "/nixarr/.state/recyclarr";
63+
description = "The location of the state directory for the Recyclarr service.";
64+
};
65+
66+
configFile = mkOption {
67+
type = types.path;
68+
description = "Path to the recyclarr YAML configuration file. See [Recyclarr's documentation](https://recyclarr.dev/wiki/yaml/config-reference) for more information.
69+
70+
**Note:** the API keys for Radarr and Sonarr can be referenced in the config file using the `RADARR_API_KEY` and `SONARR_API_KEY` environment variables (with macro `!env_var`).";
71+
example = "./recyclarr.yaml";
72+
};
73+
};
74+
75+
config = mkIf cfg.enable {
76+
assertions = [
77+
{
78+
assertion = cfg.enable -> nixarr.enable;
79+
message = ''
80+
The nixarr.recyclarr.enable option requires the nixarr.enable
81+
option to be set, but it was not.
82+
'';
83+
}
84+
{
85+
assertion = cfg.enable -> (nixarr.radarr.enable || nixarr.sonarr.enable);
86+
message = ''
87+
The nixarr.recyclarr.enable option requires at least one of nixarr.radarr.enable
88+
or nixarr.sonarr.enable to be set, but neither was enabled.
89+
'';
90+
}
91+
];
92+
93+
services.recyclarr = {
94+
enable = true;
95+
package = cfg.package;
96+
};
97+
98+
systemd.services.recyclarr-setup = {
99+
description = "Setup Recyclarr environment";
100+
requiredBy = ["recyclarr.service"];
101+
before = ["recyclarr.service"];
102+
requires = (optionals nixarr.radarr.enable ["radarr.service"]) ++
103+
(optionals nixarr.sonarr.enable ["sonarr.service"]);
104+
after = (optionals nixarr.radarr.enable ["radarr.service"]) ++
105+
(optionals nixarr.sonarr.enable ["sonarr.service"]);
106+
107+
serviceConfig = {
108+
Type = "oneshot";
109+
RemainAfterExit = true;
110+
ExecStart = "${extractApiKeys}/bin/extract-recyclarr-api-keys";
111+
};
112+
};
113+
114+
systemd.services.recyclarr = {
115+
requires = ["recyclarr-setup.service"];
116+
after = ["recyclarr-setup.service"];
117+
serviceConfig = {
118+
ExecStart = lib.mkForce "${cfg.package}/bin/recyclarr sync --app-data ${cfg.stateDir} --config ${cfg.configFile}";
119+
EnvironmentFile = "${cfg.stateDir}/env";
120+
ReadWritePaths = [ cfg.stateDir ];
121+
};
122+
};
123+
124+
systemd.tmpfiles.rules = [
125+
"d '${cfg.stateDir}' 0750 ${config.services.recyclarr.user} root - -"
126+
];
127+
};
128+
}

0 commit comments

Comments
 (0)