contexte : corriger le devis des pools vide (face sans fonctions)
La face publie aussi fonctions ; les pools retrouvent leurs VM. La comparaison a l'ancien code est refaite dans un git worktree complet : les sept sorties du site sont identiques. Garde de regression ajoutee. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d0a6002b87
commit
2e9b31bef7
3 changed files with 58 additions and 3 deletions
34
CHANGELOG.md
34
CHANGELOG.md
|
|
@ -1,5 +1,39 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 2026-10-05 (95) — Une régression publiée : le devis des pools vide, et une comparaison qui ne testait rien
|
||||
|
||||
**Ce qui s'est passé.** (94) a fait passer la découverte des locataires par la face réseau, qui
|
||||
ne publiait que cinq champs de leur nomenclature. Le devis des pools dérive les VMID par
|
||||
`deriver_nomenclature`, qui lit aussi `fonctions` : sans ce champ, **chaque pool de locataire
|
||||
s'est retrouvé vide** (0 membre, toutes les VM « sans VMID »), sans erreur. Publié dans
|
||||
`d0a6002`.
|
||||
|
||||
**Pourquoi la vérification ne l'a pas vu.** Pour prouver « identique à HEAD », j'ai lancé
|
||||
l'**ancien script** (`git show HEAD:scripts/X.py`) à côté du nouveau. Mais il importait le
|
||||
**nouveau** module de découverte : pour tous les consommateurs de la découverte, la
|
||||
comparaison comparait le nouveau code à lui-même. Sept « IDENTIQUE » qui ne testaient rien.
|
||||
|
||||
**Ce que ça a coûté** : un devis publié faux. Rien n'applique les pools automatiquement, et le
|
||||
clonage nomme son pool par une lecture directe de la nomenclature, non touchée.
|
||||
|
||||
**Corrigé** :
|
||||
- la face publie aussi `fonctions` ; faces republiées. Les pools retrouvent leurs 13 VM par
|
||||
locataire ;
|
||||
- **la comparaison refaite correctement** : un `git worktree` à `d6591cb` (avant toute
|
||||
l'étape 3), arbre complet, même environnement. Les sept sorties du site (commutateur,
|
||||
frontière, Proxmox, SDN ×2, pools, inventaire du site) sont **identiques octet pour octet**.
|
||||
Une seule différence apparente — `instance_active` à la frontière — venait du worktree, sans
|
||||
lien `instance` : la frontière lit le lien et non `SETOPS_INSTANCE`, une des devinettes de
|
||||
contexte que la conception doit supprimer. Avec le même lien : identique ;
|
||||
- garde de régression dans `test_contexte.py` (105 contrôles) : chaque pool porte autant de
|
||||
VM que le locataire en publie, aucune sans VMID.
|
||||
|
||||
**La leçon, retenue** : comparer à l'ancien code se fait dans un **arbre complet**, jamais en
|
||||
lançant l'ancien script seul ; vérifier `git diff --stat` après une édition scriptée avant de
|
||||
comparer ; accompagner chaque « identique » d'un témoin qui doit changer.
|
||||
|
||||
**Validation** : `make verifier` conforme, 92/92.
|
||||
|
||||
## 2026-10-05 (94) — Étape 3 : le site découvre ses locataires par leur face réseau
|
||||
|
||||
**Le chemin** (`docs/conception-contextes.md` §6), étape 3. La découverte des locataires
|
||||
|
|
|
|||
|
|
@ -540,10 +540,11 @@ class Locataire(Ecosysteme):
|
|||
"sources": sources,
|
||||
"index": self.index,
|
||||
"zones": zones,
|
||||
# Ce que le site lit de sa nomenclature (decouverte, frontiere, SDN, commutateur) :
|
||||
# ces cinq champs, et rien d'autre (releve du 2026-10-05).
|
||||
# Ce que le site lit de sa nomenclature (decouverte, frontiere, SDN, commutateur, pools).
|
||||
# `fonctions` manquait au premier releve : les pools en derivent les VMID — le devis
|
||||
# des pools s'est retrouve vide, publie ainsi avant d'etre vu (2026-10-05).
|
||||
"nomenclature": {k: self.nomenclature()[k] for k in
|
||||
("index", "categories", "reservations", "cidr_hote", "federe")
|
||||
("index", "categories", "reservations", "cidr_hote", "federe", "fonctions")
|
||||
if k in self.nomenclature()},
|
||||
"machines": machines,
|
||||
"groupes": groupes,
|
||||
|
|
|
|||
|
|
@ -579,6 +579,25 @@ def decouverte_lit_la_face() -> None:
|
|||
f"la decouverte du site lit l'index publie : {avant}, puis 99 une fois la face alteree")
|
||||
|
||||
|
||||
def pools_complets() -> None:
|
||||
"""Chaque pool porte toutes les VM que le locataire publie (regression du 2026-10-05 : la
|
||||
face ne publiait pas `fonctions`, et le devis des pools s'est retrouve vide, sans erreur)."""
|
||||
import devis_proxmox_pools
|
||||
import devis_reseau
|
||||
couples = C.couples_hebergeur()
|
||||
if not couples:
|
||||
print("SAUTE aucun site frere : aucun pool a confronter")
|
||||
return
|
||||
site = couples[0][0]
|
||||
with C._monter(site):
|
||||
pools = {b["tenant"]: b for b in devis_proxmox_pools.construire(devis_reseau.decouvrir_du_site())["pools"]}
|
||||
for _s, loc in couples:
|
||||
b = pools.get(loc.nom) or {}
|
||||
attendu = len((loc.face_publiee() or {}).get("machines") or {})
|
||||
verifier(len(b.get("membres") or []) == attendu and not b.get("sans_vmid"),
|
||||
f"pool {loc.nom} : {len(b.get('membres') or [])} VM sur {attendu} publiees, aucune sans VMID")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
d = Path(tmp)
|
||||
|
|
@ -599,6 +618,7 @@ def main() -> int:
|
|||
proxmox_lit_la_face()
|
||||
frontiere_lit_la_face()
|
||||
decouverte_lit_la_face()
|
||||
pools_complets()
|
||||
if ECHECS:
|
||||
print(f"\n{len(ECHECS)} echec(s).")
|
||||
return 1
|
||||
|
|
|
|||
Loading…
Reference in a new issue