create-cpo-override

Par openshift · hypershift

Créer interactivement des overrides d'images CPO — résout les images, vérifie les correctifs, modifie overrides.yaml et prépare une PR

npx skills add https://github.com/openshift/hypershift --skill create-cpo-override

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

  • skopeo installé
  • oc installé (pour oc adm release info)
  • gh CLI 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 :

  1. Essayez un léger skopeo inspect contre une image de payload de version connue (par exemple quay.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.
  2. S'il échoue, vérifiez si $PULL_SECRET est défini et pointe vers un fichier existant. Si oui, réessayez avec --authfile "$PULL_SECRET" (et utilisez -a "$PULL_SECRET" pour oc adm release info). Utilisez ce fichier d'authentification pour toutes les opérations d'image suivantes.
  3. 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 :

  1. Recherchez l'entité de version z-stream :
    search_entities(q="OpenShift X.Y.z", kind="release")
  2. Parcourez le calendrier pour la fin de développement du prochain z-stream :
    browse_schedule(entity_id=<id>, q="X.Y.<max_z+1>")
  3. Trouvez la tâche nommée X.Y.<max_z+1> Development Cut Off et notez sa date_finish.
  4. 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 :

  1. Rapportez quelles sources ont été essayées et pourquoi elles ont échoué
  2. Pointez l'utilisateur vers :
    • La skill dev build-cpo-image pour créer une image personnalisée localement
    • Le processus hotfix Konflux dans contrib/konflux/README.md
  3. Demandez à l'utilisateur de fournir une référence d'image manuellement
  4. 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 :

  1. Utilise skopeo inspect pour obtenir le label vcs-ref de l'image (commit git)
  2. Utilise gh pr view pour obtenir le commit de fusion de la PR
  3. 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 (aws ou azure)
  • 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.

Skills similaires