Actualiser update.sh

Signed-off-by: thomas <contact@thomasmlg.fr>
This commit is contained in:
2026-03-05 15:44:21 +01:00
parent 3909c4fbc8
commit 1cf3730c2f

124
update.sh
View File

@@ -26,16 +26,13 @@ log_file_only() {
echo "[$(date -Is)] $*" >>"$LOG_ARCHIVE" echo "[$(date -Is)] $*" >>"$LOG_ARCHIVE"
} }
# ─────────────────────────────
# ⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏ spinner # ⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏ spinner
# ─────────────────────────────
spinner_start() { spinner_start() {
local msg="$1" local msg="$1"
local -a frames=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏") local -a frames=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏")
local i=0 local i=0
printf "%s %s" "${frames[0]}" "$msg" printf "%s %s" "${frames[0]}" "$msg"
( (
while true; do while true; do
i=$(( (i + 1) % ${#frames[@]} )) i=$(( (i + 1) % ${#frames[@]} ))
@@ -48,6 +45,8 @@ spinner_start() {
spinner_stop() { spinner_stop() {
local rc="${1:-0}" local rc="${1:-0}"
local msg="$2"
if [[ -n "${SPINNER_PID:-}" ]]; then if [[ -n "${SPINNER_PID:-}" ]]; then
kill "$SPINNER_PID" >/dev/null 2>&1 || true kill "$SPINNER_PID" >/dev/null 2>&1 || true
wait "$SPINNER_PID" 2>/dev/null || true wait "$SPINNER_PID" 2>/dev/null || true
@@ -55,15 +54,14 @@ spinner_stop() {
fi fi
if [[ "$rc" -eq 0 ]]; then if [[ "$rc" -eq 0 ]]; then
printf "\r✅ %s\n" "$2" printf "\r✅ %s\n" "$msg"
else else
printf "\r❌ %s\n" "$2" printf "\r❌ %s\n" "$msg"
fi fi
} }
run_cmd() { run_cmd() {
local title="$1"; shift local title="$1"; shift
spinner_start "$title" spinner_start "$title"
log_file_only "----- ${title} -----" log_file_only "----- ${title} -----"
log_file_only "CMD: $*" log_file_only "CMD: $*"
@@ -82,7 +80,7 @@ run_cmd() {
return 0 return 0
} }
# 🔎 APT : nombre de paquets upgradables (simulation) # 🔎 APT : nombre de paquets upgradables
apt_upgradable_count() { apt_upgradable_count() {
LC_ALL=C apt-get -s upgrade 2>/dev/null | grep -c '^Inst ' || true LC_ALL=C apt-get -s upgrade 2>/dev/null | grep -c '^Inst ' || true
} }
@@ -114,23 +112,32 @@ update_apk() {
log "✅ Mise à jour APK terminée" log "✅ Mise à jour APK terminée"
} }
docker_image_id() { # Compose: détecter dirs via labels + vérifier compose file
docker image inspect -f '{{.Id}}' "$1" 2>/dev/null || true compose_dirs_from_labels() {
docker ps -q | while read -r cid; do
docker inspect -f '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}' "$cid" 2>/dev/null || true
done | sed '/^<no value>$/d;/^$/d' | sort -u
} }
update_docker_compose_dir() { is_compose_dir_valid() {
local d="$1"
[[ -d "$d" ]] && { [[ -f "$d/docker-compose.yml" ]] || [[ -f "$d/compose.yml" ]]; }
}
update_compose_dir() {
local dir="$1" local dir="$1"
log "📂 Projet : ${dir}" log "📂 Projet : $dir"
if docker compose version >/dev/null 2>&1; then 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 "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" # 🔁 Recréation SAFE (volumes conservés)
run_cmd "Redéploiement des services (Compose)" bash -c "cd '$dir' && docker compose up -d --remove-orphans"
return 0 return 0
fi fi
if command -v docker-compose >/dev/null 2>&1; then 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 "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" run_cmd "Redéploiement des services (Compose v1)" bash -c "cd '$dir' && docker-compose up -d --remove-orphans"
return 0 return 0
fi fi
@@ -138,89 +145,42 @@ update_docker_compose_dir() {
return 2 return 2
} }
update_docker() { update_docker_compose() {
log "🐳 Mise à jour Docker" log "🐳 Mise à jour Docker (Compose)"
# Vérif Docker avec spinner aussi
run_cmd "Vérification Docker" docker ps run_cmd "Vérification Docker" docker ps
log "🔍 Recherche de projets Docker Compose" log "🔍 Recherche de projets Docker Compose"
mapfile -t dirs < <(compose_dirs_from_labels)
mapfile -t dirs < <( valid=()
docker ps -q | while read -r cid; do
docker inspect -f '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}' "$cid" 2>/dev/null || true
done | sed '/^<no value>$/d;/^$/d' | sort -u
)
valid_dirs=()
for d in "${dirs[@]}"; do for d in "${dirs[@]}"; do
if [[ -d "$d" ]] && { [[ -f "$d/docker-compose.yml" ]] || [[ -f "$d/compose.yml" ]]; }; then if is_compose_dir_valid "$d"; then
valid_dirs+=("$d") valid+=("$d")
else else
log "⚠️ Compose ignoré (chemin invalide ou sans compose.yml) : $d" log "⚠️ Projet ignoré (chemin invalide ou sans compose.yml) : $d"
fi fi
done done
if (( ${#valid_dirs[@]} > 0 )); then if (( ${#valid[@]} == 0 )); then
log "📁 Projet(s) Compose détecté(s) : ${#valid_dirs[@]}" log "⚠️ Aucun projet Compose détecté"
for d in "${valid_dirs[@]}"; do return 0
update_docker_compose_dir "$d" fi
log "📁 Projet(s) Compose détecté(s) : ${#valid[@]}"
for d in "${valid[@]}"; do
update_compose_dir "$d"
done done
log "✅ Mise à jour Docker terminée" log "✅ Mise à jour Docker terminée"
return 0
fi
log "⚠️ Aucun projet Compose utilisable → mise à jour image par image"
mapfile -t images < <(docker ps --format '{{.Image}}' | sort -u)
if (( ${#images[@]} == 0 )); then
log "✅ Aucun conteneur Docker en cours"
return 0
fi
local updated=0
for img in "${images[@]}"; do
[[ -n "$img" ]] || continue
local old_id new_id
old_id="$(docker_image_id "$img")"
# Pull avec spinner
run_cmd "Mise à jour de l'image : ${img}" docker pull "$img"
new_id="$(docker_image_id "$img")"
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
log "✅ Image déjà à jour : ${img}"
if [[ -n "$new_id" ]]; then
log " 🏷️ ID : ${new_id:0:20}"
fi
fi
done
if [[ "$updated" -eq 0 ]]; then
log "✅ Aucune mise à jour Docker à appliquer"
else
log "✅ Images Docker mises à jour : ${updated}"
log "⚠️ Note : sans Compose, les conteneurs ne sont pas recréés automatiquement."
fi
} }
# ───────────────────────────── # --- Parsing MODE (apt/apk + docker) ---
# Mode : apt / apk + docker éventuel
# Exemples : apt, apk, apt+docker, apk+docker
# ─────────────────────────────
BASE_MODE="${MODE%%+docker}" BASE_MODE="${MODE%%+docker}"
HAS_DOCKER="0" HAS_DOCKER="0"
if [[ "$MODE" == *"+docker" ]]; then [[ "$MODE" == *"+docker" ]] && HAS_DOCKER="1"
HAS_DOCKER="1"
fi
# ─────────────── Sections lisibles ─────────────── # ─────────────── Sortie lisible ───────────────
log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log "📦 Mise à jour du système" log "📦 Mise à jour du système"
@@ -229,9 +189,7 @@ log "━━━━━━━━━━━━━━━━━━━━━━━━━
case "$BASE_MODE" in case "$BASE_MODE" in
apt) update_apt ;; apt) update_apt ;;
apk) update_apk ;; apk) update_apk ;;
*) *) log "⚠️ Impossible de détecter le gestionnaire de paquets (apt/apk)" ;;
log "⚠️ Impossible de détecter le gestionnaire de paquets (apt/apk)"
;;
esac esac
if [[ "$HAS_DOCKER" == "1" ]]; then if [[ "$HAS_DOCKER" == "1" ]]; then
@@ -239,7 +197,7 @@ if [[ "$HAS_DOCKER" == "1" ]]; then
log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log "🐳 Mise à jour du ou des conteneurs" log "🐳 Mise à jour du ou des conteneurs"
log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
update_docker update_docker_compose
else else
log "" log ""
log "🐳 Aucun conteneur Docker détecté" log "🐳 Aucun conteneur Docker détecté"