3575b391b6
- skills/agent_update.py : check_update (git fetch + log) et do_upgrade (git pull + systemctl restart) - agent1.py : commandes !agentUPDATE <nom>, !agentsUPDATE, !agentUPGRADE <nom>, !agentsUPGRADE - _handle_agent_command retourne (handled, reply) pour gérer le self-upgrade agent1 - !agentUPGRADE agent1 : envoie la réponse XMPP avant systemctl restart - !agentsUPGRADE : met à jour tous les agents puis agent1 en dernier - agents_registry.json : ajout install_path, service_name, git_branch + entrée agent1 - README.md : documentation des nouvelles commandes - TODO.md : tâches marquées comme terminées Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
102 lines
3.6 KiB
Python
102 lines
3.6 KiB
Python
"""
|
|
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/<branch>.
|
|
"""
|
|
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)
|