chore(scripts): Removing flock so NFS works#1980
chore(scripts): Removing flock so NFS works#1980georglauterbach merged 27 commits intodocker-mailserver:masterfrom NorseGaud:issues/1979
Conversation
|
I'm not super proficient in shell scripts, but is it possible to be more DRY here by moving the if conditional logic that I'm seeing repeated in diffs into the helper util as well? Does it make more sense to wrap the logic in a function that can be passed into the helper util call along with the lock file name? |
This would require eval, but it's possible: example - Helpersfunction runWithLock() {
LOCK_FILE="/tmp/docker-mailserver/$1.lock"
if [[ ! -e "\${LOCK_FILE}" ]]; then
trap rmlock EXIT
touch $LOCK_FILE
eval "$2"
fi
}
function rmlock() {
rm -f "${LOCK_FILE}"
}addmailuser (and others)# Protect config file with lock to avoid race conditions
touch "${DATABASE}"
runWithLock "$(basename "$0")" "$(cat <<BLOCK
if grep -qi "^$(escape "${USER}")|" "${DATABASE}" 2>/dev/null
then
echo "User '${USER}' already exists."
exit 1
fi
if [[ -z ${PASSWD} ]]
then
read -r -s -p "Enter Password: " PASSWD
echo
[[ -z ${PASSWD} ]] && errex "Password must not be empty"
fi
HASH="$(doveadm pw -s SHA512-CRYPT -u "${USER}" -p "${PASSWD}")"
echo "${USER}|${HASH}" >> "${DATABASE}"
BLOCK
)"See any issues @polarathene ? |
I'm not really able to give a proper review regarding this unfortunately. @aendeavor or @casperklein are often working on the shell scripts for the project and can likely weigh in on what is preferred. @aendeavor especially makes an effort to have shell scripts meet certain guidelines, but is a bit busy with other commitments at present, so they may take a little longer to chime in with a review. |
|
Proposal, make two function: Why do you think eval() is needed? addmailuser: Also check, why the tests are failing. |
|
As @polarathene mentioned, I'm low on time, so I'll keep this short.
# Protect config file with lock to avoid race conditions
touch "${DATABASE}"
runWithLock "$(basename "$0")" "$(cat <<BLOCK
if grep -qi "^$(escape "${USER}")|" "${DATABASE}" 2>/dev/null
then
echo "User '${USER}' already exists."
exit 1
fi
if [[ -z ${PASSWD} ]]
then
read -r -s -p "Enter Password: " PASSWD
echo
[[ -z ${PASSWD} ]] && errex "Password must not be empty"
fi
HASH="$(doveadm pw -s SHA512-CRYPT -u "${USER}" -p "${PASSWD}")"
echo "${USER}|${HASH}" >> "${DATABASE}"
BLOCK
)"is not an option at all. One would use the Bash-idiomatic way for "function pointers": touch "${DATABASE}"
function __admailuser
{
if grep -qi "^$(escape "${USER}")|" "${DATABASE}" 2>/dev/null
then
echo "User '${USER}' already exists."
exit 1
fi
if [[ -z ${PASSWD} ]]
then
read -r -s -p "Enter Password: " PASSWD
echo
[[ -z ${PASSWD} ]] && errex "Password must not be empty"
fi
HASH="$(doveadm pw -s SHA512-CRYPT -u "${USER}" -p "${PASSWD}")"
echo "${USER}|${HASH}" >> "${DATABASE}"
}
# Protect config file with lock to avoid race conditions
runWithLock "$(basename "$0")" "$(declare -f __addmailuser)"
|
Wouldn't this exit early if the lock cannot be obtained? We should make this more like a spin-lock with exists after trying too often. |
|
Thanks, Georg (@aendeavor). I appreciate you taking the time! I won't answer some of your points as they are not relevant for the hacked together example I provided. However, I do like passing in of the function with declare. Ultimately, the function supports either your recommended function-based idiomatic approach or the one I provided, so it remains flexible (using HEREDOC is something I don't really care about so I'll avoid it). However, Let me know what you think and I can rework the code to support this and test it thoroughly. Lastly, I don't think the test failure is due to changes I made, but I could be wrong. I'll check again after the final code. |
|
I know what |
Oh, there must be a misunderstanding on my part. There isn't a need to do it. I also like a spin-lock approach. I'll update the code with the recommended approach. |
|
Is it weird that ec linting wanted... ... when those lines use the same indentation that all other functions use (a single tab indent)? Now it just looks weird: |
Yes, but that is the intention of a lock? If it cannot be obtained, then abort. If it would continue never the less, then why using locks at all? |
@casperklein @aendeavor , should I ditch the spin-lock? It seems as if failing immediately is far less logic and the user could just retry. |
I will leave this up to you guys. I like the spinlock, but it may be overkill. Contact me if there is something very urgent :D PS: @NorseGaud Styling is now on point, good job! |
ack 👍 |
|
Hey @casperklein, any recommendations for #1980 (comment) ? |
|
Ok, ran some tests and this seems to be working great. EFS mounted using NFS4.1: Default state: Added test user: Deleting test user: Then I added I also see the check-for-changes.lock being created when the checksum file exists: I'm continuing to check the various places that locks are used and even setting up multiple machines to which I'll issue concurrent commands and make sure the locking works. |
|
Tests with two servers and an EFS NFS4.1 mount looks great: Add + Del UserSet quotaUpdate emailReady for review! |
| echo "${USER}|${HASH}" >> "${DATABASE}" | ||
| ) 200< "${DATABASE}" | ||
| create_lock "$(basename "$0")" | ||
| if grep -qi "^$(escape "${FULL_EMAIL}")|" "${DATABASE}" 2>/dev/null |
There was a problem hiding this comment.
2>/dev/null
Why? Is this, when $DATABASE does not exist yet or what should be catched here?
There was a problem hiding this comment.
Probably. Although this should never happen, since there is always a touch $DATABASE beforehand, right?
There was a problem hiding this comment.
Hey Casper, that line was actually already in the script before I modified it for the lock. Not sure I can answer your question :(
There was a problem hiding this comment.
No problem. But every time something is changed, I try to take the opportunity to review the whole file. If we all agree/think it's not necessary, i would remove it.
There was a problem hiding this comment.
@casperklein awesome, so if grep -qi "^$(escape "${FULL_EMAIL}")|" "${DATABASE}" 2>/dev/null now becomes if grep -qi "^$(escape "${FULL_EMAIL}")|" "${DATABASE}" ?
georglauterbach
left a comment
There was a problem hiding this comment.
LGTM but wee need to resolve the "issues" @casperklein pointed out with his comments first :)
Great work so far!
|
@NorseGaud not sure whether reviews will be dismissed if you do the rebase? Shall I update the branch? |
Sure, I would appreciate it (I'm traveling) 🙂 |
|
@NorseGaud See my last two little comments. Beside that, this PR looks great 👍 |
d93c262
|
Thanks y'all! |









BLOCKERS TO MERGING THIS PR (respectively ordered)
Description
#1979
cmpchecks could return a failure for any reason so we should check specifically for exit code 1 as that indicates that it's actually a failure due to differencesType of change
Checklist:
docs/)