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
|
## Verified weekly restart
|
||||||
|
|
||||||
The optional weekly restart performs separate stop and start operations. It
|
The optional weekly restart performs separate stop and start operations. It
|
||||||
waits for both systemd and `mailman status` to confirm that Mailman has stopped
|
waits for systemd, `mailman status`, and the configured LMTP listener to confirm
|
||||||
before starting it, then checks both signals again to confirm startup:
|
that Mailman has stopped before starting it. It then requires the master and
|
||||||
|
the LMTP port to become available before considering startup successful:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
mailman_enable_weekly_verified_restart: true
|
mailman_enable_weekly_verified_restart: true
|
||||||
mailman_weekly_verified_restart_on_calendar: 'Sun *-*-* 04:00:00'
|
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_stop_timeout: 120
|
||||||
mailman_weekly_verified_restart_start_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
|
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
|
immediately after a server boot. Failures are recorded by systemd in the
|
||||||
`mailman-verified-restart.service` journal.
|
`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.
|
# default and, when enabled, uses the managed host's local timezone.
|
||||||
mailman_enable_weekly_verified_restart: false
|
mailman_enable_weekly_verified_restart: false
|
||||||
mailman_weekly_verified_restart_on_calendar: 'Sun *-*-* 04:00:00'
|
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_stop_timeout: 120
|
||||||
mailman_weekly_verified_restart_start_timeout: 120
|
mailman_weekly_verified_restart_start_timeout: 120
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,15 @@
|
||||||
service: name=mailman state=restarted
|
service: name=mailman state=restarted
|
||||||
when: mailman_hyperkitty_install is changed
|
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
|
- name: Install the mailman and mailmansuite logrotate configurations
|
||||||
template: src={{ item }}-logrotate.j2 dest=/etc/logrotate.d/{{ item }} owner=root mode=0444
|
template: src={{ item }}-logrotate.j2 dest=/etc/logrotate.d/{{ item }} owner=root mode=0444
|
||||||
with_items:
|
with_items:
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,4 @@ Wants=network-online.target
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
ExecStart=/usr/local/sbin/mailman-verified-restart
|
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 SERVICE='mailman.service'
|
||||||
readonly MAILMAN='{{ mailman_bindir }}/mailman'
|
readonly MAILMAN='{{ mailman_bindir }}/mailman'
|
||||||
readonly CONFIG='{{ mailman_conf_dir }}/mailman.cfg'
|
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 STOP_TIMEOUT={{ mailman_weekly_verified_restart_stop_timeout | int }}
|
||||||
readonly START_TIMEOUT={{ mailman_weekly_verified_restart_start_timeout | int }}
|
readonly START_TIMEOUT={{ mailman_weekly_verified_restart_start_timeout | int }}
|
||||||
|
|
||||||
|
|
@ -13,16 +15,40 @@ log()
|
||||||
printf 'mailman-verified-restart: %s\n' "$*"
|
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()
|
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}" -C "${CONFIG}" status >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
mailman_is_started()
|
mailman_is_started()
|
||||||
{
|
{
|
||||||
systemctl is-active --quiet "${SERVICE}" &&
|
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()
|
wait_for_state()
|
||||||
|
|
@ -41,9 +67,8 @@ wait_for_state()
|
||||||
}
|
}
|
||||||
|
|
||||||
log 'stopping Mailman'
|
log 'stopping Mailman'
|
||||||
if ! systemctl stop "${SERVICE}"; then
|
if ! timeout "$((SYSTEMD_STOP_TIMEOUT + 10))" systemctl stop "${SERVICE}"; then
|
||||||
log 'ERROR: systemctl could not stop Mailman'
|
log 'WARNING: systemctl stop did not complete successfully; verifying the actual state'
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! wait_for_state mailman_is_stopped "${STOP_TIMEOUT}"; then
|
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
|
exit 1
|
||||||
fi
|
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 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
|
# the name of an existing chain such as 'discard', 'reject', 'hold', or
|
||||||
# 'accept', otherwise 'hold' will be used.
|
# 'accept', otherwise 'hold' will be used.
|
||||||
jump_chain: "{{ mailman_antispam_chain_behaviour }}"
|
jump_chain: {{ mailman_antispam_chain_behaviour }}
|
||||||
|
|
||||||
[runner.nntp]
|
[runner.nntp]
|
||||||
class: mailman.runners.nntp.NNTPRunner
|
class: mailman.runners.nntp.NNTPRunner
|
||||||
|
|
@ -253,4 +253,4 @@ start: {{ mailman_start_nntp_runner }}
|
||||||
class: mailman_hyperkitty.Archiver
|
class: mailman_hyperkitty.Archiver
|
||||||
enable: yes
|
enable: yes
|
||||||
configuration: {{ mailman_conf_dir }}/mailman-hyperkitty.cfg
|
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
|
ExecStart={{ mailman_bindir }}/mailman -C {{ mailman_conf_dir }}/mailman.cfg start
|
||||||
ExecReload={{ mailman_bindir }}/mailman -C {{ mailman_conf_dir }}/mailman.cfg restart
|
ExecReload={{ mailman_bindir }}/mailman -C {{ mailman_conf_dir }}/mailman.cfg restart
|
||||||
ExecStop={{ mailman_bindir }}/mailman -C {{ mailman_conf_dir }}/mailman.cfg stop
|
ExecStop={{ mailman_bindir }}/mailman -C {{ mailman_conf_dir }}/mailman.cfg stop
|
||||||
|
ExecStopPost=/bin/rm -f {{ mailman_var_dir }}/master.pid
|
||||||
Type=forking
|
Type=forking
|
||||||
PIDFile={{ mailman_var_dir }}/master.pid
|
PIDFile={{ mailman_var_dir }}/master.pid
|
||||||
SyslogIdentifier=mailman
|
SyslogIdentifier=mailman
|
||||||
|
|
@ -17,6 +18,9 @@ User={{ mailman_user }}
|
||||||
Group={{ mailman_user }}
|
Group={{ mailman_user }}
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=5s
|
RestartSec=5s
|
||||||
|
TimeoutStopSec={{ mailman_service_stop_timeout }}s
|
||||||
|
KillMode=control-group
|
||||||
|
SendSIGKILL=yes
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue