Files
nixos/hosts/nas/modules/pyload.nix

123 lines
4.0 KiB
Nix

{ config, pkgs, lib, ... }:
let
filebotScript = pkgs.callPackage ./filebot-process.nix {};
in
{
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
"unrar"
"filebot"
];
environment.systemPackages = with pkgs; [
unrar # Required for RAR archive extraction
p7zip # Required for 7z and other archive formats
];
# Create directory structure
systemd.tmpfiles.rules = [
"d /var/lib/downloads 0755 pyload pyload - -"
"d /var/lib/multimedia 0775 root jellyfin - -"
"d /var/lib/multimedia/movies 0775 jellyfin jellyfin - -"
"d /var/lib/multimedia/tv-shows 0775 jellyfin jellyfin - -"
"d /var/lib/multimedia/music 0755 jellyfin jellyfin - -"
# PyLoad hook scripts directory
"d /var/lib/pyload/config 0755 pyload pyload - -"
"d /var/lib/pyload/config/scripts 0755 pyload pyload - -"
"d /var/lib/pyload/config/scripts/package_extracted 0755 pyload pyload - -"
"L+ /var/lib/pyload/config/scripts/package_extracted/filebot-process.sh - - - - ${filebotScript}/bin/filebot-process"
];
# FileBot license secret (only if secrets.yaml exists)
sops.secrets.filebot-license = {
mode = "0440";
owner = "pyload";
group = "pyload";
path = "/var/lib/pyload/filebot-license.psm";
};
# Extraction passwords for pyload (one password per line)
sops.secrets.pyload-extraction-passwords = {
mode = "0440";
owner = "pyload";
group = "pyload";
path = "/var/lib/pyload/extraction-passwords.txt";
};
# PyLoad user with jellyfin group membership for multimedia access
users.users.pyload = {
isSystemUser = true;
group = "pyload";
home = "/var/lib/pyload";
createHome = true;
extraGroups = [ "jellyfin" ];
};
users.groups.pyload = {};
services.pyload = {
enable = true;
downloadDirectory = "/var/lib/downloads";
listenAddress = "0.0.0.0";
port = 8000;
};
# Configure pyload service
systemd.services.pyload = {
# Add extraction tools to service PATH
path = with pkgs; [
unrar # For RAR extraction
p7zip # For 7z extraction
];
environment = {
# Disable SSL certificate verification
PYLOAD__GENERAL__SSL_VERIFY = "0";
# Download speed limiting (150 Mbit/s = 19200 KiB/s)
PYLOAD__DOWNLOAD__LIMIT_SPEED = "1";
PYLOAD__DOWNLOAD__MAX_SPEED = "19200";
# Enable ExtractArchive plugin
PYLOAD__EXTRACTARCHIVE__ENABLED = "1";
PYLOAD__EXTRACTARCHIVE__DELETE = "1";
PYLOAD__EXTRACTARCHIVE__DELTOTRASH = "0";
PYLOAD__EXTRACTARCHIVE__REPAIR = "1";
PYLOAD__EXTRACTARCHIVE__RECURSIVE = "1";
PYLOAD__EXTRACTARCHIVE__FULLPATH = "1";
PYLOAD__EXTRACTARCHIVE__PASSWORDFILE = "/var/lib/pyload/extraction-passwords.txt";
# Enable ExternalScripts plugin for hooks
PYLOAD__EXTERNALSCRIPTS__ENABLED = "1";
PYLOAD__EXTERNALSCRIPTS__UNLOCK = "1"; # Run hooks asynchronously
};
serviceConfig = {
# Bind-mount DNS configuration files into the sandboxed service
BindReadOnlyPaths = [
"/etc/resolv.conf"
"/etc/nsswitch.conf"
"/etc/hosts"
"/etc/ssl"
"/etc/static/ssl"
"/run/secrets" # SOPS secrets access for FileBot license
];
# Bind mount multimedia directory as writable for FileBot hook scripts
BindPaths = [ "/var/lib/multimedia" ];
# Override SystemCallFilter to allow @resources syscalls
# FileBot (Java) needs resource management syscalls like setpriority
# during cleanup operations. Still block privileged syscalls for security.
SystemCallFilter = lib.mkForce [
"@system-service"
"@resources" # Explicitly allow resource management syscalls
"~@privileged" # Still block privileged operations
"fchown" # Re-allow fchown for FileBot file operations
"fchown32" # 32-bit compatibility
];
};
};
# Open firewall for PyLoad web interface
networking.firewall.allowedTCPPorts = [ 8000 ];
}