Add flock-based locking to prevent concurrent service operations
This commit is contained in:
@@ -180,5 +180,17 @@ _root_remove_tree() {
|
||||
docker run --rm -v "$abs_parent":/data alpine rm -rf "/data/$child"
|
||||
}
|
||||
|
||||
# Acquires an exclusive lock on a service directory to prevent concurrent operations.
|
||||
# Uses flock() which is automatically released when the process exits (even on crash/SIGKILL).
|
||||
_lock_service() {
|
||||
local service_dir="$1"
|
||||
local lockfile="${service_dir}/.deploy.lock"
|
||||
mkdir -p "${service_dir}"
|
||||
exec 200>"${lockfile}"
|
||||
if ! flock -n 200; then
|
||||
_die "Another operation is already running on this service. Aborting."
|
||||
fi
|
||||
}
|
||||
|
||||
# Load autocommands
|
||||
source "${AGENT_PATH}/datacommands_v2.sh"
|
||||
@@ -45,6 +45,10 @@ export TEMP_DIR="${2:-}"
|
||||
export DOCKER_CLI_HINTS=false
|
||||
|
||||
SERVICE_DIR="${DROPSHELL_DIR}/services/${SERVICE}"
|
||||
|
||||
# -- Acquire exclusive lock (released automatically on exit) --
|
||||
_lock_service "${SERVICE_DIR}"
|
||||
|
||||
LIVE_CONFIG="${SERVICE_DIR}/config"
|
||||
LIVE_TEMPLATE="${SERVICE_DIR}/template"
|
||||
STAGING_DIR="${SERVICE_DIR}/_staging"
|
||||
|
||||
@@ -77,6 +77,9 @@ export TEMPLATE_PATH="${DROPSHELL_DIR}/services/${SERVICE}/template"
|
||||
[[ -f "${DROPSHELL_DIR}/server_info.env" ]] || _die "Missing ${DROPSHELL_DIR}/server_info.env"
|
||||
[[ -d "${CONFIG_PATH}" ]] || _die "Service '${SERVICE}' does not exist on server (missing ${CONFIG_PATH})"
|
||||
|
||||
# -- Acquire exclusive lock (released automatically on exit) --
|
||||
_lock_service "${DROPSHELL_DIR}/services/${SERVICE}"
|
||||
|
||||
# -- Load template info (template defaults, loaded first) --
|
||||
export TEMPLATE_INFO_ENV="${TEMPLATE_PATH}/template_info.env"
|
||||
if [[ ! -f "${TEMPLATE_INFO_ENV}" ]]; then
|
||||
|
||||
Reference in New Issue
Block a user