From 9a1254048e8f3a2e23656560b093c834f2349af9 Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Mon, 17 Aug 2026 11:57:46 -0400 Subject: [PATCH] Match the WebUI template by its XML Name element, and count the final sync on rsync's actual exit The lookup grepped for a quoted container name that appears in no Unraid template, so every offboard reported four WebUIs it could not reconfigure. The final sync counted a share synced whenever Tier 1 was on, ignoring rsync.sh's status entirely. --- Partnership/partnership_manager.sh | 29 ++++++++++++++++++++----- Plugin/unraid/Partnership/containers.sh | 8 ++++++- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/Partnership/partnership_manager.sh b/Partnership/partnership_manager.sh index b5bddda..e10e782 100755 --- a/Partnership/partnership_manager.sh +++ b/Partnership/partnership_manager.sh @@ -957,20 +957,37 @@ do_final_sync() { log "Running final critical sync..." local _synced=0 _failed=0 if [[ "$DRY_RUN" == false ]]; then - if [[ "${#CRITICAL_SYNC_SHARES[@]}" -gt 0 ]]; then + # Tier 1 only, deliberately. rsync.sh honours RSYNC_ENABLED and nothing else — the Tier 2 + # gates belong to the orchestrators, so a direct call like this one runs whether or not + # CRITICAL_RSYNC_ENABLED is set. Checking Tier 2 here would refuse a final sync that works + # perfectly well, and the offboard's whole reason for existing is to get current auth data + # onto the mirror before the keys go. + # + # What was wrong was the accounting below it: a share was counted synced whenever Tier 1 + # happened to be on, with rsync.sh's exit status ignored entirely. A transfer that failed + # on a full disk, an offline share or a refused connection still reported "Final sync ✅ + # — mirror has current state", which is the one claim in this script somebody acts on. + local _gate_ok=true + if [[ "${RSYNC_ENABLED:-true}" != true ]]; then + warn "RSYNC_ENABLED=false — Tier 1 stops every rsync, no share can be sent" + _gate_ok=false + fi + + if [[ "$_gate_ok" != true ]]; then + _failed=1 + elif [[ "${#CRITICAL_SYNC_SHARES[@]}" -gt 0 ]]; then for _share in "${CRITICAL_SYNC_SHARES[@]}"; do [[ -z "$_share" ]] && continue local _path="${_share%%|*}" local _profile="${_share##*|}" + # Count on what rsync.sh returned, now that a closed gate can no longer reach here. if [[ "$_path" == "$_profile" ]]; then bash "$SCRIPT_DIR/../Rsync/rsync.sh" "$_path" --log else bash "$SCRIPT_DIR/../Rsync/rsync.sh" "$_path" \ --profile="$_profile" --log fi - # rsync.sh exits 0 both on a real sync and on a clean Tier-1 gate exit, so the - # gate is checked here rather than inferred from its status. - if [[ "${RSYNC_ENABLED:-true}" == true ]]; then (( _synced++ )); else (( _failed++ )); fi + if [[ $? -eq 0 ]]; then (( _synced++ )) || true; else (( _failed++ )) || true; fi done else warn "CRITICAL_SYNC_SHARES is empty — skipping final sync (configure in host*.conf)" @@ -988,9 +1005,11 @@ do_final_sync() { warn "Final sync did NOT complete — $MIRROR leaves with whatever state it already had" [[ "${RSYNC_ENABLED:-true}" != true ]] && \ warn " RSYNC_ENABLED=false — the Tier 1 gate stopped it before any share was sent" + [[ "${CRITICAL_RSYNC_ENABLED:-true}" != true ]] && \ + warn " CRITICAL_RSYNC_ENABLED=false — the Tier 2 gate stopped it" return 1 fi - warn "Final sync complete — mirror has current state ✅" + echo "Final sync complete — $_synced share(s) sent, mirror has current state ✅" return 0 } diff --git a/Plugin/unraid/Partnership/containers.sh b/Plugin/unraid/Partnership/containers.sh index 2ff207b..77ba5e5 100755 --- a/Plugin/unraid/Partnership/containers.sh +++ b/Plugin/unraid/Partnership/containers.sh @@ -707,11 +707,17 @@ reconfigure_webui() { return 0 fi + # Match Authelia, not "Authelia". Unraid writes the container name as bare XML + # text, so the quoted form matched nothing in any template on any host — which is why every + # offboard ended with four "template not found ... WebUI needs manual reconfiguration" + # warnings and left the mirror's auth WebUIs pointing at the owner it had just left. + # + # xargs -r so an empty first grep does not run the second one against the whole directory. local template template=$(timeout "$SSH_TIMEOUT" ssh -i "$ssh_key" \ -o ConnectTimeout="$SSH_TIMEOUT" -o BatchMode=yes root@"$remote_ip" \ "grep -rl '' '$TEMPLATES_DIR/' 2>/dev/null | \ - xargs grep -l '\"$container\"' 2>/dev/null | head -1" 2>/dev/null) + xargs -r grep -l '$container' 2>/dev/null | head -1" 2>/dev/null) if [[ -z "$template" ]]; then warn "$container template not found on $label — WebUI needs manual reconfiguration"