-
-
Notifications
You must be signed in to change notification settings - Fork 15.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rutorrent: init at 3.10-beta #85613
rutorrent: init at 3.10-beta #85613
Conversation
ln -sf ${pkgs.rutorrent}/conf/{access.ini,plugins.ini} ${cfg.home}/conf/ | ||
ln -sf ${rutorrentConfig} ${cfg.home}/conf/config.php | ||
|
||
cp -r ${pkgs.rutorrent}/php ${cfg.home}/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to copy instead of symlink the php files because it tries to import files from the share
directory using a relative path. Using symlink it search relative to the nix store path instead of the ${cfg.home}
.
I find better to use symlink and tried to find a way to configure php so it would import files relative to the symlink and not it's target. I didn't find anything, is it possible? Otherwise I might end up patching the relative paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same things for the plugins.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iv-nn So I came up with a bit of a magical solution using bind mounts. This is probably even more hacky, but I kind of like it because it leaves the /var/lib/rutorrent
clear of non-state clutter.
Basiaclly what I do is I set the nginx root = pkgs.rutorrent
, so it points to the ruTorrent nix store directly. Then I mount the config.php
file on top of it, along with the whitelisted plugins. I also set the $profilePath = '${cfg.home}';
so it points directly to the data dir. I do all of this in the phpfpm service file, so we don't even need the setup service.
Here's the modified phpfpm-rutorrent
service:
phpfpm-rutorrent.serviceConfig = {
ExecStartPre = [
(pkgs.writeShellScript "setup-rutorrent" ''
mkdir -p ${cfg.home}/{logs,settings,torrents,users}
chown -R rutorrent:rutorrent ${cfg.home}/{logs,settings,torrents,users}
chmod -R 755 ${cfg.home}/{logs,settings,torrents,users}
'')
];
TemporaryFileSystem = [ "${pkgs.rutorrent}/plugins" ];
BindReadOnlyPaths = [
"${rutorrentConfig}:${pkgs.rutorrent}/conf/config.php"
] ++ map (p: "${pkgs.rutorrent}/plugins/${p}") cfg.plugins;
};
We don't really need to mount the config file though. We could just replace it in the package with an env var pointing to the real config. Like this
phpConfig = writeText "config.php" ''
<?php
return require(getenv('RUTORRENT_CONFIG'));
?>
'';
installPhase = ''
mkdir -p $out/
cp -r . $out/
cp -f ${phpConfig} $out/conf/config.php
'';
So I think this is only a problem with plugins.
What do you think? I think if mounting on top of the nix store is ugly, we could also mount the whole app to something like /var/run/rutorrent
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of using bind mounts, it's clever. But I think I would rather mount the store files in the dataDir
than the other way around.
But seeing your other comment I realise changing $profilePath
should be enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The plugins dir is the only issue really. With the modified config file you could easily have nginx point directly to /nix/store/...
and load the settings through an env var, without any need for any bind mounts or symlinking.
Tbh, I would just skip the whole NixOS plugin management because you can manage plugins in the UI anyway. And it would greatly simplify the whole setup, though at the cost of unnecessary dependencies. Up to you though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kept the copy for now because I thought maybe it's an issue to tie the plugin setup to the php-fpm service. Shouldn't there be a way to use this service without setting nginx.enable = true
, using some other web server?
Does using copy pose a real problem?
It even allow to use custom plugins, although a better way would be to allow adding them directly through the plugins
option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iv-nn I think it's fine, forget it. I've seen Nix services do it both ways. Usually using the /nix/store/...
as the vhost root when it's simple enough, or by copying/symlinking the application into the state directory in more complex cases. I think with plugins it might be complex enough to keep it as it is. Regardless, nginx.enable = true
is not necessary as you can always point your custom vhost root
to pkgs.rutorrent
.
}; | ||
|
||
services.rtorrent.configText = '' | ||
schedule = scgi_group,0,0,"execute.nothrow=chown,\":nginx\",(cfg.rpcsock)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is dirty but I need a way to make rtorrent's rpc socket accessible by nginx if exposeInsecureRPC2mount
is set. This would get overwritten if someone use mkForce
to set it's rtorrent's configText
. Maybe I should use some systemd post start hook to chown the socket.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is better since rutorrent doesn't actually need the rpc mount if it use one of the rpc
or httprpc
plugin. Also one could use rtorrent and the rpc mount with some other client (like flood or a mobile client).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, something related to this that I noticed in the documentation. It's recommended to add this line to rtorrent so that rutorrent plugins get initialized on startup. Otherwise the plugins don't start until you open the ruTorrent client manually.
execute2 = {sh,-c,/usr/bin/php /var/www/ruTorrent/php/initplugins.php tom &}
https://github.com/Novik/ruTorrent/wiki/Plugins#starting-plugins-with-rtorrent
Though, this is super annoying for a number of reasons:
- the user (
tom
) depends on the http auth username - rtorrent now depends on rutorrent running
I'm not really sure how to approach this one. Maybe we could run it ourselves after ruTorrent starts? Though that still leaves the issue with the http auth user name which would have to be part of the config, or detected by a script scanning through the state dir (/var/lib/rutorrent
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a way to change rtorrent
's socket group and change it if rutorrent
is enabled. Should I make a separate PR for the rtorrent
's change?
For initplugins.php
the simplest way would be to let the user do it, just adding some documentation about it.
Or I could check if the nginx vhost has auth and add the config line directly to rtorrent
config if rutorrent
is enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awesome! I have some minor comments but I'll check it out in more detail as soon as I get the chance.
}; | ||
|
||
services.rtorrent.configText = '' | ||
schedule = scgi_group,0,0,"execute.nothrow=chown,\":nginx\",(cfg.rpcsock)" |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
ln -sf ${pkgs.rutorrent}/conf/{access.ini,plugins.ini} ${cfg.home}/conf/ | ||
ln -sf ${rutorrentConfig} ${cfg.home}/conf/config.php | ||
|
||
cp -r ${pkgs.rutorrent}/php ${cfg.home}/ |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
"${config.services.rtorrent.user}" = { | ||
extraGroups = [ "rutorrent" ]; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is needed if you manage the filesystem with ruTorrent? So rtorrent still has access to it?
Hm, personally I would run ruTorrent and rtorrent as the same user because otherwise it's gonna create an owner mess on the filesystem. Though I wonder if that would be a good default for NixOS too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that would be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I was testing this and I didn't notice anything weird going on with file ownership. It seems rutorrent tries to do as much as possible through rtorrent with XMLRPC. So I think it's actually fine to have a separate user as long as they're in each other's groups. Though in that case it would be nice to have the user and group configurable.
mediainfo = [ mediainfo ]; | ||
spectrogram = [ sox ]; | ||
screenshots = [ ffmpeg ]; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_cloudflare = [ python ];
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, when I was testing this it also requires some additional python libraries that are not in NixOS. Maybe we should just skip this plugin?
|
||
systemd = { | ||
services = { | ||
rtorrent.path = getPluginDependencies cfg.plugins; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is missing the php
package. Either that or we need to add php
to every plugin that requires it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what the issue is here, I don't get any error without it.
Thanks for you review, some great inputs. I've started making changes and should be done this week-end. |
soo, how is this coming along? |
ed16111
to
0dedff6
Compare
0dedff6
to
614d869
Compare
Well, it was a long week-end 😄. I finally took some time to take care of this and made some progress. |
@iv-nn awesome, looks great! I'll test it out in the next few days and see how it works on my end. One thing I wanted to ask you about is what to do about initializing ruTorrent plugins? The problem is that plugins do not get loaded until you open the WebUI which is problematic for plugins like autotools. I currently run the Maybe we could do something similar, but in the systemd service instead? I'll try it out and let you know. As for rtorrent, If I'm not mistaken the changes will have to be part of a separate PR and certainly reviewed by rtorrent maintainers, so I would go ahead and open that in advance. |
As you said the issue is with the auth username. Maybe I can check if the user has configured some auth on the vhost and if so add that line with the configured username, otherwise it would be the use responsibility. But to be honest I don't really understand what the username is used for. |
Ok, so a few minor things:
users.users = mkIf (cfg.user == "rutorrent") {
rutorrent = { ... };
};
I'm done for today, but I'll try and see what I can come up with |
Ok so I put some more thought into {
rutorrent-plugin-init = {
wantedBy = [ "rtorrent.service" ];
after = [ "rtorrent.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart = [ "${pkgs.php}/bin/php ${cfg.dataDir}/php/initplugins.php ${cfg.initPluginsForUser}" ];
};
} Either that or use {
systemd.services.rtorrent.serviceConfig.ExecStartPost =
[ "${pkgs.php}/bin/php ${cfg.dataDir}/php/initplugins.php ${cfg.initPluginsForUser}" ];
} What do you think? |
I marked this as stale due to inactivity. → More info |
4b3c1b7
to
ef177f2
Compare
ef177f2
to
f1408f7
Compare
I marked this as stale due to inactivity. → More info |
cp -r . $out/ | ||
''; | ||
|
||
meta = with stdenv.lib; { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
meta = with stdenv.lib; { | |
meta = with lib; { |
@@ -0,0 +1,25 @@ | |||
{ stdenv, fetchFromGitHub }: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{ stdenv, fetchFromGitHub }: | |
{ stdenv, lib, fetchFromGitHub }: |
Closing as dead. |
Motivation for this change
Add rutorrent, a web frontend to rtorrent.
Things done
Add the package and the NixOS service. It's a beta but the last non-beta release doesn't work with the current rtorrent.
It depends on this PR #83287 for a rtorrent service.
A few things still need to be improved.
sandbox
innix.conf
on non-NixOS linux)nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
./result/bin/
)nix path-info -S
before and after)