""" Utilitaire : vérification et application des mises à jour git pour les agents. Fonctions appelées directement depuis agent1.py (pas de trigger LLM). check_update(name, install_path, branch) → rapport git fetch do_upgrade(name, install_path, service, branch) → git pull + systemctl restart """ import subprocess import shlex from pathlib import Path def _run(cmd: str, cwd: str = None, timeout: int = 30) -> tuple: """Lance une commande shell, retourne (stdout, stderr, returncode).""" try: result = subprocess.run( shlex.split(cmd), cwd=cwd, capture_output=True, text=True, timeout=timeout ) return result.stdout.strip(), result.stderr.strip(), result.returncode except subprocess.TimeoutExpired: return "", "Timeout ({} s)".format(timeout), -1 except Exception as e: return "", str(e), -1 def check_update(agent_name: str, install_path: str, branch: str = "main") -> str: """ Vérifie si une mise à jour est disponible sur le dépôt distant. Effectue un git fetch puis compare HEAD avec origin/. """ path = install_path if not Path(path).is_dir(): return "[{}] Répertoire introuvable : {}".format(agent_name, path) # git fetch out, err, rc = _run("git fetch origin {}".format(branch), cwd=path, timeout=20) if rc != 0: return "[{}] Erreur git fetch : {}".format(agent_name, err or out) # Compter les commits disponibles out, err, rc = _run( "git log HEAD..origin/{} --oneline".format(branch), cwd=path) if rc != 0: return "[{}] Erreur git log : {}".format(agent_name, err or out) commits = [l for l in out.splitlines() if l.strip()] if not commits: return "[{}] Déjà à jour.".format(agent_name) lines = ["[{}] {} commit(s) disponible(s) :".format(agent_name, len(commits))] for c in commits[:10]: lines.append(" {}".format(c)) if len(commits) > 10: lines.append(" ... et {} autre(s)".format(len(commits) - 10)) lines.append("Lancez !agentUPGRADE {} pour appliquer.".format(agent_name)) return "\n".join(lines) def do_upgrade(agent_name: str, install_path: str, service_name: str, branch: str = "main", self_upgrade: bool = False) -> str: """ Applique la mise à jour : git pull + systemctl restart. Pour agent1 (self_upgrade=True), envoie la réponse AVANT le restart. """ path = install_path if not Path(path).is_dir(): return "[{}] Répertoire introuvable : {}".format(agent_name, path) # git pull out, err, rc = _run( "git pull origin {}".format(branch), cwd=path, timeout=60) if rc != 0: return "[{}] Erreur git pull : {}".format(agent_name, err or out) pull_msg = out or "Déjà à jour." if self_upgrade: # On retourne le message AVANT le restart (agent1 l'envoie puis se redémarre) return "[{}] {} \nRedémarrage en cours...".format(agent_name, pull_msg) # systemctl restart _, err, rc = _run("systemctl restart {}".format(service_name), timeout=15) if rc != 0: return "[{}] Pull OK mais restart échoué : {}".format(agent_name, err) # Vérifier que le service est bien remonté out, _, _ = _run("systemctl is-active {}".format(service_name), timeout=5) state = out.strip() if state == "active": return "[{}] Mise à jour appliquée. Service actif.\n{}".format(agent_name, pull_msg) else: return "[{}] Pull OK, service état : {}. Vérifiez les logs.".format( agent_name, state)