Send the webhook setup to the path the partner actually uses, and arm the sync gates before the seed that depends on them
This commit is contained in:
@@ -32,11 +32,13 @@
|
|||||||
# Step 8: Partnership onboard — configure WebUIs → owner IP, write state, Emby
|
# Step 8: Partnership onboard — configure WebUIs → owner IP, write state, Emby
|
||||||
# Step 9: Arr bootstrap — bidirectional library sync (arr_sync.sh)
|
# Step 9: Arr bootstrap — bidirectional library sync (arr_sync.sh)
|
||||||
# Step 9b: Webhook setup — register download webhook in arrs on both servers
|
# Step 9b: Webhook setup — register download webhook in arrs on both servers
|
||||||
# Step 9c: Media seed — rsync all DAILY_SYNC_SHARES to mirror (--seed)
|
# Step 9c: Arm sync gates — open RSYNC/CONF_SYNC/ARR_SYNC in master.conf, which the
|
||||||
|
# template ships closed so a fresh node cannot sync early.
|
||||||
|
# Ahead of the seed because the seed is itself an rsync and
|
||||||
|
# Tier 1 stops every rsync, including that one
|
||||||
|
# Step 9d: Media seed — rsync all DAILY_SYNC_SHARES to mirror (--seed)
|
||||||
# prevents arrs treating every file as missing after bootstrap
|
# prevents arrs treating every file as missing after bootstrap
|
||||||
# Step 9d: Webhook listener — start listener on mirror (runs continuously, no reboot needed)
|
# Step 9e: Webhook listener — start listener on mirror (runs continuously, no reboot needed)
|
||||||
# Step 9e: Arm sync gates — open RSYNC/CONF_SYNC/ARR_SYNC in master.conf, which the
|
|
||||||
# template ships closed so a fresh node cannot sync early
|
|
||||||
# Step 10: Conf push — push master.conf + setup state to all listed hosts
|
# Step 10: Conf push — push master.conf + setup state to all listed hosts
|
||||||
#
|
#
|
||||||
# ==============================================================================================
|
# ==============================================================================================
|
||||||
@@ -153,15 +155,15 @@
|
|||||||
# Skip webhook registration in arrs (Step 9b)
|
# Skip webhook registration in arrs (Step 9b)
|
||||||
#
|
#
|
||||||
# Partnership/partnership_onboard.sh --skip-media-seed
|
# Partnership/partnership_onboard.sh --skip-media-seed
|
||||||
# Skip initial media share rsync to mirror (Step 9c)
|
# Skip initial media share rsync to mirror (Step 9d)
|
||||||
# Use when mirror already has files or you want to seed manually
|
# Use when mirror already has files or you want to seed manually
|
||||||
#
|
#
|
||||||
# Partnership/partnership_onboard.sh --skip-webhook-listener
|
# Partnership/partnership_onboard.sh --skip-webhook-listener
|
||||||
# Skip starting webhook listener on mirror (Step 9d)
|
# Skip starting webhook listener on mirror (Step 9e)
|
||||||
# Listener will start automatically on next array restart
|
# Listener will start automatically on next array restart
|
||||||
#
|
#
|
||||||
# Partnership/partnership_onboard.sh --no-arm
|
# Partnership/partnership_onboard.sh --no-arm
|
||||||
# Leave RSYNC_ENABLED / CONF_SYNC_ENABLED / ARR_SYNC_ENABLED as they are (Step 9e).
|
# Leave RSYNC_ENABLED / CONF_SYNC_ENABLED / ARR_SYNC_ENABLED as they are (Step 9c).
|
||||||
# Use when onboarding a node you want to keep inert — a rebuild test, or a mirror whose
|
# Use when onboarding a node you want to keep inert — a rebuild test, or a mirror whose
|
||||||
# shares are not populated yet.
|
# shares are not populated yet.
|
||||||
#
|
#
|
||||||
@@ -196,7 +198,7 @@ SKIP_WEBHOOK_LISTENER=false
|
|||||||
PHASE1_ONLY=false # OWNER: SSH + conf push only (HOST2 not yet installed)
|
PHASE1_ONLY=false # OWNER: SSH + conf push only (HOST2 not yet installed)
|
||||||
# MIRROR: SSH key install only, no owner notification
|
# MIRROR: SSH key install only, no owner notification
|
||||||
PHASE2_ONLY=false # OWNER: containers/arr/onboard only (triggered by HOST2 after it onboards)
|
PHASE2_ONLY=false # OWNER: containers/arr/onboard only (triggered by HOST2 after it onboards)
|
||||||
SKIP_ARM=false # leave the sync gates as they are — see Step 9e
|
SKIP_ARM=false # leave the sync gates as they are — see Step 9c
|
||||||
FILTERED_ARGS=()
|
FILTERED_ARGS=()
|
||||||
|
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
@@ -799,67 +801,7 @@ else
|
|||||||
fi
|
fi
|
||||||
unset _webhook_script
|
unset _webhook_script
|
||||||
|
|
||||||
# ── Step 9c: Seed media shares on mirror ─────────────────────────────────────────────────────
|
# ── Step 9c: Arm the sync gates ───────────────────────────────────────────────────────────────
|
||||||
# arr_sync.sh bootstrapped the databases — mirror's arrs now know about all content but
|
|
||||||
# have no files on disk. Without this rsync, every imported item looks missing and arrs
|
|
||||||
# will immediately queue searches. --seed skips the empty-remote guard and does a clean push.
|
|
||||||
echo ""
|
|
||||||
echo "━━━ Step 9c — Media Share Seed ━━━"
|
|
||||||
|
|
||||||
if [[ "$SKIP_MEDIA_SEED" == true ]]; then
|
|
||||||
warn "Skipping (--skip-media-seed)"
|
|
||||||
elif [[ "${#DAILY_SYNC_SHARES[@]}" -eq 0 ]]; then
|
|
||||||
warn "DAILY_SYNC_SHARES empty for $MY_ID — skipping media seed"
|
|
||||||
warn "Configure HOST${MY_ID: -1}_DAILY_SYNC_SHARES in host${MY_ID: -1}.conf and run Rsync/rsync.sh --seed manually"
|
|
||||||
else
|
|
||||||
echo " Seeding ${#DAILY_SYNC_SHARES[@]} share(s) to $MIRROR — this may take a while"
|
|
||||||
_rsync_script="$SCRIPTS_ROOT/Rsync/rsync.sh"
|
|
||||||
_seed_flags=(--seed)
|
|
||||||
[[ "$DRY_RUN" == true ]] && _seed_flags+=(--dry-run)
|
|
||||||
[[ "$ENABLE_LOGGING" == true ]] && _seed_flags+=(--log)
|
|
||||||
for _share in "${DAILY_SYNC_SHARES[@]}"; do
|
|
||||||
echo " Seeding: $_share"
|
|
||||||
if bash "$_rsync_script" "$_share" "${_seed_flags[@]}"; then
|
|
||||||
(( MEDIA_SEED_COUNT++ )) || true
|
|
||||||
else
|
|
||||||
warn " Seed failed for $_share — re-run: Rsync/rsync.sh $_share --seed"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [[ "$MEDIA_SEED_COUNT" -gt 0 ]]; then
|
|
||||||
echo "Media seed complete — ${MEDIA_SEED_COUNT}/${#DAILY_SYNC_SHARES[@]} share(s) ✅"
|
|
||||||
MEDIA_SEED_OK=true
|
|
||||||
else
|
|
||||||
warn "Media seed: no shares completed — check errors above"
|
|
||||||
fi
|
|
||||||
unset _rsync_script _seed_flags _share
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ── Step 9d: Start webhook listener on mirror ─────────────────────────────────────────────────
|
|
||||||
# Listener is in ARRAY_START_SCRIPTS so it starts on next boot, but the mirror's array is
|
|
||||||
# already running — kick it now so events are captured immediately after onboard.
|
|
||||||
echo ""
|
|
||||||
echo "━━━ Step 9d — Webhook Listener (Mirror) ━━━"
|
|
||||||
|
|
||||||
_listener_script="$SCRIPTS_ROOT/Arrs_Stack/start_webhook_listener.sh"
|
|
||||||
if [[ "$SKIP_WEBHOOK_LISTENER" == true ]]; then
|
|
||||||
warn "Skipping (--skip-webhook-listener)"
|
|
||||||
elif [[ "${WEBHOOK_PORT:-0}" -eq 0 ]]; then
|
|
||||||
warn "WEBHOOK_PORT=0 — webhook disabled, skipping"
|
|
||||||
elif [[ "$DRY_RUN" == true ]]; then
|
|
||||||
warn "DRY RUN — would start webhook listener on $MIRROR"
|
|
||||||
WEBHOOK_LISTENER_OK=true
|
|
||||||
elif timeout "$SSH_TIMEOUT" ssh -i "$MIRROR_SSH_KEY" \
|
|
||||||
-o ConnectTimeout="$SSH_TIMEOUT" -o BatchMode=yes root@"$MIRROR_IP" \
|
|
||||||
"nohup bash '$_listener_script' > /var/log/varaverk/upgrade_webhook.log 2>&1 & echo started" \
|
|
||||||
2>/dev/null | grep -q started; then
|
|
||||||
echo "Webhook listener started on $MIRROR ✅"
|
|
||||||
WEBHOOK_LISTENER_OK=true
|
|
||||||
else
|
|
||||||
warn "Could not start listener on $MIRROR — it will start automatically on next array restart"
|
|
||||||
fi
|
|
||||||
unset _listener_script
|
|
||||||
|
|
||||||
# ── Step 9e: Arm the sync gates ───────────────────────────────────────────────────────────────
|
|
||||||
# master.conf.template ships a fresh node inert — RSYNC_ENABLED, CONF_SYNC_ENABLED and
|
# master.conf.template ships a fresh node inert — RSYNC_ENABLED, CONF_SYNC_ENABLED and
|
||||||
# ARR_SYNC_ENABLED all false — because a node that has just been seeded has empty shares and no
|
# ARR_SYNC_ENABLED all false — because a node that has just been seeded has empty shares and no
|
||||||
# verified partner, and those two facts are what make unattended syncing safe to do.
|
# verified partner, and those two facts are what make unattended syncing safe to do.
|
||||||
@@ -868,14 +810,19 @@ unset _listener_script
|
|||||||
# one-way door: the node stayed inert for ever and somebody had to remember to hand-edit three
|
# one-way door: the node stayed inert for ever and somebody had to remember to hand-edit three
|
||||||
# toggles, on the machine where forgetting looks exactly like everything working.
|
# toggles, on the machine where forgetting looks exactly like everything working.
|
||||||
#
|
#
|
||||||
# Runs before Step 10 on purpose. The push carries the owner's master.conf to every listed host,
|
# Ahead of the media seed, which it used to follow. The seed calls Rsync/rsync.sh, and Tier 1
|
||||||
# so arming here means both sides come up agreeing about whether sync is on; arming after the
|
# stops *every* rsync — so with the gates still closed all of it exited cleanly having moved
|
||||||
# push would leave the mirror a version behind until the next conf save.
|
# nothing, and, because a clean exit is exit 0, the seed counted each share as a success and
|
||||||
|
# reported "14/14 shares ✅" over an empty mirror.
|
||||||
|
#
|
||||||
|
# Still ahead of Step 10 on purpose. The push carries the owner's master.conf to every listed
|
||||||
|
# host, so arming before it means both sides come up agreeing about whether sync is on; arming
|
||||||
|
# after the push would leave the mirror a version behind until the next conf save.
|
||||||
#
|
#
|
||||||
# Owner only — the mirror receives these values in the push rather than deciding for itself.
|
# Owner only — the mirror receives these values in the push rather than deciding for itself.
|
||||||
ARM_OK=true
|
ARM_OK=true
|
||||||
echo ""
|
echo ""
|
||||||
echo "━━━ $ICON_GEAR Step 9e — Arm Sync Gates ━━━"
|
echo "━━━ $ICON_GEAR Step 9c — Arm Sync Gates ━━━"
|
||||||
|
|
||||||
if [[ "$ONBOARD_OK" == false ]]; then
|
if [[ "$ONBOARD_OK" == false ]]; then
|
||||||
warn "Skipping — onboard did not complete, leaving the gates closed"
|
warn "Skipping — onboard did not complete, leaving the gates closed"
|
||||||
@@ -903,6 +850,82 @@ else
|
|||||||
unset _master_conf
|
unset _master_conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ── Step 9d: Seed media shares on mirror ─────────────────────────────────────────────────────
|
||||||
|
# arr_sync.sh bootstrapped the databases — mirror's arrs now know about all content but
|
||||||
|
# have no files on disk. Without this rsync, every imported item looks missing and arrs
|
||||||
|
# will immediately queue searches. --seed skips the empty-remote guard and does a clean push.
|
||||||
|
echo ""
|
||||||
|
echo "━━━ Step 9d — Media Share Seed ━━━"
|
||||||
|
|
||||||
|
# Read the gate back off disk rather than trusting the value sourced at startup: Step 9c has
|
||||||
|
# just rewritten master.conf, and each rsync.sh below is a separate process that will source
|
||||||
|
# the file fresh. A closed gate here means every share would exit 0 having moved nothing, so
|
||||||
|
# say so once and skip, instead of counting fourteen no-ops as fourteen successes.
|
||||||
|
#
|
||||||
|
# The trailing comment is cut before the value is read. master.conf writes this gate as
|
||||||
|
# RSYNC_ENABLED=true # Tier 1 — global gate, overrides everything below
|
||||||
|
# so stopping at `cut -d= -f2` and squeezing whitespace yields "true#Tier1—globalgate,…",
|
||||||
|
# which is not "true" — and the seed would then skip itself on every single run, including
|
||||||
|
# the ones where the gate is open.
|
||||||
|
_rsync_gate=$(grep -m1 -E '^[[:space:]]*RSYNC_ENABLED=' "$SCRIPTS_ROOT/Configurations/master.conf" 2>/dev/null \
|
||||||
|
| cut -d= -f2- | cut -d'#' -f1 | tr -d '"'"'" | tr -d '[:space:]')
|
||||||
|
|
||||||
|
if [[ "$SKIP_MEDIA_SEED" == true ]]; then
|
||||||
|
warn "Skipping (--skip-media-seed)"
|
||||||
|
elif [[ "$DRY_RUN" == false && "$_rsync_gate" != "true" ]]; then
|
||||||
|
warn "RSYNC_ENABLED is '$_rsync_gate' — skipping media seed, rsync.sh would move nothing"
|
||||||
|
warn "Arm it and re-run: Rsync/rsync.sh <share> --seed"
|
||||||
|
elif [[ "${#DAILY_SYNC_SHARES[@]}" -eq 0 ]]; then
|
||||||
|
warn "DAILY_SYNC_SHARES empty for $MY_ID — skipping media seed"
|
||||||
|
warn "Configure HOST${MY_ID: -1}_DAILY_SYNC_SHARES in host${MY_ID: -1}.conf and run Rsync/rsync.sh --seed manually"
|
||||||
|
else
|
||||||
|
echo " Seeding ${#DAILY_SYNC_SHARES[@]} share(s) to $MIRROR — this may take a while"
|
||||||
|
_rsync_script="$SCRIPTS_ROOT/Rsync/rsync.sh"
|
||||||
|
_seed_flags=(--seed)
|
||||||
|
[[ "$DRY_RUN" == true ]] && _seed_flags+=(--dry-run)
|
||||||
|
[[ "$ENABLE_LOGGING" == true ]] && _seed_flags+=(--log)
|
||||||
|
for _share in "${DAILY_SYNC_SHARES[@]}"; do
|
||||||
|
echo " Seeding: $_share"
|
||||||
|
if bash "$_rsync_script" "$_share" "${_seed_flags[@]}"; then
|
||||||
|
(( MEDIA_SEED_COUNT++ )) || true
|
||||||
|
else
|
||||||
|
warn " Seed failed for $_share — re-run: Rsync/rsync.sh $_share --seed"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ "$MEDIA_SEED_COUNT" -gt 0 ]]; then
|
||||||
|
echo "Media seed complete — ${MEDIA_SEED_COUNT}/${#DAILY_SYNC_SHARES[@]} share(s) ✅"
|
||||||
|
MEDIA_SEED_OK=true
|
||||||
|
else
|
||||||
|
warn "Media seed: no shares completed — check errors above"
|
||||||
|
fi
|
||||||
|
unset _rsync_script _seed_flags _share
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Step 9e: Start webhook listener on mirror ─────────────────────────────────────────────────
|
||||||
|
# Listener is in ARRAY_START_SCRIPTS so it starts on next boot, but the mirror's array is
|
||||||
|
# already running — kick it now so events are captured immediately after onboard.
|
||||||
|
echo ""
|
||||||
|
echo "━━━ Step 9e — Webhook Listener (Mirror) ━━━"
|
||||||
|
|
||||||
|
_listener_script="$SCRIPTS_ROOT/Arrs_Stack/start_webhook_listener.sh"
|
||||||
|
if [[ "$SKIP_WEBHOOK_LISTENER" == true ]]; then
|
||||||
|
warn "Skipping (--skip-webhook-listener)"
|
||||||
|
elif [[ "${WEBHOOK_PORT:-0}" -eq 0 ]]; then
|
||||||
|
warn "WEBHOOK_PORT=0 — webhook disabled, skipping"
|
||||||
|
elif [[ "$DRY_RUN" == true ]]; then
|
||||||
|
warn "DRY RUN — would start webhook listener on $MIRROR"
|
||||||
|
WEBHOOK_LISTENER_OK=true
|
||||||
|
elif timeout "$SSH_TIMEOUT" ssh -i "$MIRROR_SSH_KEY" \
|
||||||
|
-o ConnectTimeout="$SSH_TIMEOUT" -o BatchMode=yes root@"$MIRROR_IP" \
|
||||||
|
"nohup bash '$_listener_script' > /var/log/varaverk/upgrade_webhook.log 2>&1 & echo started" \
|
||||||
|
2>/dev/null | grep -q started; then
|
||||||
|
echo "Webhook listener started on $MIRROR ✅"
|
||||||
|
WEBHOOK_LISTENER_OK=true
|
||||||
|
else
|
||||||
|
warn "Could not start listener on $MIRROR — it will start automatically on next array restart"
|
||||||
|
fi
|
||||||
|
unset _listener_script
|
||||||
|
|
||||||
# ── Step 10: Push master.conf to all listed hosts ─────────────────────────────────────────────
|
# ── Step 10: Push master.conf to all listed hosts ─────────────────────────────────────────────
|
||||||
# SSH is now established and all partners have the plugin installed.
|
# SSH is now established and all partners have the plugin installed.
|
||||||
# Push the authoritative master.conf so every listed host is in sync immediately.
|
# Push the authoritative master.conf so every listed host is in sync immediately.
|
||||||
@@ -953,9 +976,11 @@ echo " Step 7 — Services stack: $( [[ "$SKIP_SERVICES_STACK" == true ]] &&
|
|||||||
echo " Step 8 — Onboard: $(_ok "$ONBOARD_OK")"
|
echo " Step 8 — Onboard: $(_ok "$ONBOARD_OK")"
|
||||||
echo " Step 9 — Arr bootstrap: $( [[ "$SKIP_ARR_SYNC" == true || "$ONBOARD_OK" == false ]] && echo "skipped" || echo "$(_ok "$ARR_SYNC_OK")" )"
|
echo " Step 9 — Arr bootstrap: $( [[ "$SKIP_ARR_SYNC" == true || "$ONBOARD_OK" == false ]] && echo "skipped" || echo "$(_ok "$ARR_SYNC_OK")" )"
|
||||||
echo " Step 9b — Webhook setup: $(_skip "$SKIP_WEBHOOK_SETUP" "$WEBHOOK_SETUP_OK")"
|
echo " Step 9b — Webhook setup: $(_skip "$SKIP_WEBHOOK_SETUP" "$WEBHOOK_SETUP_OK")"
|
||||||
echo " Step 9c — Media seed: $( [[ "$SKIP_MEDIA_SEED" == true ]] && echo "skipped" || echo "${MEDIA_SEED_COUNT}/${#DAILY_SYNC_SHARES[@]} shares $(_ok "$MEDIA_SEED_OK")" )"
|
echo " Step 9c — Arm sync gates: $( [[ "$SKIP_ARM" == true ]] && echo "skipped (--no-arm)" || { [[ "$ONBOARD_OK" == false ]] && echo "skipped" || echo "$(_ok "$ARM_OK")"; } )"
|
||||||
echo " Step 9d — Webhook listener: $(_skip "$SKIP_WEBHOOK_LISTENER" "$WEBHOOK_LISTENER_OK")"
|
echo " Step 9d — Media seed: $( [[ "$SKIP_MEDIA_SEED" == true ]] && echo "skipped" \
|
||||||
echo " Step 9e — Arm sync gates: $( [[ "$SKIP_ARM" == true ]] && echo "skipped (--no-arm)" || { [[ "$ONBOARD_OK" == false ]] && echo "skipped" || echo "$(_ok "$ARM_OK")"; } )"
|
|| { [[ "$DRY_RUN" == false && "${_rsync_gate:-}" != "true" ]] && echo "skipped (rsync gate closed)" \
|
||||||
|
|| echo "${MEDIA_SEED_COUNT}/${#DAILY_SYNC_SHARES[@]} shares $(_ok "$MEDIA_SEED_OK")"; } )"
|
||||||
|
echo " Step 9e — Webhook listener: $(_skip "$SKIP_WEBHOOK_LISTENER" "$WEBHOOK_LISTENER_OK")"
|
||||||
echo " Step 10 — Conf push: $( [[ "$ONBOARD_OK" == false ]] && echo "skipped" || echo "$(_ok "$MASTER_PUSH_OK")" )"
|
echo " Step 10 — Conf push: $( [[ "$ONBOARD_OK" == false ]] && echo "skipped" || echo "$(_ok "$MASTER_PUSH_OK")" )"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
|||||||
+13
-3
@@ -253,10 +253,20 @@ if [[ "$LOCAL_ONLY" == false && -n "${REMOTE_ID:-}" ]]; then
|
|||||||
remote_flags="--local-only"
|
remote_flags="--local-only"
|
||||||
[[ "$DRY_RUN" == true ]] && remote_flags="$remote_flags --dry-run"
|
[[ "$DRY_RUN" == true ]] && remote_flags="$remote_flags --dry-run"
|
||||||
|
|
||||||
ssh -i "$SSH_KEY" -o ConnectTimeout=10 -o StrictHostKeyChecking=no \
|
# The remote's own SCRIPTS_DIR, read from its varaverk.cfg — never the flash plugin path.
|
||||||
|
# That was hardcoded here, so a partner in appdata storage mode got
|
||||||
|
# "bash: .../Tools/webhook_setup.sh: No such file or directory" and the generic
|
||||||
|
# "check SSH and that Varaverk is installed" message, which pointed at two things that
|
||||||
|
# were both fine. HOST2 has run in appdata mode since it was installed.
|
||||||
|
SSH_TIMEOUT="${SSH_TIMEOUT:-10}"
|
||||||
|
remote_sd=$(resolve_remote_scripts_dir "$remote_ip" "$SSH_KEY" "no")
|
||||||
|
remote_script="${remote_sd}/Tools/webhook_setup.sh"
|
||||||
|
|
||||||
|
ssh -i "$SSH_KEY" -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no \
|
||||||
root@"$remote_ip" \
|
root@"$remote_ip" \
|
||||||
"OVERRIDE_SECRET='$WEBHOOK_SECRET' bash /boot/config/plugins/varaverk/Tools/webhook_setup.sh $remote_flags" \
|
"[ -f '$remote_script' ] || { echo missing; exit 127; }
|
||||||
|| echo " Remote setup failed — check SSH and that Varaverk is installed on $REMOTE_SERVER_NAME"
|
OVERRIDE_SECRET='$WEBHOOK_SECRET' bash '$remote_script' $remote_flags" \
|
||||||
|
|| echo " Remote setup failed — no webhook_setup.sh at $remote_script on $REMOTE_SERVER_NAME, or SSH refused"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
Reference in New Issue
Block a user