189
update.sh
189
update.sh
@@ -1,57 +1,101 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
METHOD="${1:-unknown}"
|
||||
MODE="${1:-unknown}"
|
||||
|
||||
LOG_DIR="/var/log/lxc-updater-TM"
|
||||
# 📁 Logs par date
|
||||
LOG_ROOT="/var/log/lxc-updater-TM"
|
||||
DATE="$(date +%F)"
|
||||
TS="$(date +%H%M%S)"
|
||||
LOG_DIR="${LOG_ROOT}/${DATE}"
|
||||
LOG_FILE="${LOG_DIR}/lxc-updater-update.log"
|
||||
LOG_ARCHIVE="${LOG_DIR}/lxc-updater-update-${TS}.log"
|
||||
|
||||
mkdir -p "$LOG_DIR"
|
||||
: > "$LOG_FILE"
|
||||
: > "$LOG_ARCHIVE"
|
||||
|
||||
log() {
|
||||
echo "$1"
|
||||
echo "$1" >> "$LOG_FILE"
|
||||
echo "$1" >>"$LOG_FILE"
|
||||
echo "$1" >>"$LOG_ARCHIVE"
|
||||
}
|
||||
|
||||
run_cmd() {
|
||||
local msg="$1"
|
||||
shift
|
||||
local title="$1"; shift
|
||||
# console courte + log complet
|
||||
printf "⏳ %s..." "$title"
|
||||
{
|
||||
echo "----- ${title} -----"
|
||||
echo "CMD: $*"
|
||||
"$@"
|
||||
echo "----- FIN ${title} -----"
|
||||
echo
|
||||
} >>"$LOG_FILE" 2>&1
|
||||
echo " ✅"
|
||||
}
|
||||
|
||||
echo "⏳ $msg..."
|
||||
"$@" >>"$LOG_FILE" 2>&1
|
||||
echo "✅ $msg terminé"
|
||||
# 🔎 APT : nombre de paquets upgradables
|
||||
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 Debian / Ubuntu (APT)"
|
||||
log "📦 Mise à jour système (APT)"
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
run_cmd "Mise à jour des dépôts" apt-get update -y
|
||||
run_cmd "Installation des mises à jour" apt-get upgrade -y
|
||||
run_cmd "Mise à jour de la liste des paquets" apt-get update -y
|
||||
|
||||
systemctl daemon-reload >>"$LOG_FILE" 2>&1 || true
|
||||
local n
|
||||
n="$(apt_upgradable_count)"
|
||||
log "🔎 Paquets disponibles : ${n}"
|
||||
|
||||
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"
|
||||
fi
|
||||
}
|
||||
|
||||
update_apk() {
|
||||
|
||||
log "📦 Mise à jour Alpine (APK)"
|
||||
|
||||
log "📦 Mise à jour système (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 Compose : ${dir}"
|
||||
|
||||
# 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"
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
# 1) Essayer compose via labels (mais seulement si le dossier existe ET contient un compose)
|
||||
log "🔍 Recherche de projets Docker Compose"
|
||||
|
||||
mapfile -t dirs < <(
|
||||
@@ -61,64 +105,97 @@ update_docker() {
|
||||
)
|
||||
|
||||
valid_dirs=()
|
||||
|
||||
for d in "${dirs[@]}"; do
|
||||
if [[ -d "$d" ]] && { [[ -f "$d/docker-compose.yml" ]] || [[ -f "$d/compose.yml" ]]; }; then
|
||||
valid_dirs+=("$d")
|
||||
else
|
||||
log "⚠️ Dossier Compose ignoré : $d"
|
||||
log "⚠️ Compose ignoré (chemin invalide ou sans compose.yml) : $d"
|
||||
fi
|
||||
done
|
||||
|
||||
if (( ${#valid_dirs[@]} > 0 )); then
|
||||
|
||||
if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1 && (( ${#valid_dirs[@]} > 0 )); then
|
||||
log "📁 Projet(s) Compose détecté(s) : ${#valid_dirs[@]}"
|
||||
|
||||
for d in "${valid_dirs[@]}"; do
|
||||
|
||||
log "📂 Projet : $d"
|
||||
|
||||
if docker compose version >>"$LOG_FILE" 2>&1; then
|
||||
run_cmd "Téléchargement des images" bash -c "cd '$d' && docker compose pull"
|
||||
run_cmd "Redéploiement des services" bash -c "cd '$d' && docker compose up -d"
|
||||
elif command -v docker-compose >>"$LOG_FILE" 2>&1; then
|
||||
run_cmd "Téléchargement des images" bash -c "cd '$d' && docker-compose pull"
|
||||
run_cmd "Redéploiement des services" bash -c "cd '$d' && docker-compose up -d"
|
||||
else
|
||||
log "❌ Docker Compose n'est pas installé"
|
||||
return 2
|
||||
update_docker_compose_dir "$d"
|
||||
done
|
||||
log "✅ Mise à jour Docker (Compose) 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)"
|
||||
|
||||
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
|
||||
|
||||
old_id="$(docker_image_id "$img")"
|
||||
# pull (tout dans le log)
|
||||
{
|
||||
echo "----- PULL ${img} -----"
|
||||
docker pull "$img"
|
||||
echo
|
||||
} >>"$LOG_FILE" 2>&1 || true
|
||||
|
||||
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}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
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 "⚠️ Aucun projet Compose détecté"
|
||||
log "⬇️ Mise à jour des images Docker utilisées"
|
||||
|
||||
while read -r img; do
|
||||
[[ -n "$img" ]] || continue
|
||||
run_cmd "Téléchargement $img" docker pull "$img"
|
||||
done < <(docker ps --format '{{.Image}}' | sort -u)
|
||||
|
||||
log "✅ Images Docker mises à jour : ${updated}"
|
||||
log "⚠️ Note : sans Compose, les conteneurs ne sont pas recréés automatiquement."
|
||||
fi
|
||||
}
|
||||
|
||||
case "$METHOD" in
|
||||
apt)
|
||||
update_apt
|
||||
;;
|
||||
apk)
|
||||
update_apk
|
||||
;;
|
||||
docker)
|
||||
update_docker
|
||||
;;
|
||||
# --- Parsing MODE ---
|
||||
# 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}"
|
||||
|
||||
# 1) Toujours mettre à jour le système de base (si possible)
|
||||
case "$BASE_MODE" in
|
||||
apt) update_apt ;;
|
||||
apk) update_apk ;;
|
||||
*)
|
||||
log "❌ Méthode inconnue : $METHOD"
|
||||
exit 1
|
||||
log "⚠️ Système de base non détecté (apt/apk). On saute la mise à jour OS."
|
||||
;;
|
||||
esac
|
||||
|
||||
log "🧾 Log update : $LOG_FILE"
|
||||
# 2) Puis Docker si présent
|
||||
if [[ "$HAS_DOCKER" == "1" ]]; then
|
||||
update_docker
|
||||
fi
|
||||
|
||||
log "🧾 Log update : ${LOG_FILE}"
|
||||
log "🗃️ Archive update : ${LOG_ARCHIVE}"
|
||||
log "🎉 Mise à jour terminée"
|
||||
Reference in New Issue
Block a user