~ salmonella-environment-setup (master) ac8cf03665f43e21a8b4294e30c79277ed32a920
commit ac8cf03665f43e21a8b4294e30c79277ed32a920
Author: Mario Domenech Goulart <mario@parenteses.org>
AuthorDate: Sat Apr 17 20:49:26 2021 +0200
Commit: Mario Domenech Goulart <mario@parenteses.org>
CommitDate: Sat Apr 17 20:49:29 2021 +0200
run-salmonella.sh: proper locking to prevent multiple instances
This change implements locking to prevent multiple simultaneous
executions of run-salmonella.sh.
Locks are created in /tmp. THe lock is a directory (salmonella-lock)
with a `pid' file which contains the process identifier of the running
process.
For debugging, `/tmp/salmonella-$$.log` files are created. They
contain information about locking events and are cleaned up upon
termination of run-salmonella.sh.
diff --git a/run-salmonella.sh b/run-salmonella.sh
index 8a7aaeb..a3cf665 100755
--- a/run-salmonella.sh
+++ b/run-salmonella.sh
@@ -5,7 +5,23 @@ SRC_CONF_DIR=$ROOT_DIR/conf
HOOKS_DIR=$ROOT_DIR/hooks
LOCAL_CONF_DIR=$HOME/.salmonella-run-publish
WORK_DIR=$HOME/salmonella/build
-LOG_DIR=$HOME/salmonella
+
+LOCK_DIR=/tmp/salmonella-lock
+LOCK_PID=/tmp/salmonella-lock/pid
+
+# Temporary log file. It won't be published as part of job artifacts.
+# It is mostly to log events related to locking.
+TMP_LOG_FILE=/tmp/salmonella-$$.log
+
+
+cleanup() {
+ rm -rf "$LOCK_DIR"
+ rm -f "$TMP_LOG_FILE"
+}
+
+
+trap cleanup EXIT INT TERM
+
usage() {
cat <<EOF
@@ -71,22 +87,19 @@ SETTINGS_FILES="\
run_hooks() {
# Call hooks scripts, passing $OS, $ARCH, CHICKEN_4_PREFIX and
# CHICKEN_5_PREFIX as arguments
- local hooks_logfile
local hook
local hook_dir
- hooks_logfile=${LOG_DIR}/hooks.log
-
- mkdir -p "$LOG_DIR"
- rm -f "$hooks_logfile"
+ mkdir -p "$WORK_DIR"
+ hooks_log_file=${WORK_DIR}/hooks.log
for hook_dir in "${HOOKS_DIR}/common" "${HOOKS_DIR}/${OS}" "${HOOKS_DIR}/${OS}/${ARCH}"
do
if [ -d "$hook_dir" ]; then
for hook in "${hook_dir}/"*; do
if [ -x "$hook" ]; then
- echo "=== Running hook $hook ===" >>"$hooks_logfile"
- "$hook" "$OS" "$ARCH" "$CHICKEN_4_PREFIX" "$CHICKEN_5_PREFIX" >>"$hooks_logfile" 2>&1
+ echo "=== Running hook $hook ===" > "$hooks_log_file"
+ "$hook" "$OS" "$ARCH" "$CHICKEN_4_PREFIX" "$CHICKEN_5_PREFIX" >>"$hooks_log_file" 2>&1
fi
done
fi
@@ -94,50 +107,35 @@ run_hooks() {
}
-main() {
+run_salmonella() {
+ local confs
confs=$@
- # Check if all conf files exist
- for conf in $confs; do
- if [ ! -e "$SRC_CONF_DIR/${conf}.conf" ]; then
- echo "No configuration file found for '$conf'. Aborting." >&2
- exit 1
- fi
- done
-
- mkdir -p "$LOG_DIR" "$WORK_DIR"
- local watchdog_logfile
- watchdog_logfile="$LOG_DIR/watchdog.log"
+ mkdir -p "$WORK_DIR"
# Run salmonella from $WORK_DIR
cd "$WORK_DIR"
- ### Prevent two salmonellas from running simultaneously
- while ps ax | grep '[s]almonella-run-publish'; do
- echo "[`date`] Salmonella still running" >> "$watchdog_logfile"
- # OpenBSD's sleep doesn't suffixes like `h' (hours) or `m' (minutes)
- sleep 3600
- done
-
- # Remove leftovers from previous executions
- rm -rf salmonella-run-publish
-
- # Create the directory for the log file
- mkdir -p "$RUN_SALMONELLA_TMP_DIR"
-
- # Load settings files
- local settings_file
- for settings_file in $SETTINGS_FILES; do
- if [ -e "$settings_file" ]; then
- info "Loading $settings_file"
- . "$settings_file"
- fi
- done
-
local salmonella_run_publish
salmonella_run_publish="$CHICKEN_TESTS_PREFIX/bin/salmonella-run-publish"
for conf in $confs; do
+
+ # Remove leftovers from previous executions. Once
+ # `$RUN_SALMONELLA_TMP_DIR` is created it is safe to use
+ # `info'.
+ rm -rf "$RUN_SALMONELLA_TMP_DIR"
+ mkdir -p "$RUN_SALMONELLA_TMP_DIR"
+
+ # Load settings files
+ local settings_file
+ for settings_file in $SETTINGS_FILES; do
+ if [ -e "$settings_file" ]; then
+ info "Loading $settings_file"
+ . "$settings_file"
+ fi
+ done
+
# The inline egg writes some stuff to the home dir
rm -rf ~/.chicken-inline
@@ -157,10 +155,46 @@ main() {
info "Loading $conf_path"
"$salmonella_run_publish" "$conf_path" >>"$log_file" 2>&1
fi
- [ -d salmonella-run-publish ] && mv salmonella-run-publish "salmonella-$conf"
+ [ -d "$RUN_SALMONELLA_TMP_DIR" ] &&
+ mv "$RUN_SALMONELLA_TMP_DIR" "salmonella-$conf"
done
}
+
+main() {
+ # Check if all conf files exist
+ local conf
+ for conf in $@; do
+ if [ ! -e "$SRC_CONF_DIR/${conf}.conf" ]; then
+ echo "No configuration file found for '$conf'. Aborting." >&2
+ exit 1
+ fi
+ done
+
+ while true; do
+ if mkdir "$LOCK_DIR" 2>/dev/null; then
+ echo $$ > "$LOCK_PID"
+ echo "[$(date)] $$ acquired lock" >> "$TMP_LOG_FILE"
+ run_salmonella "$@"
+ cleanup
+ exit
+ else
+ # Check if the lock is stale
+ local pid
+ pid=$(cat "$LOCK_PID")
+ if kill -0 "$pid" 2>/dev/null; then
+ echo "[$(date)] Waiting for $pid" >> "$TMP_LOG_FILE"
+ sleep 60
+ else
+ # Lock is stale. Cleanup and continue.
+ echo "[$(date)] Cleaning up stale lock (pid=$pid)" >> "$TMP_LOG_FILE"
+ cleanup
+ fi
+ fi
+ done
+}
+
+
if [ "$1" = "-h" ] || [ "$1" = "-help" ] || [ "$1" = "--help" ]; then
usage
exit 0
Trap