Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 41 additions & 16 deletions docker/openemr/flex/openemr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ is_configured() {

AUTHORITY=yes
OPERATOR=yes
SWARM_WAIT_DEFERRED=no

# Kubernetes-specific role assignment
if [[ "${K8S}" = "admin" ]]; then
Expand Down Expand Up @@ -377,17 +378,8 @@ update_leader_heartbeat() {
fi
}

# Handles swarm mode coordination: leader election and follower waiting.
handle_swarm_mode() {
# Skip coordination if swarm mode isn't enabled
if [[ "${SWARM_MODE}" != "yes" ]]; then
return 0
fi

# Try to become the leader
try_become_leader

# If we're a follower, wait for the leader to finish setup
# Waits for the swarm leader to finish setup before reading shared configuration.
wait_for_swarm_completion() {
if [[ "${AUTHORITY}" = "no" && ! -f "${OE_ROOT}/sites/docker-completed" ]]; then
echo "Waiting for docker-leader to finish configuration (with timeout-based recovery)..."
local -i max_wait_time="${LEADER_WAIT_TIMEOUT:-600}" # Default: 10 minutes
Expand All @@ -400,8 +392,8 @@ handle_swarm_mode() {
# shellcheck disable=SC2310 # set -e behavior in conditionals is intentional
if is_leader_stale; then
echo "Leader appears to have crashed, attempting to take over..."
# shellcheck disable=SC2310 # set -e behavior in conditionals is intentional
if try_become_leader; then
try_become_leader
if [[ "${AUTHORITY}" = "yes" ]]; then
echo "Successfully became leader after previous leader failure"
break
fi
Expand All @@ -412,8 +404,11 @@ handle_swarm_mode() {

# Try one more time to become leader (in case leader died just as we timed out)
# shellcheck disable=SC2310 # set -e behavior in conditionals is intentional
if [[ ! -f "${OE_ROOT}/sites/docker-completed" ]] && try_become_leader; then
echo "Promoted to leader after waiting period"
if [[ ! -f "${OE_ROOT}/sites/docker-completed" ]]; then
try_become_leader
if [[ "${AUTHORITY}" = "yes" ]]; then
echo "Promoted to leader after waiting period"
fi
fi

# If we timed out, check if configuration actually exists
Expand All @@ -427,8 +422,10 @@ handle_swarm_mode() {
fi
fi
fi
}

# If we're the leader, create initiation marker and send heartbeat
# If we're the leader, create initiation marker and restore swarm pieces.
prepare_swarm_leader() {
if [[ "${AUTHORITY}" = "yes" ]]; then
touch "${OE_ROOT}/sites/docker-initiated"
update_leader_heartbeat
Expand All @@ -445,6 +442,28 @@ handle_swarm_mode() {
fi
}

# Handles swarm mode coordination: leader election and follower waiting.
handle_swarm_mode() {
# Skip coordination if swarm mode isn't enabled
if [[ "${SWARM_MODE}" != "yes" ]]; then
return 0
fi

# Try to become the leader
try_become_leader

# Flex followers can prepare local source/dependencies while the leader
# configures the shared sites volume, then wait before reading sqlconf.php.
if [[ "${AUTHORITY}" = "no" && ! -f "${OE_ROOT}/sites/docker-completed" ]]; then
SWARM_WAIT_DEFERRED=yes
echo "Deferring docker-leader wait until local flex build is ready"
return 0
fi

wait_for_swarm_completion
prepare_swarm_leader
}

# ============================================================================
# SWARM MODE COORDINATION (MAIN EXECUTION)
# ============================================================================
Expand Down Expand Up @@ -687,6 +706,12 @@ if [[ "${NEED_COMPOSER_BUILD}" = "true" ]] || [[ "${NEED_NPM_BUILD}" = "true" ]]
cd /var/www/localhost/htdocs
fi

if [[ "${SWARM_WAIT_DEFERRED}" = "yes" ]]; then
wait_for_swarm_completion
SWARM_WAIT_DEFERRED=no
prepare_swarm_leader
fi

if [[ "${AUTHORITY}" = "yes" ]] ||
[[ "${SWARM_MODE}" != "yes" ]]; then
if [[ -f /var/www/localhost/htdocs/auto_configure.php ]] &&
Expand Down
10 changes: 10 additions & 0 deletions tests/bats/flex/openemr.bats
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ setup() {
[[ -n "$SCRIPT_DIR" ]] && [[ -d "$SCRIPT_DIR" ]]
}

@test "flex openemr.sh: valid bash syntax" {
assert_script_syntax "${SCRIPT_DIR}/openemr.sh"
}

@test "flex openemr.sh: FLEX_REPOSITORY and FLEX_REPOSITORY_BRANCH" {
assert_script_contains "${SCRIPT_DIR}/openemr.sh" 'FLEX_REPOSITORY'
assert_script_contains "${SCRIPT_DIR}/openemr.sh" 'FLEX_REPOSITORY_BRANCH'
Expand Down Expand Up @@ -35,6 +39,12 @@ setup() {
assert_script_contains "${SCRIPT_DIR}/openemr.sh" 'SWARM_MODE='
}

@test "flex openemr.sh: swarm follower defers leader wait for flex build" {
assert_script_contains "${SCRIPT_DIR}/openemr.sh" 'SWARM_WAIT_DEFERRED=yes'
assert_script_contains "${SCRIPT_DIR}/openemr.sh" 'Deferring docker-leader wait until local flex build is ready'
assert_script_contains "${SCRIPT_DIR}/openemr.sh" 'wait_for_swarm_completion'
}

@test "flex openemr.sh: INSANE_DEV_MODE or DEVELOPER_TOOLS" {
assert_script_contains "${SCRIPT_DIR}/openemr.sh" 'EASY_DEV_MODE_NEW'
grep -qE 'INSANE_DEV_MODE|DEVELOPER_TOOLS' "${SCRIPT_DIR}/openemr.sh"
Expand Down
Loading