[IMP] script todo: QEMU — rouvrir le suivi d'installation (dernier run / historique)

Si le dashboard se ferme (bug, sortie), on peut désormais le ROUVRIR sur un
run passé pour reprendre l'analyse. Nouvelle entrée [11] du menu QEMU :
« 📈 Rouvrir le suivi d'installation (dernier run / historique) ».

- mon.list_install_runs() : liste les runs (~/.erplibre/qemu-install/*/
  session.json) triés du plus récent au plus ancien.
- _qemu_reopen_monitor : affiche l'historique (VM par run), choix (défaut =
  le dernier), puis run_monitor(session.json) rouvre le dashboard.
- « Lister les images » passe de [11] à [12] ; config -> 13+.

Validé : 20 runs listés, dashboard reconstruit (titre + 5 VM) depuis un
session.json passé.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mathieu Benoit 2026-07-30 00:22:37 -04:00
parent 4f0c3cd217
commit 0b02e9fe43
3 changed files with 95 additions and 0 deletions

View file

@ -44,6 +44,34 @@ def session_dir() -> Path:
return base return base
def list_install_runs() -> list:
"""Runs d'installation passés (chacun a un session.json), TRIÉS du plus
récent au plus ancien. Chaque entrée : dict {label, manifest, mtime,
vms, branch}. Permet de ROUVRIR le suivi d'un run (le dashboard s'étant
fermé sur un bug, on reprend l'analyse)."""
runs = []
for d in sorted(session_dir().glob("*/"), reverse=True):
manifest = d / "session.json"
if not manifest.is_file():
continue
try:
data = json.loads(manifest.read_text())
mtime = manifest.stat().st_mtime
except (OSError, ValueError):
continue
runs.append(
{
"label": d.name.rstrip("/"),
"manifest": str(manifest),
"mtime": mtime,
"vms": data.get("vms", []),
"branch": data.get("branch", ""),
}
)
runs.sort(key=lambda r: r["mtime"], reverse=True)
return runs
def _launch_one(ip: str, remote_cmd: str, log_path: str) -> None: def _launch_one(ip: str, remote_cmd: str, log_path: str) -> None:
"""Lance une install SSH DÉTACHÉE : attend le sshd, exécute, journalise """Lance une install SSH DÉTACHÉE : attend le sshd, exécute, journalise
la sortie puis écrit le marqueur de fin avec le code de sortie.""" la sortie puis écrit le marqueur de fin avec le code de sortie."""

View file

@ -1087,6 +1087,11 @@ class TODO:
"Test a VM (open Odoo in a CLI browser)" "Test a VM (open Odoo in a CLI browser)"
) )
}, },
{
"prompt_description": t(
"Reopen install monitoring (last run / history)"
)
},
{"section": t("Catalog")}, {"section": t("Catalog")},
{"prompt_description": t("List available images and specs")}, {"prompt_description": t("List available images and specs")},
] ]
@ -1121,6 +1126,8 @@ class TODO:
elif status == "10": elif status == "10":
self._qemu_test_vm() self._qemu_test_vm()
elif status == "11": elif status == "11":
self._qemu_reopen_monitor()
elif status == "12":
self._qemu_list_images() self._qemu_list_images()
else: else:
cmd_no_found = True cmd_no_found = True
@ -1383,6 +1390,46 @@ class TODO:
) )
print(f"{msg}") print(f"{msg}")
def _qemu_reopen_monitor(self):
"""Rouvre le suivi d'installation (dashboard) sur un run PASSÉ : le
dernier par défaut, ou un choix dans l'historique. Utile quand le
dashboard s'est fermé et qu'on veut reprendre l'analyse."""
from script.todo import qemu_install_monitor as mon
runs = mon.list_install_runs()
if not runs:
print(t("No install run found in history."))
return
print(f"\n{t('Install runs (most recent first):')}")
for i, r in enumerate(runs, 1):
names = ", ".join(v.get("name", "?") for v in r["vms"])
star = " *" if i == 1 else ""
print(
f" [{i}] {r['label']}{len(r['vms'])} VM{star}\n"
f" {names}"
)
sel = input(
t("Choice (number, blank = last): ")
).strip()
run = runs[0]
if sel:
try:
idx = int(sel) - 1
if 0 <= idx < len(runs):
run = runs[idx]
else:
print(t("Invalid selection."))
return
except ValueError:
print(t("Invalid selection."))
return
try:
mon.run_monitor(run["manifest"])
except ImportError:
print(t("Install textual for the dashboard (pip)."))
except Exception as exc:
print(f"{t('Command failed: ')}{exc}")
def _qemu_choose_cli_browser(self): def _qemu_choose_cli_browser(self):
"""Offre la LISTE des navigateurs CLI installés, plus une option pour """Offre la LISTE des navigateurs CLI installés, plus une option pour
en INSTALLER un autre, et renvoie celui choisi, sinon None.""" en INSTALLER un autre, et renvoie celui choisi, sinon None."""

View file

@ -1488,6 +1488,26 @@ TRANSLATIONS = {
"fr": "🧪 Tester une VM (ouvrir Odoo dans un navigateur CLI)", "fr": "🧪 Tester une VM (ouvrir Odoo dans un navigateur CLI)",
"en": "🧪 Test a VM (open Odoo in a CLI browser)", "en": "🧪 Test a VM (open Odoo in a CLI browser)",
}, },
"Reopen install monitoring (last run / history)": {
"fr": "📈 Rouvrir le suivi d'installation (dernier run / historique)",
"en": "📈 Reopen install monitoring (last run / history)",
},
"No install run found in history.": {
"fr": "Aucun run d'installation dans l'historique.",
"en": "No install run found in history.",
},
"Install runs (most recent first):": {
"fr": "Runs d'installation (du plus récent) :",
"en": "Install runs (most recent first):",
},
"Choice (number, blank = last): ": {
"fr": "Choix (numéro, vide = le dernier) : ",
"en": "Choice (number, blank = last): ",
},
"Invalid selection.": {
"fr": "Sélection invalide.",
"en": "Invalid selection.",
},
"Resolving VM IP...": { "Resolving VM IP...": {
"fr": "Résolution de l'IP de la VM…", "fr": "Résolution de l'IP de la VM…",
"en": "Resolving VM IP...", "en": "Resolving VM IP...",