fix(ci): rétention registre compatible index OCI — fin du GC destructeur #33

Merged
kevin merged 1 commit from fix/registry-gc-multiarch into main 2026-07-21 15:55:59 +00:00
Owner

Incident (4e incident registre — 2026-07-21)

Le registre entier est impullable : tous les tags de gungnir ET gungnir-updater (y compris latest et le 5.134.1 publié la veille) servent des index OCI dont le manifest enfant amd64 répond 404. Découvert par la migration de l'install Yannick (migrate.sh 5.134.1 → content at …manifests/sha256:334fa6… not found). La prod n'est pas touchée (elle build en local), mais aucun self-hosteur ne peut pull.

Cause racine

Nos images sont des index OCI multi-manifest (BuildKit : manifest amd64 + manifest d'attestation). L'étape « Rétention du registre » (ajoutée au 3e incident disque, 07-17) termine par garbage-collect --delete-untagged — or ce mode traite les manifests enfants d'un index comme « untagged » (ils sont référencés par l'index, jamais par un tag) et les détruit. Chaque release depuis le 17-07 éventrait donc tout le registre, y compris l'image qu'elle venait de publier 30 secondes avant.

Fix (3 règles gravées en commentaire du workflow)

  1. Plus jamais --delete-untagged sur un registre qui sert du multi-manifest — GC simple des blobs orphelins.
  2. La rétention supprime elle-même les enfants des index évincés (sans ça leurs revisions pinent les blobs → la rétention ne libérerait plus rien).
  3. Le keep-set inclut les enfants des index gardés — un digest partagé entre versions (cas typique de l'updater, qui change rarement) reste protégé.

Validé : YAML parse + bash -n du bloc extrait ; helper children() testé contre le vrai registre (index → 2 digests, 404 → vide propre).

Réparation du contenu détruit

Le contenu est perdu (manifests + blobs GC-és) : la release suivante re-publie les deux images et restaure un registre pullable. Les cadavres 5.132→5.134.1 restent listés mais impullables (personne ne pin ces versions ; ils sortiront de la fenêtre KEEP=3 au fil des releases).

🤖 Generated with Claude Code

## Incident (4e incident registre — 2026-07-21) **Le registre entier est impullable** : tous les tags de `gungnir` ET `gungnir-updater` (y compris `latest` et le 5.134.1 publié la veille) servent des index OCI dont le manifest enfant amd64 répond 404. Découvert par la migration de l'install Yannick (`migrate.sh 5.134.1` → `content at …manifests/sha256:334fa6… not found`). La prod n'est pas touchée (elle build en local), mais aucun self-hosteur ne peut pull. ## Cause racine Nos images sont des **index OCI multi-manifest** (BuildKit : manifest amd64 + manifest d'attestation). L'étape « Rétention du registre » (ajoutée au 3e incident disque, 07-17) termine par `garbage-collect --delete-untagged` — or ce mode traite les manifests **enfants** d'un index comme « untagged » (ils sont référencés par l'index, jamais par un tag) et les **détruit**. Chaque release depuis le 17-07 éventrait donc tout le registre, y compris l'image qu'elle venait de publier 30 secondes avant. ## Fix (3 règles gravées en commentaire du workflow) 1. **Plus jamais `--delete-untagged`** sur un registre qui sert du multi-manifest — GC simple des blobs orphelins. 2. La rétention supprime **elle-même les enfants** des index évincés (sans ça leurs revisions pinent les blobs → la rétention ne libérerait plus rien). 3. Le keep-set inclut les **enfants des index gardés** — un digest partagé entre versions (cas typique de l'updater, qui change rarement) reste protégé. Validé : YAML parse + `bash -n` du bloc extrait ; helper `children()` testé contre le vrai registre (index → 2 digests, 404 → vide propre). ## Réparation du contenu détruit Le contenu est perdu (manifests + blobs GC-és) : la **release suivante** re-publie les deux images et restaure un registre pullable. Les cadavres 5.132→5.134.1 restent listés mais impullables (personne ne pin ces versions ; ils sortiront de la fenêtre KEEP=3 au fil des releases). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(ci): rétention registre compatible index OCI — fin du GC destructeur
All checks were successful
CI / Backend — pytest (pull_request) Successful in 44s
CI / i18n — usage → locales (pull_request) Successful in 5s
87ac20c495
Le garbage-collect --delete-untagged traitait les manifests ENFANTS des
index OCI (BuildKit : amd64 + attestation) comme « untagged » et les
détruisait à chaque release — y compris ceux des versions gardées et de
l'image publiée 30 s avant. Résultat : registre ENTIER impullable
(découvert 2026-07-21 par la migration de l'install Yannick — tous les
tags gungnir + gungnir-updater servaient des index dont l'enfant amd64
répondait 404).

Fix : (1) plus de --delete-untagged, GC simple des blobs orphelins ;
(2) la rétention supprime elle-même les enfants des index évincés (sinon
leurs revisions pinent les blobs et rien n'est libéré) ; (3) le keep-set
inclut les enfants des index gardés (digest partagé entre versions — cas
updater — protégé). La release suivante re-publie les images et restaure
un registre pullable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kevin merged commit 5d0e82ecf4 into main 2026-07-21 15:55:59 +00:00
kevin deleted branch fix/registry-gc-multiarch 2026-07-21 15:55:59 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kevin/Gungnir!33
No description provided.