at master 5.6 kB view raw
1{ 2 pkgs, 3 config, 4 lib, 5 ... 6}: 7let 8 cfg = config.services.bitmagnet; 9 inherit (lib) 10 mkEnableOption 11 mkIf 12 mkOption 13 mkPackageOption 14 optional 15 ; 16 inherit (lib.types) 17 bool 18 int 19 port 20 str 21 submodule 22 ; 23 inherit (lib.generators) toYAML; 24 25 freeformType = (pkgs.formats.yaml { }).type; 26in 27{ 28 options.services.bitmagnet = { 29 enable = mkEnableOption "Bitmagnet service"; 30 useLocalPostgresDB = mkOption { 31 description = "Use a local postgresql database, create user and database"; 32 type = bool; 33 default = true; 34 }; 35 settings = mkOption { 36 description = "Bitmagnet configuration (https://bitmagnet.io/setup/configuration.html)."; 37 default = { }; 38 type = submodule { 39 inherit freeformType; 40 options = { 41 http_server = mkOption { 42 default = { }; 43 description = "HTTP server settings"; 44 type = submodule { 45 inherit freeformType; 46 options = { 47 port = mkOption { 48 type = str; 49 default = ":3333"; 50 description = "HTTP server listen port"; 51 }; 52 }; 53 }; 54 }; 55 dht_server = mkOption { 56 default = { }; 57 description = "DHT server settings"; 58 type = submodule { 59 inherit freeformType; 60 options = { 61 port = mkOption { 62 type = port; 63 default = 3334; 64 description = "DHT listen port"; 65 }; 66 }; 67 }; 68 }; 69 postgres = mkOption { 70 default = { }; 71 description = "PostgreSQL database configuration"; 72 type = submodule { 73 inherit freeformType; 74 options = { 75 host = mkOption { 76 type = str; 77 default = ""; 78 description = "Address, hostname or Unix socket path of the database server"; 79 }; 80 name = mkOption { 81 type = str; 82 default = "bitmagnet"; 83 description = "Database name to connect to"; 84 }; 85 user = mkOption { 86 type = str; 87 default = ""; 88 description = "User to connect as"; 89 }; 90 password = mkOption { 91 type = str; 92 default = ""; 93 description = "Password for database user"; 94 }; 95 }; 96 }; 97 }; 98 }; 99 }; 100 }; 101 package = mkPackageOption pkgs "bitmagnet" { }; 102 user = mkOption { 103 description = "User running bitmagnet"; 104 type = str; 105 default = "bitmagnet"; 106 }; 107 group = mkOption { 108 description = "Group of user running bitmagnet"; 109 type = str; 110 default = "bitmagnet"; 111 }; 112 openFirewall = mkOption { 113 description = "Open DHT ports in firewall"; 114 type = bool; 115 default = false; 116 }; 117 }; 118 config = mkIf cfg.enable { 119 environment.etc."xdg/bitmagnet/config.yml" = { 120 text = toYAML { } cfg.settings; 121 mode = "0440"; 122 user = cfg.user; 123 group = cfg.group; 124 }; 125 systemd.services.bitmagnet = { 126 enable = true; 127 wantedBy = [ "multi-user.target" ]; 128 after = [ 129 "network.target" 130 ] 131 ++ optional cfg.useLocalPostgresDB "postgresql.target"; 132 requires = optional cfg.useLocalPostgresDB "postgresql.target"; 133 serviceConfig = { 134 Type = "simple"; 135 DynamicUser = true; 136 User = cfg.user; 137 Group = cfg.group; 138 ExecStart = "${cfg.package}/bin/bitmagnet worker run --all"; 139 Restart = "on-failure"; 140 WorkingDirectory = "/var/lib/bitmagnet"; 141 StateDirectory = "bitmagnet"; 142 143 # Sandboxing (sorted by occurrence in https://www.freedesktop.org/software/systemd/man/systemd.exec.html) 144 ProtectSystem = "strict"; 145 ProtectHome = true; 146 PrivateTmp = true; 147 PrivateDevices = true; 148 ProtectHostname = true; 149 ProtectClock = true; 150 ProtectKernelTunables = true; 151 ProtectKernelModules = true; 152 ProtectKernelLogs = true; 153 ProtectControlGroups = true; 154 RestrictAddressFamilies = [ 155 "AF_UNIX" 156 "AF_INET" 157 "AF_INET6" 158 ]; 159 RestrictNamespaces = true; 160 LockPersonality = true; 161 MemoryDenyWriteExecute = true; 162 RestrictRealtime = true; 163 RestrictSUIDSGID = true; 164 RemoveIPC = true; 165 PrivateMounts = true; 166 }; 167 }; 168 users.users = mkIf (cfg.user == "bitmagnet") { 169 bitmagnet = { 170 group = cfg.group; 171 isSystemUser = true; 172 }; 173 }; 174 users.groups = mkIf (cfg.group == "bitmagnet") { bitmagnet = { }; }; 175 networking.firewall = mkIf cfg.openFirewall { 176 allowedTCPPorts = [ cfg.settings.dht_server.port ]; 177 allowedUDPPorts = [ cfg.settings.dht_server.port ]; 178 }; 179 services.postgresql = mkIf cfg.useLocalPostgresDB { 180 enable = true; 181 ensureDatabases = [ 182 cfg.settings.postgres.name 183 (if (cfg.settings.postgres.user == "") then cfg.user else cfg.settings.postgres.user) 184 ]; 185 ensureUsers = [ 186 { 187 name = if (cfg.settings.postgres.user == "") then cfg.user else cfg.settings.postgres.user; 188 ensureDBOwnership = true; 189 } 190 ]; 191 }; 192 }; 193 194 meta.maintainers = with lib.maintainers; [ gileri ]; 195}