Enhance backup/restore/update scripts with security and best practices
- Security improvements: set -euo pipefail, secure .env loading, safe PGPASSWORD handling - Add comprehensive logging to ./logs/ directory for all operations - Implement SHA256 checksums for backup integrity verification - Add lock file mechanism to prevent concurrent backups - Improve error handling with detailed exit codes and cleanup functions - Add safety backup of current DB before restore operations - Backup docker-compose.yml before updates with auto-restore on failure - Replace wget with curl for better reliability in health checks - Use find -mindepth for safer data directory cleanup - Add progress indicators with file sizes and operation statistics - Validate paths and checksums before restore operations - All operations now log to timestamped files with full traceability 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,102 +5,173 @@
|
||||
# Ce script met à jour Gitea de manière sécurisée
|
||||
# avec une sauvegarde automatique avant la mise à jour
|
||||
|
||||
set -e # Arrêter en cas d'erreur
|
||||
set -euo pipefail # Arrêter en cas d'erreur, variables non définies, erreurs dans pipes
|
||||
|
||||
# Couleurs pour l'affichage
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Charger les variables d'environnement
|
||||
# Charger les variables d'environnement de manière sécurisée
|
||||
if [ -f .env ]; then
|
||||
set -a
|
||||
source .env
|
||||
set +a
|
||||
else
|
||||
echo -e "${RED}Erreur: Fichier .env non trouvé${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Fonction de nettoyage en cas d'erreur
|
||||
cleanup() {
|
||||
echo -e "${YELLOW}Une erreur s'est produite. Vérifiez l'état des services.${NC}"
|
||||
echo "Pour revenir à l'état précédent, utilisez la dernière sauvegarde:"
|
||||
echo " make restore FILE=backups/gitea_backup_*.tar.gz"
|
||||
# Variables
|
||||
LOG_DIR="./logs"
|
||||
LOG_FILE="${LOG_DIR}/update_$(date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
# Créer le répertoire de logs
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# Fonction de logging
|
||||
log() {
|
||||
echo -e "$@" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
trap cleanup ERR
|
||||
# Fonction de nettoyage en cas d'erreur
|
||||
cleanup() {
|
||||
local exit_code=$?
|
||||
if [ $exit_code -ne 0 ]; then
|
||||
log "${RED}Erreur lors de la mise à jour (code: $exit_code)${NC}"
|
||||
log "${YELLOW}Vérifiez l'état des services: docker compose ps${NC}"
|
||||
log "Pour revenir à l'état précédent, utilisez la dernière sauvegarde:"
|
||||
LATEST_BACKUP=$(ls -t backups/gitea_backup_*.tar.gz 2>/dev/null | head -n 1)
|
||||
if [ -n "$LATEST_BACKUP" ]; then
|
||||
log " make restore FILE=$LATEST_BACKUP"
|
||||
fi
|
||||
log "Log: $LOG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
echo -e "${GREEN}=== Mise à jour de Gitea ===${NC}"
|
||||
echo ""
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
log "${GREEN}=== Mise à jour de Gitea ===${NC}"
|
||||
log "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] Début de la mise à jour${NC}"
|
||||
log ""
|
||||
|
||||
# Sauvegarder la version actuelle
|
||||
CURRENT_VERSION=""
|
||||
if docker compose ps | grep -q 'gitea.*running'; then
|
||||
CURRENT_VERSION=$(docker compose exec -T gitea gitea --version 2>/dev/null | head -n 1 || echo "Inconnue")
|
||||
log "Version actuelle: $CURRENT_VERSION"
|
||||
fi
|
||||
|
||||
# Vérifier que les services tournent
|
||||
if ! docker compose ps | grep -q "gitea.*running"; then
|
||||
echo -e "${YELLOW}Avertissement: Gitea ne semble pas être en cours d'exécution${NC}"
|
||||
if ! docker compose ps | grep -q 'gitea.*running'; then
|
||||
log "${YELLOW}Avertissement: Gitea ne semble pas être en cours d'exécution${NC}"
|
||||
read -p "Continuer quand même? (oui/non) " -r
|
||||
if [[ ! $REPLY =~ ^[Oo][Uu][Ii]$ ]]; then
|
||||
echo "Mise à jour annulée."
|
||||
log "Mise à jour annulée par l'utilisateur."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}[1/6] Création d'une sauvegarde de sécurité...${NC}"
|
||||
if ! bash scripts/backup.sh; then
|
||||
echo -e "${RED}Erreur: La sauvegarde a échoué. Mise à jour annulée.${NC}"
|
||||
log "${YELLOW}[1/7] Sauvegarde du docker-compose.yml...${NC}"
|
||||
# Sauvegarder docker-compose.yml au cas où
|
||||
COMPOSE_BACKUP="docker-compose.yml.backup.$(date +%Y%m%d_%H%M%S)"
|
||||
if [ -f docker-compose.yml ]; then
|
||||
cp docker-compose.yml "$COMPOSE_BACKUP"
|
||||
log "${GREEN}✓ docker-compose.yml sauvegardé: $COMPOSE_BACKUP${NC}"
|
||||
else
|
||||
log "${YELLOW}Avertissement: docker-compose.yml non trouvé${NC}"
|
||||
fi
|
||||
|
||||
log "${YELLOW}[2/7] Création d'une sauvegarde de sécurité...${NC}"
|
||||
if ! bash scripts/backup.sh 2>&1 | tee -a "$LOG_FILE"; then
|
||||
log "${RED}Erreur: La sauvegarde a échoué. Mise à jour annulée.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN}✓ Sauvegarde créée${NC}"
|
||||
log "${GREEN}✓ Sauvegarde créée${NC}"
|
||||
|
||||
echo -e "${YELLOW}[2/6] Téléchargement des nouvelles images...${NC}"
|
||||
docker compose pull
|
||||
echo -e "${GREEN}✓ Images téléchargées${NC}"
|
||||
log "${YELLOW}[3/7] Téléchargement des nouvelles images...${NC}"
|
||||
if ! docker compose pull 2>&1 | tee -a "$LOG_FILE"; then
|
||||
log "${RED}Erreur: Échec du téléchargement des images${NC}"
|
||||
exit 1
|
||||
fi
|
||||
log "${GREEN}✓ Images téléchargées${NC}"
|
||||
|
||||
echo -e "${YELLOW}[3/6] Arrêt des services...${NC}"
|
||||
docker compose down
|
||||
echo -e "${GREEN}✓ Services arrêtés${NC}"
|
||||
log "${YELLOW}[4/7] Arrêt des services...${NC}"
|
||||
if ! docker compose down 2>&1 | tee -a "$LOG_FILE"; then
|
||||
log "${YELLOW}Avertissement: Erreur lors de l'arrêt des services${NC}"
|
||||
fi
|
||||
log "${GREEN}✓ Services arrêtés${NC}"
|
||||
|
||||
echo -e "${YELLOW}[4/6] Démarrage avec les nouvelles versions...${NC}"
|
||||
docker compose up -d
|
||||
echo -e "${GREEN}✓ Services démarrés${NC}"
|
||||
log "${YELLOW}[5/7] Démarrage avec les nouvelles versions...${NC}"
|
||||
if ! docker compose up -d 2>&1 | tee -a "$LOG_FILE"; then
|
||||
log "${RED}Erreur: Échec du démarrage des services${NC}"
|
||||
exit 1
|
||||
fi
|
||||
log "${GREEN}✓ Services démarrés${NC}"
|
||||
|
||||
echo -e "${YELLOW}[5/6] Attente du démarrage complet...${NC}"
|
||||
log "${YELLOW}[6/7] Attente du démarrage complet et health check...${NC}"
|
||||
sleep 10
|
||||
|
||||
# Attendre que Gitea soit prêt
|
||||
# Attendre que Gitea soit prêt (utiliser curl au lieu de wget)
|
||||
MAX_TRIES=60
|
||||
COUNTER=0
|
||||
until docker compose exec -T gitea wget -q --spider http://localhost:3000/api/healthz 2>/dev/null; do
|
||||
until docker compose exec -T gitea curl -sf http://localhost:3000/api/healthz >/dev/null 2>&1; do
|
||||
COUNTER=$((COUNTER + 1))
|
||||
if [ $COUNTER -gt $MAX_TRIES ]; then
|
||||
echo -e "${RED}Erreur: Gitea ne répond pas après la mise à jour${NC}"
|
||||
echo "Vérifiez les logs: docker compose logs gitea"
|
||||
log "${RED}Erreur: Gitea ne répond pas après la mise à jour${NC}"
|
||||
log "Vérifiez les logs: docker compose logs gitea"
|
||||
log "${YELLOW}Tentative de restauration automatique...${NC}"
|
||||
|
||||
# Essayer de restaurer le docker-compose.yml
|
||||
if [ -f "$COMPOSE_BACKUP" ]; then
|
||||
cp "$COMPOSE_BACKUP" docker-compose.yml
|
||||
log "docker-compose.yml restauré"
|
||||
fi
|
||||
|
||||
exit 1
|
||||
fi
|
||||
echo "En attente de Gitea... ($COUNTER/$MAX_TRIES)"
|
||||
log "En attente de Gitea... ($COUNTER/$MAX_TRIES)"
|
||||
sleep 2
|
||||
done
|
||||
echo -e "${GREEN}✓ Gitea répond${NC}"
|
||||
log "${GREEN}✓ Gitea répond et est opérationnel${NC}"
|
||||
|
||||
echo -e "${YELLOW}[6/6] Vérification de l'état...${NC}"
|
||||
# Afficher les versions
|
||||
echo ""
|
||||
echo "Versions actuelles:"
|
||||
docker compose images
|
||||
log "${YELLOW}[7/7] Vérification de l'état et de la version...${NC}"
|
||||
|
||||
echo ""
|
||||
echo "État des services:"
|
||||
docker compose ps
|
||||
# Obtenir la nouvelle version
|
||||
NEW_VERSION=$(docker compose exec -T gitea gitea --version 2>/dev/null | head -n 1 || echo "Inconnue")
|
||||
log "Nouvelle version: $NEW_VERSION"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}=== Mise à jour terminée avec succès ===${NC}"
|
||||
echo ""
|
||||
echo "Vérifications recommandées:"
|
||||
echo " 1. Accéder à l'interface web: http://localhost:3000"
|
||||
echo " 2. Vérifier les dépôts existants"
|
||||
echo " 3. Tester les fonctionnalités principales"
|
||||
echo " 4. Consulter les logs: docker compose logs -f gitea"
|
||||
echo ""
|
||||
echo "En cas de problème, restaurez la sauvegarde:"
|
||||
# Afficher les versions des images
|
||||
log ""
|
||||
log "Images Docker:"
|
||||
docker compose images 2>&1 | tee -a "$LOG_FILE"
|
||||
|
||||
log ""
|
||||
log "État des services:"
|
||||
docker compose ps 2>&1 | tee -a "$LOG_FILE"
|
||||
|
||||
# Supprimer l'ancien backup docker-compose.yml si tout s'est bien passé
|
||||
if [ -f "$COMPOSE_BACKUP" ]; then
|
||||
rm -f "$COMPOSE_BACKUP"
|
||||
log "Backup temporaire docker-compose.yml supprimé"
|
||||
fi
|
||||
|
||||
log ""
|
||||
log "${GREEN}=== Mise à jour terminée avec succès ===${NC}"
|
||||
log ""
|
||||
log "Vérifications recommandées:"
|
||||
log " 1. Accéder à l'interface web: http://localhost:3000"
|
||||
log " 2. Vérifier les dépôts existants"
|
||||
log " 3. Tester les fonctionnalités principales"
|
||||
log " 4. Consulter les logs: docker compose logs -f gitea"
|
||||
log ""
|
||||
log "En cas de problème, restaurez la sauvegarde:"
|
||||
LATEST_BACKUP=$(ls -t backups/gitea_backup_*.tar.gz 2>/dev/null | head -n 1)
|
||||
if [ -n "$LATEST_BACKUP" ]; then
|
||||
echo " make restore FILE=$LATEST_BACKUP"
|
||||
log " make restore FILE=$LATEST_BACKUP"
|
||||
fi
|
||||
log ""
|
||||
log "Log de mise à jour: $LOG_FILE"
|
||||
log "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] Mise à jour terminée${NC}"
|
||||
|
||||
Reference in New Issue
Block a user