Skip to content

Conversation

@andfasano
Copy link
Contributor

This patch adds the new InternalReleaseImage CRD. See openshift/enhancements#1821 for additional details

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Sep 29, 2025
@openshift-ci-robot
Copy link

openshift-ci-robot commented Sep 29, 2025

@andfasano: This pull request references AGENT-1330 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

This patch adds the new InternalReleaseImage CRD. See openshift/enhancements#1821 for additional details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Sep 29, 2025
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Sep 29, 2025

Hello @andfasano! Some important instructions when contributing to openshift/api:
API design plays an important part in the user experience of OpenShift and as such API PRs are subject to a high level of scrutiny to ensure they follow our best practices. If you haven't already done so, please review the OpenShift API Conventions and ensure that your proposed changes are compliant. Following these conventions will help expedite the api review process for your PR.

@openshift-ci openshift-ci bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Sep 29, 2025
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Sep 29, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign joelspeed for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@andfasano andfasano force-pushed the add-internalreleaseimage-resource branch from 9ea943a to 9eca225 Compare September 29, 2025 17:19
@andfasano andfasano changed the title [WIP] AGENT-1330: machineconfiguration/v1alpha1: add InternalImageRelease [WIP] AGENT-1330: machineconfiguration/v1alpha1: add InternalReleaseImage Sep 29, 2025
@andfasano andfasano force-pushed the add-internalreleaseimage-resource branch 2 times, most recently from 0d80867 to 7ea433e Compare October 3, 2025 15:32
@andfasano
Copy link
Contributor Author

/retest-required

@JoelSpeed
Copy link
Contributor

I'm currently experimenting with AI for API review, hopefully some of the content it is generating is helpful for you to improve your API

The following code blocks were generated by Claude

⏺ I'll run a comprehensive API review for PR #2510. Let me start by setting up the environment and checking out the PR.

