wiki : chaque runner publie pour SA forge
J allais centraliser — un controleur poussant vers N forges, un temoin portant une liste. Ca aurait demande un acces sur chaque forge depuis un seul poste, et fait du temoin un fait global que personne ne detient. Le modele suit la ligne du reste : chacun sert les siens. Sans WIKI_REMOTE, l adresse se derive du nom que le plan monte expose pour serveur_forgejo. Deux notions a ne pas confondre : la forge AMONT ou l on LIT le genome, et MA forge ou l on SERT les siens. Le runner d un locataire lit chez son hebergeur et sert chez lui. WIKI_REMOTE l emporte toujours : le poste du mainteneur n est le runner d aucun ecosysteme et publie vers le domicile public du projet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
This commit is contained in:
parent
70193af24d
commit
8574b7b540
3 changed files with 104 additions and 9 deletions
30
Makefile
30
Makefile
|
|
@ -821,17 +821,33 @@ schema: ## Regenere docs/audit/schema-plan.json depuis les registres et les vali
|
|||
|
||||
.PHONY: wiki-publier
|
||||
wiki-publier: ## Publie le wiki (wiki/) vers la forge
|
||||
@# CHAQUE RUNNER PUBLIE POUR SA FORGE (2026-09-14). Sans `WIKI_REMOTE`, l'adresse se
|
||||
@# DERIVE de l'ecosysteme monte : le nom que son plan expose pour `serveur_forgejo`.
|
||||
@#
|
||||
@# DEUX NOTIONS A NE PAS CONFONDRE. La forge AMONT est celle ou l'on LIT le genome ; MA
|
||||
@# forge est celle ou l'on SERT les siens. Le runner d'un locataire lit chez son
|
||||
@# hebergeur et sert chez lui — un employe de TechnoLibre lit la forge de TechnoLibre.
|
||||
@#
|
||||
@# `WIKI_REMOTE` L'EMPORTE TOUJOURS, et c'est necessaire : le poste du mainteneur n'est
|
||||
@# le runner d'aucun ecosysteme, et publie vers le domicile PUBLIC du projet, qui n'est
|
||||
@# la forge d'aucun plan.
|
||||
@set -e; \
|
||||
if [[ -z "$(WIKI_REMOTE)" ]]; then \
|
||||
printf '%s\n' 'Refus: URL du wiki Forgejo requise.'; \
|
||||
printf '%s\n' 'Ex: make wiki-publier WIKI_REMOTE=https://forge.<domaine>/<proprio>/<depot>.wiki.git'; \
|
||||
remote="$$remote"; \
|
||||
if [[ -z "$$remote" ]]; then \
|
||||
remote="$$(python3 scripts/ma_forge.py 2>/dev/null || true)"; \
|
||||
fi; \
|
||||
if [[ -z "$$remote" ]]; then \
|
||||
printf '%s\n' 'Refus: aucune forge — ni WIKI_REMOTE, ni derivable du plan monte.'; \
|
||||
python3 scripts/ma_forge.py >/dev/null || true; \
|
||||
printf '%s\n' 'Ex: make wiki-publier WIKI_REMOTE=ssh://git@forge.<domaine>/<proprio>/<depot>.wiki.git'; \
|
||||
exit 2; \
|
||||
fi; \
|
||||
printf 'Forge visee : %s\n' "$$remote"; \
|
||||
src="$(CURDIR)/wiki"; \
|
||||
tmp="$$(mktemp -d)"; \
|
||||
trap 'rm -rf "$$tmp"' EXIT; \
|
||||
printf '%s\n' "Clonage du wiki: $(WIKI_REMOTE)"; \
|
||||
if ! git clone --quiet --depth 1 "$(WIKI_REMOTE)" "$$tmp/wiki"; then \
|
||||
printf '%s\n' "Clonage du wiki: $$remote"; \
|
||||
if ! git clone --quiet --depth 1 "$$remote" "$$tmp/wiki"; then \
|
||||
printf '%s\n' 'Echec du clone (URL ou acces ?). Le wiki doit exister (creer une 1re page dans Forgejo).'; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
|
|
@ -861,7 +877,7 @@ wiki-publier: ## Publie le wiki (wiki/) vers la forge
|
|||
'le wiki deja en service vit sur `main`. Deux issues :' \
|
||||
' - demander a Forgejo : GET /api/v1/repos/<proprio>/<depot> -> `wiki_branch`,' \
|
||||
' puis make wiki-publier WIKI_REMOTE=... WIKI_BRANCHE=<cette valeur>' \
|
||||
" - ou creer une premiere page dans l interface Forgejo de $(WIKI_REMOTE)"; \
|
||||
" - ou creer une premiere page dans l interface Forgejo de $$remote"; \
|
||||
exit 2; \
|
||||
fi; \
|
||||
fi; \
|
||||
|
|
@ -895,7 +911,7 @@ wiki-publier: ## Publie le wiki (wiki/) vers la forge
|
|||
: ' APRES le push : un temoin ne doit jamais dire qu on a publie si on a echoue.'; \
|
||||
{ printf '%s\n' '---' \
|
||||
'# Ecrit par `make wiki-publier`, lu par la preuve P60. Ne pas editer a la main.' \
|
||||
"remote: $(WIKI_REMOTE)" \
|
||||
"remote: $$remote" \
|
||||
"source: $$sha" \
|
||||
"date: $$(date +%F)"; } > "$(CURDIR)/docs/audit/wiki-publie.yml"; \
|
||||
printf '%s\n' 'Temoin depose : docs/audit/wiki-publie.yml (a committer).'
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
| P28 | Pools Proxmox : un par tenant, sans collision | AFF-110 | ✅ OK | CONFORME : 5 pool(s) Proxmox, 44 VM placee(s), aucun nom ni VMID en collision. |
|
||||
| P29 | Authentification : chaque role declare sa position | AFF-111 | ✅ OK | 33 role(s) serveur declares (interne-sans-auth 2, ldap-direct 2, sans-auth-humaine 22, socle-identite 2, web-sso 5) ; 2 lacune(s) nommee(s) : serveur_loki, serv |
|
||||
| P30 | SDN EVPN : zones, VNets et sous-reseaux derives | AFF-112 | ✅ OK | CONFORME : SDN EVPN, 3 zone(s), 15 VNet(s), 15 sous-reseau(x), aucune collision. |
|
||||
| P31 | Documentation : tout ce que le depot FAIT est nomme | — | ✅ OK | 66 scripts expliques et atteignables, 123 cibles make documentees, 68 roles avec README. |
|
||||
| P31 | Documentation : tout ce que le depot FAIT est nomme | — | ✅ OK | 67 scripts expliques et atteignables, 123 cibles make documentees, 68 roles avec README. |
|
||||
| P32 | Intrants exiges par les roles : tous fournis | — | ✅ OK | CONFORME : 38 exigence(s) de role, toutes satisfaites (149 cle(s) declaree(s) par l'instance). |
|
||||
| P33 | Aucune collision de port entre roles co-localises | — | ✅ OK | CONFORME : 35 revendication(s) de port, aucune collision entre roles co-localises (36 groupes). |
|
||||
| P34 | Chaque document declare son lecteur | — | ✅ OK | 46 document(s) declarent leur lecteur (40 genere(s) exempte(s)). |
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
| P38 | Catalogue des services : la carte dit ce que le moteur fait | — | ✅ OK | Catalogue a jour : 41 role(s) serveur/client tous nommes, 41 groupe(s) cite(s) en table existent tous. |
|
||||
| P39 | Glossaire : tout mot employe est enseigne | — | ✅ OK | Glossaire complet : 81 terme(s) du jargon expliques, 15 lien(s) valides, 96 page(s) de wiki toutes atteignables. |
|
||||
| P40 | Parente : l'ecosysteme sait de quoi il descend | — | ✅ OK | Parente coherente : 4 depot(s), tous retrouves, tous porteurs d'un remote. |
|
||||
| P41 | Resolution d'instance : une seule, partagee | — | ✅ OK | Resolution unique : 62 script(s) passent par `inventory_rules`, 3 exemption(s) nommee(s). |
|
||||
| P41 | Resolution d'instance : une seule, partagee | — | ✅ OK | Resolution unique : 63 script(s) passent par `inventory_rules`, 3 exemption(s) nommee(s). |
|
||||
| P42 | L'edge porte les noms qu'il publie | — | ✅ OK | 5 edge(s) emettent un certificat portant les noms publies (instance-ci-1646753/production, OPS-Chezlepro-lab/principal, OPS-Chezlepro/principal, OPS-Technolibre |
|
||||
| P43 | Frontiere : le devis voit les machines du site | — | ✅ OK | Devis de la frontiere : 7 machine(s) du plan retrouvees, 154 regle(s) du site. |
|
||||
| P44 | Integrations : le serveur avant ses clients | — | ✅ OK | 5 integration(s) appliquent leur serveur avant leurs clients. |
|
||||
|
|
|
|||
79
scripts/ma_forge.py
Executable file
79
scripts/ma_forge.py
Executable file
|
|
@ -0,0 +1,79 @@
|
|||
#!/usr/bin/env python3
|
||||
"""L'adresse du wiki de MA forge — celle de l'ecosysteme monte.
|
||||
|
||||
CHAQUE RUNNER PUBLIE POUR SA FORGE (decide le 2026-09-14).
|
||||
|
||||
La premiere idee etait qu'un controleur pousse vers plusieurs forges, avec un temoin
|
||||
portant une liste. Elle CENTRALISAIT : un seul poste aurait eu besoin d'un acces sur
|
||||
chaque forge, et le temoin serait devenu un fait global que personne ne detient.
|
||||
|
||||
Le modele retenu suit la ligne du reste du systeme — les voutes, les runners, les
|
||||
sauvegardes : **chacun sert les siens**. Le runner du site publie sur la forge du site ;
|
||||
celui d'un locataire sur la forge de ce locataire. Un employe de TechnoLibre lit la forge
|
||||
de TechnoLibre, pas celle de son hebergeur.
|
||||
|
||||
DEUX NOTIONS A NE PAS CONFONDRE, et c'est ce qui a rendu le sujet trouble :
|
||||
|
||||
la forge AMONT (`serveur_ops_forge_amont`) ou je LIS le genome
|
||||
MA forge (derivee ici) ou je SERS les miens
|
||||
|
||||
Le runner d'un locataire lit sur la forge du SITE et sert sur la SIENNE. Les deux adresses
|
||||
different, et le wiki appartient a la seconde.
|
||||
|
||||
CE QUI N'EST PAS DERIVABLE, ET C'EST DIT PLUTOT QUE DEVINE : le poste du mainteneur n'est
|
||||
le runner d'aucun ecosysteme. Il publie vers le domicile PUBLIC du projet, qui n'est la
|
||||
forge d'aucun plan. La, `WIKI_REMOTE` reste explicite — et il l'emporte toujours.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
RACINE = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(RACINE / "scripts"))
|
||||
|
||||
|
||||
def ma_forge() -> tuple[str | None, str]:
|
||||
"""(url du wiki, explication). `None` quand rien n'est derivable."""
|
||||
try:
|
||||
from inventory_rules import charger_applications, instance_courante
|
||||
except Exception as e:
|
||||
return None, f"moteur illisible ({e.__class__.__name__})"
|
||||
|
||||
inst = instance_courante()
|
||||
if not inst:
|
||||
return None, "aucune instance montee"
|
||||
|
||||
# `charger_applications` VEUT UN CHEMIN, pas rien. L'appeler sans argument levait un
|
||||
# `TypeError` que le `except` transformait en « plan illisible » — un message poli pour
|
||||
# une faute de programmation. Le voila nomme.
|
||||
try:
|
||||
apps = (charger_applications(Path(inst) / "plan" / "applications.yml")
|
||||
or {}).get("applications") or {}
|
||||
except (OSError, ValueError) as e:
|
||||
return None, f"plan illisible ({e.__class__.__name__})"
|
||||
|
||||
# LE NOM DU SERVICE, PAS CELUI DE LA MACHINE. Un FQDN expose survit au demenagement du
|
||||
# service ; `forge-01` non. C'est la meme regle que partout ailleurs dans ce depot.
|
||||
for nom, app in (apps.items() if isinstance(apps, dict) else []):
|
||||
if str((app or {}).get("groupe")) != "serveur_forgejo":
|
||||
continue
|
||||
exposes = (app or {}).get("expose") or []
|
||||
if not exposes:
|
||||
return None, "`serveur_forgejo` est au plan mais n'expose aucun nom"
|
||||
fqdn = str(exposes[0])
|
||||
depot = RACINE.name.lower()
|
||||
return (f"ssh://git@{fqdn}/genome/{depot}.wiki.git",
|
||||
f"forge de l'ecosysteme monte ({Path(inst).resolve().name}), exposee en {fqdn}")
|
||||
|
||||
return None, f"{Path(inst).resolve().name} ne declare aucun `serveur_forgejo`"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
url, pourquoi = ma_forge()
|
||||
if url:
|
||||
print(url)
|
||||
print(f"note : {pourquoi}", file=sys.stderr)
|
||||
raise SystemExit(0)
|
||||
print(f"note : pas de forge derivable — {pourquoi}", file=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
Loading…
Reference in a new issue