From c87cd2f5bd6e2a267a10f7b6ec27709e6265f80a Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Fri, 14 Aug 2026 00:46:22 -0400 Subject: [PATCH] [FIX] install : os-release au lieu de lsb_release, collision d'IP mieux vue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deux echecs distincts sur les VM Debian s390x posees par l'installateur. lsb_release vient du paquet lsb-release, livre avec la tache « standard ». Les images cloud l'ont ; une Debian posee par debian-installer, non. Les trois variables devenaient VIDES et le script concluait « Your version of Ubuntu is not supported » sur une Debian. /etc/os-release appartient a systemd, il est toujours la, et donne ID, VERSION_ID et VERSION_CODENAME sans rien installer. L'autre echec etait pire : l'adresse fixe choisie appartenait deja a une machine du parc, et l'installation ERPLibre s'est deroulee SUR CETTE DERNIERE. Le journal ne le disait qu'a demi-mot — « git is already the newest version », impossible sur un systeme que d-i vient de poser. Un essai sur le port 22 avec 0,4 s laissait passer toute machine eteinte ou filtree. On interroge desormais le voisinage ARP, puis ICMP, puis SSH. --- EN --- Two distinct failures on Debian s390x VMs laid down by the installer. lsb_release comes from the lsb-release package, shipped with the "standard" task. Cloud images have it; a Debian installed by debian-installer does not. All three variables came out EMPTY and the script concluded "Your version of Ubuntu is not supported" on a Debian. /etc/os-release belongs to systemd, is always there, and gives ID, VERSION_ID and VERSION_CODENAME without installing anything. The other failure was worse: the chosen static address already belonged to a machine in the fleet, and the ERPLibre install ran ON THAT ONE. The log only hinted at it — "git is already the newest version", impossible on a system d-i just laid down. A port-22 probe with 0.4 s let through any machine that was off or filtered. We now check the ARP neighbourhood, then ICMP, then SSH. Assisted-by: Claude Opus 5 (cherry picked from commit c73db1642a676ece1a06cdbdac3e9cfa5b526f3c) --- script/install/install_debian_dependency.sh | 27 ++++++++++++-- script/qemu/deploy_qemu.py | 39 ++++++++++++++++++++- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/script/install/install_debian_dependency.sh b/script/install/install_debian_dependency.sh index 61e759b..ab95eeb 100755 --- a/script/install/install_debian_dependency.sh +++ b/script/install/install_debian_dependency.sh @@ -18,9 +18,30 @@ APT_GET="sudo apt-get -o DPkg::Lock::Timeout=600" ## in order to have correct version of wkhtmltopdf installed, for a danger note refer to ## https://github.com/odoo/odoo/wiki/Wkhtmltopdf ): # Ubuntu 20.04 -UBUNTU_VERSION=$(lsb_release -rs) -DEBIAN_VERSION=$(lsb_release -cs) -OS=$(lsb_release -si) +# /etc/os-release D'ABORD, lsb_release seulement en repli. +# +# « lsb_release » vient du paquet lsb-release, qui arrive avec la tâche +# « standard ». Les images cloud l'ont ; une Debian posée par +# debian-installer, non. Les trois variables devenaient alors VIDES, et le +# script concluait « Your version of Ubuntu is not supported » sur une Debian +# — vécu sur s390x, la seule architecture qui passe par l'installateur. +# +# /etc/os-release, lui, appartient à systemd et est toujours là. Il donne +# ID=debian, VERSION_ID=13 et VERSION_CODENAME=trixie sans rien installer. +if [[ -r /etc/os-release ]]; then + # Sous-shell : « source » importerait NAME, PRETTY_NAME et le reste dans + # un script qui n'en veut pas. + UBUNTU_VERSION=$(. /etc/os-release && echo "${VERSION_ID}") + DEBIAN_VERSION=$(. /etc/os-release && echo "${VERSION_CODENAME}") + OS=$(. /etc/os-release && echo "${ID}") + # lsb_release rend « Ubuntu » et « Debian » ; os-release rend « ubuntu » et + # « debian ». Les comparaisons plus bas attendent la première forme. + OS="${OS^}" +else + UBUNTU_VERSION=$(lsb_release -rs) + DEBIAN_VERSION=$(lsb_release -cs) + OS=$(lsb_release -si) +fi # Ubuntu 18.04, 20.04 et 22.04 ne sont plus supportées, sur AUCUNE # architecture. Le mur le plus net est pikepdf, qui réclame qpdf >= 12.2, diff --git a/script/qemu/deploy_qemu.py b/script/qemu/deploy_qemu.py index 49da974..7f6b5ee 100755 --- a/script/qemu/deploy_qemu.py +++ b/script/qemu/deploy_qemu.py @@ -1712,6 +1712,43 @@ def prepare_disk( runner.run(["qemu-img", "resize", str(disk), size], privileged=True) +def _ip_taken(ip: str) -> bool: + """Adresse déjà occupée, même par une machine qui ne parle pas SSH. + + Un simple essai sur le port 22 ne suffit pas : il laisse passer toute + machine éteinte au moment du choix, ou dont sshd est filtré. Vécu — une + adresse attribuée à une VM Debian neuve appartenait déjà à une machine du + parc, et l'installation ERPLibre s'est déroulée SUR CETTE DERNIÈRE. Le + journal ne le disait qu'à demi-mot : « git is already the newest + version », impossible sur un système que d-i vient de poser. + + On interroge donc trois choses : le voisinage ARP de l'hôte, qui connaît + ce qui a parlé récemment ; ICMP, qui répond même sans service ; puis SSH. + """ + try: + neigh = subprocess.run( + ["ip", "neigh", "show", ip], + capture_output=True, + text=True, + timeout=5, + ).stdout + # « FAILED » signifie justement que personne n'a répondu. + if ip in neigh and "FAILED" not in neigh: + return True + except (OSError, subprocess.SubprocessError): + pass + try: + if subprocess.run( + ["ping", "-c", "1", "-W", "1", ip], + capture_output=True, + timeout=5, + ).returncode == 0: + return True + except (OSError, subprocess.SubprocessError): + pass + return _ip_reachable(ip, port=22, timeout=1.5) + + def static_net_plan(net: str | None, use_sudo: bool, name: str) -> dict[str, str] | None: """Adresse fixe libre pour une VM installée par debian-installer. @@ -1762,7 +1799,7 @@ def static_net_plan(net: str | None, use_sudo: bool, name: str) -> dict[str, str for offset in range(50): last = 200 + (start + offset) % 50 ip = f"{base}.{last}" - if ip in taken or _ip_reachable(ip, port=22, timeout=0.4): + if ip in taken or _ip_taken(ip): continue return { "ip": ip,