Merge pull request #86177 from mayflower/mailman-upstream

Mailman refactor
This commit is contained in:
Linus Heckemann 2020-06-19 07:54:41 +02:00 committed by GitHub
commit aea806b8ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 340 additions and 215 deletions

View File

@ -6,42 +6,46 @@ let
cfg = config.services.mailman; cfg = config.services.mailman;
pythonEnv = pkgs.python3.withPackages (ps:
[ps.mailman ps.mailman-web]
++ lib.optional cfg.hyperkitty.enable ps.mailman-hyperkitty
++ cfg.extraPythonPackages);
# This deliberately doesn't use recursiveUpdate so users can # This deliberately doesn't use recursiveUpdate so users can
# override the defaults. # override the defaults.
settings = { webSettings = {
DEFAULT_FROM_EMAIL = cfg.siteOwner; DEFAULT_FROM_EMAIL = cfg.siteOwner;
SERVER_EMAIL = cfg.siteOwner; SERVER_EMAIL = cfg.siteOwner;
ALLOWED_HOSTS = [ "localhost" "127.0.0.1" ] ++ cfg.webHosts; ALLOWED_HOSTS = [ "localhost" "127.0.0.1" ] ++ cfg.webHosts;
COMPRESS_OFFLINE = true; COMPRESS_OFFLINE = true;
STATIC_ROOT = "/var/lib/mailman-web/static"; STATIC_ROOT = "/var/lib/mailman-web-static";
MEDIA_ROOT = "/var/lib/mailman-web/media"; MEDIA_ROOT = "/var/lib/mailman-web/media";
LOGGING = {
version = 1;
disable_existing_loggers = true;
handlers.console.class = "logging.StreamHandler";
loggers.django = {
handlers = [ "console" ];
level = "INFO";
};
};
HAYSTACK_CONNECTIONS.default = {
ENGINE = "haystack.backends.whoosh_backend.WhooshEngine";
PATH = "/var/lib/mailman-web/fulltext-index";
};
} // cfg.webSettings; } // cfg.webSettings;
settingsJSON = pkgs.writeText "settings.json" (builtins.toJSON settings); webSettingsJSON = pkgs.writeText "settings.json" (builtins.toJSON webSettings);
mailmanCfg = '' # TODO: Should this be RFC42-ised so that users can set additional options without modifying the module?
[mailman] mtaConfig = pkgs.writeText "mailman-postfix.cfg" ''
site_owner: ${cfg.siteOwner} [postfix]
layout: fhs postmap_command: ${pkgs.postfix}/bin/postmap
transport_file_type: hash
[paths.fhs]
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.hyperkitty.enable ''
[archiver.hyperkitty]
class: mailman_hyperkitty.Archiver
enable: yes
configuration: /var/lib/mailman/mailman-hyperkitty.cfg
''; '';
mailmanCfg = lib.generators.toINI {} cfg.settings;
mailmanHyperkittyCfg = pkgs.writeText "mailman-hyperkitty.cfg" '' mailmanHyperkittyCfg = pkgs.writeText "mailman-hyperkitty.cfg" ''
[general] [general]
# This is your HyperKitty installation, preferably on the localhost. This # This is your HyperKitty installation, preferably on the localhost. This
@ -84,7 +88,7 @@ in {
type = types.package; type = types.package;
default = pkgs.mailman; default = pkgs.mailman;
defaultText = "pkgs.mailman"; defaultText = "pkgs.mailman";
example = "pkgs.mailman.override { archivers = []; }"; example = literalExample "pkgs.mailman.override { archivers = []; }";
description = "Mailman package to use"; description = "Mailman package to use";
}; };
@ -98,18 +102,6 @@ in {
''; '';
}; };
webRoot = mkOption {
type = types.path;
default = "${pkgs.mailman-web}/${pkgs.python3.sitePackages}";
defaultText = "\${pkgs.mailman-web}/\${pkgs.python3.sitePackages}";
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 web server
configuration files.
'';
};
webHosts = mkOption { webHosts = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [];
@ -124,7 +116,7 @@ in {
webUser = mkOption { webUser = mkOption {
type = types.str; type = types.str;
default = config.services.httpd.user; default = "mailman-web";
description = '' description = ''
User to run mailman-web as User to run mailman-web as
''; '';
@ -138,6 +130,22 @@ in {
''; '';
}; };
serve = {
enable = mkEnableOption "Automatic nginx and uwsgi setup for mailman-web";
};
extraPythonPackages = mkOption {
description = "Packages to add to the python environment used by mailman and mailman-web";
type = types.listOf types.package;
default = [];
};
settings = mkOption {
description = "Settings for mailman.cfg";
type = types.attrsOf (types.attrsOf types.str);
default = {};
};
hyperkitty = { hyperkitty = {
enable = mkEnableOption "the Hyperkitty archiver for Mailman"; enable = mkEnableOption "the Hyperkitty archiver for Mailman";
@ -158,6 +166,35 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.mailman.settings = {
mailman.site_owner = lib.mkDefault cfg.siteOwner;
mailman.layout = "fhs";
"paths.fhs" = {
bin_dir = "${pkgs.python3Packages.mailman}/bin";
var_dir = "/var/lib/mailman";
queue_dir = "$var_dir/queue";
template_dir = "$var_dir/templates";
log_dir = "/var/log/mailman";
lock_dir = "$var_dir/lock";
etc_dir = "/etc";
ext_dir = "$etc_dir/mailman.d";
pid_file = "/run/mailman/master.pid";
};
mta.configuration = lib.mkDefault "${mtaConfig}";
"archiver.hyperkitty" = lib.mkIf cfg.hyperkitty.enable {
class = "mailman_hyperkitty.Archiver";
enable = "yes";
configuration = "/var/lib/mailman/mailman-hyperkitty.cfg";
};
} // (let
loggerNames = ["root" "archiver" "bounce" "config" "database" "debug" "error" "fromusenet" "http" "locks" "mischief" "plugins" "runner" "smtp"];
loggerSectionNames = map (n: "logging.${n}") loggerNames;
in lib.genAttrs loggerSectionNames(name: { handler = "stderr"; })
);
assertions = let assertions = let
inherit (config.services) postfix; inherit (config.services) postfix;
@ -183,7 +220,17 @@ in {
(requirePostfixHash [ "config" "local_recipient_maps" ] "postfix_lmtp") (requirePostfixHash [ "config" "local_recipient_maps" ] "postfix_lmtp")
]; ];
users.users.mailman = { description = "GNU Mailman"; isSystemUser = true; }; users.users.mailman = {
description = "GNU Mailman";
isSystemUser = true;
group = "mailman";
};
users.users.mailman-web = lib.mkIf (cfg.webUser == "mailman-web") {
description = "GNU Mailman web interface";
isSystemUser = true;
group = "mailman";
};
users.groups.mailman = {};
environment.etc."mailman.cfg".text = mailmanCfg; environment.etc."mailman.cfg".text = mailmanCfg;
@ -198,14 +245,35 @@ in {
import json import json
with open('${settingsJSON}') as f: with open('${webSettingsJSON}') as f:
globals().update(json.load(f)) globals().update(json.load(f))
with open('/var/lib/mailman-web/settings_local.json') as f: with open('/var/lib/mailman-web/settings_local.json') as f:
globals().update(json.load(f)) globals().update(json.load(f))
''; '';
environment.systemPackages = [ cfg.package ] ++ (with pkgs; [ mailman-web ]); services.nginx = mkIf cfg.serve.enable {
enable = mkDefault true;
virtualHosts."${lib.head cfg.webHosts}" = {
serverAliases = cfg.webHosts;
locations = {
"/".extraConfig = "uwsgi_pass unix:/run/mailman-web.socket;";
"/static/".alias = webSettings.STATIC_ROOT + "/";
};
};
};
environment.systemPackages = [ (pkgs.buildEnv {
name = "mailman-tools";
# We don't want to pollute the system PATH with a python
# interpreter etc. so let's pick only the stuff we actually
# want from pythonEnv
pathsToLink = ["/bin"];
paths = [pythonEnv];
postBuild = ''
find $out/bin/ -mindepth 1 -not -name "mailman*" -delete
'';
}) ];
services.postfix = { services.postfix = {
recipientDelimiter = "+"; # bake recipient addresses in mail envelopes via VERP recipientDelimiter = "+"; # bake recipient addresses in mail envelopes via VERP
@ -214,181 +282,156 @@ in {
}; };
}; };
systemd.services.mailman = { systemd.sockets.mailman-uwsgi = lib.mkIf cfg.serve.enable {
description = "GNU Mailman Master Process"; wantedBy = ["sockets.target"];
after = [ "network.target" ]; before = ["nginx.service"];
restartTriggers = [ config.environment.etc."mailman.cfg".source ]; socketConfig.ListenStream = "/run/mailman-web.socket";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/mailman start";
ExecStop = "${cfg.package}/bin/mailman stop";
User = "mailman";
Type = "forking";
RuntimeDirectory = "mailman";
PIDFile = "/run/mailman/master.pid";
};
}; };
systemd.services = {
systemd.services.mailman-settings = { mailman = {
description = "Generate settings files (including secrets) for Mailman"; description = "GNU Mailman Master Process";
before = [ "mailman.service" "mailman-web.service" "hyperkitty.service" "httpd.service" "uwsgi.service" ]; after = [ "network.target" ];
requiredBy = [ "mailman.service" "mailman-web.service" "hyperkitty.service" "httpd.service" "uwsgi.service" ]; restartTriggers = [ config.environment.etc."mailman.cfg".source ];
path = with pkgs; [ jq ]; wantedBy = [ "multi-user.target" ];
script = '' serviceConfig = {
mailmanDir=/var/lib/mailman ExecStart = "${pythonEnv}/bin/mailman start";
mailmanWebDir=/var/lib/mailman-web ExecStop = "${pythonEnv}/bin/mailman stop";
User = "mailman";
mailmanCfg=$mailmanDir/mailman-hyperkitty.cfg Group = "mailman";
mailmanWebCfg=$mailmanWebDir/settings_local.json Type = "forking";
RuntimeDirectory = "mailman";
install -m 0700 -o mailman -g nogroup -d $mailmanDir LogsDirectory = "mailman";
install -m 0700 -o ${cfg.webUser} -g nogroup -d $mailmanWebDir PIDFile = "/run/mailman/master.pid";
};
if [ ! -e $mailmanWebCfg ]; then
hyperkittyApiKey=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64)
secretKey=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64)
mailmanWebCfgTmp=$(mktemp)
jq -n '.MAILMAN_ARCHIVER_KEY=$archiver_key | .SECRET_KEY=$secret_key' \
--arg archiver_key "$hyperkittyApiKey" \
--arg secret_key "$secretKey" \
>"$mailmanWebCfgTmp"
chown ${cfg.webUser} "$mailmanWebCfgTmp"
mv -n "$mailmanWebCfgTmp" $mailmanWebCfg
fi
hyperkittyApiKey="$(jq -r .MAILMAN_ARCHIVER_KEY $mailmanWebCfg)"
mailmanCfgTmp=$(mktemp)
sed "s/@API_KEY@/$hyperkittyApiKey/g" ${mailmanHyperkittyCfg} >"$mailmanCfgTmp"
chown mailman "$mailmanCfgTmp"
mv "$mailmanCfgTmp" $mailmanCfg
'';
serviceConfig = {
Type = "oneshot";
# RemainAfterExit makes restartIfChanged work for this service, so
# downstream services will get updated automatically when things like
# services.mailman.hyperkitty.baseUrl change. Otherwise users have to
# restart things manually, which is confusing.
RemainAfterExit = "yes";
}; };
};
systemd.services.mailman-web = { mailman-settings = {
description = "Init Postorius DB"; description = "Generate settings files (including secrets) for Mailman";
before = [ "httpd.service" "uwsgi.service" ]; before = [ "mailman.service" "mailman-web-setup.service" "mailman-uwsgi.service" "hyperkitty.service" ];
requiredBy = [ "httpd.service" "uwsgi.service" ]; requiredBy = [ "mailman.service" "mailman-web-setup.service" "mailman-uwsgi.service" "hyperkitty.service" ];
restartTriggers = [ config.environment.etc."mailman3/settings.py".source ]; path = with pkgs; [ jq ];
script = '' script = ''
${pkgs.mailman-web}/bin/mailman-web migrate mailmanDir=/var/lib/mailman
rm -rf static mailmanWebDir=/var/lib/mailman-web
${pkgs.mailman-web}/bin/mailman-web collectstatic
${pkgs.mailman-web}/bin/mailman-web compress mailmanCfg=$mailmanDir/mailman-hyperkitty.cfg
''; mailmanWebCfg=$mailmanWebDir/settings_local.json
serviceConfig = {
User = cfg.webUser; install -m 0775 -o mailman -g mailman -d /var/lib/mailman-web-static
Type = "oneshot"; install -m 0770 -o mailman -g mailman -d $mailmanDir
# Similar to mailman-settings.service, this makes restartTriggers work install -m 0770 -o ${cfg.webUser} -g mailman -d $mailmanWebDir
# properly for this service.
RemainAfterExit = "yes"; if [ ! -e $mailmanWebCfg ]; then
WorkingDirectory = "/var/lib/mailman-web"; hyperkittyApiKey=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64)
secretKey=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64)
mailmanWebCfgTmp=$(mktemp)
jq -n '.MAILMAN_ARCHIVER_KEY=$archiver_key | .SECRET_KEY=$secret_key' \
--arg archiver_key "$hyperkittyApiKey" \
--arg secret_key "$secretKey" \
>"$mailmanWebCfgTmp"
chown root:mailman "$mailmanWebCfgTmp"
chmod 440 "$mailmanWebCfgTmp"
mv -n "$mailmanWebCfgTmp" "$mailmanWebCfg"
fi
hyperkittyApiKey="$(jq -r .MAILMAN_ARCHIVER_KEY "$mailmanWebCfg")"
mailmanCfgTmp=$(mktemp)
sed "s/@API_KEY@/$hyperkittyApiKey/g" ${mailmanHyperkittyCfg} >"$mailmanCfgTmp"
chown mailman:mailman "$mailmanCfgTmp"
mv "$mailmanCfgTmp" "$mailmanCfg"
'';
}; };
};
systemd.services.mailman-daily = { mailman-web-setup = {
description = "Trigger daily Mailman events"; description = "Prepare mailman-web files and database";
startAt = "daily"; before = [ "uwsgi.service" "mailman-uwsgi.service" ];
restartTriggers = [ config.environment.etc."mailman.cfg".source ]; requiredBy = [ "mailman-uwsgi.service" ];
serviceConfig = { restartTriggers = [ config.environment.etc."mailman3/settings.py".source ];
ExecStart = "${cfg.package}/bin/mailman digests --send"; script = ''
User = "mailman"; [[ -e "${webSettings.STATIC_ROOT}" ]] && find "${webSettings.STATIC_ROOT}/" -mindepth 1 -delete
${pythonEnv}/bin/mailman-web migrate
${pythonEnv}/bin/mailman-web collectstatic
${pythonEnv}/bin/mailman-web compress
'';
serviceConfig = {
User = cfg.webUser;
Group = "mailman";
Type = "oneshot";
WorkingDirectory = "/var/lib/mailman-web";
};
}; };
};
systemd.services.hyperkitty = { mailman-uwsgi = mkIf cfg.serve.enable (let
inherit (cfg.hyperkitty) enable; uwsgiConfig.uwsgi = {
description = "GNU Hyperkitty QCluster Process"; type = "normal";
after = [ "network.target" ]; plugins = ["python3"];
restartTriggers = [ config.environment.etc."mailman3/settings.py".source ]; home = pythonEnv;
wantedBy = [ "mailman.service" "multi-user.target" ]; module = "mailman_web.wsgi";
serviceConfig = { };
ExecStart = "${pkgs.mailman-web}/bin/mailman-web qcluster"; uwsgiConfigFile = pkgs.writeText "uwsgi-mailman.json" (builtins.toJSON uwsgiConfig);
User = cfg.webUser; in {
WorkingDirectory = "/var/lib/mailman-web"; wantedBy = ["multi-user.target"];
requires = ["mailman-uwsgi.socket" "mailman-web-setup.service"];
restartTriggers = [ config.environment.etc."mailman3/settings.py".source ];
serviceConfig = {
# Since the mailman-web settings.py obstinately creates a logs
# dir in the cwd, change to the (writable) runtime directory before
# starting uwsgi.
ExecStart = "${pkgs.coreutils}/bin/env -C $RUNTIME_DIRECTORY ${pkgs.uwsgi.override { plugins = ["python3"]; }}/bin/uwsgi --json ${uwsgiConfigFile}";
User = cfg.webUser;
Group = "mailman";
RuntimeDirectory = "mailman-uwsgi";
};
});
mailman-daily = {
description = "Trigger daily Mailman events";
startAt = "daily";
restartTriggers = [ config.environment.etc."mailman.cfg".source ];
serviceConfig = {
ExecStart = "${pythonEnv}/bin/mailman digests --send";
User = "mailman";
Group = "mailman";
};
}; };
};
systemd.services.hyperkitty-minutely = { hyperkitty = lib.mkIf cfg.hyperkitty.enable {
inherit (cfg.hyperkitty) enable; description = "GNU Hyperkitty QCluster Process";
description = "Trigger minutely Hyperkitty events"; after = [ "network.target" ];
startAt = "minutely"; restartTriggers = [ config.environment.etc."mailman3/settings.py".source ];
restartTriggers = [ config.environment.etc."mailman3/settings.py".source ]; wantedBy = [ "mailman.service" "multi-user.target" ];
serviceConfig = { serviceConfig = {
ExecStart = "${pkgs.mailman-web}/bin/mailman-web runjobs minutely"; ExecStart = "${pythonEnv}/bin/mailman-web qcluster";
User = cfg.webUser; User = cfg.webUser;
WorkingDirectory = "/var/lib/mailman-web"; Group = "mailman";
WorkingDirectory = "/var/lib/mailman-web";
};
}; };
}; } // flip lib.mapAttrs' {
"minutely" = "minutely";
systemd.services.hyperkitty-quarter-hourly = { "quarter_hourly" = "*:00/15";
inherit (cfg.hyperkitty) enable; "hourly" = "hourly";
description = "Trigger quarter-hourly Hyperkitty events"; "daily" = "daily";
startAt = "*:00/15"; "weekly" = "weekly";
restartTriggers = [ config.environment.etc."mailman3/settings.py".source ]; "yearly" = "yearly";
serviceConfig = { } (name: startAt:
ExecStart = "${pkgs.mailman-web}/bin/mailman-web runjobs quarter_hourly"; lib.nameValuePair "hyperkitty-${name}" (lib.mkIf cfg.hyperkitty.enable {
User = cfg.webUser; description = "Trigger ${name} Hyperkitty events";
WorkingDirectory = "/var/lib/mailman-web"; inherit startAt;
}; restartTriggers = [ config.environment.etc."mailman3/settings.py".source ];
}; serviceConfig = {
ExecStart = "${pythonEnv}/bin/mailman-web runjobs minutely";
systemd.services.hyperkitty-hourly = { User = cfg.webUser;
inherit (cfg.hyperkitty) enable; Group = "mailman";
description = "Trigger hourly Hyperkitty events"; WorkingDirectory = "/var/lib/mailman-web";
startAt = "hourly"; };
restartTriggers = [ config.environment.etc."mailman3/settings.py".source ]; }));
serviceConfig = { };
ExecStart = "${pkgs.mailman-web}/bin/mailman-web runjobs hourly";
User = cfg.webUser;
WorkingDirectory = "/var/lib/mailman-web";
};
};
systemd.services.hyperkitty-daily = {
inherit (cfg.hyperkitty) enable;
description = "Trigger daily Hyperkitty events";
startAt = "daily";
restartTriggers = [ config.environment.etc."mailman3/settings.py".source ];
serviceConfig = {
ExecStart = "${pkgs.mailman-web}/bin/mailman-web runjobs daily";
User = cfg.webUser;
WorkingDirectory = "/var/lib/mailman-web";
};
};
systemd.services.hyperkitty-weekly = {
inherit (cfg.hyperkitty) enable;
description = "Trigger weekly Hyperkitty events";
startAt = "weekly";
restartTriggers = [ config.environment.etc."mailman3/settings.py".source ];
serviceConfig = {
ExecStart = "${pkgs.mailman-web}/bin/mailman-web runjobs weekly";
User = cfg.webUser;
WorkingDirectory = "/var/lib/mailman-web";
};
};
systemd.services.hyperkitty-yearly = {
inherit (cfg.hyperkitty) enable;
description = "Trigger yearly Hyperkitty events";
startAt = "yearly";
restartTriggers = [ config.environment.etc."mailman3/settings.py".source ];
serviceConfig = {
ExecStart = "${pkgs.mailman-web}/bin/mailman-web runjobs yearly";
User = cfg.webUser;
WorkingDirectory = "/var/lib/mailman-web";
};
};
meta = {
maintainers = with lib.maintainers; [ lheckemann ];
doc = ./mailman.xml;
}; };
} }

