Skip to content

Commit

Permalink
Added cross-seed support, still untested
Browse files Browse the repository at this point in the history
  • Loading branch information
rasmus-kirk committed Mar 1, 2024
1 parent bd37178 commit bf8eb5f
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 42 deletions.
1 change: 0 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@

packages = {
docs = pkgs.callPackage ./mkDocs.nix {inherit inputs;};
pandoc = pkgs.callPackage ./mkPandoc.nix {inherit inputs;};
};

devshells.default = {
Expand Down
12 changes: 6 additions & 6 deletions nixarr/openssh/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,22 @@ in {
'';
};

config = mkIf cfg.vpn.enable {
config = mkIf cfg.expose.vpn.enable {
assertions = [
{
assertion = cfg.vpn.enable -> nixarr.vpn.enable;
assertion = cfg.expose.vpn.enable -> nixarr.vpn.enable;
message = ''
The nixarr.openssh.vpn.enable option requires the
The nixarr.openssh.expose.vpn.enable option requires the
nixarr.vpn.enable option to be set, but it was not.
'';
}
];

warnings = if config.services.openssh.enable then [
''
nixarr.openssh.vpn.enable is set, but openssh is not enabled on your
system, so the openssh server is not running. This is probably not
what you wanted. You can add the following lines to enable it:
nixarr.openssh.expose.vpn.enable is set, but openssh is not enabled
on your system, so the openssh server is not running. This is probably
not what you wanted. You can add the following lines to enable it:
services.openssh = {
enable = true;
Expand Down
31 changes: 22 additions & 9 deletions nixarr/transmission/cross-seed/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@
}:
with lib; let
cfg = config.util-nixarr.services.cross-seed;
#settingsFormat = pkgs.formats.json {};
#settingsFile = settingsFormat.generate "settings.json" cfg.settings;
settingsFormat = pkgs.formats.json {};
settingsFile = settingsFormat.generate "settings.json" cfg.settings;
cross-seedPkg = import ../../../pkgs/cross-seed { inherit (pkgs) stdenv lib fetchFromGitHub; };
in {
options = {
util-nixarr.services.cross-seed = {
enable = mkEnableOption "cross-seed";

configFile = mkOption {
type = with types; nullOr path;
default = null;
example = "/var/lib/secrets/cross-seed/settings.js";
description = "cross-seed config file"; # TODO: todo
settings = mkOption {
type = types.attrs;
default = {};
example = ''
{
delay = 10;
}
'';
description = "cross-seed config"; # TODO: todo
};

dataDir = mkOption {
Expand All @@ -27,6 +31,12 @@ in {
description = "cross-seed dataDir"; # TODO: todo
};

credentialsFile = mkOption {
type = types.path;
default = "/run/secrets/cross-seed/credentialsFile.json";
description = "cross-seed dataDir"; # TODO: todo
};

user = mkOption {
type = types.str;
default = "cross-seed";
Expand Down Expand Up @@ -54,9 +64,12 @@ in {
environment.CONFIG_DIR = cfg.dataDir;

serviceConfig = {
# Run as root in case that the cfg.credentialsFile is not readable by cross-seed
ExecStartPre = [("+" + pkgs.writeShellScript "transmission-prestart" ''
mv ${cfg.configFile} ${cfg.dataDir}
'')];
${pkgs.jq}/bin/jq --slurp add ${settingsFile} '${cfg.credentialsFile}' |
install -D -m 600 -o '${cfg.user}' /dev/stdin '${cfg.dataDir}/config.json'
''
)];
Type = "simple";
User = cfg.user;
Group = cfg.group;
Expand Down
125 changes: 99 additions & 26 deletions nixarr/transmission/default.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# TODO: Dir creation and file permissions in nix
{
config,
lib,
Expand All @@ -9,19 +8,41 @@ with lib; let
cfg = config.nixarr.transmission;
nixarr = config.nixarr;
dnsServers = config.lib.vpn.dnsServers;
get-indexers = with builtins; pkgs.writeShellApplication {
name = "get-indexers";
cfg-cross-seed = config.nixarr.transmission.privateTrackers.cross-seed;
transmissionCrossSeedScript = with builtins; pkgs.writeShellApplication {
name = "mk-cross-seed-credentials";

runtimeInputs = with pkgs; [ jq yq ];
runtimeInputs = with pkgs; [ curl ];

text = ''
PROWLARR_API_KEY=$(xq '.Config.ApiKey' "${nixarr.prowlarr.stateDir}/config.xml")
''
+ toJson (
map (x:
''http://localhost:9696/${toString x}/api?apikey="$PROWLARR_API_KEY"''
) cfg.privateTrackers.cross-seed.indexIds
);
curl -XPOST http://localhost:2468/api/webhook?apikey=YOUR_API_KEY --data-urlencode "infoHash=$TR_TORRENT_HASH"
'';
};
mkCrossSeedCredentials = with builtins; pkgs.writeShellApplication {
name = "mk-cross-seed-credentials";

runtimeInputs = with pkgs; [ jq yq ];

text =
"INDEX_LINKS=("
+ strings.concatMapStringsSep " " toString cfg.privateTrackers.cross-seed.indexIds
+ ")"
''
TMP_JSON=$(mktemp)
CRED_FILE="/run/secrets/cross-seed/credentialsFile.json"
PROWLARR_API_KEY=$(xq '.Config.ApiKey' "${nixarr.prowlarr.stateDir}/config.xml")
CRED_DIR=$(dirname "$filePath")
echo '{}' > "$CRED_FILE"
chmod 400 "$CRED_FILE"
chown "${config.util-nixarr.services.cross-seed.user}" "$CRED_FILE"
for i in "''${INDEX_LINKS[@]}"
do
LINK="http://localhost:9696/$i/api?apikey=$PROWLARR_API_KEY"
jq ".torznab += [\"$LINK\"]" "$CRED_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$CRED_FILE"
done
'';
};
in {
options.nixarr.transmission = {
Expand Down Expand Up @@ -69,19 +90,47 @@ in {
their rules ¯\\_(ツ)_/¯.
'';
};

cross-seed = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable the cross-seed service.
**Required options:** [`nixarr.prowlarr.enable`](#nixarr.prowlarr.enable)
Whether or not to enable the [cross-seed](https://www.cross-seed.org/) service.
'';
};

stateDir = mkOption {
type = types.path;
default = "${nixarr.stateDir}/nixarr/cross-seed";
description = ''
The state directory for Transmission.
'';
};

indexIds = mkOption {
type = with types; listOf int;
default = [];
description = ''
list of indexers TODO: todo
List of indexer-ids, from prowlarr. These are from the RSS links
for the indexers, located by the "radio" or "RSS" logo on the
right of the indexer, you'll see the links have the form:
`http://localhost:9696/1/api?apikey=aaaaaaaaaaaaa`
Then the id needed here is the `1`.
'';
};

extraSettings = mkOption {
type = types.attrs;
default = {};
description = ''
Extra settings for the cross-seed
service, see [the cross-seed options
documentation](https://www.cross-seed.org/docs/basics/options)
'';
};
};
Expand Down Expand Up @@ -113,7 +162,7 @@ in {
description = "Transmission web-UI port.";
};

extraConfig = mkOption {
extraSettings = mkOption {
type = types.attrs;
default = {};
description = ''
Expand All @@ -140,9 +189,10 @@ in {
'';
}
{
assertion = cfg.privateTrackers.cross-seed.enable -> nixarr.prowlarr.enable;
assertion = cfg-cross-seed.enable -> nixarr.prowlarr.enable;
message = ''
TODO: todo
The nixarr.privateTrackers.cross-seed.enable option requires the
nixarr.prowlarr.enable option to be set, but it was not.
'';
}
];
Expand All @@ -151,7 +201,34 @@ in {
"d '${cfg.stateDir}' 0700 torrenter root - -"
# This is fixes a bug in nixpks (https://github.com/NixOS/nixpkgs/issues/291883)
"d '${cfg.stateDir}/.config/transmission-daemon' 0700 torrenter root - -"
];
] ++ (
if cfg-cross-seed.enable then
[ "d '${cfg-cross-seed.stateDir}' 0700 cross-seed root - -" ]
else []
);

util-nixarr.services.cross-seed = mkIf cfg-cross-seed.enable {
enable = true;
dataDir = cfg-cross-seed.stateDir;
#group = "media";
settings = {
torrentDir = "${nixarr.mediaDir}/torrents";
outputDir = "${nixarr.mediaDir}/torrents/cross-seed";
transmissionRpcUrl = "http://transmission:${builtins.toString cfg.uiPort}/transmission/rpc";
rssCadence = "20 minutes";

# Enable infrequent periodic searches
searchCadence = "1 week";
excludeRecentSearch = "1 year";
excludeOlder = "1 year";
} // cfg-cross-seed.extraSettings;
};
# Run as root in case that the cfg.credentialsFile is not readable by cross-seed
systemd.services.cross-seed.serviceConfig = mkIf cfg-cross-seed.enable {
ExecStartPre = [(mkBefore
("+" + (getExe mkCrossSeedCredentials))
)];
};

services.transmission = mkIf (!cfg.vpn.enable) {
enable = true;
Expand Down Expand Up @@ -192,6 +269,9 @@ in {
anti-brute-force-enabled = true;
anti-brute-force-threshold = 10;

script-torrent-done-enabled = true;
script-torrent-done-filename = getExe transmissionCrossSeedScript;

message-level =
if cfg.messageLevel == "none"
then 0
Expand All @@ -209,14 +289,7 @@ in {
then 6
else null;
}
// cfg.extraConfig;
};

services.cross-seed = mkIf cfg.cross-seed.enable {
enable = true;
group = "media";
dataDir = cfg.privateTrackers.cross-seed.dataDir;
configFile = cfg.privateTrackers.cross-seed.configFile;
// cfg.extraSettings;
};

util-nixarr.vpnnamespace = mkIf cfg.vpn.enable {
Expand Down Expand Up @@ -309,7 +382,7 @@ in {
# 0 = None, 1 = Critical, 2 = Error, 3 = Warn, 4 = Info, 5 = Debug, 6 = Trace
message-level = 3;
}
// cfg.extraConfig;
// cfg.extraSettings;
};

environment.systemPackages = with pkgs; [
Expand Down

0 comments on commit bf8eb5f

Please sign in to comment.