213 lines
8.2 KiB
Bash
Executable File
213 lines
8.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# =============================================================================
|
|
# phase8_teardown.sh — Reverse the cutover: remove HTTPS, restore GitHub repos
|
|
# Steps:
|
|
# 1. Remove Nginx gitea.conf + reload
|
|
# 2. Remove cert renewal cron
|
|
# 3. Optionally remove SSL certificates
|
|
# 4. Restore GitHub repo settings from the saved Phase 8 state snapshot
|
|
# =============================================================================
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
source "${SCRIPT_DIR}/lib/common.sh"
|
|
|
|
load_env
|
|
require_vars UNRAID_IP UNRAID_SSH_USER \
|
|
GITEA_DOMAIN NGINX_CONTAINER_NAME NGINX_CONF_PATH \
|
|
SSL_MODE GITHUB_USERNAME GITHUB_TOKEN \
|
|
REPO_NAMES
|
|
|
|
log_warn "=== Phase 8 Teardown: Cutover ==="
|
|
|
|
read -ra REPOS <<< "$REPO_NAMES"
|
|
PHASE8_STATE_FILE="$(_project_root)/.manifests/phase8_github_repo_state.json"
|
|
|
|
github_pages_http_code() {
|
|
local repo="$1"
|
|
curl -s -o /dev/null -w "%{http_code}" \
|
|
-H "Authorization: token ${GITHUB_TOKEN}" \
|
|
-H "Accept: application/json" \
|
|
"https://api.github.com/repos/${GITHUB_USERNAME}/${repo}/pages" 2>/dev/null || echo "000"
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Step 1: Remove Nginx config and reload
|
|
# ---------------------------------------------------------------------------
|
|
if ssh_exec UNRAID "test -f '${NGINX_CONF_PATH}/gitea.conf'" 2>/dev/null; then
|
|
printf 'Remove Nginx config for %s? [y/N] ' "$GITEA_DOMAIN"
|
|
read -r confirm
|
|
if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
|
ssh_exec UNRAID "rm -f '${NGINX_CONF_PATH}/gitea.conf'"
|
|
ssh_exec UNRAID "docker exec ${NGINX_CONTAINER_NAME} nginx -s reload" || true
|
|
log_success "Nginx config removed and reloaded"
|
|
else
|
|
log_info "Nginx config preserved"
|
|
fi
|
|
else
|
|
log_info "Nginx config already removed"
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Step 2: Remove cert renewal cron
|
|
# ---------------------------------------------------------------------------
|
|
if ssh_exec UNRAID "crontab -l 2>/dev/null | grep -q certbot" 2>/dev/null; then
|
|
ssh_exec UNRAID "crontab -l 2>/dev/null | grep -v certbot | crontab -"
|
|
log_success "Certbot renewal cron removed"
|
|
else
|
|
log_info "No certbot cron found"
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Step 3: Optionally remove SSL certificates (letsencrypt only)
|
|
# ---------------------------------------------------------------------------
|
|
if [[ "$SSL_MODE" == "letsencrypt" ]]; then
|
|
if ssh_exec UNRAID "test -d '/etc/letsencrypt/live/${GITEA_DOMAIN}'" 2>/dev/null; then
|
|
printf 'Remove SSL certificates for %s? [y/N] ' "$GITEA_DOMAIN"
|
|
read -r confirm
|
|
if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
|
ssh_exec UNRAID "rm -rf '/etc/letsencrypt/live/${GITEA_DOMAIN}' '/etc/letsencrypt/archive/${GITEA_DOMAIN}' '/etc/letsencrypt/renewal/${GITEA_DOMAIN}.conf'"
|
|
log_success "SSL certificates removed"
|
|
else
|
|
log_info "SSL certificates preserved"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Step 4: Restore GitHub repos
|
|
# Primary path: restore from state snapshot written by phase8_cutover.sh.
|
|
# Fallback path: if snapshot is missing, restore description from "— was: ..."
|
|
# and use legacy defaults for homepage/wiki/projects.
|
|
# ---------------------------------------------------------------------------
|
|
printf 'Restore GitHub repo settings (description/homepage/wiki/projects/pages)? [y/N] '
|
|
read -r confirm
|
|
if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
|
STATE_AVAILABLE=false
|
|
if [[ -f "$PHASE8_STATE_FILE" ]]; then
|
|
STATE_AVAILABLE=true
|
|
log_info "Using saved Phase 8 state from ${PHASE8_STATE_FILE}"
|
|
else
|
|
log_warn "No Phase 8 state file found — using fallback restore behavior"
|
|
fi
|
|
|
|
RESTORE_ERRORS=0
|
|
|
|
for repo in "${REPOS[@]}"; do
|
|
CURRENT_DESC=$(github_api GET "/repos/${GITHUB_USERNAME}/${repo}" 2>/dev/null | jq -r '.description // ""')
|
|
|
|
RESTORE_DESC=""
|
|
RESTORE_HOMEPAGE=""
|
|
RESTORE_HAS_WIKI=true
|
|
RESTORE_HAS_PROJECTS=true
|
|
RESTORE_PAGES_ENABLED=false
|
|
RESTORE_PAGES_CNAME=""
|
|
RESTORE_PAGES_BRANCH=""
|
|
RESTORE_PAGES_PATH="/"
|
|
|
|
if [[ "$STATE_AVAILABLE" == "true" ]] && jq -e --arg repo "$repo" 'has($repo)' "$PHASE8_STATE_FILE" >/dev/null 2>&1; then
|
|
REPO_STATE=$(jq -c --arg repo "$repo" '.[$repo]' "$PHASE8_STATE_FILE")
|
|
RESTORE_DESC=$(printf '%s' "$REPO_STATE" | jq -r '.description // ""')
|
|
RESTORE_HOMEPAGE=$(printf '%s' "$REPO_STATE" | jq -r '.homepage // ""')
|
|
RESTORE_HAS_WIKI=$(printf '%s' "$REPO_STATE" | jq -r '.has_wiki // true')
|
|
RESTORE_HAS_PROJECTS=$(printf '%s' "$REPO_STATE" | jq -r '.has_projects // true')
|
|
RESTORE_PAGES_ENABLED=$(printf '%s' "$REPO_STATE" | jq -r '.pages_enabled // false')
|
|
RESTORE_PAGES_CNAME=$(printf '%s' "$REPO_STATE" | jq -r '.pages_cname // ""')
|
|
RESTORE_PAGES_BRANCH=$(printf '%s' "$REPO_STATE" | jq -r '.pages_source_branch // ""')
|
|
RESTORE_PAGES_PATH=$(printf '%s' "$REPO_STATE" | jq -r '.pages_source_path // "/"')
|
|
else
|
|
if [[ "$CURRENT_DESC" != "[MIRROR]"* ]]; then
|
|
log_info "GitHub repo ${repo} not marked as mirror and no snapshot found — skipping"
|
|
continue
|
|
fi
|
|
if [[ "$CURRENT_DESC" == *" — was: "* ]]; then
|
|
RESTORE_DESC="${CURRENT_DESC##* — was: }"
|
|
fi
|
|
fi
|
|
|
|
# Restore description/homepage/wiki/projects
|
|
RESTORE_PAYLOAD=$(jq -n \
|
|
--arg description "$RESTORE_DESC" \
|
|
--arg homepage "$RESTORE_HOMEPAGE" \
|
|
--argjson has_wiki "$RESTORE_HAS_WIKI" \
|
|
--argjson has_projects "$RESTORE_HAS_PROJECTS" \
|
|
'{
|
|
description: $description,
|
|
homepage: $homepage,
|
|
has_wiki: $has_wiki,
|
|
has_projects: $has_projects
|
|
}')
|
|
|
|
if github_api PATCH "/repos/${GITHUB_USERNAME}/${repo}" "$RESTORE_PAYLOAD" >/dev/null 2>&1; then
|
|
log_success "Restored GitHub repo settings: ${repo}"
|
|
else
|
|
log_error "Failed to restore GitHub repo: ${repo}"
|
|
RESTORE_ERRORS=$((RESTORE_ERRORS + 1))
|
|
continue
|
|
fi
|
|
|
|
# Restore GitHub Pages state
|
|
CURRENT_PAGES_CODE=$(github_pages_http_code "$repo")
|
|
|
|
if [[ "$RESTORE_PAGES_ENABLED" == "true" ]]; then
|
|
if [[ -z "$RESTORE_PAGES_BRANCH" ]]; then
|
|
log_warn "Cannot restore Pages for ${repo}: missing source branch in saved state"
|
|
RESTORE_ERRORS=$((RESTORE_ERRORS + 1))
|
|
continue
|
|
fi
|
|
|
|
PAGES_PAYLOAD=$(jq -n \
|
|
--arg branch "$RESTORE_PAGES_BRANCH" \
|
|
--arg path "$RESTORE_PAGES_PATH" \
|
|
--arg cname "$RESTORE_PAGES_CNAME" \
|
|
'{
|
|
source: {
|
|
branch: $branch,
|
|
path: $path
|
|
}
|
|
} + (if $cname != "" then {cname: $cname} else {} end)')
|
|
|
|
if [[ "$CURRENT_PAGES_CODE" == "200" ]]; then
|
|
if github_api PUT "/repos/${GITHUB_USERNAME}/${repo}/pages" "$PAGES_PAYLOAD" >/dev/null 2>&1; then
|
|
log_success "Restored GitHub Pages config for ${repo}"
|
|
else
|
|
log_warn "Failed to update GitHub Pages config for ${repo}"
|
|
RESTORE_ERRORS=$((RESTORE_ERRORS + 1))
|
|
fi
|
|
else
|
|
if github_api POST "/repos/${GITHUB_USERNAME}/${repo}/pages" "$PAGES_PAYLOAD" >/dev/null 2>&1; then
|
|
log_success "Recreated GitHub Pages for ${repo}"
|
|
else
|
|
log_warn "Failed to recreate GitHub Pages for ${repo}"
|
|
RESTORE_ERRORS=$((RESTORE_ERRORS + 1))
|
|
fi
|
|
fi
|
|
else
|
|
if [[ "$CURRENT_PAGES_CODE" == "200" ]]; then
|
|
if github_api DELETE "/repos/${GITHUB_USERNAME}/${repo}/pages" >/dev/null 2>&1; then
|
|
log_info "Disabled GitHub Pages for ${repo} (matches pre-cutover state)"
|
|
else
|
|
log_warn "Failed to disable GitHub Pages for ${repo}"
|
|
RESTORE_ERRORS=$((RESTORE_ERRORS + 1))
|
|
fi
|
|
else
|
|
log_info "GitHub Pages already disabled for ${repo}"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [[ "$STATE_AVAILABLE" == "true" ]]; then
|
|
if [[ "$RESTORE_ERRORS" -eq 0 ]]; then
|
|
rm -f "$PHASE8_STATE_FILE"
|
|
log_info "Removed saved Phase 8 state file after successful restore"
|
|
else
|
|
log_warn "Keeping Phase 8 state file due to restore errors: ${PHASE8_STATE_FILE}"
|
|
fi
|
|
fi
|
|
else
|
|
log_info "GitHub repos left as-is"
|
|
fi
|
|
|
|
log_success "Phase 8 teardown complete"
|