Compare commits

..

No commits in common. "06687f5f7eb5cef6aa256960948245ca584b7d6f" and "6506e5cf9fe1d5ce8a2d58e9bb5fc447bfaf2707" have entirely different histories.

3 changed files with 28 additions and 81 deletions

View file

@ -16,7 +16,6 @@ import time
import tkinter as tk import tkinter as tk
from pathlib import Path from pathlib import Path
from tkinter import filedialog from tkinter import filedialog
from typing import Optional
from pykeepass import PyKeePass from pykeepass import PyKeePass
from randomwordfr import RandomWordFr from randomwordfr import RandomWordFr

View file

@ -3362,28 +3362,19 @@ class TODO:
pass pass
return 1, base_vcpus return 1, base_vcpus
def _qemu_customize_vms(self, selected): def _qemu_customize_names(self, selected):
"""Personnalise chaque VM avant déploiement : NOM, taille de DISQUE et """Noms des VM (liste parallèle à `selected`). Défaut = nom auto
RAM. `selected` = liste de (d, v, ram, disk, a) où ram (Mo) et disk (_qemu_infra_name) ; on peut en renommer certains À LA DEMANDE, par
(« 20G ») sont les valeurs FINALES (multiplicateur déjà appliqué). leurs numéros séparés de virgules (vide = garder tous les noms auto)."""
Renvoie (names, selected_maj). Défaut : rien ne change."""
names = [ names = [
self._qemu_infra_name(d, v, a) for d, v, _r, _dk, a in selected self._qemu_infra_name(d, v, a) for d, v, _r, _dk, a in selected
] ]
sel = [list(s) for s in selected] # mutable (d, v, ram, disk, a) print(f"\n{t('VM names (default = auto):')}")
for i, (nm, s) in enumerate(zip(names, selected), 1):
def show(): d, v, _r, _dk, a = s
print(f"\n{t('VMs (default = no change):')}") print(f" [{i}] {nm} ({d} {v} [{a}])")
for i, (nm, s) in enumerate(zip(names, sel), 1):
d, v, ram, disk, a = s
print(
f" [{i}] {nm} ({d} {v} [{a}]) "
f"RAM {ram}Mo {t('disk')} {disk}"
)
show()
raw = input( raw = input(
t("Modify which VMs? (numbers, comma-separated; blank = none): ") t("Rename which VMs? (numbers, comma-separated; blank = none): ")
).strip() ).strip()
for tok in re.split(r"[\s,]+", raw): for tok in re.split(r"[\s,]+", raw):
if not tok: if not tok:
@ -3392,34 +3383,13 @@ class TODO:
i = int(tok) - 1 i = int(tok) - 1
except ValueError: except ValueError:
continue continue
if not (0 <= i < len(sel)): if 0 <= i < len(names):
continue new = input(f" {names[i]} {t('->')} ").strip()
# Pour la VM i : nom, disque, RAM (vide = garder la valeur). if new:
new = input( names[i] = new
f" {names[i]} — {t('new name (blank = keep):')} "
).strip()
if new:
names[i] = new
dk = input(
f" {t('New disk size in G, blank = keep')} "
f"({sel[i][3]}): "
).strip().upper().rstrip("G")
if dk:
try:
sel[i][3] = f"{int(float(dk))}G"
except ValueError:
print(f" ⚠ {t('Invalid size.')}")
rm = input(
f" {t('New RAM in MB, blank = keep')} ({sel[i][2]}): "
).strip()
if rm:
try:
sel[i][2] = int(rm)
except ValueError:
print(f" ⚠ {t('Invalid size.')}")
if len(set(names)) != len(names): if len(set(names)) != len(names):
print(f" ⚠ {t('Duplicate names detected; keeping as entered.')}") print(f" ⚠ {t('Duplicate names detected; keeping as entered.')}")
return names, [tuple(s) for s in sel] return names
def _qemu_build_deploy_parts( def _qemu_build_deploy_parts(
self, d, v, arch, name, eram, evcpus, disk, ssh_key, branch, dry_run self, d, v, arch, name, eram, evcpus, disk, ssh_key, branch, dry_run
@ -3599,26 +3569,23 @@ class TODO:
res_mult, base_vcpus = self._qemu_prompt_resource_mult( res_mult, base_vcpus = self._qemu_prompt_resource_mult(
selected, host_cpu, free_ram selected, host_cpu, free_ram
) )
# On CUIT le multiplicateur dans `selected` (RAM finale) et on fixe un
# nombre de vCPU uniforme -> la personnalisation par VM (RAM absolue)
# n'est plus ambiguë. vCPU n'est pas éditable par VM (choix global).
evcpus = min(base_vcpus * res_mult, host_cpu)
selected = [
(d, v, ram * res_mult, disk, a)
for (d, v, ram, disk, a) in selected
]
# 2c) Personnalisation par VM : nom, disque, RAM (à la demande). def eff_res(ram):
names, selected = self._qemu_customize_vms(selected) """(RAM effective, vCPU) pour une VM selon le multiplicateur."""
return ram * res_mult, min(base_vcpus * res_mult, host_cpu)
# 3) Plan + estimation des ressources. # 2c) Noms des VM (auto par défaut, renommage granulaire à la demande).
total_ram = sum(s[2] for s in selected) names = self._qemu_customize_names(selected)
# 3) Plan + estimation des ressources (avec le multiplicateur appliqué).
total_ram = sum(s[2] * res_mult for s in selected)
total_disk = sum(self._parse_disk_gb(s[3]) for s in selected) total_disk = sum(self._parse_disk_gb(s[3]) for s in selected)
print(f"\n{t('Deployment plan')} ({len(selected)} VM, x{res_mult}) :") print(f"\n{t('Deployment plan')} ({len(selected)} VM, x{res_mult}) :")
for i, (d, v, ram, disk, a) in enumerate(selected): for i, (d, v, ram, disk, a) in enumerate(selected):
eram, evcpus = eff_res(ram)
print( print(
f" - {names[i]:<30} {d} {v:<7} [{a:<5}] " f" - {names[i]:<30} {d} {v:<7} [{a:<5}] "
f"{evcpus} vCPU RAM {ram}Mo {t('disk')} {disk}" f"{evcpus} vCPU RAM {eram}Mo {t('disk')} {disk}"
) )
print(f"\n {t('Total RAM (all running):')} {total_ram} Mo") print(f"\n {t('Total RAM (all running):')} {total_ram} Mo")
print(f" {t('Total virtual disk (thin qcow2):')} ~{total_disk} G") print(f" {t('Total virtual disk (thin qcow2):')} ~{total_disk} G")
@ -3637,8 +3604,9 @@ class TODO:
default_key = self._qemu_default_ssh_key() default_key = self._qemu_default_ssh_key()
print(f"\n{t('Preview (dry-run):')}") print(f"\n{t('Preview (dry-run):')}")
for i, (d, v, ram, disk, a) in enumerate(selected): for i, (d, v, ram, disk, a) in enumerate(selected):
eram, evcpus = eff_res(ram)
parts = self._qemu_build_deploy_parts( parts = self._qemu_build_deploy_parts(
d, v, a, names[i], ram, evcpus, disk, d, v, a, names[i], eram, evcpus, disk,
default_key, None, dry_run=True, default_key, None, dry_run=True,
) )
print(" " + " ".join(shlex.quote(p) for p in parts)) print(" " + " ".join(shlex.quote(p) for p in parts))
@ -3709,8 +3677,9 @@ class TODO:
# si les résultats reviennent dans le désordre (exécution parallèle). # si les résultats reviennent dans le désordre (exécution parallèle).
jobs = [] # (id, name, parts) jobs = [] # (id, name, parts)
for k, (name, d, v, ram, disk, a) in enumerate(pending, 1): for k, (name, d, v, ram, disk, a) in enumerate(pending, 1):
eram, evcpus = eff_res(ram)
parts = self._qemu_build_deploy_parts( parts = self._qemu_build_deploy_parts(
d, v, a, name, ram, evcpus, disk, d, v, a, name, eram, evcpus, disk,
ssh_key, install_branch, dry_run=False, ssh_key, install_branch, dry_run=False,
) )
jobs.append((f"{k}/{n_jobs}", name, parts)) jobs.append((f"{k}/{n_jobs}", name, parts))

View file

@ -1270,27 +1270,6 @@ TRANSLATIONS = {
"fr": "->", "fr": "->",
"en": "->", "en": "->",
}, },
"VMs (default = no change):": {
"fr": "VM (défaut = aucune modification) :",
"en": "VMs (default = no change):",
},
"Modify which VMs? (numbers, comma-separated; blank = none): ": {
"fr": "Modifier quelles VM ? (numéros séparés par des virgules ; "
"vide = aucune) : ",
"en": "Modify which VMs? (numbers, comma-separated; blank = none): ",
},
"new name (blank = keep):": {
"fr": "nouveau nom (vide = garder) :",
"en": "new name (blank = keep):",
},
"New disk size in G, blank = keep": {
"fr": "Nouvelle taille disque en G, vide = garder",
"en": "New disk size in G, blank = keep",
},
"New RAM in MB, blank = keep": {
"fr": "Nouvelle RAM en Mo, vide = garder",
"en": "New RAM in MB, blank = keep",
},
"Duplicate names detected; keeping as entered.": { "Duplicate names detected; keeping as entered.": {
"fr": "Noms en double détectés ; conservés tels quels.", "fr": "Noms en double détectés ; conservés tels quels.",
"en": "Duplicate names detected; keeping as entered.", "en": "Duplicate names detected; keeping as entered.",