View File

@ -0,0 +1,59 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="module-services-mailman">
<title>Mailman</title>
<para>
<link xlink:href="https://www.list.org">Mailman</link> is free
software for managing electronic mail discussion and e-newsletter
lists. Mailman and its web interface can be configured using the
corresponding NixOS module. Note that this service is best used with
an existing, securely configured Postfix setup, as it does not automatically configure this.
</para>
<section xml:id="module-services-mailman-basic-usage">
<title>Basic usage</title>
<para>
For a basic configuration, the following settings are suggested:
<programlisting>{ config, ... }: {
services.postfix = {
enable = true;
relayDomains = ["hash:/var/lib/mailman/data/postfix_domains"];
sslCert = config.security.acme.certs."lists.example.org".directory + "/full.pem";
sslKey = config.security.acme.certs."lists.example.org".directory + "/key.pem";
config = {
transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
local_recipient_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
};
};
services.mailman = {
<link linkend="opt-services.mailman.enable">enable</link> = true;
<link linkend="opt-services.mailman.serve.enable">serve.enable</link> = true;
<link linkend="opt-services.mailman.hyperkitty.enable">hyperkitty.enable</link> = true;
<link linkend="opt-services.mailman.hyperkitty.enable">webHosts</link> = ["lists.example.org"];
<link linkend="opt-services.mailman.hyperkitty.enable">siteOwner</link> = "mailman@example.org";
};
<link linkend="opt-services.nginx.virtualHosts._name_.enableACME">services.nginx.virtualHosts."lists.example.org".enableACME</link> = true;
<link linkend="opt-services.mailman.hyperkitty.enable">networking.firewall.allowedTCPPorts</link> = [ 25 80 443 ];
}</programlisting>
</para>
<para>
DNS records will also be required:
<itemizedlist>
<listitem><para><literal>AAAA</literal> and <literal>A</literal> records pointing to the host in question, in order for browsers to be able to discover the address of the web server;</para></listitem>
<listitem><para>An <literal>MX</literal> record pointing to a domain name at which the host is reachable, in order for other mail servers to be able to deliver emails to the mailing lists it hosts.</para></listitem>
</itemizedlist>
</para>
<para>
After this has been done and appropriate DNS records have been
set up, the Postorius mailing list manager and the Hyperkitty
archive browser will be available at
https://lists.example.org/. Note that this setup is not
sufficient to deliver emails to most email providers nor to
avoid spam -- a number of additional measures for authenticating
incoming and outgoing mails, such as SPF, DMARC and DKIM are
necessary, but outside the scope of the Mailman module.
</para>
</section>
</chapter>

