feat: add cross-host SSH trust, state-aware teardown, and configurable migration polling

- Add setup/cross_host_ssh.sh to establish ed25519 SSH trust between
  Unraid and Fedora (required by backup/restore scripts for direct SCP)
- Add ssh_key and authorized_key cleanup handlers to setup/cleanup.sh
- Rewrite phase8 cutover to mark GitHub repos as mirrors instead of
  archiving them (archived repos reject push mirror writes), with a
  JSON state snapshot of pre-cutover settings (description, homepage,
  wiki, projects, Pages) for exact restoration on teardown
- Rewrite phase8 teardown to restore from state snapshot with fallback
  to legacy "— was:" description parsing
- Make migration polling configurable via MIGRATION_POLL_INTERVAL_SEC
  and MIGRATION_POLL_TIMEOUT_SEC in .env (was hardcoded 120s/3s)
- Fix preflight SSL validation: check SSL_MODE instead of always
  requiring SSL_EMAIL, add conditional checks per SSL_MODE
- Add preflight checks 23-24: cross-host SSH connectivity
- Add --start-from range validation and cross_host_ssh.sh to run_all.sh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
S
2026-02-28 20:50:41 -05:00
parent dc08375ad0
commit 316d318b5e
8 changed files with 509 additions and 31 deletions

View File

@@ -22,6 +22,23 @@ require_vars GITEA_ADMIN_TOKEN GITEA_BACKUP_ADMIN_TOKEN \
MIGRATE_ISSUES MIGRATE_LABELS MIGRATE_MILESTONES MIGRATE_WIKI \
GITEA_BACKUP_MIRROR_INTERVAL
# Migration polling knobs (optional in .env)
MIGRATION_POLL_INTERVAL_SEC="${MIGRATION_POLL_INTERVAL_SEC:-3}"
MIGRATION_POLL_TIMEOUT_SEC="${MIGRATION_POLL_TIMEOUT_SEC:-600}"
if ! [[ "$MIGRATION_POLL_INTERVAL_SEC" =~ ^[1-9][0-9]*$ ]]; then
log_error "MIGRATION_POLL_INTERVAL_SEC must be a positive integer (seconds)"
exit 1
fi
if ! [[ "$MIGRATION_POLL_TIMEOUT_SEC" =~ ^[1-9][0-9]*$ ]]; then
log_error "MIGRATION_POLL_TIMEOUT_SEC must be a positive integer (seconds)"
exit 1
fi
if (( MIGRATION_POLL_TIMEOUT_SEC < MIGRATION_POLL_INTERVAL_SEC )); then
log_error "MIGRATION_POLL_TIMEOUT_SEC (${MIGRATION_POLL_TIMEOUT_SEC}) must be >= MIGRATION_POLL_INTERVAL_SEC (${MIGRATION_POLL_INTERVAL_SEC})"
exit 1
fi
phase_header 4 "Migrate Repos + Fedora Mirrors"
# ---------------------------------------------------------------------------
@@ -84,20 +101,20 @@ for repo in "${REPOS[@]}"; do
# Wait for migration to complete — poll until repo has content
# The migration API returns immediately but cloning happens async.
# We check for commits to confirm the repo has actual content.
log_info "Waiting for migration to complete..."
log_info "Waiting for migration to complete (timeout: ${MIGRATION_POLL_TIMEOUT_SEC}s, interval: ${MIGRATION_POLL_INTERVAL_SEC}s)..."
local_elapsed=0
while [[ $local_elapsed -lt 120 ]]; do
while [[ $local_elapsed -lt $MIGRATION_POLL_TIMEOUT_SEC ]]; do
COMMITS=$(gitea_api GET "/repos/${GITEA_ORG_NAME}/${repo}/commits?limit=1" 2>/dev/null || echo "[]")
COMMIT_COUNT=$(printf '%s' "$COMMITS" | jq 'length' 2>/dev/null || echo 0)
if [[ "$COMMIT_COUNT" -gt 0 ]]; then
log_success "Repo ${repo} migrated with commits"
break
fi
sleep 3
local_elapsed=$((local_elapsed + 3))
sleep "$MIGRATION_POLL_INTERVAL_SEC"
local_elapsed=$((local_elapsed + MIGRATION_POLL_INTERVAL_SEC))
done
if [[ $local_elapsed -ge 120 ]]; then
if [[ $local_elapsed -ge $MIGRATION_POLL_TIMEOUT_SEC ]]; then
log_error "Timeout waiting for ${repo} migration to complete"
FAILED=$((FAILED + 1))
continue