{ lib, pkgs, config, ... }: let qbittorent_data_directory = "/var/lib/qbittorrent"; in { options.services.qbittorrent = { enable = lib.mkEnableOption "should the headless qbittorrent service be enabled"; dataDir = lib.mkOption { type = lib.types.path; default = "/var/lib/qbittorrent"; description = lib.mdDoc '' The directory where qBittorrent stores its data files. ''; }; mediaDir = lib.mkOption { type = lib.types.path; description = lib.mdDoc '' The directory to create to store qbittorrent media. ''; }; user = lib.mkOption { type = lib.types.str; default = "qbittorrent"; description = lib.mdDoc '' User account under which qBittorrent runs. ''; }; group = lib.mkOption { type = lib.types.str; default = "qbittorrent"; description = lib.mdDoc '' Group under which qBittorrent runs. ''; }; webPort = lib.mkOption { type = lib.types.port; default = 8080; description = lib.mdDoc '' qBittorrent web UI port. ''; }; openFirewall = lib.mkOption { type = lib.types.bool; default = false; description = "Open services.qBittorrent.webPort to the outside network."; }; package = lib.mkOption { type = lib.types.package; default = pkgs.qbittorrent-nox; defaultText = lib.literalExpression "pkgs.qbittorrent-nox"; description = "The qbittorrent package to use."; }; }; config = lib.mkIf config.services.qbittorrent.enable (lib.mkMerge [ { networking.firewall = lib.mkIf config.services.qbittorrent.openFirewall { allowedTCPPorts = [config.services.qbittorrent.webPort]; }; systemd.services.qbittorrent = { # based on the plex.nix service module and # https://github.com/qbittorrent/qBittorrent/blob/master/dist/unix/systemd/qbittorrent-nox%40.service.in description = "qBittorrent-nox service"; documentation = ["man:qbittorrent-nox(1)"]; after = ["network.target"]; wantedBy = ["multi-user.target"]; serviceConfig = { Type = "simple"; User = config.services.qbittorrent.user; Group = config.services.qbittorrent.group; # Run the pre-start script with full permissions (the "!" prefix) so it # can create the data directory if necessary. ExecStartPre = let preStartScript = pkgs.writeScript "qbittorrent-run-prestart" '' #!${pkgs.bash}/bin/bash # Create data directory if it doesn't exist if ! test -d "$QBT_PROFILE"; then echo "Creating initial qBittorrent data directory in: $QBT_PROFILE" install -d -m 0755 -o "${config.services.qbittorrent.user}" -g "${config.services.qbittorrent.group}" "$QBT_PROFILE" fi ''; in "!${preStartScript}"; #ExecStart = "${pkgs.qbittorrent-nox}/bin/qbittorrent-nox"; ExecStart = "${config.services.qbittorrent.package}/bin/qbittorrent-nox"; # To prevent "Quit & shutdown daemon" from working; we want systemd to # manage it! #Restart = "on-success"; #UMask = "0002"; #LimitNOFILE = cfg.openFilesLimit; }; environment = { QBT_PROFILE = config.services.qbittorrent.dataDir; QBT_WEBUI_PORT = toString config.services.qbittorrent.webPort; }; }; } (lib.mkIf config.host.impermanence.enable { fileSystems."/persist/system/qbittorrent".neededForBoot = true; host.storage.pool.extraDatasets = { # sops age key needs to be available to pre persist for user generation "persist/system/qbittorrent" = { type = "zfs_fs"; mountpoint = "/persist/system/qbittorrent"; options = { canmount = "on"; }; }; }; assertions = [ { assertion = config.services.qbittorrent.dataDir == qbittorent_data_directory; message = "qbittorrent data directory does not match persistence"; } ]; environment.persistence = { "/persist/system/root" = { directories = [ { directory = qbittorent_data_directory; user = "qbittorrent"; group = "qbittorrent"; } ]; }; "/persist/system/qbittorrent" = { enable = true; hideMounts = true; directories = [ { directory = config.services.qbittorrent.mediaDir; user = "qbittorrent"; group = "qbittorrent"; mode = "1775"; } ]; }; }; }) ]); }