View File

@ -1,4 +1,4 @@
{ stdenv, buildPythonPackage, fetchPypi, isPy3k, alembic, aiosmtpd, dnspython { stdenv, buildPythonPackage, fetchPypi, fetchpatch, isPy3k, alembic, aiosmtpd, dnspython
, flufl_bounce, flufl_i18n, flufl_lock, lazr_config, lazr_delegates, passlib , flufl_bounce, flufl_i18n, flufl_lock, lazr_config, lazr_delegates, passlib
, requests, zope_configuration, click, falcon, importlib-resources , requests, zope_configuration, click, falcon, importlib-resources
, zope_component, lynx, postfix, authheaders, gunicorn , zope_component, lynx, postfix, authheaders, gunicorn
@ -20,7 +20,19 @@ buildPythonPackage rec {
zope_component authheaders gunicorn zope_component authheaders gunicorn
]; ];
patchPhase = '' patches = [
(fetchpatch {
url = https://gitlab.com/mailman/mailman/-/commit/4b206e2a5267a0e17f345fd7b2d957122ba57566.patch;
sha256 = "06axmrn74p81wvcki36c7gfj5fp5q15zxz2yl3lrvijic7hbs4n2";
})
(fetchpatch {
url = https://gitlab.com/mailman/mailman/-/commit/9613154f3c04fa2383fbf017031ef263c291418d.patch;
sha256 = "0vyw87s857vfxbf7kihwb6w094xyxmxbi1bpdqi3ybjamjycp55r";
})
./log-stderr.patch
];
postPatch = ''
substituteInPlace src/mailman/config/postfix.cfg \ substituteInPlace src/mailman/config/postfix.cfg \
--replace /usr/sbin/postmap ${postfix}/bin/postmap --replace /usr/sbin/postmap ${postfix}/bin/postmap
substituteInPlace src/mailman/config/schema.cfg \ substituteInPlace src/mailman/config/schema.cfg \

View File

@ -0,0 +1,13 @@
diff --git a/src/mailman/core/logging.py b/src/mailman/core/logging.py
index f8f87279f..7ff13b003 100644
--- a/src/mailman/core/logging.py
+++ b/src/mailman/core/logging.py
@@ -142,6 +142,8 @@ def _init_logger(propagate, sub_name, log, logger_config):
address, facility = _get_syslog_params(logger_config)
handler = logging.handlers.SysLogHandler(
address=address, facility=facility)
+ elif logger_config.handler == 'stderr':
+ handler = logging.StreamHandler(sys.stderr)
else:
path_str = logger_config.path
path_abs = os.path.normpath(os.path.join(config.LOG_DIR, path_str))

View File

@ -1,6 +1,5 @@
{ buildPythonPackage, lib, fetchgit, isPy3k { buildPythonPackage, lib, fetchgit, isPy3k
, git, makeWrapper, sassc, hyperkitty, postorius, whoosh , git, makeWrapper, sassc, hyperkitty, postorius, whoosh
, django
}: }:
buildPythonPackage rec { buildPythonPackage rec {
@ -17,8 +16,13 @@ buildPythonPackage rec {
# This is just so people installing from pip also get uwsgi # This is just so people installing from pip also get uwsgi
# installed, AFAICT. # installed, AFAICT.
# Django is depended on transitively by hyperkitty and postorius,
# and mailman_web has overly restrictive version bounds on it, so
# let's remove it.
postPatch = '' postPatch = ''
sed -i '/^ uwsgi$/d' setup.cfg sed -i '/^ uwsgi$/d' setup.cfg
sed -i '/^ Django/d' setup.cfg
''; '';
nativeBuildInputs = [ git makeWrapper ]; nativeBuildInputs = [ git makeWrapper ];
@ -36,7 +40,5 @@ buildPythonPackage rec {
description = "Django project for Mailman 3 web interface"; description = "Django project for Mailman 3 web interface";
license = licenses.gpl3; license = licenses.gpl3;
maintainers = with maintainers; [ peti qyliss ]; maintainers = with maintainers; [ peti qyliss ];
# mailman-web requires django < 2.2
broken = versionOlder "2.2" django.version;
}; };
} }

View File

@ -15831,11 +15831,7 @@ in
mailman-rss = callPackage ../development/python-modules/mailman-rss { }; mailman-rss = callPackage ../development/python-modules/mailman-rss { };
mailman-web = with (python3.override { mailman-web = with python3.pkgs; toPythonApplication mailman-web;
packageOverrides = self: super: {
django = self.django_1_11;
};
}).pkgs; toPythonApplication mailman-web;
mattermost = callPackage ../servers/mattermost { }; mattermost = callPackage ../servers/mattermost { };
matterircd = callPackage ../servers/mattermost/matterircd.nix { }; matterircd = callPackage ../servers/mattermost/matterircd.nix { };