diff --git a/CHANGELOG.md b/CHANGELOG.md index ae89fb1..ab89794 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,14 @@ ## Unreleased Added: -- Added Readarr Audiobook for running two readarr instances +- Added Readarr Audiobook for running two readarr instances (one for audiobooks, one for regular books) +- Audiobookshelf service, with expose options - Port configurations on: - Radarr - Sonarr - Prowlarr - Readarr -- Audiobookshelf service, with expose options + - Lidarr ## 2025-05-28 diff --git a/nixarr/audiobookshelf/default.nix b/nixarr/audiobookshelf/default.nix index 64d4c41..f193583 100644 --- a/nixarr/audiobookshelf/default.nix +++ b/nixarr/audiobookshelf/default.nix @@ -6,9 +6,7 @@ }: with lib; let cfg = config.nixarr.audiobookshelf; - uid = 242; - user = "streamer"; - group = "streamer"; + globals = config.util-nixarr.globals; port = 9292; nixarr = config.nixarr; in { @@ -153,21 +151,20 @@ in { ]; users = { - groups."${group}" = {}; - users."${user}" = { + groups.${globals.audiobookshelf.group}.gid = globals.gids.${globals.audiobookshelf.group}; + users.${globals.audiobookshelf.user} = { isSystemUser = true; - group = group; - uid = uid; + group = globals.audiobookshelf.group; + uid = globals.uids.${globals.audiobookshelf.user}; }; }; systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0700 ${user} root - -" + "d '${cfg.stateDir}' 0700 ${globals.audiobookshelf.user} root - -" # Media Dirs - "d '${nixarr.mediaDir}/library/books' 0775 ${user} ${group} - -" - "d '${nixarr.mediaDir}/library/audio-books' 0775 ${user} ${group} - -" - "d '${nixarr.mediaDir}/library/podcasts' 0775 ${user} ${group} - -" + "d '${nixarr.mediaDir}/library/audiobooks' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/podcasts' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" ]; systemd.services.audiobookshelf = { @@ -179,8 +176,8 @@ in { serviceConfig = { IOSchedulingPriority = 0; Type = "simple"; - User = user; - Group = group; + User = globals.audiobookshelf.user; + Group = globals.audiobookshelf.group; StateDirectory = cfg.stateDir; WorkingDirectory = cfg.stateDir; ExecStart = "${cfg.package}/bin/audiobookshelf --host ${host} --port ${toString cfg.port}"; diff --git a/nixarr/autobrr/default.nix b/nixarr/autobrr/default.nix index cb2336c..d2298cc 100644 --- a/nixarr/autobrr/default.nix +++ b/nixarr/autobrr/default.nix @@ -6,10 +6,8 @@ }: with lib; let cfg = config.nixarr.autobrr; + globals = config.util-nixarr.globals; nixarr = config.nixarr; - # Externalize username and group - user = "autobrr"; - group = "autobrr"; # Define config format and template configFormat = pkgs.formats.toml {}; @@ -97,16 +95,17 @@ in { ]; users = { - groups.${group} = {}; - users.${user} = { + groups.${globals.autobrr.group}.gid = globals.gids.${globals.autobrr.group}; + users.${globals.autobrr.user} = { isSystemUser = true; - group = group; + group = globals.autobrr.group; + uid = globals.uids.${globals.autobrr.user}; }; }; # Create state directory with proper permissions systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0700 ${user} ${group} - -" + "d '${cfg.stateDir}' 0700 ${globals.autobrr.user} root - -" ]; # Configure the autobrr service @@ -134,8 +133,8 @@ in { serviceConfig = { Type = "simple"; - User = user; - Group = "root"; + User = globals.autobrr.user; + Group = globals.autobrr.group; UMask = 066; DynamicUser = lib.mkForce false; # disable SecretFilec diff --git a/nixarr/bazarr/default.nix b/nixarr/bazarr/default.nix index 77b7c54..000800a 100644 --- a/nixarr/bazarr/default.nix +++ b/nixarr/bazarr/default.nix @@ -6,9 +6,8 @@ }: with lib; let cfg = config.nixarr.bazarr; + globals = config.util-nixarr.globals; port = 6767; - user = "bazarr"; - group = "media"; nixarr = config.nixarr; in { options.nixarr.bazarr = { @@ -80,7 +79,7 @@ in { ]; systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0700 ${user} root - -" + "d '${cfg.stateDir}' 0700 ${globals.bazarr.user} root - -" ]; systemd.services.bazarr = { @@ -90,8 +89,8 @@ in { serviceConfig = { Type = "simple"; - User = user; - Group = group; + User = globals.bazarr.user; + Group = globals.bazarr.group; SyslogIdentifier = "bazarr"; ExecStart = pkgs.writeShellScript "start-bazarr" '' ${pkgs.bazarr}/bin/bazarr \ @@ -108,11 +107,12 @@ in { }; users = { - users."${user}" = { + groups.${globals.bazarr.group}.gid = globals.gids.${globals.bazarr.group}; + users.${globals.bazarr.user} = { isSystemUser = true; - group = group; + group = globals.bazarr.group; + uid = globals.uids.${globals.bazarr.user}; }; - groups."${group}" = {}; }; # Enable and specify VPN namespace to confine service in. diff --git a/nixarr/default.nix b/nixarr/default.nix index cc112ad..6452145 100644 --- a/nixarr/default.nix +++ b/nixarr/default.nix @@ -6,6 +6,7 @@ }: with lib; let cfg = config.nixarr; + globals = config.util-nixarr.globals; list-unlinked = pkgs.writeShellApplication { name = "list-unlinked"; runtimeInputs = with pkgs; [util-linux]; @@ -30,72 +31,72 @@ with lib; let find "${cfg.mediaDir}" \( -type d -exec chmod 0775 {} + -true \) -o \( -exec chmod 0664 {} + \) '' + strings.optionalString cfg.jellyfin.enable '' - chown -R streamer:media "${cfg.mediaDir}/library" - chown -R streamer:root "${cfg.jellyfin.stateDir}" + chown -R ${globals.libraryOwner.user}:${globals.libraryOwner.group} "${cfg.mediaDir}/library" + chown -R ${globals.jellyfin.user}:root "${cfg.jellyfin.stateDir}" find "${cfg.jellyfin.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.plex.enable '' - chown -R streamer:media "${cfg.mediaDir}/library" - chown -R streamer:root "${cfg.plex.stateDir}" + chown -R ${globals.libraryOwner.user}:${globals.libraryOwner.group} "${cfg.mediaDir}/library" + chown -R ${globals.plex.user}:root "${cfg.plex.stateDir}" find "${cfg.plex.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.audiobookshelf.enable '' - chown -R streamer:media "${cfg.mediaDir}/library" - chown -R streamer:root "${cfg.audiobookshelf.stateDir}" + chown -R ${globals.libraryOwner.user}:${globals.libraryOwner.group} "${cfg.mediaDir}/library" + chown -R ${globals.audiobookshelf.user}:root "${cfg.audiobookshelf.stateDir}" find "${cfg.audiobookshelf.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.transmission.enable '' - chown -R torrenter:media "${cfg.mediaDir}/torrents" - chown -R torrenter:cross-seed "${cfg.transmission.stateDir}" + chown -R ${globals.transmission.user}:${globals.transmission.group} "${cfg.mediaDir}/torrents" + chown -R ${globals.transmission.user}:${globals.transmission.group} "${cfg.transmission.stateDir}" find "${cfg.transmission.stateDir}" \( -type d -exec chmod 0750 {} + -true \) -o \( -exec chmod 0640 {} + \) '' + strings.optionalString cfg.sabnzbd.enable '' - chown -R usenet:media "${cfg.mediaDir}/usenet" - chown -R usenet:root "${cfg.sabnzbd.stateDir}" + chown -R ${globals.sabnzbd.user}:${globals.sabnzbd.group} "${cfg.mediaDir}/usenet" + chown -R ${globals.sabnzbd.user}:root "${cfg.sabnzbd.stateDir}" find "${cfg.sabnzbd.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.transmission.privateTrackers.cross-seed.enable '' - chown -R cross-seed:root "${cfg.transmission.privateTrackers.cross-seed.stateDir}" + chown -R ${globals.cross-seed.user}:root "${cfg.transmission.privateTrackers.cross-seed.stateDir}" find "${cfg.transmission.privateTrackers.cross-seed.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.prowlarr.enable '' - chown -R prowlarr:root "${cfg.prowlarr.stateDir}" + chown -R ${globals.prowlarr.user}:root "${cfg.prowlarr.stateDir}" find "${cfg.prowlarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.sonarr.enable '' - chown -R sonarr:root "${cfg.sonarr.stateDir}" + chown -R ${globals.sonarr.user}:root "${cfg.sonarr.stateDir}" find "${cfg.sonarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.radarr.enable '' - chown -R radarr:root "${cfg.radarr.stateDir}" + chown -R ${globals.radarr.user}:root "${cfg.radarr.stateDir}" find "${cfg.radarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.lidarr.enable '' - chown -R lidarr:root "${cfg.lidarr.stateDir}" + chown -R ${globals.lidarr.user}:root "${cfg.lidarr.stateDir}" find "${cfg.lidarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.bazarr.enable '' - chown -R bazarr:root "${cfg.bazarr.stateDir}" + chown -R ${globals.bazarr.user}:root "${cfg.bazarr.stateDir}" find "${cfg.bazarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.readarr.enable '' - chown -R readarr:root "${cfg.readarr.stateDir}" + chown -R ${globals.readarr.user}:root "${cfg.readarr.stateDir}" find "${cfg.readarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.readarr-audiobook.enable '' - chown -R readarr:root "${cfg.readarr-audiobook.stateDir}" + chown -R ${globals.readarr.user}:root "${cfg.readarr-audiobook.stateDir}" find "${cfg.readarr-audiobook.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.jellyseerr.enable '' - chown -R jellyseerr:root "${cfg.jellyseerr.stateDir}" + chown -R ${globals.jellyseerr.user}:root "${cfg.jellyseerr.stateDir}" find "${cfg.jellyseerr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.autobrr.enable '' - chown -R autobrr:root "${cfg.autobrr.stateDir}" + chown -R ${globals.autobrr.user}:root "${cfg.autobrr.stateDir}" find "${cfg.autobrr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) '' + strings.optionalString cfg.recyclarr.enable '' - chown -R recyclarr:root "${cfg.recyclarr.stateDir}" + chown -R ${globals.recyclarr.user}:root "${cfg.recyclarr.stateDir}" find "${cfg.recyclarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \) ''; }; diff --git a/nixarr/jellyfin/default.nix b/nixarr/jellyfin/default.nix index ea09441..e07f201 100644 --- a/nixarr/jellyfin/default.nix +++ b/nixarr/jellyfin/default.nix @@ -6,10 +6,8 @@ }: with lib; let cfg = config.nixarr.jellyfin; + globals = config.util-nixarr.globals; defaultPort = 8096; - uid = 242; - user = "streamer"; - group = "streamer"; nixarr = config.nixarr; in { options.nixarr.jellyfin = { @@ -141,23 +139,28 @@ in { ]; users = { - groups."${group}" = {}; - users."${user}" = { + groups.${globals.jellyfin.group}.gid = globals.gids.${globals.jellyfin.group}; + users.${globals.jellyfin.user} = { isSystemUser = true; - group = group; - uid = uid; + group = globals.jellyfin.group; + uid = globals.uids.${globals.jellyfin.user}; }; }; systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0700 ${user} root - -" + "d '${cfg.stateDir}' 0700 ${globals.jellyfin.user} root - -" + "d '${cfg.stateDir}/log' 0700 ${globals.jellyfin.user} root - -" + "d '${cfg.stateDir}/cache' 0700 ${globals.jellyfin.user} root - -" + "d '${cfg.stateDir}/data' 0700 ${globals.jellyfin.user} root - -" + "d '${cfg.stateDir}/config' 0700 ${globals.jellyfin.user} root - -" # Media Dirs - "d '${nixarr.mediaDir}/library' 0775 ${user} ${group} - -" - "d '${nixarr.mediaDir}/library/shows' 0775 ${user} ${group} - -" - "d '${nixarr.mediaDir}/library/movies' 0775 ${user} ${group} - -" - "d '${nixarr.mediaDir}/library/music' 0775 ${user} ${group} - -" - "d '${nixarr.mediaDir}/library/books' 0775 ${user} ${group} - -" + "d '${nixarr.mediaDir}/library' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/shows' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/movies' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/music' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/books' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/audiobooks' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" ]; # Always prioritise Jellyfin IO @@ -166,8 +169,8 @@ in { services.jellyfin = { enable = cfg.enable; package = cfg.package; - user = user; - group = group; + user = globals.jellyfin.user; + group = globals.jellyfin.group; openFirewall = cfg.openFirewall; logDir = "${cfg.stateDir}/log"; cacheDir = "${cfg.stateDir}/cache"; diff --git a/nixarr/jellyseerr/default.nix b/nixarr/jellyseerr/default.nix index 80fe336..b84b681 100644 --- a/nixarr/jellyseerr/default.nix +++ b/nixarr/jellyseerr/default.nix @@ -6,11 +6,9 @@ }: with lib; let cfg = config.nixarr.jellyseerr; + globals = config.util-nixarr.globals; nixarr = config.nixarr; port = 5055; - uid = 294; - user = "jellyseerr"; - group = "jellyseerr"; in { options.nixarr.jellyseerr = { enable = mkOption { @@ -146,7 +144,7 @@ in { ]; systemd.tmpfiles.rules = [ - "d '${cfg.configDir}' 0700 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}' 0700 ${globals.jellyseerr.user} root - -" ]; systemd.services.jellyseerr = { @@ -155,15 +153,15 @@ in { wantedBy = ["multi-user.target"]; environment = { PORT = toString cfg.port; - CONFIG_DIRECTORY = cfg.configDir; + CONFIG_DIRECTORY = cfg.stateDir; }; serviceConfig = { Type = "exec"; StateDirectory = "jellyseerr"; DynamicUser = false; - User = cfg.user; - Group = cfg.group; + User = globals.jellyseerr.user; + Group = globals.jellyseerr.group; ExecStart = lib.getExe cfg.package; Restart = "on-failure"; @@ -183,17 +181,17 @@ in { RemoveIPC = true; PrivateMounts = true; ProtectSystem = "strict"; - ReadWritePaths = [cfg.configDir]; + ReadWritePaths = [cfg.stateDir]; }; }; users = { - users."${user}" = { + groups.${globals.jellyseerr.group}.gid = globals.gids.${globals.jellyseerr.group}; + users.${globals.jellyseerr.user} = { isSystemUser = true; - group = group; - uid = uid; + group = globals.jellyseerr.group; + uid = globals.uids.${globals.jellyseerr.user}; }; - groups."${group}" = {}; }; networking.firewall = mkIf cfg.expose.https.enable { diff --git a/nixarr/lidarr/default.nix b/nixarr/lidarr/default.nix index af5322e..e3952b9 100644 --- a/nixarr/lidarr/default.nix +++ b/nixarr/lidarr/default.nix @@ -6,10 +6,9 @@ }: with lib; let cfg = config.nixarr.lidarr; + globals = config.util-nixarr.globals; nixarr = config.nixarr; port = 8686; - user = "lidarr"; - group = "media"; in { options.nixarr.lidarr = { enable = mkOption { @@ -79,11 +78,25 @@ in { } ]; + users = { + groups.${globals.lidarr.group}.gid = globals.gids.${globals.lidarr.group}; + users.${globals.lidarr.user} = { + isSystemUser = true; + group = globals.lidarr.group; + uid = globals.uids.${globals.lidarr.user}; + }; + }; + + systemd.tmpfiles.rules = [ + "d '${nixarr.mediaDir}/library' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/music' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + ]; + services.lidarr = { enable = cfg.enable; package = cfg.package; - user = user; - group = group; + user = globals.lidarr.user; + group = globals.lidarr.group; settings.server.port = cfg.port; openFirewall = cfg.openFirewall; dataDir = cfg.stateDir; diff --git a/nixarr/plex/default.nix b/nixarr/plex/default.nix index 1838607..6fbbecd 100644 --- a/nixarr/plex/default.nix +++ b/nixarr/plex/default.nix @@ -6,10 +6,8 @@ }: with lib; let cfg = config.nixarr.plex; + globals = config.util-nixarr.globals; defaultPort = 32400; - uid = 242; - user = "streamer"; - group = "media"; nixarr = config.nixarr; in { options.nixarr.plex = { @@ -141,23 +139,21 @@ in { ]; users = { - groups."${group}" = {}; - users."${user}" = { + groups.${globals.plex.group}.gid = globals.gids.${globals.plex.group}; + users.${globals.plex.user} = { isSystemUser = true; group = group; - uid = uid; + uid = globals.uids.${globals.plex.user}; }; }; systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0700 ${user} root - -" - - # Media Dirs - "d '${nixarr.mediaDir}/library' 0775 ${user} ${group} - -" - "d '${nixarr.mediaDir}/library/shows' 0775 ${user} ${group} - -" - "d '${nixarr.mediaDir}/library/movies' 0775 ${user} ${group} - -" - "d '${nixarr.mediaDir}/library/music' 0775 ${user} ${group} - -" - "d '${nixarr.mediaDir}/library/books' 0775 ${user} ${group} - -" + "d '${nixarr.mediaDir}/library' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/shows' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/movies' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/music' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/books' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/audiobooks' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" ]; # Always prioritise Plex IO @@ -166,8 +162,8 @@ in { services.plex = { enable = cfg.enable; package = cfg.package; - user = user; - group = group; + user = globals.plex.user; + group = globals.plex.group; openFirewall = cfg.openFirewall; dataDir = cfg.stateDir; }; diff --git a/nixarr/prowlarr/default.nix b/nixarr/prowlarr/default.nix index 71263c7..a9f4fa6 100644 --- a/nixarr/prowlarr/default.nix +++ b/nixarr/prowlarr/default.nix @@ -6,10 +6,8 @@ }: with lib; let cfg = config.nixarr.prowlarr; + globals = config.util-nixarr.globals; nixarr = config.nixarr; - uid = 293; - user = "prowlarr"; - group = "prowlarr"; port = 9696; in { options.nixarr.prowlarr = { @@ -83,7 +81,7 @@ in { ]; systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0700 ${user} ${group} - -" + "d '${cfg.stateDir}' 0700 ${globals.prowlarr.user} root - -" ]; systemd.services.prowlarr = { @@ -94,8 +92,8 @@ in { serviceConfig = { Type = "simple"; - User = user; - Group = group; + User = globals.prowlarr.user; + Group = globals.prowlarr.group; ExecStart = "${lib.getExe cfg.package} -nobrowser -data=${cfg.stateDir}"; Restart = "on-failure"; }; @@ -106,11 +104,11 @@ in { }; users = { - groups."${group}" = {}; - users."${user}" = { - group = "prowlarr"; - home = cfg.stateDir; - uid = uid; + groups.${globals.prowlarr.group}.gid = globals.gids.${globals.prowlarr.group}; + users.${globals.prowlarr.user} = { + isSystemUser = true; + group = globals.prowlarr.group; + uid = globals.uids.${globals.prowlarr.user}; }; }; diff --git a/nixarr/radarr/default.nix b/nixarr/radarr/default.nix index 0390a6c..7520497 100644 --- a/nixarr/radarr/default.nix +++ b/nixarr/radarr/default.nix @@ -6,9 +6,8 @@ }: with lib; let cfg = config.nixarr.radarr; + globals = config.util-nixarr.globals; port = 7878; - user = "radarr"; - group = "media"; nixarr = config.nixarr; in { options.nixarr.radarr = { @@ -79,11 +78,25 @@ in { } ]; + systemd.tmpfiles.rules = [ + "d '${nixarr.mediaDir}/library' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/movies' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + ]; + + users = { + groups.${globals.radarr.group}.gid = globals.gids.${globals.radarr.group}; + users.${globals.radarr.user} = { + isSystemUser = true; + group = globals.radarr.group; + uid = globals.uids.${globals.radarr.user}; + }; + }; + services.radarr = { enable = cfg.enable; package = cfg.package; - user = "radarr"; - group = "media"; + user = globals.radarr.user; + group = globals.radarr.group; settings.server.port = cfg.port; openFirewall = cfg.openFirewall; dataDir = cfg.stateDir; diff --git a/nixarr/readarr-audiobook/default.nix b/nixarr/readarr-audiobook/default.nix index e0f89ca..6f75ea6 100644 --- a/nixarr/readarr-audiobook/default.nix +++ b/nixarr/readarr-audiobook/default.nix @@ -6,10 +6,8 @@ }: with lib; let cfg = config.nixarr.readarr-audiobook; + globals = config.util-nixarr.globals; nixarr = config.nixarr; - uid = 269; - user = "readarr"; - group = "readarr"; port = 9494; in { options.nixarr.readarr-audiobook = { @@ -82,8 +80,20 @@ in { } ]; + users = { + groups.${globals.readarr-audiobook.group}.gid = globals.gids.${globals.readarr-audiobook.group}; + users.${globals.readarr-audiobook.user} = { + isSystemUser = true; + group = globals.readarr-audiobook.group; + uid = globals.uids.${globals.readarr-audiobook.user}; + }; + }; + systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0700 ${user} ${group} - -" + "d '${cfg.stateDir}' 0700 ${globals.readarr-audiobook.user} root - -" + + "d '${nixarr.mediaDir}/library' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/audiobooks' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" ]; systemd.services.readarr-audiobook = { @@ -94,8 +104,8 @@ in { serviceConfig = { Type = "simple"; - User = user; - Group = group; + User = globals.readarr-audiobook.user; + Group = globals.readarr-audiobook.group; ExecStart = "${lib.getExe cfg.package} -nobrowser -data=${cfg.stateDir}"; Restart = "on-failure"; }; @@ -105,13 +115,6 @@ in { allowedTCPPorts = [cfg.port]; }; - users.users."${user}" = { - group = group; - home = cfg.stateDir; - uid = uid; - }; - users.groups."${group}" = {}; - # Enable and specify VPN namespace to confine service in. systemd.services.readarr-audiobook.vpnConfinement = mkIf cfg.vpn.enable { enable = true; diff --git a/nixarr/readarr/default.nix b/nixarr/readarr/default.nix index 709f66d..a8e4606 100644 --- a/nixarr/readarr/default.nix +++ b/nixarr/readarr/default.nix @@ -6,10 +6,8 @@ }: with lib; let cfg = config.nixarr.readarr; + globals = config.util-nixarr.globals; nixarr = config.nixarr; - uid = 250; - user = "readarr"; - group = "readarr"; port = 8787; in { options.nixarr.readarr = { @@ -80,8 +78,20 @@ in { } ]; + users = { + groups.${globals.readarr.group}.gid = globals.gids.${globals.readarr.group}; + users.${globals.readarr.user} = { + isSystemUser = true; + group = globals.readarr.group; + uid = globals.uids.${globals.readarr.user}; + }; + }; + systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0700 ${user} ${group} - -" + "d '${cfg.stateDir}' 0700 ${globals.readarr.user} root - -" + + "d '${nixarr.mediaDir}/library' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/books' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" ]; systemd.services.readarr = { @@ -92,8 +102,8 @@ in { serviceConfig = { Type = "simple"; - User = user; - Group = group; + User = globals.readarr.user; + Group = globals.readarr.group; ExecStart = "${lib.getExe cfg.package} -nobrowser -data=${cfg.stateDir}"; Restart = "on-failure"; }; @@ -103,13 +113,6 @@ in { allowedTCPPorts = [cfg.port]; }; - users.users.readarr = { - group = group; - home = cfg.stateDir; - uid = uid; - }; - users.groups.readarr = {}; - # Enable and specify VPN namespace to confine service in. systemd.services.readarr.vpnConfinement = mkIf cfg.vpn.enable { enable = true; diff --git a/nixarr/recyclarr/default.nix b/nixarr/recyclarr/default.nix index f4ea9d3..947d63c 100644 --- a/nixarr/recyclarr/default.nix +++ b/nixarr/recyclarr/default.nix @@ -7,6 +7,7 @@ }: with lib; let cfg = config.nixarr.recyclarr; + globals = config.util-nixarr.globals; nixarr = config.nixarr; format = pkgs.formats.yaml {}; @@ -186,6 +187,15 @@ in { } ]; + users = { + groups.${globals.recyclarr.group}.gid = globals.gids.${globals.recyclarr.group}; + users.${globals.recyclarr.user} = { + isSystemUser = true; + group = globals.recyclarr.group; + uid = globals.uids.${globals.recyclarr.user}; + }; + }; + services.recyclarr = { enable = true; package = cfg.package; diff --git a/nixarr/sabnzbd/default.nix b/nixarr/sabnzbd/default.nix index c42dde0..ee85606 100644 --- a/nixarr/sabnzbd/default.nix +++ b/nixarr/sabnzbd/default.nix @@ -6,6 +6,7 @@ }: with lib; let cfg = config.nixarr.sabnzbd; + globals = config.util-nixarr.globals; nixarr = config.nixarr; in { options.nixarr.sabnzbd = { @@ -185,33 +186,34 @@ in { ]; users = { - groups.usenet = {}; - users.usenet = { + groups.${globals.sabnzbd.group}.gid = globals.gids.${globals.sabnzbd.group}; + users.${globals.sabnzbd.user} = { isSystemUser = true; - group = "usenet"; + group = group; + uid = globals.uids.${globals.sabnzbd.user}; }; }; systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0700 usenet root - -" + "d '${cfg.stateDir}' 0700 ${globals.sabnzbd.user} root - -" "C ${cfg.stateDir}/sabnzbd.ini - - - - ${ini-base-config-file}" # Media dirs - "d '${nixarr.mediaDir}/usenet' 0755 usenet media - -" - "d '${nixarr.mediaDir}/usenet/.incomplete' 0755 usenet media - -" - "d '${nixarr.mediaDir}/usenet/.watch' 0755 usenet media - -" - "d '${nixarr.mediaDir}/usenet/manual' 0775 usenet media - -" - "d '${nixarr.mediaDir}/usenet/lidarr' 0775 usenet media - -" - "d '${nixarr.mediaDir}/usenet/radarr' 0775 usenet media - -" - "d '${nixarr.mediaDir}/usenet/sonarr' 0775 usenet media - -" - "d '${nixarr.mediaDir}/usenet/readarr' 0775 usenet media - -" + "d '${nixarr.mediaDir}/usenet' 0755 ${globals.sabnzbd.user} ${globals.sabnzbd.group} - -" + "d '${nixarr.mediaDir}/usenet/.incomplete' 0755 ${globals.sabnzbd.user} ${globals.sabnzbd.group} - -" + "d '${nixarr.mediaDir}/usenet/.watch' 0755 ${globals.sabnzbd.user} ${globals.sabnzbd.group} - -" + "d '${nixarr.mediaDir}/usenet/manual' 0775 ${globals.sabnzbd.user} ${globals.sabnzbd.group} - -" + "d '${nixarr.mediaDir}/usenet/lidarr' 0775 ${globals.sabnzbd.user} ${globals.sabnzbd.group} - -" + "d '${nixarr.mediaDir}/usenet/radarr' 0775 ${globals.sabnzbd.user} ${globals.sabnzbd.group} - -" + "d '${nixarr.mediaDir}/usenet/sonarr' 0775 ${globals.sabnzbd.user} ${globals.sabnzbd.group} - -" + "d '${nixarr.mediaDir}/usenet/readarr' 0775 ${globals.sabnzbd.user} ${globals.sabnzbd.group} - -" ]; services.sabnzbd = { enable = true; package = cfg.package; - user = "usenet"; - group = "media"; + user = globals.sabnzbd.user; + group = globals.sabnzbd.group; configFile = "${cfg.stateDir}/sabnzbd.ini"; }; diff --git a/nixarr/sonarr/default.nix b/nixarr/sonarr/default.nix index 34a5ccc..422937c 100644 --- a/nixarr/sonarr/default.nix +++ b/nixarr/sonarr/default.nix @@ -6,6 +6,7 @@ }: with lib; let cfg = config.nixarr.sonarr; + globals = config.util-nixarr.globals; defaultPort = 8989; nixarr = config.nixarr; in { @@ -71,11 +72,25 @@ in { } ]; + users = { + groups.${globals.sonarr.group}.gid = globals.gids.${globals.sonarr.group}; + users.${globals.sonarr.user} = { + isSystemUser = true; + group = globals.sonarr.group; + uid = globals.uids.${globals.sonarr.user}; + }; + }; + + systemd.tmpfiles.rules = [ + "d '${nixarr.mediaDir}/library' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + "d '${nixarr.mediaDir}/library/shows' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -" + ]; + services.sonarr = { enable = cfg.enable; package = cfg.package; - user = "sonarr"; - group = "media"; + user = globals.sonarr.user; + group = globals.sonarr.group; openFirewall = cfg.openFirewall; dataDir = cfg.stateDir; }; diff --git a/nixarr/transmission/cross-seed/default.nix b/nixarr/transmission/cross-seed/default.nix index b75b359..b637b77 100644 --- a/nixarr/transmission/cross-seed/default.nix +++ b/nixarr/transmission/cross-seed/default.nix @@ -85,7 +85,7 @@ in { systemd.tmpfiles.rules = [ "L+ '${cfg.dataDir}'/config.js - - - - ${configJs}" - "d '${cfg.dataDir}' 0700 ${cfg.user} ${cfg.group} - -" + "d '${cfg.dataDir}' 0700 ${cfg.user} root - -" ] ++ ( if cfg.settings.outputDir != null @@ -119,15 +119,13 @@ in { }; }; - users.users = mkIf (cfg.user == "cross-seed") { - cross-seed = { + users = { + groups.${cfg.group}.gid = globals.gids.${cfg.group}; + users.${cfg.user} = { isSystemUser = true; group = cfg.group; + uid = globals.uids.${cfg.user}; }; }; - - users.groups = mkIf (cfg.group == "cross-seed") { - cross-seed = {}; - }; }; } diff --git a/nixarr/transmission/default.nix b/nixarr/transmission/default.nix index 2d4ee1f..a8ede6b 100644 --- a/nixarr/transmission/default.nix +++ b/nixarr/transmission/default.nix @@ -6,7 +6,9 @@ }: with lib; let cfg = config.nixarr.transmission; + globals = config.util-nixarr.globals; nixarr = config.nixarr; + cfg-cross-seed = config.nixarr.transmission.privateTrackers.cross-seed; downloadDir = "${nixarr.mediaDir}/torrents"; transmissionCrossSeedScript = with builtins; @@ -284,37 +286,37 @@ in { ]; users = { - groups = { - torrenter = {}; - cross-seed = {}; - }; - users.torrenter = { + groups.${globals.transmission.group}.gid = globals.gids.${globals.transmission.group}; + groups.${globals.cross-seed.group}.gid = globals.gids.${globals.cross-seed.group}; + users.${globals.transmission.user} = { isSystemUser = true; - group = "torrenter"; + group = globals.transmission.group; + uid = globals.uids.${globals.transmission.user}; }; }; systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0750 torrenter cross-seed - -" + "d '${cfg.stateDir}' 0750 ${globals.transmission.user} ${globals.cross-seed.group} - -" # This is fixes a bug in nixpks (https://github.com/NixOS/nixpkgs/issues/291883) - "d '${cfg.stateDir}/.config' 0750 torrenter cross-seed - -" - "d '${cfg.stateDir}/.config/transmission-daemon' 0750 torrenter cross-seed - -" + "d '${cfg.stateDir}/.config' 0750 ${globals.transmission.user} ${globals.cross-seed.group} - -" + "d '${cfg.stateDir}/.config/transmission-daemon' 0750 ${globals.transmission.user} ${globals.cross-seed.group} - -" # Media Dirs - "d '${nixarr.mediaDir}/torrents' 0755 torrenter media - -" - "d '${nixarr.mediaDir}/torrents/.incomplete' 0755 torrenter media - -" - "d '${nixarr.mediaDir}/torrents/.watch' 0755 torrenter media - -" - "d '${nixarr.mediaDir}/torrents/manual' 0755 torrenter media - -" - "d '${nixarr.mediaDir}/torrents/lidarr' 0755 torrenter media - -" - "d '${nixarr.mediaDir}/torrents/radarr' 0755 torrenter media - -" - "d '${nixarr.mediaDir}/torrents/sonarr' 0755 torrenter media - -" - "d '${nixarr.mediaDir}/torrents/readarr' 0755 torrenter media - -" + "d '${nixarr.mediaDir}/torrents' 0755 ${globals.transmission.user} ${globals.transmission.group} - -" + "d '${nixarr.mediaDir}/torrents/.incomplete' 0755 ${globals.transmission.user} ${globals.transmission.group} - -" + "d '${nixarr.mediaDir}/torrents/.watch' 0755 ${globals.transmission.user} ${globals.transmission.group} - -" + "d '${nixarr.mediaDir}/torrents/manual' 0755 ${globals.transmission.user} ${globals.transmission.group} - -" + "d '${nixarr.mediaDir}/torrents/lidarr' 0755 ${globals.transmission.user} ${globals.transmission.group} - -" + "d '${nixarr.mediaDir}/torrents/radarr' 0755 ${globals.transmission.user} ${globals.transmission.group} - -" + "d '${nixarr.mediaDir}/torrents/sonarr' 0755 ${globals.transmission.user} ${globals.transmission.group} - -" + "d '${nixarr.mediaDir}/torrents/readarr' 0755 ${globals.transmission.user} ${globals.transmission.group} - -" ]; util-nixarr.services.cross-seed = mkIf cfg-cross-seed.enable { enable = true; dataDir = cfg-cross-seed.stateDir; - group = "cross-seed"; + user = globals.cross-seed.user; + group = globals.cross-seed.group; settings = { torrentDir = "${cfg.stateDir}/.config/transmission-daemon/torrents"; @@ -352,8 +354,8 @@ in { services.transmission = { enable = true; - user = "torrenter"; - group = "media"; + user = globals.transmission.user; + group = globals.transmission.group; home = cfg.stateDir; webHome = if cfg.flood.enable diff --git a/util/default.nix b/util/default.nix index 4c2a13e..d45be31 100644 --- a/util/default.nix +++ b/util/default.nix @@ -1,5 +1,6 @@ { imports = [ ./upnp + ./globals ]; } diff --git a/util/globals/default.nix b/util/globals/default.nix new file mode 100644 index 0000000..88fa464 --- /dev/null +++ b/util/globals/default.nix @@ -0,0 +1,112 @@ +# TODO: Dir creation and file permissions in nix +{ + pkgs, + config, + lib, + ... +}: +with lib; let + globals = config.util-nixarr.globals; +in { + options.util-nixarr.globals = mkOption { + type = types.attrs; + default = {}; + }; + + config.util-nixarr.globals = { + libraryOwner.user = "root"; + libraryOwner.group = "media"; + + uids = { + plex = 193; + jellyfin = 146; + audiobookshelf = 156; + autobrr = 188; + bazarr = 232; + lidarr = 306; + prowlarr = 293; + jellyseerr = 250; + sonarr = 274; + radarr = 275; + readarr = 250; + readarr-audiobook = 211; + recyclarr = 269; + sabnzbd = 38; + transmission = 70; + cross-seed = 183; + }; + gids = { + autobrr = 188; + prowlarr = 287; + cross-seed = 183; + jellyseerr = 250; + media = 169; + recyclarr = 269; + }; + + audiobookshelf = { + user = "audiobookshelf"; + group = globals.libraryOwner.group; + }; + autobrr = { + user = "autobrr"; + group = "autobrr"; + }; + bazarr = { + user = "bazarr"; + group = globals.libraryOwner.group; + }; + jellyfin = { + user = "jellyfin"; + group = globals.libraryOwner.group; + }; + jellyseerr = { + user = "jellyseerr"; + group = "jellyseerr"; + }; + lidarr = { + user = "lidarr"; + group = globals.libraryOwner.group; + }; + plex = { + user = "plex"; + group = globals.libraryOwner.group; + }; + prowlarr = { + user = "prowlarr"; + group = "prowlarr"; + }; + radarr = { + user = "radarr"; + group = globals.libraryOwner.group; + }; + readarr = { + user = "readarr"; + group = globals.libraryOwner.group; + }; + readarr-audiobook = { + user = "readarr-audiobook"; + readarr-group = globals.libraryOwner.group; + }; + recyclarr = { + user = "recyclarr"; + group = "recyclarr"; + }; + sabnzbd = { + user = "sabnzbd"; + group = globals.libraryOwner.group; + }; + sonarr = { + user = "sonarr"; + group = globals.libraryOwner.group; + }; + transmission = { + user = "transmission"; + group = globals.libraryOwner.group; + }; + cross-seed = { + user = "cross-seed"; + group = "cross-seed"; + }; + }; +}