| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- #! /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="\e[31m\e[1m"
- WHITE="\e[37m"
- ORANGE="\e[38;5;214m"
- LBLUE="\e[94m"
- RESET="\e[0m"
- set -euEo pipefail
- shopt -s inherit_errexit
- 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 "${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 "${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 [[ "$(uname)" == 'Darwin' ]]
- then
- readlink() {
- # requires coreutils
- greadlink "${@:+$@}"
- }
- fi
- 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)
- 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
- }
- _main "${@:+$@}"
|