nixos/deluge: add autFile, config and port options (#58552)

nixos/deluge: add autFile, config and port options
This commit is contained in:
Silvan Mosberger 2019-06-04 23:16:06 +02:00 committed by GitHub
commit 08f2e282e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 184 additions and 19 deletions

View file

@ -5,8 +5,33 @@ with lib;
let
cfg = config.services.deluge;
cfg_web = config.services.deluge.web;
openFilesLimit = 4096;
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
ln -sf ${configFile} ${configDir}/core.conf
ln -sf ${cfg.authFile} ${configDir}/auth
else
# Declarative for the first time, backup stateful files
ln -sb --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 = {
@ -15,42 +40,151 @@ in {
openFilesLimit = mkOption {
default = openFilesLimit;
example = 8192;
description = ''
Number of files to allow deluged to open.
'';
};
config = mkOption {
type = types.attrs;
default = {};
example = literalExample ''
{
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 = ''
Deluge core configuration for the core.conf file. Only has an effect
when <option>services.deluge.declarative</option> is set to
<literal>true</literal>. String values must be quoted, integer and
boolean values must not. See
<link xlink:href="https://git.deluge-torrent.org/deluge/tree/deluge/core/preferencesmanager.py#n41"/>
for the availaible options.
'';
};
declarative = mkOption {
type = types.bool;
default = false;
description = ''
Whether to use a declarative deluge configuration.
Only if set to <literal>true</literal>, the options
<option>services.deluge.config</option>,
<option>services.deluge.openFirewall</option> and
<option>services.deluge.authFile</option> will be
applied.
'';
};
openFirewall = mkOption {
default = false;
type = types.bool;
description = ''
Whether to open the firewall for the ports in
<option>services.deluge.config.listen_ports</option>. It only takes effet if
<option>services.deluge.declarative</option> is set to
<literal>true</literal>.
It does NOT apply to the daemon port nor the web UI port. To access those
ports secuerly check the documentation
<link xlink:href="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 = ''
The directory where deluge will create files.
'';
};
authFile = mkOption {
type = types.path;
example = "/run/keys/deluge-auth";
description = ''
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</option> is set to
<literal>true</literal>.
See <link xlink:href="https://dev.deluge-torrent.org/wiki/UserGuide/Authentication"/> for
more informations.
'';
};
};
deluge.web.enable = mkEnableOption "Deluge Web daemon";
deluge.web = {
enable = mkEnableOption "Deluge Web daemon";
port = mkOption {
type = types.port;
default = 8112;
description = ''
Deluge web UI port.
'';
};
};
};
};
config = mkIf cfg.enable {
systemd.tmpfiles.rules = [ "d '${configDir}' 0770 deluge deluge" ]
++ optional (cfg.config ? "download_location")
"d '${cfg.config.download_location}' 0770 deluge deluge"
++ optional (cfg.config ? "torrentfiles_location")
"d '${cfg.config.torrentfiles_location}' 0770 deluge deluge"
++ optional (cfg.config ? "move_completed_path")
"d '${cfg.config.move_completed_path}' 0770 deluge deluge";
systemd.services.deluged = {
after = [ "network.target" ];
description = "Deluge BitTorrent Daemon";
wantedBy = [ "multi-user.target" ];
path = [ pkgs.deluge ];
serviceConfig = {
ExecStart = "${pkgs.deluge}/bin/deluged -d";
# To prevent "Quit & shutdown daemon" from working; we want systemd to manage it!
ExecStart = ''
${pkgs.deluge}/bin/deluged \
--do-not-daemonize \
--config ${configDir}
'';
# To prevent "Quit & shutdown daemon" from working; we want systemd to
# manage it!
Restart = "on-success";
User = "deluge";
Group = "deluge";
UMask = "0002";
LimitNOFILE = cfg.openFilesLimit;
};
preStart = preStart;
};
systemd.services.delugeweb = mkIf cfg_web.enable {
after = [ "network.target" ];
after = [ "network.target" "deluged.service"];
requires = [ "deluged.service" ];
description = "Deluge BitTorrent WebUI";
wantedBy = [ "multi-user.target" ];
path = [ pkgs.deluge ];
serviceConfig.ExecStart = "${pkgs.deluge}/bin/deluge --ui web";
serviceConfig.User = "deluge";
serviceConfig.Group = "deluge";
serviceConfig = {
ExecStart = ''
${pkgs.deluge}/bin/deluge-web \
--config ${configDir} \
--port ${toString cfg.web.port}
'';
User = "deluge";
Group = "deluge";
};
};
networking.firewall = 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));
};
environment.systemPackages = [ pkgs.deluge ];
@ -58,7 +192,7 @@ in {
users.users.deluge = {
group = "deluge";
uid = config.ids.uids.deluge;
home = "/var/lib/deluge/";
home = cfg.dataDir;
createHome = true;
description = "Deluge Daemon user";
};

View file

@ -5,25 +5,56 @@ import ./make-test.nix ({ pkgs, ...} : {
};
nodes = {
server =
simple = {
services.deluge = {
enable = true;
web.enable = true;
};
networking.firewall.allowedTCPPorts = [ 8112 ];
};
declarative =
{ ... }:
{ services.deluge = {
{
services.deluge = {
enable = true;
web.enable = true;
openFirewall = true;
declarative = true;
config = {
allow_remote = true;
download_location = "/var/lib/deluge/my-download";
daemon_port = 58846;
listen_ports = [ 6881 6889 ];
};
web = {
enable = true;
port = 3142;
};
authFile = pkgs.writeText "deluge-auth" ''
localclient:a7bef72a890:10
andrew:password:10
user3:anotherpass:5
'';
};
networking.firewall.allowedTCPPorts = [ 8112 ];
environment.systemPackages = [ pkgs.deluge ];
};
client = { };
};
testScript = ''
startAll;
$server->waitForUnit("deluged");
$server->waitForUnit("delugeweb");
$client->waitForUnit("network.target");
$client->waitUntilSucceeds("curl --fail http://server:8112");
$simple->waitForUnit("deluged");
$simple->waitForUnit("delugeweb");
$simple->waitForOpenPort("8112");
$declarative->waitForUnit("network.target");
$declarative->waitUntilSucceeds("curl --fail http://simple:8112");
$declarative->waitForUnit("deluged");
$declarative->waitForUnit("delugeweb");
$declarative->waitUntilSucceeds("curl --fail http://declarative:3142");
$declarative->succeed("deluge-console 'help' | grep -q 'rm - Remove a torrent'");
$declarative->succeed("deluge-console 'connect 127.0.0.1:58846 andrew password; help' | grep -q 'rm - Remove a torrent'");
'';
})