diff options
Diffstat (limited to 'modules/piracy')
-rw-r--r-- | modules/piracy/default.nix | 177 | ||||
-rw-r--r-- | modules/piracy/jackett.nix | 46 | ||||
-rw-r--r-- | modules/piracy/lidarr.nix | 84 | ||||
-rw-r--r-- | modules/piracy/radarr.nix | 84 | ||||
-rw-r--r-- | modules/piracy/sonarr.nix | 84 |
5 files changed, 475 insertions, 0 deletions
diff --git a/modules/piracy/default.nix b/modules/piracy/default.nix new file mode 100644 index 0000000..be957f0 --- /dev/null +++ b/modules/piracy/default.nix @@ -0,0 +1,177 @@ +{ + config, + lib, + libNginx, + pkgs, + ... +}: +let + cfg = config.nixfiles.modules.piracy; +in +{ + imports = lib.attrValues (lib.modulesIn ./.); + + options.nixfiles.modules.piracy = { + enable = lib.mkEnableOption "tools for working with the BitTorrent protocol"; + + group = lib.mkOption { + type = lib.types.str; + default = "piracy"; + }; + gid = lib.mkOption { + type = lib.types.int; + default = 210; # Unused UID from Nixpkgs. + }; + + flood = { + enable = lib.mkEnableOption "Flood" // { + default = cfg.enable; + }; + + domain = lib.mkOption { + description = "Domain name sans protocol scheme."; + type = lib.types.str; + default = "flood.${config.networking.domain}"; + }; + }; + }; + + config = + let + files = "/export/rtorrent"; + socket = "/run/rtorrent/rpc.sock"; + in + lib.mkIf cfg.enable ( + lib.mkMerge [ + { + ark.directories = [ + config.services.rtorrent.dataDir + files + ]; + + services.rtorrent = { + enable = true; + + user = "rtorrent"; + inherit (cfg) group; + + rpcSocket = socket; + configText = + with config.services.rtorrent; + lib.mkForce '' + directory.default.set = ${files} + session.path.set = ${dataDir}/session + + network.port_range.set = ${toString port}-${toString port} + network.port_random.set = no + + dht.mode.set = disable + protocol.pex.set = no + + trackers.use_udp.set = no + + protocol.encryption.set = allow_incoming,try_outgoing,enable_retry + + pieces.memory.max.set = ${toString (lib.pow 2 11)}M + pieces.preload.type.set = 2 + + network.max_open_files.set = ${toString (lib.pow 2 13)} + network.max_open_sockets.set = ${toString (lib.pow 2 13)} + + network.http.max_open.set = ${toString (lib.pow 2 10)} + + throttle.global_down.max_rate.set_kb = 0 + throttle.global_up.max_rate.set_kb = 0 + + network.scgi.open_local = ${socket} + network.xmlrpc.size_limit.set = ${toString (lib.pow 2 17)} + + encoding.add = utf8 + system.umask.set = 0007 + + log.open_file = "log", "/var/log/rtorrent/log" + log.add_output = "info", "log" + ''; + }; + + systemd = { + sockets.rtorrent = { + socketConfig.ListenStream = socket; + wantedBy = [ "sockets.target" ]; + }; + + services.rtorrent = { + serviceConfig = { + UMask = "0007"; + RuntimeDirectory = "rtorrent"; + LogsDirectory = "rtorrent"; + ReadWritePaths = [ files ]; + }; + after = [ "rtorrent.socket" ]; + requires = [ "rtorrent.socket" ]; + }; + + tmpfiles.rules = with config.services.rtorrent; [ + "d '${files}' 0750 ${user} ${cfg.group} -" + ]; + }; + + users = { + users.${config.services.rtorrent.user}.uid = cfg.gid; + groups.${config.services.rtorrent.group}.gid = cfg.gid; + }; + my.extraGroups = [ cfg.group ]; + + boot.kernel.sysctl = { + "net.core.rmem_max" = lib.mkOverride 500 (lib.pow 2 24); + "net.core.wmem_max" = lib.mkOverride 500 (lib.pow 2 24); + "net.ipv4.tcp_fin_timeout" = lib.mkOverride 500 30; + "net.ipv4.tcp_rmem" = lib.mkOverride 500 (lib.mkTcpMem 12 23 24); + "net.ipv4.tcp_slow_start_after_idle" = 0; + "net.ipv4.tcp_tw_recycle" = lib.mkOverride 500 1; + "net.ipv4.tcp_tw_reuse" = lib.mkOverride 500 1; + "net.ipv4.tcp_wmem" = lib.mkOverride 500 (lib.mkTcpMem 12 23 24); + }; + } + (lib.mkIf cfg.flood.enable { + ark.directories = [ "/var/lib/private/flood" ]; + + nixfiles.modules.nginx = with config.services.flood; { + enable = true; + upstreams.flood.servers."${host}:${toString port}" = { }; + virtualHosts.${cfg.flood.domain} = { + root = "${package}/lib/node_modules/flood/dist/assets"; + locations = { + "/".tryFiles = "$uri /index.html"; + "/api" = { + proxyPass = "http://flood"; + extraConfig = libNginx.config.noProxyBuffering; + }; + }; + extraConfig = libNginx.config.internalOnly; + }; + }; + + services.flood = { + enable = true; + extraArgs = [ + "--auth=none" + "--assets=false" + "--allowedpath=${files}" + "--rtsocket=${socket}" + ]; + }; + + systemd.services.flood = { + path = [ pkgs.mediainfo ]; + serviceConfig = { + Group = cfg.group; + ReadOnlyPaths = [ files ]; + }; + after = [ "rtorrent.socket" ]; + requires = [ "rtorrent.socket" ]; + }; + }) + ] + ); +} diff --git a/modules/piracy/jackett.nix b/modules/piracy/jackett.nix new file mode 100644 index 0000000..7ef9311 --- /dev/null +++ b/modules/piracy/jackett.nix @@ -0,0 +1,46 @@ +{ + config, + inputs, + lib, + libNginx, + this, + ... +}: +let + cfg = config.nixfiles.modules.piracy.jackett; +in +{ + options.nixfiles.modules.piracy.jackett = { + enable = lib.mkEnableOption "Jackett"; + + domain = lib.mkOption { + description = "Domain name sans protocol scheme."; + type = lib.types.str; + default = "jackett.${config.networking.domain}"; + }; + }; + + config = lib.mkIf cfg.enable { + ark.directories = [ "/var/lib/jackett" ]; + + nixfiles.modules.nginx = { + enable = true; + upstreams.jackett.servers."127.0.0.1:9117" = { }; + virtualHosts.${cfg.domain} = { + locations."/".proxyPass = "http://jackett"; + extraConfig = libNginx.config.internalOnly; + }; + }; + + services.jackett.enable = true; + + topology = with cfg; { + nodes.${this.hostname}.services.jackett = { + name = "Jackett"; + icon = "${inputs.homelab-svg-assets}/assets/jackett.svg"; + info = domain; + details.listen.text = "127.0.0.1:9117"; + }; + }; + }; +} diff --git a/modules/piracy/lidarr.nix b/modules/piracy/lidarr.nix new file mode 100644 index 0000000..a905d8e --- /dev/null +++ b/modules/piracy/lidarr.nix @@ -0,0 +1,84 @@ +{ + config, + inputs, + lib, + libNginx, + this, + ... +}: +with lib; +let + cfg = config.nixfiles.modules.piracy.lidarr; + + port = 8686; +in +{ + options.nixfiles.modules.piracy.lidarr = { + enable = mkEnableOption "Lidarr"; + + domain = mkOption { + description = "Domain name sans protocol scheme."; + type = with types; str; + default = "lidarr.${config.networking.domain}"; + }; + }; + + config = mkIf cfg.enable { + secrets.lidarr-api-key.file = "${inputs.self}/secrets/lidarr-api-key"; + + ark.directories = [ "/var/lib/lidarr" ]; + + nixfiles.modules = { + nginx = { + enable = true; + upstreams.lidarr.servers."127.0.0.1:${toString port}" = { }; + virtualHosts.${cfg.domain} = { + locations."/".proxyPass = "http://lidarr"; + extraConfig = libNginx.config.internalOnly; + }; + }; + + piracy = { + enable = true; + jackett.enable = true; + }; + }; + + services = { + lidarr = { + enable = true; + group = "piracy"; + }; + + prometheus.exporters.exportarr-lidarr = { + enable = true; + url = "http://127.0.0.1"; + port = port + 10000; + apiKeyFile = config.secrets.lidarr-api-key.path; + inherit (config.services.lidarr) user; + inherit (config.services.lidarr) group; + listenAddress = this.wireguard.ipv4.address; + environment.CONFIG = "/var/lib/lidarr/.config/Lidarr/config.xml"; + }; + }; + + systemd = { + tmpfiles.rules = with config.services.lidarr; [ + "d /var/lib/lidarr/root 0755 ${user} ${group} - -" + ]; + + services.lidarr.after = [ + "flood.service" + "jackett.service" + "local-fs.target" + ]; + }; + + topology = with cfg; { + nodes.${this.hostname}.services.lidarr = { + info = domain; + details.listen.text = "127.0.0.1:${toString port}"; + }; + }; + }; +} diff --git a/modules/piracy/radarr.nix b/modules/piracy/radarr.nix new file mode 100644 index 0000000..ac2fe7f --- /dev/null +++ b/modules/piracy/radarr.nix @@ -0,0 +1,84 @@ +{ + config, + inputs, + lib, + libNginx, + this, + ... +}: +with lib; +let + cfg = config.nixfiles.modules.piracy.radarr; + + port = 7878; +in +{ + options.nixfiles.modules.piracy.radarr = { + enable = mkEnableOption "Radarr"; + + domain = mkOption { + description = "Domain name sans protocol scheme."; + type = with types; str; + default = "radarr.${config.networking.domain}"; + }; + }; + + config = mkIf cfg.enable { + secrets.radarr-api-key.file = "${inputs.self}/secrets/radarr-api-key"; + + ark.directories = [ "/var/lib/radarr" ]; + + nixfiles.modules = { + nginx = { + enable = true; + upstreams.radarr.servers."127.0.0.1:${toString port}" = { }; + virtualHosts.${cfg.domain} = { + locations."/".proxyPass = "http://radarr"; + extraConfig = libNginx.config.internalOnly; + }; + }; + + piracy = { + enable = true; + jackett.enable = true; + }; + }; + + services = { + radarr = { + enable = true; + group = "piracy"; + }; + + prometheus.exporters.exportarr-radarr = { + enable = true; + url = "http://127.0.0.1"; + port = port + 10000; + apiKeyFile = config.secrets.radarr-api-key.path; + inherit (config.services.radarr) user; + inherit (config.services.radarr) group; + listenAddress = this.wireguard.ipv4.address; + environment.CONFIG = "/var/lib/radarr/.config/Radarr/config.xml"; + }; + }; + + systemd = { + tmpfiles.rules = with config.services.radarr; [ + "d /var/lib/radarr/root 0755 ${user} ${group} - -" + ]; + + services.lidarr.after = [ + "flood.service" + "jackett.service" + "local-fs.target" + ]; + }; + + topology = with cfg; { + nodes.${this.hostname}.services.radarr = { + info = domain; + details.listen.text = "127.0.0.1:${toString port}"; + }; + }; + }; +} diff --git a/modules/piracy/sonarr.nix b/modules/piracy/sonarr.nix new file mode 100644 index 0000000..8715a12 --- /dev/null +++ b/modules/piracy/sonarr.nix @@ -0,0 +1,84 @@ +{ + config, + inputs, + lib, + libNginx, + this, + ... +}: +with lib; +let + cfg = config.nixfiles.modules.piracy.sonarr; + + port = 8989; +in +{ + options.nixfiles.modules.piracy.sonarr = { + enable = mkEnableOption "Sonarr"; + + domain = mkOption { + description = "Domain name sans protocol scheme."; + type = with types; str; + default = "sonarr.${config.networking.domain}"; + }; + }; + + config = mkIf cfg.enable { + secrets.sonarr-api-key.file = "${inputs.self}/secrets/sonarr-api-key"; + + ark.directories = [ "/var/lib/sonarr" ]; + + nixfiles.modules = { + nginx = { + enable = true; + upstreams.sonarr.servers."127.0.0.1:${toString port}" = { }; + virtualHosts.${cfg.domain} = { + locations."/".proxyPass = "http://sonarr"; + extraConfig = libNginx.config.internalOnly; + }; + }; + + piracy = { + enable = true; + jackett.enable = true; + }; + }; + + services = { + sonarr = { + enable = true; + group = "piracy"; + }; + + prometheus.exporters.exportarr-sonarr = { + enable = true; + url = "http://127.0.0.1"; + port = port + 10000; + apiKeyFile = config.secrets.sonarr-api-key.path; + inherit (config.services.sonarr) user; + inherit (config.services.sonarr) group; + listenAddress = this.wireguard.ipv4.address; + environment.CONFIG = "/var/lib/sonarr/.config/Sonarr/config.xml"; + }; + }; + + systemd = { + tmpfiles.rules = with config.services.sonarr; [ + "d /var/lib/sonarr/root 0755 ${user} ${group} - -" + ]; + + services.sonarr.after = [ + "flood.service" + "jackett.service" + "local-fs.target" + ]; + }; + + topology = with cfg; { + nodes.${this.hostname}.services.sonarr = { + info = domain; + details.listen.text = "127.0.0.1:${toString port}"; + }; + }; + }; +} |