diff --git a/update.sh b/update.sh index 6d7a7b3..dba6ac7 100644 --- a/update.sh +++ b/update.sh @@ -21,29 +21,74 @@ log() { echo "$1" >>"$LOG_ARCHIVE" } -run_cmd() { - local title="$1"; shift - # console courte + log complet - printf "⏳ %s..." "$title" - { - echo "----- ${title} -----" - echo "CMD: $*" - "$@" - echo "----- FIN ${title} -----" - echo - } >>"$LOG_FILE" 2>&1 - echo " ✅" +log_file_only() { + echo "[$(date -Is)] $*" >>"$LOG_FILE" + echo "[$(date -Is)] $*" >>"$LOG_ARCHIVE" } -# 🔎 APT : nombre de paquets upgradables +# ───────────────────────────── +# ⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏ spinner +# ───────────────────────────── +spinner_start() { + local msg="$1" + local -a frames=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏") + local i=0 + + printf "%s %s" "${frames[0]}" "$msg" + + ( + while true; do + i=$(( (i + 1) % ${#frames[@]} )) + printf "\r%s %s" "${frames[$i]}" "$msg" + sleep 0.12 + done + ) & + SPINNER_PID=$! +} + +spinner_stop() { + local rc="${1:-0}" + if [[ -n "${SPINNER_PID:-}" ]]; then + kill "$SPINNER_PID" >/dev/null 2>&1 || true + wait "$SPINNER_PID" 2>/dev/null || true + unset SPINNER_PID + fi + + if [[ "$rc" -eq 0 ]]; then + printf "\r✅ %s\n" "$2" + else + printf "\r❌ %s\n" "$2" + fi +} + +run_cmd() { + local title="$1"; shift + + spinner_start "$title" + log_file_only "----- ${title} -----" + log_file_only "CMD: $*" + + set +e + "$@" >>"$LOG_FILE" 2>&1 + local rc=$? + set -e + + spinner_stop "$rc" "$title" + + if [[ $rc -ne 0 ]]; then + log_file_only "ERREUR (code=$rc) sur: $title" + return $rc + fi + return 0 +} + +# 🔎 APT : nombre de paquets upgradables (simulation) apt_upgradable_count() { - # On force l’anglais pour un parsing plus stable LC_ALL=C apt-get -s upgrade 2>/dev/null | grep -c '^Inst ' || true } update_apt() { - log "📦 Mise à jour système (APT)" - + log "📦 Mise à jour Debian / Ubuntu (APT)" export DEBIAN_FRONTEND=noninteractive run_cmd "Mise à jour de la liste des paquets" apt-get update -y @@ -54,48 +99,51 @@ update_apt() { if [[ "$n" -eq 0 ]]; then log "✅ Aucun paquet à mettre à jour" - else - run_cmd "Installation des mises à jour (${n} paquet(s))" apt-get upgrade -y - run_cmd "Rechargement systemd (si nécessaire)" systemctl daemon-reload - log "✅ Mise à jour APT terminée" + return 0 fi + + run_cmd "Installation des mises à jour (${n} paquet(s))" apt-get upgrade -y + run_cmd "Rechargement systemd (si nécessaire)" systemctl daemon-reload + log "✅ Mise à jour APT terminée" } update_apk() { - log "📦 Mise à jour système (APK)" + log "📦 Mise à jour Alpine (APK)" run_cmd "Mise à jour des dépôts" apk update - # apk ne donne pas un compteur simple “upgradable” comme apt, - # donc on fait l’upgrade et tout est loggué. run_cmd "Installation des mises à jour" apk upgrade log "✅ Mise à jour APK terminée" } -# 🔎 Docker : ID image docker_image_id() { docker image inspect -f '{{.Id}}' "$1" 2>/dev/null || true } update_docker_compose_dir() { local dir="$1" + log "📂 Projet : ${dir}" - log "📂 Projet Compose : ${dir}" + if docker compose version >/dev/null 2>&1; then + run_cmd "Téléchargement des images (Compose)" bash -c "cd '$dir' && docker compose pull" + run_cmd "Redéploiement des services (Compose)" bash -c "cd '$dir' && docker compose up -d" + return 0 + fi - # pull - run_cmd "Docker Compose pull (${dir})" bash -c "cd '$dir' && docker compose pull" - # up - run_cmd "Docker Compose up -d (${dir})" bash -c "cd '$dir' && docker compose up -d" + if command -v docker-compose >/dev/null 2>&1; then + run_cmd "Téléchargement des images (Compose v1)" bash -c "cd '$dir' && docker-compose pull" + run_cmd "Redéploiement des services (Compose v1)" bash -c "cd '$dir' && docker-compose up -d" + return 0 + fi + + log "❌ Docker Compose n'est pas installé" + return 2 } update_docker() { log "🐳 Mise à jour Docker" - # Vérif docker - if ! docker ps >>"$LOG_FILE" 2>&1; then - log "❌ Docker n'est pas accessible" - return 1 - fi + # Vérif Docker avec spinner aussi + run_cmd "Vérification Docker" docker ps - # 1) Essayer compose via labels (mais seulement si le dossier existe ET contient un compose) log "🔍 Recherche de projets Docker Compose" mapfile -t dirs < <( @@ -113,17 +161,16 @@ update_docker() { fi done - if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1 && (( ${#valid_dirs[@]} > 0 )); then + if (( ${#valid_dirs[@]} > 0 )); then log "📁 Projet(s) Compose détecté(s) : ${#valid_dirs[@]}" for d in "${valid_dirs[@]}"; do update_docker_compose_dir "$d" done - log "✅ Mise à jour Docker (Compose) terminée" + log "✅ Mise à jour Docker terminée" return 0 fi - # 2) Fallback : pull image par image et afficher si ça change - log "⚠️ Aucun Compose utilisable → mise à jour image par image (pull seulement)" + log "⚠️ Aucun projet Compose utilisable → mise à jour image par image" mapfile -t images < <(docker ps --format '{{.Image}}' | sort -u) if (( ${#images[@]} == 0 )); then @@ -135,23 +182,19 @@ update_docker() { for img in "${images[@]}"; do [[ -n "$img" ]] || continue + local old_id new_id old_id="$(docker_image_id "$img")" - # pull (tout dans le log) - { - echo "----- PULL ${img} -----" - docker pull "$img" - echo - } >>"$LOG_FILE" 2>&1 || true + + # Pull avec spinner + run_cmd "Mise à jour de l'image : ${img}" docker pull "$img" new_id="$(docker_image_id "$img")" - # Affichage propre if [[ -n "$old_id" && -n "$new_id" && "$old_id" != "$new_id" ]]; then updated=$((updated+1)) log "⬆️ Image mise à jour : ${img}" log " 🔁 ${old_id:0:20} ➜ ${new_id:0:20}" else - # soit déjà à jour, soit pas d’ID exploitable log "✅ Image déjà à jour : ${img}" if [[ -n "$new_id" ]]; then log " 🏷️ ID : ${new_id:0:20}" @@ -161,41 +204,48 @@ update_docker() { if [[ "$updated" -eq 0 ]]; then log "✅ Aucune mise à jour Docker à appliquer" - log "💡 (Si tu veux une MAJ complète des conteneurs, privilégie Docker Compose)" else log "✅ Images Docker mises à jour : ${updated}" log "⚠️ Note : sans Compose, les conteneurs ne sont pas recréés automatiquement." fi } -# --- Parsing MODE --- -# Exemples : -# - apt -# - apk -# - apt+docker -# - apk+docker +# ───────────────────────────── +# Mode : apt / apk + docker éventuel +# Exemples : apt, apk, apt+docker, apk+docker +# ───────────────────────────── BASE_MODE="${MODE%%+docker}" HAS_DOCKER="0" if [[ "$MODE" == *"+docker" ]]; then HAS_DOCKER="1" fi -log "🧭 Mode de mise à jour : ${MODE}" +# ─────────────── Sections lisibles ─────────────── + +log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +log "📦 Mise à jour du système" +log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -# 1) Toujours mettre à jour le système de base (si possible) case "$BASE_MODE" in apt) update_apt ;; apk) update_apk ;; *) - log "⚠️ Système de base non détecté (apt/apk). On saute la mise à jour OS." + log "⚠️ Impossible de détecter le gestionnaire de paquets (apt/apk)" ;; esac -# 2) Puis Docker si présent if [[ "$HAS_DOCKER" == "1" ]]; then + log "" + log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + log "🐳 Mise à jour du ou des conteneurs" + log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" update_docker +else + log "" + log "🐳 Aucun conteneur Docker détecté" fi +log "" log "🧾 Log update : ${LOG_FILE}" log "🗃️ Archive update : ${LOG_ARCHIVE}" log "🎉 Mise à jour terminée" \ No newline at end of file