From 73e445b7e65305f25a7da41142ff37dea40844fd Mon Sep 17 00:00:00 2001 From: "Dejan R." Date: Thu, 27 Nov 2025 16:29:29 +0000 Subject: [PATCH] rewrited backup script --- scripts/restore-netbird.sh | 330 ++++++++++++++++++++++++------------- 1 file changed, 216 insertions(+), 114 deletions(-) diff --git a/scripts/restore-netbird.sh b/scripts/restore-netbird.sh index 4aad210..ccbf586 100644 --- a/scripts/restore-netbird.sh +++ b/scripts/restore-netbird.sh @@ -1,134 +1,236 @@ #!/bin/bash -set -e -# ============================================ -# CONFIG -# ============================================ -BASE_DIR="/home/Dejan/Docker/Netbird-compose" -BACKUP_DIR="${BASE_DIR}/backup" +# Netbird Docker Compose Restore Script +# This script restores a backup and recreates the full directory structure -cd "$BASE_DIR" +# Configuration +COMPOSE_DIR="/home/Dejan/Docker/Netbird-compose" +BACKUP_DIR="${COMPOSE_DIR}/backup" -# ============================================ -# SELECT BACKUP FILE -# ============================================ -if [[ -n "$1" ]]; then - BACKUP_FILE="$1" - # If a relative path is passed, prepend BACKUP_DIR if file not found - if [[ ! -f "$BACKUP_FILE" ]]; then - if [[ -f "${BACKUP_DIR}/$BACKUP_FILE" ]]; then - BACKUP_FILE="${BACKUP_DIR}/$BACKUP_FILE" +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Function to print colored messages +print_msg() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +print_question() { + echo -e "${BLUE}[QUESTION]${NC} $1" +} + +# Function to show usage +show_usage() { + echo "Usage: $0 " + echo "" + echo "Examples:" + echo " $0 netbird-backup-20241127_161245.tar.gz" + echo " $0 backup/netbird-backup-20241127_161245.tar.gz" + echo " $0 /home/Dejan/Docker/Netbird-compose/backup/netbird-backup-20241127_161245.tar.gz" + echo "" + echo "Available backups:" + if [ -d "$BACKUP_DIR" ]; then + ls -1t "$BACKUP_DIR"/netbird-backup-*.tar.gz 2>/dev/null | head -n 10 + else + echo " No backup directory found" + fi + exit 1 +} + +# Check if running as root +if [ "$EUID" -ne 0 ]; then + print_error "Please run as root" + exit 1 +fi + +# Check if backup file argument is provided +if [ -z "$1" ]; then + print_error "No backup file specified" + show_usage +fi + +BACKUP_FILE="$1" + +# Resolve backup file path +if [ ! -f "$BACKUP_FILE" ]; then + # Try in backup directory + if [ -f "$BACKUP_DIR/$BACKUP_FILE" ]; then + BACKUP_FILE="$BACKUP_DIR/$BACKUP_FILE" + elif [ -f "$COMPOSE_DIR/$BACKUP_FILE" ]; then + BACKUP_FILE="$COMPOSE_DIR/$BACKUP_FILE" + else + print_error "Backup file not found: $1" + print_msg "Searched in:" + echo " - $1" + echo " - $BACKUP_DIR/$1" + echo " - $COMPOSE_DIR/$1" + echo "" + show_usage + fi +fi + +print_msg "Restore Script for Netbird Docker Compose" +print_msg "==========================================" +print_msg "Backup file: $BACKUP_FILE" +print_msg "Target directory: $COMPOSE_DIR" +echo "" + +# Verify backup file +if ! tar -tzf "$BACKUP_FILE" &>/dev/null; then + print_error "Invalid or corrupted backup file" + exit 1 +fi + +BACKUP_SIZE=$(du -h "$BACKUP_FILE" | cut -f1) +print_msg "Backup size: $BACKUP_SIZE" + +# Show what will be restored +print_msg "Backup contents preview:" +tar -tzf "$BACKUP_FILE" | head -n 20 +if [ $(tar -tzf "$BACKUP_FILE" | wc -l) -gt 20 ]; then + echo " ... and more files" +fi +echo "" + +# Warning and confirmation +print_warning "WARNING: This will stop all services and replace current files!" +print_warning "Current directory contents will be overwritten!" +echo "" +print_question "Do you want to create a safety backup before restoring? (recommended) [Y/n]" +read -r SAFETY_BACKUP + +if [[ ! "$SAFETY_BACKUP" =~ ^[Nn]$ ]]; then + SAFETY_TIMESTAMP=$(date +"%Y%m%d_%H%M%S") + SAFETY_FILE="${BACKUP_DIR}/pre-restore-backup-${SAFETY_TIMESTAMP}.tar.gz" + print_msg "Creating safety backup: $SAFETY_FILE" + + cd "$COMPOSE_DIR" || exit 1 + + # Stop services first if docker-compose.yml exists + if [ -f "docker-compose.yml" ]; then + print_msg "Stopping current services..." + docker-compose down 2>/dev/null + fi + + tar -czf "$SAFETY_FILE" \ + --exclude='./backup' \ + --exclude='./.git' \ + -C "$COMPOSE_DIR" . 2>/dev/null + + if [ $? -eq 0 ]; then + print_msg "Safety backup created successfully" + else + print_warning "Failed to create safety backup, but continuing..." + fi +fi + +echo "" +print_question "Are you sure you want to restore from this backup? [y/N]" +read -r CONFIRM + +if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then + print_msg "Restore cancelled by user" + exit 0 +fi + +print_msg "Starting restore process..." + +# Change to compose directory +cd "$COMPOSE_DIR" || { + print_error "Failed to change to directory: $COMPOSE_DIR" + exit 1 +} + +# Stop docker compose services if they exist +if [ -f "docker-compose.yml" ]; then + print_msg "Stopping Docker Compose services..." + docker-compose down + if [ $? -eq 0 ]; then + print_msg "Services stopped successfully" + else + print_warning "Failed to stop services (they may not be running)" fi - fi else - # Auto-select latest backup - BACKUP_FILE=$(ls -1t "${BACKUP_DIR}"/netbird_backup_*.tar.gz 2>/dev/null | head -n 1 || true) + print_msg "No docker-compose.yml found, skipping service stop" fi -if [[ -z "$BACKUP_FILE" || ! -f "$BACKUP_FILE" ]]; then - echo "ERROR: Backup file not found." - echo "Usage: $0 [path/to/netbird_backup_*.tar.gz]" - exit 1 +# Remove current files (except backup directory and this script) +print_msg "Removing current files..." +find "$COMPOSE_DIR" -mindepth 1 -maxdepth 1 ! -name 'backup' ! -name 'restore-netbird.sh' ! -name '.git' -exec rm -rf {} + 2>/dev/null + +# Extract backup +print_msg "Extracting backup archive..." +tar -xzf "$BACKUP_FILE" -C "$COMPOSE_DIR" + +if [ $? -eq 0 ]; then + print_msg "Backup extracted successfully" +else + print_error "Failed to extract backup" + exit 1 fi -echo "[*] Using backup file: $BACKUP_FILE" +# Set proper permissions +print_msg "Setting permissions..." +chmod +x "$COMPOSE_DIR"/*.sh 2>/dev/null +if [ -d "$COMPOSE_DIR/machinekey" ]; then + chmod 777 "$COMPOSE_DIR/machinekey" +fi +chmod 600 "$COMPOSE_DIR/acme.json" 2>/dev/null -# ============================================ -# PREPARE TEMP DIR -# ============================================ -TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S") -TEMP_DIR="/tmp/netbird_restore_${TIMESTAMP}" +# Verify critical files +print_msg "Verifying restored files..." +CRITICAL_FILES=("docker-compose.yml" ".env") +ALL_GOOD=true -echo "[*] Creating temp directory: $TEMP_DIR" -mkdir -p "$TEMP_DIR" - -echo "[*] Extracting backup archive..." -tar -xzf "$BACKUP_FILE" -C "$TEMP_DIR" - -# ============================================ -# STOP CURRENT STACK -# ============================================ -echo "[*] Stopping current NetBird stack (if running)..." -docker compose down || true - -# ============================================ -# RESTORE DOCKER VOLUMES -# ============================================ -VOLUMES=( - "netbird_zdb_data" - "netbird_management" - "netbird_zitadel_certs" -) - -for VOL in "${VOLUMES[@]}"; do - VOL_ARCHIVE="${TEMP_DIR}/${VOL}.tar.gz" - if [[ ! -f "$VOL_ARCHIVE" ]]; then - echo "[!] WARNING: Volume archive not found for ${VOL} at ${VOL_ARCHIVE}, skipping..." - continue - fi - - echo "[*] Ensuring Docker volume exists: $VOL" - if ! docker volume ls -q | grep -q "^${VOL}$"; then - docker volume create "$VOL" >/dev/null - fi - - echo "[*] Restoring volume: $VOL" - docker run --rm \ - -v "${VOL}:/volume" \ - -v "${TEMP_DIR}:/backup" \ - alpine sh -c "cd /volume && tar -xzf /backup/$(basename "$VOL_ARCHIVE")" +for file in "${CRITICAL_FILES[@]}"; do + if [ -f "$COMPOSE_DIR/$file" ]; then + print_msg "✓ $file restored" + else + print_error "✗ $file missing" + ALL_GOOD=false + fi done -# ============================================ -# RESTORE CONFIG FILES -# ============================================ -echo "[*] Restoring configuration files to ${BASE_DIR}..." - -# docker-compose.yml -if [[ -f "${TEMP_DIR}/docker-compose.yml" ]]; then - cp -a "${TEMP_DIR}/docker-compose.yml" "${BASE_DIR}/" +if [ "$ALL_GOOD" = false ]; then + print_error "Some critical files are missing!" + exit 1 fi -# *.env files -if ls "${TEMP_DIR}"/*.env >/dev/null 2>&1; then - cp -a "${TEMP_DIR}"/*.env "${BASE_DIR}/" +# Start docker compose services +print_msg "Starting Docker Compose services..." +docker-compose up -d + +if [ $? -eq 0 ]; then + print_msg "Services started successfully" +else + print_error "Failed to start services" + print_msg "You can try manually with: cd $COMPOSE_DIR && docker-compose up -d" + exit 1 fi -# management.json -if [[ -f "${TEMP_DIR}/management.json" ]]; then - cp -a "${TEMP_DIR}/management.json" "${BASE_DIR}/" +# Wait a moment and show service status +sleep 3 +print_msg "Current service status:" +docker-compose ps + +print_msg "==========================================" +print_msg "Restore completed successfully!" +print_msg "Restored from: $BACKUP_FILE" +if [[ ! "$SAFETY_BACKUP" =~ ^[Nn]$ ]] && [ -f "$SAFETY_FILE" ]; then + print_msg "Safety backup saved at: $SAFETY_FILE" fi +print_msg "==========================================" -# turnserver.conf -if [[ -f "${TEMP_DIR}/turnserver.conf" ]]; then - cp -a "${TEMP_DIR}/turnserver.conf" "${BASE_DIR}/" -fi - -# machinekey directory -if [[ -d "${TEMP_DIR}/machinekey" ]]; then - rm -rf "${BASE_DIR}/machinekey" - cp -a "${TEMP_DIR}/machinekey" "${BASE_DIR}/" -fi - -# traefik-stack directory (if present in backup) -if [[ -d "${TEMP_DIR}/traefik-stack" ]]; then - rm -rf "${BASE_DIR}/traefik-stack" - cp -a "${TEMP_DIR}/traefik-stack" "${BASE_DIR}/" -fi - -# ============================================ -# CLEAN UP TEMP -# ============================================ -echo "[*] Cleaning up temporary directory..." -rm -rf "$TEMP_DIR" - -# ============================================ -# START STACK -# ============================================ -echo "[*] Starting NetBird stack..." -docker compose up -d - -echo "==========================================================" -echo "Restore completed from: $BACKUP_FILE" -echo "NetBird + Zitadel stack should now be running again." -echo "==========================================================" +exit 0 \ No newline at end of file