chore(scripts): Removing flock so NFS works (#1980)

Co-authored-by: Casper <casperklein@users.noreply.github.com>
Co-authored-by: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com>
This commit is contained in:
Nathan Pierce 2021-06-15 08:03:41 -04:00 committed by GitHub
parent ba32943986
commit 5becce8064
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 302 additions and 273 deletions

View File

@ -25,7 +25,7 @@ clean:
# remove running and stopped test containers # remove running and stopped test containers
-@ [[ -d config.bak ]] && { rm -rf config ; mv config.bak config ; } || : -@ [[ -d config.bak ]] && { rm -rf config ; mv config.bak config ; } || :
-@ [[ -d testconfig.bak ]] && { sudo rm -rf test/config ; mv testconfig.bak test/config ; } || : -@ [[ -d testconfig.bak ]] && { sudo rm -rf test/config ; mv testconfig.bak test/config ; } || :
-@ for container in $$(docker ps -a | grep -E "mail|ldap_for_mail|mail_overri.*|hadolint|eclint|shellcheck" | cut -f 1-1 -d ' '); do docker rm -f $$container; done -@ for container in $$(docker ps -a --filter name='^/mail$$|^ldap_for_mail$$|^mail_override_hostname$$|^open-dkim$$|^hadolint$$|^eclint$$|^shellcheck$$' | sed 1d | cut -f 1-1 -d ' '); do docker rm -f $$container; done
-@ sudo rm -rf test/onedir test/alias test/quota test/relay test/config/dovecot-lmtp/userdb test/config/key* test/config/opendkim/keys/domain.tld/ test/config/opendkim/keys/example.com/ test/config/opendkim/keys/localdomain2.com/ test/config/postfix-aliases.cf test/config/postfix-receive-access.cf test/config/postfix-receive-access.cfe test/config/dovecot-quotas.cf test/config/postfix-send-access.cf test/config/postfix-send-access.cfe test/config/relay-hosts/chksum test/config/relay-hosts/postfix-aliases.cf test/config/dhparams.pem test/config/dovecot-lmtp/dh.pem test/config/relay-hosts/dovecot-quotas.cf test/config/user-patches.sh test/alias/config/postfix-virtual.cf test/quota/config/dovecot-quotas.cf test/quota/config/postfix-accounts.cf test/relay/config/postfix-relaymap.cf test/relay/config/postfix-sasl-password.cf test/duplicate_configs/ -@ sudo rm -rf test/onedir test/alias test/quota test/relay test/config/dovecot-lmtp/userdb test/config/key* test/config/opendkim/keys/domain.tld/ test/config/opendkim/keys/example.com/ test/config/opendkim/keys/localdomain2.com/ test/config/postfix-aliases.cf test/config/postfix-receive-access.cf test/config/postfix-receive-access.cfe test/config/dovecot-quotas.cf test/config/postfix-send-access.cf test/config/postfix-send-access.cfe test/config/relay-hosts/chksum test/config/relay-hosts/postfix-aliases.cf test/config/dhparams.pem test/config/dovecot-lmtp/dh.pem test/config/relay-hosts/dovecot-quotas.cf test/config/user-patches.sh test/alias/config/postfix-virtual.cf test/quota/config/dovecot-quotas.cf test/quota/config/postfix-accounts.cf test/relay/config/postfix-relaymap.cf test/relay/config/postfix-sasl-password.cf test/duplicate_configs/
# ----------------------------------------------- # -----------------------------------------------

View File

@ -35,21 +35,19 @@ function __usage
[[ ${1:-} == 'help' ]] && { __usage ; exit 0 ; } [[ ${1:-} == 'help' ]] && { __usage ; exit 0 ; }
USER="${1}" FULL_EMAIL="${1}"
shift shift
PASSWD="${*}" PASSWD="${*}"
[[ -z ${USER} ]] && { __usage ; errex 'No username specified' ; } [[ -z ${FULL_EMAIL} ]] && { __usage ; errex 'No username specified' ; }
[[ "${USER}" =~ .*\@.* ]] || { __usage ; errex 'Username must include the domain' ; } [[ "${FULL_EMAIL}" =~ .*\@.* ]] || { __usage ; errex 'Username must include the domain' ; }
# Protect config file with lock to avoid race conditions # Protect config file with lock to avoid race conditions
touch "${DATABASE}" touch "${DATABASE}"
( create_lock "$(basename "$0")"
flock -e 200 if grep -qi "^$(escape "${FULL_EMAIL}")|" "${DATABASE}"
if grep -qi "^$(escape "${USER}")|" "${DATABASE}" 2>/dev/null
then then
echo "User '${USER}' already exists." echo "User '${FULL_EMAIL}' already exists."
exit 1 exit 1
fi fi
@ -60,6 +58,18 @@ touch "${DATABASE}"
[[ -z ${PASSWD} ]] && errex "Password must not be empty" [[ -z ${PASSWD} ]] && errex "Password must not be empty"
fi fi
HASH="$(doveadm pw -s SHA512-CRYPT -u "${USER}" -p "${PASSWD}")" HASH="$(doveadm pw -s SHA512-CRYPT -u "${FULL_EMAIL}" -p "${PASSWD}")"
echo "${USER}|${HASH}" >> "${DATABASE}" echo "${FULL_EMAIL}|${HASH}" >> "${DATABASE}"
) 200< "${DATABASE}"
USER="${FULL_EMAIL%@*}"
DOMAIN="${FULL_EMAIL#*@}"
# Tests fail if the creation of /var/mail/${DOMAIN}/${USER} doesn't happen fast enough after addmailuser executes (check-for-changes.sh race-condition)
if [[ -e "/tmp/docker-mailserver-config-chksum" ]] # Prevent infinite loop in tests like "checking accounts: user3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf even when that file does not exist"
then
while [[ ! -d "/var/mail/${DOMAIN}/${USER}" ]]
do
echo "Waiting for dovecot to create /var/mail/${DOMAIN}/${USER}..."
sleep 1
done
fi

View File

@ -86,15 +86,13 @@ then
fi fi
fi fi
( create_lock "$(basename "$0")"
flock -e 200
for EMAIL in "${@}" for EMAIL in "${@}"
do do
ERROR=false ERROR=false
# very simple plausibility check # very simple plausibility check
[[ ${EMAIL} != *@*.* ]] && errex "No valid address: ${EMAIL}" [[ ${EMAIL} != *@*.* ]] && errex "No valid email address: ${EMAIL}"
USER="${EMAIL%@*}" USER="${EMAIL%@*}"
DOMAIN="${EMAIL#*@}" DOMAIN="${EMAIL#*@}"
@ -153,6 +151,7 @@ use 'sudo docker exec mailserver rm -R /var/mail/${DOMAIN}/${USER}'"
echo "Mailbox couldn't be deleted." >&2 echo "Mailbox couldn't be deleted." >&2
ERROR=true ERROR=true
fi fi
rmdir "/var/mail/${DOMAIN}" 2>/dev/null || true
else else
echo "Mailbox directory '/var/mail/${DOMAIN}/${USER}' did not exist." >&2 echo "Mailbox directory '/var/mail/${DOMAIN}/${USER}' did not exist." >&2
ERROR=true ERROR=true
@ -160,7 +159,4 @@ use 'sudo docker exec mailserver rm -R /var/mail/${DOMAIN}/${USER}'"
${ERROR} && errex 'See the messages above.' ${ERROR} && errex 'See the messages above.'
done done
) 200< "${DATABASE}"
exit 0 exit 0

View File

@ -33,10 +33,9 @@ then
fi fi
# Protect config file with lock to avoid race conditions # Protect config file with lock to avoid race conditions
touch "${DATABASE}" create_lock "$(basename "$0")"
(
flock -e 200
touch "${DATABASE}"
if [ -z "${QUOTA}" ]; then if [ -z "${QUOTA}" ]; then
read -r -s "Enter quota (e.g. 10M): " QUOTA read -r -s "Enter quota (e.g. 10M): " QUOTA
echo echo
@ -52,5 +51,3 @@ touch "${DATABASE}"
delquota "${USER}" delquota "${USER}"
echo "${USER}:${QUOTA}" >>"${DATABASE}" echo "${USER}:${QUOTA}" >>"${DATABASE}"
) 200< "${DATABASE}"

View File

@ -28,8 +28,7 @@ fi
HASH="$(doveadm pw -s SHA512-CRYPT -u "${USER}" -p "${PASSWD}")" HASH="$(doveadm pw -s SHA512-CRYPT -u "${USER}" -p "${PASSWD}")"
# Protect config file with lock to avoid race conditions # Protect config file with lock to avoid race conditions
( touch "${DATABASE}"
flock -e 200 create_lock "$(basename "$0")"
grep -qi "^$(escape "${USER}")|" "${DATABASE}" 2>/dev/null || errex "User \"${USER}\" does not exist" grep -qi "^$(escape "${USER}")|" "${DATABASE}" 2>/dev/null || errex "User \"${USER}\" does not exist"
sed -i "s ^""${USER}""|.* ""${USER}""|""${HASH}"" " "${DATABASE}" sed -i "s ^""${USER}""|.* ""${USER}""|""${HASH}"" " "${DATABASE}"
) 200< "${DATABASE}"

View File

@ -6,7 +6,9 @@
LOG_DATE=$(date +"%Y-%m-%d %H:%M:%S ") LOG_DATE=$(date +"%Y-%m-%d %H:%M:%S ")
_notify 'task' "${LOG_DATE} Start check-for-changes script." _notify 'task' "${LOG_DATE} Start check-for-changes script."
# ? --------------------------------------------- Checks SCRIPT_NAME="$(basename "$0")"
# ? Checks
cd /tmp/docker-mailserver || exit 1 cd /tmp/docker-mailserver || exit 1
@ -43,10 +45,17 @@ while true
do do
LOG_DATE=$(date +"%Y-%m-%d %H:%M:%S ") LOG_DATE=$(date +"%Y-%m-%d %H:%M:%S ")
# Lock configuration while working
create_lock "${SCRIPT_NAME}"
# get chksum and check it, no need to lock config yet # get chksum and check it, no need to lock config yet
_monitored_files_checksums >"${CHKSUM_FILE}.new" _monitored_files_checksums >"${CHKSUM_FILE}.new"
cmp --silent -- "${CHKSUM_FILE}" "${CHKSUM_FILE}.new"
if ! cmp --silent -- "${CHKSUM_FILE}" "${CHKSUM_FILE}.new" # cmp return codes
# 0 files are identical
# 1 files differ
# 2 inaccessible or missing argument
if [ $? -eq 1 ]
then then
_notify 'inf' "${LOG_DATE} Change detected" _notify 'inf' "${LOG_DATE} Change detected"
CHANGED=$(grep -Fxvf "${CHKSUM_FILE}" "${CHKSUM_FILE}.new" | sed 's/^[^ ]\+ //') CHANGED=$(grep -Fxvf "${CHKSUM_FILE}" "${CHKSUM_FILE}.new" | sed 's/^[^ ]\+ //')
@ -60,9 +69,6 @@ do
# TODO Perform updates below conditionally too -------- # TODO Perform updates below conditionally too --------
# Also note that changes are performed in place and are not atomic # Also note that changes are performed in place and are not atomic
# We should fix that and write to temporary files, stop, swap and start # We should fix that and write to temporary files, stop, swap and start
# Lock configuration while working
(
flock -e 200
for FILE in ${CHANGED} for FILE in ${CHANGED}
do do
@ -226,11 +232,11 @@ s/$/ regexp:\/etc\/postfix\/regexp/
# prevent restart of dovecot when smtp_only=1 # prevent restart of dovecot when smtp_only=1
[[ ${SMTP_ONLY} -ne 1 ]] && supervisorctl restart dovecot [[ ${SMTP_ONLY} -ne 1 ]] && supervisorctl restart dovecot
) 200<postfix-accounts.cf # end lock fi
# mark changes as applied # mark changes as applied
mv "${CHKSUM_FILE}.new" "${CHKSUM_FILE}" mv "${CHKSUM_FILE}.new" "${CHKSUM_FILE}"
fi remove_lock "${SCRIPT_NAME}"
sleep 1 sleep 1
done done

View File

@ -15,7 +15,22 @@ function escape
echo "${1//./\\.}" echo "${1//./\\.}"
} }
# ? --------------------------------------------- IP & CIDR function create_lock
{
SCRIPT_NAME="$1"
LOCK_FILE="/tmp/docker-mailserver/${SCRIPT_NAME}.lock"
[[ -e "${LOCK_FILE}" ]] && errex "Lock file ${LOCK_FILE} exists. Another $1 execution is happening. Try again later."
trap remove_lock EXIT # This won't work if the script is, for example, check-for-changes.sh which uses a while loop to stay running; you'll need to include a remove_lock call at the end of your logic
touch "${LOCK_FILE}"
}
function remove_lock
{
SCRIPT_NAME=${SCRIPT_NAME:-$1}
rm -f "/tmp/docker-mailserver/${SCRIPT_NAME}.lock"
}
# ? IP & CIDR
function _mask_ip_digit function _mask_ip_digit
{ {

View File

@ -6,7 +6,13 @@
SCRIPT="lint.sh" SCRIPT="lint.sh"
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" if [[ "$(uname)" == "Darwin" ]]
then
readlink() {
greadlink "${@:+$@}" # Requires coreutils
}
fi
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
REPO_ROOT="$(realpath "${SCRIPT_DIR}"/../../)" REPO_ROOT="$(realpath "${SCRIPT_DIR}"/../../)"
HADOLINT_VERSION=2.4.1 HADOLINT_VERSION=2.4.1
@ -51,7 +57,7 @@ function __log_success
function __in_path function __in_path
{ {
command -v "${@}" &>/dev/null && return 0 ; return 1 ; command -v "${@:+$@}" &>/dev/null && return 0 ; return 1 ;
} }
function _eclint function _eclint
@ -142,4 +148,4 @@ function __main
esac esac
} }
__main "${@}" || exit ${?} __main "${@:+$@}" || exit ${?}