mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2025-10-08 00:03:45 -04:00
224 lines
9.0 KiB
Bash
224 lines
9.0 KiB
Bash
#!/usr/bin/env bash
|
|
# _modules/scripts/core.sh
|
|
# THIS SCRIPT IS DESIGNED TO BE RUNNING BY MAILCOW SCRIPTS ONLY!
|
|
# DO NOT, AGAIN, NOT TRY TO RUN THIS SCRIPT STANDALONE!!!!!!
|
|
|
|
# ANSI color for red errors
|
|
RED='\e[31m'
|
|
GREEN='\e[32m'
|
|
YELLOW='\e[33m'
|
|
BLUE='\e[34m'
|
|
MAGENTA='\e[35m'
|
|
LIGHT_RED='\e[91m'
|
|
LIGHT_GREEN='\e[92m'
|
|
NC='\e[0m'
|
|
|
|
caller="${BASH_SOURCE[1]##*/}"
|
|
|
|
get_installed_tools(){
|
|
for bin in openssl curl docker git awk sha1sum grep cut jq; do
|
|
if [[ -z $(command -v ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi
|
|
done
|
|
|
|
if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo -e "${LIGHT_RED}BusyBox grep detected, please install gnu grep, \"apk add --no-cache --upgrade grep\"${NC}"; exit 1; fi
|
|
# This will also cover sort
|
|
if cp --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo -e "${LIGHT_RED}BusyBox cp detected, please install coreutils, \"apk add --no-cache --upgrade coreutils\"${NC}"; exit 1; fi
|
|
if sed --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo -e "${LIGHT_RED}BusyBox sed detected, please install gnu sed, \"apk add --no-cache --upgrade sed\"${NC}"; exit 1; fi
|
|
}
|
|
|
|
get_docker_version(){
|
|
# Check Docker Version (need at least 24.X)
|
|
docker_version=$(docker version --format '{{.Server.Version}}' | cut -d '.' -f 1)
|
|
}
|
|
|
|
get_compose_type(){
|
|
if docker compose > /dev/null 2>&1; then
|
|
if docker compose version --short | grep -e "^2." -e "^v2." > /dev/null 2>&1; then
|
|
COMPOSE_VERSION=native
|
|
COMPOSE_COMMAND="docker compose"
|
|
if [[ "$caller" == "update.sh" ]]; then
|
|
sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=native/' "$SCRIPT_DIR/mailcow.conf"
|
|
fi
|
|
echo -e "\e[33mFound Docker Compose Plugin (native).\e[0m"
|
|
echo -e "\e[33mSetting the DOCKER_COMPOSE_VERSION Variable to native\e[0m"
|
|
sleep 2
|
|
echo -e "\e[33mNotice: You'll have to update this Compose Version via your Package Manager manually!\e[0m"
|
|
else
|
|
echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m"
|
|
echo -e "\e[31mPlease update/install it manually regarding to this doc site: https://docs.mailcow.email/install/\e[0m"
|
|
exit 1
|
|
fi
|
|
elif docker-compose > /dev/null 2>&1; then
|
|
if ! [[ $(alias docker-compose 2> /dev/null) ]] ; then
|
|
if docker-compose version --short | grep "^2." > /dev/null 2>&1; then
|
|
COMPOSE_VERSION=standalone
|
|
COMPOSE_COMMAND="docker-compose"
|
|
if [[ "$caller" == "update.sh" ]]; then
|
|
sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=standalone/' "$SCRIPT_DIR/mailcow.conf"
|
|
fi
|
|
echo -e "\e[33mFound Docker Compose Standalone.\e[0m"
|
|
echo -e "\e[33mSetting the DOCKER_COMPOSE_VERSION Variable to standalone\e[0m"
|
|
sleep 2
|
|
echo -e "\e[33mNotice: For an automatic update of docker-compose please use the update_compose.sh scripts located at the helper-scripts folder.\e[0m"
|
|
else
|
|
echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m"
|
|
echo -e "\e[31mPlease update/install manually regarding to this doc site: https://docs.mailcow.email/install/\e[0m"
|
|
exit 1
|
|
fi
|
|
fi
|
|
else
|
|
echo -e "\e[31mCannot find Docker Compose.\e[0m"
|
|
echo -e "\e[31mPlease install it regarding to this doc site: https://docs.mailcow.email/install/\e[0m"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
detect_bad_asn() {
|
|
echo -e "\e[33mDetecting if your IP is listed on Spamhaus Bad ASN List...\e[0m"
|
|
response=$(curl --connect-timeout 15 --max-time 30 -s -o /dev/null -w "%{http_code}" "https://asn-check.mailcow.email")
|
|
if [ "$response" -eq 503 ]; then
|
|
if [ -z "$SPAMHAUS_DQS_KEY" ]; then
|
|
echo -e "\e[33mYour server's public IP uses an AS that is blocked by Spamhaus to use their DNS public blocklists for Postfix.\e[0m"
|
|
echo -e "\e[33mmailcow did not detected a value for the variable SPAMHAUS_DQS_KEY inside mailcow.conf!\e[0m"
|
|
sleep 2
|
|
echo ""
|
|
echo -e "\e[33mTo use the Spamhaus DNS Blocklists again, you will need to create a FREE account for their Data Query Service (DQS) at: https://www.spamhaus.com/free-trial/sign-up-for-a-free-data-query-service-account\e[0m"
|
|
echo -e "\e[33mOnce done, enter your DQS API key in mailcow.conf and mailcow will do the rest for you!\e[0m"
|
|
echo ""
|
|
sleep 2
|
|
else
|
|
echo -e "\e[33mYour server's public IP uses an AS that is blocked by Spamhaus to use their DNS public blocklists for Postfix.\e[0m"
|
|
echo -e "\e[32mmailcow detected a Value for the variable SPAMHAUS_DQS_KEY inside mailcow.conf. Postfix will use DQS with the given API key...\e[0m"
|
|
fi
|
|
elif [ "$response" -eq 200 ]; then
|
|
echo -e "\e[33mCheck completed! Your IP is \e[32mclean\e[0m"
|
|
elif [ "$response" -eq 429 ]; then
|
|
echo -e "\e[33mCheck completed! \e[31mYour IP seems to be rate limited on the ASN Check service... please try again later!\e[0m"
|
|
else
|
|
echo -e "\e[31mCheck failed! \e[0mMaybe a DNS or Network problem?\e[0m"
|
|
fi
|
|
}
|
|
|
|
check_online_status() {
|
|
CHECK_ONLINE_DOMAINS=('https://github.com' 'https://hub.docker.com')
|
|
for domain in "${CHECK_ONLINE_DOMAINS[@]}"; do
|
|
if timeout 6 curl --head --silent --output /dev/null ${domain}; then
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
prefetch_images() {
|
|
[[ -z ${BRANCH} ]] && { echo -e "\e[33m\nUnknown branch...\e[0m"; exit 1; }
|
|
git fetch origin #${BRANCH}
|
|
while read image; do
|
|
RET_C=0
|
|
until docker pull "${image}"; do
|
|
RET_C=$((RET_C + 1))
|
|
echo -e "\e[33m\nError pulling $image, retrying...\e[0m"
|
|
[ ${RET_C} -gt 3 ] && { echo -e "\e[31m\nToo many failed retries, exiting\e[0m"; exit 1; }
|
|
sleep 1
|
|
done
|
|
done < <(git show "origin/${BRANCH}:docker-compose.yml" | grep "image:" | awk '{ gsub("image:","", $3); print $2 }')
|
|
}
|
|
|
|
docker_garbage() {
|
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
|
|
IMGS_TO_DELETE=()
|
|
|
|
declare -A IMAGES_INFO
|
|
COMPOSE_IMAGES=($(grep -oP "image: \K(ghcr\.io/)?mailcow.+" "${SCRIPT_DIR}/docker-compose.yml"))
|
|
|
|
for existing_image in $(docker images --format "{{.ID}}:{{.Repository}}:{{.Tag}}" | grep -E '(mailcow/|ghcr\.io/mailcow/)'); do
|
|
ID=$(echo "$existing_image" | cut -d ':' -f 1)
|
|
REPOSITORY=$(echo "$existing_image" | cut -d ':' -f 2)
|
|
TAG=$(echo "$existing_image" | cut -d ':' -f 3)
|
|
|
|
if [[ "$REPOSITORY" == "mailcow/backup" || "$REPOSITORY" == "ghcr.io/mailcow/backup" ]]; then
|
|
if [[ "$TAG" != "<none>" ]]; then
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
if [[ " ${COMPOSE_IMAGES[@]} " =~ " ${REPOSITORY}:${TAG} " ]]; then
|
|
continue
|
|
else
|
|
IMGS_TO_DELETE+=("$ID")
|
|
IMAGES_INFO["$ID"]="$REPOSITORY:$TAG"
|
|
fi
|
|
done
|
|
|
|
if [[ ! -z ${IMGS_TO_DELETE[*]} ]]; then
|
|
echo "The following unused mailcow images were found:"
|
|
for id in "${IMGS_TO_DELETE[@]}"; do
|
|
echo " ${IMAGES_INFO[$id]} ($id)"
|
|
done
|
|
|
|
if [ -z "$FORCE" ]; then
|
|
read -r -p "Do you want to delete them to free up some space? [y/N] " response
|
|
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
|
docker rmi ${IMGS_TO_DELETE[*]}
|
|
else
|
|
echo "OK, skipped."
|
|
fi
|
|
else
|
|
echo "Running in forced mode! Force removing old mailcow images..."
|
|
docker rmi ${IMGS_TO_DELETE[*]}
|
|
fi
|
|
echo -e "\e[32mFurther cleanup...\e[0m"
|
|
echo "If you want to cleanup further garbage collected by Docker, please make sure all containers are up and running before cleaning your system by executing \"docker system prune\""
|
|
fi
|
|
}
|
|
|
|
in_array() {
|
|
local e match="$1"
|
|
shift
|
|
for e; do [[ "$e" == "$match" ]] && return 0; done
|
|
return 1
|
|
}
|
|
|
|
detect_major_update() {
|
|
if [ ${BRANCH} == "master" ]; then
|
|
# Array with major versions
|
|
# Add major versions here
|
|
MAJOR_VERSIONS=(
|
|
"2025-02"
|
|
"2025-03"
|
|
"2025-09"
|
|
)
|
|
|
|
current_version=""
|
|
if [[ -f "${SCRIPT_DIR}/data/web/inc/app_info.inc.php" ]]; then
|
|
current_version=$(grep 'MAILCOW_GIT_VERSION' ${SCRIPT_DIR}/data/web/inc/app_info.inc.php | sed -E 's/.*MAILCOW_GIT_VERSION="([^"]+)".*/\1/')
|
|
fi
|
|
if [[ -z "$current_version" ]]; then
|
|
return 1
|
|
fi
|
|
release_url="https://github.com/mailcow/mailcow-dockerized/releases/tag"
|
|
|
|
updates_to_apply=()
|
|
|
|
for version in "${MAJOR_VERSIONS[@]}"; do
|
|
if [[ "$current_version" < "$version" ]]; then
|
|
updates_to_apply+=("$version")
|
|
fi
|
|
done
|
|
|
|
if [[ ${#updates_to_apply[@]} -gt 0 ]]; then
|
|
echo -e "\e[33m\nMAJOR UPDATES to be applied:\e[0m"
|
|
for update in "${updates_to_apply[@]}"; do
|
|
echo "$update - $release_url/$update"
|
|
done
|
|
|
|
echo -e "\nPlease read the release notes before proceeding."
|
|
read -p "Do you want to proceed with the update? [y/n] " response
|
|
if [[ "${response}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
|
echo "Proceeding with the update..."
|
|
else
|
|
echo "Update canceled. Exiting."
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
} |