⏺ Bash(CURRENT_BRANCH=$(git branch --show-current); echo "📍 Current branch: $CURRENT_BRANCH"; if ! git diff --quiet || ! git diff --cached --quiet; then echo "❌ ERROR…)
  ⎿  📍 Current branch: agents                           
     ✅ No uncommitted changes detected. Safe to proceed.

⏺ Bash(echo "🔍 Reviewing PR #2510"; echo "🔄 Checking out PR #2510..."; gh pr checkout "2510")
  ⎿  🔍 Reviewing PR #2510                
     🔄 Checking out PR #2510...
     From https://github.com/openshift/api
     … +2 lines (ctrl+o to expand)

⏺ Bash(echo "📁 Analyzing changed files..."; gh pr view "2510" --json files --jq '.files[].path' | grep '\.go$' | grep -E '/(v1|v1alpha1|v1beta1)/')
  ⎿  📁 Analyzing changed files...                              
     machineconfiguration/v1alpha1/register.go
     machineconfiguration/v1alpha1/types_internalreleaseimage.go
     … +2 lines (ctrl+o to expand)

⏺ Bash(echo "⏳ Running linting checks on PR changes..."; make lint)
  ⎿  Error: make: *** [lint] Error 1

     ⏳ Running linting checks on PR changes...
     hack/golangci-lint.sh run --new-from-rev=master 
     Tools vendor version mismatch, removing old utils
     Writing tools vendor version 206d340a14a3ede2d30e25b37757397aacac6799
     go build -mod=vendor -o /Users/jspeed/go/src/github.com/openshift/api/tools/_output/bin/darwin/arm64/golangci-lint ./vendor/github.com/golangci/golangci-lint/v2/cmd/golangci-lint
     go build -mod=vendor -buildmode=plugin -o /Users/jspeed/go/src/github.com/openshift/api/tools/_output/bin/darwin/arm64/kube-api-linter.so ./vendor/sigs.k8s.io/kube-api-linter/pkg/plugin
     ln -fs /Users/jspeed/go/src/github.com/openshift/api/tools/_output/bin/darwin/arm64/kube-api-linter.so /Users/jspeed/go/src/github.com/openshift/api/tools/_output/bin/kube-api-linter.so
     machineconfiguration/v1alpha1/types_internalreleaseimage.go:35:2: requiredfields: field Spec has a valid zero value ({}), but the validation is not complete (e.g. min properties/adding required fields). The field should be a pointer to allow the zero value to be set. If the zero value is not a valid use case, complete the validation and remove the 
     pointer. (kubeapilinter)
     … +7 lines (ctrl+o to see all)

⏺ Now let me analyze the main API file for documentation requirements:

⏺ Read(machineconfiguration/v1alpha1/types_internalreleaseimage.go)
  ⎿  Read 111 lines (ctrl+o to expand)

⏺ Let me also check the PR diff to understand exactly what changed:

⏺ Bash(gh pr diff "2510")
  ⎿  diff --git a/machineconfiguration/v1alpha1/register.go b/machineconfiguration/v1alpha1/register.go
     index c60f521f940..451be959977 100644
     --- a/machineconfiguration/v1alpha1/register.go
     … +601 lines (ctrl+o to expand)

⏺ API Review Report for PR #2510

  ❌ REVIEW FAILED - Issues Found

  The API review has identified several critical issues that must be addressed before this PR can be approved.

  🚨 Linting Errors (CRITICAL)

  The make lint command failed with kubeapilinter errors:

  +35: Spec field validation issue
  Current (problematic) code:
  Spec InternalReleaseImageSpec `json:"spec,omitzero"`

  Suggested change:
  - Spec InternalReleaseImageSpec `json:"spec,omitzero"`
  + Spec *InternalReleaseImageSpec `json:"spec,omitzero"`

  Explanation: The field has a valid zero value ({}) but incomplete validation. Since it's marked as +required, it should be a pointer to allow the zero value to be set, or the validation should be completed to make the zero value invalid.

  +39: Status field validation issue
  Current (problematic) code:
  Status InternalReleaseImageStatus `json:"status"`

  Suggested change:
  - Status InternalReleaseImageStatus `json:"status"`
  + Status *InternalReleaseImageStatus `json:"status"`

  Explanation: The field has a valid zero value ({}) but incomplete validation. Since status subresources typically allow empty initial states, this should be a pointer to allow the zero value to be set.

  📚 Documentation Issues (MODERATE)

  +48: Missing optional field behavior documentation
  Current (problematic) code:
  // conditions represent the observations of an internal release image current state.
  // +listType=map
  // +listMapKey=type
  // +kubebuilder:validation:MaxItems=20
  // +optional
  Conditions []metav1.Condition `json:"conditions,omitempty"`

  Suggested change:
  - // conditions represent the observations of an internal release image current state.
  + // conditions represent the observations of an internal release image current state.
  + // When omitted, the resource has no status conditions to report.

  Explanation: Optional fields must explain what happens when they are omitted. The field comment should state the behavior when the field is not present.

  +57: Missing optional field behavior documentation
  Current (problematic) code:
  // availableReleases is a list of release bundle identifiers currently detected
  // from the attached ISO.
  // +listType=map
  // +listMapKey=name
  // +kubebuilder:validation:MinItems=1
  // +kubebuilder:validation:MaxItems=64
  // +optional
  AvailableReleases []InternalReleaseImageRef `json:"availableReleases,omitempty"`

  Suggested change:
  - // availableReleases is a list of release bundle identifiers currently detected
  - // from the attached ISO.
  + // availableReleases is a list of release bundle identifiers currently detected
  + // from the attached ISO.
  + // When omitted or empty, no release bundles have been detected from the attached ISO.

  Explanation: Optional fields must explain what happens when they are omitted. Also, the validation constraints (MinItems=1, MaxItems=64) should be documented.

  +66: Missing optional field behavior documentation
  Current (problematic) code:
  // releases is a list of the currently managed release bundles.
  // +listType=map
  // +listMapKey=name
  // +kubebuilder:validation:MinItems=1
  // +kubebuilder:validation:MaxItems=64
  // +optional
  Releases []InternalReleaseImageRef `json:"releases,omitempty"`

  Suggested change:
  - // releases is a list of the currently managed release bundles.
  + // releases is a list of the currently managed release bundles.
  + // When omitted or empty, no release bundles are currently being managed.

  Explanation: Optional fields must explain what happens when they are omitted. Also, the validation constraints (MinItems=1, MaxItems=64) should be documented.

  +78: Missing optional field behavior documentation
  Current (problematic) code:
  // releases is a list of release bundle identifiers that the user wants to
  // add/remove to/from the control plane nodes.
  // +optional
  // +kubebuilder:validation:MinItems=1
  // +kubebuilder:validation:MaxItems=20
  // +listType=map
  // +listMapKey=name
  Releases []InternalReleaseImageRef `json:"releases,omitempty"`

  Suggested change:
  - // releases is a list of release bundle identifiers that the user wants to
  - // add/remove to/from the control plane nodes.
  + // releases is a list of release bundle identifiers that the user wants to
  + // add/remove to/from the control plane nodes.
  + // When omitted or empty, no release bundle operations are requested.
  + // Must contain between 1 and 20 items when specified.

  Explanation: Optional fields must explain what happens when they are omitted. The validation constraints (MinItems=1, MaxItems=20) must also be documented in the field comment.

  +93: Missing optional field behavior documentation
  Current (problematic) code:
  // image is an OCP release imaged referenced by digest.
  // The format of the image pull spec is: host[:port][/namespace]/name@sha256:<digest>,
  // where the digest must be 64 characters long, and consist only of lowercase hexadecimal characters, a-f and 0-9.
  // The length of the whole spec must be between 1 to 447 characters.
  // +optional
  Image machineosconfig.ImageDigestFormat `json:"image,omitempty"`

  Suggested change:
  - // image is an OCP release imaged referenced by digest.
  - // The format of the image pull spec is: host[:port][/namespace]/name@sha256:<digest>,
  - // where the digest must be 64 characters long, and consist only of lowercase hexadecimal characters, a-f and 0-9.
  - // The length of the whole spec must be between 1 to 447 characters.
  + // image is an OCP release imaged referenced by digest.
  + // The format of the image pull spec is: host[:port][/namespace]/name@sha256:<digest>,
  + // where the digest must be 64 characters long, and consist only of lowercase hexadecimal characters, a-f and 0-9.
  + // The length of the whole spec must be between 1 to 447 characters.
  + // When omitted, the release bundle identifier refers to the name only without an associated image.

  Explanation: Optional fields must explain what happens when they are omitted. This field needs to clarify what happens when no image is specified for a release bundle.

  ✅ Positive Findings

  - API Structure: Well-organized with appropriate separation between spec and status
  - Feature Gate: Properly gated behind NoRegistryClusterOperations feature gate
  - Validation Rules: Comprehensive validation using kubebuilder markers and CEL expressions
  - Generated Files: All required generated files (deepcopy, CRDs, swagger docs) are present and properly updated
  - List Support: Proper list type and map key annotations for array fields
  - Compatibility: Correctly marked as compatibility level 4 for alpha API

  📋 Action Required

  1. CRITICAL: Fix the linting errors by addressing the pointer vs value type issues for Spec and Status fields
  2. REQUIRED: Add proper documentation for all optional fields explaining behavior when omitted
  3. RECOMMENDED: Document validation constraints in field comments for better developer experience

  The PR cannot be approved until the critical linting errors are resolved and all optional fields have proper behavior documentation.

I think the linting issues are actually not the response I'd like. Instead lets try and make the zero values not valid (required fields or MinProperties markers. The linter should be prompting you on these already

For the comments, it has highlighted that you haven't explained what happens when the optional fields are omitted, though I'm not sure its suggestions are super helpful, please review and think about what you'd actually like to put in. If it has identified something where you can't think of a reason why it wouldn't be present, then maybe the field should actually be required


Quizzing specifically about whether all validations were documented, some further output

⏺ You're absolutely right. Looking more carefully at the validation markers, I missed several undocumented validation markers:

  Additional Undocumented Validation Markers I Missed:

  +47: MaxItems validation not documented
  // +kubebuilder:validation:MaxItems=20
  The comment doesn't mention the maximum of 20 items for conditions.

  +55-56: MinItems and MaxItems validation not documented
  // +kubebuilder:validation:MinItems=1
  // +kubebuilder:validation:MaxItems=64
  The comment doesn't mention the 1-64 item range for availableReleases.

  +63-64: MinItems and MaxItems validation not documented
  // +kubebuilder:validation:MinItems=1  
  // +kubebuilder:validation:MaxItems=64
  The comment doesn't mention the 1-64 item range for releases in status.

  +84-85: MinLength and MaxLength validation not documented
  // +kubebuilder:validation:MinLength=1
  // +kubebuilder:validation:MaxLength=64
  The comment doesn't mention the 1-64 character length constraints for the name field.

  So no, my original review was incomplete. I identified the optional field behavior issues but missed documenting several validation constraints that should be included in the field comments according to OpenShift API documentation standards.

@andfasano andfasano force-pushed the add-internalreleaseimage-resource branch 2 times, most recently from 7b60a33 to ab6545c Compare October 7, 2025 16:29
@andfasano
Copy link
Contributor Author

/api-review

@andfasano andfasano force-pushed the add-internalreleaseimage-resource branch 3 times, most recently from cf83224 to c2f669c Compare October 10, 2025 15:46
@andfasano
Copy link
Contributor Author

/test verify


// InternalReleaseImageSpec defines the desired state of a InternalReleaseImage.
type InternalReleaseImageSpec struct {
// releases is a list of release bundle identifiers that the user wants to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(suggestion from claude): we should document the constraints (maximum # you can specify)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't sufficient to specify the +kubebuilder:validation:MaxItems value?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that's the validation, it's asking for the godoc to explicitly state for the user what the maximum is, something like This field can contain between x and y release bundles

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok

@andfasano andfasano force-pushed the add-internalreleaseimage-resource branch from a9c080e to 5bb2da8 Compare October 17, 2025 14:49
@andfasano
Copy link
Contributor Author

/retest

@andfasano andfasano force-pushed the add-internalreleaseimage-resource branch from 5bb2da8 to ee91dd4 Compare October 17, 2025 17:02
@andfasano
Copy link
Contributor Author

/retest

Copy link
Contributor

@yuqi-zhang yuqi-zhang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall the structure makes more sense to me. A few questions/comments on the new MCN fields (and the previous question on the conditions)

// +listType=map
// +listMapKey=name
// +kubebuilder:validation:MaxItems=5
// +optional
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just thinking out loud, maybe we should have this be required (if the IRI status exists) so at it would always reflect what the daemon is currently detecting? And if we don't detect anything we just have an empty list?

// +listMapKey=name
// +kubebuilder:validation:MaxItems=5
// +optional
AvailableReleases []InternalReleaseImageRef `json:"availableReleases,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we have the split, what get's reflected here? If e.g. each control plane node doesn't currently have the same available (mounted) releases, would this reflect it as available if any control plane node is hosting that image? Or only when all control plane nodes have it mounted and reporting?

Copy link
Contributor Author

@andfasano andfasano Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned before, the idea was to keep IRI as the main (centralized) user interface both for editing and monitoring (for the sake of simplicity). As soon as a new release will be detected on on of the node, and reported on its MCN status, it will be added as well in the IRI availableRelease field.
So, the IRI reports the info from a cluster-wide scope point of view, where the the MCN remains scoped only for the node

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iiuc a release will be added here if and only if all nodes have it properly stored. So, iiuc, the only possibilities for a realease to not be in all nodes are:

  1. The image is still being copied.
  2. There's a failure in the copy process. I guess we will add details in the MCN and here, isn't it? What would each CR report in its conditions?

// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=5
// +optional
InstalledReleases []InternalReleaseImageDetailedRef `json:"installedReleases,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question as above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, as above, the IRI will report that a release is installed (at a cluster level) only when all the node successfully completed the installation

@andfasano andfasano force-pushed the add-internalreleaseimage-resource branch 4 times, most recently from 63bf18d to eb17df7 Compare October 23, 2025 19:00
@andfasano andfasano force-pushed the add-internalreleaseimage-resource branch from eb17df7 to b91c71a Compare October 24, 2025 17:04
// be used to amend the `spec.Releases` field to add a new release bundle to the cluster.
// An empty value indicates that no ISOs are currently being detected on any control plane
// node.
// Must not exceed 5 entries.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crdName: internalreleaseimages.machineconfiguration.openshift.io
featureGate: NoRegistryClusterOperations
tests:
onCreate:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No onUpdate tests? Look like a CR that really needs them. (add/remove a release)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, will followup

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Oct 27, 2025

@andfasano: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/verify 69a28e6 link true /test verify
ci/prow/lint 69a28e6 link true /test lint

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants