From 03d91aa1f9346ba7419457da997c447c44197f4f Mon Sep 17 00:00:00 2001 From: "Dejan R." Date: Tue, 25 Nov 2025 06:59:50 +0000 Subject: [PATCH] added restore.sh file --- restore.sh | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100755 restore.sh diff --git a/restore.sh b/restore.sh new file mode 100755 index 0000000..a869e47 --- /dev/null +++ b/restore.sh @@ -0,0 +1,111 @@ +#!/bin/bash +set -euo pipefail + +# ==================================== +# Forgejo restore script +# ==================================== + +# Where this script lives (Forgejo project root) +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +BACKUP_DIR="$SCRIPT_DIR/backup" +TIMESTAMP="$(date +%Y-%m-%d_%H-%M-%S)" + +usage() { + echo "Usage: $0 " + echo + echo " can be:" + echo " - Full path to a backup tar.gz" + echo " - Filename in the backup/ directory" + echo " - If omitted, the latest backup in backup/ is used (if available)" + exit 1 +} + +# ------------------------------------ +# 1) Pick backup file +# ------------------------------------ +if [[ $# -ge 1 ]]; then + INPUT_FILE="$1" + # If it's not an absolute path and not already in backup/, assume it's in backup/ + if [[ "$INPUT_FILE" != /* && "$INPUT_FILE" != "$BACKUP_DIR/"* ]]; then + BACKUP_FILE="$BACKUP_DIR/$INPUT_FILE" + else + BACKUP_FILE="$INPUT_FILE" + fi +else + # No argument → pick the latest backup in backup/ + echo "No backup file specified, selecting latest from $BACKUP_DIR..." + BACKUP_FILE="$(ls -1t "$BACKUP_DIR"/forgejo-backup-*.tar.gz 2>/dev/null | head -n 1 || true)" + if [[ -z "${BACKUP_FILE:-}" ]]; then + echo "ERROR: No backups found in $BACKUP_DIR" + usage + fi +fi + +if [[ ! -f "$BACKUP_FILE" ]]; then + echo "ERROR: Backup file not found: $BACKUP_FILE" + exit 1 +fi + +echo "=== Forgejo restore ===" +echo "Project dir : $SCRIPT_DIR" +echo "Backup dir : $BACKUP_DIR" +echo "Backup file : $BACKUP_FILE" +echo + +read -rp "!!! This will overwrite current Forgejo data. Continue? [y/N] " ANSWER +case "$ANSWER" in + y|Y|yes|YES) ;; + *) echo "Aborted."; exit 1 ;; +esac + +# ------------------------------------ +# 2) Stop Forgejo +# ------------------------------------ +echo "[1/4] Stopping Forgejo containers (if running)..." +docker compose down || true + +# ------------------------------------ +# 3) Safety snapshot of current state +# ------------------------------------ +SAFETY_BACKUP="$BACKUP_DIR/forgejo-pre-restore-${TIMESTAMP}.tar.gz" +echo "[2/4] Creating safety backup of CURRENT state -> $SAFETY_BACKUP" +tar -czf "$SAFETY_BACKUP" \ + forgejo \ + docker-compose.yml \ + .gitignore \ + README.md \ + .git 2>/dev/null || true + +echo "[OK] Safety backup created." + +# ------------------------------------ +# 4) Restore from selected backup +# ------------------------------------ +echo "[3/4] Removing current Forgejo data (moving to forgejo.old-$TIMESTAMP)..." + +if [[ -d forgejo ]]; then + mv forgejo "forgejo.old-$TIMESTAMP" +fi + +# If config files exist, move them too (just in case) +for f in docker-compose.yml .gitignore README.md; do + if [[ -f "$f" ]]; then + mv "$f" "${f}.old-$TIMESTAMP" + fi +done + +echo "[4/4] Extracting backup archive..." +tar -xzf "$BACKUP_FILE" -C "$SCRIPT_DIR" + +echo "=== Restore complete ===" +echo "Starting Forgejo containers..." +docker compose up -d + +echo "Forgejo should now be running with data from:" +echo " $BACKUP_FILE" +echo +echo "Previous state saved as:" +echo " $SAFETY_BACKUP" +echo " forgejo.old-$TIMESTAMP (and *.old-$TIMESTAMP for configs, if any)"