[IMP] script todo: QEMU — commande « Tester une VM » (ouvre Odoo en navigateur CLI)

Nouvelle entrée [10] dans « Gérer » du menu QEMU/KVM : 🧪 Tester une VM.
Elle liste les VM, demande laquelle, résout son IP puis ouvre
http://IP:8069 (Odoo) dans un navigateur web EN LIGNE DE COMMANDE choisi
par l'utilisateur.

- _qemu_test_vm : résolution d'IP (_qemu_vm_ip), lancement du navigateur,
  message d'aide si la page ne s'affiche pas (Odoo pas démarré / réseau).
- _qemu_choose_cli_browser : liste les navigateurs CLI installés et laisse
  choisir ; si aucun, propose d'en installer un (réutilise CLI_BROWSERS /
  INSTALLABLE_BROWSERS / browser_install_command de qemu_install_monitor).
- « Lister les images » passe de [10] à [11] ; les entrées de config
  suivent à 12+ (branche else inchangée via la liste `real`).

Validé : rendu du menu, choix du navigateur ([2]->elinks, vide->w3m).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mathieu Benoit 2026-07-30 03:17:58 +00:00
parent 59bf857558
commit babe69dbf7
2 changed files with 131 additions and 0 deletions

View file

@ -1082,6 +1082,11 @@ class TODO:
{"prompt_description": t("Resize a VM disk")},
{"prompt_description": t("Delete VM(s)")},
{"prompt_description": t("Clean up QEMU (orphan files)")},
{
"prompt_description": t(
"Test a VM (open Odoo in a CLI browser)"
)
},
{"section": t("Catalog")},
{"prompt_description": t("List available images and specs")},
]
@ -1114,6 +1119,8 @@ class TODO:
elif status == "9":
self._qemu_cleanup()
elif status == "10":
self._qemu_test_vm()
elif status == "11":
self._qemu_list_images()
else:
cmd_no_found = True
@ -1342,6 +1349,87 @@ class TODO:
print(f"{t('Will execute:')} {cmd}")
self.execute.exec_command_live(cmd, source_erplibre=False)
def _qemu_test_vm(self):
"""Teste une VM : résout son IP puis ouvre Odoo (:8069) dans un
navigateur web EN LIGNE DE COMMANDE choisi par l'utilisateur."""
self._qemu_list_vms()
print()
name = input(t("VM name or ID: ")).strip()
if not name:
print(t("VM name is required!"))
return
real = self._qemu_domname(name)
if not self._qemu_domain_exists(real):
print(f"{real}: {t('VM not found.')}")
return
print(f"\n{t('Resolving VM IP...')}")
ip = self._qemu_vm_ip(real, timeout=120)
if not ip:
print(t("No IP found for this VM."))
return
browser = self._qemu_choose_cli_browser()
if not browser:
return
url = f"http://{ip}:8069"
print(f"{browser} {url}")
rc = self.execute.exec_command_live(
f"{browser} {shlex.quote(url)}", source_erplibre=False
)
if rc != 0:
msg = t(
"Page may not have loaded: Odoo not started on :8069, "
"or network/firewall."
)
print(f"{msg}")
def _qemu_choose_cli_browser(self):
"""Offre la LISTE des navigateurs CLI installés (ou propose d'en
installer un) et renvoie celui choisi, sinon None."""
from script.todo.qemu_install_monitor import (
CLI_BROWSERS,
INSTALLABLE_BROWSERS,
browser_install_command,
)
available = [b for b in CLI_BROWSERS if shutil.which(b)]
if not available:
print(t("No CLI browser installed. Which to install?"))
for i, (b, desc) in enumerate(INSTALLABLE_BROWSERS, 1):
print(f" [{i}] {desc}{' *' if i == 1 else ''}")
sel = input(t("Choice (number, blank = w3m): ")).strip()
browser = INSTALLABLE_BROWSERS[0][0]
try:
idx = int(sel) - 1
if 0 <= idx < len(INSTALLABLE_BROWSERS):
browser = INSTALLABLE_BROWSERS[idx][0]
except ValueError:
pass
cmd = browser_install_command(browser)
if not cmd:
print(t("Unknown package manager; install it manually."))
return None
printable = " ".join(cmd)
print(f"{t('Command:')} {printable}")
if not self._is_yes(input(t("Install now? (y/N): "))):
return None
os.system(printable)
return browser if shutil.which(browser) else None
if len(available) == 1:
return available[0]
print(f"\n{t('Which browser to view the page?')}")
for i, b in enumerate(available, 1):
print(f" [{i}] {b}{' *' if i == 1 else ''}")
sel = input(t("Choice (number, blank = first): ")).strip()
if not sel:
return available[0]
try:
idx = int(sel) - 1
if 0 <= idx < len(available):
return available[idx]
except ValueError:
pass
return available[0]
# ------------------------------------------------------------------ #
# Redimensionnement du disque d'une VM
# ------------------------------------------------------------------ #

View file

@ -1432,6 +1432,49 @@ TRANSLATIONS = {
"fr": "Aucune erreur détectée.",
"en": "No error detected.",
},
"Test a VM (open Odoo in a CLI browser)": {
"fr": "🧪 Tester une VM (ouvrir Odoo dans un navigateur CLI)",
"en": "🧪 Test a VM (open Odoo in a CLI browser)",
},
"Resolving VM IP...": {
"fr": "Résolution de l'IP de la VM…",
"en": "Resolving VM IP...",
},
"No IP found for this VM.": {
"fr": "Aucune IP trouvée pour cette VM.",
"en": "No IP found for this VM.",
},
"No CLI browser installed. Which to install?": {
"fr": "Aucun navigateur CLI installé. Lequel installer ?",
"en": "No CLI browser installed. Which to install?",
},
"Choice (number, blank = w3m): ": {
"fr": "Choix (numéro, vide = w3m) : ",
"en": "Choice (number, blank = w3m): ",
},
"Unknown package manager; install it manually.": {
"fr": "Gestionnaire de paquets inconnu ; installez-le manuellement.",
"en": "Unknown package manager; install it manually.",
},
"Install now? (y/N): ": {
"fr": "Installer maintenant ? (o/N) : ",
"en": "Install now? (y/N): ",
},
"Which browser to view the page?": {
"fr": "Quel navigateur pour voir la page ?",
"en": "Which browser to view the page?",
},
"Choice (number, blank = first): ": {
"fr": "Choix (numéro, vide = le premier) : ",
"en": "Choice (number, blank = first): ",
},
"Page may not have loaded: Odoo not started on :8069, "
"or network/firewall.": {
"fr": "La page ne s'est peut-être pas affichée : Odoo n'est pas "
"démarré sur :8069, ou réseau/pare-feu.",
"en": "Page may not have loaded: Odoo not started on :8069, "
"or network/firewall.",
},
"errors": {
"fr": "erreurs",
"en": "errors",