erplibre/script/todo
Mathieu Benoit 1a8f1525b1 [FIX] proxmox : sh: 1: Syntax error: "(" unexpected
Rapporté. La chaîne, en trois maillons : sur un hôte sans pont, « ip -o link
show type bridge » ne rend RIEN, la sortie ne contient donc que
l'avertissement de ssh sur la clé d'hôte — que le lecteur a pris pour un nom
de pont. « (ED25519) » s'est retrouvé dans « --net0 virtio,bridge=… », enrobé
de « sudo sh -c », et dash a répondu ce que l'utilisateur a lu. Le bruit de
ssh est maintenant retiré à la source, et un pont doit avoir la forme d'un
lien pour en être un.

Éprouvé sur l'hôte réel, VM créée puis détruite : le pont ne montait pas
(ifupdown2 accuse « another instance » quand /run/network manque — un
mensonge), le noyau Debian n'a ni module bridge ni table NAT, et une VM en
adresse fixe n'avait aucun résolveur. Le déploiement écrit désormais un
journal par VM sous ~/.erplibre/proxmox-deploy et en donne le chemin.

--- EN ---

Reported. The chain, in three links: on a host with no bridge, "ip -o link
show type bridge" returns NOTHING, so the output holds only ssh's host-key
warning — which the parser took for a bridge name. "(ED25519)" landed in
"--net0 virtio,bridge=…", wrapped in "sudo sh -c", and dash answered what the
user read. Ssh's noise is now stripped at the source, and a bridge must have
the shape of a link to be one.

Proven on the real host, VM created then destroyed: the bridge would not come
up (ifupdown2 claims "another instance" when /run/network is missing — a lie),
the Debian kernel has neither the bridge module nor the NAT table, and a
statically addressed VM had no resolver at all. Deployment now writes one log
per VM under ~/.erplibre/proxmox-deploy and prints its path.

