Créer une substitution CPO
Synopsis
/create-cpo-override
Description
Crée de manière interactive des entrées de substitution d'image control-plane-operator (CPO) dans
hypershift-operator/controlplaneoperator-overrides/assets/overrides.yaml.
Automatise la découverte d'images, la vérification des correctifs, la modification YAML et la préparation de PR
pour que le résultat soit compatible avec /validate-pr-override-images.
Prérequis
skopeoinstalléocinstallé (pouroc adm release info)ghCLI authentifié- Le référentiel git local a récupéré les branches de version pertinentes (
git fetch --all) - Accès Internet à quay.io et à l'API Cincinnati
Implémentation
Suivez les étapes ci-dessous dans l'ordre. Chaque étape s'appuie sur la précédente.
Utilisez AskUserQuestion pour les invites à choix multiples si indiqué. Pour les
entrées libres, demandez à l'utilisateur directement dans la conversation.
Étape 0 — Détecter le secret d'extraction
De nombreuses images de payload OCP nécessitent une authentification. Avant toute opération d'image, vérifiez qu'un secret d'extraction fonctionnel est disponible :
- Essayez un léger
skopeo inspectcontre une image de payload de version connue (par exemplequay.io/openshift-release-dev/ocp-release:4.18.0-multi). S'il réussit, l'authentification par défaut du runtime de conteneurs est suffisante — aucun flag supplémentaire nécessaire. - S'il échoue, vérifiez si
$PULL_SECRETest défini et pointe vers un fichier existant. Si oui, réessayez avec--authfile "$PULL_SECRET"(et utilisez-a "$PULL_SECRET"pouroc adm release info). Utilisez ce fichier d'authentification pour toutes les opérations d'image suivantes. - Si aucune des deux ne fonctionne, demandez à l'utilisateur de fournir un chemin vers un fichier de secret d'extraction.
S'il n'en a pas, avertissez que les images provenant du payload (Sources 1 & 2)
ne seront pas disponibles et seules les images Konflux (Source 3, publiques sur
quay.io/redhat-user-workloads/) peuvent être résolues automatiquement.
Étape 1 — Collecter les entrées
Collectez les éléments suivants auprès de l'utilisateur. Posez toutes les questions d'avance (ou par groupes logiques) plutôt qu'une à la fois.
1a. Plateforme(s)
Demandez à l'utilisateur quelle(s) plateforme(s) substituer.
Options : aws, azure ou both.
1b. Ticket Jira
Demandez le ticket Jira parent qui justifie la substitution (par exemple OCPBUGS-86238).
Ceci est utilisé dans les marqueurs de commentaire et le message de commit.
1c. Branches
Demandez quelles branches mineures d'OCP ont besoin de substitutions (par exemple 4.20, 4.21).
1d. Plage de version par branche
Pour chaque branche, demandez à l'utilisateur quelles versions z-stream substituer. Formats acceptés :
| Entrée | Signification |
|---|---|
4.20.0-4.20.24 |
Plage explicite |
all |
Tous les z-stream de X.Y.0 jusqu'au plus haut z-stream du canal Cincinnati fast-X.Y |
4.20.15 |
Version unique |
Quand l'utilisateur dit all, résolvez la plage comme suit :
curl -sH 'Accept: application/json' \
"https://api.openshift.com/api/upgrades_info/v1/graph?channel=fast-${BRANCH}&arch=multi" \
| python3 -c "
import json, sys
data = json.load(sys.stdin)
versions = [n['version'] for n in data.get('nodes', [])
if n['version'].startswith('${BRANCH}.')]
zs = sorted(int(v.split('.')[2]) for v in versions)
print(max(zs))
"
Ensuite, générez tous les z-stream de X.Y.0 à X.Y.<max_z> inclus
(Cincinnati omet certains z-stream comme 4.20.7, 4.20.9 — les clusters peuvent toujours les
exécuter, donc incluez-les tous).
1d-ii. Vérifier le prochain z-stream via les dates de fin de développement
C'est critique pour éviter les régressions de mise à niveau. Si un client est sur une version substituée (par exemple 4.22.3) et passe au prochain z-stream (par exemple 4.22.4), la substitution ne s'applique plus. Si ce prochain z-stream ne contient pas le correctif dans son payload, le client régresse.
Pour déterminer si le prochain z-stream après la plage de substitution doit être inclus, vérifiez la date de fin de développement pour cette version par rapport aux dates de fusion des PR.
Si le serveur MCP productpages est disponible, utilisez-le :
- Recherchez l'entité de version z-stream :
search_entities(q="OpenShift X.Y.z", kind="release") - Parcourez le calendrier pour la fin de développement du prochain z-stream :
browse_schedule(entity_id=<id>, q="X.Y.<max_z+1>") - Trouvez la tâche nommée
X.Y.<max_z+1> Development Cut Offet notez sadate_finish. - Comparez avec la date de fusion de chaque PR requise (depuis
gh pr view --json mergedAt).
Si toutes les PR ont fusionné avant la date limite, le prochain z-stream
incluera les correctifs — aucune substitution nécessaire pour celui-ci. Ajoutez un commentaire dans
overrides.yaml le notant (par exemple « 4.22.4 n'a pas besoin de substitution : les deux
PR ont fusionné avant la fin de développement »).
Si une PR a fusionné après la date limite, étendez la plage de substitution pour inclure ce z-stream et répétez la vérification pour celui qui suit.
Si le serveur MCP productpages n'est PAS disponible, avertissez l'utilisateur et demandez
la date limite :
⚠️ Impossible de vérifier les dates de fin de développement — le serveur MCP Product Pages n'est pas connecté. Veuillez vérifier la date de fin de développement pour
X.Y.<max_z+1>sur https://pp.engineering.redhat.com et la fournir ici pour que je puisse vérifier que la plage de substitution est complète.
Quand l'utilisateur fournit la date limite, comparez-la avec les dates de fusion des PR (même logique que ci-dessus). Si une PR a fusionné après la limite, étendez la plage de substitution et demandez la date limite du prochain z-stream. Répétez jusqu'à ce que la plage soit sûre.
1e. PR requises
Demandez quelles PR GitHub doivent être présentes dans l'image de substitution. Acceptez les URL de PR
(par exemple https://github.com/openshift/hypershift/pull/8593) ou les numéros simples
(par exemple 8593). Plusieurs PR peuvent être séparées par des virgules.
Les PR peuvent être spécifiées par branche ou globalement (appliquées à toutes les branches). Si une PR est un cherry-pick, l'utilisateur doit fournir le numéro de PR spécifique à la branche.
1f. Image par branche (optionnel)
Demandez si l'utilisateur souhaite fournir des images spécifiques ou les faire résoudre automatiquement. Si résolution automatique, passez à l'étape 2.
Étape 2 — Résoudre automatiquement les images
Pour chaque branche qui a besoin d'une image, essayez les sources dans cet ordre. Arrêtez à la première source dont l'image contient toutes les PR requises pour cette branche.
Source 1 : Dernier payload stable
# Obtenez la dernière version dans stable-X.Y
LATEST=$(curl -sH 'Accept: application/json' \
"https://api.openshift.com/api/upgrades_info/v1/graph?channel=stable-${BRANCH}&arch=multi" \
| python3 -c "
import json, sys
data = json.load(sys.stdin)
versions = [n['version'] for n in data.get('nodes', [])
if n['version'].startswith('${BRANCH}.')]
versions.sort(key=lambda v: [int(x) for x in v.split('.')])
print(versions[-1])
")
# Obtenez le commit source du composant hypershift du payload en utilisant la sortie JSON.
# Cela évite d'avoir besoin d'un accès skopeo au référentiel interne ocp-v4.0-art-dev.
COMMIT=$(oc adm release info \
${AUTHFILE:+-a "$AUTHFILE"} \
"quay.io/openshift-release-dev/ocp-release:${LATEST}-multi" \
-o json 2>/dev/null \
| jq -r '.references.spec.tags[] | select(.name == "hypershift") | .annotations["io.openshift.build.commit.id"]')
Vérifiez que toutes les PR requises sont ancêtres de $COMMIT en utilisant
git merge-base --is-ancestor. Si c'est le cas, le correctif est déjà dans le dernier
payload stable — aucune substitution n'est nécessaire pour cette branche. Rapportez-le
à l'utilisateur et passez la branche.
Note : n'utilisez pas le pullspec d'image interne du payload (ocp-v4.0-art-dev)
comme image de substitution elle-même — ce référentiel nécessite un accès à registre spécial que
les clusters n'ont pas. Si une substitution est toujours nécessaire pour des z-stream plus anciens,
passez à la Source 3 (Konflux).
Source 2 : Dernier payload fast
Identique à la Source 1 mais interrogez fast-${BRANCH} au lieu de stable-${BRANCH}.
Si le correctif est déjà dans fast, rapportez-le et passez la branche.
Source 3 : Build push Konflux
REPO="quay.io/redhat-user-workloads/crt-redhat-acm-tenant/control-plane-operator-${BRANCH_HYPHEN}"
# BRANCH_HYPHEN est par exemple "4-21" (points remplacés par des tirets)
# Listez les tags, filtrez les tags de commit SHA hex 40-caractères (builds push)
TAGS=$(skopeo list-tags "docker://${REPO}" 2>/dev/null \
| python3 -c "
import json, sys, re
tags = json.load(sys.stdin).get('Tags', [])
# Les tags de build push sont hex 40-caractères, sans suffixe
commits = [t for t in tags if re.fullmatch(r'[0-9a-f]{40}', t)]
for c in commits:
print(c)
")
Pour chaque tag de commit candidat (vérifiez les plus récents en premier — utilisez git log pour les
ordonner), vérifiez que les PR requises sont ancêtres :
for PR_NUM in $REQUIRED_PRS; do
PR_MERGE=$(gh pr view "$PR_NUM" --repo openshift/hypershift \
--json mergeCommit --jq '.mergeCommit.oid // empty')
git merge-base --is-ancestor "$PR_MERGE" "$COMMIT_TAG"
done
Si toutes les PR passent, obtenez la référence épinglée au digest :
DIGEST=$(skopeo inspect --override-os linux --override-arch amd64 \
"docker://${REPO}:${COMMIT_TAG}" 2>/dev/null \
| python3 -c "import json,sys; print(json.load(sys.stdin)['Digest'])")
IMAGE="${REPO}@${DIGEST}"
Étiquette source : Konflux push build (commit ${COMMIT_TAG:0:12}).
Source 4 : Aucune image trouvée
Si aucune des sources ci-dessus n'a une image contenant toutes les PR requises :
- Rapportez quelles sources ont été essayées et pourquoi elles ont échoué
- Pointez l'utilisateur vers :
- La skill dev
build-cpo-imagepour créer une image personnalisée localement - Le processus hotfix Konflux dans
contrib/konflux/README.md
- La skill dev
- Demandez à l'utilisateur de fournir une référence d'image manuellement
- Quand il le fait, vérifiez-la (Étape 3) et continuez
Étape 3 — Vérifier que les PR sont présentes dans les images
Pour chaque tuple (branch, image, PR), exécutez le script de vérification existant :
.claude/skills/validate-pr-override-images/verify-pr-in-image.sh \
"$IMAGE" "$PR_NUM" "$(git rev-parse --show-toplevel)"
Ce script :
- Utilise
skopeo inspectpour obtenir le labelvcs-refde l'image (commit git) - Utilise
gh pr viewpour obtenir le commit de fusion de la PR - Vérifie
git merge-base --is-ancestor <pr-merge-commit> <image-commit>
Si une vérification échoue, rapportez l'échec et demandez à l'utilisateur comment procéder (fournir une image différente, passer la branche ou abandonner).
Étape 4 — Tester la tirabilité de l'image
Pour chaque image résolue, confirmez qu'elle peut être tirée (utilisez le fichier d'authentification de l'Étape 0 si un a été détecté) :
skopeo inspect --override-os linux --override-arch amd64 \
${AUTHFILE:+--authfile "$AUTHFILE"} \
"docker://${IMAGE}" > /dev/null 2>&1
Rapportez les éventuels échecs.
Étape 5 — Présenter un résumé pour confirmation
Affichez un tableau de résumé et demandez à l'utilisateur de confirmer avant de faire des modifications :
=== Résumé de substitution CPO ===
Ticket : OCPBUGS-XXXXX
Plateforme(s) : azure
Branche 4.20 :
Versions : 4.20.0 - 4.20.27 (28 entrées)
Image : quay.io/redhat-user-workloads/crt-redhat-acm-tenant/control-plane-operator-4-20@sha256:155e4e...
Source : Build push Konflux (commit 46f3b353fd5c)
PR vérifiées : #8593 PASS, #8565 PASS
Branche 4.21 :
Versions : 4.21.0 - 4.21.18 (19 entrées)
Image : quay.io/redhat-user-workloads/crt-redhat-acm-tenant/control-plane-operator-4-21@sha256:1b3f1b...
Source : Build push Konflux (commit c84f8073)
PR vérifiées : #8565 PASS
Branche 4.22 :
Aucune substitution nécessaire — le correctif s'est intégré avant GA (PR #8564, commit d6c72d15)
Continuer avec la modification d'overrides.yaml ? [Oui / Non]
Étape 6 — Éditer overrides.yaml
Modifiez hypershift-operator/controlplaneoperator-overrides/assets/overrides.yaml.
Règles de placement :
- Ajoutez les entrées sous la clé de plateforme appropriée (
awsouazure) - Ajoutez les nouvelles entrées de substitution avant la section
testing: - Si des entrées pour le même ticket+branche existent déjà, remplacez-les
Format : Lisez le overrides.yaml existant et répliquez exactement ses conventions
— marqueurs de commentaire, indentation et structure d'entrée. Ne codez
pas en dur un format ici ; le fichier lui-même est la source de vérité.
Étape 7 — Exécuter les tests unitaires
go test ./hypershift-operator/controlplaneoperator-overrides/...
Si les tests échouent, corrigez le YAML et réexécutez. Problèmes courants :
- Erreurs d'analyse YAML (mauvaise indentation)
- Entrées de version dupliquées entre différentes sections de ticket
Étape 8 — Préparer le commit et la description de PR
Commit
Indexez uniquement le fichier de substitution (et tout nouveau fichier PDS Konflux si nécessaire) :
git add hypershift-operator/controlplaneoperator-overrides/assets/overrides.yaml
# Si des fichiers PDS Konflux ont été créés :
# git add contrib/konflux/cpo_X_Y_stream.yaml
Format du message de commit :
<TICKET>: ajouter des substitutions CPO pour <courte description>
Ajouter des substitutions d'image CPO <plateforme> pour <branches> pour corriger <description>.
<Branche qui n'a pas besoin de substitution> n'a pas besoin de substitution : le correctif
(PR #NNNN, commit <sha-court>) s'est intégré avant <version> et sera
inclus dans la version GA.
- X.Y.0-X.Y.Z : <TICKET-par-branche> (PR #NNNN cherry-pick vers release-X.Y)
- ...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Description de PR
La description de PR doit inclure les lignes de contrat de validation que
/validate-pr-override-images analyse. Le format du contrat est documenté dans
docs/content/contribute/cpo-overrides.md
sous « Validating Override Images Contain Claimed PRs ». Générez ces lignes
à partir du mappage branche-vers-PR collecté à l'Étape 1.
Incluez une section Résumé, les lignes de contrat (en dehors des blocs de code pour que le validateur puisse les analyser), et une section Plan de test.
Validation post-PR
Après la création de la PR, exécutez /validate-pr-override-images <numéro-pr> pour
confirmer que la PR passe la validation de bout en bout. Si elle échoue, corrigez la description
de PR ou les références d'image et réexécutez jusqu'à ce qu'elle passe.