Set-OPS-Public/playbooks/maintenance/emancipation-prouver.yml

161 lines
8 KiB
YAML
Raw Normal View History

emancipation : l instrument de la quatrieme ligne — couper, pas sonder docs/filiation-emancipation.md decrit quatre temps et n en outillait que trois. Le quatrieme est celui qu on oublie : « une emancipation non prouvee est une emancipation non faite ». SONDER NE PROUVE RIEN. Verifier que le service local repond ne dit pas si l amont sert encore — le depot le disait deja du cache : « tant qu internet repond, un apt update qui reussit ne dit pas d ou vient l octet ». L instrument COUPE donc l amont et refait marcher la chose. LE MEME ESSAI REND LES DEUX VERDICTS, et c est ce qui le rend honnete : coupe, la fonction marche -> EMANCIPE, et c est prouve coupe, la fonction casse -> PAS EMANCIPE, dependance prouvee REELLE Le second n est pas un echec de l outil, c est son CONTROLE NEGATIF rendu par la meme commande. Une preuve d emancipation incapable de montrer la dependance qu elle mesure ne prouverait rien le jour ou elle passerait au vert. UN TEMOIN PRECEDE LA COUPURE : la fonction marchait-elle seulement avant ? Sans lui, une panne preexistante se lirait comme une dependance. LA COUPURE EST GARANTIE REVERSIBLE : une TABLE nftables dediee, jamais une regle glissee dans une table existante — elle se retire d un geste et ne peut pas laisser d etat partiel. Le bloc `always` la retire meme si la mesure echoue ou si le play est interrompu, et une tache verifie ensuite qu elle a bien disparu. MESURE LE JOUR DE SA NAISSANCE, les deux verdicts sur du vrai materiel : obs-01 / resolveur PAS EMANCIPE — plus aucune resolution des la coupure forge-01 / artefacts EMANCIPE — apt installe, cache du site coupe Ce second verdict a ete DOUTE puis verifie : apt aurait pu reussir en rejouant des listes fraiches. Refait avec un dossier de listes NEUF, amont coupe : reussit quand meme. Le cache sert vraiment son contenu. make verifier : vert. make prouver : CONFORME, 55 OK, 0 echec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
2026-09-01 08:36:28 -04:00
---
# PROUVER QU'UN LIEN EST COUPÉ — l'instrument de la quatrième ligne.
#
# `docs/filiation-emancipation.md` décrit quatre temps, et n'en outillait que trois :
#
# le lien de filiation déclaré au plan le moteur
# le constat d'aptitude « tu pourrais » la machine INSTRUIT
# l'acte d'émancipation retirer le lien l'HUMAIN, CONFIRMER=true
# la preuve que c'est coupé ← CE PLAYBOOK la machine, APRÈS l'acte
#
# « Une émancipation non prouvée est une émancipation non faite. »
#
# ─── POURQUOI SONDER NE SUFFIT PAS ───────────────────────────────────────────
#
# Vérifier que le service local répond ne prouve RIEN. Le dépôt le dit déjà, à propos du
# cache : « tant qu'internet répond, un `apt update` qui réussit ne dit pas d'où vient
# l'octet ». Un écosystème peut avoir monté son propre service ET continuer à tirer de
# l'amont sans que personne ne le voie.
#
# On COUPE donc, et on refait marcher la chose. C'est le seul geste qui distingue
# « j'ai un service local » de « je n'ai plus besoin du tien ».
#
# ─── LE MÊME ESSAI REND LES DEUX VERDICTS ────────────────────────────────────
#
# Le verdict vient de la MESURE, jamais d'une déclaration :
#
# coupé, la fonction marche -> ÉMANCIPÉ, et c'est prouvé
# coupé, la fonction casse -> PAS ÉMANCIPÉ — et la dépendance est prouvée REELLE
#
# Le second n'est pas un échec de l'outil : c'est son contrôle négatif, rendu par la même
# commande. Une preuve d'émancipation qui ne saurait pas montrer la dépendance qu'elle
# mesure ne prouverait rien le jour où elle passerait au vert.
#
# ─── LA COUPURE EST GARANTIE RÉVERSIBLE ──────────────────────────────────────
#
# Une TABLE nftables dédiée, jamais une règle glissée dans une table existante : elle se
# retire d'un seul geste, et ne peut pas laisser d'état partiel si l'essai s'interrompt.
# Le `always` la retire quoi qu'il arrive — y compris si la mesure échoue.
#
# Usage :
# make emancipation-prouver SERVICE=artefacts CONFIRMER=true
# make emancipation-prouver SERVICE=genome CONFIRMER=true
# make emancipation-prouver SERVICE=resolveur CONFIRMER=true
- name: Prouver qu'un lien de filiation est coupé
hosts: "{{ emancipation_hotes | default('hotes_actifs') }}"
gather_facts: false
become: true
vars:
# CE QU'ON COUPE, ET CE QU'ON REFAIT MARCHER. Chaque service nomme son amont (lu au
# plan, jamais écrit ici) et l'épreuve qui dit s'il tient sans lui.
emancipation_services:
artefacts:
amont: "{{ serveur_artefacts_amont | default(artefacts_amorcage | default('')) }}"
epreuve: "apt-get -qq update"
dit: "installer des paquets"
genome:
amont: "{{ serveur_ops_forge_amont | default('') }}"
epreuve: "git ls-remote {{ serveur_ops_forge_amont | default('') }}/genome/set-ops-public.git HEAD"
dit: "cloner le génome"
resolveur:
amont: "{{ dns_amorcage | default('') }}"
epreuve: "getent hosts deb.debian.org"
dit: "résoudre un nom public"
emancipation_ce_service: "{{ emancipation_services[emancipation_service] }}"
# L'ADRESSE SEULE, sans schéma ni port : c'est elle qu'on bloque.
emancipation_adresse: >-
{{ (emancipation_ce_service.amont | regex_replace('^\w+://', '')
| regex_replace('[:/].*$', '')) }}
tasks:
- name: Exiger un service connu et un amont déclaré
ansible.builtin.assert:
that:
- emancipation_service is defined
- emancipation_service in emancipation_services
- emancipation_adresse | length > 0
fail_msg: >-
SERVICE doit valoir l'un de {{ emancipation_services.keys() | join(', ') }},
et cet écosystème doit DÉCLARER l'amont correspondant. Un emprunt qu'aucune
variable ne nomme ne peut pas être prouvé coupé — c'est la forme normée de
`docs/filiation-emancipation.md` qui rend cette preuve possible.
# PAS de `run_once` : l'amont se lit dans les variables de CHAQUE hote. Un
# ecosysteme peut tres bien emprunter sur une machine et pas sur une autre — c'est
# meme le cas ici, ou seul le porteur du cache chaine vers celui du site. Verifier
# une fois pour toutes lirait le premier hote et parlerait au nom des autres.
- name: Prouver
block:
# ── L'ÉTAT AVANT : la fonction marche-t-elle seulement ? ────────────
#
# Sans ce témoin, une fonction déjà cassée AVANT la coupure se lirait comme une
# dépendance prouvée. On mesure donc le point de départ.
- name: Témoin — la fonction marche-t-elle AVANT toute coupure ?
ansible.builtin.command:
cmd: "{{ emancipation_ce_service.epreuve }}"
register: emancipation_temoin
failed_when: false
changed_when: false
- name: Refuser de mesurer une fonction déjà cassée
ansible.builtin.assert:
that:
- emancipation_temoin.rc == 0
fail_msg: >-
« {{ emancipation_ce_service.dit }} » ne marche DÉJÀ PAS sur cet hôte, avant
qu'on ait rien coupé. Une coupure ne prouverait rien ici : on lirait une
panne préexistante comme une dépendance. Réparer d'abord.
# ── LA COUPURE ─────────────────────────────────────────────────────
- name: Couper le lien vers l'amont
ansible.builtin.command:
argv:
- nft
- -f
- "-"
stdin: |
table inet setops_emancipation {
chain output {
type filter hook output priority -10; policy accept;
ip daddr {{ emancipation_adresse }} reject with icmpx type admin-prohibited
}
}
changed_when: true
# ── L'ÉPREUVE ──────────────────────────────────────────────────────
- name: L'épreuve, l'amont coupé
ansible.builtin.command:
cmd: "{{ emancipation_ce_service.epreuve }}"
register: emancipation_epreuve
failed_when: false
changed_when: false
always:
# RETIRÉE QUOI QU'IL ARRIVE — y compris si l'épreuve échoue, si le play est
# interrompu, ou si la mesure lève. Une coupure qui survit à son essai serait une
# panne qu'on aurait fabriquée soi-même.
- name: Rétablir le lien
ansible.builtin.command:
argv: ["nft", "delete", "table", "inet", "setops_emancipation"]
failed_when: false
changed_when: true
- name: Vérifier que le lien est bien rétabli
ansible.builtin.command:
argv: ["nft", "list", "table", "inet", "setops_emancipation"]
register: emancipation_reste
failed_when: emancipation_reste.rc == 0
changed_when: false
- name: "✔ Émancipation — {{ emancipation_service }}"
ansible.builtin.debug:
msg: >-
{{ (emancipation_epreuve.rc == 0) | ternary(
'ÉMANCIPÉ (prouvé) — « ' ~ emancipation_ce_service.dit ~ ' » fonctionne
l amont ' ~ emancipation_adresse ~ ' COUPÉ. Le lien peut être retiré du
plan : il ne sert plus.',
'PAS ÉMANCIPÉ — « ' ~ emancipation_ce_service.dit ~ ' » casse dès que
l amont ' ~ emancipation_adresse ~ ' est coupé. La dépendance est REELLE,
et cette mesure est le contrôle négatif de la preuve future.') }}