Fix the offboard calling rsync_stop.sh at a path that has never existed, and stop the summary contradicting its own steps

Step 1 printed 'Rsync stopped' over a file-not-found, and the closing block asserted a clean separation and a synced auth config regardless of what happened.
This commit is contained in:
Gmer4Lfe
2026-08-17 10:04:08 -04:00
parent 24e347bb2d
commit 51125fa05a
+74 -7
View File
@@ -173,6 +173,7 @@ STEP_REMOTE_CLEANUP_OK=true # or "skipped" when the mirror is unreachable
STEP_MIRROR_STACK_OK=true # or "skipped"
STEP_STATE_WRITE_OK=true
STEP_STATE_PUSH_OK=false # INACTIVE actually delivered to the mirror, or "skipped"
STEP_SETUP_PUSH_OK=false # cleared phase flags delivered to the mirror, or "skipped"
FILTERED_ARGS=()
for arg in "$@"; do
@@ -255,6 +256,24 @@ echo ""
# ==============================================================================================
_VV_SYNC_GATES=(RSYNC_ENABLED CRITICAL_RSYNC_ENABLED CONF_SYNC_ENABLED ARR_SYNC_ENABLED)
# ── Stop any running rsync, and say honestly whether it worked ────────────────────────────────
#
# Both offboard paths called "$SCRIPTS_ROOT/Rsync/rsync_stop.sh". That file has never existed —
# rsync_stop.sh lives in System_Essentials/. With stderr sent to /dev/null the "No such file"
# went unseen, and the line below it printed "Rsync stopped ✅" unconditionally, so every
# offboard ever run reported stopping an rsync it had not touched. On the owner path the failed
# exit also set STEP_STOP_OK=false, which is why the summary said ❌ two lines under a ✅.
#
# One helper, one path, and the outcome is the return value.
stop_rsync_now() {
local script="$SCRIPTS_ROOT/System_Essentials/rsync_stop.sh"
if [[ ! -f "$script" ]]; then
warn "rsync_stop.sh not found at $script"
return 1
fi
bash "$script" --rsync-only
}
_disarm_sync_gates() {
local gate rc=0 conf="$SCRIPTS_ROOT/Configurations/master.conf"
for gate in "${_VV_SYNC_GATES[@]}"; do
@@ -357,8 +376,12 @@ if [[ "$AM_MIRROR" == true ]]; then
echo "━━━ $ICON_STOP Step 1/8 — Stop Rsync ━━━"
if [[ "$DRY_RUN" == false ]]; then
bash "$SCRIPTS_ROOT/Rsync/rsync_stop.sh" --rsync-only 2>/dev/null || true
if stop_rsync_now; then
echo "Rsync stopped ✅"
else
warn "Could not stop rsync — a transfer may still be running into $OWNER"
STEP_STOP_RSYNC_OK=false
fi
else
warn "DRY RUN — would stop rsync"
fi
@@ -506,8 +529,14 @@ echo ""
echo "━━━ $ICON_STOP Step 1/10 — Stop Rsync ━━━"
if [[ "$DRY_RUN" == false ]]; then
bash "$SCRIPTS_ROOT/Rsync/rsync_stop.sh" --rsync-only 2>/dev/null || STEP_STOP_OK=false
if stop_rsync_now; then
echo "Rsync stopped ✅"
else
warn "Could not stop rsync — a transfer may still be running into $MIRROR"
warn " Everything below changes state while data is still moving, which is the one"
warn " ordering this step exists to prevent. Check: ps -ef | grep rsync"
STEP_STOP_OK=false
fi
else
warn "DRY RUN — would stop rsync"
fi
@@ -637,10 +666,21 @@ if [[ "$DRY_RUN" == false ]]; then
unset _setup_db _flag
if [[ "$MIRROR_REACHABLE" == true ]]; then
# Two separate pushes, and the summary used to report only the second. A run where the
# setup.db push failed and the state-file push succeeded printed "Could not push state
# file to remote" in the body and "Pushed to mirror: ✅" in the summary — describing
# different files with the same words. They are tracked apart now, because they fail
# apart: the mirror can be told the partnership is INACTIVE while keeping the phase
# flags that make its own UI still claim a finished onboard.
#
# Pushed after the flags are cleared, so the mirror receives the cleared file rather than
# the version that still claimed a finished onboard.
platform_push_setup_state 2>/dev/null || \
warn "Could not push cleared setup state to $MIRROR"
if platform_push_setup_state 2>/dev/null; then
STEP_SETUP_PUSH_OK=true
else
warn "Could not push cleared phase flags to $MIRROR — its wizard and partnership"
warn " card will keep showing a completed onboard until it is reinstalled or pulled"
fi
if push_state_to_remote "$LOCAL_STATE_FILE" "$MIRROR_IP" "$MIRROR_SSH_KEY"; then
STEP_STATE_PUSH_OK=true
else
@@ -648,10 +688,12 @@ if [[ "$DRY_RUN" == false ]]; then
fi
else
STEP_STATE_PUSH_OK=skipped
STEP_SETUP_PUSH_OK=skipped
fi
else
warn "DRY RUN — would write INACTIVE state, blocklist $MIRROR, push to remote"
STEP_STATE_PUSH_OK=true
STEP_SETUP_PUSH_OK=true
fi
# ── Step 11: SSH key revocation ───────────────────────────────────────────────────────────────
@@ -751,7 +793,8 @@ echo " Step 7 — Remote cleanup: $( [[ "$STEP_REMOTE_CLEANUP_OK" == skipped ]
echo " Step 8 — Mirror stack: $( [[ "$STEP_MIRROR_STACK_OK" == skipped ]] && echo "skipped (unreachable)" || { [[ "$STEP_MIRROR_STACK_OK" == true ]] && echo "started ✅" || echo "⚠️ check warnings above"; } )"
echo " Step 9 — Emby revoked: $(_ok "${STEP_EMBY_OK:-true}")"
echo " Step 10 — State: $( [[ "$STEP_STATE_WRITE_OK" == true ]] && echo "INACTIVE ✅" || echo "⚠️ WRITE FAILED — still looks ACTIVE here" )"
echo " Step 10 — Pushed to mirror: $( [[ "$STEP_STATE_PUSH_OK" == skipped ]] && echo "skipped (unreachable)" || { [[ "$STEP_STATE_PUSH_OK" == true ]] && echo "✅" || echo "⚠️ $MIRROR still reads ACTIVE"; } )"
echo " Step 10 — INACTIVE pushed: $( [[ "$STEP_STATE_PUSH_OK" == skipped ]] && echo "skipped (unreachable)" || { [[ "$STEP_STATE_PUSH_OK" == true ]] && echo "✅" || echo "⚠️ $MIRROR still reads ACTIVE"; } )"
echo " Step 10 — Phase flags pushed: $( [[ "$STEP_SETUP_PUSH_OK" == skipped ]] && echo "skipped (unreachable)" || { [[ "$STEP_SETUP_PUSH_OK" == true ]] && echo "✅" || echo "⚠️ $MIRROR still shows a finished onboard"; } )"
echo " Step 11 — Keys revoked: $(_revoke_status)"
echo ""
echo " Blocklist: $MIRROR blocked — re-onboard to permit access again ✅"
@@ -768,11 +811,35 @@ fi
echo " FALLBACK_ENABLED is still true — nothing left to fail over to, turn it off yourself"
echo ""
echo " $MIRROR leaves with:"
# Each line reads the step that produced it. "✓ Current auth config (final sync)" was a
# literal, so an offboard whose Step 2 had just warned "Final sync did NOT complete" still
# closed by telling the operator the mirror held current auth data. That is the one claim here
# somebody might act on — it is the difference between a partner that can stand alone and one
# carrying a stale copy of the auth stack.
if [[ "$STEP_SYNC_OK" == true ]]; then
echo " ✓ Current auth config (final sync)"
else
echo " ✗ Auth config NOT synced — it keeps whatever it already had (see Step 2)"
fi
if [[ "${WEBUI_FAILURES:-0}" -eq 0 ]]; then
echo " ✓ Auth WebUIs → localhost"
else
echo "${WEBUI_FAILURES} auth WebUI(s) still point at $LOCAL_SERVER_NAME — fix by hand there"
fi
echo "${PARTNERSHIP_GRACE_HOURS:-6}hr to collect backups"
echo ""
[[ "$DRY_RUN" == true ]] && warn "DRY RUN — no changes made" || \
warn "$ICON_DONE DONE — clean separation complete ✅"
# The verdict is derived, never asserted. "DONE — clean separation complete ✅" printed
# unconditionally, under a summary that had already shown two failed steps.
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — no changes made"
elif [[ "$STEP_STOP_OK" == true && "$STEP_SYNC_OK" == true \
&& "$STEP_STATE_PUSH_OK" != false && "$STEP_SETUP_PUSH_OK" != false \
&& "${WEBUI_FAILURES:-0}" -eq 0 ]]; then
echo "$ICON_DONE DONE — clean separation complete ✅"
else
warn "$ICON_DONE Offboard finished with unresolved steps — the partnership is ended, but"
warn " the ❌ lines above did not happen. Re-read them before re-onboarding."
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━"
exit 0