Files
docker-stack-template/gitea-auto-update.sh
T

139 lines
7.0 KiB
Bash
Executable File

#!/bin/bash
# =============================================================================
# gitea-auto-update.sh — Vérifie et applique les mises à jour Gitea Docker
# =============================================================================
# À placer dans /usr/local/bin/ ou ~/scripts/
# Cron recommandé : 0 4 * * * /usr/local/bin/gitea-auto-update.sh
#
# Paramètres configurables (modifier ci-dessous ou passer en variables d'env)
# =============================================================================
set -euo pipefail
# ─── Configuration (modifiable) ─────────────────────────────────────────────
COMPOSE_DIR="${COMPOSE_DIR:-$HOME/dev/git/outils/gitea}"
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}"
CONTAINER_NAME="${CONTAINER_NAME:-gitea_server}"
IMAGE_NAME="${IMAGE_NAME:-gitea/gitea}"
IMAGE_TAG="${IMAGE_TAG:-latest}" # "latest" ou version spécifique
LOG_FILE="${LOG_FILE:-/var/log/gitea-update.log}"
ENABLE_NOTIFICATIONS="${ENABLE_NOTIFICATIONS:-false}" # true pour envoyer un résumé
NOTIFY_METHOD="${NOTIFY_METHOD:-log}" # log, telegram, ntfy
TELEGRAM_CHAT_ID="${TELEGRAM_CHAT_ID:-}"
NTPY_TOPIC="${NTPY_TOPIC:-}"
HEALTH_CHECK_URL="${HEALTH_CHECK_URL:-http://localhost:3000}"
HEALTH_CHECK_TIMEOUT="${HEALTH_CHECK_TIMEOUT:-30}"
# ─── Logging ─────────────────────────────────────────────────────────────────
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
notify() {
local msg="$1"
case "$NOTIFY_METHOD" in
telegram)
[[ -n "$TELEGRAM_CHAT_ID" ]] && curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
-d "chat_id=$TELEGRAM_CHAT_ID" -d "text=$msg" > /dev/null 2>&1 || true
;;
ntfy)
[[ -n "$NTPY_TOPIC" ]] && curl -s -H "Title: Gitea Update" -d "$msg" "https://ntfy.sh/$NTPY_TOPIC" > /dev/null 2>&1 || true
;;
esac
}
log "════════════════════════════════════════════════════════"
log "🔄 Début vérification mise à jour Gitea"
# ─── Pré-vérifications ──────────────────────────────────────────────────────
cd "$COMPOSE_DIR" || { log "❌ Répertoire $COMPOSE_DIR introuvable"; exit 1; }
if ! command -v docker &>/dev/null; then
log "❌ Docker n'est pas installé"
exit 1
fi
# ─── Récupérer l'image digest actuelle ──────────────────────────────────────
OLD_DIGEST=$(docker image inspect "${IMAGE_NAME}:${IMAGE_TAG}" --format '{{.RepoDigests}}' 2>/dev/null | grep -oP 'sha256:[a-f0-9]+' || echo "")
log "📦 Image actuelle : ${IMAGE_NAME}:${IMAGE_TAG}"
log "🔍 Digest actuel : ${OLD_DIGEST:-non disponible}"
# ─── Pull de la nouvelle image ──────────────────────────────────────────────
log "📥 Pull de la nouvelle image..."
PULL_OUTPUT=$(docker compose -f "$COMPOSE_FILE" pull "$CONTAINER_NAME" 2>&1)
PULL_EXIT=$?
if [[ $PULL_EXIT -ne 0 ]]; then
log "❌ Échec du pull : $PULL_OUTPUT"
exit 1
fi
NEW_DIGEST=$(docker image inspect "${IMAGE_NAME}:${IMAGE_TAG}" --format '{{.RepoDigests}}' 2>/dev/null | grep -oP 'sha256:[a-f0-9]+' || echo "")
log "🔍 Nouveau digest : ${NEW_DIGEST:-non disponible}"
# ─── Comparer les digests ───────────────────────────────────────────────────
if [[ -n "$OLD_DIGEST" ]] && [[ -n "$NEW_DIGEST" ]] && [[ "$OLD_DIGEST" == "$NEW_DIGEST" ]]; then
log "✅ Aucune mise à jour disponible (digest identique)"
log "═══ Fin ───────────────────────────────────────────"
exit 0
fi
# ─── MISE À JOUR NÉCESSAIRE ─────────────────────────────────────────────────
log "🔔 Nouvelle version détectée ! Mise à jour en cours..."
# Backup rapide avant mise à jour (optionnel, le script de backup complet gère le quotidien)
BACKUP_PRE_DIR="${BACKUP_PRE_DIR:-/tmp/gitea-pre-update-$(date +%Y%m%d-%H%M%S)}"
mkdir -p "$BACKUP_PRE_DIR"
log "💾 Backup pré-update vers $BACKUP_PRE_DIR"
docker exec gitea_db mysqldump -u root -pgitea gitea > "$BACKUP_PRE_DIR/gitea_db.sql" 2>/dev/null || {
log "⚠️ Backup pré-update DB échoué, on continue quand même"
}
# Recréer le conteneur avec la nouvelle image
log "🚀 Redémarrage du conteneur avec la nouvelle image..."
UP_OUTPUT=$(docker compose -f "$COMPOSE_FILE" up -d "$CONTAINER_NAME" 2>&1)
UP_EXIT=$?
if [[ $UP_EXIT -ne 0 ]]; then
log "❌ Échec du redémarrage : $UP_OUTPUT"
log "⚠️ Tentative de rollback..."
docker compose -f "$COMPOSE_FILE" up -d "$CONTAINER_NAME" 2>&1 || true
notify "❌ GITEA UPDATE FAILED sur $(hostname) — rollback effectué"
exit 1
fi
# ─── Vérification santé ─────────────────────────────────────────────────────
log "🏥 Vérification santé (timeout=${HEALTH_CHECK_TIMEOUT}s)..."
for i in $(seq 1 "$HEALTH_CHECK_TIMEOUT"); do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$HEALTH_CHECK_URL" 2>/dev/null || echo "000")
if [[ "$STATUS" == "200" || "$STATUS" == "302" || "$STATUS" == "303" ]]; then
log "✅ Gitea répond (HTTP $STATUS) après ${i}s"
break
fi
if [[ $i -eq "$HEALTH_CHECK_TIMEOUT" ]]; then
log "❌ Gitea ne répond pas après ${HEALTH_CHECK_TIMEOUT}s"
notify "⚠️ GITEA UPDATE : service lent à démarrer sur $(hostname) — vérifier"
exit 1
fi
sleep 1
done
# ─── Rapport final ──────────────────────────────────────────────────────────
GITEA_VERSION=$(curl -s "$HEALTH_CHECK_URL/api/v1/version" 2>/dev/null | grep -oP '"version":"\K[^"]+' || echo "inconnue")
log "✅ Mise à jour réussie !"
log "📋 Nouvelle version : $GITEA_VERSION"
log "📋 Ancien digest : ${OLD_DIGEST:-N/A}"
log "📋 Nouveau digest : ${NEW_DIGEST:-N/A}"
log "═══ Fin ───────────────────────────────────────────"
notify "✅ Gitea mis à jour vers $GITEA_VERSION sur $(hostname)"
# Nettoyage vieilles images
docker image prune -f 2>/dev/null || true
exit 0