about summary refs log tree commit diff
path: root/modules/nixos/rtorrent.nix
diff options
context:
space:
mode:
authorAzat Bahawi <azat@bahawi.net>2024-03-31 21:29:27 +0300
committerAzat Bahawi <azat@bahawi.net>2024-03-31 21:29:27 +0300
commit9a5427e3a0c0ccf2a82dc503149a26b23fbd6004 (patch)
treef28beec29deeea36038615a8fb98a810891940b5 /modules/nixos/rtorrent.nix
parent2024-03-19 (diff)
2024-03-31
Diffstat (limited to '')
-rw-r--r--modules/nixos/rtorrent.nix427
1 files changed, 230 insertions, 197 deletions
diff --git a/modules/nixos/rtorrent.nix b/modules/nixos/rtorrent.nix
index c39f306..82ef1b2 100644
--- a/modules/nixos/rtorrent.nix
+++ b/modules/nixos/rtorrent.nix
@@ -5,14 +5,18 @@
   pkgs,
   ...
 }:
-with lib; let
+with lib;
+let
   cfg = config.nixfiles.modules.rtorrent;
-in {
+in
+{
   options.nixfiles.modules.rtorrent = {
     enable = mkEnableOption "rTorrent";
 
     flood = {
-      enable = mkEnableOption "Flood" // {default = cfg.enable;};
+      enable = mkEnableOption "Flood" // {
+        default = cfg.enable;
+      };
 
       domain = mkOption {
         description = "Domain name sans protocol scheme.";
@@ -22,202 +26,223 @@ in {
     };
   };
 
-  config = let
-    user = "rtorrent";
-    group = "rtorrent";
-    baseDir = "/var/lib/rtorrent";
-    rpcSocket = "${baseDir}/rpc.socket";
-  in
+  config =
+    let
+      user = "rtorrent";
+      group = "rtorrent";
+      baseDir = "/var/lib/rtorrent";
+      rpcSocket = "${baseDir}/rpc.socket";
+    in
     mkIf cfg.enable (mkMerge [
-      (let
-        port = 50000;
-      in {
-        ark.directories = [baseDir];
-
-        systemd = {
-          services.rtorrent = {
-            description = "rTorrent";
-            after = ["network.target" "local-fs.target"];
-            serviceConfig = let
-              leechDir = "${baseDir}/leech";
-              seedDir = "${baseDir}/seed";
-              sessionDir = "${baseDir}/session";
-              logDir = "${baseDir}/log";
-              configFile = let
-                moveCompleted = getExe (pkgs.writeShellApplication {
-                  name = "move-completed";
-                  runtimeInputs = with pkgs; [
-                    coreutils-full
-                    gnused
-                    findutils
+      (
+        let
+          port = 50000;
+        in
+        {
+          ark.directories = [ baseDir ];
+
+          systemd = {
+            services.rtorrent = {
+              description = "rTorrent";
+              after = [
+                "network.target"
+                "local-fs.target"
+              ];
+              serviceConfig =
+                let
+                  leechDir = "${baseDir}/leech";
+                  seedDir = "${baseDir}/seed";
+                  sessionDir = "${baseDir}/session";
+                  logDir = "${baseDir}/log";
+                  configFile =
+                    let
+                      moveCompleted = getExe (
+                        pkgs.writeShellApplication {
+                          name = "move-completed";
+                          runtimeInputs = with pkgs; [
+                            coreutils-full
+                            gnused
+                            findutils
+                          ];
+                          text = ''
+                            set -x
+
+                            leech_path="$1"
+                            seed_path="$2"
+                            # seed_path="$(echo "$2" | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf '%b')"
+
+                            mkdir -pv "$seed_path"
+                            mv -fv "$leech_path" "$seed_path"
+                          '';
+                        }
+                      );
+                    in
+                    pkgs.writeText "rtorrent.rc" ''
+                      method.insert = cfg.leech,     private|const|string, (cat, "${leechDir}")
+                      method.insert = cfg.seed,      private|const|string, (cat, "${seedDir}")
+                      method.insert = cfg.session,   private|const|string, (cat, "${sessionDir}")
+                      method.insert = cfg.log,       private|const|string, (cat, "${logDir}")
+                      method.insert = cfg.rpcsocket, private|const|string, (cat, "${rpcSocket}")
+
+                      directory.default.set = (cat, (cfg.leech))
+                      session.path.set = (cat, (cfg.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 (pow 2 11)}M
+                      pieces.preload.type.set = 2
+
+                      network.xmlrpc.size_limit.set = ${toString (pow 2 17)}
+
+                      network.max_open_files.set   = ${toString (pow 2 10)}
+                      network.max_open_sockets.set = ${toString (pow 2 10)}
+
+                      network.http.max_open.set = ${toString (pow 2 8)}
+
+                      throttle.global_down.max_rate.set_kb = 0
+                      throttle.global_up.max_rate.set_kb   = 0
+
+                      encoding.add = UTF-8
+                      system.umask.set = 0027
+                      system.cwd.set = (directory.default)
+
+                      network.scgi.open_local = (cat, (cfg.rpcsocket))
+
+                      method.insert = d.move_completed, simple, "\
+                        d.directory.set=$argument.1=;\
+                        execute=${moveCompleted}, $argument.0=, $argument.1=;\
+                        d.save_full_session=\
+                      "
+                      method.insert = d.leech_path, simple, "\
+                        if=(d.is_multi_file),\
+                        (cat, (d.directory), /),\
+                        (cat, (d.directory), /, (d.name))\
+                      "
+                      method.insert = d.seed_path, simple, "\
+                        cat=$cfg.seed=, /, $d.custom1=\
+                      "
+                      method.set_key = event.download.finished, move_complete, "\
+                        d.move_completed=$d.leech_path=, $d.seed_path=\
+                      "
+
+                      log.open_file = "log", (cat, (cfg.log), "/", "default.log")
+                      log.add_output = "info", "log"
+                      log.execute = (cat, (cfg.log), "/", "execute.log")
+                    '';
+                in
+                {
+                  Restart = "on-failure";
+                  RestartSec = 3;
+
+                  KillMode = "process";
+                  KillSignal = "SIGHUP";
+
+                  User = user;
+                  Group = group;
+
+                  ExecStartPre = concatStringsSep " " [
+                    "${pkgs.coreutils-full}/bin/mkdir -p"
+                    leechDir
+                    seedDir
+                    sessionDir
+                    logDir
+                  ];
+                  ExecStart = concatStringsSep " " [
+                    (getExe pkgs.rtorrent)
+                    "-n"
+                    "-o system.daemon.set=true"
+                    "-o network.bind_address.set=0.0.0.0"
+                    "-o import=${configFile}"
+                  ];
+                  ExecStop = concatStringsSep " " [
+                    "${pkgs.coreutils-full}/bin/rm -rf"
+                    rpcSocket
                   ];
-                  text = ''
-                    set -x
-
-                    leech_path="$1"
-                    seed_path="$2"
-                    # seed_path="$(echo "$2" | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf '%b')"
-
-                    mkdir -pv "$seed_path"
-                    mv -fv "$leech_path" "$seed_path"
-                  '';
-                });
-              in
-                pkgs.writeText "rtorrent.rc" ''
-                  method.insert = cfg.leech,     private|const|string, (cat, "${leechDir}")
-                  method.insert = cfg.seed,      private|const|string, (cat, "${seedDir}")
-                  method.insert = cfg.session,   private|const|string, (cat, "${sessionDir}")
-                  method.insert = cfg.log,       private|const|string, (cat, "${logDir}")
-                  method.insert = cfg.rpcsocket, private|const|string, (cat, "${rpcSocket}")
-
-                  directory.default.set = (cat, (cfg.leech))
-                  session.path.set = (cat, (cfg.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 (pow 2 11)}M
-                  pieces.preload.type.set = 2
-
-                  network.xmlrpc.size_limit.set = ${toString (pow 2 17)}
-
-                  network.max_open_files.set   = ${toString (pow 2 10)}
-                  network.max_open_sockets.set = ${toString (pow 2 10)}
-
-                  network.http.max_open.set = ${toString (pow 2 8)}
-
-                  throttle.global_down.max_rate.set_kb = 0
-                  throttle.global_up.max_rate.set_kb   = 0
-
-                  encoding.add = UTF-8
-                  system.umask.set = 0027
-                  system.cwd.set = (directory.default)
-
-                  network.scgi.open_local = (cat, (cfg.rpcsocket))
-
-                  method.insert = d.move_completed, simple, "\
-                    d.directory.set=$argument.1=;\
-                    execute=${moveCompleted}, $argument.0=, $argument.1=;\
-                    d.save_full_session=\
-                  "
-                  method.insert = d.leech_path, simple, "\
-                    if=(d.is_multi_file),\
-                    (cat, (d.directory), /),\
-                    (cat, (d.directory), /, (d.name))\
-                  "
-                  method.insert = d.seed_path, simple, "\
-                    cat=$cfg.seed=, /, $d.custom1=\
-                  "
-                  method.set_key = event.download.finished, move_complete, "\
-                    d.move_completed=$d.leech_path=, $d.seed_path=\
-                  "
-
-                  log.open_file = "log", (cat, (cfg.log), "/", "default.log")
-                  log.add_output = "info", "log"
-                  log.execute = (cat, (cfg.log), "/", "execute.log")
-                '';
-            in {
-              Restart = "on-failure";
-              RestartSec = 3;
-
-              KillMode = "process";
-              KillSignal = "SIGHUP";
 
-              User = user;
-              Group = group;
+                  RuntimeDirectory = "rtorrent";
+                  RuntimeDirectoryMode = 750;
+                  UMask = 27;
+                  AmbientCapabilities = [ "" ];
+                  CapabilityBoundingSet = [ "" ];
+                  LockPersonality = true;
+                  MemoryDenyWriteExecute = true;
+                  NoNewPrivileges = true;
+                  PrivateDevices = true;
+                  PrivateTmp = true;
+                  PrivateUsers = true;
+                  ProtectClock = true;
+                  ProtectControlGroups = true;
+                  ProtectHome = true;
+                  ProtectHostname = true;
+                  ProtectKernelLogs = true;
+                  ProtectKernelModules = true;
+                  ProtectKernelTunables = true;
+                  ProcSubset = "pid";
+                  RemoveIPC = true;
+                  RestrictAddressFamilies = [
+                    "AF_UNIX"
+                    "AF_INET"
+                    "AF_INET6"
+                  ];
+                  RestrictNamespaces = true;
+                  RestrictRealtime = true;
+                  RestrictSUIDSGID = true;
+                  SystemCallArchitectures = "native";
+                  SystemCallFilter = [
+                    "@system-service"
+                    "~@resources"
+                    "~@privileged"
+                  ];
+                };
+              wantedBy = [ "multi-user.target" ];
+            };
 
-              ExecStartPre = concatStringsSep " " [
-                "${pkgs.coreutils-full}/bin/mkdir -p"
-                leechDir
-                seedDir
-                sessionDir
-                logDir
-              ];
-              ExecStart = concatStringsSep " " [
-                (getExe pkgs.rtorrent)
-                "-n"
-                "-o system.daemon.set=true"
-                "-o network.bind_address.set=0.0.0.0"
-                "-o import=${configFile}"
-              ];
-              ExecStop = concatStringsSep " " [
-                "${pkgs.coreutils-full}/bin/rm -rf"
-                rpcSocket
-              ];
+            tmpfiles.rules = [ "d '${baseDir}' 0750 ${user} ${group} -" ];
+          };
 
-              RuntimeDirectory = "rtorrent";
-              RuntimeDirectoryMode = 0750;
-              UMask = 0027;
-              AmbientCapabilities = [""];
-              CapabilityBoundingSet = [""];
-              LockPersonality = true;
-              MemoryDenyWriteExecute = true;
-              NoNewPrivileges = true;
-              PrivateDevices = true;
-              PrivateTmp = true;
-              PrivateUsers = true;
-              ProtectClock = true;
-              ProtectControlGroups = true;
-              ProtectHome = true;
-              ProtectHostname = true;
-              ProtectKernelLogs = true;
-              ProtectKernelModules = true;
-              ProtectKernelTunables = true;
-              ProcSubset = "pid";
-              RemoveIPC = true;
-              RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"];
-              RestrictNamespaces = true;
-              RestrictRealtime = true;
-              RestrictSUIDSGID = true;
-              SystemCallArchitectures = "native";
-              SystemCallFilter = ["@system-service" "~@resources" "~@privileged"];
+          users = {
+            users.${user} = {
+              inherit group;
+              shell = pkgs.bashInteractive;
+              home = baseDir;
+              description = "rTorrent";
+              isSystemUser = true;
             };
-            wantedBy = ["multi-user.target"];
+            groups.${group} = { };
           };
-
-          tmpfiles.rules = ["d '${baseDir}' 0750 ${user} ${group} -"];
-        };
-
-        users = {
-          users.${user} = {
-            inherit group;
-            shell = pkgs.bashInteractive;
-            home = baseDir;
-            description = "rTorrent";
-            isSystemUser = true;
+          my.extraGroups = [ group ];
+
+          networking.firewall.allowedTCPPorts = [ port ];
+
+          boot.kernel.sysctl = {
+            "net.core.rmem_max" = mkOverride 500 (pow 2 24);
+            "net.core.wmem_max" = mkOverride 500 (pow 2 24);
+            "net.ipv4.tcp_fin_timeout" = mkOverride 500 30;
+            "net.ipv4.tcp_rmem" = mkOverride 500 (mkTcpMem 12 23 24);
+            "net.ipv4.tcp_slow_start_after_idle" = 0;
+            "net.ipv4.tcp_tw_recycle" = mkOverride 500 1;
+            "net.ipv4.tcp_tw_reuse" = mkOverride 500 1;
+            "net.ipv4.tcp_wmem" = mkOverride 500 (mkTcpMem 12 23 24);
           };
-          groups.${group} = {};
-        };
-        my.extraGroups = [group];
-
-        networking.firewall.allowedTCPPorts = [port];
-
-        boot.kernel.sysctl = {
-          "net.core.rmem_max" = mkOverride 500 (pow 2 24);
-          "net.core.wmem_max" = mkOverride 500 (pow 2 24);
-          "net.ipv4.tcp_fin_timeout" = mkOverride 500 30;
-          "net.ipv4.tcp_rmem" = mkOverride 500 (mkTcpMem 12 23 24);
-          "net.ipv4.tcp_slow_start_after_idle" = 0;
-          "net.ipv4.tcp_tw_recycle" = mkOverride 500 1;
-          "net.ipv4.tcp_tw_reuse" = mkOverride 500 1;
-          "net.ipv4.tcp_wmem" = mkOverride 500 (mkTcpMem 12 23 24);
-        };
-      })
-      (let
-        port = 50001;
-        pkg = pkgs.nodePackages.flood;
-      in
+        }
+      )
+      (
+        let
+          port = 50001;
+          pkg = pkgs.nodePackages.flood;
+        in
         mkIf cfg.flood.enable {
           nixfiles.modules.nginx = {
             enable = true;
-            upstreams.flood.servers."127.0.0.1:${toString port}" = {};
+            upstreams.flood.servers."127.0.0.1:${toString port}" = { };
             virtualHosts.${cfg.flood.domain} = {
               root = "${pkg}/lib/node_modules/flood/dist/assets";
               locations = {
@@ -233,8 +258,11 @@ in {
 
           systemd.services.flood = {
             description = "Flood";
-            after = ["network.target" "rtorrent.service"];
-            path = with pkgs; [mediainfo];
+            after = [
+              "network.target"
+              "rtorrent.service"
+            ];
+            path = with pkgs; [ mediainfo ];
             serviceConfig = {
               Restart = "on-failure";
               RestartSec = 3;
@@ -255,10 +283,10 @@ in {
               ];
 
               RuntimeDirectory = "rtorrent";
-              RuntimeDirectoryMode = 0750;
-              UMask = 0027;
-              AmbientCapabilities = [""];
-              CapabilityBoundingSet = [""];
+              RuntimeDirectoryMode = 750;
+              UMask = 27;
+              AmbientCapabilities = [ "" ];
+              CapabilityBoundingSet = [ "" ];
               LockPersonality = true;
               NoNewPrivileges = true;
               PrivateDevices = true;
@@ -274,7 +302,11 @@ in {
               ProcSubset = "pid";
               ProtectProc = "invisible";
               RemoveIPC = true;
-              RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"];
+              RestrictAddressFamilies = [
+                "AF_UNIX"
+                "AF_INET"
+                "AF_INET6"
+              ];
               RestrictNamespaces = true;
               RestrictRealtime = true;
               RestrictSUIDSGID = true;
@@ -288,8 +320,9 @@ in {
                 "~@resources"
               ];
             };
-            wantedBy = ["multi-user.target"];
+            wantedBy = [ "multi-user.target" ];
           };
-        })
+        }
+      )
     ]);
 }

Consider giving Nix/NixOS a try! <3