mirror of
https://github.com/docker-mailserver/docker-mailserver.git
synced 2024-01-19 02:48:50 +00:00
fa8bfdc22a
This bug was causing `setup.sh -c` to target the wrong container (the first DMS container started) if more than one DMS container was running.
241 lines
5.9 KiB
Bash
Executable file
241 lines
5.9 KiB
Bash
Executable file
#! /bin/bash
|
|
|
|
# version v1.0.0
|
|
# executed manually / via Make
|
|
# task wrapper for various setup scripts
|
|
|
|
CONFIG_PATH=
|
|
CONTAINER_NAME=
|
|
CRI=
|
|
DEFAULT_CONFIG_PATH=
|
|
DESIRED_CONFIG_PATH=
|
|
DIR=$(pwd)
|
|
DMS_CONFIG='/tmp/docker-mailserver'
|
|
IMAGE_NAME=
|
|
DEFAULT_IMAGE_NAME='docker.io/mailserver/docker-mailserver:latest'
|
|
INFO=
|
|
PODMAN_ROOTLESS=false
|
|
USE_SELINUX=
|
|
USE_TTY=
|
|
VOLUME=
|
|
|
|
RED=$(echo -ne '\e[31m\e[1m')
|
|
WHITE=$(echo -ne '\e[37m')
|
|
ORANGE=$(echo -ne '\e[38;5;214m')
|
|
LBLUE=$(echo -ne '\e[94m')
|
|
RESET=$(echo -ne '\e[0m')
|
|
|
|
set -euEo pipefail
|
|
shopt -s inherit_errexit 2>/dev/null || true
|
|
trap '__err "${BASH_SOURCE}" "${FUNCNAME[0]:-?}" "${BASH_COMMAND:-?}" "${LINENO:-?}" "${?:-?}"' ERR
|
|
|
|
function __err
|
|
{
|
|
[[ ${5} -gt 1 ]] && exit 1
|
|
|
|
local ERR_MSG="\n--- ${RED}UNCHECKED ERROR${RESET}"
|
|
ERR_MSG+="\n - script = ${1}"
|
|
ERR_MSG+="\n - function = ${2}"
|
|
ERR_MSG+="\n - command = ${3}"
|
|
ERR_MSG+="\n - line = ${4}"
|
|
ERR_MSG+="\n - exit code = ${5}"
|
|
ERR_MSG+='\n\nThis should not have happened. Please file a bug report.\n'
|
|
|
|
echo -e "${ERR_MSG}"
|
|
}
|
|
|
|
function _show_local_usage
|
|
{
|
|
# shellcheck disable=SC2059
|
|
printf '%s' "${ORANGE}OPTIONS${RESET}
|
|
${LBLUE}Config path, container or image adjustments${RESET}
|
|
-i IMAGE_NAME
|
|
Provides the name of the 'docker-mailserver' image. The default value is
|
|
'${WHITE}${DEFAULT_IMAGE_NAME}${RESET}'
|
|
|
|
-c CONTAINER_NAME
|
|
Provides the name of the running container.
|
|
|
|
-p PATH
|
|
Provides the local path of the config folder to the temporary container instance.
|
|
Does not work if an existing a 'docker-mailserver' container is already running.
|
|
|
|
${LBLUE}SELinux${RESET}
|
|
-z
|
|
Allows container access to the bind mount content that is shared among
|
|
multiple containers on a SELinux-enabled host.
|
|
|
|
-Z
|
|
Allows container access to the bind mount content that is private and
|
|
unshared with other containers on a SELinux-enabled host.
|
|
|
|
${LBLUE}Podman${RESET}
|
|
-R
|
|
Accept running in Podman rootless mode. Ignored when using Docker / Docker Compose.
|
|
|
|
"
|
|
|
|
[[ ${1:-} == 'no-exit' ]] && return 0
|
|
|
|
# shellcheck disable=SC2059
|
|
printf '%s' "${ORANGE}EXIT STATUS${RESET}
|
|
Exit status is 0 if the command was successful. If there was an unexpected error, an error
|
|
message is shown describing the error. In case of an error, the script will exit with exit
|
|
status 1.
|
|
|
|
"
|
|
}
|
|
|
|
function _get_absolute_script_directory
|
|
{
|
|
if dirname "$(readlink -f "${0}")" &>/dev/null
|
|
then
|
|
DIR=$(dirname "$(readlink -f "${0}")")
|
|
elif realpath -e -L "${0}" &>/dev/null
|
|
then
|
|
DIR=$(realpath -e -L "${0}")
|
|
DIR="${DIR%/setup.sh}"
|
|
fi
|
|
}
|
|
|
|
function _set_default_config_path
|
|
{
|
|
if [[ -d "${DIR}/config" ]]
|
|
then
|
|
# legacy path (pre v10.2.0)
|
|
DEFAULT_CONFIG_PATH="${DIR}/config"
|
|
else
|
|
DEFAULT_CONFIG_PATH="${DIR}/docker-data/dms/config"
|
|
fi
|
|
}
|
|
|
|
function _handle_config_path
|
|
{
|
|
if [[ -z ${DESIRED_CONFIG_PATH} ]]
|
|
then
|
|
# no desired config path
|
|
if [[ -n ${CONTAINER_NAME} ]]
|
|
then
|
|
VOLUME=$(${CRI} inspect "${CONTAINER_NAME}" \
|
|
--format="{{range .Mounts}}{{ println .Source .Destination}}{{end}}" | \
|
|
grep "${DMS_CONFIG}$" 2>/dev/null || :)
|
|
fi
|
|
|
|
if [[ -n ${VOLUME} ]]
|
|
then
|
|
CONFIG_PATH=$(echo "${VOLUME}" | awk '{print $1}')
|
|
fi
|
|
|
|
if [[ -z ${CONFIG_PATH} ]]
|
|
then
|
|
CONFIG_PATH=${DEFAULT_CONFIG_PATH}
|
|
fi
|
|
else
|
|
CONFIG_PATH=${DESIRED_CONFIG_PATH}
|
|
fi
|
|
}
|
|
|
|
function _run_in_new_container
|
|
{
|
|
# start temporary container with specified image
|
|
if ! ${CRI} history -q "${IMAGE_NAME}" &>/dev/null
|
|
then
|
|
echo "Image '${IMAGE_NAME}' not found. Pulling ..."
|
|
${CRI} pull "${IMAGE_NAME}"
|
|
fi
|
|
|
|
${CRI} run --rm "${USE_TTY}" \
|
|
-v "${CONFIG_PATH}:${DMS_CONFIG}${USE_SELINUX}" \
|
|
"${IMAGE_NAME}" "${@}"
|
|
}
|
|
|
|
function _main
|
|
{
|
|
_get_absolute_script_directory
|
|
_set_default_config_path
|
|
|
|
local OPTIND
|
|
while getopts ":c:i:p:zZR" OPT
|
|
do
|
|
case ${OPT} in
|
|
( i ) IMAGE_NAME="${OPTARG}" ;;
|
|
( z | Z ) USE_SELINUX=":${OPT}" ;;
|
|
( c ) CONTAINER_NAME="${OPTARG}" ;;
|
|
( R ) PODMAN_ROOTLESS=true ;;
|
|
( p )
|
|
case "${OPTARG}" in
|
|
( /* ) DESIRED_CONFIG_PATH="${OPTARG}" ;;
|
|
( * ) DESIRED_CONFIG_PATH="${DIR}/${OPTARG}" ;;
|
|
esac
|
|
|
|
if [[ ! -d ${DESIRED_CONFIG_PATH} ]]
|
|
then
|
|
echo "Specified directory '${DESIRED_CONFIG_PATH}' doesn't exist" >&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
|
|
( * )
|
|
echo "Invalid option: '-${OPTARG}'" >&2
|
|
echo -e "Use './setup.sh help' to get a complete overview.\n" >&2
|
|
_show_local_usage 'no-exit'
|
|
exit 1
|
|
;;
|
|
|
|
esac
|
|
done
|
|
shift $(( OPTIND - 1 ))
|
|
|
|
if command -v docker &>/dev/null
|
|
then
|
|
CRI=docker
|
|
elif command -v podman &>/dev/null
|
|
then
|
|
CRI=podman
|
|
if ! ${PODMAN_ROOTLESS} && [[ ${EUID} -ne 0 ]]
|
|
then
|
|
read -r -p "You are running Podman in rootless mode. Continue? [Y/n] "
|
|
[[ -n ${REPLY} ]] && [[ ${REPLY} =~ (n|N) ]] && exit 0
|
|
fi
|
|
else
|
|
echo 'No supported Container Runtime Interface detected.'
|
|
exit 1
|
|
fi
|
|
|
|
INFO=$(${CRI} ps --no-trunc --format "{{.Image}};{{.Names}}" --filter \
|
|
label=org.opencontainers.image.title="docker-mailserver" | tail -1)
|
|
|
|
[[ -z ${CONTAINER_NAME} ]] && CONTAINER_NAME=${INFO#*;}
|
|
[[ -z ${IMAGE_NAME} ]] && IMAGE_NAME=${INFO%;*}
|
|
if [[ -z ${IMAGE_NAME} ]]
|
|
then
|
|
IMAGE_NAME=${NAME:-${DEFAULT_IMAGE_NAME}}
|
|
fi
|
|
|
|
if test -t 0
|
|
then
|
|
USE_TTY="-it"
|
|
else
|
|
# GitHub Actions will fail (or really anything else
|
|
# lacking an interactive tty) if we don't set a
|
|
# value here; "-t" alone works for these cases.
|
|
USE_TTY="-t"
|
|
fi
|
|
|
|
_handle_config_path
|
|
|
|
if [[ -n ${CONTAINER_NAME} ]]
|
|
then
|
|
${CRI} exec "${USE_TTY}" "${CONTAINER_NAME}" setup "${@}"
|
|
else
|
|
_run_in_new_container setup "${@}"
|
|
fi
|
|
|
|
[[ ${1:-} == 'help' ]] && _show_local_usage
|
|
|
|
return 0
|
|
}
|
|
|
|
[[ -z ${1:-} ]] && set 'help'
|
|
_main "${@}"
|