diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md index 5153aa0525c4..1c287414435d 100644 --- a/nixos/doc/manual/release-notes/rl-2411.section.md +++ b/nixos/doc/manual/release-notes/rl-2411.section.md @@ -94,6 +94,9 @@ - [chromadb](https://www.trychroma.com/), an open-source AI application database. Batteries included. Available as [services.chromadb](options.html#opt-services.chromadb.enable). +- [bitmagnet](https://bitmagnet.io/), A self-hosted BitTorrent indexer, DHT crawler, content classifier and torrent search engine with web UI, GraphQL API and Servarr stack integration. + Available as [services.bitmagnet](options.html#opt-services.bitmagnet.enable). + ## Backward Incompatibilities {#sec-release-24.11-incompatibilities} - `transmission` package has been aliased with a `trace` warning to `transmission_3`. Since [Transmission 4 has been released last year](https://github.com/transmission/transmission/releases/tag/4.0.0), and Transmission 3 will eventually go away, it was decided perform this warning alias to make people aware of the new version. The `services.transmission.package` defaults to `transmission_3` as well because the upgrade can cause data loss in certain specific usage patterns (examples: [#5153](https://github.com/transmission/transmission/issues/5153), [#6796](https://github.com/transmission/transmission/issues/6796)). Please make sure to back up to your data directory per your usage: diff --git a/nixos/modules/services/torrent/bitmagnet.nix b/nixos/modules/services/torrent/bitmagnet.nix new file mode 100644 index 000000000000..8d96c0b430a9 --- /dev/null +++ b/nixos/modules/services/torrent/bitmagnet.nix @@ -0,0 +1,185 @@ +{ + pkgs, + config, + lib, + ... +}: +let + cfg = config.services.bitmagnet; + inherit (lib) + mkEnableOption + mkIf + mkOption + mkPackageOption + optional + ; + inherit (lib.types) + bool + int + port + str + submodule + ; + inherit (lib.generators) toYAML; + + freeformType = (pkgs.formats.yaml { }).type; +in +{ + options.services.bitmagnet = { + enable = mkEnableOption "Bitmagnet service"; + useLocalPostgresDB = mkOption { + description = "Use a local postgresql database, create user and database"; + type = bool; + default = true; + }; + settings = mkOption { + description = "Bitmagnet configuration (https://bitmagnet.io/setup/configuration.html)."; + default = { }; + type = submodule { + inherit freeformType; + options = { + http_server = mkOption { + default = { }; + type = submodule { + inherit freeformType; + options = { + port = mkOption { + type = str; + default = ":3333"; + }; + }; + }; + }; + dht_server = mkOption { + default = { }; + type = submodule { + inherit freeformType; + options = { + port = mkOption { + type = port; + default = 3334; + }; + }; + }; + }; + postgres = mkOption { + default = { }; + type = submodule { + inherit freeformType; + options = { + host = mkOption { + type = str; + default = ""; + }; + name = mkOption { + type = str; + default = "bitmagnet"; + }; + user = mkOption { + type = str; + default = ""; + }; + password = mkOption { + type = str; + default = ""; + }; + }; + }; + }; + }; + }; + }; + package = mkPackageOption pkgs "bitmagnet" { }; + user = mkOption { + description = "User running bitmagnet"; + type = str; + default = "bitmagnet"; + }; + group = mkOption { + description = "Group of user running bitmagnet"; + type = str; + default = "bitmagnet"; + }; + openFirewall = mkOption { + description = "Open DHT ports in firewall"; + type = bool; + default = false; + }; + }; + config = mkIf cfg.enable { + environment.etc."xdg/bitmagnet/config.yml" = { + text = toYAML { } cfg.settings; + mode = "0440"; + user = cfg.user; + group = cfg.group; + }; + systemd.services.bitmagnet = { + enable = true; + wantedBy = [ "multi-user.target" ]; + after = [ + "network.target" + ] ++ optional cfg.useLocalPostgresDB "postgresql.service"; + requires = optional cfg.useLocalPostgresDB "postgresql.service"; + serviceConfig = { + Type = "simple"; + DynamicUser = true; + User = cfg.user; + Group = cfg.group; + ExecStart = "${cfg.package}/bin/bitmagnet worker run --all"; + Restart = "on-failure"; + WorkingDirectory = "/var/lib/bitmagnet"; + StateDirectory = "bitmagnet"; + + # Sandboxing (sorted by occurrence in https://www.freedesktop.org/software/systemd/man/systemd.exec.html) + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = [ + "AF_UNIX" + "AF_INET" + "AF_INET6" + ]; + RestrictNamespaces = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + PrivateMounts = true; + }; + }; + users.users = mkIf (cfg.user == "bitmagnet") { + bitmagnet = { + group = cfg.group; + isSystemUser = true; + }; + }; + users.groups = mkIf (cfg.group == "bitmagnet") { bitmagnet = { }; }; + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = [ cfg.dht_server.port ]; + allowedUDPPorts = [ cfg.dht_server.port ]; + }; + services.postgresql = mkIf cfg.useLocalPostgresDB { + enable = true; + ensureDatabases = [ + cfg.settings.postgres.name + (if (cfg.settings.postgres.user == "") then cfg.user else cfg.settings.postgres.user) + ]; + ensureUsers = [ + { + name = if (cfg.settings.postgres.user == "") then cfg.user else cfg.settings.postgres.user; + ensureDBOwnership = true; + } + ]; + }; + }; + + meta.maintainers = with lib.maintainers; [ gileri ]; +}