Some checks are pending
verifier / verifier (push) Waiting to run
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
160 lines
8 KiB
YAML
160 lines
8 KiB
YAML
---
|
|
# 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.') }}
|