bascule du plan sur le gabarit recapture, prouvee par une VM reelle
proxmox_clone_* pointent sur modeleChezlepro-travail (99998). L'ancien reste sur le cluster — il porte encore un resolv.conf et une cle privee d'hote SSH du reseau de fabrication ; a supprimer quand plusieurs VM seront nees du nouveau. Preuve par une machine, pas par lecture de config : web-dorsal-01 rase puis recree par le chemin normal. Herite du nouveau gabarit un resolv.conf reduit a ses commentaires, un machine-id neuf, une cle d'hote regeneree. Deploiement complet sans echec, cinq devis CONFORME. raser accepte --hote : les quatre verrous restent en vigueur, on ne fait que RESTREINDRE la liste derivee du plan. Releve, non corrige : le premier deploiement s'est interrompu sur client_unbound, a l'instant de la bascule du resolveur vers 127.0.0.1 — sshd fige sa resolution a l'ouverture de session (« banner exchange »). L'hote repondait une minute plus tard et la reprise est passee integralement. C'est une COURSE, meme famille que celles de la reconstruction. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
3618dfc129
commit
9cdfcc5deb
3 changed files with 46 additions and 2 deletions
34
CHANGELOG.md
34
CHANGELOG.md
|
|
@ -1,5 +1,39 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 2026-08-09 — Le plan bascule sur le gabarit recapturé, prouvé par une VM réelle
|
||||
|
||||
`proxmox_clone_source_nom` / `proxmox_clone_vmid_modele` pointent désormais sur
|
||||
`modeleChezlepro-travail` (99998). L'ancien (99999) reste sur le cluster : il porte encore
|
||||
un `/etc/resolv.conf` et une clé privée d'hôte SSH du réseau de fabrication. À supprimer
|
||||
quand plusieurs VM seront nées du nouveau — pas avant.
|
||||
|
||||
**Preuve par une machine réelle**, et non par lecture de configuration : `web-dorsal-01` —
|
||||
l'hôte le moins engagé de la flotte, 12 Ko dans `/var/www` — rasé puis recréé par le chemin
|
||||
normal (`make raser HOTE=…`, `make creer-vm`, `make deployer`).
|
||||
|
||||
Ce qu'elle a hérité du nouveau gabarit :
|
||||
|
||||
```
|
||||
resolv.conf → les commentaires seuls, aucune identité de fabrication
|
||||
machine-id → cc9c58c1… neuf et unique
|
||||
clé d'hôte → SHA256:pES0/… régénérée
|
||||
cloud-init → done
|
||||
```
|
||||
|
||||
Déploiement complet, **zéro échec**, et les cinq devis de service `CONFORME`.
|
||||
|
||||
**`raser` accepte maintenant `--hote`.** Raser une seule machine sert à éprouver un gabarit
|
||||
ou à reprendre un hôte ; les **quatre verrous restent en vigueur** — on ne fait que
|
||||
restreindre la liste dérivée du plan, jamais l'élargir.
|
||||
|
||||
**Un défaut relevé au passage, non corrigé.** Le premier déploiement s'est interrompu sur
|
||||
`client_unbound`, à l'instant où le résolveur bascule vers `127.0.0.1` : toute résolution
|
||||
en vol se fige le temps qu'Unbound réponde, y compris celle que fait `sshd` à l'ouverture
|
||||
de session — d'où « Connection timed out during banner exchange ». L'hôte répondait de
|
||||
nouveau une minute plus tard et la reprise est passée intégralement, presque tout en
|
||||
`changed=0`. C'est une **course**, de la même famille que celles de la reconstruction, et
|
||||
elle mérite le même remède : attendre une condition plutôt que de subir la bascule.
|
||||
|
||||
## 2026-08-09 — Gabarit recapturé sur copie de travail, sans toucher à l'original
|
||||
|
||||
`modeleChezlepro` (99999) cloné en `modeleChezlepro-travail` (99998), préparé, vérifié,
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -588,7 +588,7 @@ _attendre-flotte: ansible-runtime
|
|||
|
||||
.PHONY: reconstruire
|
||||
raser: ansible-runtime _instance-requise ## DESTRUCTIF : detruit les VM derivees du plan — exige CONFIRMER=true ET INSTANCE=<nom>
|
||||
@python3 scripts/raser.py $(if $(INSTANCE),--instance $(INSTANCE)) $(if $(filter true,$(CONFIRMER)),--confirmer)
|
||||
@python3 scripts/raser.py $(if $(INSTANCE),--instance $(INSTANCE)) $(if $(HOTE),--hote $(HOTE)) $(if $(filter true,$(CONFIRMER)),--confirmer)
|
||||
|
||||
reconstruire: _instance-requise ## Reconstruit un ecosysteme depuis zero : VM puis deploiement complet
|
||||
@set -e; \
|
||||
|
|
|
|||
|
|
@ -71,11 +71,20 @@ def plan_derive(base: Path) -> list[tuple[str, int]]:
|
|||
def main(argv: list[str] | None = None) -> int:
|
||||
ap = argparse.ArgumentParser(description="Rase les VM derivees du plan de l'instance active.")
|
||||
ap.add_argument("--instance", help="nom de l'ecosysteme a raser (doit correspondre au monte)")
|
||||
ap.add_argument("--hote", help="ne raser QUE cet hote (les quatre verrous s'appliquent)")
|
||||
ap.add_argument("--confirmer", action="store_true")
|
||||
a = ap.parse_args(argv)
|
||||
|
||||
base, nom_actif = instance_active()
|
||||
couples = plan_derive(base)
|
||||
if a.hote:
|
||||
# Les quatre verrous restent en vigueur : on ne fait que RESTREINDRE la liste
|
||||
# derivee du plan. Raser un seul hote sert a eprouver un gabarit ou a reprendre
|
||||
# une machine, sans toucher aux treize autres.
|
||||
couples = [c for c in couples if c[0] == a.hote]
|
||||
if not couples:
|
||||
print(f"L'hote « {a.hote} » n'est pas au plan : rien a raser.")
|
||||
return 2
|
||||
if not couples:
|
||||
print("Le plan ne derive aucune VM : rien a raser.")
|
||||
return 0
|
||||
|
|
@ -116,7 +125,8 @@ def main(argv: list[str] | None = None) -> int:
|
|||
|
||||
if not a.confirmer:
|
||||
print(f"\n{len(presentes)} VM seraient DETRUITES, disques compris.\n"
|
||||
f"Relancer avec : make raser CONFIRMER=true INSTANCE={nom_actif}")
|
||||
f"Relancer avec : make raser CONFIRMER=true INSTANCE={nom_actif}"
|
||||
+ (f" HOTE={a.hote}" if a.hote else ""))
|
||||
return 0
|
||||
|
||||
if (a.instance or "").lower() != nom_actif:
|
||||
|
|
|
|||
Loading…
Reference in a new issue