forked from ISTI-ansible-roles/ansible-role-mailman
84 lines
3.6 KiB
Markdown
84 lines
3.6 KiB
Markdown
# mailman
|
|
|
|
The site-wide antispam defaults are deliberately empty:
|
|
|
|
```yaml
|
|
mailman_antispam_header_checks: []
|
|
mailman_antispam_chain_behaviour: discard
|
|
```
|
|
|
|
Mailing-list owners can manage list-specific header matches and select their
|
|
action (`accept`, `discard`, `hold`, or `reject`) from Postorius. The global
|
|
chain is used only when a matching rule has no explicit action.
|
|
|
|
Existing lists without any header matches can be initialized through the
|
|
Mailman database model by enabling the optional seed operation:
|
|
|
|
```yaml
|
|
mailman_seed_empty_list_header_matches: true
|
|
mailman_empty_list_header_matches:
|
|
- header: 'X-Spam-Flag'
|
|
pattern: '^YES$'
|
|
action: 'discard'
|
|
```
|
|
|
|
The operation is idempotent. A list is modified only when its header-match
|
|
collection is empty; lists with one or more existing rules are left untouched.
|
|
|
|
## Verified weekly restart
|
|
|
|
The optional weekly restart performs separate stop and start operations. It
|
|
waits for systemd, `mailman status`, and the configured LMTP listener to confirm
|
|
that Mailman has stopped before starting it. It then requires the master and
|
|
the LMTP port to become available before considering startup successful:
|
|
|
|
```yaml
|
|
mailman_enable_weekly_verified_restart: true
|
|
mailman_weekly_verified_restart_on_calendar: 'Sun *-*-* 04:00:00'
|
|
mailman_service_stop_timeout: 30
|
|
mailman_weekly_verified_restart_stop_timeout: 120
|
|
mailman_weekly_verified_restart_start_timeout: 120
|
|
```
|
|
|
|
The timer is deliberately not persistent, so a missed run is not executed
|
|
immediately after a server boot. Failures are recorded by systemd in the
|
|
`mailman-verified-restart.service` journal.
|
|
|
|
The managed `mailman.service` uses `KillMode=control-group` and an explicit
|
|
`TimeoutStopSec`. If Mailman's own stop command hangs, systemd terminates the
|
|
whole service cgroup and removes a stale master PID file. The weekly job still
|
|
verifies the real stopped state and does not start a second instance until the
|
|
master and LMTP listener are gone.
|
|
The normal role execution also waits for the configured LMTP port and fails if
|
|
the listener does not become available after starting or restarting Mailman.
|
|
|
|
## Legacy HyperKitty compatibility fixes
|
|
|
|
The optional compatibility patcher addresses three failures observed with the
|
|
legacy Python 3.6 web stack: malformed `From`/`Subject` headers, nested
|
|
`message/rfc822` parts without `Content-Transfer-Encoding`, and unreadable
|
|
gettext catalogs. It also normalizes non-ASCII sender addresses and backports
|
|
the byte-oriented delivery used by newer `mailman-hyperkitty` releases, so
|
|
surrogate-escaped message bytes do not pass through Requests as Unicode text.
|
|
Enable it only for the known package versions:
|
|
|
|
```yaml
|
|
mailman_enable_legacy_hyperkitty_compatibility_patches: true
|
|
mailman_legacy_hyperkitty_version: '1.3.3'
|
|
mailman_legacy_django_mailman3_version: '1.3.4'
|
|
mailman_legacy_mailman_hyperkitty_version: '1.1.0'
|
|
```
|
|
|
|
The Python source patches are idempotent, compiled before any file is replaced,
|
|
and installed atomically. The task fails without changing any source file if
|
|
the installed versions or expected source fragments do not match. Invalid
|
|
`django_extensions` `.mo` files are preserved beside the original name with a
|
|
`.disabled-by-ansible` suffix, allowing Django to fall back to another locale.
|
|
The uWSGI and Mailman services are restarted only when a source file or catalog
|
|
actually changes. After restarting Mailman, the handler requires the configured
|
|
LMTP listener to become available.
|
|
|
|
Disable this option before upgrading HyperKitty, django-mailman3, or
|
|
mailman-hyperkitty, then review whether the compatibility patches are still
|
|
needed with the new versions.
|