diff --git a/script/todo/todo.py b/script/todo/todo.py index c2ff56a..360184d 100755 --- a/script/todo/todo.py +++ b/script/todo/todo.py @@ -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 # ------------------------------------------------------------------ # diff --git a/script/todo/todo_i18n.py b/script/todo/todo_i18n.py index e1a7736..053c7a9 100644 --- a/script/todo/todo_i18n.py +++ b/script/todo/todo_i18n.py @@ -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",