erplibre/script/todo/longtest_menu.py

200 lines
7.9 KiB
Python
Raw Normal View History

[ADD] LongTest : jusqu'à quel étage un Proxmox imbriqué tient-il La profondeur d'imbrication praticable ne se déduit pas, elle se mesure. Une mesure à la main a trouvé, au quatrième étage, un invité 36 fois plus lent que le temps réel — 583 secondes d'horloge pour 16 secondes de temps invité, chaque ligne d'ACPI prenant une seconde — puis un noyau gelé au MÊME octet quelles que soient les ressources. Un chiffre obtenu une fois, sur une machine, n'est pas un chiffre. D'où trois choses. L'algorithme, en fonctions pures. Deux ressources s'épuisent en descendant : la mémoire, chaque étage gardant de quoi faire tourner ses propres démons, et le disque, celui de l'enfant vivant DANS celui du parent. Une troisième se dégrade, et elle borne le vCPU à deux au-delà du premier étage : douze ont gelé le noyau invité, les mêmes deux avançaient. La mémoire n'est PAS bornée — la même VM gelait au même octet avec 9 Go et avec 2 Go, donc la rogner ne gagnerait rien et priverait l'étage du dessous. Le plan est annoncé avant toute création, et jamais au-delà de ce qui tient. Le garde-fou dans l'écran. Il lisait la capacité de l'HÔTE et l'offrait en entier : sur un troisième étage à 14 cœurs, il a proposé 12 vCPU à une VM qui n'a jamais démarré. Le nombre n'était pas absurde pour la machine ; il l'était pour sa profondeur, que l'écran ignorait. Elle se compte maintenant sur la chaîne de ProxyJump — un rebond par étage, et c'est nous qui écrivons ces entrées. Le test long, dans LongTest/ et non dans test/ : le lanceur unitaire doit rester lançable en quelques secondes, partout, y compris sans virtualisation. La descente est uniforme — créer, attendre le ssh, installer, redémarrer et vérifier le noyau, remettre pmxcfs debout, contrôler le stockage — et s'arrête au premier étage qui échoue en NOMMANT l'étape. Il envoie notre install_proxmox.sh par scp plutôt que de laisser la VM cloner le dépôt : c'est notre code qu'on éprouve, et un correctif absent du distant a fait revenir le même défaut sur trois VM. --- EN --- The practicable nesting depth cannot be deduced, only measured. A manual measurement found, at the fourth level, a guest 36 times slower than real time — 583 seconds of wall clock for 16 seconds of guest time, each ACPI line taking a second — then a kernel frozen at the SAME byte whatever the resources. A number obtained once, on one machine, is not a number. Hence three things. The algorithm, in pure functions. Two resources run out going down: memory, each level keeping what its own daemons need, and disk, the child's living INSIDE the parent's. A third degrades, and it caps the vCPU at two beyond the first level: twelve froze the guest kernel, the same two progressed. Memory is NOT capped — the same VM froze at the same byte with 9 GB and with 2 GB, so trimming it would gain nothing and starve the level below. The plan is announced before anything is created, and never beyond what fits. The guard in the screen. It read the HOST's capacity and offered all of it: on a third level with 14 cores it proposed 12 vCPU to a VM that never booted. The number was not absurd for the machine; it was for its depth, which the screen did not know. It is now counted on the ProxyJump chain — one hop per level, and we are the ones writing those entries. The long test, in LongTest/ and not test/: the unit runner must stay runnable in seconds, anywhere, including without virtualisation. The descent is uniform — create, wait for ssh, install, reboot and check the kernel, bring pmxcfs back, check the storage — and stops at the first level that fails, NAMING the step. It sends our install_proxmox.sh over scp instead of letting the VM clone the repository: it is our code being exercised, and a fix absent from the remote made the same defect return on three VMs. Assisted-by: Claude Opus 5 (cherry picked from commit 4f70c461330cac6f46783a60e0f33052a979fa23)
2026-08-26 06:20:52 -04:00
#!/usr/bin/env python3
# © 2026 TechnoLibre (http://www.technolibre.ca)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
"""Les tests LONGS : de vraies machines, des heures.
Ils vivent dans `long_test/` et non dans `test/`, et ce n'est pas un rangement
[ADD] LongTest : jusqu'à quel étage un Proxmox imbriqué tient-il La profondeur d'imbrication praticable ne se déduit pas, elle se mesure. Une mesure à la main a trouvé, au quatrième étage, un invité 36 fois plus lent que le temps réel — 583 secondes d'horloge pour 16 secondes de temps invité, chaque ligne d'ACPI prenant une seconde — puis un noyau gelé au MÊME octet quelles que soient les ressources. Un chiffre obtenu une fois, sur une machine, n'est pas un chiffre. D'où trois choses. L'algorithme, en fonctions pures. Deux ressources s'épuisent en descendant : la mémoire, chaque étage gardant de quoi faire tourner ses propres démons, et le disque, celui de l'enfant vivant DANS celui du parent. Une troisième se dégrade, et elle borne le vCPU à deux au-delà du premier étage : douze ont gelé le noyau invité, les mêmes deux avançaient. La mémoire n'est PAS bornée — la même VM gelait au même octet avec 9 Go et avec 2 Go, donc la rogner ne gagnerait rien et priverait l'étage du dessous. Le plan est annoncé avant toute création, et jamais au-delà de ce qui tient. Le garde-fou dans l'écran. Il lisait la capacité de l'HÔTE et l'offrait en entier : sur un troisième étage à 14 cœurs, il a proposé 12 vCPU à une VM qui n'a jamais démarré. Le nombre n'était pas absurde pour la machine ; il l'était pour sa profondeur, que l'écran ignorait. Elle se compte maintenant sur la chaîne de ProxyJump — un rebond par étage, et c'est nous qui écrivons ces entrées. Le test long, dans LongTest/ et non dans test/ : le lanceur unitaire doit rester lançable en quelques secondes, partout, y compris sans virtualisation. La descente est uniforme — créer, attendre le ssh, installer, redémarrer et vérifier le noyau, remettre pmxcfs debout, contrôler le stockage — et s'arrête au premier étage qui échoue en NOMMANT l'étape. Il envoie notre install_proxmox.sh par scp plutôt que de laisser la VM cloner le dépôt : c'est notre code qu'on éprouve, et un correctif absent du distant a fait revenir le même défaut sur trois VM. --- EN --- The practicable nesting depth cannot be deduced, only measured. A manual measurement found, at the fourth level, a guest 36 times slower than real time — 583 seconds of wall clock for 16 seconds of guest time, each ACPI line taking a second — then a kernel frozen at the SAME byte whatever the resources. A number obtained once, on one machine, is not a number. Hence three things. The algorithm, in pure functions. Two resources run out going down: memory, each level keeping what its own daemons need, and disk, the child's living INSIDE the parent's. A third degrades, and it caps the vCPU at two beyond the first level: twelve froze the guest kernel, the same two progressed. Memory is NOT capped — the same VM froze at the same byte with 9 GB and with 2 GB, so trimming it would gain nothing and starve the level below. The plan is announced before anything is created, and never beyond what fits. The guard in the screen. It read the HOST's capacity and offered all of it: on a third level with 14 cores it proposed 12 vCPU to a VM that never booted. The number was not absurd for the machine; it was for its depth, which the screen did not know. It is now counted on the ProxyJump chain — one hop per level, and we are the ones writing those entries. The long test, in LongTest/ and not test/: the unit runner must stay runnable in seconds, anywhere, including without virtualisation. The descent is uniform — create, wait for ssh, install, reboot and check the kernel, bring pmxcfs back, check the storage — and stops at the first level that fails, NAMING the step. It sends our install_proxmox.sh over scp instead of letting the VM clone the repository: it is our code being exercised, and a fix absent from the remote made the same defect return on three VMs. Assisted-by: Claude Opus 5 (cherry picked from commit 4f70c461330cac6f46783a60e0f33052a979fa23)
2026-08-26 06:20:52 -04:00
de confort : le lanceur unitaire balaie `test/test_*.py` et doit rester
lançable en quelques secondes, partout. Un test qui crée dix VM n'a rien à y
faire — il le ferait échouer sur toute machine sans virtualisation, et
personne ne l'attendrait.
Ce menu ne fait que les lancer, en montrant leur sortie en direct : ces
scripts durent des heures, et une sortie capturée jusqu'à la fin ne dirait
rien pendant tout ce temps.
"""
import os
import click
from script.todo.todo_i18n import t
# Le répertoire des tests longs, à la racine du dépôt.
LONGTEST_DIR = "long_test"
[ADD] LongTest : jusqu'à quel étage un Proxmox imbriqué tient-il La profondeur d'imbrication praticable ne se déduit pas, elle se mesure. Une mesure à la main a trouvé, au quatrième étage, un invité 36 fois plus lent que le temps réel — 583 secondes d'horloge pour 16 secondes de temps invité, chaque ligne d'ACPI prenant une seconde — puis un noyau gelé au MÊME octet quelles que soient les ressources. Un chiffre obtenu une fois, sur une machine, n'est pas un chiffre. D'où trois choses. L'algorithme, en fonctions pures. Deux ressources s'épuisent en descendant : la mémoire, chaque étage gardant de quoi faire tourner ses propres démons, et le disque, celui de l'enfant vivant DANS celui du parent. Une troisième se dégrade, et elle borne le vCPU à deux au-delà du premier étage : douze ont gelé le noyau invité, les mêmes deux avançaient. La mémoire n'est PAS bornée — la même VM gelait au même octet avec 9 Go et avec 2 Go, donc la rogner ne gagnerait rien et priverait l'étage du dessous. Le plan est annoncé avant toute création, et jamais au-delà de ce qui tient. Le garde-fou dans l'écran. Il lisait la capacité de l'HÔTE et l'offrait en entier : sur un troisième étage à 14 cœurs, il a proposé 12 vCPU à une VM qui n'a jamais démarré. Le nombre n'était pas absurde pour la machine ; il l'était pour sa profondeur, que l'écran ignorait. Elle se compte maintenant sur la chaîne de ProxyJump — un rebond par étage, et c'est nous qui écrivons ces entrées. Le test long, dans LongTest/ et non dans test/ : le lanceur unitaire doit rester lançable en quelques secondes, partout, y compris sans virtualisation. La descente est uniforme — créer, attendre le ssh, installer, redémarrer et vérifier le noyau, remettre pmxcfs debout, contrôler le stockage — et s'arrête au premier étage qui échoue en NOMMANT l'étape. Il envoie notre install_proxmox.sh par scp plutôt que de laisser la VM cloner le dépôt : c'est notre code qu'on éprouve, et un correctif absent du distant a fait revenir le même défaut sur trois VM. --- EN --- The practicable nesting depth cannot be deduced, only measured. A manual measurement found, at the fourth level, a guest 36 times slower than real time — 583 seconds of wall clock for 16 seconds of guest time, each ACPI line taking a second — then a kernel frozen at the SAME byte whatever the resources. A number obtained once, on one machine, is not a number. Hence three things. The algorithm, in pure functions. Two resources run out going down: memory, each level keeping what its own daemons need, and disk, the child's living INSIDE the parent's. A third degrades, and it caps the vCPU at two beyond the first level: twelve froze the guest kernel, the same two progressed. Memory is NOT capped — the same VM froze at the same byte with 9 GB and with 2 GB, so trimming it would gain nothing and starve the level below. The plan is announced before anything is created, and never beyond what fits. The guard in the screen. It read the HOST's capacity and offered all of it: on a third level with 14 cores it proposed 12 vCPU to a VM that never booted. The number was not absurd for the machine; it was for its depth, which the screen did not know. It is now counted on the ProxyJump chain — one hop per level, and we are the ones writing those entries. The long test, in LongTest/ and not test/: the unit runner must stay runnable in seconds, anywhere, including without virtualisation. The descent is uniform — create, wait for ssh, install, reboot and check the kernel, bring pmxcfs back, check the storage — and stops at the first level that fails, NAMING the step. It sends our install_proxmox.sh over scp instead of letting the VM clone the repository: it is our code being exercised, and a fix absent from the remote made the same defect return on three VMs. Assisted-by: Claude Opus 5 (cherry picked from commit 4f70c461330cac6f46783a60e0f33052a979fa23)
2026-08-26 06:20:52 -04:00
[REF] long_test : moteur commun, sûreté déclarée, sixième étape deep_proxmox.py passe de 1245 à 474 lignes : tout ce qui ne connaît ni « qm » ni pmxcfs vit désormais dans descente.py, prêt pour un second test long. L'extraction a mis à nu ce qui protégeait un hôte qu'on n'a pas créé : rien. a_defaire exigeait « vmid » et « parent_alias », deux clés que seule une descente écrit — la protection tenait parce qu'aucun champ ne décrivait un hôte emprunté. Un champ « cree », écrit à l'instant de la création, la rend explicite et ferme trois portes : la liste de destruction, le repli par NOM de detruire_etage1, et le retrait des entrées ~/.ssh/config de l'utilisateur. Quatrième porte : le dossier des rapports est partagé. « deep_qemu --detruire » aurait pris le rapport le plus récent, fût-il celui d'une descente Proxmox. Le rapport porte son outil ; un rapport plus ancien, qui n'en a pas, est placé par le préfixe de son nom de fichier plutôt que d'être rendu indéfaisable. detruire_etage1 ne devine plus le nom de sa cible : il est obligatoire. Et une sixième étape est née — « cet étage peut-il héberger le suivant ? » — parce que le contrôle du stockage était celui du DÉBUT de l'étage suivant. 64 tests, les cinq garde-fous morts sous mutation. Au passage : la classe LongTestMenuMixin, que mon renommage de répertoire avait rebaptisée long_testMenuMixin sans qu'aucun test le voie. --- EN --- deep_proxmox.py drops from 1245 to 474 lines: everything that knows neither "qm" nor pmxcfs now lives in descente.py, ready for a second long test. The extraction laid bare what protected a host we did not create: nothing. a_defaire required "vmid" and "parent_alias", two keys only a descent writes — the protection held because no field described a borrowed host. A "cree" field, written the instant a machine is created, makes it explicit and closes three doors: the destroy list, detruire_etage1's fallback to the NAME, and the removal of the user's own ~/.ssh/config entries. Fourth door: the report directory is shared. "deep_qemu --detruire" would have taken the most recent report, Proxmox's included. Reports now carry their tool; an older one without it is placed by its filename prefix rather than made undestroyable. detruire_etage1 no longer guesses its target's name: it is mandatory. And a sixth step is born — "can this level host the next?" — because the storage check was the one at the START of the next level. 64 tests, all five guards die under mutation. Along the way: the class LongTestMenuMixin, which my directory rename had turned into long_testMenuMixin without any test noticing. Assisted-by: claude-opus-5 (cherry picked from commit e1bc9ae3cfacd36a502bc88dc0789a4e86ce986b)
2026-08-28 01:31:36 -04:00
class LongTestMenuMixin:
[ADD] LongTest : jusqu'à quel étage un Proxmox imbriqué tient-il La profondeur d'imbrication praticable ne se déduit pas, elle se mesure. Une mesure à la main a trouvé, au quatrième étage, un invité 36 fois plus lent que le temps réel — 583 secondes d'horloge pour 16 secondes de temps invité, chaque ligne d'ACPI prenant une seconde — puis un noyau gelé au MÊME octet quelles que soient les ressources. Un chiffre obtenu une fois, sur une machine, n'est pas un chiffre. D'où trois choses. L'algorithme, en fonctions pures. Deux ressources s'épuisent en descendant : la mémoire, chaque étage gardant de quoi faire tourner ses propres démons, et le disque, celui de l'enfant vivant DANS celui du parent. Une troisième se dégrade, et elle borne le vCPU à deux au-delà du premier étage : douze ont gelé le noyau invité, les mêmes deux avançaient. La mémoire n'est PAS bornée — la même VM gelait au même octet avec 9 Go et avec 2 Go, donc la rogner ne gagnerait rien et priverait l'étage du dessous. Le plan est annoncé avant toute création, et jamais au-delà de ce qui tient. Le garde-fou dans l'écran. Il lisait la capacité de l'HÔTE et l'offrait en entier : sur un troisième étage à 14 cœurs, il a proposé 12 vCPU à une VM qui n'a jamais démarré. Le nombre n'était pas absurde pour la machine ; il l'était pour sa profondeur, que l'écran ignorait. Elle se compte maintenant sur la chaîne de ProxyJump — un rebond par étage, et c'est nous qui écrivons ces entrées. Le test long, dans LongTest/ et non dans test/ : le lanceur unitaire doit rester lançable en quelques secondes, partout, y compris sans virtualisation. La descente est uniforme — créer, attendre le ssh, installer, redémarrer et vérifier le noyau, remettre pmxcfs debout, contrôler le stockage — et s'arrête au premier étage qui échoue en NOMMANT l'étape. Il envoie notre install_proxmox.sh par scp plutôt que de laisser la VM cloner le dépôt : c'est notre code qu'on éprouve, et un correctif absent du distant a fait revenir le même défaut sur trois VM. --- EN --- The practicable nesting depth cannot be deduced, only measured. A manual measurement found, at the fourth level, a guest 36 times slower than real time — 583 seconds of wall clock for 16 seconds of guest time, each ACPI line taking a second — then a kernel frozen at the SAME byte whatever the resources. A number obtained once, on one machine, is not a number. Hence three things. The algorithm, in pure functions. Two resources run out going down: memory, each level keeping what its own daemons need, and disk, the child's living INSIDE the parent's. A third degrades, and it caps the vCPU at two beyond the first level: twelve froze the guest kernel, the same two progressed. Memory is NOT capped — the same VM froze at the same byte with 9 GB and with 2 GB, so trimming it would gain nothing and starve the level below. The plan is announced before anything is created, and never beyond what fits. The guard in the screen. It read the HOST's capacity and offered all of it: on a third level with 14 cores it proposed 12 vCPU to a VM that never booted. The number was not absurd for the machine; it was for its depth, which the screen did not know. It is now counted on the ProxyJump chain — one hop per level, and we are the ones writing those entries. The long test, in LongTest/ and not test/: the unit runner must stay runnable in seconds, anywhere, including without virtualisation. The descent is uniform — create, wait for ssh, install, reboot and check the kernel, bring pmxcfs back, check the storage — and stops at the first level that fails, NAMING the step. It sends our install_proxmox.sh over scp instead of letting the VM clone the repository: it is our code being exercised, and a fix absent from the remote made the same defect return on three VMs. Assisted-by: Claude Opus 5 (cherry picked from commit 4f70c461330cac6f46783a60e0f33052a979fa23)
2026-08-26 06:20:52 -04:00
def _longtest_script(self, nom):
"""Chemin d'un test long, ou "" s'il n'est pas là."""
chemin = os.path.join(os.getcwd(), LONGTEST_DIR, nom)
return chemin if os.path.exists(chemin) else ""
def _longtest_run(self, nom, args=""):
"""Lance un test long, sortie en DIRECT.
En direct parce qu'il dure des heures : capturer sa sortie pour
l'afficher à la fin, c'est ne rien montrer pendant tout ce temps —
et c'est justement la progression étage par étage qui intéresse.
"""
chemin = self._longtest_script(nom)
if not chemin:
print(f" ✗ {t('Script not found:')} {LONGTEST_DIR}/{nom}")
return
cmd = f"./.venv.erplibre/bin/python {chemin}"
if args:
cmd += f" {args}"
print(f"\n{t('Will execute:')} {cmd}")
self.execute.exec_command_live(cmd, source_erplibre=False)
def prompt_execute_longtest(self):
print(f"⏳ {t('Long tests: real VMs, hours. Not the unit suite.')}")
choices = [
{
"prompt_description": t(
"Nested Proxmox depth: plan only (dry-run)"
)
},
{"prompt_description": t("Nested Proxmox depth: run it")},
[ADD] long_test : partir d'un hôte existant, et le menu des deux piles Créer une VM de tête pour héberger un hyperviseur qu'on possède déjà coûte cinq minutes ET un étage d'imbrication — donc de la lenteur, puisque c'est elle qu'on mesure. « --hote » part d'un hôte existant ; le menu le propose sans le rechercher, l'hôte Proxmox déjà retenu étant lu par _pve_host(ask=False). Trois conséquences que le code ne tirait pas : - le plan se dimensionne sur la RACINE, lue par ssh. Le dimensionner sur la machine locale quand les étages vivent ailleurs annoncerait des étages qui ne tiennent pas ; - les délais comptent la profondeur ABSOLUE. Un enfant de niveau 1 posé dans une racine déjà au troisième étage est en réalité au quatrième, et héritait de délais quatre fois trop courts — le défaut même que « delai » raconte avoir corrigé ; - la racine n'est pas un étage atteint. L'y compter décalait de un le total et le code de sortie ; elle va dans une clé à part, et jamais « cree ». « sudo » est DÉDUIT de « id -u » et non supposé, et une racine illisible fait renoncer au lieu d'inventer une capacité. Le menu offre les deux piles et défait chacune séparément — elles partagent le dossier des rapports mais chacune ne connaît que les siens. Un test vérifie que toute entrée affichée a son branchement : ils sont couplés par position, sans garde. 80 tests, quatre garde-fous morts sous mutation. --- EN --- Creating a head VM to host a hypervisor you already own costs five minutes AND one level of nesting — that is, slowness, which is the very thing being measured. "--hote" starts from an existing host; the menu offers it without searching, reading the already-chosen Proxmox host via _pve_host(ask=False). Three consequences the code did not draw: - the plan is sized on the ROOT, read over ssh. Sizing it on the local machine while the levels live elsewhere would announce levels that do not fit; - delays count ABSOLUTE depth. A level-1 child placed in a root already at the third level is really at the fourth, and inherited delays four times too short — the very defect "delai" recounts having fixed; - the root is not a level reached. Counting it shifted the total and the exit code by one; it goes in its own key, and never as "cree". "sudo" is DEDUCED from "id -u" rather than assumed, and an unreadable root makes us give up instead of inventing a capacity. The menu offers both stacks and undoes each separately — they share the report directory but each knows only its own. A test checks that every displayed entry has its branch: they are coupled by position, with no guard. 80 tests, four guards die under mutation. Assisted-by: claude-opus-5 (cherry picked from commit c2ab1a968346458925f55fc95619eb4ebd9d3efa)
2026-08-28 03:29:01 -04:00
{
"prompt_description": t(
"Nested QEMU depth: plan only (dry-run)"
)
},
{"prompt_description": t("Nested QEMU depth: run it")},
{"prompt_description": t("Download cache: plan only (dry-run)")},
{"prompt_description": t("Download cache: two VMs, measure")},
{
"prompt_description": t(
"Download cache: measure, then cut the upstream"
)
},
[ADD] LongTest : jusqu'à quel étage un Proxmox imbriqué tient-il La profondeur d'imbrication praticable ne se déduit pas, elle se mesure. Une mesure à la main a trouvé, au quatrième étage, un invité 36 fois plus lent que le temps réel — 583 secondes d'horloge pour 16 secondes de temps invité, chaque ligne d'ACPI prenant une seconde — puis un noyau gelé au MÊME octet quelles que soient les ressources. Un chiffre obtenu une fois, sur une machine, n'est pas un chiffre. D'où trois choses. L'algorithme, en fonctions pures. Deux ressources s'épuisent en descendant : la mémoire, chaque étage gardant de quoi faire tourner ses propres démons, et le disque, celui de l'enfant vivant DANS celui du parent. Une troisième se dégrade, et elle borne le vCPU à deux au-delà du premier étage : douze ont gelé le noyau invité, les mêmes deux avançaient. La mémoire n'est PAS bornée — la même VM gelait au même octet avec 9 Go et avec 2 Go, donc la rogner ne gagnerait rien et priverait l'étage du dessous. Le plan est annoncé avant toute création, et jamais au-delà de ce qui tient. Le garde-fou dans l'écran. Il lisait la capacité de l'HÔTE et l'offrait en entier : sur un troisième étage à 14 cœurs, il a proposé 12 vCPU à une VM qui n'a jamais démarré. Le nombre n'était pas absurde pour la machine ; il l'était pour sa profondeur, que l'écran ignorait. Elle se compte maintenant sur la chaîne de ProxyJump — un rebond par étage, et c'est nous qui écrivons ces entrées. Le test long, dans LongTest/ et non dans test/ : le lanceur unitaire doit rester lançable en quelques secondes, partout, y compris sans virtualisation. La descente est uniforme — créer, attendre le ssh, installer, redémarrer et vérifier le noyau, remettre pmxcfs debout, contrôler le stockage — et s'arrête au premier étage qui échoue en NOMMANT l'étape. Il envoie notre install_proxmox.sh par scp plutôt que de laisser la VM cloner le dépôt : c'est notre code qu'on éprouve, et un correctif absent du distant a fait revenir le même défaut sur trois VM. --- EN --- The practicable nesting depth cannot be deduced, only measured. A manual measurement found, at the fourth level, a guest 36 times slower than real time — 583 seconds of wall clock for 16 seconds of guest time, each ACPI line taking a second — then a kernel frozen at the SAME byte whatever the resources. A number obtained once, on one machine, is not a number. Hence three things. The algorithm, in pure functions. Two resources run out going down: memory, each level keeping what its own daemons need, and disk, the child's living INSIDE the parent's. A third degrades, and it caps the vCPU at two beyond the first level: twelve froze the guest kernel, the same two progressed. Memory is NOT capped — the same VM froze at the same byte with 9 GB and with 2 GB, so trimming it would gain nothing and starve the level below. The plan is announced before anything is created, and never beyond what fits. The guard in the screen. It read the HOST's capacity and offered all of it: on a third level with 14 cores it proposed 12 vCPU to a VM that never booted. The number was not absurd for the machine; it was for its depth, which the screen did not know. It is now counted on the ProxyJump chain — one hop per level, and we are the ones writing those entries. The long test, in LongTest/ and not test/: the unit runner must stay runnable in seconds, anywhere, including without virtualisation. The descent is uniform — create, wait for ssh, install, reboot and check the kernel, bring pmxcfs back, check the storage — and stops at the first level that fails, NAMING the step. It sends our install_proxmox.sh over scp instead of letting the VM clone the repository: it is our code being exercised, and a fix absent from the remote made the same defect return on three VMs. Assisted-by: Claude Opus 5 (cherry picked from commit 4f70c461330cac6f46783a60e0f33052a979fa23)
2026-08-26 06:20:52 -04:00
{"prompt_description": t("Undo what the descent created")},
]
# Le cache n'est pas une descente : ni profondeur, ni hôte de départ.
# Ses entrées sont donc traitées à part plutôt que pliées dans la
# table des piles imbriquées.
cache = {
"5": "--dry-run",
"6": "",
"7": "--hors-ligne",
}
[ADD] long_test : partir d'un hôte existant, et le menu des deux piles Créer une VM de tête pour héberger un hyperviseur qu'on possède déjà coûte cinq minutes ET un étage d'imbrication — donc de la lenteur, puisque c'est elle qu'on mesure. « --hote » part d'un hôte existant ; le menu le propose sans le rechercher, l'hôte Proxmox déjà retenu étant lu par _pve_host(ask=False). Trois conséquences que le code ne tirait pas : - le plan se dimensionne sur la RACINE, lue par ssh. Le dimensionner sur la machine locale quand les étages vivent ailleurs annoncerait des étages qui ne tiennent pas ; - les délais comptent la profondeur ABSOLUE. Un enfant de niveau 1 posé dans une racine déjà au troisième étage est en réalité au quatrième, et héritait de délais quatre fois trop courts — le défaut même que « delai » raconte avoir corrigé ; - la racine n'est pas un étage atteint. L'y compter décalait de un le total et le code de sortie ; elle va dans une clé à part, et jamais « cree ». « sudo » est DÉDUIT de « id -u » et non supposé, et une racine illisible fait renoncer au lieu d'inventer une capacité. Le menu offre les deux piles et défait chacune séparément — elles partagent le dossier des rapports mais chacune ne connaît que les siens. Un test vérifie que toute entrée affichée a son branchement : ils sont couplés par position, sans garde. 80 tests, quatre garde-fous morts sous mutation. --- EN --- Creating a head VM to host a hypervisor you already own costs five minutes AND one level of nesting — that is, slowness, which is the very thing being measured. "--hote" starts from an existing host; the menu offers it without searching, reading the already-chosen Proxmox host via _pve_host(ask=False). Three consequences the code did not draw: - the plan is sized on the ROOT, read over ssh. Sizing it on the local machine while the levels live elsewhere would announce levels that do not fit; - delays count ABSOLUTE depth. A level-1 child placed in a root already at the third level is really at the fourth, and inherited delays four times too short — the very defect "delai" recounts having fixed; - the root is not a level reached. Counting it shifted the total and the exit code by one; it goes in its own key, and never as "cree". "sudo" is DEDUCED from "id -u" rather than assumed, and an unreadable root makes us give up instead of inventing a capacity. The menu offers both stacks and undoes each separately — they share the report directory but each knows only its own. A test checks that every displayed entry has its branch: they are coupled by position, with no guard. 80 tests, four guards die under mutation. Assisted-by: claude-opus-5 (cherry picked from commit c2ab1a968346458925f55fc95619eb4ebd9d3efa)
2026-08-28 03:29:01 -04:00
# Chaque choix : le script, et s'il faut demander d'où l'on part.
scripts = {
"1": ("deep_proxmox.py", True),
"2": ("deep_proxmox.py", True),
"3": ("deep_qemu.py", True),
"4": ("deep_qemu.py", True),
}
[ADD] LongTest : jusqu'à quel étage un Proxmox imbriqué tient-il La profondeur d'imbrication praticable ne se déduit pas, elle se mesure. Une mesure à la main a trouvé, au quatrième étage, un invité 36 fois plus lent que le temps réel — 583 secondes d'horloge pour 16 secondes de temps invité, chaque ligne d'ACPI prenant une seconde — puis un noyau gelé au MÊME octet quelles que soient les ressources. Un chiffre obtenu une fois, sur une machine, n'est pas un chiffre. D'où trois choses. L'algorithme, en fonctions pures. Deux ressources s'épuisent en descendant : la mémoire, chaque étage gardant de quoi faire tourner ses propres démons, et le disque, celui de l'enfant vivant DANS celui du parent. Une troisième se dégrade, et elle borne le vCPU à deux au-delà du premier étage : douze ont gelé le noyau invité, les mêmes deux avançaient. La mémoire n'est PAS bornée — la même VM gelait au même octet avec 9 Go et avec 2 Go, donc la rogner ne gagnerait rien et priverait l'étage du dessous. Le plan est annoncé avant toute création, et jamais au-delà de ce qui tient. Le garde-fou dans l'écran. Il lisait la capacité de l'HÔTE et l'offrait en entier : sur un troisième étage à 14 cœurs, il a proposé 12 vCPU à une VM qui n'a jamais démarré. Le nombre n'était pas absurde pour la machine ; il l'était pour sa profondeur, que l'écran ignorait. Elle se compte maintenant sur la chaîne de ProxyJump — un rebond par étage, et c'est nous qui écrivons ces entrées. Le test long, dans LongTest/ et non dans test/ : le lanceur unitaire doit rester lançable en quelques secondes, partout, y compris sans virtualisation. La descente est uniforme — créer, attendre le ssh, installer, redémarrer et vérifier le noyau, remettre pmxcfs debout, contrôler le stockage — et s'arrête au premier étage qui échoue en NOMMANT l'étape. Il envoie notre install_proxmox.sh par scp plutôt que de laisser la VM cloner le dépôt : c'est notre code qu'on éprouve, et un correctif absent du distant a fait revenir le même défaut sur trois VM. --- EN --- The practicable nesting depth cannot be deduced, only measured. A manual measurement found, at the fourth level, a guest 36 times slower than real time — 583 seconds of wall clock for 16 seconds of guest time, each ACPI line taking a second — then a kernel frozen at the SAME byte whatever the resources. A number obtained once, on one machine, is not a number. Hence three things. The algorithm, in pure functions. Two resources run out going down: memory, each level keeping what its own daemons need, and disk, the child's living INSIDE the parent's. A third degrades, and it caps the vCPU at two beyond the first level: twelve froze the guest kernel, the same two progressed. Memory is NOT capped — the same VM froze at the same byte with 9 GB and with 2 GB, so trimming it would gain nothing and starve the level below. The plan is announced before anything is created, and never beyond what fits. The guard in the screen. It read the HOST's capacity and offered all of it: on a third level with 14 cores it proposed 12 vCPU to a VM that never booted. The number was not absurd for the machine; it was for its depth, which the screen did not know. It is now counted on the ProxyJump chain — one hop per level, and we are the ones writing those entries. The long test, in LongTest/ and not test/: the unit runner must stay runnable in seconds, anywhere, including without virtualisation. The descent is uniform — create, wait for ssh, install, reboot and check the kernel, bring pmxcfs back, check the storage — and stops at the first level that fails, NAMING the step. It sends our install_proxmox.sh over scp instead of letting the VM clone the repository: it is our code being exercised, and a fix absent from the remote made the same defect return on three VMs. Assisted-by: Claude Opus 5 (cherry picked from commit 4f70c461330cac6f46783a60e0f33052a979fa23)
2026-08-26 06:20:52 -04:00
help_info = self.fill_help_info(choices)
while True:
status = click.prompt(help_info)
print()
if status == "0":
return False
if status in cache:
self._longtest_run("qemu_cache.py", cache[status])
continue
[ADD] long_test : partir d'un hôte existant, et le menu des deux piles Créer une VM de tête pour héberger un hyperviseur qu'on possède déjà coûte cinq minutes ET un étage d'imbrication — donc de la lenteur, puisque c'est elle qu'on mesure. « --hote » part d'un hôte existant ; le menu le propose sans le rechercher, l'hôte Proxmox déjà retenu étant lu par _pve_host(ask=False). Trois conséquences que le code ne tirait pas : - le plan se dimensionne sur la RACINE, lue par ssh. Le dimensionner sur la machine locale quand les étages vivent ailleurs annoncerait des étages qui ne tiennent pas ; - les délais comptent la profondeur ABSOLUE. Un enfant de niveau 1 posé dans une racine déjà au troisième étage est en réalité au quatrième, et héritait de délais quatre fois trop courts — le défaut même que « delai » raconte avoir corrigé ; - la racine n'est pas un étage atteint. L'y compter décalait de un le total et le code de sortie ; elle va dans une clé à part, et jamais « cree ». « sudo » est DÉDUIT de « id -u » et non supposé, et une racine illisible fait renoncer au lieu d'inventer une capacité. Le menu offre les deux piles et défait chacune séparément — elles partagent le dossier des rapports mais chacune ne connaît que les siens. Un test vérifie que toute entrée affichée a son branchement : ils sont couplés par position, sans garde. 80 tests, quatre garde-fous morts sous mutation. --- EN --- Creating a head VM to host a hypervisor you already own costs five minutes AND one level of nesting — that is, slowness, which is the very thing being measured. "--hote" starts from an existing host; the menu offers it without searching, reading the already-chosen Proxmox host via _pve_host(ask=False). Three consequences the code did not draw: - the plan is sized on the ROOT, read over ssh. Sizing it on the local machine while the levels live elsewhere would announce levels that do not fit; - delays count ABSOLUTE depth. A level-1 child placed in a root already at the third level is really at the fourth, and inherited delays four times too short — the very defect "delai" recounts having fixed; - the root is not a level reached. Counting it shifted the total and the exit code by one; it goes in its own key, and never as "cree". "sudo" is DEDUCED from "id -u" rather than assumed, and an unreadable root makes us give up instead of inventing a capacity. The menu offers both stacks and undoes each separately — they share the report directory but each knows only its own. A test checks that every displayed entry has its branch: they are coupled by position, with no guard. 80 tests, four guards die under mutation. Assisted-by: claude-opus-5 (cherry picked from commit c2ab1a968346458925f55fc95619eb4ebd9d3efa)
2026-08-28 03:29:01 -04:00
if status in scripts:
script, demander = scripts[status]
# La profondeur est DEMANDÉE : c'est le réglage qui décide de
# la durée — au-delà de trois étages, tout est 15 à 30 fois
# plus lent, et cinq se comptent en heures.
args = f"--depth {self._longtest_depth()}"
if demander:
args += self._longtest_depart(script)
if status in ("1", "3"):
args += " --dry-run"
self._longtest_run(script, args)
elif status == "8":
[ADD] long_test : partir d'un hôte existant, et le menu des deux piles Créer une VM de tête pour héberger un hyperviseur qu'on possède déjà coûte cinq minutes ET un étage d'imbrication — donc de la lenteur, puisque c'est elle qu'on mesure. « --hote » part d'un hôte existant ; le menu le propose sans le rechercher, l'hôte Proxmox déjà retenu étant lu par _pve_host(ask=False). Trois conséquences que le code ne tirait pas : - le plan se dimensionne sur la RACINE, lue par ssh. Le dimensionner sur la machine locale quand les étages vivent ailleurs annoncerait des étages qui ne tiennent pas ; - les délais comptent la profondeur ABSOLUE. Un enfant de niveau 1 posé dans une racine déjà au troisième étage est en réalité au quatrième, et héritait de délais quatre fois trop courts — le défaut même que « delai » raconte avoir corrigé ; - la racine n'est pas un étage atteint. L'y compter décalait de un le total et le code de sortie ; elle va dans une clé à part, et jamais « cree ». « sudo » est DÉDUIT de « id -u » et non supposé, et une racine illisible fait renoncer au lieu d'inventer une capacité. Le menu offre les deux piles et défait chacune séparément — elles partagent le dossier des rapports mais chacune ne connaît que les siens. Un test vérifie que toute entrée affichée a son branchement : ils sont couplés par position, sans garde. 80 tests, quatre garde-fous morts sous mutation. --- EN --- Creating a head VM to host a hypervisor you already own costs five minutes AND one level of nesting — that is, slowness, which is the very thing being measured. "--hote" starts from an existing host; the menu offers it without searching, reading the already-chosen Proxmox host via _pve_host(ask=False). Three consequences the code did not draw: - the plan is sized on the ROOT, read over ssh. Sizing it on the local machine while the levels live elsewhere would announce levels that do not fit; - delays count ABSOLUTE depth. A level-1 child placed in a root already at the third level is really at the fourth, and inherited delays four times too short — the very defect "delai" recounts having fixed; - the root is not a level reached. Counting it shifted the total and the exit code by one; it goes in its own key, and never as "cree". "sudo" is DEDUCED from "id -u" rather than assumed, and an unreadable root makes us give up instead of inventing a capacity. The menu offers both stacks and undoes each separately — they share the report directory but each knows only its own. A test checks that every displayed entry has its branch: they are coupled by position, with no guard. 80 tests, four guards die under mutation. Assisted-by: claude-opus-5 (cherry picked from commit c2ab1a968346458925f55fc95619eb4ebd9d3efa)
2026-08-28 03:29:01 -04:00
self._longtest_defaire()
[ADD] LongTest : jusqu'à quel étage un Proxmox imbriqué tient-il La profondeur d'imbrication praticable ne se déduit pas, elle se mesure. Une mesure à la main a trouvé, au quatrième étage, un invité 36 fois plus lent que le temps réel — 583 secondes d'horloge pour 16 secondes de temps invité, chaque ligne d'ACPI prenant une seconde — puis un noyau gelé au MÊME octet quelles que soient les ressources. Un chiffre obtenu une fois, sur une machine, n'est pas un chiffre. D'où trois choses. L'algorithme, en fonctions pures. Deux ressources s'épuisent en descendant : la mémoire, chaque étage gardant de quoi faire tourner ses propres démons, et le disque, celui de l'enfant vivant DANS celui du parent. Une troisième se dégrade, et elle borne le vCPU à deux au-delà du premier étage : douze ont gelé le noyau invité, les mêmes deux avançaient. La mémoire n'est PAS bornée — la même VM gelait au même octet avec 9 Go et avec 2 Go, donc la rogner ne gagnerait rien et priverait l'étage du dessous. Le plan est annoncé avant toute création, et jamais au-delà de ce qui tient. Le garde-fou dans l'écran. Il lisait la capacité de l'HÔTE et l'offrait en entier : sur un troisième étage à 14 cœurs, il a proposé 12 vCPU à une VM qui n'a jamais démarré. Le nombre n'était pas absurde pour la machine ; il l'était pour sa profondeur, que l'écran ignorait. Elle se compte maintenant sur la chaîne de ProxyJump — un rebond par étage, et c'est nous qui écrivons ces entrées. Le test long, dans LongTest/ et non dans test/ : le lanceur unitaire doit rester lançable en quelques secondes, partout, y compris sans virtualisation. La descente est uniforme — créer, attendre le ssh, installer, redémarrer et vérifier le noyau, remettre pmxcfs debout, contrôler le stockage — et s'arrête au premier étage qui échoue en NOMMANT l'étape. Il envoie notre install_proxmox.sh par scp plutôt que de laisser la VM cloner le dépôt : c'est notre code qu'on éprouve, et un correctif absent du distant a fait revenir le même défaut sur trois VM. --- EN --- The practicable nesting depth cannot be deduced, only measured. A manual measurement found, at the fourth level, a guest 36 times slower than real time — 583 seconds of wall clock for 16 seconds of guest time, each ACPI line taking a second — then a kernel frozen at the SAME byte whatever the resources. A number obtained once, on one machine, is not a number. Hence three things. The algorithm, in pure functions. Two resources run out going down: memory, each level keeping what its own daemons need, and disk, the child's living INSIDE the parent's. A third degrades, and it caps the vCPU at two beyond the first level: twelve froze the guest kernel, the same two progressed. Memory is NOT capped — the same VM froze at the same byte with 9 GB and with 2 GB, so trimming it would gain nothing and starve the level below. The plan is announced before anything is created, and never beyond what fits. The guard in the screen. It read the HOST's capacity and offered all of it: on a third level with 14 cores it proposed 12 vCPU to a VM that never booted. The number was not absurd for the machine; it was for its depth, which the screen did not know. It is now counted on the ProxyJump chain — one hop per level, and we are the ones writing those entries. The long test, in LongTest/ and not test/: the unit runner must stay runnable in seconds, anywhere, including without virtualisation. The descent is uniform — create, wait for ssh, install, reboot and check the kernel, bring pmxcfs back, check the storage — and stops at the first level that fails, NAMING the step. It sends our install_proxmox.sh over scp instead of letting the VM clone the repository: it is our code being exercised, and a fix absent from the remote made the same defect return on three VMs. Assisted-by: Claude Opus 5 (cherry picked from commit 4f70c461330cac6f46783a60e0f33052a979fa23)
2026-08-26 06:20:52 -04:00
else:
print(t("Command not found !"))
[ADD] long_test : partir d'un hôte existant, et le menu des deux piles Créer une VM de tête pour héberger un hyperviseur qu'on possède déjà coûte cinq minutes ET un étage d'imbrication — donc de la lenteur, puisque c'est elle qu'on mesure. « --hote » part d'un hôte existant ; le menu le propose sans le rechercher, l'hôte Proxmox déjà retenu étant lu par _pve_host(ask=False). Trois conséquences que le code ne tirait pas : - le plan se dimensionne sur la RACINE, lue par ssh. Le dimensionner sur la machine locale quand les étages vivent ailleurs annoncerait des étages qui ne tiennent pas ; - les délais comptent la profondeur ABSOLUE. Un enfant de niveau 1 posé dans une racine déjà au troisième étage est en réalité au quatrième, et héritait de délais quatre fois trop courts — le défaut même que « delai » raconte avoir corrigé ; - la racine n'est pas un étage atteint. L'y compter décalait de un le total et le code de sortie ; elle va dans une clé à part, et jamais « cree ». « sudo » est DÉDUIT de « id -u » et non supposé, et une racine illisible fait renoncer au lieu d'inventer une capacité. Le menu offre les deux piles et défait chacune séparément — elles partagent le dossier des rapports mais chacune ne connaît que les siens. Un test vérifie que toute entrée affichée a son branchement : ils sont couplés par position, sans garde. 80 tests, quatre garde-fous morts sous mutation. --- EN --- Creating a head VM to host a hypervisor you already own costs five minutes AND one level of nesting — that is, slowness, which is the very thing being measured. "--hote" starts from an existing host; the menu offers it without searching, reading the already-chosen Proxmox host via _pve_host(ask=False). Three consequences the code did not draw: - the plan is sized on the ROOT, read over ssh. Sizing it on the local machine while the levels live elsewhere would announce levels that do not fit; - delays count ABSOLUTE depth. A level-1 child placed in a root already at the third level is really at the fourth, and inherited delays four times too short — the very defect "delai" recounts having fixed; - the root is not a level reached. Counting it shifted the total and the exit code by one; it goes in its own key, and never as "cree". "sudo" is DEDUCED from "id -u" rather than assumed, and an unreadable root makes us give up instead of inventing a capacity. The menu offers both stacks and undoes each separately — they share the report directory but each knows only its own. A test checks that every displayed entry has its branch: they are coupled by position, with no guard. 80 tests, four guards die under mutation. Assisted-by: claude-opus-5 (cherry picked from commit c2ab1a968346458925f55fc95619eb4ebd9d3efa)
2026-08-28 03:29:01 -04:00
def _longtest_defaire(self):
"""Défaire, chaque pile la sienne.
Les deux scripts partagent le dossier des rapports mais chacun ne
connaît que les siens : lancer les deux ne peut pas faire détruire à
l'un ce que l'autre a créé.
Le script demande « OUI » avant de détruire, mais il LISTE d'abord :
on lui fait faire cette liste à blanc pour qu'un choix d'une touche ne
mène pas directement à un « qm destroy --purge ».
"""
for script in ("deep_proxmox.py", "deep_qemu.py", "qemu_cache.py"):
[ADD] long_test : partir d'un hôte existant, et le menu des deux piles Créer une VM de tête pour héberger un hyperviseur qu'on possède déjà coûte cinq minutes ET un étage d'imbrication — donc de la lenteur, puisque c'est elle qu'on mesure. « --hote » part d'un hôte existant ; le menu le propose sans le rechercher, l'hôte Proxmox déjà retenu étant lu par _pve_host(ask=False). Trois conséquences que le code ne tirait pas : - le plan se dimensionne sur la RACINE, lue par ssh. Le dimensionner sur la machine locale quand les étages vivent ailleurs annoncerait des étages qui ne tiennent pas ; - les délais comptent la profondeur ABSOLUE. Un enfant de niveau 1 posé dans une racine déjà au troisième étage est en réalité au quatrième, et héritait de délais quatre fois trop courts — le défaut même que « delai » raconte avoir corrigé ; - la racine n'est pas un étage atteint. L'y compter décalait de un le total et le code de sortie ; elle va dans une clé à part, et jamais « cree ». « sudo » est DÉDUIT de « id -u » et non supposé, et une racine illisible fait renoncer au lieu d'inventer une capacité. Le menu offre les deux piles et défait chacune séparément — elles partagent le dossier des rapports mais chacune ne connaît que les siens. Un test vérifie que toute entrée affichée a son branchement : ils sont couplés par position, sans garde. 80 tests, quatre garde-fous morts sous mutation. --- EN --- Creating a head VM to host a hypervisor you already own costs five minutes AND one level of nesting — that is, slowness, which is the very thing being measured. "--hote" starts from an existing host; the menu offers it without searching, reading the already-chosen Proxmox host via _pve_host(ask=False). Three consequences the code did not draw: - the plan is sized on the ROOT, read over ssh. Sizing it on the local machine while the levels live elsewhere would announce levels that do not fit; - delays count ABSOLUTE depth. A level-1 child placed in a root already at the third level is really at the fourth, and inherited delays four times too short — the very defect "delai" recounts having fixed; - the root is not a level reached. Counting it shifted the total and the exit code by one; it goes in its own key, and never as "cree". "sudo" is DEDUCED from "id -u" rather than assumed, and an unreadable root makes us give up instead of inventing a capacity. The menu offers both stacks and undoes each separately — they share the report directory but each knows only its own. A test checks that every displayed entry has its branch: they are coupled by position, with no guard. 80 tests, four guards die under mutation. Assisted-by: claude-opus-5 (cherry picked from commit c2ab1a968346458925f55fc95619eb4ebd9d3efa)
2026-08-28 03:29:01 -04:00
self._longtest_run(script, "--detruire --dry-run")
if self._is_yes(input(f"\n{t('Destroy all that? (y/N): ')}")):
self._longtest_run(script, "--detruire")
def _longtest_depart(self, script):
"""D'où part la descente : une VM neuve, ou un hôte qu'on a déjà.
Créer une machine de tête pour héberger un hyperviseur qu'on possède
déjà coûte cinq minutes ET un étage d'imbrication — donc de la
lenteur, puisque c'est justement elle qu'on mesure.
L'hôte déjà retenu est proposé sans qu'on ait à le rechercher : c'est
`_pve_host(ask=False)`, qui ne demande rien et ne dit rien s'il n'y en
a pas.
"""
connu = None
if script == "deep_proxmox.py":
try:
connu = self._pve_host(ask=False)
except Exception: # noqa: BLE001 - une préférence illisible
connu = None
print(f"\n{t('Where does the descent start?')}")
print(f" [1] {t('Create a fresh QEMU VM as level one')} *")
if connu:
print(f" [2] {t('Start from:')} {self._pve_label(connu)}")
print(f" [3] {t('Start from another existing host')}")
choix = input(t("Choice (1-3, default 1): ")).strip()
if choix == "2" and connu:
return self._longtest_args_hote(connu)
if choix == "3":
hote = (
self._pve_pick_host()
if script == "deep_proxmox.py"
else self._longtest_hote_manuel()
)
if hote:
return self._longtest_args_hote(hote)
print(t("Cancelled."))
return ""
@staticmethod
def _longtest_args_hote(hote):
"""Les options que le script attend, à partir d'un dict d'hôte."""
args = f" --hote {hote['target']}"
if hote.get("jump"):
args += f" --jump {hote['jump']}"
return args
def _longtest_hote_manuel(self):
"""Un hôte libvirt de départ, saisi à la main.
Pas de sélecteur vérifié comme pour Proxmox : ce qu'on veut ici, c'est
un hôte qui porte KVM, et c'est le script qui le CONSTATE au premier
contrôle — /dev/kvm et l'imbrication — plutôt que le menu qui le
suppose.
"""
cible = input(t("Address (user@host, blank = cancel): ")).strip()
if not cible:
return None
return {
"target": cible,
"jump": input(t("SSH jump host (blank = none): ")).strip(),
}
[ADD] LongTest : jusqu'à quel étage un Proxmox imbriqué tient-il La profondeur d'imbrication praticable ne se déduit pas, elle se mesure. Une mesure à la main a trouvé, au quatrième étage, un invité 36 fois plus lent que le temps réel — 583 secondes d'horloge pour 16 secondes de temps invité, chaque ligne d'ACPI prenant une seconde — puis un noyau gelé au MÊME octet quelles que soient les ressources. Un chiffre obtenu une fois, sur une machine, n'est pas un chiffre. D'où trois choses. L'algorithme, en fonctions pures. Deux ressources s'épuisent en descendant : la mémoire, chaque étage gardant de quoi faire tourner ses propres démons, et le disque, celui de l'enfant vivant DANS celui du parent. Une troisième se dégrade, et elle borne le vCPU à deux au-delà du premier étage : douze ont gelé le noyau invité, les mêmes deux avançaient. La mémoire n'est PAS bornée — la même VM gelait au même octet avec 9 Go et avec 2 Go, donc la rogner ne gagnerait rien et priverait l'étage du dessous. Le plan est annoncé avant toute création, et jamais au-delà de ce qui tient. Le garde-fou dans l'écran. Il lisait la capacité de l'HÔTE et l'offrait en entier : sur un troisième étage à 14 cœurs, il a proposé 12 vCPU à une VM qui n'a jamais démarré. Le nombre n'était pas absurde pour la machine ; il l'était pour sa profondeur, que l'écran ignorait. Elle se compte maintenant sur la chaîne de ProxyJump — un rebond par étage, et c'est nous qui écrivons ces entrées. Le test long, dans LongTest/ et non dans test/ : le lanceur unitaire doit rester lançable en quelques secondes, partout, y compris sans virtualisation. La descente est uniforme — créer, attendre le ssh, installer, redémarrer et vérifier le noyau, remettre pmxcfs debout, contrôler le stockage — et s'arrête au premier étage qui échoue en NOMMANT l'étape. Il envoie notre install_proxmox.sh par scp plutôt que de laisser la VM cloner le dépôt : c'est notre code qu'on éprouve, et un correctif absent du distant a fait revenir le même défaut sur trois VM. --- EN --- The practicable nesting depth cannot be deduced, only measured. A manual measurement found, at the fourth level, a guest 36 times slower than real time — 583 seconds of wall clock for 16 seconds of guest time, each ACPI line taking a second — then a kernel frozen at the SAME byte whatever the resources. A number obtained once, on one machine, is not a number. Hence three things. The algorithm, in pure functions. Two resources run out going down: memory, each level keeping what its own daemons need, and disk, the child's living INSIDE the parent's. A third degrades, and it caps the vCPU at two beyond the first level: twelve froze the guest kernel, the same two progressed. Memory is NOT capped — the same VM froze at the same byte with 9 GB and with 2 GB, so trimming it would gain nothing and starve the level below. The plan is announced before anything is created, and never beyond what fits. The guard in the screen. It read the HOST's capacity and offered all of it: on a third level with 14 cores it proposed 12 vCPU to a VM that never booted. The number was not absurd for the machine; it was for its depth, which the screen did not know. It is now counted on the ProxyJump chain — one hop per level, and we are the ones writing those entries. The long test, in LongTest/ and not test/: the unit runner must stay runnable in seconds, anywhere, including without virtualisation. The descent is uniform — create, wait for ssh, install, reboot and check the kernel, bring pmxcfs back, check the storage — and stops at the first level that fails, NAMING the step. It sends our install_proxmox.sh over scp instead of letting the VM clone the repository: it is our code being exercised, and a fix absent from the remote made the same defect return on three VMs. Assisted-by: Claude Opus 5 (cherry picked from commit 4f70c461330cac6f46783a60e0f33052a979fa23)
2026-08-26 06:20:52 -04:00
def _longtest_depth(self):
"""Profondeur demandée. Trois par défaut, parce que trois marche.
Mesuré sur cette machine : les trois premiers étages prennent 280, 495
et 1 064 secondes — une demi-heure. Le quatrième a demandé 7 h 18
d'installation et 4 h 20 d'amorçage, et les suivants se comptent en
jours. Dix par défaut promettait ce qu'aucune machine ne tient.
"""
brut = input(f"{t('Depth (default 3): ')}").strip()
return int(brut) if brut.isdigit() and int(brut) > 0 else 3