at master 4.1 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 utils, 6 ... 7}: 8 9let 10 cfg = config.services.recyclarr; 11 format = pkgs.formats.yaml { }; 12 stateDir = "/var/lib/recyclarr"; 13 configPath = "${stateDir}/config.json"; 14in 15{ 16 options.services.recyclarr = { 17 enable = lib.mkEnableOption "recyclarr service"; 18 19 package = lib.mkPackageOption pkgs "recyclarr" { }; 20 21 configuration = lib.mkOption { 22 type = format.type; 23 default = { }; 24 example = { 25 sonarr = [ 26 { 27 instance_name = "main"; 28 base_url = "http://localhost:8989"; 29 api_key = { 30 _secret = "/run/credentials/recyclarr.service/sonarr-api_key"; 31 }; 32 } 33 ]; 34 radarr = [ 35 { 36 instance_name = "main"; 37 base_url = "http://localhost:7878"; 38 api_key = { 39 _secret = "/run/credentials/recyclarr.service/radarr-api_key"; 40 }; 41 } 42 ]; 43 }; 44 description = '' 45 Recyclarr YAML configuration as a Nix attribute set. 46 47 For detailed configuration options and examples, see the 48 [official configuration reference](https://recyclarr.dev/wiki/yaml/config-reference/). 49 50 The configuration is processed using [utils.genJqSecretsReplacementSnippet](https://github.com/NixOS/nixpkgs/blob/master/nixos/lib/utils.nix#L232-L331) to handle secret substitution. 51 52 To avoid permission issues, secrets should be provided via systemd's credential mechanism: 53 54 ```nix 55 systemd.services.recyclarr.serviceConfig.LoadCredential = [ 56 "radarr-api_key:''${config.sops.secrets.radarr-api_key.path}" 57 ]; 58 ``` 59 ''; 60 }; 61 62 schedule = lib.mkOption { 63 type = lib.types.str; 64 default = "daily"; 65 description = "When to run recyclarr in systemd calendar format."; 66 }; 67 68 command = lib.mkOption { 69 type = lib.types.str; 70 default = "sync"; 71 description = "The recyclarr command to run (e.g., sync)."; 72 }; 73 74 user = lib.mkOption { 75 type = lib.types.str; 76 default = "recyclarr"; 77 description = "User account under which recyclarr runs."; 78 }; 79 80 group = lib.mkOption { 81 type = lib.types.str; 82 default = "recyclarr"; 83 description = "Group under which recyclarr runs."; 84 }; 85 }; 86 87 config = lib.mkIf cfg.enable { 88 89 users.users = lib.mkIf (cfg.user == "recyclarr") { 90 recyclarr = { 91 isSystemUser = true; 92 description = "recyclarr user"; 93 home = stateDir; 94 group = cfg.group; 95 }; 96 }; 97 98 users.groups = lib.mkIf (cfg.group == "recyclarr") { 99 ${cfg.group} = { }; 100 }; 101 102 systemd.services.recyclarr = { 103 description = "Recyclarr Service"; 104 105 # YAML is a JSON super-set 106 preStart = utils.genJqSecretsReplacementSnippet cfg.configuration configPath; 107 108 serviceConfig = { 109 Type = "oneshot"; 110 User = cfg.user; 111 Group = cfg.group; 112 StateDirectory = "recyclarr"; 113 ExecStart = "${lib.getExe cfg.package} ${cfg.command} --app-data ${stateDir} --config ${configPath}"; 114 115 ProtectSystem = "strict"; 116 ProtectHome = true; 117 PrivateTmp = true; 118 PrivateDevices = true; 119 ProtectHostname = true; 120 ProtectClock = true; 121 ProtectKernelTunables = true; 122 ProtectKernelModules = true; 123 ProtectKernelLogs = true; 124 ProtectControlGroups = true; 125 126 PrivateNetwork = false; 127 RestrictAddressFamilies = [ 128 "AF_INET" 129 "AF_INET6" 130 ]; 131 132 NoNewPrivileges = true; 133 RestrictSUIDSGID = true; 134 RemoveIPC = true; 135 136 ReadWritePaths = [ stateDir ]; 137 138 CapabilityBoundingSet = ""; 139 140 LockPersonality = true; 141 RestrictRealtime = true; 142 }; 143 }; 144 145 systemd.timers.recyclarr = { 146 description = "Recyclarr Timer"; 147 wantedBy = [ "timers.target" ]; 148 partOf = [ "recyclarr.service" ]; 149 150 timerConfig = { 151 OnCalendar = cfg.schedule; 152 Persistent = true; 153 RandomizedDelaySec = "5m"; 154 }; 155 }; 156 }; 157}