refactor(compose): detect proper compose cmd

This commit is contained in:
Asif Bacchus 2022-07-12 14:55:43 -06:00
parent 818483f92e
commit 475a0d0dd2
2 changed files with 180 additions and 158 deletions

View File

@ -9,6 +9,14 @@
</inspection_tool> </inspection_tool>
</profile> </profile>
</component> </component>
<component name="GitSharedSettings">
<option name="FORCE_PUSH_PROHIBITED_PATTERNS">
<list>
<option value="master" />
<option value="main" />
</list>
</option>
</component>
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="$PROJECT_DIR$" vcs="Git" />
</component> </component>

View File

@ -43,7 +43,7 @@ consoleError() {
} }
exitError() { exitError() {
printf "%s[%s] --- %s execution completed with error ---\n%s" "$err" "$(stamp)" "$scriptName" "$norm" >> "$logfile" printf "%s[%s] --- %s execution completed with error ---\n%s" "$err" "$(stamp)" "$scriptName" "$norm" >>"$logfile"
exit "$1" exit "$1"
} }
@ -51,13 +51,13 @@ doRestore() {
sourceFiles=$(find "${backupLocation}" -iname "${1}" -type d) sourceFiles=$(find "${backupLocation}" -iname "${1}" -type d)
if [ -n "$sourceFiles" ]; then if [ -n "$sourceFiles" ]; then
if [ "$verbose" -eq 1 ]; then if [ "$verbose" -eq 1 ]; then
if (! (cd "$sourceFiles/_data" && tar -cf - .) | (cd "${2}" && tar xvf -) >> "$logfile" ); then if ( ! (cd "$sourceFiles/_data" && tar -cf - .) | (cd "${2}" && tar xvf -) >>"$logfile"); then
return 1 return 1
else else
return 0 return 0
fi fi
else else
if (! (cd "$sourceFiles/_data" && tar -cf - .) | (cd "${2}" && tar xvf -) > /dev/null 2>&1 ); then if ( ! (cd "$sourceFiles/_data" && tar -cf - .) | (cd "${2}" && tar xvf -) >/dev/null 2>&1); then
return 1 return 1
else else
return 0 return 0
@ -146,30 +146,30 @@ textNewline() {
} }
trapExit() { trapExit() {
printf "%s[%s] -- [ERROR] 99: Caught signal --%s\n" "$err" "$(stamp)" "$norm" >> "$logfile" printf "%s[%s] -- [ERROR] 99: Caught signal --%s\n" "$err" "$(stamp)" "$norm" >>"$logfile"
printf "%s[%s] --- %s execution terminated via signal ---\n%s" "$err" "$(stamp)" "$scriptName" "$norm" >> "$logfile" printf "%s[%s] --- %s execution terminated via signal ---\n%s" "$err" "$(stamp)" "$scriptName" "$norm" >>"$logfile"
exit 99 exit 99
} }
writeLog() { writeLog() {
if [ "$1" = "task" ]; then if [ "$1" = "task" ]; then
printf "%s[%s] -- [INFO] %s... " "$info" "$(stamp)" "$2" >> "$logfile" printf "%s[%s] -- [INFO] %s... " "$info" "$(stamp)" "$2" >>"$logfile"
elif [ "$1" = "done" ]; then elif [ "$1" = "done" ]; then
if [ -z "$2" ]; then if [ -z "$2" ]; then
printf "%sdone%s --\n%s" "$ok" "$info" "$norm" >> "$logfile" printf "%sdone%s --\n%s" "$ok" "$info" "$norm" >>"$logfile"
elif [ "$2" = "error" ]; then elif [ "$2" = "error" ]; then
printf "%sERROR%s --\n%s" "$err" "$info" "$norm" >> "$logfile" printf "%sERROR%s --\n%s" "$err" "$info" "$norm" >>"$logfile"
elif [ "$2" = "warn" ]; then elif [ "$2" = "warn" ]; then
printf "%swarning%s --\n%s" "$yellow" "$info" "$norm" >> "$logfile" printf "%swarning%s --\n%s" "$yellow" "$info" "$norm" >>"$logfile"
fi fi
elif [ "$1" = "error" ]; then elif [ "$1" = "error" ]; then
printf "%s[%s] -- [ERROR] %s: %s --\n%s" "$err" "$(stamp)" "$2" "$3" "$norm" >> "$logfile" printf "%s[%s] -- [ERROR] %s: %s --\n%s" "$err" "$(stamp)" "$2" "$3" "$norm" >>"$logfile"
elif [ "$1" = "warn" ]; then elif [ "$1" = "warn" ]; then
printf "%s[%s] -- [WARNING] %s --\n%s" "$yellow" "$(stamp)" "$2" "$norm" >> "$logfile" printf "%s[%s] -- [WARNING] %s --\n%s" "$yellow" "$(stamp)" "$2" "$norm" >>"$logfile"
elif [ "$1" = "info" ]; then elif [ "$1" = "info" ]; then
printf "%s[%s] -- [INFO] %s --\n%s" "$info" "$(stamp)" "$2" "$norm" >> "$logfile" printf "%s[%s] -- [INFO] %s --\n%s" "$info" "$(stamp)" "$2" "$norm" >>"$logfile"
elif [ "$1" = "success" ]; then elif [ "$1" = "success" ]; then
printf "%s[%s] -- [SUCCESS] %s --\n%s" "$ok" "$(stamp)" "$2" "$norm" >> "$logfile" printf "%s[%s] -- [SUCCESS] %s --\n%s" "$ok" "$(stamp)" "$2" "$norm" >>"$logfile"
fi fi
} }
@ -195,6 +195,7 @@ mcDockerCompose='/opt/mailcow-dockerized/docker-compose.yml'
sqlRunning=0 sqlRunning=0
dockerStartTimeout=180 dockerStartTimeout=180
dockerStopTimeout=120 dockerStopTimeout=120
dockerCmd="docker compose"
### check if user is root ### check if user is root
if [ "$(id -u)" -ne 0 ]; then if [ "$(id -u)" -ne 0 ]; then
@ -204,11 +205,11 @@ fi
### process startup parameters ### process startup parameters
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case "$1" in case "$1" in
-h|-\?|--help) -h | -\? | --help)
# display help # display help
scriptHelp scriptHelp
;; ;;
-l|--log) -l | --log)
# set logfile location # set logfile location
if [ -z "$2" ]; then if [ -z "$2" ]; then
consoleError '1' "Log file path cannot be null. Leave unspecified to save log in the same directory as this script." consoleError '1' "Log file path cannot be null. Leave unspecified to save log in the same directory as this script."
@ -216,10 +217,10 @@ while [ $# -gt 0 ]; do
logfile="$2" logfile="$2"
shift shift
;; ;;
-v|--verbose) -v | --verbose)
verbose=1 verbose=1
;; ;;
-d|--docker-compose) -d | --docker-compose)
# FULL path to docker-compose file # FULL path to docker-compose file
if [ -n "$2" ]; then if [ -n "$2" ]; then
if [ -f "$2" ]; then if [ -f "$2" ]; then
@ -232,7 +233,7 @@ while [ $# -gt 0 ]; do
consoleError '1' "$1: cannot be blank/empty." consoleError '1' "$1: cannot be blank/empty."
fi fi
;; ;;
-m|--mailcow-config) -m | --mailcow-config)
# FULL path to mailcow configuration file file # FULL path to mailcow configuration file file
if [ -n "$2" ]; then if [ -n "$2" ]; then
if [ -f "$2" ]; then if [ -f "$2" ]; then
@ -245,7 +246,7 @@ while [ $# -gt 0 ]; do
consoleError '1' "$1: cannot be blank/empty." consoleError '1' "$1: cannot be blank/empty."
fi fi
;; ;;
-t1|--timeout-start) -t1 | --timeout-start)
if [ -z "$2" ]; then if [ -z "$2" ]; then
consoleError '1' "$1: cannot be blank/empty." consoleError '1' "$1: cannot be blank/empty."
else else
@ -253,7 +254,7 @@ while [ $# -gt 0 ]; do
shift shift
fi fi
;; ;;
-t2|--timeout-stop) -t2 | --timeout-stop)
if [ -z "$2" ]; then if [ -z "$2" ]; then
consoleError '1' "$1: cannot be blank/empty." consoleError '1' "$1: cannot be blank/empty."
else else
@ -261,9 +262,9 @@ while [ $# -gt 0 ]; do
shift shift
fi fi
;; ;;
-b|--backup-location) -b | --backup-location)
if [ -n "$2" ]; then if [ -n "$2" ]; then
if [ -d "$2" ] && [ -n "$( ls -A "$2" )" ]; then if [ -d "$2" ] && [ -n "$(ls -A "$2")" ]; then
backupLocation="${2%/}" backupLocation="${2%/}"
shift shift
else else
@ -309,6 +310,14 @@ export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
if ! command -v docker >/dev/null; then if ! command -v docker >/dev/null; then
consoleError '3' 'docker does not seem to be installed!' consoleError '3' 'docker does not seem to be installed!'
fi fi
# verify compose installed and set proper commands based on version
if ! (docker compose version >/dev/null 2>&1); then
if ! (docker-compose --version >/dev/null 2>&1); then
printf "\n%sERROR: Docker Compose not installed or not functioning%s\n\n" "$err" "$norm"
exit 3
fi
dockerCmd="docker-compose"
fi
# mailcow.conf? # mailcow.conf?
if [ ! -f "$mcConfig" ]; then if [ ! -f "$mcConfig" ]; then
consoleError '1' "mailcow configuration file ($mcConfig) cannot be found." consoleError '1' "mailcow configuration file ($mcConfig) cannot be found."
@ -353,7 +362,7 @@ else
fi fi
fi fi
# write initial log entries # write initial log entries
if ! printf "%s[%s] --- Start %s execution ---\n%s" "$magenta" "$(stamp)" "$scriptName" "$norm" 2>/dev/null >> "$logfile"; then if ! printf "%s[%s] --- Start %s execution ---\n%s" "$magenta" "$(stamp)" "$scriptName" "$norm" 2>/dev/null >>"$logfile"; then
consoleError '1' "Unable to write to log file ($logfile)" consoleError '1' "Unable to write to log file ($logfile)"
fi fi
writeLog 'info' "Log located at $logfile" writeLog 'info' "Log located at $logfile"
@ -383,14 +392,14 @@ if [ "$restoreSQL" -eq 1 ]; then
sqlBackup=$(find "${backupLocation}/tmp" -iname "*.sql") sqlBackup=$(find "${backupLocation}/tmp" -iname "*.sql")
if [ -n "$sqlBackup" ]; then if [ -n "$sqlBackup" ]; then
# start mysql container if not already running # start mysql container if not already running
if ! docker container inspect -f '{{ .State.Running }}' ${COMPOSE_PROJECT_NAME}_mysql-mailcow_1 > /dev/null 2>&1; then if ! docker container inspect -f '{{ .State.Running }}' ${COMPOSE_PROJECT_NAME}_mysql-mailcow_1 >/dev/null 2>&1; then
docker-compose up -d mysql-mailcow > /dev/null 2>&1 "${dockerCmd}" up -d mysql-mailcow >/dev/null 2>&1
if docker container inspect -f '{{ .State.Running }}' ${COMPOSE_PROJECT_NAME}_mysql-mailcow_1 > /dev/null 2>&1; then if docker container inspect -f '{{ .State.Running }}' ${COMPOSE_PROJECT_NAME}_mysql-mailcow_1 >/dev/null 2>&1; then
sqlRunning=1 sqlRunning=1
else else
writeLog 'done' 'error' writeLog 'done' 'error'
writeLog 'error' '12' "Cannot start mysql-mailcow container -- cannot restore mailcow database!" writeLog 'error' '12' "Cannot start mysql-mailcow container -- cannot restore mailcow database!"
errorCount=$((errorCount+1)) errorCount=$((errorCount + 1))
fi fi
else else
sqlRunning=1 sqlRunning=1
@ -398,29 +407,29 @@ if [ "$restoreSQL" -eq 1 ]; then
else else
writeLog 'done' 'error' writeLog 'done' 'error'
writeLog 'error' '11' "Cannot locate SQL backup -- cannot restore mailcow database!" writeLog 'error' '11' "Cannot locate SQL backup -- cannot restore mailcow database!"
errorCount=$((errorCount+1)) errorCount=$((errorCount + 1))
fi fi
# restore sql # restore sql
if [ "$sqlRunning" -eq 1 ]; then if [ "$sqlRunning" -eq 1 ]; then
if docker exec -i "$(docker-compose ps -q mysql-mailcow)" mysql -u${DBUSER} -p${DBPASS} ${DBNAME} < "${sqlBackup}" > /dev/null 2>&1; then if docker exec -i "$("${dockerCmd}" ps -q mysql-mailcow)" mysql -u${DBUSER} -p${DBPASS} ${DBNAME} <"${sqlBackup}" >/dev/null 2>&1; then
writeLog 'done' writeLog 'done'
else else
writeLog 'done' 'error' writeLog 'done' 'error'
writeLog 'error' '13' "Something went wrong while trying to restore SQL database. Perhaps try again?" writeLog 'error' '13' "Something went wrong while trying to restore SQL database. Perhaps try again?"
errorCount=$((errorCount+1)) errorCount=$((errorCount + 1))
fi fi
fi fi
fi fi
### stop containers (necessary for all restore operations except SQL) ### stop containers (necessary for all restore operations except SQL)
writeLog 'task' "Stopping mailcow" writeLog 'task' "Stopping mailcow"
if ! docker-compose down --timeout "${dockerStopTimeout}" > /dev/null 2>&1; then if ! "${dockerCmd}" down --timeout "${dockerStopTimeout}" >/dev/null 2>&1; then
writeLog 'done' 'error' writeLog 'done' 'error'
writeLog 'error' '20' "Unable to bring mailcow containers down -- cannot reliably restore. Aborting." writeLog 'error' '20' "Unable to bring mailcow containers down -- cannot reliably restore. Aborting."
exitError 20 exitError 20
fi fi
if [ "$( docker ps --filter "name=${COMPOSE_PROJECT_NAME}" -q | wc -l )" -gt 0 ]; then if [ "$(docker ps --filter "name=${COMPOSE_PROJECT_NAME}" -q | wc -l)" -gt 0 ]; then
writeLog 'done' 'error' writeLog 'done' 'error'
writeLog 'error' '20' "Unable to bring mailcow containers down -- cannot reliably restore. Aborting." writeLog 'error' '20' "Unable to bring mailcow containers down -- cannot reliably restore. Aborting."
exitError 20 exitError 20
@ -436,7 +445,8 @@ if [ "$restoreMail" -eq 1 ]; then
fi fi
# restore email messages # restore email messages
doRestore "${COMPOSE_PROJECT_NAME}_vmail-vol-1" "$dockerVolumeMail"; ec="$?" doRestore "${COMPOSE_PROJECT_NAME}_vmail-vol-1" "$dockerVolumeMail"
ec="$?"
case "$ec" in case "$ec" in
0) 0)
if [ "$verbose" -eq 1 ]; then if [ "$verbose" -eq 1 ]; then
@ -464,7 +474,8 @@ if [ "$restoreMail" -eq 1 ]; then
esac esac
# restore encryption key # restore encryption key
doRestore "${COMPOSE_PROJECT_NAME}_crypt-vol-1" "$dockerVolumeCrypt"; ec="$?" doRestore "${COMPOSE_PROJECT_NAME}_crypt-vol-1" "$dockerVolumeCrypt"
ec="$?"
case "$ec" in case "$ec" in
0) 0)
if [ "$verbose" -eq 1 ]; then if [ "$verbose" -eq 1 ]; then
@ -500,7 +511,8 @@ if [ "$restorePostfix" -eq 1 ]; then
writeLog 'task' "Restoring postfix files" writeLog 'task' "Restoring postfix files"
fi fi
doRestore "${COMPOSE_PROJECT_NAME}_postfix-vol-1" "$dockerVolumePostfix"; ec="$?" doRestore "${COMPOSE_PROJECT_NAME}_postfix-vol-1" "$dockerVolumePostfix"
ec="$?"
case "$ec" in case "$ec" in
0) 0)
if [ "$verbose" -eq 1 ]; then if [ "$verbose" -eq 1 ]; then
@ -536,7 +548,8 @@ if [ "$restoreRspamd" -eq 1 ]; then
writeLog 'task' "Restoring Rspamd files" writeLog 'task' "Restoring Rspamd files"
fi fi
doRestore "${COMPOSE_PROJECT_NAME}_rspamd-vol-1" "$dockerVolumeRspamd"; ec="$?" doRestore "${COMPOSE_PROJECT_NAME}_rspamd-vol-1" "$dockerVolumeRspamd"
ec="$?"
case "$ec" in case "$ec" in
0) 0)
if [ "$verbose" -eq 1 ]; then if [ "$verbose" -eq 1 ]; then
@ -572,7 +585,8 @@ if [ "$restoreRedis" -eq 1 ]; then
writeLog 'task' "Restoring redis database" writeLog 'task' "Restoring redis database"
fi fi
doRestore "${COMPOSE_PROJECT_NAME}_redis-vol-1" "$dockerVolumeRedis"; ec="$?" doRestore "${COMPOSE_PROJECT_NAME}_redis-vol-1" "$dockerVolumeRedis"
ec="$?"
case "$ec" in case "$ec" in
0) 0)
if [ "$verbose" -eq 1 ]; then if [ "$verbose" -eq 1 ]; then
@ -602,24 +616,24 @@ fi
### restart mailcow ### restart mailcow
writeLog 'task' "Starting mailcow" writeLog 'task' "Starting mailcow"
if ! docker-compose up -d > /dev/null 2>&1; then if ! "${dockerCmd}" up -d >/dev/null 2>&1; then
writeLog 'done' 'warn' writeLog 'done' 'warn'
writeLog 'warn' '21' "Unable to automatically start mailcow containers. Please attempt a manual start and note any errors." writeLog 'warn' '21' "Unable to automatically start mailcow containers. Please attempt a manual start and note any errors."
warnCount=$((warnCount+1)) warnCount=$((warnCount + 1))
fi fi
writeLog 'done' writeLog 'done'
### exit gracefully ### exit gracefully
if [ "$errorCount" -gt 0 ]; then if [ "$errorCount" -gt 0 ]; then
# note non-terminating errors # note non-terminating errors
printf "%s[%s] --- %s execution completed with %s error(s) ---\n%s" "$err" "$(stamp)" "$scriptName" "$errorCount" "$norm" >> "$logfile" printf "%s[%s] --- %s execution completed with %s error(s) ---\n%s" "$err" "$(stamp)" "$scriptName" "$errorCount" "$norm" >>"$logfile"
exit 98 exit 98
elif [ "$warnCount" -gt 0 ]; then elif [ "$warnCount" -gt 0 ]; then
printf "%s[%s] --- %s execution completed with %s warning(s) ---\n%s" "$yellow" "$(stamp)" "$scriptName" "$warnCount" "$norm" >> "$logfile" printf "%s[%s] --- %s execution completed with %s warning(s) ---\n%s" "$yellow" "$(stamp)" "$scriptName" "$warnCount" "$norm" >>"$logfile"
exit 97 exit 97
else else
writeLog 'success' "All processes completed" writeLog 'success' "All processes completed"
printf "%s[%s] --- %s execution completed ---\n%s" "$magenta" "$(stamp)" "$scriptName" "$norm" >> "$logfile" printf "%s[%s] --- %s execution completed ---\n%s" "$magenta" "$(stamp)" "$scriptName" "$norm" >>"$logfile"
exit 0 exit 0
fi fi