Proxmox VE n'existe qu'après un redémarrage : tant que la VM tourne le noyau de son image cloud, elle n'a aucun module netfilter — ni pont NAT, ni invité. install_proxmox.sh pose le noyau puis s'arrête, à raison, car lancé par ssh un reboot couperait sa session et ferait passer l'installation pour un échec. On le découvrait donc des jours plus tard, en créant un pont. Le redémarrage revient à l'enveloppe de lancement, qui tourne sur NOTRE machine et survit à celui de la VM : installation, reboot, attente, puis vérification du noyau. Le ✅ ne s'écrit qu'après, et il veut donc dire « hyperviseur utilisable ». Trois choix méritent d'être dits. On ne redémarre qu'après un SUCCÈS — redémarrer après un échec effacerait la seule machine sur laquelle on pouvait chercher. On n'attend pas que ssh « revienne » mais que « uname -r » porte le motif attendu : sshd répond encore une seconde ou deux après l'ordre, et on lirait l'ancien noyau en croyant avoir la réponse. Et l'absence du noyau attendu est un vrai ÉCHEC, pas un avertissement. Le shell est exécuté par les tests, ssh bouchonné, dans les quatre cas — dont celui où les deux premières lectures rendent l'ancien noyau. Un garde qu'on ne sait pas éprouver s'ouvre le jour où il casse. La note du sommaire ne paraît plus que sans suivi, où rien ne redémarre : réclamer un redémarrage déjà fait est une consigne fausse. --- EN --- Proxmox VE only exists after a reboot: while the VM runs its cloud image's kernel it has no netfilter module — no NAT bridge, no guest. install_proxmox.sh installs the kernel then stops, rightly, since run over ssh a reboot would cut its own session and make the install look failed. So you found out days later, when creating a bridge. The reboot moves to the launch wrapper, which runs on OUR machine and survives the VM's: install, reboot, wait, then verify the kernel. The ✅ is written only after, and therefore means "usable hypervisor". Three choices worth stating. We reboot only after SUCCESS — rebooting after a failure would wipe the one machine you could investigate. We do not wait for ssh to "come back" but for "uname -r" to carry the expected pattern: sshd answers for another second or two after the order, and we would read the old kernel believing we had the answer. And a missing expected kernel is a real FAILURE, not a warning. The shell is executed by the tests, ssh stubbed, in all four cases — including the one where the first two reads return the old kernel. A guard you cannot exercise opens the day it breaks. The summary note now appears only without monitoring, where nothing reboots: asking for a reboot already done is a false instruction. Assisted-by: Claude Opus 5 |
||
|---|---|---|
| .. | ||
| auto_ask.py | ||
| database_manager.py | ||
| deploy_form_extras.py | ||
| deploy_form_lib.py | ||
| deploy_form_plan.py | ||
| kdbx_manager.py | ||
| logo_ascii.txt | ||
| migration_form.py | ||
| migration_stats.py | ||
| migration_status.py | ||
| migration_status_tui.py | ||
| proxmox_deploy_form.py | ||
| proxmox_menu.py | ||
| qemu_access.py | ||
| qemu_deploy.py | ||
| qemu_deploy_form.py | ||
| qemu_hardware.py | ||
| qemu_install.py | ||
| qemu_install_monitor.py | ||
| qemu_manage.py | ||
| qemu_menu.py | ||
| README.base.md | ||
| README.fr.md | ||
| README.md | ||
| source_todo.sh | ||
| textual_setup.py | ||
| todo.json | ||
| todo.py | ||
| todo_example.json | ||
| todo_file_browser.py | ||
| todo_i18n.py | ||
| todo_prefs.py | ||
| todo_telemetry.py | ||
| todo_upgrade.py | ||
| version_manager.py | ||
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.