[FIX] script todo: résolution d'IP en parallèle (dashboard ne s'ouvrait jamais)
Après un déploiement infra, la résolution d'IP tournait EN SÉRIE (boucle ssh_config puis install), jusqu'à 10 min par VM émulée, SANS aucune sortie : le dashboard « n'ouvrait jamais » (impression de blocage), d'autant qu'une VM qui ne boote pas (IP jamais attribuée) bloquait tout le reste. Fix : _qemu_resolve_ips résout les IP de toutes les VM EN PARALLÈLE, avec progression affichée par VM, une seule fois, réutilisée pour ~/.ssh/config ET l'installation (plus de double résolution). _qemu_install_erplibre_* acceptent une IP/ip_map déjà résolue. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7bd44d21a9
commit
b49e107b83
1 changed files with 44 additions and 11 deletions
|
|
@ -1763,6 +1763,28 @@ class TODO:
|
|||
# Meilleur effort : le dernier bail (le plus récent) plutôt que le 1er.
|
||||
return cands[-1] if cands else None
|
||||
|
||||
def _qemu_resolve_ips(self, names):
|
||||
"""Résout les IP de plusieurs VM EN PARALLÈLE (le boot émulé est lent),
|
||||
en affichant la progression au fur et à mesure. Renvoie {nom: ip|None}.
|
||||
Évite l'attente EN SÉRIE et SANS sortie qui donnait l'impression d'un
|
||||
blocage (dashboard qui « n'ouvre jamais »)."""
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
|
||||
print(f"\n{t('Resolving VM IPs (parallel, emulated boot is slow)...')}")
|
||||
result = {}
|
||||
workers = min(len(names), (os.cpu_count() or 4)) or 1
|
||||
with ThreadPoolExecutor(max_workers=workers) as pool:
|
||||
futs = {pool.submit(self._qemu_vm_ip, n): n for n in names}
|
||||
for fut in as_completed(futs):
|
||||
n = futs[fut]
|
||||
try:
|
||||
ip = fut.result()
|
||||
except Exception:
|
||||
ip = None
|
||||
result[n] = ip
|
||||
print(f" {n}: {ip or t('no IP')}")
|
||||
return result
|
||||
|
||||
def _qemu_vm_arch(self, name):
|
||||
"""Architecture d'une VM (jeton amd64/arm64/s390x) via virsh dumpxml."""
|
||||
try:
|
||||
|
|
@ -1952,10 +1974,10 @@ class TODO:
|
|||
f"make {self.ERPLIBRE_ODOO_TARGET}"
|
||||
)
|
||||
|
||||
def _qemu_install_erplibre_monitored(self, names, branch):
|
||||
def _qemu_install_erplibre_monitored(self, names, branch, ip_map=None):
|
||||
"""Lance l'install ERPLibre en parallèle DÉTACHÉE sur les VM et ouvre
|
||||
le dashboard Textual. Quitter le dashboard n'arrête pas les installs.
|
||||
"""
|
||||
`ip_map` : IP déjà résolues (sinon on résout ici, EN PARALLÈLE)."""
|
||||
from script.todo.qemu_install_monitor import (
|
||||
launch_installs,
|
||||
run_monitor,
|
||||
|
|
@ -1966,10 +1988,11 @@ class TODO:
|
|||
mod = self._qemu_import_module()
|
||||
except Exception:
|
||||
mod = None
|
||||
if ip_map is None:
|
||||
ip_map = self._qemu_resolve_ips(names)
|
||||
vms = []
|
||||
for name in names:
|
||||
print(f" {name}: {t('resolving IP...')}")
|
||||
ip = self._qemu_vm_ip(name)
|
||||
ip = ip_map.get(name)
|
||||
if ip:
|
||||
d, v, a = (
|
||||
self._qemu_vm_meta(name, mod)
|
||||
|
|
@ -2012,10 +2035,12 @@ class TODO:
|
|||
# Commande prête à copier pour relire/partager tous les logs.
|
||||
print(f" {t('Read the logs:')} tail -n +1 {logdir}/*.log")
|
||||
|
||||
def _qemu_install_erplibre_vm(self, name, ssh_key, branch):
|
||||
def _qemu_install_erplibre_vm(self, name, ssh_key, branch, ip=None):
|
||||
"""Clone ERPLibre (branche donnée) dans ~/git/erplibre de la VM puis
|
||||
exécute « make install_os » et « make install_odoo_18 » (streamé)."""
|
||||
ip = self._qemu_vm_ip(name)
|
||||
exécute « make install_os » et « make install_odoo_18 » (streamé).
|
||||
`ip` : IP déjà résolue (sinon on la résout ici)."""
|
||||
if ip is None:
|
||||
ip = self._qemu_vm_ip(name)
|
||||
if not ip:
|
||||
print(
|
||||
f" {name}: {t('no IP obtained, ERPLibre install skipped.')}"
|
||||
|
|
@ -2316,10 +2341,16 @@ class TODO:
|
|||
if rc == 0:
|
||||
deployed.append(jname)
|
||||
|
||||
# 6) ~/.ssh/config (une fois les VM démarrées et l'IP attribuée).
|
||||
# 6) Résolution des IP EN PARALLÈLE (réutilisée pour ssh_config +
|
||||
# install) : une boucle EN SÉRIE bloquait plusieurs minutes par VM
|
||||
# émulée SANS sortie -> le dashboard « n'ouvrait jamais ».
|
||||
ip_map = {}
|
||||
if deployed and (add_ssh_config or install_branch):
|
||||
ip_map = self._qemu_resolve_ips(deployed)
|
||||
|
||||
if add_ssh_config:
|
||||
for name in deployed:
|
||||
ip = self._qemu_vm_ip(name)
|
||||
ip = ip_map.get(name)
|
||||
if ip:
|
||||
self._write_ssh_config_entry(name, "erplibre", ip)
|
||||
|
||||
|
|
@ -2327,7 +2358,9 @@ class TODO:
|
|||
if install_branch:
|
||||
if install_monitor:
|
||||
# Installs détachées en parallèle + dashboard Textual.
|
||||
self._qemu_install_erplibre_monitored(deployed, install_branch)
|
||||
self._qemu_install_erplibre_monitored(
|
||||
deployed, install_branch, ip_map
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f"\n{t('Installing ERPLibre on each VM')} "
|
||||
|
|
@ -2335,7 +2368,7 @@ class TODO:
|
|||
)
|
||||
for name in deployed:
|
||||
self._qemu_install_erplibre_vm(
|
||||
name, ssh_key, install_branch
|
||||
name, ssh_key, install_branch, ip_map.get(name)
|
||||
)
|
||||
|
||||
print(f"\n✅ {t('ERPLibre infra deployment done.')}")
|
||||
|
|
|
|||
Loading…
Reference in a new issue