Script de mise à jour des projets Docker Compose
#!/bin/python3 #Appel des dépendances import subprocess import os from typing import Dict, List, Tuple, Optional # Fonction qui affiche le message d'accueil def display_welcome_message(): """ Affiche un message d'accueil stylisé pour le script de mise à jour Docker Compose. """ # Couleurs ANSI (fonctionnent dans la plupart des terminaux Linux) RESET = "\033[0m" GREEN = "\033[92m" BOLD = "\033[1m" # Message d'accueil personnalisé welcome_message = f""" {BOLD}{GREEN}🚀 Bienvenue dans le script de mise à jour de projets Docker Compose ! 🚀 ℹ️ Pré-requis : 1️⃣ Le paquet docker-compose-plugin doit être installé. La version legacy de docker-compose n'est pas compatible ❌ 2️⃣ Le service Docker doit être démarré normalement 3️⃣ Les projets Docker Compose doivent être stockés dans le répertoire d'un des utilisateurs du système (/home/xxxx) Autrement, le chemin racine des projets peut être modifié à la ligne 179 de ce script (replacez le "/home") 4️⃣ Le tag 'latest' doit également être mentionné dans la configuration des images à mettre à jour{RESET} """ # Afficher le message print(welcome_message) # Fonction pour récupérer les projets docker compose actif et le chemin de la configuration def find_docker_compose_projects(root_dir: str = "/") -> Dict[str, str]: """ Cherche les fichiers docker-compose.yml dans les répertoires et vérifie les projets actifs. Retourne un dictionnaire {nom_projet: chemin_du_repertoire}. """ projects = {} for dirpath, _, filenames in os.walk(root_dir): if "docker-compose.yml" in filenames: try: # Vérifier si le projet est en cours d'exécution result = subprocess.run( ["docker", "compose", "-f", os.path.join(dirpath, "docker-compose.yml"), "ps", "--services", "--filter", "status=running"], capture_output=True, text=True, ) services = result.stdout.strip().split("\n") if services and services[0]: project_name = os.path.basename(dirpath) projects[project_name] = dirpath except Exception as e: print(f"Erreur pour {dirpath}: {e}") return projects # Fonction qui affiche les projets docker compose numérotés def display_project_menu(projects: Dict[str, str]) -> None: """ Affiche un menu numéroté des projets Docker Compose actifs. Args: projects: Dictionnaire {nom_projet: chemin_du_repertoire} retourné par `find_docker_compose_projects`. """ if not projects: print("Aucun projet Docker Compose actif trouvé.") return print("\nProjets Docker Compose actifs :") for index, (project_name, project_path) in enumerate(projects.items(), start=1): print(f"{index}. {project_name} ({project_path})") # Fonction qui demande à l'utilisateur de choisir un projet à mettre à jour et lancer la maj si OK def select_and_confirm_project(projects: Dict[str, str]) -> Optional[Tuple[str, str]]: """ Demande à l'utilisateur de sélectionner un projet Docker Compose par son numéro, vérifie la validité du choix, et demande confirmation. Args: projects: Dictionnaire {nom_projet: chemin_du_repertoire} des projets actifs. Returns: Un tuple (nom_projet, chemin) si la sélection est confirmée, sinon None. """ if not projects: print("Aucun projet disponible.") return None try: # Afficher le menu display_project_menu(projects) # Demander la sélection selection = input("\nEntrez le numéro du projet à mettre à jour (ou 'q' pour quitter) : ") if selection.lower() == 'q': return None selected_index = int(selection) - 1 project_list = list(projects.items()) if selected_index < 0 or selected_index >= len(project_list): print("Numéro invalide.") return None selected_project = project_list[selected_index] # Demander confirmation confirm = input(f"\nVous avez sélectionné : {selected_project[0]} ({selected_project[1]})\nConfirmez-vous cette sélection ? (o/n) : ") if confirm.lower() == 'o': return selected_project else: print("Sélection annulée.") return None except ValueError: print("Veuillez entrer un numéro valide.") return None # Fonction de mise à jour def update_docker_compose_project(project_name: str, project_path: str) -> bool: """ Met à jour un projet Docker Compose en exécutant `docker-compose pull` et `docker-compose up -d`. Args: project_name: Nom du projet (pour les logs). project_path: Chemin du répertoire contenant le fichier docker-compose.yml. Returns: bool: True si la mise à jour a réussi, False sinon. """ try: print(f"\nMise à jour du projet {project_name} dans {project_path}...") # 1. Se déplacer dans le répertoire du projet os.chdir(project_path) # 2. Exécuter `docker-compose pull` pour récupérer les dernières images print("Récupération des dernières images...") pull_result = subprocess.run( ["docker", "compose", "pull"], capture_output=True, text=True, check=True ) print(pull_result.stdout) # 3. Exécuter `docker-compose up -d` pour redémarrer les conteneurs print("Redémarrage des conteneurs...") up_result = subprocess.run( ["docker", "compose", "up", "-d"], capture_output=True, text=True, check=True ) print(up_result.stdout) print(f"\nLe projet {project_name} a été mis à jour avec succès !") return True except subprocess.CalledProcessError as e: print(f"\n❌ Erreur lors de la mise à jour du projet {project_name} :") print(f"Commande échouée : {e.cmd}") print(f"Code de retour : {e.returncode}") print(f"Erreur : {e.stderr}") return False except Exception as e: print(f"\n❌ Erreur inattendue lors de la mise à jour du projet {project_name} : {e}") return False # Fonction principale def main(): display_welcome_message() # Message d'accueil projects = find_docker_compose_projects("/home") # Remplacer "/home" par le chemin racine des projets Docker Compose if not projects: print("Aucun projet Docker Compose actif trouvé.") return selected = select_and_confirm_project(projects) if selected: project_name, project_path = selected success = update_docker_compose_project(project_name, project_path) # Executer la mise à jour # Executer la fonction main() if __name__ == "__main__": main()