[UPD] LongTest : trois étages par défaut, la mesure le dit
Le défaut promettait dix étages qu'aucune machine ne tient. Une descente
complète par ligne, sur 28 cœurs :
étage 1 : 0 s d'amorçage, 200 s d'installation, 280 s en tout
étage 2 : 37 s, 344 s, 495 s
étage 3 : 93 s, 777 s, 1 064 s
étage 4 : 15 608 s, 26 306 s, n'a pas abouti
Trois étages coûtent une demi-heure. Le quatrième a coûté 4 h 20 d'amorçage et
7 h 18 d'installation sur la même machine : tout y est 15 à 30 fois plus lent,
pas une seule étape. C'est aussi là que les fabricants s'arrêtent — le
quatrième étage est le troisième hyperviseur imbriqué, AMD en documente deux.
La profondeur reste le seul paramètre, et le README dit désormais ce qu'on
achète en la montant.
--- EN ---
The default promised ten levels no machine can hold. One full descent per row,
on 28 cores:
level 1: 0 s boot, 200 s install, 280 s total
level 2: 37 s, 344 s, 495 s
level 3: 93 s, 777 s, 1 064 s
level 4: 15 608 s, 26 306 s, did not finish
Three levels cost half an hour. The fourth cost 4 h 20 of boot and 7 h 18 of
install on the same machine: everything there is 15 to 30 times slower, not one
step. It is also where the vendors stop — level 4 is the third nested
hypervisor, and AMD documents two.
Depth remains the only parameter, and the README now says what raising it buys.
Assisted-by: claude-opus-5
(cherry picked from commit 226d6ffa3c664ba9e1a6dfdf48d52027b52eda23)
This commit is contained in:
parent
30399b4559
commit
8e5f5b9097
7 changed files with 187 additions and 16 deletions
|
|
@ -33,11 +33,36 @@ Which is the point of the script: a number obtained once, on one machine, in
|
||||||
one chain, is an anecdote.
|
one chain, is an anecdote.
|
||||||
|
|
||||||
```
|
```
|
||||||
./LongTest/deep_proxmox.py --depth 10 --dry-run # the plan, nothing created
|
./LongTest/deep_proxmox.py # three levels, ~30 minutes
|
||||||
./LongTest/deep_proxmox.py --depth 10 # hours
|
./LongTest/deep_proxmox.py --dry-run # the plan, nothing created
|
||||||
|
./LongTest/deep_proxmox.py --depth 5 # ask for more, knowingly
|
||||||
./LongTest/deep_proxmox.py --detruire # undo it
|
./LongTest/deep_proxmox.py --detruire # undo it
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### How deep is worth asking for
|
||||||
|
|
||||||
|
The depth is the only setting, and **three** is the default because three
|
||||||
|
works. Measured on a 28-core machine, one full descent per row:
|
||||||
|
|
||||||
|
| level | boot (ssh) | install | total |
|
||||||
|
|------:|-----------:|--------:|------:|
|
||||||
|
| 1 | 0 s | 200 s | 280 s |
|
||||||
|
| 2 | 37 s | 344 s | 495 s |
|
||||||
|
| 3 | 93 s | 777 s | 1 064 s |
|
||||||
|
| 4 | **15 608 s** | **26 306 s** | did not finish |
|
||||||
|
|
||||||
|
Three levels cost half an hour. The **fourth** cost 4 h 20 of boot and 7 h 18
|
||||||
|
of install on the same machine — everything there is 15 to 30 times slower, not
|
||||||
|
just one step. And it lands exactly where the hardware vendors stop: level 4 is
|
||||||
|
the *third* nested hypervisor, and AMD documents two.
|
||||||
|
|
||||||
|
A wider guest makes it worse, sharply: at level 4, one extra vCPU multiplied
|
||||||
|
the boot by 9.4 (1 664 s at two vCPU, 15 608 s at three), and at eight vCPU the
|
||||||
|
guest read 32 MiB in 106 minutes with a static instruction pointer. At levels 2
|
||||||
|
and 3 that same vCPU costs nothing.
|
||||||
|
|
||||||
|
So: three by default, five if you want to know, ten only to watch the wall.
|
||||||
|
|
||||||
The descent is **uniform**. Every level, the first included, goes through the
|
The descent is **uniform**. Every level, the first included, goes through the
|
||||||
same six steps: create, wait for ssh, install Proxmox, reboot and check the
|
same six steps: create, wait for ssh, install Proxmox, reboot and check the
|
||||||
kernel, bring pmxcfs back up, check the storage. Only creation differs —
|
kernel, bring pmxcfs back up, check the storage. Only creation differs —
|
||||||
|
|
@ -141,11 +166,37 @@ D'où le script : un chiffre obtenu une fois, sur une machine, dans une chaîne,
|
||||||
est une anecdote.
|
est une anecdote.
|
||||||
|
|
||||||
```
|
```
|
||||||
./LongTest/deep_proxmox.py --depth 10 --dry-run # le plan, rien de créé
|
./LongTest/deep_proxmox.py # trois étages, ~30 minutes
|
||||||
./LongTest/deep_proxmox.py --depth 10 # des heures
|
./LongTest/deep_proxmox.py --dry-run # le plan, rien de créé
|
||||||
|
./LongTest/deep_proxmox.py --depth 5 # en demander plus, sciemment
|
||||||
./LongTest/deep_proxmox.py --detruire # défaire
|
./LongTest/deep_proxmox.py --detruire # défaire
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Quelle profondeur vaut la peine d'être demandée
|
||||||
|
|
||||||
|
La profondeur est le seul réglage, et **trois** est le défaut parce que trois
|
||||||
|
marche. Mesuré sur une machine à 28 cœurs, une descente complète par ligne :
|
||||||
|
|
||||||
|
| étage | amorçage (ssh) | installation | total |
|
||||||
|
|------:|---------------:|-------------:|------:|
|
||||||
|
| 1 | 0 s | 200 s | 280 s |
|
||||||
|
| 2 | 37 s | 344 s | 495 s |
|
||||||
|
| 3 | 93 s | 777 s | 1 064 s |
|
||||||
|
| 4 | **15 608 s** | **26 306 s** | n'a pas abouti |
|
||||||
|
|
||||||
|
Trois étages coûtent une demi-heure. Le **quatrième** a coûté 4 h 20
|
||||||
|
d'amorçage et 7 h 18 d'installation sur la même machine — tout y est 15 à 30
|
||||||
|
fois plus lent, pas une seule étape. Et cela tombe précisément là où les
|
||||||
|
fabricants s'arrêtent : le quatrième étage est le *troisième* hyperviseur
|
||||||
|
imbriqué, et AMD en documente deux.
|
||||||
|
|
||||||
|
Un invité plus large aggrave brutalement : au quatrième étage, un vCPU de plus
|
||||||
|
a multiplié l'amorçage par 9,4 (1 664 s à deux vCPU, 15 608 s à trois), et à
|
||||||
|
huit vCPU l'invité a lu 32 Mio en 106 minutes, pointeur d'instruction
|
||||||
|
immobile. Aux étages 2 et 3, ce même vCPU ne coûte rien.
|
||||||
|
|
||||||
|
Donc : trois par défaut, cinq pour savoir, dix seulement pour voir le mur.
|
||||||
|
|
||||||
La descente est **uniforme**. Chaque étage, le premier compris, passe par les
|
La descente est **uniforme**. Chaque étage, le premier compris, passe par les
|
||||||
mêmes six étapes : créer, attendre le ssh, installer Proxmox, redémarrer et
|
mêmes six étapes : créer, attendre le ssh, installer Proxmox, redémarrer et
|
||||||
vérifier le noyau, remettre pmxcfs debout, contrôler le stockage. Seule la
|
vérifier le noyau, remettre pmxcfs debout, contrôler le stockage. Seule la
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,37 @@ D'où le script : un chiffre obtenu une fois, sur une machine, dans une chaîne,
|
||||||
est une anecdote.
|
est une anecdote.
|
||||||
|
|
||||||
```
|
```
|
||||||
./LongTest/deep_proxmox.py --depth 10 --dry-run # le plan, rien de créé
|
./LongTest/deep_proxmox.py # trois étages, ~30 minutes
|
||||||
./LongTest/deep_proxmox.py --depth 10 # des heures
|
./LongTest/deep_proxmox.py --dry-run # le plan, rien de créé
|
||||||
|
./LongTest/deep_proxmox.py --depth 5 # en demander plus, sciemment
|
||||||
./LongTest/deep_proxmox.py --detruire # défaire
|
./LongTest/deep_proxmox.py --detruire # défaire
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Quelle profondeur vaut la peine d'être demandée
|
||||||
|
|
||||||
|
La profondeur est le seul réglage, et **trois** est le défaut parce que trois
|
||||||
|
marche. Mesuré sur une machine à 28 cœurs, une descente complète par ligne :
|
||||||
|
|
||||||
|
| étage | amorçage (ssh) | installation | total |
|
||||||
|
|------:|---------------:|-------------:|------:|
|
||||||
|
| 1 | 0 s | 200 s | 280 s |
|
||||||
|
| 2 | 37 s | 344 s | 495 s |
|
||||||
|
| 3 | 93 s | 777 s | 1 064 s |
|
||||||
|
| 4 | **15 608 s** | **26 306 s** | n'a pas abouti |
|
||||||
|
|
||||||
|
Trois étages coûtent une demi-heure. Le **quatrième** a coûté 4 h 20
|
||||||
|
d'amorçage et 7 h 18 d'installation sur la même machine — tout y est 15 à 30
|
||||||
|
fois plus lent, pas une seule étape. Et cela tombe précisément là où les
|
||||||
|
fabricants s'arrêtent : le quatrième étage est le *troisième* hyperviseur
|
||||||
|
imbriqué, et AMD en documente deux.
|
||||||
|
|
||||||
|
Un invité plus large aggrave brutalement : au quatrième étage, un vCPU de plus
|
||||||
|
a multiplié l'amorçage par 9,4 (1 664 s à deux vCPU, 15 608 s à trois), et à
|
||||||
|
huit vCPU l'invité a lu 32 Mio en 106 minutes, pointeur d'instruction
|
||||||
|
immobile. Aux étages 2 et 3, ce même vCPU ne coûte rien.
|
||||||
|
|
||||||
|
Donc : trois par défaut, cinq pour savoir, dix seulement pour voir le mur.
|
||||||
|
|
||||||
La descente est **uniforme**. Chaque étage, le premier compris, passe par les
|
La descente est **uniforme**. Chaque étage, le premier compris, passe par les
|
||||||
mêmes six étapes : créer, attendre le ssh, installer Proxmox, redémarrer et
|
mêmes six étapes : créer, attendre le ssh, installer Proxmox, redémarrer et
|
||||||
vérifier le noyau, remettre pmxcfs debout, contrôler le stockage. Seule la
|
vérifier le noyau, remettre pmxcfs debout, contrôler le stockage. Seule la
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,36 @@ Which is the point of the script: a number obtained once, on one machine, in
|
||||||
one chain, is an anecdote.
|
one chain, is an anecdote.
|
||||||
|
|
||||||
```
|
```
|
||||||
./LongTest/deep_proxmox.py --depth 10 --dry-run # the plan, nothing created
|
./LongTest/deep_proxmox.py # three levels, ~30 minutes
|
||||||
./LongTest/deep_proxmox.py --depth 10 # hours
|
./LongTest/deep_proxmox.py --dry-run # the plan, nothing created
|
||||||
|
./LongTest/deep_proxmox.py --depth 5 # ask for more, knowingly
|
||||||
./LongTest/deep_proxmox.py --detruire # undo it
|
./LongTest/deep_proxmox.py --detruire # undo it
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### How deep is worth asking for
|
||||||
|
|
||||||
|
The depth is the only setting, and **three** is the default because three
|
||||||
|
works. Measured on a 28-core machine, one full descent per row:
|
||||||
|
|
||||||
|
| level | boot (ssh) | install | total |
|
||||||
|
|------:|-----------:|--------:|------:|
|
||||||
|
| 1 | 0 s | 200 s | 280 s |
|
||||||
|
| 2 | 37 s | 344 s | 495 s |
|
||||||
|
| 3 | 93 s | 777 s | 1 064 s |
|
||||||
|
| 4 | **15 608 s** | **26 306 s** | did not finish |
|
||||||
|
|
||||||
|
Three levels cost half an hour. The **fourth** cost 4 h 20 of boot and 7 h 18
|
||||||
|
of install on the same machine — everything there is 15 to 30 times slower, not
|
||||||
|
just one step. And it lands exactly where the hardware vendors stop: level 4 is
|
||||||
|
the *third* nested hypervisor, and AMD documents two.
|
||||||
|
|
||||||
|
A wider guest makes it worse, sharply: at level 4, one extra vCPU multiplied
|
||||||
|
the boot by 9.4 (1 664 s at two vCPU, 15 608 s at three), and at eight vCPU the
|
||||||
|
guest read 32 MiB in 106 minutes with a static instruction pointer. At levels 2
|
||||||
|
and 3 that same vCPU costs nothing.
|
||||||
|
|
||||||
|
So: three by default, five if you want to know, ten only to watch the wall.
|
||||||
|
|
||||||
The descent is **uniform**. Every level, the first included, goes through the
|
The descent is **uniform**. Every level, the first included, goes through the
|
||||||
same six steps: create, wait for ssh, install Proxmox, reboot and check the
|
same six steps: create, wait for ssh, install Proxmox, reboot and check the
|
||||||
kernel, bring pmxcfs back up, check the storage. Only creation differs —
|
kernel, bring pmxcfs back up, check the storage. Only creation differs —
|
||||||
|
|
|
||||||
|
|
@ -1174,7 +1174,13 @@ def principal(argv=None):
|
||||||
parseur = argparse.ArgumentParser(
|
parseur = argparse.ArgumentParser(
|
||||||
description="Jusqu'à quel étage un Proxmox dans un Proxmox tient-il ?"
|
description="Jusqu'à quel étage un Proxmox dans un Proxmox tient-il ?"
|
||||||
)
|
)
|
||||||
parseur.add_argument("--depth", type=int, default=10)
|
# Trois par défaut, et c'est une MESURE, pas une prudence : les trois
|
||||||
|
# premiers étages coûtent 280, 495 et 1 064 secondes — une demi-heure en
|
||||||
|
# tout. Le quatrième en a coûté 7 h 18 d'installation et 4 h 20 d'amorçage
|
||||||
|
# sur la même machine. Un défaut à dix promettait ce qu'aucune machine ne
|
||||||
|
# peut tenir ; la profondeur reste un paramètre, et c'est à qui la demande
|
||||||
|
# de savoir ce qu'il demande.
|
||||||
|
parseur.add_argument("--depth", type=int, default=3)
|
||||||
parseur.add_argument("--dry-run", action="store_true")
|
parseur.add_argument("--dry-run", action="store_true")
|
||||||
parseur.add_argument("--detruire", action="store_true")
|
parseur.add_argument("--detruire", action="store_true")
|
||||||
args = parseur.parse_args(argv)
|
args = parseur.parse_args(argv)
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,12 @@ class LongTestMenuMixin:
|
||||||
print(t("Command not found !"))
|
print(t("Command not found !"))
|
||||||
|
|
||||||
def _longtest_depth(self):
|
def _longtest_depth(self):
|
||||||
"""Profondeur demandée. Dix par défaut : c'est ce qu'on veut mesurer."""
|
"""Profondeur demandée. Trois par défaut, parce que trois marche.
|
||||||
brut = input(f"{t('Depth (default 10): ')}").strip()
|
|
||||||
return int(brut) if brut.isdigit() and int(brut) > 0 else 10
|
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
|
||||||
|
|
|
||||||
|
|
@ -3454,9 +3454,9 @@ TRANSLATIONS = {
|
||||||
"fr": "Script introuvable :",
|
"fr": "Script introuvable :",
|
||||||
"en": "Script not found:",
|
"en": "Script not found:",
|
||||||
},
|
},
|
||||||
"Depth (default 10): ": {
|
"Depth (default 3): ": {
|
||||||
"fr": "Profondeur (défaut 10) : ",
|
"fr": "Profondeur (défaut 3) : ",
|
||||||
"en": "Depth (default 10): ",
|
"en": "Depth (default 3): ",
|
||||||
},
|
},
|
||||||
"Nesting level": {
|
"Nesting level": {
|
||||||
"fr": "Étage d'imbrication",
|
"fr": "Étage d'imbrication",
|
||||||
|
|
|
||||||
|
|
@ -208,15 +208,72 @@ class TestLEssaiABlanc(unittest.TestCase):
|
||||||
(int(n), int(v), int(r), int(d)) for n, v, r, d in plan
|
(int(n), int(v), int(r), int(d)) for n, v, r, d in plan
|
||||||
)
|
)
|
||||||
for parent, enfant in zip(etages, etages[1:]):
|
for parent, enfant in zip(etages, etages[1:]):
|
||||||
for i, quoi in ((1, "vCPU"), (2, "RAM"), (3, "disque")):
|
# Mémoire et disque : STRICTEMENT décroissants, chaque parent
|
||||||
|
# portant son enfant en plus de lui-même.
|
||||||
|
for i, quoi in ((2, "RAM"), (3, "disque")):
|
||||||
self.assertGreater(
|
self.assertGreater(
|
||||||
parent[i], enfant[i], f"étage {parent[0]} : {quoi}"
|
parent[i], enfant[i], f"étage {parent[0]} : {quoi}"
|
||||||
)
|
)
|
||||||
|
# Le processeur : jamais plus étroit, mais pas toujours plus
|
||||||
|
# large. Deux étages imbriqués peu profonds ont la même largeur —
|
||||||
|
# au quatrième étage, un vCPU de plus multiplie l'amorçage par
|
||||||
|
# 9,4, alors qu'aux étages 2 et 3 il ne coûte rien.
|
||||||
|
self.assertGreaterEqual(
|
||||||
|
parent[1], enfant[1], f"étage {parent[0]} : vCPU"
|
||||||
|
)
|
||||||
# Et le plus profond reçoit ce qu'un Proxmox de test demande, pas ce
|
# Et le plus profond reçoit ce qu'un Proxmox de test demande, pas ce
|
||||||
# qui reste.
|
# qui reste.
|
||||||
self.assertEqual(etages[-1][1], 2, "vCPU du plus profond")
|
self.assertEqual(etages[-1][1], 2, "vCPU du plus profond")
|
||||||
|
|
||||||
|
|
||||||
|
class TestLaProfondeurParDefaut(unittest.TestCase):
|
||||||
|
"""Trois, et c'est une MESURE, pas une prudence.
|
||||||
|
|
||||||
|
Sur la machine où ce test a été écrit, les trois premiers étages coûtent
|
||||||
|
280, 495 et 1 064 secondes — une demi-heure en tout. Le quatrième a demandé
|
||||||
|
7 h 18 d'installation et 4 h 20 d'amorçage, et les suivants se comptent en
|
||||||
|
jours. Un défaut à dix promettait ce qu'aucune machine ne peut tenir : la
|
||||||
|
profondeur reste un paramètre, mais le défaut doit marcher."""
|
||||||
|
|
||||||
|
def test_the_script_defaults_to_three(self):
|
||||||
|
import inspect
|
||||||
|
import sys as _sys
|
||||||
|
|
||||||
|
_sys.path.insert(0, os.path.join(RACINE, "LongTest"))
|
||||||
|
import deep_proxmox
|
||||||
|
|
||||||
|
src = inspect.getsource(deep_proxmox.principal)
|
||||||
|
self.assertIn('"--depth", type=int, default=3', src)
|
||||||
|
|
||||||
|
def test_the_menu_defaults_to_three(self):
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
from script.todo.todo import TODO
|
||||||
|
|
||||||
|
src = inspect.getsource(TODO._longtest_depth)
|
||||||
|
self.assertIn("else 3", src)
|
||||||
|
# Et l'invite le DIT : un défaut caché se subit, il ne se choisit pas.
|
||||||
|
self.assertIn("Depth (default 3): ", src)
|
||||||
|
|
||||||
|
def test_the_prompt_is_translated(self):
|
||||||
|
from script.todo.todo_i18n import TRANSLATIONS
|
||||||
|
|
||||||
|
entree = TRANSLATIONS.get("Depth (default 3): ")
|
||||||
|
self.assertIsNotNone(entree, "invite non traduite")
|
||||||
|
self.assertIn("3", entree["fr"])
|
||||||
|
|
||||||
|
def test_the_default_depth_fits_a_modest_machine(self):
|
||||||
|
"""Le défaut doit tenir là où le test sera lancé, pas seulement sur la
|
||||||
|
machine de celui qui l'a écrit."""
|
||||||
|
from script.proxmox import nesting
|
||||||
|
|
||||||
|
plan = nesting.nesting_plan(
|
||||||
|
3, cpu_hote=8, ram_dispo_mo=24000, disque_libre_go=120
|
||||||
|
)
|
||||||
|
self.assertEqual(plan["atteignable"], 3)
|
||||||
|
self.assertEqual(plan["arret"], "")
|
||||||
|
|
||||||
|
|
||||||
class TestDefaireSansEffacerAutreChose(unittest.TestCase):
|
class TestDefaireSansEffacerAutreChose(unittest.TestCase):
|
||||||
"""« --detruire » effaçait par SOUS-CHAÎNE de nom, dans le mauvais ordre,
|
"""« --detruire » effaçait par SOUS-CHAÎNE de nom, dans le mauvais ordre,
|
||||||
sans confirmation et sans honorer --dry-run.
|
sans confirmation et sans honorer --dry-run.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue