mirror of
https://github.com/docker-mailserver/docker-mailserver.git
synced 2024-01-19 02:48:50 +00:00
scripts: improve panic helpers (#3155)
This commit is contained in:
parent
b5fc40eb7a
commit
dab70709d9
|
@ -144,7 +144,7 @@ function _create_dovecot_alias_dummy_accounts
|
||||||
|
|
||||||
if [[ -z ${REAL_ACC[1]} ]]
|
if [[ -z ${REAL_ACC[1]} ]]
|
||||||
then
|
then
|
||||||
dms_panic__misconfigured 'postfix-accounts.cf' 'alias configuration'
|
_dms_panic__misconfigured 'postfix-accounts.cf' 'alias configuration' 'immediate'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# test if user has a defined quota
|
# test if user has a defined quota
|
||||||
|
|
|
@ -29,7 +29,7 @@ function _obtain_hostname_and_domainname
|
||||||
# will result in an error that returns an empty value. This warrants a panic.
|
# will result in an error that returns an empty value. This warrants a panic.
|
||||||
if [[ -z ${HOSTNAME} ]]
|
if [[ -z ${HOSTNAME} ]]
|
||||||
then
|
then
|
||||||
dms_panic__misconfigured 'obtain_hostname' '/etc/hosts'
|
_dms_panic__misconfigured 'obtain_hostname' '/etc/hosts'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If the `HOSTNAME` is more than 2 labels long (eg: mail.example.com),
|
# If the `HOSTNAME` is more than 2 labels long (eg: mail.example.com),
|
||||||
|
|
|
@ -22,9 +22,10 @@ function _exit_with_error
|
||||||
# PANIC_SCOPE => Optionally provide a string for debugging to better identify/locate the source of the panic.
|
# PANIC_SCOPE => Optionally provide a string for debugging to better identify/locate the source of the panic.
|
||||||
function dms_panic
|
function dms_panic
|
||||||
{
|
{
|
||||||
local PANIC_TYPE=${1}
|
local PANIC_TYPE=${1:-}
|
||||||
local PANIC_INFO=${2}
|
local PANIC_INFO=${2:-}
|
||||||
local PANIC_SCOPE=${3} #optional
|
local PANIC_SCOPE=${3-} # optional, must not be :- but just -
|
||||||
|
local PANIC_STRATEGY=${4:-} # optional
|
||||||
|
|
||||||
local SHUTDOWN_MESSAGE
|
local SHUTDOWN_MESSAGE
|
||||||
|
|
||||||
|
@ -49,6 +50,10 @@ function dms_panic
|
||||||
SHUTDOWN_MESSAGE="Invalid value for ${PANIC_INFO}!"
|
SHUTDOWN_MESSAGE="Invalid value for ${PANIC_INFO}!"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
( 'general' )
|
||||||
|
SHUTDOWN_MESSAGE=${PANIC_INFO}
|
||||||
|
;;
|
||||||
|
|
||||||
( * ) # `dms_panic` was called directly without a valid PANIC_TYPE
|
( * ) # `dms_panic` was called directly without a valid PANIC_TYPE
|
||||||
SHUTDOWN_MESSAGE='Something broke :('
|
SHUTDOWN_MESSAGE='Something broke :('
|
||||||
;;
|
;;
|
||||||
|
@ -56,27 +61,38 @@ function dms_panic
|
||||||
|
|
||||||
if [[ -n ${PANIC_SCOPE:-} ]]
|
if [[ -n ${PANIC_SCOPE:-} ]]
|
||||||
then
|
then
|
||||||
_shutdown "${PANIC_SCOPE} | ${SHUTDOWN_MESSAGE}"
|
_shutdown "${PANIC_SCOPE} | ${SHUTDOWN_MESSAGE}" "${PANIC_STRATEGY}"
|
||||||
else
|
else
|
||||||
_shutdown "${SHUTDOWN_MESSAGE}"
|
_shutdown "${SHUTDOWN_MESSAGE}" "${PANIC_STRATEGY}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Convenience wrappers based on type:
|
# Convenience wrappers based on type:
|
||||||
function dms_panic__fail_init { dms_panic 'fail-init' "${1}" "${2}"; }
|
function _dms_panic__fail_init { dms_panic 'fail-init' "${1:-}" "${2:-}" "${3:-}" ; }
|
||||||
function dms_panic__no_env { dms_panic 'no-env' "${1}" "${2}"; }
|
function _dms_panic__no_env { dms_panic 'no-env' "${1:-}" "${2:-}" "${3:-}" ; }
|
||||||
function dms_panic__no_file { dms_panic 'no-file' "${1}" "${2}"; }
|
function _dms_panic__no_file { dms_panic 'no-file' "${1:-}" "${2:-}" "${3:-}" ; }
|
||||||
function dms_panic__misconfigured { dms_panic 'misconfigured' "${1}" "${2}"; }
|
function _dms_panic__misconfigured { dms_panic 'misconfigured' "${1:-}" "${2:-}" "${3:-}" ; }
|
||||||
function dms_panic__invalid_value { dms_panic 'invalid-value' "${1}" "${2}"; }
|
function _dms_panic__invalid_value { dms_panic 'invalid-value' "${1:-}" "${2:-}" "${3:-}" ; }
|
||||||
|
function _dms_panic__general { dms_panic 'general' "${1:-}" "${2:-}" "${3:-}" ; }
|
||||||
|
|
||||||
# Call this method when you want to panic (i.e. emit an 'ERROR' log, and exit uncleanly).
|
# Call this method when you want to panic (i.e. emit an 'ERROR' log, and exit uncleanly).
|
||||||
# `dms_panic` methods should be preferred if your failure type is supported.
|
# `dms_panic` methods should be preferred if your failure type is supported.
|
||||||
function _shutdown
|
function _shutdown
|
||||||
{
|
{
|
||||||
_log 'error' "${1}"
|
_log 'error' "${1:-_shutdown called without message}"
|
||||||
_log 'error' 'Shutting down'
|
_log 'error' 'Shutting down'
|
||||||
|
|
||||||
sleep 1
|
sleep 1
|
||||||
kill 1
|
kill 1
|
||||||
exit 1
|
|
||||||
|
if [[ ${2:-wait} == 'immediate' ]]
|
||||||
|
then
|
||||||
|
# In case the user requested an immediate exit, he ensure he is not in a subshell
|
||||||
|
# call and exiting the whole script is safe. This way, we make the shutdown quicker.
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
# We can simply wait until Supervisord has terminated all processes; this way,
|
||||||
|
# we do not return from a subshell call and continue as if nothing happened.
|
||||||
|
sleep 1000
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,7 +229,7 @@ function _setup_ssl
|
||||||
|
|
||||||
_log 'trace' "SSL configured with 'CA signed/custom' certificates"
|
_log 'trace' "SSL configured with 'CA signed/custom' certificates"
|
||||||
else
|
else
|
||||||
dms_panic__no_file "${TMP_KEY_WITH_FULLCHAIN}" "${SCOPE_SSL_TYPE}"
|
_dms_panic__no_file "${TMP_KEY_WITH_FULLCHAIN}" "${SCOPE_SSL_TYPE}"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ function _setup_ssl
|
||||||
# Fail early:
|
# Fail early:
|
||||||
if [[ -z ${SSL_KEY_PATH} ]] && [[ -z ${SSL_CERT_PATH} ]]
|
if [[ -z ${SSL_KEY_PATH} ]] && [[ -z ${SSL_CERT_PATH} ]]
|
||||||
then
|
then
|
||||||
dms_panic__no_env 'SSL_KEY_PATH or SSL_CERT_PATH' "${SCOPE_SSL_TYPE}"
|
_dms_panic__no_env 'SSL_KEY_PATH or SSL_CERT_PATH' "${SCOPE_SSL_TYPE}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n ${SSL_ALT_KEY_PATH} ]] \
|
if [[ -n ${SSL_ALT_KEY_PATH} ]] \
|
||||||
|
@ -251,7 +251,7 @@ function _setup_ssl
|
||||||
&& [[ ! -f ${SSL_ALT_KEY_PATH} ]] \
|
&& [[ ! -f ${SSL_ALT_KEY_PATH} ]] \
|
||||||
&& [[ ! -f ${SSL_ALT_CERT_PATH} ]]
|
&& [[ ! -f ${SSL_ALT_CERT_PATH} ]]
|
||||||
then
|
then
|
||||||
dms_panic__no_file "(ALT) ${SSL_ALT_KEY_PATH} or ${SSL_ALT_CERT_PATH}" "${SCOPE_SSL_TYPE}"
|
_dms_panic__no_file "(ALT) ${SSL_ALT_KEY_PATH} or ${SSL_ALT_CERT_PATH}" "${SCOPE_SSL_TYPE}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -f ${SSL_KEY_PATH} ]] && [[ -f ${SSL_CERT_PATH} ]]
|
if [[ -f ${SSL_KEY_PATH} ]] && [[ -f ${SSL_CERT_PATH} ]]
|
||||||
|
@ -280,7 +280,7 @@ function _setup_ssl
|
||||||
|
|
||||||
_log 'trace' "SSL configured with 'Manual' certificates"
|
_log 'trace' "SSL configured with 'Manual' certificates"
|
||||||
else
|
else
|
||||||
dms_panic__no_file "${SSL_KEY_PATH} or ${SSL_CERT_PATH}" "${SCOPE_SSL_TYPE}"
|
_dms_panic__no_file "${SSL_KEY_PATH} or ${SSL_CERT_PATH}" "${SCOPE_SSL_TYPE}"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
@ -325,7 +325,7 @@ function _setup_ssl
|
||||||
|
|
||||||
_log 'trace' "SSL configured with 'self-signed' certificates"
|
_log 'trace' "SSL configured with 'self-signed' certificates"
|
||||||
else
|
else
|
||||||
dms_panic__no_file "${SS_KEY} or ${SS_CERT}" "${SCOPE_SSL_TYPE}"
|
_dms_panic__no_file "${SS_KEY} or ${SS_CERT}" "${SCOPE_SSL_TYPE}"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
@ -381,7 +381,7 @@ function _setup_ssl
|
||||||
;;
|
;;
|
||||||
|
|
||||||
( * ) # Unknown option, panic.
|
( * ) # Unknown option, panic.
|
||||||
dms_panic__invalid_value 'SSL_TYPE' "${SCOPE_TLS_LEVEL}"
|
_dms_panic__invalid_value 'SSL_TYPE' "${SCOPE_TLS_LEVEL}"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
esac
|
esac
|
||||||
|
@ -404,7 +404,7 @@ function _find_letsencrypt_domain
|
||||||
LETSENCRYPT_DOMAIN=${DOMAINNAME}
|
LETSENCRYPT_DOMAIN=${DOMAINNAME}
|
||||||
else
|
else
|
||||||
_log 'error' "Cannot find a valid DOMAIN for '/etc/letsencrypt/live/<DOMAIN>/', tried: '${SSL_DOMAIN}', '${HOSTNAME}', '${DOMAINNAME}'"
|
_log 'error' "Cannot find a valid DOMAIN for '/etc/letsencrypt/live/<DOMAIN>/', tried: '${SSL_DOMAIN}', '${HOSTNAME}', '${DOMAINNAME}'"
|
||||||
dms_panic__misconfigured 'LETSENCRYPT_DOMAIN' '_find_letsencrypt_domain'
|
_dms_panic__misconfigured 'LETSENCRYPT_DOMAIN' '_find_letsencrypt_domain'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "${LETSENCRYPT_DOMAIN}"
|
echo "${LETSENCRYPT_DOMAIN}"
|
||||||
|
@ -418,7 +418,7 @@ function _find_letsencrypt_key
|
||||||
local LETSENCRYPT_DOMAIN=${1}
|
local LETSENCRYPT_DOMAIN=${1}
|
||||||
if [[ -z ${LETSENCRYPT_DOMAIN} ]]
|
if [[ -z ${LETSENCRYPT_DOMAIN} ]]
|
||||||
then
|
then
|
||||||
dms_panic__misconfigured 'LETSENCRYPT_DOMAIN' '_find_letsencrypt_key'
|
_dms_panic__misconfigured 'LETSENCRYPT_DOMAIN' '_find_letsencrypt_key'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -e /etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/privkey.pem ]]
|
if [[ -e /etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/privkey.pem ]]
|
||||||
|
@ -429,7 +429,7 @@ function _find_letsencrypt_key
|
||||||
LETSENCRYPT_KEY='key'
|
LETSENCRYPT_KEY='key'
|
||||||
else
|
else
|
||||||
_log 'error' "Cannot find key file ('privkey.pem' or 'key.pem') in '/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/'"
|
_log 'error' "Cannot find key file ('privkey.pem' or 'key.pem') in '/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN}/'"
|
||||||
dms_panic__misconfigured 'LETSENCRYPT_KEY' '_find_letsencrypt_key'
|
_dms_panic__misconfigured 'LETSENCRYPT_KEY' '_find_letsencrypt_key'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "${LETSENCRYPT_KEY}"
|
echo "${LETSENCRYPT_KEY}"
|
||||||
|
|
|
@ -92,13 +92,13 @@ function _replace_by_env_in_file
|
||||||
{
|
{
|
||||||
if [[ -z ${1+set} ]]
|
if [[ -z ${1+set} ]]
|
||||||
then
|
then
|
||||||
dms_panic__invalid_value 'first argument unset' 'utils.sh:_replace_by_env_in_file'
|
_dms_panic__invalid_value 'first argument unset' 'utils.sh:_replace_by_env_in_file' 'immediate'
|
||||||
elif [[ -z ${2+set} ]]
|
elif [[ -z ${2+set} ]]
|
||||||
then
|
then
|
||||||
dms_panic__invalid_value 'second argument unset' 'utils.sh:_replace_by_env_in_file'
|
_dms_panic__invalid_value 'second argument unset' 'utils.sh:_replace_by_env_in_file' 'immediate'
|
||||||
elif [[ ! -f ${2} ]]
|
elif [[ ! -f ${2} ]]
|
||||||
then
|
then
|
||||||
dms_panic__invalid_value "file '${2}' does not exist" 'utils.sh:_replace_by_env_in_file'
|
_dms_panic__invalid_value "file '${2}' does not exist" 'utils.sh:_replace_by_env_in_file' 'immediate'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local ENV_PREFIX=${1} CONFIG_FILE=${2}
|
local ENV_PREFIX=${1} CONFIG_FILE=${2}
|
||||||
|
|
|
@ -60,11 +60,11 @@ function _register_functions
|
||||||
;;
|
;;
|
||||||
|
|
||||||
( 'OIDC' )
|
( 'OIDC' )
|
||||||
_shutdown 'OIDC user account provisioning is not yet implemented'
|
_dms_panic__fail_init 'OIDC user account provisioning - it is not yet implemented' '' 'immediate'
|
||||||
;;
|
;;
|
||||||
|
|
||||||
( * )
|
( * )
|
||||||
_shutdown "'${ACCOUNT_PROVISIONER}' is not a valid value for ACCOUNT_PROVISIONER"
|
_dms_panic__invalid_value "'${ACCOUNT_PROVISIONER}' is not a valid value for ACCOUNT_PROVISIONER" '' 'immediate'
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ function _check_hostname
|
||||||
# HOSTNAME should be an FQDN (eg: hostname.domain)
|
# HOSTNAME should be an FQDN (eg: hostname.domain)
|
||||||
if ! grep -q -E '^(\S+[.]\S+)$' <<< "${HOSTNAME}"
|
if ! grep -q -E '^(\S+[.]\S+)$' <<< "${HOSTNAME}"
|
||||||
then
|
then
|
||||||
_shutdown 'Setting hostname/domainname is required'
|
_dms_panic__general 'Setting hostname/domainname is required' '' 'immediate'
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ function _default_start_daemon
|
||||||
if [[ ${?} -ne 0 ]]
|
if [[ ${?} -ne 0 ]]
|
||||||
then
|
then
|
||||||
_log 'error' "${RESULT}"
|
_log 'error' "${RESULT}"
|
||||||
dms_panic__fail_init "${1}"
|
_dms_panic__fail_init "${1}" '' 'immediate'
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,10 @@ function _setup_apply_fixes_after_configuration
|
||||||
touch /dev/shm/supervisor.sock
|
touch /dev/shm/supervisor.sock
|
||||||
|
|
||||||
_log 'debug' 'Checking /var/mail permissions'
|
_log 'debug' 'Checking /var/mail permissions'
|
||||||
_chown_var_mail_if_necessary || _shutdown 'Failed to fix /var/mail permissions'
|
if ! _chown_var_mail_if_necessary
|
||||||
|
then
|
||||||
|
_dms_panic__general 'Failed to fix /var/mail permissions' '' 'immediate'
|
||||||
|
fi
|
||||||
|
|
||||||
_log 'debug' 'Removing files and directories from older versions'
|
_log 'debug' 'Removing files and directories from older versions'
|
||||||
rm -rf /var/mail-state/spool-postfix/{dev,etc,lib,pid,usr,private/auth}
|
rm -rf /var/mail-state/spool-postfix/{dev,etc,lib,pid,usr,private/auth}
|
||||||
|
|
|
@ -182,7 +182,7 @@ function _setup_dovecot_local_user
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
_shutdown 'No accounts provided - Dovecot could not be started'
|
_dms_panic__fail_init 'accounts provisioning because no accounts were provided - Dovecot could not be started' '' 'immediate'
|
||||||
}
|
}
|
||||||
|
|
||||||
__wait_until_an_account_is_added_or_shutdown
|
__wait_until_an_account_is_added_or_shutdown
|
||||||
|
@ -206,7 +206,7 @@ function _setup_dovecot_inet_protocols
|
||||||
PROTOCOL='[::]' # IPv6 only
|
PROTOCOL='[::]' # IPv6 only
|
||||||
else
|
else
|
||||||
# Unknown value, panic.
|
# Unknown value, panic.
|
||||||
dms_panic__invalid_value 'DOVECOT_INET_PROTOCOLS' "${DOVECOT_INET_PROTOCOLS}"
|
_dms_panic__invalid_value 'DOVECOT_INET_PROTOCOLS' "${DOVECOT_INET_PROTOCOLS}" 'immediate'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sedfile -i "s|^#listen =.*|listen = ${PROTOCOL}|g" /etc/dovecot/dovecot.conf
|
sedfile -i "s|^#listen =.*|listen = ${PROTOCOL}|g" /etc/dovecot/dovecot.conf
|
||||||
|
|
|
@ -22,7 +22,7 @@ function _setup_docker_permit
|
||||||
if [[ -z ${CONTAINER_IP} ]]
|
if [[ -z ${CONTAINER_IP} ]]
|
||||||
then
|
then
|
||||||
_log 'error' 'Detecting the container IP address failed'
|
_log 'error' 'Detecting the container IP address failed'
|
||||||
dms_panic__misconfigured 'NETWORK_INTERFACE' 'Network Setup [docker_permit]'
|
_dms_panic__misconfigured 'NETWORK_INTERFACE' 'Network Setup [docker_permit]' 'immediate'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while read -r IP
|
while read -r IP
|
||||||
|
|
Loading…
Reference in a new issue