summaryrefslogtreecommitdiffstats
path: root/makefu
diff options
context:
space:
mode:
Diffstat (limited to 'makefu')
-rw-r--r--makefu/3modules/rtorrent.nix311
1 files changed, 311 insertions, 0 deletions
diff --git a/makefu/3modules/rtorrent.nix b/makefu/3modules/rtorrent.nix
new file mode 100644
index 000000000..404c9d4f0
--- /dev/null
+++ b/makefu/3modules/rtorrent.nix
@@ -0,0 +1,311 @@
+{ config, lib, pkgs, ... }:
+
+with config.krebs.lib;
+let
+ nginx-user = config.services.nginx.user;
+ nginx-group = config.services.nginx.group;
+ rutorrent-deps = with pkgs; [ curl php coreutils procps ffmpeg mediainfo ] ++
+ (if config.nixpkgs.config.allowUnfree then
+ trace "enabling unfree packages for rutorrent" [ unrar unzip ] else
+ trace "not enabling unfree packages for rutorrent because allowUnfree is unset" [])
+;
+ rutorrent = pkgs.stdenv.mkDerivation {
+ name = "rutorrent-src-3.7";
+ src = pkgs.fetchFromGitHub {
+ owner = "Novik";
+ repo = "rutorrent";
+ rev = "b727523a153454d4976f04b0c47336ae57cc50d5";
+ sha256 = "0s5wa0jnck781amln9c2p4pc0i5mq3j5693ra151lnwhz63aii4a";
+ };
+ phases = [ "installPhase" ];
+ installPhase = ''
+ cp -r $src $out
+ '';
+ };
+ fpm-socket = "/var/run/php5-fpm.sock";
+ systemd-logfile = cfg.workDir + "/rtorrent-systemd.log";
+ configFile = pkgs.writeText "rtorrent-config" ''
+ # THIS FILE IS AUTOGENERATED
+ ${optionalString (cfg.listenPort != null) ''
+ port_range = ${toString cfg.listenPort}-${toString cfg.listenPort}
+ port_random = no
+ ''}
+
+ ${optionalString (cfg.watchDir != null) ''
+ schedule = watch_directory,5,5load_start=${cfg.watchDir}/*.torrent
+ ''}
+
+ directory = ${cfg.downloadDir}
+ session = ${cfg.sessionDir}
+
+ ${optionalString (cfg.xmlrpc != null) ''
+ scgi_port = ${cfg.xmlrpc}
+ ''}
+
+ system.file_allocate.set = ${if cfg.preAllocate then "yes" else "no"}
+
+ # Prepare systemd logging
+ log.open_file = "rtorrent-systemd", ${systemd-logfile}
+ log.add_output = "warn", "rtorrent-systemd"
+ log.add_output = "notice", "rtorrent-systemd"
+ log.add_output = "info", "rtorrent-systemd"
+ # log.add_output = "debug", "rtorrent-systemd"
+ log.execute = ${systemd-logfile}.execute
+ log.xmlrpc = ${systemd-logfile}.xmlrpc
+ ${cfg.extraConfig}
+ '';
+
+ cfg = config.makefu.rtorrent;
+ webcfg = config.makefu.rtorrent.web;
+ out = {
+ options.makefu.rtorrent = api;
+ config = lib.recursiveUpdate (lib.mkIf cfg.enable imp) (lib.mkIf cfg.web.enable web-imp);
+ };
+
+ api = {
+ enable = mkEnableOption "rtorrent";
+
+ web = {
+ enable = mkEnableOption "rtorrent";
+
+ package = mkOption {
+ type = types.package;
+ description = ''
+ path to rutorrent package
+ '';
+ default = rutorrent;
+ };
+
+ listenAddress = mkOption {
+ type = types.str;
+ description =''
+ nginx listen address
+ '';
+ default = "localhost:8005";
+ };
+
+ webdir = mkOption {
+ type = types.path;
+ description = ''
+ rutorrent php files will be written to this folder.
+ when using nginx, be aware that the the folder should be readable by nginx.
+ because rutorrent does not hold mutable data in a separate folder
+ these files must be writable.
+ '';
+ default = "/var/lib/rutorrent";
+ };
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.rtorrent;
+ };
+
+ xmlrpc = mkOption {
+ type = with types; nullOr str;
+ description = ''
+ enable xmlrpc at given interface and port.
+
+ for documentation see:
+ https://github.com/rakshasa/rtorrent/wiki/RPC-Setup-XMLRPC
+ '';
+ example = "localhost:5000";
+ default = null;
+ };
+ preAllocate = mkOption {
+ type = types.bool;
+ description = ''
+ Pre-Allocate torrent files
+ '';
+ default = true;
+ };
+
+ logLevel = mkOption {
+ type = types.str;
+ description = ''
+ Log level to be used for systemd log
+ '';
+ default = "warn";
+ };
+
+ downloadDir = mkOption {
+ type = types.path;
+ description = ''
+ directory where torrents are stored
+ '';
+ default = cfg.workDir + "/downloads";
+ };
+
+ sessionDir = mkOption {
+ type = types.path;
+ description = ''
+ directory where torrent progress is stored
+ '';
+ default = cfg.workDir + "/rtorrent-session";
+ };
+
+ watchDir = mkOption {
+ type = with types; nullOr str;
+ description = ''
+ directory to watch for torrent files.
+ If unset, no watch directory will be configured
+ '';
+ default = null;
+ };
+
+ listenPort = mkOption {
+ type = with types; nullOr int;
+ description =''
+ listening port. if you want multiple ports, use extraConfig port_range
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.string;
+ description = ''
+ config to be placed into ${cfg.workDir}/.rtorrent.rc
+
+ see ${cfg.package}/share/doc/rtorrent/rtorrent.rc
+ '';
+ default = "";
+ };
+
+ user = mkOption {
+ description = ''
+ user which will run rtorrent. if kept default a new user will be created
+ '';
+ type = types.str;
+ default = "rtorrent";
+ };
+
+ workDir = mkOption {
+ description = ''
+ working directory. rtorrent will search in HOME for `.rtorrent.rc`
+ '';
+ type = types.str;
+ default = "/var/lib/rtorrent";
+ };
+
+ };
+
+ imp = {
+ systemd.services.rtorrent-daemon = {
+ description = "rtorrent headless";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ restartIfChanged = true;
+ serviceConfig = {
+ Type = "forking";
+ ExecStartPre = pkgs.writeDash "prepare-folder" ''
+ mkdir -p ${cfg.workDir} ${cfg.sessionDir}
+ touch ${systemd-logfile}
+ cp -f ${configFile} ${cfg.workDir}/.rtorrent.rc
+ '';
+ ExecStart = "${pkgs.tmux.bin}/bin/tmux new-session -s rt -n rtorrent -d 'PATH=/bin:/usr/bin:${makeBinPath rutorrent-deps} ${cfg.package}/bin/rtorrent'";
+
+ # PrivateTmp = true;
+ ## now you can simply sudo -u rtorrent tmux a
+ ## otherwise the tmux session is stored in some private folder in /tmp
+ WorkingDirectory = cfg.workDir;
+ Restart = "on-failure";
+ User = "${cfg.user}";
+ };
+
+ };
+ systemd.services.rtorrent-log = {
+ after = [ "rtorrent-daemon.service" ];
+ bindsTo = [ "rtorrent-daemon.service" ];
+ wantedBy = [ "rtorrent-daemon.service" ];
+ serviceConfig = {
+ ExecStart = "${pkgs.coreutils}/bin/tail -f ${systemd-logfile}";
+ User = "${cfg.user}";
+ };
+ };
+
+ users = lib.mkIf (cfg.user == "rtorrent") {
+ users.rtorrent = {
+ uid = genid "rtorrent";
+ home = cfg.workDir;
+ group = nginx-group;
+ shell = "/bin/sh"; #required for tmux
+ createHome = true;
+ };
+ groups.rtorrent.gid = genid "rtorrent";
+ };
+ };
+ web-imp = {
+ systemd.services.rutorrent-prepare = {
+ after = [ "rtorrent-daemon.service" ];
+ serviceConfig = {
+ Type = "oneshot";
+ # we create the folder and set the permissions to allow nginx
+ # TODO: update files if the version of rutorrent changed
+ ExecStart = pkgs.writeDash "create-webconfig-dir" ''
+ if [ ! -e ${webcfg.webdir} ];then
+ echo "creating webconfiguration directory for rutorrent: ${webcfg.webdir}"
+ cp -r ${webcfg.package} ${webcfg.webdir}
+ chown -R ${cfg.user}:${nginx-group} ${webcfg.webdir}
+ chmod -R 770 ${webcfg.webdir}
+ else
+ echo "not overwriting ${webcfg.webdir}"
+ fi
+ '';
+ };
+ };
+ krebs.nginx.enable = true;
+ krebs.nginx.servers.rutorrent = {
+ listen = [ webcfg.listenAddress ];
+ extraConfig = "root ${webcfg.webdir};";
+ # TODO: authentication
+ 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$" ''
+ root ${webcfg.webdir};
+ client_max_body_size 200M;
+ fastcgi_split_path_info ^(.+\.php)(/.+)$;
+ fastcgi_pass unix:${fpm-socket};
+ try_files $uri =404;
+ fastcgi_index index.php;
+ include ${pkgs.nginx}/conf/fastcgi_params;
+ include ${pkgs.nginx}/conf/fastcgi.conf;
+ '')
+
+ ];
+ };
+ services.phpfpm = {
+ # phpfpm does not have an enable option
+ poolConfigs = let
+ user = config.services.nginx.user;
+ group = config.services.nginx.group;
+ fpm-socket = "/var/run/php5-fpm.sock";
+ in {
+ rutorrent = ''
+ user = ${user}
+ group = ${group}
+ listen = ${fpm-socket}
+ listen.owner = ${user}
+ listen.group = ${group}
+ pm = dynamic
+ pm.max_children = 5
+ pm.start_servers = 2
+ pm.min_spare_servers = 1
+ pm.max_spare_servers = 3
+ chdir = /
+ # errors to journal
+ php_admin_value[error_log] = 'stderr'
+ php_admin_flag[log_errors] = on
+ catch_workers_output = yes
+ env[PATH] = ${makeBinPath rutorrent-deps}
+ '';
+ };
+ };
+ };
+in
+out
+