nixpkgs-suyu/nixos/modules/services/torrent/deluge.nix
pennae 2e751c0772 treewide: automatically md-convert option descriptions
the conversion procedure is simple:

 - find all things that look like options, ie calls to either `mkOption`
   or `lib.mkOption` that take an attrset. remember the attrset as the
   option
 - for all options, find a `description` attribute who's value is not a
   call to `mdDoc` or `lib.mdDoc`
 - textually convert the entire value of the attribute to MD with a few
   simple regexes (the set from mdize-module.sh)
 - if the change produced a change in the manual output, discard
 - if the change kept the manual unchanged, add some text to the
   description to make sure we've actually found an option. if the
   manual changes this time, keep the converted description

this procedure converts 80% of nixos options to markdown. around 2000
options remain to be inspected, but most of those fail the "does not
change the manual output check": currently the MD conversion process
does not faithfully convert docbook tags like <code> and <package>, so
any option using such tags will not be converted at all.
2022-07-30 15:16:34 +02:00

279 lines
9.2 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.deluge;
cfg_web = config.services.deluge.web;
isDeluge1 = versionOlder cfg.package.version "2.0.0";
openFilesLimit = 4096;
listenPortsDefault = [ 6881 6889 ];
listToRange = x: { from = elemAt x 0; to = elemAt x 1; };
configDir = "${cfg.dataDir}/.config/deluge";
configFile = pkgs.writeText "core.conf" (builtins.toJSON cfg.config);
declarativeLockFile = "${configDir}/.declarative";
preStart = if cfg.declarative then ''
if [ -e ${declarativeLockFile} ]; then
# Was declarative before, no need to back up anything
${if isDeluge1 then "ln -sf" else "cp"} ${configFile} ${configDir}/core.conf
ln -sf ${cfg.authFile} ${configDir}/auth
else
# Declarative for the first time, backup stateful files
${if isDeluge1 then "ln -s" else "cp"} -b --suffix=.stateful ${configFile} ${configDir}/core.conf
ln -sb --suffix=.stateful ${cfg.authFile} ${configDir}/auth
echo "Autogenerated file that signifies that this server configuration is managed declaratively by NixOS" \
> ${declarativeLockFile}
fi
'' else ''
if [ -e ${declarativeLockFile} ]; then
rm ${declarativeLockFile}
fi
'';
in {
options = {
services = {
deluge = {
enable = mkEnableOption "Deluge daemon";
openFilesLimit = mkOption {
default = openFilesLimit;
type = types.either types.int types.str;
description = lib.mdDoc ''
Number of files to allow deluged to open.
'';
};
config = mkOption {
type = types.attrs;
default = {};
example = literalExpression ''
{
download_location = "/srv/torrents/";
max_upload_speed = "1000.0";
share_ratio_limit = "2.0";
allow_remote = true;
daemon_port = 58846;
listen_ports = [ ${toString listenPortsDefault} ];
}
'';
description = lib.mdDoc ''
Deluge core configuration for the core.conf file. Only has an effect
when {option}`services.deluge.declarative` is set to
`true`. String values must be quoted, integer and
boolean values must not. See
<https://git.deluge-torrent.org/deluge/tree/deluge/core/preferencesmanager.py#n41>
for the availaible options.
'';
};
declarative = mkOption {
type = types.bool;
default = false;
description = lib.mdDoc ''
Whether to use a declarative deluge configuration.
Only if set to `true`, the options
{option}`services.deluge.config`,
{option}`services.deluge.openFirewall` and
{option}`services.deluge.authFile` will be
applied.
'';
};
openFirewall = mkOption {
default = false;
type = types.bool;
description = lib.mdDoc ''
Whether to open the firewall for the ports in
{option}`services.deluge.config.listen_ports`. It only takes effet if
{option}`services.deluge.declarative` is set to
`true`.
It does NOT apply to the daemon port nor the web UI port. To access those
ports secuerly check the documentation
<https://dev.deluge-torrent.org/wiki/UserGuide/ThinClient#CreateSSHTunnel>
or use a VPN or configure certificates for deluge.
'';
};
dataDir = mkOption {
type = types.path;
default = "/var/lib/deluge";
description = lib.mdDoc ''
The directory where deluge will create files.
'';
};
authFile = mkOption {
type = types.path;
example = "/run/keys/deluge-auth";
description = lib.mdDoc ''
The file managing the authentication for deluge, the format of this
file is straightforward, each line contains a
username:password:level tuple in plaintext. It only has an effect
when {option}`services.deluge.declarative` is set to
`true`.
See <https://dev.deluge-torrent.org/wiki/UserGuide/Authentication> for
more informations.
'';
};
user = mkOption {
type = types.str;
default = "deluge";
description = lib.mdDoc ''
User account under which deluge runs.
'';
};
group = mkOption {
type = types.str;
default = "deluge";
description = lib.mdDoc ''
Group under which deluge runs.
'';
};
extraPackages = mkOption {
type = types.listOf types.package;
default = [];
description = lib.mdDoc ''
Extra packages available at runtime to enable Deluge's plugins. For example,
extraction utilities are required for the built-in "Extractor" plugin.
This always contains unzip, gnutar, xz and bzip2.
'';
};
package = mkOption {
type = types.package;
example = literalExpression "pkgs.deluge-2_x";
description = lib.mdDoc ''
Deluge package to use.
'';
};
};
deluge.web = {
enable = mkEnableOption "Deluge Web daemon";
port = mkOption {
type = types.port;
default = 8112;
description = lib.mdDoc ''
Deluge web UI port.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = lib.mdDoc ''
Open ports in the firewall for deluge web daemon
'';
};
};
};
};
config = mkIf cfg.enable {
services.deluge.package = mkDefault (
if versionAtLeast config.system.stateVersion "20.09" then
pkgs.deluge-2_x
else
# deluge-1_x is no longer packaged and this will resolve to an error
# thanks to the alias for this name. This is left here so that anyone
# using NixOS older than 20.09 receives that error when they upgrade
# and is forced to make an intentional choice to switch to deluge-2_x.
# That might be slightly inconvenient but there is no path to
# downgrade from 2.x to 1.x so NixOS should not automatically perform
# this state migration.
pkgs.deluge-1_x
);
# Provide a default set of `extraPackages`.
services.deluge.extraPackages = with pkgs; [ unzip gnutar xz bzip2 ];
systemd.tmpfiles.rules = [
"d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group}"
"d '${cfg.dataDir}/.config' 0770 ${cfg.user} ${cfg.group}"
"d '${cfg.dataDir}/.config/deluge' 0770 ${cfg.user} ${cfg.group}"
]
++ optional (cfg.config ? download_location)
"d '${cfg.config.download_location}' 0770 ${cfg.user} ${cfg.group}"
++ optional (cfg.config ? torrentfiles_location)
"d '${cfg.config.torrentfiles_location}' 0770 ${cfg.user} ${cfg.group}"
++ optional (cfg.config ? move_completed_path)
"d '${cfg.config.move_completed_path}' 0770 ${cfg.user} ${cfg.group}";
systemd.services.deluged = {
after = [ "network.target" ];
description = "Deluge BitTorrent Daemon";
wantedBy = [ "multi-user.target" ];
path = [ cfg.package ] ++ cfg.extraPackages;
serviceConfig = {
ExecStart = ''
${cfg.package}/bin/deluged \
--do-not-daemonize \
--config ${configDir}
'';
# To prevent "Quit & shutdown daemon" from working; we want systemd to
# manage it!
Restart = "on-success";
User = cfg.user;
Group = cfg.group;
UMask = "0002";
LimitNOFILE = cfg.openFilesLimit;
};
preStart = preStart;
};
systemd.services.delugeweb = mkIf cfg_web.enable {
after = [ "network.target" "deluged.service"];
requires = [ "deluged.service" ];
description = "Deluge BitTorrent WebUI";
wantedBy = [ "multi-user.target" ];
path = [ cfg.package ];
serviceConfig = {
ExecStart = ''
${cfg.package}/bin/deluge-web \
${optionalString (!isDeluge1) "--do-not-daemonize"} \
--config ${configDir} \
--port ${toString cfg.web.port}
'';
User = cfg.user;
Group = cfg.group;
};
};
networking.firewall = mkMerge [
(mkIf (cfg.declarative && cfg.openFirewall && !(cfg.config.random_port or true)) {
allowedTCPPortRanges = singleton (listToRange (cfg.config.listen_ports or listenPortsDefault));
allowedUDPPortRanges = singleton (listToRange (cfg.config.listen_ports or listenPortsDefault));
})
(mkIf (cfg.web.openFirewall) {
allowedTCPPorts = [ cfg.web.port ];
})
];
environment.systemPackages = [ cfg.package ];
users.users = mkIf (cfg.user == "deluge") {
deluge = {
group = cfg.group;
uid = config.ids.uids.deluge;
home = cfg.dataDir;
description = "Deluge Daemon user";
};
};
users.groups = mkIf (cfg.group == "deluge") {
deluge = {
gid = config.ids.gids.deluge;
};
};
};
}