You've already forked docker-mailserver
							
							
				mirror of
				https://github.com/docker-mailserver/docker-mailserver.git
				synced 2025-10-31 00:17:45 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			202 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			5.4 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='ghcr.io/docker-mailserver/docker-mailserver:latest'
 | |
| INFO=
 | |
| PODMAN_ROOTLESS=false
 | |
| USE_SELINUX=
 | |
| USE_TTY=
 | |
| VOLUME=
 | |
| 
 | |
| 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
 | |
| 
 | |
| 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 "${@}"
 |