From b13b9489ad23ab245e1d4a4f6cca8d97fab62a42 Mon Sep 17 00:00:00 2001 From: Rodney Lorrimar Date: Sun, 29 Nov 2015 21:28:29 +0000 Subject: [PATCH] pump.io service: init Pump.io runs its web server as a standalone service listening on 443. It's also possible to put the service behind a HTTP reverse proxy. --- nixos/modules/misc/ids.nix | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/web-apps/pump.io.nix | 364 ++++++++++++++++++++ 3 files changed, 367 insertions(+) create mode 100644 nixos/modules/services/web-apps/pump.io.nix diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 2b40120641a..6ff95605d4b 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -237,6 +237,7 @@ calibre-server = 213; heapster = 214; bepasty = 215; + pumpio = 216; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -451,6 +452,7 @@ xtreemfs = 212; calibre-server = 213; bepasty = 215; + pumpio = 216; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index a8cf38f1c8f..9fc1d54bd84 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -401,6 +401,7 @@ ./services/ttys/agetty.nix ./services/ttys/gpm.nix ./services/ttys/kmscon.nix + ./services/web-apps/pump.io.nix ./services/web-servers/apache-httpd/default.nix ./services/web-servers/fcgiwrap.nix ./services/web-servers/jboss/default.nix diff --git a/nixos/modules/services/web-apps/pump.io.nix b/nixos/modules/services/web-apps/pump.io.nix new file mode 100644 index 00000000000..b7c64bc6940 --- /dev/null +++ b/nixos/modules/services/web-apps/pump.io.nix @@ -0,0 +1,364 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.pumpio; + dataDir = "/var/lib/pump.io"; + user = "pumpio"; + + configOptions = { + driver = if cfg.driver == "disk" then null else cfg.driver; + params = ({ } // + (if cfg.driver == "disk" then { + dir = dataDir; + } else { }) // + (if cfg.driver == "mongodb" || cfg.driver == "redis" then { + host = cfg.dbHost; + port = cfg.dbPort; + dbname = cfg.dbName; + dbuser = cfg.dbUser; + dbpass = cfg.dbPassword; + } else { }) // + (if cfg.driver == "memcached" then { + host = cfg.dbHost; + port = cfg.dbPort; + } else { }) // + cfg.driverParams); + + secret = cfg.secret; + + address = cfg.address; + port = cfg.port; + + noweb = false; + urlPort = cfg.urlPort; + hostname = cfg.hostname; + favicon = cfg.favicon; + + site = cfg.site; + owner = cfg.owner; + ownerURL = cfg.ownerURL; + + key = cfg.sslKey; + cert = cfg.sslCert; + bounce = false; + + spamhost = cfg.spamHost; + spamclientid = cfg.spamClientId; + spamclientsecret = cfg.spamClientSecret; + + requireEmail = cfg.requireEmail; + smtpserver = cfg.smtpHost; + smtpport = cfg.smtpPort; + smtpuser = cfg.smtpUser; + smtppass = cfg.smtpPassword; + smtpusessl = cfg.smtpUseSSL; + smtpfrom = cfg.smtpFrom; + + nologger = false; + uploaddir = "${dataDir}/uploads"; + debugClient = false; + firehose = cfg.firehose; + disableRegistration = cfg.disableRegistration; + } // + (if cfg.port < 1024 then { + serverUser = user; # have pump.io listen then drop privileges + } else { }) // + cfg.extraConfig; + +in + +{ + options = { + + services.pumpio = { + + enable = mkEnableOption "Pump.io social streams server"; + + secret = mkOption { + type = types.str; + example = "my dog has fleas"; + description = '' + A session-generating secret, server-wide password. Warning: + this is stored in cleartext in the Nix store! + ''; + }; + + site = mkOption { + type = types.str; + example = "Awesome Sauce"; + description = "Name of the server"; + }; + + owner = mkOption { + type = types.str; + default = ""; + example = "Awesome Inc."; + description = "Name of owning entity, if you want to link to it."; + }; + + ownerURL = mkOption { + type = types.str; + default = ""; + example = "https://pump.io"; + description = "URL of owning entity, if you want to link to it."; + }; + + address = mkOption { + type = types.str; + default = "localhost"; + description = '' + Web server listen address. + ''; + }; + + port = mkOption { + type = types.int; + default = 31337; + description = '' + Port to listen on. Defaults to 31337, which is suitable for + running behind a reverse proxy. For a standalone server, + use 443. + ''; + }; + + hostname = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The hostname of the server, used for generating + URLs. Defaults to "localhost" which doesn't do much for you. + ''; + }; + + urlPort = mkOption { + type = types.int; + default = 443; + description = '' + Port to use for generating URLs. This basically has to be + either 80 or 443 because the host-meta and Webfinger + protocols don't make any provision for HTTP/HTTPS servers + running on other ports. + ''; + }; + + favicon = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Local filesystem path to the favicon.ico file to use. This + will be served as "/favicon.ico" by the server. + ''; + }; + + sslKey = mkOption { + type = types.path; + example = "${dataDir}/myserver.key"; + default = ""; + description = '' + The path to the server certificate private key. The + certificate is required, but it can be self-signed. + ''; + }; + + sslCert = mkOption { + type = types.path; + example = "${dataDir}/myserver.crt"; + default = ""; + description = '' + The path to the server certificate. The certificate is + required, but it can be self-signed. + ''; + }; + + firehose = mkOption { + type = types.str; + default = "ofirehose.com"; + description = '' + Firehose host running the ofirehose software. Defaults to + "ofirehose.com". Public notices will be ping this firehose + server and from there go out to search engines and the + world. If you want to disconnect from the public web, set + this to something falsy. + ''; + }; + + disableRegistration = mkOption { + type = types.bool; + default = false; + description = '' + Disables registering new users on the site through the Web + or the API. + ''; + }; + + requireEmail = mkOption { + type = types.bool; + default = false; + description = "Require an e-mail address to register."; + }; + + extraConfig = mkOption { + default = { }; + description = '' + Extra configuration options which are serialized to json and added + to the pump.io.json config file. + ''; + }; + + driver = mkOption { + type = types.enum [ "mongodb" "disk" "lrucache" "memcached" "redis" ]; + default = "mongodb"; + description = "Type of database. Corresponds to a nodejs databank driver."; + }; + + driverParams = mkOption { + default = { }; + description = "Extra parameters for the driver."; + }; + + dbHost = mkOption { + type = types.str; + default = "localhost"; + description = "The database host to connect to."; + }; + + dbPort = mkOption { + type = types.int; + default = 27017; + description = "The port that the database is listening on."; + }; + + dbName = mkOption { + type = types.str; + default = "pumpio"; + description = "The name of the database to use."; + }; + + dbUser = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The username. Defaults to null, meaning no authentication. + ''; + }; + + dbPassword = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The password corresponding to dbUser. Warning: this is + stored in cleartext in the Nix store! + ''; + }; + + smtpHost = mkOption { + type = types.nullOr types.str; + default = null; + example = "localhost"; + description = '' + Server to use for sending transactional email. If it's not + set up, no email is sent and features like password recovery + and email notification won't work. + ''; + }; + + smtpPort = mkOption { + type = types.int; + default = 25; + description = '' + Port to connect to on SMTP server. + ''; + }; + + smtpUser = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Username to use to connect to SMTP server. Might not be + necessary for some servers. + ''; + }; + + smtpPassword = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Password to use to connect to SMTP server. Might not be + necessary for some servers. Warning: this is stored in + cleartext in the Nix store! + ''; + }; + + smtpUseSSL = mkOption { + type = types.bool; + default = false; + description = '' + Only use SSL with the SMTP server. By default, a SSL + connection is negotiated using TLS. You may need to change + the smtpPort value if you set this. + ''; + }; + + smtpFrom = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Email address to use in the "From:" header of outgoing + notifications. Defaults to 'no-reply@' plus the site + hostname. + ''; + }; + + spamHost = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Host running activityspam software to use to test updates + for spam. + ''; + }; + spamClientId = mkOption { + type = types.nullOr types.str; + default = null; + description = "OAuth pair for spam server."; + }; + spamClientSecret = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + OAuth pair for spam server. Warning: this is + stored in cleartext in the Nix store! + ''; + }; + }; + + }; + + config = mkIf cfg.enable { + systemd.services."pump.io" = + { description = "pump.io social network stream server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig.ExecStart = "${pkgs.pumpio}/bin/pump -c /etc/pump.io.json"; + serviceConfig.User = if cfg.port < 1024 then "root" else user; + serviceConfig.Group = user; + }; + + environment.etc."pump.io.json" = { + mode = "0440"; + gid = config.ids.gids.pumpio; + text = builtins.toJSON configOptions; + }; + + users.extraGroups.pumpio.gid = config.ids.gids.pumpio; + users.extraUsers.pumpio = { + group = "pumpio"; + uid = config.ids.uids.pumpio; + description = "Pump.io user"; + home = dataDir; + createHome = true; + }; + }; +}