forked from ISTI-ansible-roles/ansible-role-mailman
Fix the configuration template and the restart script.
This commit is contained in:
parent
ef104e06c4
commit
e0bf89d83d
14
README.md
14
README.md
|
|
@ -28,12 +28,14 @@ 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 both systemd and `mailman status` to confirm that Mailman has stopped
|
||||
before starting it, then checks both signals again to confirm startup:
|
||||
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
|
||||
```
|
||||
|
|
@ -41,3 +43,11 @@ 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.
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ mailman_enable_daily_notifications: true
|
|||
# default and, when enabled, uses the managed host's local timezone.
|
||||
mailman_enable_weekly_verified_restart: false
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,15 @@
|
|||
service: name=mailman state=restarted
|
||||
when: mailman_hyperkitty_install is changed
|
||||
|
||||
- name: Wait for the Mailman LMTP listener
|
||||
ansible.builtin.wait_for:
|
||||
host: '{{ mailman_lmtp_host }}'
|
||||
port: '{{ mailman_lmtp_port }}'
|
||||
state: started
|
||||
sleep: 1
|
||||
timeout: '{{ mailman_weekly_verified_restart_start_timeout }}'
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Install the mailman and mailmansuite logrotate configurations
|
||||
template: src={{ item }}-logrotate.j2 dest=/etc/logrotate.d/{{ item }} owner=root mode=0444
|
||||
with_items:
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@ Wants=network-online.target
|
|||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/sbin/mailman-verified-restart
|
||||
TimeoutStartSec={{ (mailman_weekly_verified_restart_stop_timeout | int) + (mailman_weekly_verified_restart_start_timeout | int) + 30 }}
|
||||
TimeoutStartSec={{ (mailman_service_stop_timeout | int) + (mailman_weekly_verified_restart_stop_timeout | int) + (mailman_weekly_verified_restart_start_timeout | int) + 30 }}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ set -uo pipefail
|
|||
readonly SERVICE='mailman.service'
|
||||
readonly MAILMAN='{{ mailman_bindir }}/mailman'
|
||||
readonly CONFIG='{{ mailman_conf_dir }}/mailman.cfg'
|
||||
readonly LMTP_PORT={{ mailman_lmtp_port | int }}
|
||||
readonly SYSTEMD_STOP_TIMEOUT={{ mailman_service_stop_timeout | int }}
|
||||
readonly STOP_TIMEOUT={{ mailman_weekly_verified_restart_stop_timeout | int }}
|
||||
readonly START_TIMEOUT={{ mailman_weekly_verified_restart_start_timeout | int }}
|
||||
|
||||
|
|
@ -13,16 +15,40 @@ log()
|
|||
printf 'mailman-verified-restart: %s\n' "$*"
|
||||
}
|
||||
|
||||
lmtp_is_listening()
|
||||
{
|
||||
local sockets
|
||||
local suffix=":${LMTP_PORT}"
|
||||
|
||||
if ! sockets="$(ss -H -ltn)"; then
|
||||
return 2
|
||||
fi
|
||||
|
||||
awk -v suffix="${suffix}" '
|
||||
substr($4, length($4) - length(suffix) + 1) == suffix {
|
||||
found = 1
|
||||
}
|
||||
END { exit !found }
|
||||
' <<< "${sockets}"
|
||||
}
|
||||
|
||||
mailman_is_stopped()
|
||||
{
|
||||
! systemctl is-active --quiet "${SERVICE}" &&
|
||||
local listener_status
|
||||
|
||||
lmtp_is_listening
|
||||
listener_status=$?
|
||||
|
||||
[[ ${listener_status} -eq 1 ]] &&
|
||||
! systemctl is-active --quiet "${SERVICE}" &&
|
||||
! "${MAILMAN}" -C "${CONFIG}" status >/dev/null 2>&1
|
||||
}
|
||||
|
||||
mailman_is_started()
|
||||
{
|
||||
systemctl is-active --quiet "${SERVICE}" &&
|
||||
"${MAILMAN}" -C "${CONFIG}" status >/dev/null 2>&1
|
||||
"${MAILMAN}" -C "${CONFIG}" status >/dev/null 2>&1 &&
|
||||
lmtp_is_listening
|
||||
}
|
||||
|
||||
wait_for_state()
|
||||
|
|
@ -41,9 +67,8 @@ wait_for_state()
|
|||
}
|
||||
|
||||
log 'stopping Mailman'
|
||||
if ! systemctl stop "${SERVICE}"; then
|
||||
log 'ERROR: systemctl could not stop Mailman'
|
||||
exit 1
|
||||
if ! timeout "$((SYSTEMD_STOP_TIMEOUT + 10))" systemctl stop "${SERVICE}"; then
|
||||
log 'WARNING: systemctl stop did not complete successfully; verifying the actual state'
|
||||
fi
|
||||
|
||||
if ! wait_for_state mailman_is_stopped "${STOP_TIMEOUT}"; then
|
||||
|
|
@ -65,4 +90,4 @@ if ! wait_for_state mailman_is_started "${START_TIMEOUT}"; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
log 'Mailman is active and its master process is running'
|
||||
log "Mailman is active, its master is running and LMTP port ${LMTP_PORT} is listening"
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ header_checks:
|
|||
# The chain to jump to if any of the header patterns matches. This must be
|
||||
# the name of an existing chain such as 'discard', 'reject', 'hold', or
|
||||
# 'accept', otherwise 'hold' will be used.
|
||||
jump_chain: "{{ mailman_antispam_chain_behaviour }}"
|
||||
jump_chain: {{ mailman_antispam_chain_behaviour }}
|
||||
|
||||
[runner.nntp]
|
||||
class: mailman.runners.nntp.NNTPRunner
|
||||
|
|
@ -253,4 +253,4 @@ start: {{ mailman_start_nntp_runner }}
|
|||
class: mailman_hyperkitty.Archiver
|
||||
enable: yes
|
||||
configuration: {{ mailman_conf_dir }}/mailman-hyperkitty.cfg
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ Environment=PATH={{ mailman_bindir }}
|
|||
ExecStart={{ mailman_bindir }}/mailman -C {{ mailman_conf_dir }}/mailman.cfg start
|
||||
ExecReload={{ mailman_bindir }}/mailman -C {{ mailman_conf_dir }}/mailman.cfg restart
|
||||
ExecStop={{ mailman_bindir }}/mailman -C {{ mailman_conf_dir }}/mailman.cfg stop
|
||||
ExecStopPost=/bin/rm -f {{ mailman_var_dir }}/master.pid
|
||||
Type=forking
|
||||
PIDFile={{ mailman_var_dir }}/master.pid
|
||||
SyslogIdentifier=mailman
|
||||
|
|
@ -17,6 +18,9 @@ User={{ mailman_user }}
|
|||
Group={{ mailman_user }}
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
TimeoutStopSec={{ mailman_service_stop_timeout }}s
|
||||
KillMode=control-group
|
||||
SendSIGKILL=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
|
|||
Loading…
Reference in New Issue