[FIX] qemu debian s390x : rallumer la VM quand l'installateur a fini
« This domain is not running » apres une installation reussie. Le disque portait 1,22 Gio et le XML persistant amorcait deja sur « hd » : rien n'avait echoue, la VM etait simplement eteinte. virt-install mene l'installation en deux temps — amorcage transitoire sur kernel+initrd, puis configuration definitive sur disque — et le passage se fait par un ARRET. C'est virt-install qui rallume ensuite, sauf qu'avec « --wait 0 » il est deja parti. On ne peut pas le laisser attendre : sous emulation l'installation dure des heures, et le deploiement rendrait la main a ce rythme. Un veilleur detache fait donc le dernier geste, avec 6 h de garde. Mesure : domaine « shut off », veilleur lance, domaine « running ». Et la VM installee repond en SSH. --- EN --- "This domain is not running" after a successful install. The disk held 1.22 GiB and the persistent XML already booted from "hd": nothing had failed, the VM was simply powered off. virt-install runs the install in two stages — a transient kernel+initrd boot, then the final disk-boot config — and the handover goes through a SHUTDOWN. virt-install powers it back on afterwards, except that with "--wait 0" it is already gone. We cannot let it wait: under emulation the install takes hours, and deployment would return at that pace. So a detached watcher makes the last move, with a 6 h guard. Measured: domain "shut off", watcher started, domain "running". And the installed VM answers over SSH. Assisted-by: Claude Opus 5 (cherry picked from commit 9c6cdb7f14ca504fd9d0855ba0dacc3dbf43c04f)
This commit is contained in:
parent
58da6cdacd
commit
b181ad56e8
1 changed files with 50 additions and 0 deletions
|
|
@ -2266,6 +2266,54 @@ def virt_install(
|
||||||
runner.run(log_env + cmd, privileged=True)
|
runner.run(log_env + cmd, privileged=True)
|
||||||
|
|
||||||
|
|
||||||
|
def watch_and_restart(name: str, runner: Runner) -> None:
|
||||||
|
"""Rallume la VM quand debian-installer a fini et l'a éteinte.
|
||||||
|
|
||||||
|
virt-install mène l'installation en DEUX temps : un amorçage transitoire
|
||||||
|
sur kernel+initrd, puis la configuration définitive, qui démarre sur le
|
||||||
|
disque. Le passage de l'un à l'autre se fait par un arrêt — l'installateur
|
||||||
|
redémarre, libvirt détruit le domaine transitoire — et c'est virt-install
|
||||||
|
qui rallume ensuite. Avec « --wait 0 » il est déjà parti : le domaine
|
||||||
|
reste « shut off », disque installé et XML correct, mais éteint.
|
||||||
|
|
||||||
|
On ne peut pas pour autant laisser virt-install attendre : sous émulation
|
||||||
|
l'installation dure des heures, et le déploiement rendrait la main à ce
|
||||||
|
rythme-là. Un veilleur détaché fait donc le dernier geste.
|
||||||
|
"""
|
||||||
|
if runner.dry_run:
|
||||||
|
print(f"[dry-run] veilleur de redémarrage pour {name}")
|
||||||
|
return
|
||||||
|
sudo = "sudo " if runner.use_sudo else ""
|
||||||
|
# 6 h de garde : bien au-delà d'une installation émulée, et le veilleur
|
||||||
|
# meurt de lui-même si quelque chose a mal tourné.
|
||||||
|
script = (
|
||||||
|
f"for i in $(seq 1 720); do "
|
||||||
|
f" s=$({sudo}virsh -c {LIBVIRT_URI} domstate {name} 2>/dev/null); "
|
||||||
|
f' if [ "$s" = "shut off" ]; then '
|
||||||
|
f" {sudo}virsh -c {LIBVIRT_URI} start {name} >/dev/null 2>&1; "
|
||||||
|
f" exit 0; "
|
||||||
|
f" fi; "
|
||||||
|
f" sleep 30; "
|
||||||
|
f"done"
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
subprocess.Popen(
|
||||||
|
["/bin/sh", "-c", script],
|
||||||
|
stdin=subprocess.DEVNULL,
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
stderr=subprocess.DEVNULL,
|
||||||
|
start_new_session=True,
|
||||||
|
)
|
||||||
|
except (OSError, subprocess.SubprocessError) as exc:
|
||||||
|
print(f" ⚠ veilleur non lancé ({exc}) ; démarrer à la main :")
|
||||||
|
print(f" sudo virsh start {name}")
|
||||||
|
return
|
||||||
|
print(
|
||||||
|
f" Veilleur lancé : {name} sera rallumée dès que l'installateur"
|
||||||
|
" l'aura éteinte."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _ip_reachable(ip: str, port: int = 22, timeout: float = 3) -> bool:
|
def _ip_reachable(ip: str, port: int = 22, timeout: float = 3) -> bool:
|
||||||
"""Vrai si le port SSH répond (distingue le bail actif du bail périmé)."""
|
"""Vrai si le port SSH répond (distingue le bail actif du bail périmé)."""
|
||||||
try:
|
try:
|
||||||
|
|
@ -2818,6 +2866,8 @@ def main() -> None:
|
||||||
print(f"\n== 5/5 virt-install (--osinfo {resolved_osinfo}) ==")
|
print(f"\n== 5/5 virt-install (--osinfo {resolved_osinfo}) ==")
|
||||||
ensure_network(network_name(args.network), runner)
|
ensure_network(network_name(args.network), runner)
|
||||||
virt_install(args, disk, seed, resolved_osinfo, runner, installer)
|
virt_install(args, disk, seed, resolved_osinfo, runner, installer)
|
||||||
|
if installer:
|
||||||
|
watch_and_restart(args.name, runner)
|
||||||
|
|
||||||
has_key = bool(ssh_keys)
|
has_key = bool(ssh_keys)
|
||||||
print("\nTerminé. Suivi :")
|
print("\nTerminé. Suivi :")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue