#!/bin/bash # ============================================================================================== # ============================= Onboard Cancel ================================================= # ============================================================================================== # # PURPOSE # ───────────────────────────────────────────────────────────────────────────── # Undoes Phase 1 of the onboard process: # 1. Remove HOST1's public key from HOST2's authorized_keys (while key still works) # 2. Remove phase flags from HOST2's varaverk_setup.db # 3. Delete local SSH key pair # 4. Clear phase flags from local varaverk_setup.db # # Run on the OWNER. If HOST2 is unreachable the local side is still cleaned up. # # ============================================================================================== # RUNTIME MODES # ============================================================================================== # # Partnership/onboard_cancel.sh # Cancel Phase 1 — remove keys and reset state # # Partnership/onboard_cancel.sh --dry-run # Preview all steps without making changes # # ============================================================================================== SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPTS_ROOT="$SCRIPT_DIR/.." SSH_TIMEOUT=15 source "$SCRIPTS_ROOT/load_config.sh" parse_args "$@" [[ "$EUID" -ne 0 ]] && { error "Must be run as root"; exit 1; } acquire_lock detect_hosts OWNER_ID="${PARTNERSHIP_OWNER_HOST:-HOST1}" MIRROR_ID=$( [[ "$OWNER_ID" == "HOST1" ]] && echo "HOST2" || echo "HOST1" ) MIRROR="${!MIRROR_ID}" SSH_KEY_PUB="${SSH_KEY}.pub" STATE_FILE="/boot/config/varaverk_setup.db" START=$(date +%s) echo "" echo "━━━ Cancel Phase 1 — $MY_ID → $MIRROR_ID ($MIRROR) — $(date '+%Y-%m-%d %H:%M:%S') ━━━" echo "" [[ "$DRY_RUN" == true ]] && warn "DRY RUN — no changes will be made" echo "" REMOTE_CLEANED=false LOCAL_KEY_GONE=false STATE_CLEARED=false # ── Step 1: Remove HOST1's public key from HOST2 ────────────────────────────── echo "━━━ Step 1 — Remove Public Key from $MIRROR_ID ━━━" if [[ ! -f "$SSH_KEY_PUB" ]]; then log "No local public key at $SSH_KEY_PUB — nothing to remove from $MIRROR_ID" REMOTE_CLEANED=true else # Extract the key blob (middle field of pub key) — used as a unique identifier. # Use | as sed delimiter to avoid clashing with base64 / characters in the blob. KEY_BLOB=$(awk '{print $2}' "$SSH_KEY_PUB") MIRROR_IP=$(resolve_tailscale_ip "$MIRROR" 2>/dev/null || true) if [[ -z "$MIRROR_IP" ]]; then warn "Cannot resolve $MIRROR Tailscale IP — skipping remote cleanup" warn "Remove HOST1's public key from $MIRROR:/root/.ssh/authorized_keys manually" elif [[ "$DRY_RUN" == true ]]; then warn "DRY RUN — would remove key blob from $MIRROR:/root/.ssh/authorized_keys" warn "DRY RUN — would clear ${MIRROR_ID}_PHASE* from $MIRROR:/boot/config/varaverk_setup.db" REMOTE_CLEANED=true else timeout "$SSH_TIMEOUT" ssh -i "$SSH_KEY" \ -o ConnectTimeout="$SSH_TIMEOUT" -o BatchMode=yes root@"$MIRROR_IP" \ "sed -i \"|${KEY_BLOB}|d\" /root/.ssh/authorized_keys 2>/dev/null sed -i \"/^${MIRROR_ID}_PHASE/d\" /boot/config/varaverk_setup.db 2>/dev/null echo ok" 2>/dev/null | grep -q ok && { log "HOST1 key removed from $MIRROR authorized_keys ✅" log "Phase flags cleared on $MIRROR ✅" REMOTE_CLEANED=true } || warn "Could not SSH to $MIRROR — remove HOST1 key and phase flags there manually" fi fi # ── Step 2: Delete local SSH key pair ───────────────────────────────────────── echo "" echo "━━━ Step 2 — Delete Local SSH Key ━━━" if [[ ! -f "$SSH_KEY" && ! -f "$SSH_KEY_PUB" ]]; then log "Local key already gone" LOCAL_KEY_GONE=true elif [[ "$DRY_RUN" == true ]]; then warn "DRY RUN — would delete: $SSH_KEY" warn "DRY RUN — would delete: $SSH_KEY_PUB" LOCAL_KEY_GONE=true else rm -f "$SSH_KEY" "$SSH_KEY_PUB" && { log "Local key pair deleted ✅" LOCAL_KEY_GONE=true } || warn "Failed to delete $SSH_KEY — check permissions" fi # ── Step 3: Clear phase flags from local setup.db ───────────────────────────── echo "" echo "━━━ Step 3 — Clear Phase State ━━━" if [[ ! -f "$STATE_FILE" ]]; then log "No varaverk_setup.db — nothing to clear" STATE_CLEARED=true elif [[ "$DRY_RUN" == true ]]; then warn "DRY RUN — would remove ${MIRROR_ID}_PHASE* from $STATE_FILE" STATE_CLEARED=true else sed -i "/^${MIRROR_ID}_PHASE/d" "$STATE_FILE" && { log "Phase flags cleared from local setup.db ✅" STATE_CLEARED=true } fi # ── Summary ─────────────────────────────────────────────────────────────────── END=$(date +%s) echo "" echo "━━━━━ CANCEL SUMMARY ━━━━━" echo " $MIRROR_ID key removed: $( [[ "$REMOTE_CLEANED" == true ]] && echo "✅" || echo "⚠ manual cleanup needed" )" echo " Local key deleted: $( [[ "$LOCAL_KEY_GONE" == true ]] && echo "✅" || echo "⚠ still present" )" echo " Phase state cleared: $( [[ "$STATE_CLEARED" == true ]] && echo "✅" || echo "⚠" )" echo " Duration: $(format_duration $(( END - START )))" echo "" if [[ "$REMOTE_CLEANED" == false ]]; then echo " Manual cleanup on $MIRROR:" echo " sed -i '/$(awk "{print \$3}" "$SSH_KEY_PUB" 2>/dev/null || echo "HOST1_key_comment")//d' /root/.ssh/authorized_keys" fi echo " Run Phase 1 again to restart the onboard process." echo "━━━━━━━━━━━━━━━━━━━━━━━" exit 0