at 25.11-pre 7.6 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 cfg = config.services.aria2; 10 11 homeDir = "/var/lib/aria2"; 12 defaultRpcListenPort = 6800; 13 defaultDir = "${homeDir}/Downloads"; 14 15 portRangesToString = 16 ranges: 17 lib.concatStringsSep "," ( 18 map ( 19 x: 20 if x.from == x.to then 21 builtins.toString x.from 22 else 23 builtins.toString x.from + "-" + builtins.toString x.to 24 ) ranges 25 ); 26 27 customToKeyValue = lib.generators.toKeyValue { 28 mkKeyValue = lib.generators.mkKeyValueDefault { 29 mkValueString = 30 v: if builtins.isList v then portRangesToString v else lib.generators.mkValueStringDefault { } v; 31 } "="; 32 }; 33in 34{ 35 imports = [ 36 (lib.mkRemovedOptionModule [ 37 "services" 38 "aria2" 39 "rpcSecret" 40 ] "Use services.aria2.rpcSecretFile instead") 41 (lib.mkRemovedOptionModule [ 42 "services" 43 "aria2" 44 "extraArguments" 45 ] "Use services.aria2.settings instead") 46 (lib.mkRenamedOptionModule 47 [ "services" "aria2" "downloadDir" ] 48 [ "services" "aria2" "settings" "dir" ] 49 ) 50 (lib.mkRenamedOptionModule 51 [ "services" "aria2" "listenPortRange" ] 52 [ "services" "aria2" "settings" "listen-port" ] 53 ) 54 (lib.mkRenamedOptionModule 55 [ "services" "aria2" "rpcListenPort" ] 56 [ "services" "aria2" "settings" "rpc-listen-port" ] 57 ) 58 ]; 59 60 options = { 61 services.aria2 = { 62 enable = lib.mkOption { 63 type = lib.types.bool; 64 default = false; 65 description = '' 66 Whether or not to enable the headless Aria2 daemon service. 67 68 Aria2 daemon can be controlled via the RPC interface using one of many 69 WebUIs (http://localhost:${toString defaultRpcListenPort}/ by default). 70 71 Targets are downloaded to `${defaultDir}` by default and are 72 accessible to users in the `aria2` group. 73 ''; 74 }; 75 openPorts = lib.mkOption { 76 type = lib.types.bool; 77 default = false; 78 description = '' 79 Open listen and RPC ports found in `settings.listen-port` and 80 `settings.rpc-listen-port` options in the firewall. 81 ''; 82 }; 83 rpcSecretFile = lib.mkOption { 84 type = lib.types.path; 85 example = "/run/secrets/aria2-rpc-token.txt"; 86 description = '' 87 A file containing the RPC secret authorization token. 88 Read https://aria2.github.io/manual/en/html/aria2c.html#rpc-auth to know how this option value is used. 89 ''; 90 }; 91 downloadDirPermission = lib.mkOption { 92 type = lib.types.str; 93 default = "0770"; 94 description = '' 95 The permission for `settings.dir`. 96 97 The default is 0770, which denies access for users not in the `aria2` 98 group. 99 100 You may want to adjust `serviceUMask` as well, which further restricts 101 the file permission for newly created files (i.e. the downloads). 102 ''; 103 }; 104 serviceUMask = lib.mkOption { 105 type = lib.types.str; 106 default = "0022"; 107 example = "0002"; 108 description = '' 109 The file mode creation mask for Aria2 service. 110 111 The default is 0022 for compatibility reason, as this is the default 112 used by systemd. However, this results in file permission 0644 for new 113 files, and denies `aria2` group member from modifying the file. 114 115 You may want to set this value to `0002` so you can manage the file 116 more easily. 117 ''; 118 }; 119 settings = lib.mkOption { 120 description = '' 121 Generates the `aria2.conf` file. Refer to [the documentation][0] for 122 all possible settings. 123 124 [0]: https://aria2.github.io/manual/en/html/aria2c.html#synopsis 125 ''; 126 default = { }; 127 type = lib.types.submodule { 128 freeformType = 129 with lib.types; 130 attrsOf (oneOf [ 131 bool 132 int 133 float 134 singleLineStr 135 ]); 136 options = { 137 save-session = lib.mkOption { 138 type = lib.types.singleLineStr; 139 default = "${homeDir}/aria2.session"; 140 description = "Save error/unfinished downloads to FILE on exit."; 141 }; 142 dir = lib.mkOption { 143 type = lib.types.singleLineStr; 144 default = defaultDir; 145 description = "Directory to store downloaded files."; 146 }; 147 conf-path = lib.mkOption { 148 type = lib.types.singleLineStr; 149 default = "${homeDir}/aria2.conf"; 150 description = "Configuration file path."; 151 }; 152 enable-rpc = lib.mkOption { 153 type = lib.types.bool; 154 default = true; 155 description = "Enable JSON-RPC/XML-RPC server."; 156 }; 157 listen-port = lib.mkOption { 158 type = with lib.types; listOf (attrsOf port); 159 default = [ 160 { 161 from = 6881; 162 to = 6999; 163 } 164 ]; 165 description = "Set UDP listening port range used by DHT(IPv4, IPv6) and UDP tracker."; 166 }; 167 rpc-listen-port = lib.mkOption { 168 type = lib.types.port; 169 default = defaultRpcListenPort; 170 description = "Specify a port number for JSON-RPC/XML-RPC server to listen to. Possible Values: 1024-65535"; 171 }; 172 }; 173 }; 174 }; 175 }; 176 }; 177 178 config = lib.mkIf cfg.enable { 179 assertions = [ 180 { 181 assertion = cfg.settings.enable-rpc; 182 message = "RPC has to be enabled, the default module option takes care of that."; 183 } 184 { 185 assertion = !(cfg.settings ? rpc-secret); 186 message = "Set the RPC secret through services.aria2.rpcSecretFile so it will not end up in the world-readable nix store."; 187 } 188 ]; 189 190 # Need to open ports for proper functioning 191 networking.firewall = lib.mkIf cfg.openPorts { 192 allowedUDPPortRanges = config.services.aria2.settings.listen-port; 193 allowedTCPPorts = [ config.services.aria2.settings.rpc-listen-port ]; 194 }; 195 196 users.users.aria2 = { 197 group = "aria2"; 198 uid = config.ids.uids.aria2; 199 description = "aria2 user"; 200 home = homeDir; 201 createHome = false; 202 }; 203 204 users.groups.aria2.gid = config.ids.gids.aria2; 205 206 systemd.tmpfiles.rules = [ 207 "d '${homeDir}' 0770 aria2 aria2 - -" 208 "d '${config.services.aria2.settings.dir}' ${config.services.aria2.downloadDirPermission} aria2 aria2 - -" 209 ]; 210 211 systemd.services.aria2 = { 212 description = "aria2 Service"; 213 after = [ "network.target" ]; 214 wantedBy = [ "multi-user.target" ]; 215 preStart = '' 216 if [[ ! -e "${cfg.settings.save-session}" ]] 217 then 218 touch "${cfg.settings.save-session}" 219 fi 220 cp -f "${pkgs.writeText "aria2.conf" (customToKeyValue cfg.settings)}" "${cfg.settings.conf-path}" 221 chmod +w "${cfg.settings.conf-path}" 222 echo "rpc-secret=$(cat "$CREDENTIALS_DIRECTORY/rpcSecretFile")" >> "${cfg.settings.conf-path}" 223 ''; 224 225 serviceConfig = { 226 Restart = "on-abort"; 227 ExecStart = "${pkgs.aria2}/bin/aria2c --conf-path=${cfg.settings.conf-path}"; 228 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 229 User = "aria2"; 230 Group = "aria2"; 231 LoadCredential = "rpcSecretFile:${cfg.rpcSecretFile}"; 232 UMask = cfg.serviceUMask; 233 }; 234 }; 235 }; 236 237 meta.maintainers = [ lib.maintainers.timhae ]; 238}