#!/usr/bin/env bash # gitea-backup.sh — Daily Gitea backup to Wasabi S3. # Mirrors all repos + dumps the Gitea SQLite DB + config. # Schedule: Daily at 4 AM ET via cron (no_agent) set -euo pipefail SSH_KEY="/root/.ssh/itpp-infra" APP2="root@152.53.39.202" S3_BUCKET="s3://hermes-vps-backups/gitea" ENDPOINT="https://s3.us-east-1.wasabisys.com" TS="$(date -u +%Y%m%d-%H%M%S)" STAGE="/tmp/gitea-backup-${TS}" TOKEN="1761daa2c537fb72b365e54619208329d8e3ad33" RETENTION_DAYS=30 if [ -f /opt/awscli-venv/bin/activate ]; then source /opt/awscli-venv/bin/activate fi log() { echo "[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] $*"; } log "Starting Gitea backup" mkdir -p "$STAGE/repos" "$STAGE/db" # 1. Mirror all repos via git clone --mirror log "Mirroring repos..." REPO_LIST=$(curl -sk "https://git.itpropartner.com/api/v1/user/repos" \ -H "Authorization: token ${TOKEN}" 2>/dev/null | \ python3 -c "import json,sys; [print(r['name']) for r in json.load(sys.stdin)]" 2>/dev/null) COUNT=0 for repo in $REPO_LIST; do git clone --mirror "https://ippadmin:${TOKEN}@git.itpropartner.com/ippadmin/${repo}.git" \ "$STAGE/repos/${repo}.git" >/dev/null 2>&1 && COUNT=$((COUNT+1)) || log "WARN: clone failed for $repo" done log "Mirrored ${COUNT} repos" # 2. Dump Gitea DB + config from app2 log "Backing up Gitea DB..." ssh -i "$SSH_KEY" -o ConnectTimeout=10 -o BatchMode=yes "$APP2" \ "docker cp gitea:/data/gitea/gitea.db /tmp/gitea.db && docker cp gitea:/data/gitea/conf/app.ini /tmp/gitea-app.ini" 2>/dev/null scp -q -i "$SSH_KEY" -o BatchMode=yes \ "$APP2:/tmp/gitea.db" "$STAGE/db/gitea.db" 2>/dev/null || log "WARN: scp db failed" scp -q -i "$SSH_KEY" -o BatchMode=yes \ "$APP2:/tmp/gitea-app.ini" "$STAGE/db/app.ini" 2>/dev/null || log "WARN: scp config failed" SIZE=$(du -sh "$STAGE" 2>/dev/null | cut -f1) log "Staged: ${SIZE}" # 3. Upload to S3 log "Uploading to S3..." aws s3 sync "$STAGE/" "${S3_BUCKET}/daily/${TS}/" \ --endpoint-url "$ENDPOINT" >/dev/null 2>&1 || { log "FATAL: S3 upload failed"; exit 1; } log "Uploaded: ${S3_BUCKET}/daily/${TS}/" # 4. Cleanup old backups aws s3 ls "${S3_BUCKET}/daily/" --endpoint-url "$ENDPOINT" 2>/dev/null | \ awk -v cutoff="$(date -d "${RETENTION_DAYS} days ago" -u +%Y-%m-%d)" \ '$1 < cutoff {print $2}' | while read -r old; do aws s3 rm "${S3_BUCKET}/daily/${old}" --recursive --endpoint-url "$ENDPOINT" >/dev/null 2>&1 log "Purged: $old" done # 5. Cleanup local staging ssh -i "$SSH_KEY" -o BatchMode=yes "$APP2" "rm -f /tmp/gitea.db /tmp/gitea-app.ini" 2>/dev/null rm -rf "$STAGE" log "Backup complete: ${COUNT} repos"