2022-10-17 08:40:09 +00:00
|
|
|
#!/bin/bash
|
2022-02-21 10:56:57 +00:00
|
|
|
|
2022-03-21 14:01:07 +00:00
|
|
|
function _exit_with_error
|
2022-02-21 10:56:57 +00:00
|
|
|
{
|
2022-03-21 06:07:52 +00:00
|
|
|
if [[ -n ${1+set} ]]
|
|
|
|
then
|
|
|
|
_log 'error' "${1}"
|
|
|
|
else
|
2022-03-21 14:01:07 +00:00
|
|
|
_log 'error' "Call to '_exit_with_error' is missing a message to log"
|
2022-03-21 06:07:52 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
_log 'error' 'Aborting'
|
2022-04-19 19:09:25 +00:00
|
|
|
exit "${2:-1}"
|
2022-02-21 10:56:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# `dms_panic` methods are appropriate when the type of error is a not recoverable,
|
|
|
|
# or needs to be very clear to the user about misconfiguration.
|
|
|
|
#
|
|
|
|
# Method is called with args:
|
|
|
|
# PANIC_TYPE => (Internal value for matching). You should use the convenience methods below based on your panic type.
|
|
|
|
# PANIC_INFO => Provide your own message string to insert into the error message for that PANIC_TYPE.
|
|
|
|
# PANIC_SCOPE => Optionally provide a string for debugging to better identify/locate the source of the panic.
|
|
|
|
function dms_panic
|
|
|
|
{
|
2023-03-06 09:06:50 +00:00
|
|
|
local PANIC_TYPE=${1:-}
|
|
|
|
local PANIC_INFO=${2:-}
|
2023-04-18 21:38:46 +00:00
|
|
|
local PANIC_SCOPE=${3:-}
|
2022-02-21 10:56:57 +00:00
|
|
|
|
|
|
|
local SHUTDOWN_MESSAGE
|
|
|
|
|
|
|
|
case "${PANIC_TYPE:-}" in
|
|
|
|
( 'fail-init' ) # PANIC_INFO == <name of service or process that failed to start / initialize>
|
|
|
|
SHUTDOWN_MESSAGE="Failed to start ${PANIC_INFO}!"
|
|
|
|
;;
|
|
|
|
|
|
|
|
( 'no-env' ) # PANIC_INFO == <ENV VAR name>
|
|
|
|
SHUTDOWN_MESSAGE="Environment Variable: ${PANIC_INFO} is not set!"
|
|
|
|
;;
|
|
|
|
|
|
|
|
( 'no-file' ) # PANIC_INFO == <invalid filepath>
|
|
|
|
SHUTDOWN_MESSAGE="File ${PANIC_INFO} does not exist!"
|
|
|
|
;;
|
|
|
|
|
|
|
|
( 'misconfigured' ) # PANIC_INFO == <something possibly misconfigured, eg an ENV var>
|
|
|
|
SHUTDOWN_MESSAGE="${PANIC_INFO} appears to be misconfigured, please verify."
|
|
|
|
;;
|
|
|
|
|
|
|
|
( 'invalid-value' ) # PANIC_INFO == <an unsupported or invalid value, eg in a case match>
|
|
|
|
SHUTDOWN_MESSAGE="Invalid value for ${PANIC_INFO}!"
|
|
|
|
;;
|
|
|
|
|
2023-03-06 09:06:50 +00:00
|
|
|
( 'general' )
|
|
|
|
SHUTDOWN_MESSAGE=${PANIC_INFO}
|
|
|
|
;;
|
|
|
|
|
2022-02-21 10:56:57 +00:00
|
|
|
( * ) # `dms_panic` was called directly without a valid PANIC_TYPE
|
|
|
|
SHUTDOWN_MESSAGE='Something broke :('
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
if [[ -n ${PANIC_SCOPE:-} ]]
|
|
|
|
then
|
2023-04-18 21:38:46 +00:00
|
|
|
_shutdown "${PANIC_SCOPE} | ${SHUTDOWN_MESSAGE}"
|
2022-02-21 10:56:57 +00:00
|
|
|
else
|
2023-04-18 21:38:46 +00:00
|
|
|
_shutdown "${SHUTDOWN_MESSAGE}"
|
2022-02-21 10:56:57 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# Convenience wrappers based on type:
|
2023-03-06 09:06:50 +00:00
|
|
|
function _dms_panic__fail_init { dms_panic 'fail-init' "${1:-}" "${2:-}" "${3:-}" ; }
|
|
|
|
function _dms_panic__no_env { dms_panic 'no-env' "${1:-}" "${2:-}" "${3:-}" ; }
|
|
|
|
function _dms_panic__no_file { dms_panic 'no-file' "${1:-}" "${2:-}" "${3:-}" ; }
|
|
|
|
function _dms_panic__misconfigured { dms_panic 'misconfigured' "${1:-}" "${2:-}" "${3:-}" ; }
|
|
|
|
function _dms_panic__invalid_value { dms_panic 'invalid-value' "${1:-}" "${2:-}" "${3:-}" ; }
|
|
|
|
function _dms_panic__general { dms_panic 'general' "${1:-}" "${2:-}" "${3:-}" ; }
|
2022-02-21 10:56:57 +00:00
|
|
|
|
2022-03-21 06:07:52 +00:00
|
|
|
# Call this method when you want to panic (i.e. emit an 'ERROR' log, and exit uncleanly).
|
2022-02-21 10:56:57 +00:00
|
|
|
# `dms_panic` methods should be preferred if your failure type is supported.
|
2023-04-18 21:38:46 +00:00
|
|
|
trap "exit 1" SIGUSR1
|
|
|
|
SCRIPT_PID=${$}
|
2022-02-21 10:56:57 +00:00
|
|
|
function _shutdown
|
|
|
|
{
|
2023-03-06 09:06:50 +00:00
|
|
|
_log 'error' "${1:-_shutdown called without message}"
|
2022-03-21 06:07:52 +00:00
|
|
|
_log 'error' 'Shutting down'
|
2022-02-21 10:56:57 +00:00
|
|
|
|
2022-03-26 09:17:08 +00:00
|
|
|
sleep 1
|
2023-04-18 21:38:46 +00:00
|
|
|
kill -SIGTERM 1 # Trigger graceful DMS shutdown.
|
|
|
|
kill -SIGUSR1 "${SCRIPT_PID}" # Stop start-mailserver.sh execution, even when _shutdown() is called from a subshell.
|
2022-02-21 10:56:57 +00:00
|
|
|
}
|
2023-04-24 12:35:19 +00:00
|
|
|
|
|
|
|
# Calling this function sets up a handler for the `ERR` signal, that occurs when
|
|
|
|
# an error is not properly checked (e.g., in an `if`-clause or in an `&&` block).
|
|
|
|
#
|
|
|
|
# This is mostly useful for debugging. It also helps when using something like `set -eE`,
|
|
|
|
# as it shows where the script aborts.
|
|
|
|
function _trap_err_signal
|
|
|
|
{
|
|
|
|
trap '__log_unexpected_error "${FUNCNAME[0]:-}" "${BASH_COMMAND:-}" "${LINENO:-}" "${?:-}"' ERR
|
|
|
|
|
|
|
|
# shellcheck disable=SC2317
|
|
|
|
function __log_unexpected_error
|
|
|
|
{
|
|
|
|
local MESSAGE="Unexpected error occured :: script = ${SCRIPT:-${0}} "
|
|
|
|
MESSAGE+=" | function = ${1:-none (global)}"
|
|
|
|
MESSAGE+=" | command = ${2:-?}"
|
|
|
|
MESSAGE+=" | line = ${3:-?}"
|
|
|
|
MESSAGE+=" | exit code = ${4:-?}"
|
|
|
|
|
|
|
|
_log 'error' "${MESSAGE}"
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
}
|