diff options
author | Peter Simons <simons@cryp.to> | 2019-09-01 20:33:47 +0200 |
---|---|---|
committer | Peter Simons <simons@cryp.to> | 2019-09-11 12:19:23 +0200 |
commit | 72c7ba5aba1d8dde9da8f4e7b5805edb30cbad7b (patch) | |
tree | 81677e67bda83b285e09402e65edba846d1f9980 /nixos | |
parent | 14854f20bb8002fa70828c820233ec05b177d04f (diff) | |
download | nixlib-72c7ba5aba1d8dde9da8f4e7b5805edb30cbad7b.tar nixlib-72c7ba5aba1d8dde9da8f4e7b5805edb30cbad7b.tar.gz nixlib-72c7ba5aba1d8dde9da8f4e7b5805edb30cbad7b.tar.bz2 nixlib-72c7ba5aba1d8dde9da8f4e7b5805edb30cbad7b.tar.lz nixlib-72c7ba5aba1d8dde9da8f4e7b5805edb30cbad7b.tar.xz nixlib-72c7ba5aba1d8dde9da8f4e7b5805edb30cbad7b.tar.zst nixlib-72c7ba5aba1d8dde9da8f4e7b5805edb30cbad7b.zip |
nixos/mailman: add support for the Mailman Web UI (Postorius & Hyperkitty)
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/modules/services/mail/mailman.nix | 193 |
1 files changed, 184 insertions, 9 deletions
diff --git a/nixos/modules/services/mail/mailman.nix b/nixos/modules/services/mail/mailman.nix index 11dd5cb48db0..93f4d8899553 100644 --- a/nixos/modules/services/mail/mailman.nix +++ b/nixos/modules/services/mail/mailman.nix @@ -6,14 +6,14 @@ let cfg = config.services.mailman; - pythonEnv = pkgs.python3.withPackages (ps: [ps.mailman]); + mailmanPyEnv = pkgs.python3.withPackages (ps: [ps.mailman ps.mailman-hyperkitty]); mailmanExe = with pkgs; stdenv.mkDerivation { name = "mailman-" + python3Packages.mailman.version; unpackPhase = ":"; installPhase = '' mkdir -p $out/bin - sed >"$out/bin/mailman" <"${pythonEnv}/bin/mailman" \ + sed >"$out/bin/mailman" <"${mailmanPyEnv}/bin/mailman" \ -e "2 iexport MAILMAN_CONFIG_FILE=/etc/mailman.cfg" chmod +x $out/bin/mailman ''; @@ -28,13 +28,40 @@ let bin_dir: ${pkgs.python3Packages.mailman}/bin var_dir: /var/lib/mailman queue_dir: $var_dir/queue + template_dir: $var_dir/templates log_dir: $var_dir/log lock_dir: $var_dir/lock etc_dir: /etc ext_dir: $etc_dir/mailman.d pid_file: /run/mailman/master.pid + '' + optionalString (cfg.hyperkittyApiKey != null) '' + [archiver.hyperkitty] + class: mailman_hyperkitty.Archiver + enable: yes + configuration: ${pkgs.writeText "mailman-hyperkitty.cfg" mailmanHyperkittyCfg} ''; + mailmanHyperkittyCfg = '' + [general] + # This is your HyperKitty installation, preferably on the localhost. This + # address will be used by Mailman to forward incoming emails to HyperKitty + # for archiving. It does not need to be publicly available, in fact it's + # better if it is not. + base_url: ${cfg.hyperkittyBaseUrl} + + # Shared API key, must be the identical to the value in HyperKitty's + # settings. + api_key: ${cfg.hyperkittyApiKey} + ''; + + djangoPyEnv = pkgs.python3.withPackages (x: with x; [postorius hyperkitty]); + + djangoExe = with pkgs; stdenv.mkDerivation { + name = "mailman-django-" + python3Packages.mailman.version; + unpackPhase = ":"; + installPhase = "install -D ${djangoPyEnv}/bin/django-admin $out/bin/mailman-django-admin"; + }; + in { ###### interface @@ -51,7 +78,7 @@ in { siteOwner = mkOption { type = types.str; - default = "postmaster"; + default = "postmaster@example.org"; description = '' Certain messages that must be delivered to a human, but which can't be delivered to a list owner (e.g. a bounce from a list owner), will @@ -59,6 +86,51 @@ in { ''; }; + webRoot = mkOption { + type = types.path; + default = pkgs.python3Packages.mailman-web.override { serverEMail = cfg.siteOwner; + archiverKey = cfg.hyperkittyApiKey; + allowedHosts = cfg.webHosts; + }; + defaultText = "pkgs.python3Packages.mailman-web"; + description = '' + The web root for the Hyperkity + Postorius apps provided by Mailman. + This variable can be set, of course, but it mainly exists so that site + admins can refer to it in their own hand-written httpd configuration files. + ''; + }; + + webHosts = mkOption { + type = types.listOf types.string; + default = []; + description = '' + The list of hostnames and/or IP addresses from which the Mailman Web + UI will accept requests. By default, "localhost" and "127.0.0.1" are + enabled. All additional names under which your web server accepts + requests for the UI must be listed here or incoming requests will be + rejected. + ''; + }; + + hyperkittyBaseUrl = mkOption { + type = types.str; + default = "http://localhost/hyperkitty/"; + description = '' + Where can Mailman connect to Hyperkitty's internal API, preferably on + localhost? + ''; + }; + + hyperkittyApiKey = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The shared secret used to authenticate Mailman's internal + communication with Hyperkitty. Must be set to enable support for the + Hyperkitty archiver. Note that this secret is going to be visible to + all local users in the Nix store. + ''; + }; }; }; @@ -71,25 +143,22 @@ in { { assertion = cfg.enable -> config.services.postfix.enable; message = "Mailman requires Postfix"; } - { assertion = config.services.postfix.recipientDelimiter == "+"; - message = "Postfix's recipientDelimiter must be set to '+'."; - } ]; users.users.mailman = { description = "GNU Mailman"; isSystemUser = true; }; environment = { - systemPackages = [ mailmanExe ]; + systemPackages = [ mailmanExe djangoExe pkgs.sassc ]; etc."mailman.cfg".text = mailmanCfg; }; services.postfix = { relayDomains = [ "hash:/var/lib/mailman/data/postfix_domains" ]; + recipientDelimiter = "+"; # bake recipient addresses in mail envelopes via VERP config = { transport_maps = [ "hash:/var/lib/mailman/data/postfix_lmtp" ]; local_recipient_maps = [ "hash:/var/lib/mailman/data/postfix_lmtp" ]; - # Mailman uses recipient delimiters, so we don't need special handling. - owner_request_special = "no"; + owner_request_special = "no"; # Mailman handles -owner addresses on its own }; }; @@ -109,6 +178,112 @@ in { }; }; + systemd.services.mailman-web = { + description = "Init Postorius DB"; + before = [ "httpd.service" ]; + wantedBy = [ "httpd.service" ]; + script = '' + ${djangoExe}/bin/mailman-django-admin migrate --pythonpath ${cfg.webRoot} --settings settings + rm -rf static + ${djangoExe}/bin/mailman-django-admin collectstatic --pythonpath ${cfg.webRoot} --settings settings + ${djangoExe}/bin/mailman-django-admin compress --pythonpath ${cfg.webRoot} --settings settings + ''; + serviceConfig = { + User = config.services.httpd.user; + Type = "oneshot"; + StateDirectory = "mailman-web"; + StateDirectoryMode = "0700"; + WorkingDirectory = "/var/lib/mailman-web"; + }; + }; + + systemd.services.mailman-daily = { + description = "Trigger daily Mailman events"; + startAt = "daily"; + serviceConfig = { + ExecStart = "${mailmanExe}/bin/mailman digests --send"; + User = "mailman"; + }; + }; + + systemd.services.hyperkitty = { + enable = cfg.hyperkittyApiKey != null; + description = "GNU Hyperkitty QCluster Process"; + after = [ "network.target" ]; + wantedBy = [ "mailman.service" "multi-user.target" ]; + serviceConfig = { + ExecStart = "${djangoExe}/bin/mailman-django-admin qcluster --pythonpath ${cfg.webRoot} --settings settings"; + User = config.services.httpd.user; + WorkingDirectory = "/var/lib/mailman-web"; + }; + }; + + systemd.services.hyperkitty-minutely = { + enable = cfg.hyperkittyApiKey != null; + description = "Trigger minutely Hyperkitty events"; + startAt = "minutely"; + serviceConfig = { + ExecStart = "${djangoExe}/bin/mailman-django-admin runjobs minutely --pythonpath ${cfg.webRoot} --settings settings"; + User = config.services.httpd.user; + WorkingDirectory = "/var/lib/mailman-web"; + }; + }; + + systemd.services.hyperkitty-quarter-hourly = { + enable = cfg.hyperkittyApiKey != null; + description = "Trigger quarter-hourly Hyperkitty events"; + startAt = "*:00/15"; + serviceConfig = { + ExecStart = "${djangoExe}/bin/mailman-django-admin runjobs quarter_hourly --pythonpath ${cfg.webRoot} --settings settings"; + User = config.services.httpd.user; + WorkingDirectory = "/var/lib/mailman-web"; + }; + }; + + systemd.services.hyperkitty-hourly = { + enable = cfg.hyperkittyApiKey != null; + description = "Trigger hourly Hyperkitty events"; + startAt = "hourly"; + serviceConfig = { + ExecStart = "${djangoExe}/bin/mailman-django-admin runjobs hourly --pythonpath ${cfg.webRoot} --settings settings"; + User = config.services.httpd.user; + WorkingDirectory = "/var/lib/mailman-web"; + }; + }; + + systemd.services.hyperkitty-daily = { + enable = cfg.hyperkittyApiKey != null; + description = "Trigger daily Hyperkitty events"; + startAt = "daily"; + serviceConfig = { + ExecStart = "${djangoExe}/bin/mailman-django-admin runjobs daily --pythonpath ${cfg.webRoot} --settings settings"; + User = config.services.httpd.user; + WorkingDirectory = "/var/lib/mailman-web"; + }; + }; + + systemd.services.hyperkitty-weekly = { + enable = cfg.hyperkittyApiKey != null; + description = "Trigger weekly Hyperkitty events"; + startAt = "weekly"; + serviceConfig = { + ExecStart = "${djangoExe}/bin/mailman-django-admin runjobs weekly --pythonpath ${cfg.webRoot} --settings settings"; + User = config.services.httpd.user; + WorkingDirectory = "/var/lib/mailman-web"; + }; + }; + + systemd.services.hyperkitty-yearly = { + enable = cfg.hyperkittyApiKey != null; + description = "Trigger yearly Hyperkitty events"; + startAt = "yearly"; + serviceConfig = { + ExecStart = "${djangoExe}/bin/mailman-django-admin runjobs yearly --pythonpath ${cfg.webRoot} --settings settings"; + User = config.services.httpd.user; + WorkingDirectory = "/var/lib/mailman-web"; + }; + }; + }; } |