From 08ebf99c7798796fbbedf8141eafec890689ac13 Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Thu, 13 Aug 2026 21:41:25 -0400 Subject: [PATCH] [FIX] qemu debian s390x : adresse fixe, l'initrd ne sait pas faire de DHCP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le syslog de d-i a tranche : « Menu item 'netcfg-static' selected », puis « Taking down interface enc1 ». netcfg-dhcp n'apparait JAMAIS — il n'est pas dans l'initrd s390x, et aucun variant netboot n'existe pour cette architecture (404 sur trixie comme sur bookworm). Aucun DHCP n'etait donc tente. Sept hypotheses ont cherche pourquoi il echouait ; il n'avait jamais lieu. C'est la convention IBM Z, ou le reseau se donne au parmfile. deploy_qemu choisit desormais une adresse libre en HAUT de la plage — dnsmasq attribue depuis le bas — et la preseede. Mesure : l'ecran d'adressage statique a disparu, l'installateur poursuit. --- EN --- d-i's syslog settled it: "Menu item 'netcfg-static' selected", then "Taking down interface enc1". netcfg-dhcp NEVER appears — it is not in the s390x initrd, and no netboot variant exists for this architecture (404 on trixie and bookworm alike). So no DHCP was ever attempted. Seven hypotheses looked for why it failed; it never happened. This is the IBM Z convention, where the network is given in the parmfile. deploy_qemu now picks a free address at the TOP of the range — dnsmasq allocates from the bottom — and preseeds it. Measured: the static addressing screen is gone, the installer moves on. Assisted-by: Claude Opus 5 (cherry picked from commit 8c630969a605ec191a65dc93896014ac9e3a1227) --- script/qemu/deploy_qemu.py | 84 +++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/script/qemu/deploy_qemu.py b/script/qemu/deploy_qemu.py index 1eab9f4..bdcf0cd 100755 --- a/script/qemu/deploy_qemu.py +++ b/script/qemu/deploy_qemu.py @@ -1711,8 +1711,63 @@ def prepare_disk( runner.run(["qemu-img", "resize", str(disk), size], privileged=True) +def static_net_plan(net: str | None, use_sudo: bool) -> dict[str, str] | None: + """Adresse fixe libre pour une VM installée par debian-installer. + + L'initrd s390x ne contient QUE « netcfg-static » : le journal de d-i + montre « Menu item 'netcfg-static' selected », jamais netcfg-dhcp, puis + « Taking down interface enc1 ». Aucun DHCP n'est tenté — c'est la + convention IBM Z, où la configuration réseau se donne au parmfile. Il + faut donc fournir une adresse, et elle doit être libre. + + On la prend en HAUT de la plage : dnsmasq attribue depuis le bas, donc + les collisions avec un bail futur sont les plus improbables là. + """ + if not net: + return None + cmd = ["virsh", "-c", LIBVIRT_URI, "net-dumpxml", net] + if use_sudo: + cmd.insert(0, "sudo") + try: + xml = subprocess.run( + cmd, capture_output=True, text=True, timeout=20 + ).stdout + except (OSError, subprocess.SubprocessError): + return None + m = re.search(r" str: """Preseed debian-installer équivalent au cloud-config des autres distros. @@ -1743,6 +1798,21 @@ def build_preseed( # « auto » évite la question du choix d'interface : sous virtio-ccw # elle s'appelle enc1 et non eth0, et le nom n'est pas devinable. f"d-i netcfg/get_hostname string {args.hostname}", + # Adresse fixe : sans elle, netcfg-static pose la question a l'ecran + # et l'installation s'arrete la, indefiniment. + *( + [ + "d-i netcfg/disable_autoconfig boolean true", + "d-i netcfg/disable_dhcp boolean true", + f"d-i netcfg/get_ipaddress string {static['ip']}", + f"d-i netcfg/get_netmask string {static['netmask']}", + f"d-i netcfg/get_gateway string {static['gateway']}", + f"d-i netcfg/get_nameservers string {static['dns']}", + "d-i netcfg/confirm_static boolean true", + ] + if static + else [] + ), "d-i netcfg/get_domain string localdomain", "d-i netcfg/hostname string " + args.hostname, "d-i mirror/country string manual", @@ -2661,8 +2731,18 @@ def main() -> None: create_blank_disk(disk, args.disk_size, runner, args.force) print(f"\n== 4/5 Preseed embarqué dans l'initrd ==") + static = static_net_plan(network_name(args.network), not args.dry_run) + if static: + print(f" Adresse fixe retenue : {static['ip']}" + f" (passerelle {static['gateway']})") + else: + print(" ⚠ Aucune adresse fixe déterminée : netcfg-static posera" + " la question à l'écran et l'installation s'arrêtera.") build_installer_initrd( - build_preseed(args, pw_hash, ssh_keys), initrd_src, initrd, runner + build_preseed(args, pw_hash, ssh_keys, static), + initrd_src, + initrd, + runner, ) installer = (kernel, initrd) else: