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.1content 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.