mailman/templates/mailman-verified-restart.sh.j2

94 lines
2.3 KiB
Django/Jinja

#!/bin/bash
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 }}
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()
{
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 &&
lmtp_is_listening
}
wait_for_state()
{
local check_function="$1"
local timeout="$2"
local deadline=$((SECONDS + timeout))
while (( SECONDS < deadline )); do
if "${check_function}"; then
return 0
fi
sleep 1
done
"${check_function}"
}
log 'stopping Mailman'
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
log 'ERROR: Mailman did not stop completely within the timeout; start skipped'
exit 1
fi
log 'Mailman is completely stopped'
systemctl reset-failed "${SERVICE}" >/dev/null 2>&1 || true
log 'starting Mailman'
if ! systemctl start "${SERVICE}"; then
log 'ERROR: systemctl could not start Mailman'
exit 1
fi
if ! wait_for_state mailman_is_started "${START_TIMEOUT}"; then
log 'ERROR: Mailman did not become active within the timeout'
exit 1
fi
log "Mailman is active, its master is running and LMTP port ${LMTP_PORT} is listening"