at 17.09-beta 13 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.pumpio; 7 dataDir = "/var/lib/pump.io"; 8 runDir = "/run/pump.io"; 9 user = "pumpio"; 10 11 optionalSet = condition: value: if condition then value else {}; 12 13 configScript = ./pump.io-configure.js; 14 configOptions = { 15 outputFile = "${runDir}/config.json"; 16 config = 17 (optionalSet (cfg.driver != "disk") { 18 driver = cfg.driver; 19 }) // 20 { 21 params = (optionalSet (cfg.driver == "disk") { dir = dataDir; }) // 22 (optionalSet (cfg.driver == "mongodb" || cfg.driver == "redis") { 23 host = cfg.dbHost; 24 port = cfg.dbPort; 25 dbname = cfg.dbName; 26 dbuser = cfg.dbUser; 27 dbpass = cfg.dbPassword; 28 }) // 29 (optionalSet (cfg.driver == "memcached") { 30 host = cfg.dbHost; 31 port = cfg.dbPort; 32 }) // cfg.driverParams; 33 secret = cfg.secret; 34 35 address = cfg.address; 36 port = cfg.port; 37 38 noweb = false; 39 urlPort = cfg.urlPort; 40 hostname = cfg.hostname; 41 favicon = cfg.favicon; 42 43 site = cfg.site; 44 owner = cfg.owner; 45 ownerURL = cfg.ownerURL; 46 47 key = cfg.sslKey; 48 cert = cfg.sslCert; 49 bounce = false; 50 51 spamhost = cfg.spamHost; 52 spamclientid = cfg.spamClientId; 53 spamclientsecret = cfg.spamClientSecret; 54 55 requireEmail = cfg.requireEmail; 56 smtpserver = cfg.smtpHost; 57 smtpport = cfg.smtpPort; 58 smtpuser = cfg.smtpUser; 59 smtppass = cfg.smtpPassword; 60 smtpusessl = cfg.smtpUseSSL; 61 smtpfrom = cfg.smtpFrom; 62 63 nologger = false; 64 enableUploads = cfg.enableUploads; 65 datadir = dataDir; 66 debugClient = false; 67 firehose = cfg.firehose; 68 disableRegistration = cfg.disableRegistration; 69 70 inherit (cfg) secretFile dbPasswordFile smtpPasswordFile spamClientSecretFile; 71 } // 72 (optionalSet (cfg.port < 1024) { 73 serverUser = user; # have pump.io listen then drop privileges 74 }) // cfg.extraConfig; 75}; in { 76 options = { 77 78 services.pumpio = { 79 80 enable = mkEnableOption "Pump.io social streams server"; 81 82 secret = mkOption { 83 type = types.nullOr types.str; 84 default = null; 85 example = "my dog has fleas"; 86 description = '' 87 A session-generating secret, server-wide password. Warning: 88 this is stored in cleartext in the Nix store! 89 ''; 90 }; 91 92 secretFile = mkOption { 93 type = types.nullOr types.path; 94 default = null; 95 example = "/run/keys/pump.io-secret"; 96 description = '' 97 A file containing the session-generating secret, 98 server-wide password. 99 ''; 100 }; 101 102 site = mkOption { 103 type = types.str; 104 example = "Awesome Sauce"; 105 description = "Name of the server"; 106 }; 107 108 owner = mkOption { 109 type = types.str; 110 default = ""; 111 example = "Awesome Inc."; 112 description = "Name of owning entity, if you want to link to it."; 113 }; 114 115 ownerURL = mkOption { 116 type = types.str; 117 default = ""; 118 example = "https://pump.io"; 119 description = "URL of owning entity, if you want to link to it."; 120 }; 121 122 address = mkOption { 123 type = types.str; 124 default = "localhost"; 125 description = '' 126 Web server listen address. 127 ''; 128 }; 129 130 port = mkOption { 131 type = types.int; 132 default = 31337; 133 description = '' 134 Port to listen on. Defaults to 31337, which is suitable for 135 running behind a reverse proxy. For a standalone server, 136 use 443. 137 ''; 138 }; 139 140 hostname = mkOption { 141 type = types.nullOr types.str; 142 default = "localhost"; 143 description = '' 144 The hostname of the server, used for generating 145 URLs. Defaults to "localhost" which doesn't do much for you. 146 ''; 147 }; 148 149 urlPort = mkOption { 150 type = types.int; 151 default = 443; 152 description = '' 153 Port to use for generating URLs. This basically has to be 154 either 80 or 443 because the host-meta and Webfinger 155 protocols don't make any provision for HTTP/HTTPS servers 156 running on other ports. 157 ''; 158 }; 159 160 favicon = mkOption { 161 type = types.nullOr types.path; 162 default = null; 163 description = '' 164 Local filesystem path to the favicon.ico file to use. This 165 will be served as "/favicon.ico" by the server. 166 ''; 167 }; 168 169 enableUploads = mkOption { 170 type = types.bool; 171 default = true; 172 description = '' 173 If you want to disable file uploads, set this to false. Uploaded files will be stored 174 in ${dataDir}/uploads. 175 ''; 176 }; 177 178 sslKey = mkOption { 179 type = types.path; 180 example = "${dataDir}/myserver.key"; 181 default = ""; 182 description = '' 183 The path to the server certificate private key. The 184 certificate is required, but it can be self-signed. 185 ''; 186 }; 187 188 sslCert = mkOption { 189 type = types.path; 190 example = "${dataDir}/myserver.crt"; 191 default = ""; 192 description = '' 193 The path to the server certificate. The certificate is 194 required, but it can be self-signed. 195 ''; 196 }; 197 198 firehose = mkOption { 199 type = types.str; 200 default = "ofirehose.com"; 201 description = '' 202 Firehose host running the ofirehose software. Defaults to 203 "ofirehose.com". Public notices will be ping this firehose 204 server and from there go out to search engines and the 205 world. If you want to disconnect from the public web, set 206 this to something falsy. 207 ''; 208 }; 209 210 disableRegistration = mkOption { 211 type = types.bool; 212 default = false; 213 description = '' 214 Disables registering new users on the site through the Web 215 or the API. 216 ''; 217 }; 218 219 requireEmail = mkOption { 220 type = types.bool; 221 default = false; 222 description = "Require an e-mail address to register."; 223 }; 224 225 extraConfig = mkOption { 226 default = { }; 227 description = '' 228 Extra configuration options which are serialized to json and added 229 to the pump.io.json config file. 230 ''; 231 }; 232 233 driver = mkOption { 234 type = types.enum [ "mongodb" "disk" "lrucache" "memcached" "redis" ]; 235 default = "mongodb"; 236 description = "Type of database. Corresponds to a nodejs databank driver."; 237 }; 238 239 driverParams = mkOption { 240 default = { }; 241 description = "Extra parameters for the driver."; 242 }; 243 244 dbHost = mkOption { 245 type = types.str; 246 default = "localhost"; 247 description = "The database host to connect to."; 248 }; 249 250 dbPort = mkOption { 251 type = types.int; 252 default = 27017; 253 description = "The port that the database is listening on."; 254 }; 255 256 dbName = mkOption { 257 type = types.str; 258 default = "pumpio"; 259 description = "The name of the database to use."; 260 }; 261 262 dbUser = mkOption { 263 type = types.nullOr types.str; 264 default = null; 265 description = '' 266 The username. Defaults to null, meaning no authentication. 267 ''; 268 }; 269 270 dbPassword = mkOption { 271 type = types.nullOr types.str; 272 default = null; 273 description = '' 274 The password corresponding to dbUser. Warning: this is 275 stored in cleartext in the Nix store! 276 ''; 277 }; 278 279 dbPasswordFile = mkOption { 280 type = types.nullOr types.path; 281 default = null; 282 example = "/run/keys/pump.io-dbpassword"; 283 description = '' 284 A file containing the password corresponding to dbUser. 285 ''; 286 }; 287 288 smtpHost = mkOption { 289 type = types.nullOr types.str; 290 default = null; 291 example = "localhost"; 292 description = '' 293 Server to use for sending transactional email. If it's not 294 set up, no email is sent and features like password recovery 295 and email notification won't work. 296 ''; 297 }; 298 299 smtpPort = mkOption { 300 type = types.int; 301 default = 25; 302 description = '' 303 Port to connect to on SMTP server. 304 ''; 305 }; 306 307 smtpUser = mkOption { 308 type = types.nullOr types.str; 309 default = null; 310 description = '' 311 Username to use to connect to SMTP server. Might not be 312 necessary for some servers. 313 ''; 314 }; 315 316 smtpPassword = mkOption { 317 type = types.nullOr types.str; 318 default = null; 319 description = '' 320 Password to use to connect to SMTP server. Might not be 321 necessary for some servers. Warning: this is stored in 322 cleartext in the Nix store! 323 ''; 324 }; 325 326 smtpPasswordFile = mkOption { 327 type = types.nullOr types.path; 328 default = null; 329 example = "/run/keys/pump.io-smtppassword"; 330 description = '' 331 A file containing the password used to connect to SMTP 332 server. Might not be necessary for some servers. 333 ''; 334 }; 335 336 337 smtpUseSSL = mkOption { 338 type = types.bool; 339 default = false; 340 description = '' 341 Only use SSL with the SMTP server. By default, a SSL 342 connection is negotiated using TLS. You may need to change 343 the smtpPort value if you set this. 344 ''; 345 }; 346 347 smtpFrom = mkOption { 348 type = types.nullOr types.str; 349 default = null; 350 description = '' 351 Email address to use in the "From:" header of outgoing 352 notifications. Defaults to 'no-reply@' plus the site 353 hostname. 354 ''; 355 }; 356 357 spamHost = mkOption { 358 type = types.nullOr types.str; 359 default = null; 360 description = '' 361 Host running activityspam software to use to test updates 362 for spam. 363 ''; 364 }; 365 spamClientId = mkOption { 366 type = types.nullOr types.str; 367 default = null; 368 description = "OAuth pair for spam server."; 369 }; 370 spamClientSecret = mkOption { 371 type = types.nullOr types.str; 372 default = null; 373 description = '' 374 OAuth pair for spam server. Warning: this is 375 stored in cleartext in the Nix store! 376 ''; 377 }; 378 spamClientSecretFile = mkOption { 379 type = types.nullOr types.path; 380 default = null; 381 example = "/run/keys/pump.io-spamclientsecret"; 382 description = '' 383 A file containing the OAuth key for the spam server. 384 ''; 385 }; 386 }; 387 388 }; 389 390 config = mkIf cfg.enable { 391 warnings = let warn = k: optional (cfg.${k} != null) 392 "config.services.pumpio.${k} is insecure. Use ${k}File instead."; 393 in concatMap warn [ "secret" "dbPassword" "smtpPassword" "spamClientSecret" ]; 394 395 assertions = [ 396 { assertion = !(isNull cfg.secret && isNull cfg.secretFile); 397 message = "pump.io needs a secretFile configured"; 398 } 399 ]; 400 401 systemd.services."pump.io" = 402 { description = "Pump.io - stream server that does most of what people really want from a social network"; 403 after = [ "network.target" ]; 404 wantedBy = [ "multi-user.target" ]; 405 406 preStart = '' 407 mkdir -p ${dataDir}/uploads 408 mkdir -p ${runDir} 409 chown pumpio:pumpio ${dataDir}/uploads ${runDir} 410 chmod 770 ${dataDir}/uploads ${runDir} 411 412 ${pkgs.nodejs}/bin/node ${configScript} <<EOF 413 ${builtins.toJSON configOptions} 414 EOF 415 416 chgrp pumpio ${configOptions.outputFile} 417 chmod 640 ${configOptions.outputFile} 418 ''; 419 420 serviceConfig = { 421 ExecStart = "${pkgs.pumpio}/bin/pump -c ${configOptions.outputFile}"; 422 PermissionsStartOnly = true; 423 User = if cfg.port < 1024 then "root" else user; 424 Group = user; 425 }; 426 environment = { NODE_ENV = "production"; }; 427 }; 428 429 users.extraGroups.pumpio.gid = config.ids.gids.pumpio; 430 users.extraUsers.pumpio = { 431 group = "pumpio"; 432 uid = config.ids.uids.pumpio; 433 description = "Pump.io user"; 434 home = dataDir; 435 createHome = true; 436 }; 437 }; 438}