[ADD] tui qemu: one run per installation

The form's parallelism was pinned at 4, while the CLI already counted
host cores: two interfaces, two answers.

A box ticked by default now gives one run per install -- five VMs, five
deployments -- and the core count stops capping it. Unticking hands
control back to the dropdown, whose default finally follows the host. The
CLI offers the same toggle through "n".

--- FR ---

Le parallélisme du formulaire était figé à 4, quand la CLI comptait déjà
les cœurs de l'hôte : deux interfaces, deux réponses.

Une case cochée par défaut donne désormais une exécution par
installation — cinq VM, cinq déploiements — et le nombre de cœurs cesse
alors de plafonner. La décocher rend la main à la liste, dont le défaut
suit enfin l'hôte. La CLI offre la même bascule par « n ».

Assisted-by: Claude Opus 5
This commit is contained in:
Mathieu Benoit 2026-08-11 08:59:10 -04:00
parent 571ccf3c90
commit c7b9d2396d
3 changed files with 51 additions and 13 deletions

View file

@ -491,10 +491,20 @@ def run_deploy_form(ctx, run_app: bool = True):
id="f_sshcfg",
)
yield Static(t("Parallelism"), classes="grouptitle")
# Cochée, la case donne une exécution PAR installation :
# le plafond du nombre de CPU ne s'applique plus. Décochée,
# le nombre reprend la main, et son défaut suit l'hôte —
# la CLI comptait déjà les CPU, la TUI restait figée à 4.
yield Checkbox(
t("One run per install"),
value=defaults.get("par_per_install", True),
id="f_par_all",
)
yield Select(
[(str(n), n) for n in range(1, host_cpu + 1)],
value=min(4, host_cpu),
value=host_cpu,
allow_blank=False,
disabled=True,
id="f_par",
)
with Vertical(id="right"):
@ -674,6 +684,8 @@ def run_deploy_form(ctx, run_app: bool = True):
def on_checkbox_changed(self, event) -> None:
if event.checkbox.id == "f_install":
self._recompute() # le disque annoncé inclut le +5 G ERPLibre
elif event.checkbox.id == "f_par_all":
self.query_one("#f_par", Select).disabled = event.value
# -- actions ---------------------------------------------------- #
def action_select_all(self) -> None:
@ -732,7 +744,14 @@ def run_deploy_form(ctx, run_app: bool = True):
or "",
"install": install,
"add_ssh_config": self.query_one("#f_sshcfg", Checkbox).value,
"parallelism": self.query_one("#f_par", Select).value,
# Une exécution par installation : le nombre de VM retenues
# fait foi. Le déploiement le borne ensuite à ce même nombre,
# donc une valeur haute ne crée jamais de travailleur inutile.
"parallelism": (
max(1, len(self.vms))
if self.query_one("#f_par_all", Checkbox).value
else self.query_one("#f_par", Select).value
),
}
def action_preview(self) -> None:

View file

@ -5581,17 +5581,28 @@ class TODO:
print(t("Nothing to create - every VM already exists."))
return None
# Nombre de déploiements en parallèle. Défaut = nombre de CPU de l'hôte
# (borné par le nombre de VM). On affiche aussi le NB DE VM à déployer.
default_par = min(n_jobs, os.cpu_count() or 4) or 1
raw = input(
f"{t('Parallel deployments (default:')} {default_par}, "
f"{n_jobs} {t('VMs')}): "
).strip()
try:
parallelism = max(1, int(raw)) if raw else default_par
except ValueError:
parallelism = default_par
# Nombre de déploiements en parallèle. Par défaut UNE EXÉCUTION PAR
# INSTALLATION : le plafond du nombre de CPU ne s'applique pas, c'est
# le nombre de VM qui fait foi. « n » retombe sur ce plafond, et un
# chiffre vaut pour lui-même — même règle que les autres invites.
default_par = n_jobs or 1
cpu_par = min(n_jobs, os.cpu_count() or 4) or 1
print(f" [n] {t('limit to host cores')} ({cpu_par})")
raw = (
input(
f"{t('Parallel deployments (default:')} {default_par}, "
f"{n_jobs} {t('VMs')}): "
)
.strip()
.lower()
)
if raw == "n":
parallelism = cpu_par
else:
try:
parallelism = max(1, int(raw)) if raw else default_par
except ValueError:
parallelism = default_par
spec = {
"res_label": res_label,

View file

@ -2023,6 +2023,14 @@ TRANSLATIONS = {
"fr": "Choix (numéro, vide = rouvrir) : ",
"en": "Choice (number, blank = reopen): ",
},
"One run per install": {
"fr": "une execution par installation",
"en": "One run per install",
},
"limit to host cores": {
"fr": "limiter au nombre de coeurs de l'hote",
"en": "limit to host cores",
},
"free value…": {
"fr": "valeur libre…",
"en": "free value…",