Assisted-by: Claude Opus 5
2026-08-25 03:19:18 -04:00
..
mail [ADD] mail: read and send email from the TODO CLI 2026-08-16 03:56:34 -04:00
auto_ask.py [ADD] migration: announce the countdown, and cycle three panel states 2026-08-22 07:23:59 -04:00
database_manager.py [ADD] analyse: inspect an Odoo database without restoring it 2026-08-10 03:10:50 -04:00
deploy_form_lib.py [UPD] todo : nommer la case d'installation par ce qu'elle commande 2026-08-25 03:17:13 -04:00
deploy_form_plan.py [REF] todo : un fichier par sujet, un socle par formulaire 2026-08-25 03:16:07 -04:00
kdbx_manager.py [FIX] security: the KeePass password leaves the command line too 2026-08-23 02:11:50 -04:00
logo_ascii.txt [IMP] bot assistant TODO 2025-04-27 02:40:20 -04:00
migration_form.py [ADD] migration: offer « go back to a step » on the resume screen 2026-08-22 07:23:59 -04:00
migration_stats.py [ADD] migration: see and repair the website COW views 2026-08-10 03:10:50 -04:00
migration_status.py [ADD] migration state: read the server log so nobody has to 2026-08-22 07:23:59 -04:00
migration_status_tui.py [FIX] migration state: open the quality screen in its own process 2026-08-22 07:23:59 -04:00
proxmox_deploy_form.py [FIX] proxmox : sh: 1: Syntax error: "(" unexpected 2026-08-25 03:19:18 -04:00
proxmox_menu.py [FIX] proxmox : sh: 1: Syntax error: "(" unexpected 2026-08-25 03:19:18 -04:00
qemu_access.py [REF] todo : un fichier par sujet, un socle par formulaire 2026-08-25 03:16:07 -04:00
qemu_deploy.py [UPD] todo : nommer la case d'installation par ce qu'elle commande 2026-08-25 03:17:13 -04:00
qemu_deploy_form.py [UPD] todo : nommer la case d'installation par ce qu'elle commande 2026-08-25 03:17:13 -04:00
qemu_hardware.py [ADD] qemu : régler le mode CPU, les écrans et le réseau d'une VM 2026-08-23 02:07:42 -04:00
qemu_install.py [FIX] qemu : ne pas poser ERPLibre sur une VM Proxmox VE 2026-08-25 03:17:13 -04:00
qemu_install_monitor.py [FIX] déploiement : suivre une VM même sans installation ERPLibre 2026-08-23 03:50:57 -04:00
qemu_manage.py [REF] todo : un fichier par sujet, un socle par formulaire 2026-08-25 03:16:07 -04:00
qemu_menu.py [FIX] todo : nettoyer ce que le découpage a laissé derrière 2026-08-25 03:17:13 -04:00
README.base.md [ADD] proxmox : un écran pour déployer sur un hôte distant 2026-08-25 03:17:13 -04:00
README.fr.md [ADD] proxmox : un écran pour déployer sur un hôte distant 2026-08-25 03:17:13 -04:00
README.md [ADD] proxmox : un écran pour déployer sur un hôte distant 2026-08-25 03:17:13 -04:00
source_todo.sh [ADD] install: mise as Python provider, pyenv as fallback 2026-08-16 23:33:49 -04:00
textual_setup.py [ADD] todo: install Textual on demand 2026-08-07 03:22:26 -04:00
todo.json [ADD] todo: QEMU/KVM menu 2026-08-07 03:22:26 -04:00
todo.py [ADD] todo : dire la place qui reste sous le plan de déploiement 2026-08-25 03:17:13 -04:00
todo_example.json [UPD] TODO: simplify code by reusing method and support same command 2025-04-28 00:35:27 -04:00
todo_file_browser.py [FIX] todo: test menu, file browser and KeePass refusals 2026-08-16 03:56:34 -04:00
todo_i18n.py [ADD] migration: retirer les index qu'Odoo 17 a créés en double 2026-08-25 03:19:18 -04:00
todo_prefs.py [ADD] mail: read and send email from the TODO CLI 2026-08-16 03:56:34 -04:00
todo_telemetry.py [ADD] todo: navigation telemetry 2026-08-07 03:22:26 -04:00
todo_upgrade.py [ADD] migration: prédire la copie de site qui rendra 500 après le palier 2026-08-25 03:19:18 -04:00
version_manager.py [IMP] script: update copyright year to 2026 2026-03-11 23:16:05 -04:00

TODO is an assistant robot to use ERPLibre Execute it with ./script/todo/todo.py or make todo.

For a new project, copy todo_example.json to private/todo/todo_override.json | private/todo/todo_override_private.json and edit it.

The mail/ package is the mail client reachable from Assistant > Mail: several IMAP/SMTP accounts, a local cache, and a Textual TUI. See ../../doc/EMAIL.md.

Where the code lives

todo.py carries the menus and the general helpers. Everything around a single subject sits in its own file, and the whole thing is assembled by mixins on the TODO class — one file, one subject, its header states its boundary.

File What it owns
todo.py the menus, the configuration, the general helpers
qemu_menu.py the QEMU/KVM menu, the image catalogue, the statistics
qemu_deploy.py deciding then running a deployment
qemu_install.py the recipes run inside a VM
qemu_manage.py lifecycle, disks, hardware, cleanup, addresses
qemu_access.py SSH, tunnels, consoles, Android emulator
proxmox_menu.py the same, on a REMOTE Proxmox VE host

The two deployment forms — libvirt here, Proxmox over there — ask the same questions, so they share a foundation rather than each holding a copy:

File What it owns
deploy_form_lib.py pure logic (sizes, plan, totals, spec), the shared CSS, the resource-row factory, the progress view
deploy_form_plan.py the plan's gestures: overrides, locks, copies, renaming, free values
qemu_deploy_form.py what QEMU/KVM adds: desktops, tools, branches, install profiles
proxmox_deploy_form.py what Proxmox adds: host, storage, bridge, VMID, address

A form inherits PlanMixin and provides three hooks: which presets each resource offers, the name a VM would fall back to, and what a lock freezes. test_todo_deploy_form_lib.py fails if a form redefines a gesture the foundation already carries — that is what keeps the architecture from drifting back into two copies.