[IMP] script todo: en-tête d'install (date, distro, version, archi) dans le log
Le log d'installation commence désormais par un en-tête identifiant l'installation : date, VM, distribution + version, architecture, branche, IP. Écrit dès la création du log (plus jamais vide au démarrage). _qemu_install_erplibre_monitored déduit distro/version/arch de chaque VM (nom via _qemu_infra_name + arch via virsh dumpxml) et les passe à launch_installs, qui écrit l'en-tête et les stocke dans le manifeste. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b395e7c3ed
commit
939e26ba83
3 changed files with 87 additions and 4 deletions
|
|
@ -89,22 +89,50 @@ def _launch_one(ip: str, remote_cmd: str, log_path: str) -> None:
|
|||
)
|
||||
|
||||
|
||||
def _log_header(vm: dict, branch: str, when: str) -> str:
|
||||
"""En-tête du log : date, VM, distribution, version, architecture, branche.
|
||||
Permet d'identifier l'installation d'un coup d'œil (et de ne jamais laisser
|
||||
le log vide pendant l'attente du boot)."""
|
||||
distro = vm.get("distro") or "?"
|
||||
version = vm.get("version") or ""
|
||||
arch = vm.get("arch") or "?"
|
||||
bar = "=" * 64
|
||||
return (
|
||||
f"{bar}\n"
|
||||
f" ERPLibre — {t('installation')}\n"
|
||||
f" Date : {when}\n"
|
||||
f" VM : {vm['name']}\n"
|
||||
f" Distribution : {distro} {version}\n"
|
||||
f" Architecture : {arch}\n"
|
||||
f" Branche : {branch}\n"
|
||||
f" IP : {vm['ip']}\n"
|
||||
f"{bar}\n\n"
|
||||
)
|
||||
|
||||
|
||||
def launch_installs(vms: list[dict], branch: str, remote_cmd: str) -> str:
|
||||
"""vms : [{name, ip}]. Lance chaque install détachée, écrit un manifeste
|
||||
et retourne son chemin. remote_cmd : script exécuté dans chaque VM."""
|
||||
"""vms : [{name, ip, distro?, version?, arch?}]. Lance chaque install
|
||||
détachée, écrit un manifeste et retourne son chemin. remote_cmd : script
|
||||
exécuté dans chaque VM."""
|
||||
sdir = session_dir()
|
||||
stamp = time.strftime("%Y%m%d-%H%M%S")
|
||||
when = time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
logdir = sdir / stamp
|
||||
logdir.mkdir(parents=True, exist_ok=True)
|
||||
entries = []
|
||||
for vm in vms:
|
||||
log_path = str(logdir / f"{vm['name']}.log")
|
||||
Path(log_path).write_text("") # log vide = état « en attente »
|
||||
# En-tête d'emblée (date/distro/version/arch) : le log n'est jamais
|
||||
# vide, l'utilisateur voit tout de suite QUOI s'installe.
|
||||
Path(log_path).write_text(_log_header(vm, branch, when))
|
||||
_launch_one(vm["ip"], remote_cmd, log_path)
|
||||
entries.append(
|
||||
{
|
||||
"name": vm["name"],
|
||||
"ip": vm["ip"],
|
||||
"distro": vm.get("distro"),
|
||||
"version": vm.get("version"),
|
||||
"arch": vm.get("arch"),
|
||||
"log": log_path,
|
||||
"ssh": f"ssh erplibre@{vm['ip']}",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1763,6 +1763,40 @@ 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_vm_arch(self, name):
|
||||
"""Architecture d'une VM (jeton amd64/arm64/s390x) via virsh dumpxml."""
|
||||
try:
|
||||
res = subprocess.run(
|
||||
["sudo", "virsh", "dumpxml", name],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=15,
|
||||
)
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
return None
|
||||
m = re.search(r"<type[^>]*\barch='([^']+)'", res.stdout)
|
||||
if not m:
|
||||
return None
|
||||
return {
|
||||
"x86_64": "amd64",
|
||||
"aarch64": "arm64",
|
||||
"s390x": "s390x",
|
||||
}.get(m.group(1), m.group(1))
|
||||
|
||||
def _qemu_vm_meta(self, name, mod):
|
||||
"""(distro, version, arch) d'une VM déduits de son nom + son arch. Le
|
||||
nom suit _qemu_infra_name(distro, version, arch) : on retrouve donc
|
||||
(distro, version) en testant les combinaisons du catalogue."""
|
||||
arch = self._qemu_vm_arch(name) or "amd64"
|
||||
try:
|
||||
for d, (versions, _default) in mod.DISTROS.items():
|
||||
for v in versions:
|
||||
if self._qemu_infra_name(d, v, arch) == name:
|
||||
return d, v, arch
|
||||
except Exception:
|
||||
pass
|
||||
return None, None, arch
|
||||
|
||||
def _qemu_pick_branch(self):
|
||||
"""Liste les branches distantes d'ERPLibre et en fait choisir une."""
|
||||
print(f"\n{t('Fetching ERPLibre branch list...')}")
|
||||
|
|
@ -1928,12 +1962,29 @@ class TODO:
|
|||
)
|
||||
|
||||
remote = self._qemu_erplibre_remote_cmd(branch)
|
||||
try:
|
||||
mod = self._qemu_import_module()
|
||||
except Exception:
|
||||
mod = None
|
||||
vms = []
|
||||
for name in names:
|
||||
print(f" {name}: {t('resolving IP...')}")
|
||||
ip = self._qemu_vm_ip(name)
|
||||
if ip:
|
||||
vms.append({"name": name, "ip": ip})
|
||||
d, v, a = (
|
||||
self._qemu_vm_meta(name, mod)
|
||||
if mod
|
||||
else (None, None, None)
|
||||
)
|
||||
vms.append(
|
||||
{
|
||||
"name": name,
|
||||
"ip": ip,
|
||||
"distro": d,
|
||||
"version": v,
|
||||
"arch": a,
|
||||
}
|
||||
)
|
||||
else:
|
||||
print(f" {name}: {t('no IP, skipped.')}")
|
||||
if not vms:
|
||||
|
|
|
|||
|
|
@ -1201,6 +1201,10 @@ TRANSLATIONS = {
|
|||
"fr": "Toutes les architectures supportées",
|
||||
"en": "All supported architectures",
|
||||
},
|
||||
"installation": {
|
||||
"fr": "installation",
|
||||
"en": "installation",
|
||||
},
|
||||
"(includes emulated architectures — some VMs are slow)": {
|
||||
"fr": "(inclut des architectures émulées — certaines VM sont lentes)",
|
||||
"en": "(includes emulated architectures — some VMs are slow)",
|
||||
|
|
|
|||
Loading…
Reference in a new issue