diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index 656fa4c1444c..8caa9a5de0fd 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -7877,6 +7877,17 @@ githubId = 15957973; name = "Jeffry Molanus"; }; + gileri = { + email = "s@linuxw.info"; + github = "gileri"; + githubId = 493438; + name = "Éric Gillet"; + keys = [ + { + fingerprint = "E478 85DC 8F33 FA86 D3FC 183D 80A8 14DB 8ED5 70BC"; + } + ]; + }; gilice = { email = "gilice@proton.me"; github = "gilice"; diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md index 929017a5e550..371d338a3418 100644 --- a/nixos/doc/manual/release-notes/rl-2411.section.md +++ b/nixos/doc/manual/release-notes/rl-2411.section.md @@ -165,6 +165,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). + - [Wakapi](https://wakapi.dev/), a time tracking software for programmers. Available as [services.wakapi](#opt-services.wakapi.enable). - [foot](https://codeberg.org/dnkl/foot), a fast, lightweight and minimalistic Wayland terminal emulator. Available as [programs.foot](#opt-programs.foot.enable). 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 ]; +}