migration
This commit is contained in:
165
scripts/gitea-restore.sh
Normal file
165
scripts/gitea-restore.sh
Normal file
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Gitea restore helper — restores a gitea-dump zip into a running Gitea deployment
|
||||
#
|
||||
# Prerequisites:
|
||||
# - Gitea deployed on the target cluster (Helm chart via ArgoCD)
|
||||
# - kubectl context pointing to the target cluster
|
||||
# - A gitea-dump zip file (from gitea-backup.sh download or CronJob)
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/gitea-restore.sh <gitea-dump-file.zip>
|
||||
#
|
||||
# What it does:
|
||||
# 1. Scales Gitea down to 0
|
||||
# 2. Restores the PostgreSQL database from gitea-db.sql
|
||||
# 3. Restores Git repositories to the data PVC
|
||||
# 4. Scales Gitea back up
|
||||
|
||||
NAMESPACE="gitea"
|
||||
DEPLOYMENT="gitea"
|
||||
PG_STATEFULSET="gitea-postgresql"
|
||||
PVC="gitea-shared-storage"
|
||||
HELPER_POD="gitea-restore-helper"
|
||||
HELPER_IMAGE="alpine:3.20"
|
||||
PG_USER="gitea"
|
||||
PG_DB="gitea"
|
||||
|
||||
DUMP_FILE="${1:?Usage: $0 <gitea-dump-file.zip>}"
|
||||
|
||||
if [ ! -f "$DUMP_FILE" ]; then
|
||||
echo "Error: file not found: $DUMP_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Gitea Restore ==="
|
||||
echo "Dump file: $DUMP_FILE"
|
||||
echo ""
|
||||
|
||||
# --- Safety prompt ---
|
||||
read -r -p "This will OVERWRITE the Gitea database and repositories on the current cluster. Continue? [y/N] " confirm
|
||||
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||||
echo "Aborted."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cleanup() {
|
||||
kubectl -n "$NAMESPACE" delete pod "$HELPER_POD" --ignore-not-found --grace-period=0 > /dev/null 2>&1 || true
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# --- Step 1: Extract dump locally ---
|
||||
RESTORE_DIR=$(mktemp -d)
|
||||
echo ""
|
||||
echo "[1/5] Extracting dump..."
|
||||
unzip -q "$DUMP_FILE" -d "$RESTORE_DIR"
|
||||
|
||||
# Detect SQL dump file (gitea-db.sql or gitea-dump-*.sql)
|
||||
SQL_FILE=$(find "$RESTORE_DIR" -maxdepth 1 -name '*.sql' | head -1)
|
||||
if [ -z "$SQL_FILE" ]; then
|
||||
echo "Error: no .sql file found in dump."
|
||||
rm -rf "$RESTORE_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Detect repos — either a "repos" folder or gitea-repo.zip
|
||||
if [ -d "$RESTORE_DIR/repos" ]; then
|
||||
REPOS_SOURCE="dir"
|
||||
REPOS_PATH="$RESTORE_DIR/repos"
|
||||
elif [ -f "$RESTORE_DIR/gitea-repo.zip" ]; then
|
||||
REPOS_SOURCE="zip"
|
||||
REPOS_PATH="$RESTORE_DIR/gitea-repo.zip"
|
||||
else
|
||||
echo "Error: no repos/ directory or gitea-repo.zip found in dump."
|
||||
rm -rf "$RESTORE_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo " Found: $(basename "$SQL_FILE") ($(du -h "$SQL_FILE" | cut -f1))"
|
||||
echo " Found: repos ($REPOS_SOURCE)"
|
||||
[ -d "$RESTORE_DIR/data" ] && echo " Found: data/"
|
||||
[ -f "$RESTORE_DIR/app.ini" ] && echo " Found: app.ini (managed by Helm, skipping)"
|
||||
|
||||
# --- Step 2: Scale down Gitea ---
|
||||
echo ""
|
||||
echo "[2/5] Scaling down Gitea..."
|
||||
kubectl -n "$NAMESPACE" scale deployment "$DEPLOYMENT" --replicas=0
|
||||
kubectl -n "$NAMESPACE" rollout status deployment "$DEPLOYMENT" --timeout=60s 2>/dev/null || true
|
||||
echo " Waiting for pods to terminate..."
|
||||
kubectl -n "$NAMESPACE" wait --for=delete pod -l app.kubernetes.io/name=gitea --timeout=120s 2>/dev/null || true
|
||||
echo " Gitea is down."
|
||||
|
||||
# --- Step 3: Restore database ---
|
||||
echo ""
|
||||
echo "[3/5] Restoring database..."
|
||||
# Drop and recreate to ensure clean state
|
||||
kubectl -n "$NAMESPACE" exec "${PG_STATEFULSET}-0" -- \
|
||||
psql -U "$PG_USER" -d postgres -c "DROP DATABASE IF EXISTS ${PG_DB};" 2>/dev/null
|
||||
kubectl -n "$NAMESPACE" exec "${PG_STATEFULSET}-0" -- \
|
||||
psql -U "$PG_USER" -d postgres -c "CREATE DATABASE ${PG_DB} OWNER ${PG_USER};" 2>/dev/null
|
||||
kubectl -n "$NAMESPACE" exec -i "${PG_STATEFULSET}-0" -- \
|
||||
psql -U "$PG_USER" -d "$PG_DB" < "$SQL_FILE" > /dev/null
|
||||
echo " Database restored."
|
||||
|
||||
# --- Step 4: Restore repositories ---
|
||||
echo ""
|
||||
echo "[4/5] Restoring repositories..."
|
||||
|
||||
# Need a helper pod on the same node as the PVC (RWO)
|
||||
cleanup
|
||||
kubectl -n "$NAMESPACE" run "$HELPER_POD" --restart=Never \
|
||||
--image="$HELPER_IMAGE" \
|
||||
--overrides="{
|
||||
\"spec\":{
|
||||
\"containers\":[{
|
||||
\"name\":\"$HELPER_POD\",
|
||||
\"image\":\"$HELPER_IMAGE\",
|
||||
\"command\":[\"sleep\",\"3600\"],
|
||||
\"volumeMounts\":[{\"name\":\"data\",\"mountPath\":\"/data\"}]
|
||||
}],
|
||||
\"volumes\":[{
|
||||
\"name\":\"data\",
|
||||
\"persistentVolumeClaim\":{\"claimName\":\"$PVC\"}
|
||||
}]
|
||||
}
|
||||
}" > /dev/null 2>&1
|
||||
|
||||
kubectl -n "$NAMESPACE" wait --for=condition=Ready "pod/$HELPER_POD" --timeout=120s > /dev/null 2>&1
|
||||
|
||||
# Clear existing repos
|
||||
kubectl -n "$NAMESPACE" exec "$HELPER_POD" -- sh -c "rm -rf /data/gitea/repositories/*" 2>/dev/null || true
|
||||
|
||||
# Upload repos — tar via stdin since kubectl cp needs tar in the container
|
||||
echo " Uploading repositories..."
|
||||
if [ "$REPOS_SOURCE" = "dir" ]; then
|
||||
# repos/ directory — tar and stream into the PVC
|
||||
tar -cf - -C "$REPOS_PATH" . | kubectl -n "$NAMESPACE" exec -i "$HELPER_POD" -- sh -c "tar -xf - -C /data/gitea/repositories/"
|
||||
else
|
||||
# gitea-repo.zip — stream and extract
|
||||
cat "$REPOS_PATH" | kubectl -n "$NAMESPACE" exec -i "$HELPER_POD" -- sh -c "cat > /tmp/gitea-repo.zip && unzip -q -o /tmp/gitea-repo.zip -d /data/gitea/repositories/ && rm /tmp/gitea-repo.zip"
|
||||
fi
|
||||
|
||||
# Restore data/ directory (avatars, attachments, LFS, etc.) if present
|
||||
if [ -d "$RESTORE_DIR/data" ]; then
|
||||
echo " Uploading data (avatars, attachments, LFS)..."
|
||||
tar -cf - -C "$RESTORE_DIR/data" . | kubectl -n "$NAMESPACE" exec -i "$HELPER_POD" -- sh -c "tar -xf - -C /data/gitea/"
|
||||
fi
|
||||
|
||||
# Fix ownership
|
||||
kubectl -n "$NAMESPACE" exec "$HELPER_POD" -- chown -R 1000:1000 /data/gitea/
|
||||
echo " Repositories restored."
|
||||
|
||||
# --- Step 5: Scale back up ---
|
||||
echo ""
|
||||
echo "[5/5] Scaling Gitea back up..."
|
||||
kubectl -n "$NAMESPACE" scale deployment "$DEPLOYMENT" --replicas=1
|
||||
kubectl -n "$NAMESPACE" rollout status deployment "$DEPLOYMENT" --timeout=120s
|
||||
|
||||
# Cleanup temp dir
|
||||
rm -rf "$RESTORE_DIR"
|
||||
|
||||
echo ""
|
||||
echo "=== Restore complete ==="
|
||||
echo "Gitea should be back online with restored data."
|
||||
echo "Verify at your Gitea URL that repos and users are present."
|
||||
Reference in New Issue
Block a user