patient 0 efface : l index 29 est libere, et le site n ouvre plus rien a 10.29.0.0/16
Ses machines n existaient plus depuis le 2026-09-06 (D-83), mais son plan restait sur disque : la federation lui reservait l index 29 et quatre machines du site lui ouvraient SSH, apt, DNS et HTTPS. Les commentaires et documents vivants gardent leur lecon sans le nommer ; les archives restent telles quelles. Pas encore sur le reseau : les regles regenerees attendent le runner du site. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5f6ffda5e8
commit
c0f610be33
28 changed files with 75 additions and 66 deletions
28
CHANGELOG.md
28
CHANGELOG.md
|
|
@ -1,5 +1,33 @@
|
||||||
# CHANGELOG — Set-OPS
|
# CHANGELOG — Set-OPS
|
||||||
|
|
||||||
|
## 2026-09-27 (1) — Patient 0 effacé, l'index 29 libéré
|
||||||
|
|
||||||
|
Ses machines n'existaient plus depuis le 2026-09-06 (D-83), mais son plan restait sur
|
||||||
|
disque en `federe: true` : la fédération lui réservait l'index 29, et quatre machines du
|
||||||
|
site ouvraient SSH, apt, DNS et HTTPS à `10.29.0.0/16` — un périmètre vide.
|
||||||
|
|
||||||
|
**Ce qui est fait :**
|
||||||
|
|
||||||
|
- `SITE-Chezlepro/underlay.yml` : `OPS-Patient0: 29` retiré de `tenants`.
|
||||||
|
- `SITE-Chezlepro/plan/serveurs.yml` : le runner du site ne clone plus `ops-patient0`.
|
||||||
|
- `make flux` : `10.29.0.0/16` sort des règles de `site-backup-01`, `site-cache-01`,
|
||||||
|
`site-dns-01`, `site-dnspub-01` et `site-forge-01` — et rien d'autre ne change.
|
||||||
|
- Le dépôt local `OPS-Patient0/` est supprimé ; sa copie reste sur `eregion`.
|
||||||
|
- Les commentaires et documents vivants qui le nommaient gardent leur leçon sans le nommer
|
||||||
|
(moteur, modèles, tenants, sites). Le CHANGELOG, les rapports de preuve datés et la
|
||||||
|
chronique restent tels quels : ce sont des archives.
|
||||||
|
- `filiation-emancipation.md` §« Qui est le parent ? » ramené à la décision et à la dette
|
||||||
|
qui reste — `eregion`, hors flotte, alimente la forge qui fait autorité.
|
||||||
|
|
||||||
|
**Ce qui n'est pas encore sur le réseau.** Les `.nft` régénérés doivent être posés par le
|
||||||
|
runner du site. Le SDN (zone `t29`, VLAN 1291-1296), la frontière et le pare-feu Proxmox
|
||||||
|
n'ont pas pu être relus depuis le poste : le cluster ne répondait pas (22 et 8006).
|
||||||
|
|
||||||
|
**Mesuré en passant.** `make sdn-plan`, cluster injoignable, annonce « à créer : 33 » —
|
||||||
|
TOUTES les zones, Chezlepro comprise. Il lit un cluster muet comme un cluster vide, là où
|
||||||
|
`frontiere-plan` refuse de conclure. `make verifier` : 82 OK, 1 échec — P02,
|
||||||
|
`test_ecriture_plan.py` sur `domaines.yml` (`'list' object has no attribute 'get'`),
|
||||||
|
présent avant ce changement.
|
||||||
## 2026-09-25 — Le registre disait « mesure » d'une cible qui coupe l'amont
|
## 2026-09-25 — Le registre disait « mesure » d'une cible qui coupe l'amont
|
||||||
|
|
||||||
**21 preuves sur `test_runbooks.py`, `verifier` à 0 écart.** Un outil tiers veut
|
**21 preuves sur `test_runbooks.py`, `verifier` à 0 écart.** Un outil tiers veut
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ sont les seules vérifiables.
|
||||||
| # | Décision | Pourquoi | Détail | Garde |
|
| # | Décision | Pourquoi | Détail | Garde |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| **D-82** | **Patient 0 n'est le parent de personne.** Il est la **mise en œuvre de référence** du modèle `origine` — le plus petit écosystème complet — et un pair de la famille du génome, pas sa racine | trois faits l'ont retiré un par un : D-81 a donné l'autorité du génome à la forge du SITE (son dernier lecteur corrigé le 2026-08-26, Technolibre le 08-31) ; le dénominateur commun vit dans les modèles depuis le 08-24 ; et **l'ancêtre était locataire de son enfant** — index 29 sur la fabric de `SITE-Chezlepro`, qui descend de lui. Ce qu'il devait éliminer — le SPOF `eregion`, hors flotte — n'a PAS été éliminé mais **promu** : le poste y pousse, la forge du site en tire. Cette dette appartient désormais au SITE, et la nommer est le minimum : *un objectif qu'on abandonne sans le dire devient un objectif qu'on croit atteint* | `OPS-Patient0/README.md`, `docs/filiation-emancipation.md` | — |
|
| **D-82** | **Patient 0 n'est le parent de personne.** Il est la **mise en œuvre de référence** du modèle `origine` — le plus petit écosystème complet — et un pair de la famille du génome, pas sa racine | trois faits l'ont retiré un par un : D-81 a donné l'autorité du génome à la forge du SITE (son dernier lecteur corrigé le 2026-08-26, Technolibre le 08-31) ; le dénominateur commun vit dans les modèles depuis le 08-24 ; et **l'ancêtre était locataire de son enfant** — index 29 sur la fabric de `SITE-Chezlepro`, qui descend de lui. Ce qu'il devait éliminer — le SPOF `eregion`, hors flotte — n'a PAS été éliminé mais **promu** : le poste y pousse, la forge du site en tire. Cette dette appartient désormais au SITE, et la nommer est le minimum : *un objectif qu'on abandonne sans le dire devient un objectif qu'on croit atteint* | `OPS-Patient0/README.md`, `docs/filiation-emancipation.md` | — |
|
||||||
| **D-83** | **Patient 0 a été retiré** — ses machines n'existent plus (constaté le 2026-09-06) | D-82 lui avait laissé une raison d'être : la mise en œuvre de référence du modèle `origine`, et un **témoin** de plus du génome. Le retrait solde la première et **abaisse la seconde de trois copies vivantes à deux** (`eregion`, la forge du site). Ce qu'il devait éliminer — le SPOF `eregion` — reste entier, et sans lui il n'y a plus de miroir indépendant pour l'absorber. **Son plan reste sur disque et la fédération lui réserve toujours l'index 29** : tant que ce n'est pas tranché, le site ouvre SSH, apt, DNS et HTTPS à `10.29.0.0/16` — un périmètre vide | `OPS-Patient0/`, `SITE-Chezlepro/flux-genere/` | **P21** (index), **P23** |
|
| **D-83** | **Patient 0 a été retiré** — ses machines n'existent plus (constaté le 2026-09-06) | D-82 lui avait laissé une raison d'être : la mise en œuvre de référence du modèle `origine`, et un **témoin** de plus du génome. Le retrait solde la première et **abaisse la seconde de trois copies vivantes à deux** (`eregion`, la forge du site). Ce qu'il devait éliminer — le SPOF `eregion` — reste entier, et sans lui il n'y a plus de miroir indépendant pour l'absorber. **Son plan a été effacé le 2026-09-27** : l'index 29 est libéré, et le site n'ouvre plus rien à `10.29.0.0/16` | `SITE-Chezlepro/underlay.yml` (`tenants`), `SITE-Chezlepro/flux-genere/` | **P21** (index), **P23** |
|
||||||
| **D-84** | **Le plan de contrôle reste gelé — c'est la CARTE DES SEUILS qui était fausse** | La question « et si on retirait le gel ? » a mis à l'épreuve les cinq seuils de `positionnement.md`, et deux ne tenaient pas. **RBAC** : couvert depuis que trois classes d'acteurs aux pouvoirs disjoints existent — poste, runner de site, runners de tenant — séparés **cryptographiquement** (une voûte, une clé, 2026-08-28) et non par une table de permissions qu'une faille applicative contournerait ; adopter AWX pour ce besoin serait **régresser**. **IPAM** : sans objet par construction — rien ne s'alloue, tout dérive du seed, et P20/P21/P23/P28/P33 tiennent déjà ce qu'un IPAM vérifierait *a posteriori*. Les deux lignes sont retirées du tableau : les garder aurait fait adopter un outil pour un besoin déjà rempli. **Et un seuil manquait** — l'**émancipation** : le GUI est mono-utilisateur (`127.0.0.1` + jeton), or la trajectoire mène à plusieurs humains aux portées disjointes, sur des machines qui ne sont pas les nôtres. Ce seuil n'appelle pas AWX, il appelle une décision non prise. *Un seuil qu'on ne nomme pas est un seuil qu'on franchit sans le voir.* Corollaire consigné : le gel porte sur les **fonctions**, jamais sur les **vues** — montrer à l'écran ce que le moteur sait déjà ne franchit aucun seuil | `positionnement.md` §3, §4, §5 | — |
|
| **D-84** | **Le plan de contrôle reste gelé — c'est la CARTE DES SEUILS qui était fausse** | La question « et si on retirait le gel ? » a mis à l'épreuve les cinq seuils de `positionnement.md`, et deux ne tenaient pas. **RBAC** : couvert depuis que trois classes d'acteurs aux pouvoirs disjoints existent — poste, runner de site, runners de tenant — séparés **cryptographiquement** (une voûte, une clé, 2026-08-28) et non par une table de permissions qu'une faille applicative contournerait ; adopter AWX pour ce besoin serait **régresser**. **IPAM** : sans objet par construction — rien ne s'alloue, tout dérive du seed, et P20/P21/P23/P28/P33 tiennent déjà ce qu'un IPAM vérifierait *a posteriori*. Les deux lignes sont retirées du tableau : les garder aurait fait adopter un outil pour un besoin déjà rempli. **Et un seuil manquait** — l'**émancipation** : le GUI est mono-utilisateur (`127.0.0.1` + jeton), or la trajectoire mène à plusieurs humains aux portées disjointes, sur des machines qui ne sont pas les nôtres. Ce seuil n'appelle pas AWX, il appelle une décision non prise. *Un seuil qu'on ne nomme pas est un seuil qu'on franchit sans le voir.* Corollaire consigné : le gel porte sur les **fonctions**, jamais sur les **vues** — montrer à l'écran ce que le moteur sait déjà ne franchit aucun seuil | `positionnement.md` §3, §4, §5 | — |
|
||||||
| **D-85** | **cloud-init naît avec la VM et ne lui survit pas** | cloud-init n'est pas un logiciel d'installation : c'est une **source de vérité externe**, qui se réveille à *chaque* démarrage et relit le lecteur attaché par l'hyperviseur — lequel peut redéfinir comptes, clés SSH autorisées, mots de passe et réseau. Sur une machine que le plan possède, c'est un **second maître** : le plan ne le décrit pas, `make valider` ne le mesure pas, et il parle en premier. Sa tâche est pourtant finie à la première seconde — c'est parce qu'il a **réussi** à poser l'adresse et les clés qu'Ansible a pu entrer. **Trois moitiés, qui se défont séparément** : le **gabarit** le garde (sans lui un clone ne naît pas — P56) ; le **socle** ne l'installe plus (le garder produisait un va-et-vient à chaque déploiement : le socle installe, le durcissement retire, deux `changed` par passage) ; le **durcissement** le retire (`cloud_init_retrait`, en dernier). **Ce qui rend le retrait sûr est mesuré, pas supposé** (2026-09-09, `obs-01`) : `/etc/network/interfaces.d/50-cloud-init` n'appartient à aucun paquet — `dpkg -S` ne le trouve pas — et le `postrm` ne le nomme jamais, même en `purge`. L'adresse survit. Le rôle le **vérifie** malgré tout, avant et après : une VM qui perd ce fichier ne se plaint pas, elle repart sans adresse et plus personne ne peut entrer pour le constater. **⚠ CE QUE CETTE DÉCISION NE FERME PAS — et il faut le dire, sinon elle se lit comme une émancipation qu'elle n'est pas.** Retirer cloud-init **n'ôte aucun pouvoir à l'hébergeur**. `qemu-guest-agent` est au gabarit (P56 : il doit y être — c'est par lui que `creer-vm` confirme la matérialisation sans entrer chez le tenant), et l'API Proxmox expose sur son dos, sur toute VM vivante de la flotte, un pouvoir **strictement plus grand** que le lecteur cloud-init : `exec`, `file-write`, `file-read`, `set-user-password`, `shutdown` (relevé le 2026-09-09 sur `edge-mta-01`, jeton d'API du site). Ce que D-85 ferme est donc **précis et étroit** : (a) une réapplication **automatique, à chaque démarrage**, depuis un support que le plan ne possède pas et qu'aucune preuve ne lit ; (b) le code de cloud-init lui-même — un interpréteur Python complet, exécuté en root au démarrage, et ses ~29 dépendances. Elle ne ferme **pas** la mainmise de l'hyperviseur sur ses invités : celle-là est une propriété de la virtualisation, pas de cloud-init, et elle appelle sa propre décision — non prise. **Le seuil où le remplacer deviendrait juste** : le jour où une première seconde ne peut plus être amorcée par Proxmox (autre hyperviseur, métal nu, hébergeur sans API), le chemin par l'agent invite cesse d'être une réimplémentation d'un standard — que `positionnement.md` interdit — et devient **le chemin portable**. Tant que ce seuil n'est pas atteint, écrire soi-même l'amorçage serait échanger un standard éprouvé contre du code maison au moment le plus fragile, dont le mode de panne est le pire : une VM injoignable | `roles/cloud_init_retrait/`, `serveur_durci.yml`, `positionnement.md` | **P63** |
|
| **D-85** | **cloud-init naît avec la VM et ne lui survit pas** | cloud-init n'est pas un logiciel d'installation : c'est une **source de vérité externe**, qui se réveille à *chaque* démarrage et relit le lecteur attaché par l'hyperviseur — lequel peut redéfinir comptes, clés SSH autorisées, mots de passe et réseau. Sur une machine que le plan possède, c'est un **second maître** : le plan ne le décrit pas, `make valider` ne le mesure pas, et il parle en premier. Sa tâche est pourtant finie à la première seconde — c'est parce qu'il a **réussi** à poser l'adresse et les clés qu'Ansible a pu entrer. **Trois moitiés, qui se défont séparément** : le **gabarit** le garde (sans lui un clone ne naît pas — P56) ; le **socle** ne l'installe plus (le garder produisait un va-et-vient à chaque déploiement : le socle installe, le durcissement retire, deux `changed` par passage) ; le **durcissement** le retire (`cloud_init_retrait`, en dernier). **Ce qui rend le retrait sûr est mesuré, pas supposé** (2026-09-09, `obs-01`) : `/etc/network/interfaces.d/50-cloud-init` n'appartient à aucun paquet — `dpkg -S` ne le trouve pas — et le `postrm` ne le nomme jamais, même en `purge`. L'adresse survit. Le rôle le **vérifie** malgré tout, avant et après : une VM qui perd ce fichier ne se plaint pas, elle repart sans adresse et plus personne ne peut entrer pour le constater. **⚠ CE QUE CETTE DÉCISION NE FERME PAS — et il faut le dire, sinon elle se lit comme une émancipation qu'elle n'est pas.** Retirer cloud-init **n'ôte aucun pouvoir à l'hébergeur**. `qemu-guest-agent` est au gabarit (P56 : il doit y être — c'est par lui que `creer-vm` confirme la matérialisation sans entrer chez le tenant), et l'API Proxmox expose sur son dos, sur toute VM vivante de la flotte, un pouvoir **strictement plus grand** que le lecteur cloud-init : `exec`, `file-write`, `file-read`, `set-user-password`, `shutdown` (relevé le 2026-09-09 sur `edge-mta-01`, jeton d'API du site). Ce que D-85 ferme est donc **précis et étroit** : (a) une réapplication **automatique, à chaque démarrage**, depuis un support que le plan ne possède pas et qu'aucune preuve ne lit ; (b) le code de cloud-init lui-même — un interpréteur Python complet, exécuté en root au démarrage, et ses ~29 dépendances. Elle ne ferme **pas** la mainmise de l'hyperviseur sur ses invités : celle-là est une propriété de la virtualisation, pas de cloud-init, et elle appelle sa propre décision — non prise. **Le seuil où le remplacer deviendrait juste** : le jour où une première seconde ne peut plus être amorcée par Proxmox (autre hyperviseur, métal nu, hébergeur sans API), le chemin par l'agent invite cesse d'être une réimplémentation d'un standard — que `positionnement.md` interdit — et devient **le chemin portable**. Tant que ce seuil n'est pas atteint, écrire soi-même l'amorçage serait échanger un standard éprouvé contre du code maison au moment le plus fragile, dont le mode de panne est le pire : une VM injoignable | `roles/cloud_init_retrait/`, `serveur_durci.yml`, `positionnement.md` | **P63** |
|
||||||
| **D-86** | **La supervision se déploie juste après la PKI, pas à la fin** | L'observabilité (`prometheus`, `loki`, `grafana`) et le **moteur** de supervision (`icinga`) passent en couche 4, immédiatement après `client_pki` ; les agents qui les nourrissent (`client_metrique`, `client_journal`, `client_sante`) en couche 5. **Le raisonnement** : ce qui se déploie ensuite l'est *sous l'œil* de la supervision — une unité qui casse se voit à la minute, pas à la fin. Une **reconstruction depuis zéro** est précisément le moment où l'on a le plus besoin de voir, et c'était le seul moment où l'on ne voyait rien. **Déplacer les serveurs sans les agents n'aurait rien changé** : ce sont les agents qui rapportent, et ils étaient en dernière couche. **Ce que ça a coûté en dépendances** : `serveur_postgresql` monte aussi (il n'exige rien lui-même, et `icinga` l'exige). **Ce qui reste tard, à dessein** : `icingaweb2` et `oauth2_proxy` réclament LDAP et Keycloak — c'est la CONSOLE, pas la mesure. L'interface humaine peut attendre. **Limite dite franchement** : les *notifications* dépendent de `client_smtp`, encore en dernière couche — pendant une reconstruction, l'état est mesuré et consultable, mais rien ne part par courriel avant la fin. **CE QUI REND CE DÉPLACEMENT POSSIBLE**, et qui n'est pas un détail : le DNS (`powerdns`, `resolveur`) reste en couche 6, donc *après* la supervision. Or `icinga` joint sa base par un **nom** (`data-sql-01.chezlepro.internal`), et `client_sante` pousse vers un **nom**. Ça tient parce que le **plancher `/etc/hosts`**, posé dès la couche 1 par `hosts_statiques`, porte déjà les 34 entrées de l'écosystème — vérifié. C'est exactement ce pour quoi il existe : *« il ne s'installe pas, il rend installable »*. Sans lui, cette décision serait impossible. **P08** valide l'ordre : aucune arête en arrière | `docs/couches-deploiement.yml`, `catalogue-services.md` §Ordre | **P08** |
|
| **D-86** | **La supervision se déploie juste après la PKI, pas à la fin** | L'observabilité (`prometheus`, `loki`, `grafana`) et le **moteur** de supervision (`icinga`) passent en couche 4, immédiatement après `client_pki` ; les agents qui les nourrissent (`client_metrique`, `client_journal`, `client_sante`) en couche 5. **Le raisonnement** : ce qui se déploie ensuite l'est *sous l'œil* de la supervision — une unité qui casse se voit à la minute, pas à la fin. Une **reconstruction depuis zéro** est précisément le moment où l'on a le plus besoin de voir, et c'était le seul moment où l'on ne voyait rien. **Déplacer les serveurs sans les agents n'aurait rien changé** : ce sont les agents qui rapportent, et ils étaient en dernière couche. **Ce que ça a coûté en dépendances** : `serveur_postgresql` monte aussi (il n'exige rien lui-même, et `icinga` l'exige). **Ce qui reste tard, à dessein** : `icingaweb2` et `oauth2_proxy` réclament LDAP et Keycloak — c'est la CONSOLE, pas la mesure. L'interface humaine peut attendre. **Limite dite franchement** : les *notifications* dépendent de `client_smtp`, encore en dernière couche — pendant une reconstruction, l'état est mesuré et consultable, mais rien ne part par courriel avant la fin. **CE QUI REND CE DÉPLACEMENT POSSIBLE**, et qui n'est pas un détail : le DNS (`powerdns`, `resolveur`) reste en couche 6, donc *après* la supervision. Or `icinga` joint sa base par un **nom** (`data-sql-01.chezlepro.internal`), et `client_sante` pousse vers un **nom**. Ça tient parce que le **plancher `/etc/hosts`**, posé dès la couche 1 par `hosts_statiques`, porte déjà les 34 entrées de l'écosystème — vérifié. C'est exactement ce pour quoi il existe : *« il ne s'installe pas, il rend installable »*. Sans lui, cette décision serait impossible. **P08** valide l'ordre : aucune arête en arrière | `docs/couches-deploiement.yml`, `catalogue-services.md` §Ordre | **P08** |
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ Jusqu'ici, le moteur a rencontré ce besoin **trois fois sans le nommer** :
|
||||||
```
|
```
|
||||||
client_artefacts_actif dérivé : « une source existe-t-elle chez moi ? »
|
client_artefacts_actif dérivé : « une source existe-t-elle chez moi ? »
|
||||||
serveur_ops_forge_externe « je lis mon génome ailleurs »
|
serveur_ops_forge_externe « je lis mon génome ailleurs »
|
||||||
client_backup_cible patient 0 sauvegarde chez eregion — mutualisé, en production
|
client_backup_cible « je sauvegarde chez le site » — mutualisé, en production
|
||||||
```
|
```
|
||||||
|
|
||||||
Trois astuces, une seule notion. Ce document la déclare.
|
Trois astuces, une seule notion. Ce document la déclare.
|
||||||
|
|
@ -239,29 +239,14 @@ déclarer du tout.
|
||||||
|
|
||||||
## Qui est le parent ? — tranché le 2026-08-31 (D-82)
|
## Qui est le parent ? — tranché le 2026-08-31 (D-82)
|
||||||
|
|
||||||
Le dilemme est resté ouvert trois jours. Les faits l'ont tranché plus que le raisonnement :
|
**Personne. La forge du SITE fait autorité pour le génome** (D-81) ; toute autre copie est
|
||||||
**personne n'est le parent, et la forge du SITE est l'autorité.**
|
un miroir. Le dépôt l'avait suivi avant de le déclarer : `serveur_forge_site`, puis
|
||||||
|
`serveur_cache_site`, puis `serveur_resolveur_site` — trois services prêtés par le site à
|
||||||
|
ses locataires, un seul patron.
|
||||||
|
|
||||||
Trois issues avaient été posées. C'est la deuxième qui l'emporte, non parce qu'elle était
|
**Ce que ça ne règle pas.** La forge qui fait autorité est alimentée depuis `eregion`, hors
|
||||||
la plus élégante, mais parce que les deux autres avaient cessé d'être disponibles :
|
flotte — que Set-OPS ne déploie, ne sauvegarde ni ne prouve. Le génome compte deux copies
|
||||||
|
vivantes : `eregion` et la forge du site. Cette dette appartient au SITE.
|
||||||
- **patient 0 redevient la source** — impossible sans le rendre atteignable depuis *tout*
|
|
||||||
site, alors qu'il vit dans la fabric d'un seul, en locataire de son propre descendant ;
|
|
||||||
- **le SITE est la source** ✔ — c'est ce que D-81 avait déjà fait, et que le reste du dépôt
|
|
||||||
a suivi sans qu'on le déclare : `serveur_forge_site`, puis `serveur_cache_site`, puis
|
|
||||||
`serveur_resolveur_site`. Trois services prêtés, un seul patron ;
|
|
||||||
- **une famille de pairs** — reste vraie *pour la redondance*. C'est ce que patient 0
|
|
||||||
gardait : un miroir du génome, comme chaque écosystème. Il perdait le rang, pas la place.
|
|
||||||
|
|
||||||
> **Il a perdu la place aussi : ses machines n'existent plus (2026-09-06).** La famille du
|
|
||||||
> génome compte donc **deux** copies vivantes au lieu de trois — `eregion` et la forge du
|
|
||||||
> site. Or c'est précisément le raisonnement ci-dessus qui portait tout : *on n'échappe pas
|
|
||||||
> à la boucle par la ruse, mais par le nombre.* Le nombre a baissé, et le SPOF que patient 0
|
|
||||||
> devait absorber (`eregion`, hors flotte) est toujours là.
|
|
||||||
|
|
||||||
**Ce que ça ne règle pas.** Le point unique de défaillance que patient 0 devait éliminer —
|
|
||||||
`eregion`, hors flotte — n'a pas disparu : il alimente maintenant l'autorité. La dette a
|
|
||||||
changé de propriétaire, pas de nature. Elle appartient au SITE.
|
|
||||||
|
|
||||||
## État — revu le 2026-09-06
|
## État — revu le 2026-09-06
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ qu'on touche à son plan — c'est ce qui rend la portabilité possible.
|
||||||
|
|
||||||
> **Un tenant ne détient jamais un secret du monde physique.**
|
> **Un tenant ne détient jamais un secret du monde physique.**
|
||||||
|
|
||||||
Chaque tenant a porté dans sa voûte le jeton d'API du cluster — patient 0 a dû le recopier
|
Chaque tenant a porté dans sa voûte le jeton d'API du cluster — chaque nouveau tenant devait le
|
||||||
pour exister. C'était exactement la faute des **neuf copies** de la résolution d'instance,
|
recopier pour exister. C'était exactement la faute des **neuf copies** de la résolution d'instance,
|
||||||
appliquée aux secrets : une valeur qui vit à N endroits finit par diverger, et on ne peut
|
appliquée aux secrets : une valeur qui vit à N endroits finit par diverger, et on ne peut
|
||||||
plus révoquer l'une sans révoquer les autres.
|
plus révoquer l'une sans révoquer les autres.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@ make instances
|
||||||
OPS-Chezlepro-lab 13 1131-1136 LOCAL non
|
OPS-Chezlepro-lab 13 1131-1136 LOCAL non
|
||||||
* OPS-Chezlepro 17 1171-1176 oui oui
|
* OPS-Chezlepro 17 1171-1176 oui oui
|
||||||
OPS-Technolibre 23 1231-1236 oui non
|
OPS-Technolibre 23 1231-1236 oui non
|
||||||
OPS-Patient0 29 1291-1296 oui ?
|
|
||||||
* = instance active (symlink 'instance'). Basculer : make instance-utiliser NOM=<depot>
|
* = instance active (symlink 'instance'). Basculer : make instance-utiliser NOM=<depot>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ Raisons assumées :
|
||||||
Ce document a longtemps écrit « ~13 VM ». Le moteur pilote aujourd'hui **quatre plans
|
Ce document a longtemps écrit « ~13 VM ». Le moteur pilote aujourd'hui **quatre plans
|
||||||
vivants** (mesuré le 2026-09-06) : Chezlepro 14 VM, Technolibre 15, le lab 15, plus les
|
vivants** (mesuré le 2026-09-06) : Chezlepro 14 VM, Technolibre 15, le lab 15, plus les
|
||||||
7 machines du site — **51 VM déclarées**, réparties sur des écosystèmes qui ne se parlent
|
7 machines du site — **51 VM déclarées**, réparties sur des écosystèmes qui ne se parlent
|
||||||
pas. *(Patient 0 en portait 5 ; ses machines n'existent plus.)* Ça reste très loin de l'échelle entreprise pour laquelle NetBox est fait,
|
pas. Ça reste très loin de l'échelle entreprise pour laquelle NetBox est fait,
|
||||||
et le seuil du §4 n'est pas franchi. Mais la courbe monte : c'est **le** chiffre à
|
et le seuil du §4 n'est pas franchi. Mais la courbe monte : c'est **le** chiffre à
|
||||||
regarder quand on se demande si la décision tient encore.
|
regarder quand on se demande si la décision tient encore.
|
||||||
3. **Modèle sur-mesure** — NetBox exprimerait nos DSN / expositions à coups de
|
3. **Modèle sur-mesure** — NetBox exprimerait nos DSN / expositions à coups de
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ contenu.
|
||||||
- un temps 2 déclaré fait pendant que le plan ne révoque **aucune** clé.
|
- un temps 2 déclaré fait pendant que le plan ne révoque **aucune** clé.
|
||||||
|
|
||||||
Elle ne juge **pas** un écosystème sans registre : tous ne sont pas remis, et beaucoup ne
|
Elle ne juge **pas** un écosystème sans registre : tous ne sont pas remis, et beaucoup ne
|
||||||
le seront jamais — le lab, patient 0, l'écosystème de l'hébergeur lui-même.
|
le seront jamais — le lab, l'écosystème de l'hébergeur lui-même.
|
||||||
|
|
||||||
## 7. Ce que cette procédure ne couvre pas
|
## 7. Ce que cette procédure ne couvre pas
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,7 @@
|
||||||
Le **code** de Set-OPS est répliqué **deux fois** : `eregion` et la forge du site. Les
|
Le **code** de Set-OPS est répliqué **deux fois** : `eregion` et la forge du site. Les
|
||||||
**voûtes chiffrées** y sont aussi.
|
**voûtes chiffrées** y sont aussi.
|
||||||
|
|
||||||
> **Ce chiffre était trois, et il a baissé sans que rien ne le signale.** Le troisième
|
> **Ce chiffre était trois, et il a baissé sans que rien ne le signale.** Un coffre répliqué deux fois reste
|
||||||
> témoin était patient 0 ; ses machines n'existent plus. Un coffre répliqué deux fois reste
|
|
||||||
> solide — mais c'est la **redondance du génome** qui a diminué, pas le chiffrement, et
|
> solide — mais c'est la **redondance du génome** qui a diminué, pas le chiffrement, et
|
||||||
> c'est exactement ce que la page *Filiation, signatures & témoins* appelle la vraie mesure
|
> c'est exactement ce que la page *Filiation, signatures & témoins* appelle la vraie mesure
|
||||||
> de résistance d'une lignée : combien de copies **vivantes**, sur combien de machines
|
> de résistance d'une lignée : combien de copies **vivantes**, sur combien de machines
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ identite_realm: "exemple"
|
||||||
# `instance` du moteur, en dur. Tout role lisant le plan lisait donc celui de
|
# `instance` du moteur, en dur. Tout role lisant le plan lisait donc celui de
|
||||||
# l'instance POINTEE PAR LE LIEN, et non celle qu'on deploie.
|
# l'instance POINTEE PAR LE LIEN, et non celle qu'on deploie.
|
||||||
#
|
#
|
||||||
# CE QUE CA A DONNE. En deployant patient 0 avec `SETOPS_INSTANCE`, le plancher
|
# CE QUE CA A DONNE. En deployant un autre ecosysteme avec `SETOPS_INSTANCE`, le plancher
|
||||||
# /etc/hosts de `ops-01` a recu les FQDN de CHEZLEPRO -- auth.chezlepro.internal,
|
# /etc/hosts de `ops-01` a recu les FQDN de CHEZLEPRO -- auth.chezlepro.internal,
|
||||||
# forge.chezlepro.internal... -- pointes sur l'edge de patient 0. Un ecosysteme
|
# forge.chezlepro.internal... -- pointes sur l'edge de l'autre. Un ecosysteme
|
||||||
# annoncait les noms d'un autre. Neuf roles lisent cette variable ; le plancher est
|
# annoncait les noms d'un autre. Neuf roles lisent cette variable ; le plancher est
|
||||||
# simplement celui qui l'a rendu visible.
|
# simplement celui qui l'a rendu visible.
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
# Sans ce fichier, `client_pki` n'emet le certificat de l'edge qu'avec ses propres noms
|
# Sans ce fichier, `client_pki` n'emet le certificat de l'edge qu'avec ses propres noms
|
||||||
# (`infra-edge-01.genese.internal`), et nginx retombe sur le certificat auto-signe de
|
# (`infra-edge-01.genese.internal`), et nginx retombe sur le certificat auto-signe de
|
||||||
# Debian pour tout FQDN expose. Le service repond, la page s'affiche apres un
|
# Debian pour tout FQDN expose. Le service repond, la page s'affiche apres un
|
||||||
# avertissement — et rien ne signale la panne. C'est ce qui s'est passe ici : la forge de
|
# avertissement — et rien ne signale la panne. C'est ce qui s'est passe ici : une forge
|
||||||
# patient 0 etait publiee derriere un `ssl-cert-snakeoil.pem`, et `git clone` a ete le
|
# etait publiee derriere un `ssl-cert-snakeoil.pem`, et `git clone` a ete le
|
||||||
# premier a refuser, a juste titre.
|
# premier a refuser, a juste titre.
|
||||||
#
|
#
|
||||||
# Ce fichier appartient au MODELE parce que trois instances sur quatre le portaient
|
# Ce fichier appartient au MODELE parce que trois instances sur quatre le portaient
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ hosts_statiques_expositions: []
|
||||||
#
|
#
|
||||||
# LE PIÈGE, MESURÉ LE 2026-08-23. `forge.alliance-boreale.ca` résout vers 192.168.14.66
|
# LE PIÈGE, MESURÉ LE 2026-08-23. `forge.alliance-boreale.ca` résout vers 192.168.14.66
|
||||||
# depuis le poste d'administration, et vers 69.70.26.51 — l'adresse PUBLIQUE — depuis
|
# depuis le poste d'administration, et vers 69.70.26.51 — l'adresse PUBLIQUE — depuis
|
||||||
# l'overlay de patient 0, qui ne sait pas l'atteindre de l'intérieur (pas de retour en
|
# l'overlay d'un écosystème, qui ne sait pas l'atteindre de l'intérieur (pas de retour en
|
||||||
# épingle). Le clone initial du miroir avait pourtant réussi : la résolution n'est pas
|
# épingle). Le clone initial du miroir avait pourtant réussi : la résolution n'est pas
|
||||||
# stable, elle dépend du résolveur interrogé. Un miroir qui se synchronise toutes les
|
# stable, elle dépend du résolveur interrogé. Un miroir qui se synchronise toutes les
|
||||||
# huit heures serait tombé dessus tôt ou tard, et le silence aurait duré.
|
# huit heures serait tombé dessus tôt ou tard, et le silence aurait duré.
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
# n'atteint jamais la couche qui poserait le bon amont. Le correctif se retrouve dans la
|
# n'atteint jamais la couche qui poserait le bon amont. Le correctif se retrouve dans la
|
||||||
# couche que la panne empeche d'atteindre, et il faut une main pour en sortir.
|
# couche que la panne empeche d'atteindre, et il faut une main pour en sortir.
|
||||||
#
|
#
|
||||||
# C'est exactement ce qui est arrive : l'amont pointait sur le cache de patient 0, eteint
|
# C'est exactement ce qui est arrive : l'amont pointait sur le cache d'un autre ecosysteme, eteint
|
||||||
# la veille pour liberer de la RAM. `apt` rendait `503 Connection timeout` EN CITANT
|
# la veille pour liberer de la RAM. `apt` rendait `503 Connection timeout` EN CITANT
|
||||||
# L'ADRESSE DU CACHE LOCAL, jamais celle de l'amont manquant — la panne accusait le
|
# L'ADRESSE DU CACHE LOCAL, jamais celle de l'amont manquant — la panne accusait le
|
||||||
# maillon visible.
|
# maillon visible.
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ vivaient sur `backup-01`, une VM de sa propre flotte.** Raser l'écosystème aur
|
||||||
les données et leur seul filet dans le même geste.
|
les données et leur seul filet dans le même geste.
|
||||||
|
|
||||||
La doctrine affirmait pourtant que `client_backup_cible` *« pointe déjà hors de
|
La doctrine affirmait pourtant que `client_backup_cible` *« pointe déjà hors de
|
||||||
l'écosystème »*. C'était vrai pour patient 0, qui sauvegarde chez `eregion` — faux pour
|
l'écosystème »*. C'était faux pour
|
||||||
Chezlepro. *Un document qui décrit une propriété que le réel n'a pas est exactement ce que
|
Chezlepro. *Un document qui décrit une propriété que le réel n'a pas est exactement ce que
|
||||||
ce dépôt traque.*
|
ce dépôt traque.*
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
# CE QUE SON ABSENCE COÛTAIT (mesuré le 2026-09-01). Chezlepro sauvegardait sur
|
# CE QUE SON ABSENCE COÛTAIT (mesuré le 2026-09-01). Chezlepro sauvegardait sur
|
||||||
# `backup-01`, une VM de sa PROPRE flotte. Raser l'écosystème aurait détruit les données
|
# `backup-01`, une VM de sa PROPRE flotte. Raser l'écosystème aurait détruit les données
|
||||||
# et leur seul filet dans le même geste — et la doctrine affirmait pourtant que
|
# et leur seul filet dans le même geste — et la doctrine affirmait pourtant que
|
||||||
# `client_backup_cible` « pointe déjà hors de l'écosystème ». C'était vrai pour patient 0,
|
# `client_backup_cible` « pointe déjà hors de l'écosystème ». C'était faux pour
|
||||||
# faux pour Chezlepro.
|
# Chezlepro.
|
||||||
#
|
#
|
||||||
# `voisins_site` désigne les autres tenants que CE SITE héberge. Ni `flotte`, ni `externe` :
|
# `voisins_site` désigne les autres tenants que CE SITE héberge. Ni `flotte`, ni `externe` :
|
||||||
# un dépôt de sauvegarde ouvert à l'Internet serait la pire porte du site.
|
# un dépôt de sauvegarde ouvert à l'Internet serait la pire porte du site.
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
# AVANT le marqueur, dans le MÊME play, donc ses variables sont en portée. Et l'ordre
|
# AVANT le marqueur, dans le MÊME play, donc ses variables sont en portée. Et l'ordre
|
||||||
# cesse de dépendre de la façon dont on lance le déploiement.
|
# cesse de dépendre de la façon dont on lance le déploiement.
|
||||||
#
|
#
|
||||||
# Chez patient 0 les deux vivaient sur le même hôte et étaient appliqués ensemble : la
|
# Dans le premier écosystème les deux vivaient sur le même hôte et étaient appliqués ensemble : la
|
||||||
# dépendance existait déjà, elle n'était simplement écrite nulle part.
|
# dépendance existait déjà, elle n'était simplement écrite nulle part.
|
||||||
dependencies:
|
dependencies:
|
||||||
- role: serveur_artefacts
|
- role: serveur_artefacts
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
# CE RÔLE MARQUE UN CACHE ; IL N'EN INSTALLE PAS.
|
# CE RÔLE MARQUE UN CACHE ; IL N'EN INSTALLE PAS.
|
||||||
#
|
#
|
||||||
# Il présuppose `serveur_artefacts` sur le même hôte — c'est lui qui pose apt-cacher-ng —
|
# Il présuppose `serveur_artefacts` sur le même hôte — c'est lui qui pose apt-cacher-ng —
|
||||||
# et lit ses variables. Chez patient 0 les deux vivaient sur `forge-01`, donc la
|
# et lit ses variables. Dans le premier écosystème les deux vivaient sur `forge-01`, donc la
|
||||||
# dépendance ne se voyait pas. La première machine à ne porter que le marqueur l'a
|
# dépendance ne se voyait pas. La première machine à ne porter que le marqueur l'a
|
||||||
# révélée, et le message était : « variable non définie : `serveur_artefacts_port` ».
|
# révélée, et le message était : « variable non définie : `serveur_artefacts_port` ».
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -105,8 +105,8 @@ serveur_forgejo_oidc_discovery: >-
|
||||||
#
|
#
|
||||||
# POURQUOI CE CHOIX EXISTE (2026-08-22). Une offre `forge` pour un petit organisme
|
# POURQUOI CE CHOIX EXISTE (2026-08-22). Une offre `forge` pour un petit organisme
|
||||||
# exigeait une VM PostgreSQL entiere — un serveur, une zone, un secret, une sauvegarde —
|
# exigeait une VM PostgreSQL entiere — un serveur, une zone, un secret, une sauvegarde —
|
||||||
# pour une base que trois personnes sollicitent. Le premier ecosysteme a en avoir profite
|
# pour une base que trois personnes sollicitent. Moins de surface, aussi, sur une forge
|
||||||
# est patient 0, qui porte le genome : moins de surface sur la machine dont tout descend.
|
# qui porte le genome : c'est la machine dont tout descend.
|
||||||
#
|
#
|
||||||
# CE QUE `sqlite` CHANGE AILLEURS : rien a la sauvegarde — le job `serveur_forgejo` de
|
# CE QUE `sqlite` CHANGE AILLEURS : rien a la sauvegarde — le job `serveur_forgejo` de
|
||||||
# `client_backup` emporte deja `serveur_forgejo_data`, ou le fichier se trouve. Et rien
|
# `client_backup` emporte deja `serveur_forgejo_data`, ou le fichier se trouve. Et rien
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@
|
||||||
|
|
||||||
- name: Creer le compte administrateur (une fois)
|
- name: Creer le compte administrateur (une fois)
|
||||||
# `--must-change-password=false` : SANS LUI, LE COMPTE EST INUTILISABLE (2026-08-23,
|
# `--must-change-password=false` : SANS LUI, LE COMPTE EST INUTILISABLE (2026-08-23,
|
||||||
# premiere forge de patient 0). Forgejo exige par defaut un changement de mot de passe
|
# premiere forge d'un ecosysteme). Forgejo exige par defaut un changement de mot de passe
|
||||||
# au premier acces, et refuse TOUTE requete d'API tant qu'il n'a pas eu lieu :
|
# au premier acces, et refuse TOUTE requete d'API tant qu'il n'a pas eu lieu :
|
||||||
# « You must change your password ». Or ce role desactive la connexion locale
|
# « You must change your password ». Or ce role desactive la connexion locale
|
||||||
# (`serveur_forgejo_connexion_locale: false`, SSO d'abord) — il n'existait donc aucun
|
# (`serveur_forgejo_connexion_locale: false`, SSO d'abord) — il n'existait donc aucun
|
||||||
|
|
@ -438,7 +438,7 @@
|
||||||
# ON VERIFIE L'ETAT, ON NE FAIT PAS CONFIANCE AU DRAPEAU (2026-08-25).
|
# ON VERIFIE L'ETAT, ON NE FAIT PAS CONFIANCE AU DRAPEAU (2026-08-25).
|
||||||
#
|
#
|
||||||
# La creation passe deja `--must-change-password=false` — corrige le 2026-08-23, sur la
|
# La creation passe deja `--must-change-password=false` — corrige le 2026-08-23, sur la
|
||||||
# premiere forge de patient 0. **Forgejo 16 l'a ignore** : le compte de la forge du SITE
|
# premiere forge d'un ecosysteme. **Forgejo 16 l'a ignore** : le compte de la forge du SITE
|
||||||
# est ne avec le drapeau POSE malgre l'option.
|
# est ne avec le drapeau POSE malgre l'option.
|
||||||
#
|
#
|
||||||
# La panne qui en resulte n'accuse rien de juste : toute requete d'API rend **403**, pas
|
# La panne qui en resulte n'accuse rien de juste : toute requete d'API rend **403**, pas
|
||||||
|
|
|
||||||
|
|
@ -90,8 +90,8 @@ serveur_ops_forge_amont_ac_depot: "{{ serveur_ops_racine }}/.ac-amont.crt"
|
||||||
#
|
#
|
||||||
# AUCUN DÉFAUT NE NOMME UN ÉCOSYSTÈME PARTICULIER (2026-08-24).
|
# AUCUN DÉFAUT NE NOMME UN ÉCOSYSTÈME PARTICULIER (2026-08-24).
|
||||||
#
|
#
|
||||||
# La première version listait ici `ops-patient0`. Tout écosystème qui aurait déployé un
|
# La première version listait ici le dépôt d'un écosystème précis. Tout écosystème qui aurait
|
||||||
# poste sans déclarer ses propres dépôts aurait donc cloné le génome de **patient 0** —
|
# déployé un poste sans déclarer ses propres dépôts aurait donc cloné le génome d'un **autre** —
|
||||||
# silencieusement, et en croyant piloter le sien. C'est la faute que ce dépôt combat sous
|
# silencieusement, et en croyant piloter le sien. C'est la faute que ce dépôt combat sous
|
||||||
# tous ses déguisements : un défaut plausible qui rend un résultat faux sans rien dire.
|
# tous ses déguisements : un défaut plausible qui rend un résultat faux sans rien dire.
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
# UN POSTE QUI NE SAIT PAS SUR QUOI IL TRAVAILLE N'A RIEN À PILOTER.
|
# UN POSTE QUI NE SAIT PAS SUR QUOI IL TRAVAILLE N'A RIEN À PILOTER.
|
||||||
#
|
#
|
||||||
# On exige explicitement ce qu'il pilote, plutôt que de retomber sur un défaut : le
|
# On exige explicitement ce qu'il pilote, plutôt que de retomber sur un défaut : le
|
||||||
# défaut nommait patient 0, et un écosystème distrait aurait cloné le génome d'un autre
|
# défaut nommait un écosystème précis, et un écosystème distrait aurait cloné le génome d'un autre
|
||||||
# sans qu'aucune erreur ne le signale.
|
# sans qu'aucune erreur ne le signale.
|
||||||
#
|
#
|
||||||
# DEUX FORMES DE RUNNER, ET UNE SEULE ÉTAIT PRÉVUE (2026-08-25).
|
# DEUX FORMES DE RUNNER, ET UNE SEULE ÉTAIT PRÉVUE (2026-08-25).
|
||||||
|
|
@ -318,7 +318,7 @@
|
||||||
#
|
#
|
||||||
# UN POSTE D'EXPLOITATION QUI APPELLE galaxy.ansible.com POUR SE CONSTRUIRE N'EST PAS
|
# UN POSTE D'EXPLOITATION QUI APPELLE galaxy.ansible.com POUR SE CONSTRUIRE N'EST PAS
|
||||||
# SOUVERAIN. Mesure du 2026-08-23, premier deploiement : `ansible-galaxy collection
|
# SOUVERAIN. Mesure du 2026-08-23, premier deploiement : `ansible-galaxy collection
|
||||||
# install` a echoue depuis l'overlay de patient 0 —
|
# install` a echoue depuis l'overlay d'un écosystème —
|
||||||
# `SSL: UNEXPECTED_EOF_WHILE_READING` — parce que la frontiere ne laisse pas passer ce
|
# `SSL: UNEXPECTED_EOF_WHILE_READING` — parce que la frontiere ne laisse pas passer ce
|
||||||
# flux, et c'est tres bien ainsi. Ouvrir une regle vers un serveur americain pour que
|
# flux, et c'est tres bien ainsi. Ouvrir une regle vers un serveur americain pour que
|
||||||
# l'ecosysteme sache se reconstruire aurait ete la mauvaise reponse.
|
# l'ecosysteme sache se reconstruire aurait ete la mauvaise reponse.
|
||||||
|
|
|
||||||
|
|
@ -849,8 +849,8 @@ def construire(tenants: list[tuple[str, str, dict]]) -> dict:
|
||||||
# un droit d'entree general. Et la regle ne suffit pas a lire : sans la cle TSIG de
|
# un droit d'entree general. Et la regle ne suffit pas a lire : sans la cle TSIG de
|
||||||
# sa relation, le primaire refuse le transfert.
|
# sa relation, le primaire refuse le transfert.
|
||||||
# SEULEMENT LES LOCATAIRES QUI PUBLIENT (resserre le 2026-09-16). La premiere
|
# SEULEMENT LES LOCATAIRES QUI PUBLIENT (resserre le 2026-09-16). La premiere
|
||||||
# version prenait l'autoritatif de TOUS les locataires du site : Patient0, qui n'a
|
# version prenait l'autoritatif de TOUS les locataires du site : un locataire sans
|
||||||
# aucune zone publique, recevait une ouverture 5300 depuis le serveur public. Rien
|
# zone publique recevait une ouverture 5300 depuis le serveur public. Rien
|
||||||
# n'y ecoutait — mais un chemin ouvert vers une machine qui n'en a pas besoin est
|
# n'y ecoutait — mais un chemin ouvert vers une machine qui n'en a pas besoin est
|
||||||
# exactement ce que le moindre privilege refuse.
|
# exactement ce que le moindre privilege refuse.
|
||||||
def _publie(_nom_tenant: str) -> bool:
|
def _publie(_nom_tenant: str) -> bool:
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ def placement_du_tenant() -> tuple[dict, Path | None]:
|
||||||
"""Les valeurs de placement declarees par le tenant VISE.
|
"""Les valeurs de placement declarees par le tenant VISE.
|
||||||
|
|
||||||
SETOPS_INSTANCE d'abord ; le symlink `instance/` n'en est que le cas courant. Code en
|
SETOPS_INSTANCE d'abord ; le symlink `instance/` n'en est que le cas courant. Code en
|
||||||
dur, il rendait ce devis incapable de regarder un AUTRE tenant : viser patient 0
|
dur, il rendait ce devis incapable de regarder un AUTRE tenant : viser un autre tenant
|
||||||
mesurait en silence le placement de l'instance montee, et rendait un verdict juste
|
mesurait en silence le placement de l'instance montee, et rendait un verdict juste
|
||||||
pour le mauvais tenant (mesure du 2026-08-20 — les deux avaient les memes quatre
|
pour le mauvais tenant (mesure du 2026-08-20 — les deux avaient les memes quatre
|
||||||
valeurs, ce qui est exactement la circonstance ou l'erreur ne se voit pas).
|
valeurs, ce qui est exactement la circonstance ou l'erreur ne se voit pas).
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
CE QUE CE SCRIPT PROTEGE, ET POURQUOI C'EST LE PLUS URGENT (mesure du 2026-09-05).
|
CE QUE CE SCRIPT PROTEGE, ET POURQUOI C'EST LE PLUS URGENT (mesure du 2026-09-05).
|
||||||
|
|
||||||
Le CODE de Set-OPS est replique trois fois : `eregion`, la forge du site, patient 0. Les
|
Le CODE de Set-OPS est replique deux fois : `eregion` et la forge du site. Les
|
||||||
voutes chiffrees y sont aussi — le coffre est solide.
|
voutes chiffrees y sont aussi — le coffre est solide.
|
||||||
|
|
||||||
Les CLES qui ouvrent ce coffre, elles, vivent dans six fichiers de `~/.config`, 357
|
Les CLES qui ouvrent ce coffre, elles, vivent dans six fichiers de `~/.config`, 357
|
||||||
|
|
|
||||||
|
|
@ -272,8 +272,7 @@ def integrations_de(srv: dict, services_hote: set[str] | None = None,
|
||||||
UNIVERSELLE N'EST POSEE QUE SI SON SERVICE CENTRAL EXISTE ICI (2026-08-22).
|
UNIVERSELLE N'EST POSEE QUE SI SON SERVICE CENTRAL EXISTE ICI (2026-08-22).
|
||||||
|
|
||||||
Pourquoi cette regle a manque. « Tout hote est mesure » est vrai dans un ecosysteme qui
|
Pourquoi cette regle a manque. « Tout hote est mesure » est vrai dans un ecosysteme qui
|
||||||
porte un Prometheus. Dans un ecosysteme qui n'en a pas — un patient 0 minimal, une
|
porte un Prometheus. Dans un ecosysteme qui n'en a pas — une petite offre — la meme phrase pose sur chaque machine un client qui n'a personne a qui
|
||||||
petite offre — la meme phrase pose sur chaque machine un client qui n'a personne a qui
|
|
||||||
parler, et le controle de dependances refuse le deploiement. Le moteur supposait
|
parler, et le controle de dependances refuse le deploiement. Le moteur supposait
|
||||||
l'ecosysteme COMPLET ; c'est la troisieme fois que cette hypothese se paie, apres les
|
l'ecosysteme COMPLET ; c'est la troisieme fois que cette hypothese se paie, apres les
|
||||||
intrants (P32) et les bases (P35).
|
intrants (P32) et les bases (P35).
|
||||||
|
|
|
||||||
|
|
@ -1072,7 +1072,7 @@ def preuve_base_par_consommateur() -> tuple[bool, str]:
|
||||||
"""
|
"""
|
||||||
# INSTANCE, pas le symlink en dur : sans cela cette preuve mesurait toujours
|
# INSTANCE, pas le symlink en dur : sans cela cette preuve mesurait toujours
|
||||||
# l'instance montee, quelle que soit celle qu'on visait (2026-08-22, en verifiant
|
# l'instance montee, quelle que soit celle qu'on visait (2026-08-22, en verifiant
|
||||||
# patient 0 — elle a rendu un verdict juste sur le mauvais ecosysteme).
|
# un autre ecosysteme — elle a rendu un verdict juste sur le mauvais ecosysteme).
|
||||||
plan = INSTANCE / "plan"
|
plan = INSTANCE / "plan"
|
||||||
if not (plan / "bases-donnees.yml").is_file():
|
if not (plan / "bases-donnees.yml").is_file():
|
||||||
return True, "Aucun registre de bases : rien a verifier."
|
return True, "Aucun registre de bases : rien a verifier."
|
||||||
|
|
@ -1475,7 +1475,7 @@ def preuve_resolution_unique() -> tuple[bool, str]:
|
||||||
def preuve_edge_porte_ses_noms() -> tuple[bool, str]:
|
def preuve_edge_porte_ses_noms() -> tuple[bool, str]:
|
||||||
"""Tout ecosysteme qui PUBLIE des noms sert un certificat qui les porte.
|
"""Tout ecosysteme qui PUBLIE des noms sert un certificat qui les porte.
|
||||||
|
|
||||||
POURQUOI CETTE PREUVE EXISTE (2026-08-23). L'edge de patient 0 publiait sa forge
|
POURQUOI CETTE PREUVE EXISTE (2026-08-23). L'edge d'un ecosysteme publiait sa forge
|
||||||
derriere `ssl-cert-snakeoil.pem` — le certificat auto-signe de Debian. Le service
|
derriere `ssl-cert-snakeoil.pem` — le certificat auto-signe de Debian. Le service
|
||||||
repondait, la page s'affichait apres un avertissement, `make prouver` etait vert :
|
repondait, la page s'affichait apres un avertissement, `make prouver` etait vert :
|
||||||
rien, nulle part, ne signalait que la publication n'etait pas de confiance. Le premier
|
rien, nulle part, ne signalait que la publication n'etait pas de confiance. Le premier
|
||||||
|
|
@ -3905,8 +3905,8 @@ def preuve_amorcage_suit_le_site() -> tuple[bool, str]:
|
||||||
a quinze couches de sa cause.
|
a quinze couches de sa cause.
|
||||||
|
|
||||||
CE QUE CETTE PREUVE NE FAIT PAS : juger une adresse qui ne designe pas le site. Un
|
CE QUE CETTE PREUVE NE FAIT PAS : juger une adresse qui ne designe pas le site. Un
|
||||||
tenant peut legitimement s'amorcer sur un resolveur public — `OPS-Technolibre` et
|
tenant peut legitimement s'amorcer sur un resolveur public — `OPS-Technolibre`
|
||||||
`OPS-Patient0` visent `9.9.9.9`, et c'est un choix, pas un oubli. On ne verifie que
|
vise `9.9.9.9`, et c'est un choix, pas un oubli. On ne verifie que
|
||||||
les valeurs qui PRETENDENT designer une machine du site : meme troisieme octet de
|
les valeurs qui PRETENDENT designer une machine du site : meme troisieme octet de
|
||||||
zone, autre deuxieme octet. Une adresse etrangere au site n'est pas notre affaire.
|
zone, autre deuxieme octet. Une adresse etrangere au site n'est pas notre affaire.
|
||||||
"""
|
"""
|
||||||
|
|
@ -4227,7 +4227,7 @@ def preuve_remise_tenue() -> tuple[bool, str]:
|
||||||
des empreintes, jamais des valeurs.
|
des empreintes, jamais des valeurs.
|
||||||
|
|
||||||
CE QU'ELLE NE JUGE PAS. Un ecosysteme SANS registre : tous ne sont pas remis, et
|
CE QU'ELLE NE JUGE PAS. Un ecosysteme SANS registre : tous ne sont pas remis, et
|
||||||
plusieurs ne le seront jamais — le lab, patient 0, l'ecosysteme de l'hebergeur
|
plusieurs ne le seront jamais — le lab, l'ecosysteme de l'hebergeur
|
||||||
lui-meme. Exiger un registre partout ferait du bruit la ou il n'y a rien a tenir.
|
lui-meme. Exiger un registre partout ferait du bruit la ou il n'y a rien a tenir.
|
||||||
|
|
||||||
ET CE QU'ELLE NE PEUT PAS PROUVER : que l'hebergeur ne puisse PLUS entrer. Le plan
|
ET CE QU'ELLE NE PEUT PAS PROUVER : que l'hebergeur ne puisse PLUS entrer. Le plan
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
POURQUOI CE SCRIPT DOIT POUVOIR VIVRE SUR LA CLE USB.
|
POURQUOI CE SCRIPT DOIT POUVOIR VIVRE SUR LA CLE USB.
|
||||||
|
|
||||||
Le jour ou l'on s'en sert, le poste est mort. Le depot Set-OPS est replique — eregion, la
|
Le jour ou l'on s'en sert, le poste est mort. Le depot Set-OPS est replique — eregion et la
|
||||||
forge du site, patient 0 — mais le CLONER demande la cle SSH, qui est justement dans
|
forge du site — mais le CLONER demande la cle SSH, qui est justement dans
|
||||||
l'archive qu'on essaie d'ouvrir. Une procedure de restauration qui vit dans le depot
|
l'archive qu'on essaie d'ouvrir. Une procedure de restauration qui vit dans le depot
|
||||||
serait donc inaccessible exactement quand elle sert.
|
serait donc inaccessible exactement quand elle sert.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -289,8 +289,7 @@ règles. Un par écosystème.
|
||||||
## L'état, et sa preuve
|
## L'état, et sa preuve
|
||||||
|
|
||||||
**SQLite** — Une base de données qui tient dans **un fichier**, sans serveur ni compte.
|
**SQLite** — Une base de données qui tient dans **un fichier**, sans serveur ni compte.
|
||||||
Suffisante pour une petite forge — c'est ce que portait patient 0, dont les machines
|
Suffisante pour une petite forge. À l'inverse de
|
||||||
n'existent plus. À l'inverse de
|
|
||||||
*PostgreSQL*, qui est un service à part entière — un serveur, une zone, un secret.
|
*PostgreSQL*, qui est un service à part entière — un serveur, une zone, un secret.
|
||||||
|
|
||||||
**restic** — L'outil de sauvegarde chiffrée et dédupliquée. Cf. [Sauvegardes](Sauvegardes).
|
**restic** — L'outil de sauvegarde chiffrée et dédupliquée. Cf. [Sauvegardes](Sauvegardes).
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ parce que de l'intérieur d'un fichier, la copie locale a toujours l'air correct
|
||||||
|
|
||||||
### Ce que ça donnait
|
### Ce que ça donnait
|
||||||
|
|
||||||
`make placement-plan` visait patient 0 et répondait :
|
`make placement-plan` visait un autre tenant et répondait :
|
||||||
|
|
||||||
```
|
```
|
||||||
Devis du placement — tenant « instance »
|
Devis du placement — tenant « instance »
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue