181 lines
5.2 KiB
Bash
Executable File
181 lines
5.2 KiB
Bash
Executable File
#!/bin/bash
|
||
# scripts/restore.sh - Restauration d'un backup
|
||
|
||
set -euo pipefail
|
||
|
||
# Charger les variables d'environnement
|
||
if [ ! -f .env ]; then
|
||
echo "❌ Erreur: Fichier .env introuvable"
|
||
exit 1
|
||
fi
|
||
|
||
# shellcheck disable=SC1091
|
||
source .env
|
||
|
||
# Vérifier les variables requises
|
||
: "${MYSQL_USER:?Variable MYSQL_USER non définie}"
|
||
: "${MYSQL_PASSWORD:?Variable MYSQL_PASSWORD non définie}"
|
||
: "${MYSQL_DATABASE:?Variable MYSQL_DATABASE non définie}"
|
||
|
||
if [ -z "${1:-}" ]; then
|
||
echo "Usage: $0 <backup_file.tar.gz>"
|
||
exit 1
|
||
fi
|
||
|
||
BACKUP_FILE="$1"
|
||
|
||
# Valider le chemin du fichier (éviter path traversal)
|
||
if [[ "$BACKUP_FILE" =~ \.\./\.\. ]]; then
|
||
echo "❌ Chemin de fichier invalide"
|
||
exit 1
|
||
fi
|
||
|
||
if [ ! -f "$BACKUP_FILE" ]; then
|
||
echo "❌ Fichier introuvable: $BACKUP_FILE"
|
||
exit 1
|
||
fi
|
||
|
||
# Vérifier que c'est bien un fichier tar.gz
|
||
if ! file "$BACKUP_FILE" | grep -q "gzip compressed"; then
|
||
echo "❌ Le fichier n'est pas une archive gzip valide"
|
||
exit 1
|
||
fi
|
||
|
||
echo "⚠️ ATTENTION: Cette opération va écraser les données actuelles !"
|
||
read -r -p "Continuer? (yes/no): " confirm
|
||
|
||
if [ "$confirm" != "yes" ]; then
|
||
echo "Annulé."
|
||
exit 0
|
||
fi
|
||
|
||
# Extraire le backup
|
||
TEMP_DIR=$(mktemp -d)
|
||
|
||
# Fonction de nettoyage
|
||
cleanup() {
|
||
local exit_code=$?
|
||
if [ -d "$TEMP_DIR" ]; then
|
||
echo "🧹 Nettoyage du répertoire temporaire..."
|
||
rm -rf "${TEMP_DIR:?}"
|
||
fi
|
||
exit "$exit_code"
|
||
}
|
||
|
||
trap cleanup EXIT INT TERM
|
||
|
||
echo "📂 Extraction vers $TEMP_DIR..."
|
||
if ! tar -xzf "$BACKUP_FILE" -C "$TEMP_DIR"; then
|
||
echo "❌ Erreur lors de l'extraction"
|
||
exit 1
|
||
fi
|
||
|
||
# Trouver le répertoire de backup de manière sécurisée
|
||
BACKUP_DIR=$(find "$TEMP_DIR" -mindepth 1 -maxdepth 1 -type d | head -n1)
|
||
if [ -z "$BACKUP_DIR" ]; then
|
||
echo "❌ Aucun répertoire trouvé dans l'archive"
|
||
exit 1
|
||
fi
|
||
|
||
BACKUP_DIR=$(basename "$BACKUP_DIR")
|
||
|
||
# Arrêter les services
|
||
echo "⏹️ Arrêt des services..."
|
||
docker-compose down
|
||
|
||
# Vérifier que les fichiers requis existent
|
||
if [ ! -f "$TEMP_DIR/$BACKUP_DIR/database.sql" ]; then
|
||
echo "❌ Fichier database.sql manquant dans l'archive"
|
||
exit 1
|
||
fi
|
||
|
||
if [ ! -f "$TEMP_DIR/$BACKUP_DIR/config.tar.gz" ]; then
|
||
echo "❌ Fichier config.tar.gz manquant dans l'archive"
|
||
exit 1
|
||
fi
|
||
|
||
# Restaurer la base de données
|
||
echo "💾 Restauration de la base de données..."
|
||
docker-compose up -d db
|
||
|
||
# Attendre que la base de données soit prête
|
||
echo "⏳ Attente de la base de données..."
|
||
for i in {1..30}; do
|
||
if docker-compose exec -T db mysqladmin ping -h localhost --silent 2>/dev/null; then
|
||
echo "✅ Base de données prête"
|
||
break
|
||
fi
|
||
if [ "$i" -eq 30 ]; then
|
||
echo "❌ Timeout: La base de données n'est pas prête"
|
||
exit 1
|
||
fi
|
||
sleep 1
|
||
done
|
||
|
||
# Restaurer avec MYSQL_PWD pour éviter le mot de passe dans la commande
|
||
if ! docker-compose exec -T db sh -c "MYSQL_PWD=\"\$MYSQL_PASSWORD\" mysql \
|
||
-u\"\$MYSQL_USER\" \
|
||
\"\$MYSQL_DATABASE\"" < "$TEMP_DIR/$BACKUP_DIR/database.sql"; then
|
||
echo "❌ Erreur lors de la restauration de la base de données"
|
||
exit 1
|
||
fi
|
||
|
||
# Redémarrer tous les services d'abord
|
||
echo "▶️ Démarrage des services..."
|
||
docker-compose up -d
|
||
|
||
# Attendre que Nextcloud soit prêt
|
||
echo "⏳ Attente du démarrage de Nextcloud..."
|
||
for i in {1..60}; do
|
||
if docker-compose exec -T nextcloud curl -f http://localhost/status.php >/dev/null 2>&1; then
|
||
echo "✅ Nextcloud prêt"
|
||
break
|
||
fi
|
||
if [ "$i" -eq 60 ]; then
|
||
echo "❌ Timeout: Nextcloud n'est pas prêt"
|
||
exit 1
|
||
fi
|
||
sleep 1
|
||
done
|
||
|
||
# Restaurer les fichiers via le container pour éviter les problèmes de permissions
|
||
echo "📁 Restauration des fichiers..."
|
||
|
||
# Restaurer la configuration
|
||
if ! docker-compose exec -T -u www-data nextcloud tar -xzf - -C /var/www/html/config < "$TEMP_DIR/$BACKUP_DIR/config.tar.gz"; then
|
||
echo "❌ Erreur lors de la restauration de la configuration"
|
||
exit 1
|
||
fi
|
||
|
||
# Restaurer les données
|
||
if [ -f "$TEMP_DIR/$BACKUP_DIR/data.tar.gz" ]; then
|
||
echo "📦 Restauration des données utilisateurs..."
|
||
if ! docker-compose exec -T -u www-data nextcloud tar -xzf - -C /var/www/html/data < "$TEMP_DIR/$BACKUP_DIR/data.tar.gz"; then
|
||
echo "❌ Erreur lors de la restauration des données"
|
||
exit 1
|
||
fi
|
||
elif [ -d "$TEMP_DIR/$BACKUP_DIR/data" ]; then
|
||
echo "⚠️ Format de backup rsync détecté, copie manuelle nécessaire"
|
||
echo " Utilisez: docker cp pour copier $TEMP_DIR/$BACKUP_DIR/data/ vers le container"
|
||
fi
|
||
|
||
# Restaurer les apps personnalisées si présentes
|
||
if [ -f "$TEMP_DIR/$BACKUP_DIR/apps.tar.gz" ]; then
|
||
echo "📦 Restauration des apps personnalisées..."
|
||
docker-compose exec -T -u www-data nextcloud tar -xzf - -C /var/www/html/custom_apps < "$TEMP_DIR/$BACKUP_DIR/apps.tar.gz" || echo "ℹ️ Pas d'apps à restaurer"
|
||
fi
|
||
|
||
# Réparer
|
||
echo "🔧 Réparation..."
|
||
docker-compose exec -T -u www-data nextcloud php occ maintenance:repair || echo "⚠️ Erreur lors de la réparation"
|
||
|
||
# Désactiver le mode maintenance avant le scan
|
||
echo "▶️ Désactivation du mode maintenance..."
|
||
docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off || echo "⚠️ Impossible de désactiver le mode maintenance"
|
||
|
||
# Scanner les fichiers
|
||
echo "🔍 Scan des fichiers..."
|
||
docker-compose exec -T -u www-data nextcloud php occ files:scan --all || echo "⚠️ Erreur lors du scan"
|
||
|
||
echo "✅ Restauration terminée !"
|