Unverified Commit 4a938b59 authored by K900's avatar K900 Committed by GitHub
Browse files

nixos/bitmagnet: init (#337310)

parents 09749752 d8f20db7
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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";
+3 −0
Original line number Diff line number Diff line
@@ -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).
+185 −0
Original line number Diff line number Diff line
{
  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 ];
}