From 9709817be60eadaf7f79190c2fb2a8fb828632ce Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Mon, 14 Sep 2026 10:20:34 -0400 Subject: [PATCH] site : le rebond ET la cle decrivent le controleur, pas le site MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deux corrections, et la premiere est une faute que j ai ecrite ce soir. La fonction appelait underlay_mod — un nom qui n existe pas dans ce fichier, le module y est importe as U. Python levait un AttributeError a chaque appel, et mon except Exception: return False le rendait MUET. La fonction repondait donc toujours je ne suis pas une machine du site, le rebond etait toujours pose, et rien ne le disait. Une garde qui se tait ne garde rien. Le except ne couvre plus qu un plan illisible. Une faute de programmation remonte. Et cle_ssh subit le meme traitement que le rebond : il vaut le chemin de la cle sur le POSTE. Impose au runner, il designe un fichier absent chez lui. Les deux decrivent COMMENT ON ARRIVE, pas ce vers quoi on va. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q --- scripts/site_inventaire.py | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/scripts/site_inventaire.py b/scripts/site_inventaire.py index 6363fef..cc378ee 100755 --- a/scripts/site_inventaire.py +++ b/scripts/site_inventaire.py @@ -95,13 +95,24 @@ def _controleur_est_une_machine_du_site() -> bool: comportement d'avant, donc le seul qu'on sache sur. Degrader, jamais deviner. """ import socket + # `U`, PAS `underlay_mod` — ET LE `except` AVALAIT LA FAUTE (2026-09-14). + # + # La premiere version appelait `underlay_mod`, un nom qui n'existe pas dans ce + # fichier : le module y est importe `as U`. Python levait donc un `AttributeError` + # a CHAQUE appel — et le `except Exception: return False` le rendait muet. + # + # RESULTAT : la fonction repondait toujours « je ne suis pas une machine du site », le + # rebond etait toujours pose, et rien ne le disait. Une garde qui se tait ne garde + # rien ; c'est exactement le defaut que ce depot traque ailleurs, ecrit ici. + # + # LE `except` NE COUVRE PLUS QUE CE QU'IL DOIT : un plan illisible ou absent, pas une + # faute de programmation. Une erreur d'attribut ou de nom doit remonter. + court = socket.gethostname().split(".")[0] try: - court = socket.gethostname().split(".")[0] - except Exception: - return False - try: - serveurs = (underlay_mod.lire_plan_site("serveurs.yml") or {}).get("serveurs") or {} - except Exception: + serveurs = (U.lire_plan_site("serveurs.yml") or {}).get("serveurs") or {} + except (OSError, ValueError) as e: + print(f"note : plan du site illisible ({e.__class__.__name__}) — rebond conserve.", + file=sys.stderr) return False return court in serveurs @@ -300,7 +311,19 @@ def inventaire() -> dict: # pour ses propres machines ; les locataires ont chacun la leur, ailleurs. if intrants.get("backup_pubkey"): communes["serveur_backup_pubkey"] = str(intrants["backup_pubkey"]) - if intrants.get("cle_ssh"): + # LA CLE AUSSI EST UNE PROPRIETE DU CONTROLEUR, PAS DU SITE (2026-09-14). + # + # `cle_ssh` vaut `~/.ssh/id_ed25519_ansible_chezlepro` : le chemin sur le POSTE de + # l'exploitant. Impose au runner du site, il designe un fichier qui n'existe pas chez + # lui — et Ansible echoue sans dire que le chemin vient d'ailleurs. + # + # Le runner a SA propre paire, celle que le plan du site autorise desormais sur ses + # machines (`cles_admin`). Lui laisser son defaut, c'est le laisser etre lui-meme. + # + # MEME CONDITION QUE LE REBOND, ET CE N'EST PAS UN HASARD : les deux decrivent COMMENT + # ON ARRIVE, pas ce vers quoi on va. Ce qui depend de l'endroit d'ou l'on part n'a pas + # sa place dans la description d'un site. + if intrants.get("cle_ssh") and not _controleur_est_une_machine_du_site(): communes["ansible_ssh_private_key_file"] = intrants["cle_ssh"] # LE SITE N'AVAIT AUCUN MOYEN D'AUTORISER UNE CLE D'ADMINISTRATION (2026-09-14). #