m rtorrent: split web rpc and rutorrent functionality

This commit is contained in:
makefu 2016-08-23 13:09:16 +02:00
parent 7761a15e57
commit d73d552096
No known key found for this signature in database
GPG Key ID: 36F7711F3FC0F225
2 changed files with 103 additions and 43 deletions

View File

@ -2,11 +2,17 @@ _:
let let
listenPort = 60123; listenPort = 60123;
xml-port = 5000; xml-port = 5000;
authfile = <torrent-secrets/authfile>;
in { in {
makefu.rtorrent = { makefu.rtorrent = {
enable = true; enable = true;
web.enable = true; web = {
xmlrpc = "localhost:${toString xml-port}"; enable = true;
enableAuth = true;
inherit authfile;
};
rutorrent.enable = true;
enableXMLRPC = true;
logLevel = "debug"; logLevel = "debug";
inherit listenPort; inherit listenPort;
}; };

View File

@ -2,6 +2,10 @@
with config.krebs.lib; with config.krebs.lib;
let let
cfg = config.makefu.rtorrent;
webcfg = config.makefu.rtorrent.web;
rucfg = config.makefu.rtorrent.rutorrent;
nginx-user = config.services.nginx.user; nginx-user = config.services.nginx.user;
nginx-group = config.services.nginx.group; nginx-group = config.services.nginx.group;
rutorrent-deps = with pkgs; [ curl php coreutils procps ffmpeg mediainfo ] ++ rutorrent-deps = with pkgs; [ curl php coreutils procps ffmpeg mediainfo ] ++
@ -17,9 +21,17 @@ let
rev = "b727523a153454d4976f04b0c47336ae57cc50d5"; rev = "b727523a153454d4976f04b0c47336ae57cc50d5";
sha256 = "0s5wa0jnck781amln9c2p4pc0i5mq3j5693ra151lnwhz63aii4a"; sha256 = "0s5wa0jnck781amln9c2p4pc0i5mq3j5693ra151lnwhz63aii4a";
}; };
phases = [ "installPhase" ]; phases = [ "patchPhase" "installPhase" ];
patchPhase = ''
cp -r $src src/
chmod u+w -R src/
sed -i -e 's#^\s*$scgi_port.*#$scgi_port = 0;#' \
-e 's#^\s*$scgi_host.*#$scgi_host = "unix://${cfg.xmlrpc-socket}";#' \
"src/conf/config.php"
'';
installPhase = '' installPhase = ''
cp -r $src $out cp -r src/ $out
echo "replacing scgi port and host variable in conf/config.php"
''; '';
}; };
fpm-socket = "/var/run/php5-fpm.sock"; fpm-socket = "/var/run/php5-fpm.sock";
@ -38,8 +50,12 @@ let
directory = ${cfg.downloadDir} directory = ${cfg.downloadDir}
session = ${cfg.sessionDir} session = ${cfg.sessionDir}
${optionalString (cfg.xmlrpc != null) '' ${optionalString (cfg.enableXMLRPC ) ''
scgi_port = ${cfg.xmlrpc} # prepare socket and set permissions. rtorrent user is part of group nginx
# TODO: configure a shared torrent group
execute_nothrow = rm,${cfg.xmlrpc-socket}
scgi_local = ${cfg.xmlrpc-socket}
schedule = scgi_permission,0,0,"execute.nothrow=chmod,\"ug+w,o=\",${cfg.xmlrpc-socket}"
''} ''}
system.file_allocate.set = ${if cfg.preAllocate then "yes" else "no"} system.file_allocate.set = ${if cfg.preAllocate then "yes" else "no"}
@ -55,35 +71,52 @@ let
${cfg.extraConfig} ${cfg.extraConfig}
''; '';
cfg = config.makefu.rtorrent;
webcfg = config.makefu.rtorrent.web;
out = { out = {
options.makefu.rtorrent = api; options.makefu.rtorrent = api;
config = lib.recursiveUpdate (lib.mkIf cfg.enable imp) (lib.mkIf cfg.web.enable web-imp); config = lib.recursiveUpdate (lib.mkIf cfg.enable imp)
( lib.recursiveUpdate (lib.mkIf cfg.web.enable rpcweb-imp)
(lib.mkIf cfg.rutorrent.enable rutorrent-imp));
}; };
api = { api = {
enable = mkEnableOption "rtorrent"; enable = mkEnableOption "rtorrent";
web = { web = {
enable = mkEnableOption "rtorrent"; # configure NGINX to provide /RPC2 for listen address
# authentication also applies to rtorrent.rutorrent
package = mkOption { enable = mkEnableOption "rtorrent nginx web RPC";
type = types.package;
description = ''
path to rutorrent package
'';
default = rutorrent;
};
listenAddress = mkOption { listenAddress = mkOption {
type = types.str; type = types.str;
description ='' description =''
nginx listen address nginx listen address for rtorrent web
''; '';
default = "localhost:8005"; default = "localhost:8005";
}; };
enableAuth = mkEnableOption "rutorrent authentication";
authfile = mkOption {
type = types.path;
description = ''
basic authentication file to be used.
Use `${pkgs.apacheHttpd}/bin/htpasswd -c <file> <username>` to create the file.
Only in use if authentication is enabled.
'';
};
};
rutorrent = {
enable = mkEnableOption "rutorrent";
package = mkOption {
type = types.package;
description = ''
path to rutorrent package. When using your own ruTorrent package,
make sure you patch the scgi_port and scgi_host.
'';
default = rutorrent;
};
webdir = mkOption { webdir = mkOption {
type = types.path; type = types.path;
description = '' description = ''
@ -94,6 +127,7 @@ let
''; '';
default = "/var/lib/rutorrent"; default = "/var/lib/rutorrent";
}; };
}; };
package = mkOption { package = mkOption {
@ -102,17 +136,18 @@ let
}; };
# TODO: enable xmlrpc with web.enable # TODO: enable xmlrpc with web.enable
xmlrpc = mkOption { enableXMLRPC = mkEnableOption "rtorrent xmlrpc via socket";
type = with types; nullOr str; xmlrpc-socket = mkOption {
type = types.str;
description = '' description = ''
enable xmlrpc at given interface and port. enable xmlrpc at given socket. Required for web-interface.
for documentation see: for documentation see:
https://github.com/rakshasa/rtorrent/wiki/RPC-Setup-XMLRPC https://github.com/rakshasa/rtorrent/wiki/RPC-Setup-XMLRPC
''; '';
example = "localhost:5000"; default = cfg.workDir + "/rtorrent.sock";
default = null;
}; };
preAllocate = mkOption { preAllocate = mkOption {
type = types.bool; type = types.bool;
description = '' description = ''
@ -234,41 +269,60 @@ let
groups.rtorrent.gid = genid "rtorrent"; groups.rtorrent.gid = genid "rtorrent";
}; };
}; };
web-imp = {
rpcweb-imp = {
krebs.nginx.enable = mkDefault true;
krebs.nginx.servers.rtorrent = {
listen = [ webcfg.listenAddress ];
server-names = [ "default" ];
extraConfig = ''
${optionalString webcfg.enableAuth ''
auth_basic "rtorrent";
auth_basic_user_file ${webcfg.authfile};
''}
'';
locations = [
(nameValuePair "/RPC2" ''
include ${pkgs.nginx}/conf/scgi_params;
scgi_param SCRIPT_NAME /RPC2;
scgi_pass unix:${cfg.xmlrpc-socket};
'')
];
};
};
rutorrent-imp = let
webdir = rucfg.webdir;
in {
systemd.services.rutorrent-prepare = { systemd.services.rutorrent-prepare = {
after = [ "rtorrent-daemon.service" ]; after = [ "rtorrent-daemon.service" ];
bindsTo = [ "rtorrent-daemon.service" ];
wantedBy = [ "rtorrent-daemon.service" ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
# we create the folder and set the permissions to allow nginx # we create the folder and set the permissions to allow nginx
# TODO: update files if the version of rutorrent changed # TODO: update files if the version of rutorrent changed
ExecStart = pkgs.writeDash "create-webconfig-dir" '' ExecStart = pkgs.writeDash "create-webconfig-dir" ''
if [ ! -e ${webcfg.webdir} ];then if [ ! -e ${webdir} ];then
echo "creating webconfiguration directory for rutorrent: ${webcfg.webdir}" echo "creating webconfiguration directory for rutorrent: ${webdir}"
cp -r ${webcfg.package} ${webcfg.webdir} cp -r ${rucfg.package} ${webdir}
chown -R ${cfg.user}:${nginx-group} ${webcfg.webdir} chown -R ${cfg.user}:${nginx-group} ${webdir}
chmod -R 770 ${webcfg.webdir} chmod -R 770 ${webdir}
else else
echo "not overwriting ${webcfg.webdir}" echo "not overwriting ${webdir}"
fi fi
''; '';
}; };
}; };
krebs.nginx.enable = true; krebs.nginx.servers.rtorrent = {
krebs.nginx.servers.rutorrent = { extraConfig = ''
listen = [ webcfg.listenAddress ]; root ${webdir};
extraConfig = "root ${webcfg.webdir};"; '';
# TODO: authentication
locations = [ locations = [
# auth_basic "Restricted"; ##auth zone - whatever you want to use
# auth_basic_user_file torpasswd; ##auth file - relative to /etc/nginx/.
(nameValuePair "/RPC2" ''
scgi_pass localhost:5000;
include ${pkgs.nginx}/conf/scgi_params;
'')
(nameValuePair "~ \.php$" '' (nameValuePair "~ \.php$" ''
root ${webcfg.webdir};
client_max_body_size 200M; client_max_body_size 200M;
root ${webdir};
fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:${fpm-socket}; fastcgi_pass unix:${fpm-socket};
try_files $uri =404; try_files $uri =404;