Files
stechuhr3/scripts/restore-backup.sh

276 lines
8.1 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# =============================================================================
# TimeClock v3 - Backup-Restore Script
# =============================================================================
# Stellt ein Datenbank-Backup wieder her
#
# Verwendung:
# ./restore-backup.sh [BACKUP_FILE]
# ./restore-backup.sh # Zeigt Liste der verfügbaren Backups
# ./restore-backup.sh timeclock_db_20251018_020000.sql.gz
#
# WARNUNG: Dies überschreibt die aktuelle Datenbank!
# =============================================================================
set -e
# Farben
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Konfiguration
BACKUP_DIR="/var/backups/timeclock"
PROJECT_DIR="/var/www/timeclock"
ENV_FILE="$PROJECT_DIR/backend/.env"
# Logging
log() {
echo -e "${BLUE} $1${NC}"
}
log_success() {
echo -e "${GREEN}$1${NC}"
}
log_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
log_error() {
echo -e "${RED}$1${NC}"
}
# =============================================================================
# Voraussetzungen prüfen
# =============================================================================
if [ ! -f "$ENV_FILE" ]; then
log_error ".env Datei nicht gefunden: $ENV_FILE"
exit 1
fi
if [ ! -d "$BACKUP_DIR" ]; then
log_error "Backup-Verzeichnis nicht gefunden: $BACKUP_DIR"
exit 1
fi
# =============================================================================
# Datenbank-Credentials aus .env lesen
# =============================================================================
get_env_value() {
grep "^$1=" "$ENV_FILE" | cut -d '=' -f2- | tr -d '"' | tr -d "'"
}
DB_HOST=$(get_env_value "DB_HOST")
DB_PORT=$(get_env_value "DB_PORT")
DB_NAME=$(get_env_value "DB_NAME")
DB_USER=$(get_env_value "DB_USER")
DB_PASSWORD=$(get_env_value "DB_PASSWORD")
# Defaults
DB_HOST=${DB_HOST:-localhost}
DB_PORT=${DB_PORT:-3306}
if [ -z "$DB_NAME" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ]; then
log_error "Datenbank-Credentials unvollständig in .env"
exit 1
fi
# =============================================================================
# Verfügbare Backups auflisten
# =============================================================================
list_backups() {
echo ""
log "Verfügbare Backups in $BACKUP_DIR:"
echo ""
BACKUPS=($(ls -t "$BACKUP_DIR"/timeclock_db_*.sql.gz 2>/dev/null))
if [ ${#BACKUPS[@]} -eq 0 ]; then
log_warning "Keine Backups gefunden!"
exit 1
fi
for i in "${!BACKUPS[@]}"; do
BACKUP="${BACKUPS[$i]}"
FILENAME=$(basename "$BACKUP")
SIZE=$(du -h "$BACKUP" | cut -f1)
DATE=$(stat -c %y "$BACKUP" | cut -d'.' -f1)
printf "%2d) %-50s %6s %s\n" $((i+1)) "$FILENAME" "$SIZE" "$DATE"
done
echo ""
}
# =============================================================================
# Backup-Datei auswählen
# =============================================================================
select_backup() {
list_backups
read -p "Wähle ein Backup (Nummer) oder 'q' zum Beenden: " selection
if [ "$selection" = "q" ] || [ "$selection" = "Q" ]; then
log "Abgebrochen."
exit 0
fi
if ! [[ "$selection" =~ ^[0-9]+$ ]]; then
log_error "Ungültige Eingabe!"
exit 1
fi
BACKUPS=($(ls -t "$BACKUP_DIR"/timeclock_db_*.sql.gz 2>/dev/null))
INDEX=$((selection - 1))
if [ $INDEX -lt 0 ] || [ $INDEX -ge ${#BACKUPS[@]} ]; then
log_error "Ungültige Auswahl!"
exit 1
fi
BACKUP_FILE="${BACKUPS[$INDEX]}"
}
# =============================================================================
# Restore durchführen
# =============================================================================
restore_backup() {
local backup_file=$1
if [ ! -f "$backup_file" ]; then
log_error "Backup-Datei nicht gefunden: $backup_file"
exit 1
fi
echo ""
log_warning "WARNUNG: Dies wird die aktuelle Datenbank '$DB_NAME' überschreiben!"
log "Backup-Datei: $(basename $backup_file)"
log "Größe: $(du -h $backup_file | cut -f1)"
log "Datenbank: $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME"
echo ""
read -p "Fortfahren? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then
log "Abgebrochen."
exit 0
fi
# Erstelle Backup der aktuellen Datenbank (Sicherheitskopie)
log "Erstelle Sicherheitskopie der aktuellen Datenbank..."
SAFETY_BACKUP="$BACKUP_DIR/timeclock_db_pre_restore_$(date +%Y%m%d_%H%M%S).sql.gz"
if mysqldump \
--host="$DB_HOST" \
--port="$DB_PORT" \
--user="$DB_USER" \
--password="$DB_PASSWORD" \
--single-transaction \
--databases "$DB_NAME" \
| gzip > "$SAFETY_BACKUP"; then
log_success "Sicherheitskopie erstellt: $(basename $SAFETY_BACKUP)"
else
log_error "Sicherheitskopie fehlgeschlagen!"
read -p "Trotzdem fortfahren? (yes/no): " force
if [ "$force" != "yes" ]; then
exit 1
fi
fi
# Restore durchführen
log "Stelle Backup wieder her..."
# Datenbank leeren (optional, aber empfohlen)
log "Leere Datenbank..."
mysql \
--host="$DB_HOST" \
--port="$DB_PORT" \
--user="$DB_USER" \
--password="$DB_PASSWORD" \
-e "DROP DATABASE IF EXISTS $DB_NAME; CREATE DATABASE $DB_NAME;"
# Backup einspielen
if gunzip < "$backup_file" | mysql \
--host="$DB_HOST" \
--port="$DB_PORT" \
--user="$DB_USER" \
--password="$DB_PASSWORD"; then
log_success "Backup erfolgreich wiederhergestellt!"
# Datenbank-Statistiken
TABLE_COUNT=$(mysql \
--host="$DB_HOST" \
--port="$DB_PORT" \
--user="$DB_USER" \
--password="$DB_PASSWORD" \
-e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '$DB_NAME';" -s -N)
log "Datenbank-Statistik:"
log " 📊 Tabellen: $TABLE_COUNT"
# Optional: Service neu starten
log_warning "Möchtest du den Backend-Service neu starten?"
read -p "Service neu starten? (y/n): " restart
if [ "$restart" = "y" ] || [ "$restart" = "Y" ]; then
if command -v pm2 &> /dev/null && pm2 list | grep -q "timeclock-backend"; then
pm2 restart timeclock-backend
log_success "PM2-Service neu gestartet"
elif systemctl is-active --quiet timeclock; then
sudo systemctl restart timeclock
log_success "systemd-Service neu gestartet"
else
log_warning "Service-Verwaltung nicht gefunden - bitte manuell neu starten"
fi
fi
echo ""
log_success "Restore abgeschlossen!"
log "Sicherheitskopie der alten Datenbank: $(basename $SAFETY_BACKUP)"
else
log_error "Restore fehlgeschlagen!"
log "Die Sicherheitskopie befindet sich unter: $(basename $SAFETY_BACKUP)"
exit 1
fi
}
# =============================================================================
# Hauptprogramm
# =============================================================================
echo ""
echo -e "${BLUE}════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE} TimeClock v3 - Backup Restore${NC}"
echo -e "${BLUE}════════════════════════════════════════════════════════════${NC}"
echo ""
# Wenn Backup-Datei als Argument übergeben wurde
if [ $# -eq 1 ]; then
BACKUP_FILE="$1"
# Wenn nur Dateiname (ohne Pfad) übergeben wurde
if [ ! -f "$BACKUP_FILE" ]; then
BACKUP_FILE="$BACKUP_DIR/$1"
fi
restore_backup "$BACKUP_FILE"
else
# Interaktive Auswahl
select_backup
restore_backup "$BACKUP_FILE"
fi
exit 0