feat: implement /update in BaseAgent (git pull + systemctl restart)
- _do_self_update(): git pull, skip restart if already up to date, send result back via MQTT reply_to before restarting (2s delay) - _get_install_dir(): derive from config path - _get_service_name(): from config or install dir basename Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -511,9 +511,81 @@ class BaseAgent(ABC):
|
|||||||
all_agents = [a.agent_id for a in self.registry.all_agents()]
|
all_agents = [a.agent_id for a in self.registry.all_agents()]
|
||||||
return f"Agents en ligne : {online}\nAgents connus : {all_agents}"
|
return f"Agents en ligne : {online}\nAgents connus : {all_agents}"
|
||||||
|
|
||||||
|
if cmd == "update":
|
||||||
|
return self._do_self_update(source_msg)
|
||||||
|
|
||||||
# Commandes custom de l'agent
|
# Commandes custom de l'agent
|
||||||
return self.handle_custom_command(cmd, args, source_msg)
|
return self.handle_custom_command(cmd, args, source_msg)
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
# Mise à jour self
|
||||||
|
# ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
def _get_install_dir(self) -> str:
|
||||||
|
"""Répertoire d'installation : parent du dossier config."""
|
||||||
|
return os.path.dirname(os.path.dirname(os.path.abspath(self._config_path)))
|
||||||
|
|
||||||
|
def _get_service_name(self) -> str:
|
||||||
|
"""Nom du service systemd : depuis config ou nom du répertoire d'install."""
|
||||||
|
return self.config.get("service_name") or os.path.basename(self._get_install_dir())
|
||||||
|
|
||||||
|
def _do_self_update(self, source_msg: Optional[Message] = None) -> str:
|
||||||
|
"""git pull → systemctl restart si des changements sont détectés."""
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
install_dir = self._get_install_dir()
|
||||||
|
service_name = self._get_service_name()
|
||||||
|
logger.info(f"[Update] git pull dans {install_dir} (service : {service_name})")
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
["git", "pull"],
|
||||||
|
cwd=install_dir,
|
||||||
|
capture_output=True, text=True, timeout=60,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
msg = f"[{self.agent_id}] ❌ git pull impossible : {e}"
|
||||||
|
self._send_update_reply(source_msg, msg)
|
||||||
|
return msg
|
||||||
|
|
||||||
|
if result.returncode != 0:
|
||||||
|
msg = f"[{self.agent_id}] ❌ git pull échoué :\n{result.stderr.strip()}"
|
||||||
|
self._send_update_reply(source_msg, msg)
|
||||||
|
return msg
|
||||||
|
|
||||||
|
stdout = result.stdout.strip()
|
||||||
|
|
||||||
|
if "Already up to date" in stdout:
|
||||||
|
msg = f"[{self.agent_id}] ✓ Déjà à jour — pas de redémarrage."
|
||||||
|
self._send_update_reply(source_msg, msg)
|
||||||
|
return msg
|
||||||
|
|
||||||
|
msg = (
|
||||||
|
f"[{self.agent_id}] ✓ Mis à jour :\n{stdout}\n"
|
||||||
|
f"Redémarrage du service {service_name}..."
|
||||||
|
)
|
||||||
|
self._send_update_reply(source_msg, msg)
|
||||||
|
|
||||||
|
# Restart différé pour laisser le temps au message MQTT d'être envoyé
|
||||||
|
def _restart():
|
||||||
|
import time
|
||||||
|
time.sleep(2)
|
||||||
|
try:
|
||||||
|
subprocess.run(["systemctl", "restart", service_name], timeout=30, check=True)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"[Update] Erreur restart {service_name} : {e}")
|
||||||
|
|
||||||
|
threading.Thread(target=_restart, daemon=True, name="update-restart").start()
|
||||||
|
return msg
|
||||||
|
|
||||||
|
def _send_update_reply(self, source_msg: Optional[Message], body: str):
|
||||||
|
"""Renvoie la réponse d'update à Nexus via MQTT si possible."""
|
||||||
|
if source_msg and source_msg.reply_to:
|
||||||
|
try:
|
||||||
|
self.mqtt.reply(source_msg, body)
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"[Update] Impossible d'envoyer la réponse : {e}")
|
||||||
|
|
||||||
# ──────────────────────────────────────────────
|
# ──────────────────────────────────────────────
|
||||||
# Capacités
|
# Capacités
|
||||||
# ──────────────────────────────────────────────
|
# ──────────────────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user