Skip to content

Conversation

hongkailiu
Copy link
Member

Before this full, the logging was only for the case that findClusterIncludeConfigFromInstallConfig is called, i.e., the path from an install-config file is provided.

This pull extends it to the case where the
configuration is taken from the current cluster.

Another change from the pull is that the logging
messages include the target version that is determined by inspecting the release image. The implementation for this is adding a new callback ImageConfigCallback.

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

@hongkailiu: This pull request explicitly references no jira issue.

In response to this:

Before this full, the logging was only for the case that findClusterIncludeConfigFromInstallConfig is called, i.e., the path from an install-config file is provided.

This pull extends it to the case where the
configuration is taken from the current cluster.

Another change from the pull is that the logging
messages include the target version that is determined by inspecting the release image. The implementation for this is adding a new callback ImageConfigCallback.

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 requested review from ardaguclu and deads2k June 23, 2025 16:43
Copy link
Contributor

openshift-ci bot commented Jun 23, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: hongkailiu
Once this PR has been reviewed and has the lgtm label, please assign ardaguclu 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

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 23, 2025
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 25, 2025
Before this full, the logging was only for the case
that `findClusterIncludeConfigFromInstallConfig` is
called, i.e., the path from an install-config
file is provided.

This pull extends it to the case where the
configuration is taken from the current cluster.

Another change from the pull is that the logging
messages include the target version that is determined
by inspecting the release image. The implementation
for this is adding a new callback `ImageConfigCallback`.
@petr-muller
Copy link
Member

/cc

@openshift-ci openshift-ci bot requested a review from petr-muller July 7, 2025 12:46
Comment on lines +384 to +386
inclusionConfig, err = findClusterIncludeConfig(ctx, o.RESTConfig, versionInImageConfig)
} else {
inclusionConfig, err = findClusterIncludeConfigFromInstallConfig(ctx, o.InstallConfig)
inclusionConfig, err = findClusterIncludeConfigFromInstallConfig(ctx, o.InstallConfig, versionInImageConfig)
Copy link
Member

Choose a reason for hiding this comment

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

Maybe I am missing something but I don't understand when is versionInImageConfig actually populated. What I'm reading is:

  1. It is empty on L354 when declared
  2. It can be populated on L371 inside the opts.ImageConfigCallback callback (which itself is populated on L355)
  3. It can only be actually populated once opts.ImageConfigCallback is called at least one
  4. The callback is called in pkg/cli/image/extract/extract.go:L426 in o.Run()
  5. Here on L384 / L386 we expect this to be a populated string already but I do not see any opportunity betwen L372 and the L383 if where o.Run() could be called, even indirectly.

How is versionInImageConfig not always an empty string on L384/L386??

Copy link
Member

Choose a reason for hiding this comment

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

This is reiterated #1958 (comment) but I do not understand the answer.

return
}
klog.V(2).Infof("Retrieved the version from image configuration in the image to extract: %s", v)
versionInImageConfig = v
Copy link
Member

Choose a reason for hiding this comment

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

We assume we never reach this place twice here (= we assume the callback is never called multiple time in a way that reaches this assignment) otherwise the old value is overwritten.

That assumption may be fine but I'd either add a comment here about it or logged if we reach here while versionInImageConfig is not empty.

}

// versionInImageConfig stores the version from the label of the image
// At the moment it is used later only for the logging purpose and thus is not blocking if failures occur upon getting its value
Copy link
Member

Choose a reason for hiding this comment

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

If the errors are not blocking then maybe they should be logged as warnings, not errors?

Copy link
Contributor

openshift-ci bot commented Jul 16, 2025

@hongkailiu: 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/e2e-aws-ovn-serial-1of2 7056f53 link true /test e2e-aws-ovn-serial-1of2
ci/prow/e2e-aws-ovn-serial-2of2 7056f53 link true /test e2e-aws-ovn-serial-2of2

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.

@openshift-bot
Copy link
Contributor

Issues go stale after 90d of inactivity.

Mark the issue as fresh by commenting /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.
Exclude this issue from closing by commenting /lifecycle frozen.

If this issue is safe to close now please do so with /close.

/lifecycle stale

@openshift-ci openshift-ci bot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Oct 15, 2025
@hongkailiu
Copy link
Member Author

@coderabbitai full review

Copy link

coderabbitai bot commented Oct 20, 2025

✅ Actions performed

Full review triggered.

Copy link

coderabbitai bot commented Oct 20, 2025

Walkthrough

The changes introduce a callback-based mechanism to extract and propagate the release version from Docker image configuration labels through the image extraction and cluster inclusion workflow, enabling version-aware filtering and centralized capability difference logging.

Changes

Cohort / File(s) Change Summary
Release version extraction and propagation
pkg/cli/admin/release/extract.go, pkg/cli/admin/release/extract_tools.go
Adds ImageConfigCallback field to ExtractOptions to capture release version from image config labels into versionInImageConfig. Introduces logCapabilitySetMayDiffer() helper to centralize capability difference messaging. Extends findClusterIncludeConfig() and findClusterIncludeConfigFromInstallConfig() to accept and use versionInImageConfig for version-aware filtering.
Image extraction callback infrastructure
pkg/cli/image/extract/extract.go
Adds public ImageConfigCallback field to ExtractOptions with signature func(*dockerv1client.DockerImageConfig). Hooks callback invocation at two sites in Run() where imageConfig is obtained, immediately before condition evaluation and extraction logic.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

The changes span three files with coherent, callback-based additions and parameter propagation. The logic involves version extraction from labels, callback infrastructure setup, and refactoring of capability difference handling. Complexity is moderate—understanding the intent and flow across functions requires careful reading, but the individual changes are straightforward modifications to existing logic.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "Include the target version in the logging" directly relates to the main objectives of this changeset. The changes introduce a mechanism to extract the release version from image configuration (via the new ImageConfigCallback) and propagate it through the logging functions. The title accurately captures the primary outcome: incorporating target version information into logging output. While the title doesn't explicitly mention extending logging to the current cluster case, the instructions acknowledge that titles need not cover every detail, only the most important change from the developer's perspective.
Description Check ✅ Passed The pull request description is clearly related to the changeset. It explains the prior limitation (logging only for install-config path), the extension being made (logging for current cluster case), and the mechanism for achieving this (including target version via ImageConfigCallback). The description accurately reflects the changes documented in the raw_summary, providing meaningful context about both the scope extension and the version-inclusion feature. This is a lenient check that passes as long as the description is not completely off-topic, and this description is well-aligned with the actual changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
pkg/cli/admin/release/extract.go (2)

352-373: Make version capture non-blocking, stable, and avoid overwrites.

  • Use Warning/Info (not Error) for non-blocking failures.
  • Don’t overwrite if callback fires multiple times; log and keep first value.

Apply:

-	// versionInImageConfig stores the version from the label of the image
-	// At the moment it is used later only for the logging purpose and thus is not blocking if failures occur upon getting its value
+	// versionInImageConfig stores the version from the image label.
+	// Best-effort and non-blocking if retrieval fails.
 	var versionInImageConfig string
 	opts.ImageConfigCallback = func(imageConfig *dockerv1client.DockerImageConfig) {
-		if imageConfig == nil {
-			// This should never happen
-			klog.Error("Cannot retrieve the version because no image configuration is provided in the image to extract")
-			return
-		}
-		if imageConfig.Config == nil {
-			klog.Error("Cannot retrieve the version from image configuration in the image to extract because it has no configuration")
-			return
-		}
+		if imageConfig == nil || imageConfig.Config == nil {
+			klog.V(2).Info("Skipping target-version capture: image has no config")
+			return
+		}
 		v, ok := imageConfig.Config.Labels["io.openshift.release"]
 		if !ok {
-			klog.Error("Cannot retrieve the version from image configuration in the image to extract because it does not have the required label 'io.openshift.release'")
+			klog.V(2).Info("Skipping target-version capture: label 'io.openshift.release' not present")
 			return
 		}
-		klog.V(2).Infof("Retrieved the version from image configuration in the image to extract: %s", v)
-		versionInImageConfig = v
+		if versionInImageConfig != "" && versionInImageConfig != v {
+			klog.V(2).Infof("Target version label changed from %q to %q; keeping the first value", versionInImageConfig, v)
+			return
+		}
+		klog.V(2).Infof("Retrieved target version from image configuration: %s", v)
+		versionInImageConfig = v
 	}

Earlier feedback requested logging when overwriting and warning level for non-blocking cases.


384-387: versionInImageConfig is used before the callback can populate it.

The callback runs during opts.Run(); inclusionConfig is computed earlier, so target version is usually empty here.

Two fixes (pick one):

  • Preferred: Pre-populate from release metadata before building inclusionConfig.

Add just before computing inclusionConfig:

// Pre-populate target version to avoid callback-ordering race
if versionInImageConfig == "" {
	infoOpts := NewInfoOptions(o.IOStreams)
	infoOpts.SecurityOptions = o.SecurityOptions
	infoOpts.FilterOptions = o.FilterOptions
	infoOpts.FileDir = o.FileDir
	infoOpts.ICSPFile = o.ICSPFile
	infoOpts.IDMSFile = o.IDMSFile
	if rel, err := infoOpts.LoadReleaseInfo(o.From, false); err == nil {
		versionInImageConfig = rel.PreferredName()
		klog.V(2).Infof("Determined target version from release metadata: %s", versionInImageConfig)
	} else {
		klog.V(2).Infof("Could not determine target version from release metadata yet: %v", err)
	}
}
  • Minimal: Keep code as-is but rely on the helper’s empty-target guard (see prior comment). This avoids bad logs but loses the “target version” detail.

I can push a PR patch with option 1 if preferred.

🧹 Nitpick comments (1)
pkg/cli/image/extract/extract.go (1)

144-146: Document concurrency for ImageConfigCallback.

Note this callback may be invoked concurrently when MaxPerRegistry > 1, mirroring ImageMetadataCallback semantics.

Apply:

-	// ImageConfigCallback is invoked once image config retrieved
-	ImageConfigCallback func(imageConfig *dockerv1client.DockerImageConfig)
+	// ImageConfigCallback is invoked once per image after its config is retrieved.
+	// May be called concurrently when MaxPerRegistry > 1.
+	ImageConfigCallback func(imageConfig *dockerv1client.DockerImageConfig)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between ea5c720 and 7056f53.

📒 Files selected for processing (3)
  • pkg/cli/admin/release/extract.go (2 hunks)
  • pkg/cli/admin/release/extract_tools.go (3 hunks)
  • pkg/cli/image/extract/extract.go (2 hunks)
🔇 Additional comments (3)
pkg/cli/admin/release/extract_tools.go (2)

1220-1222: Passing target version through is good; be aware these calls may now fail.

Because logCapabilitySetMayDiffer currently returns an error on version lookup failure, these paths can now fail where they previously only logged. If non-breaking behavior is desired, adopt the non-blocking implementation in the previous comment.

Also applies to: 1265-1267


1170-1189: Confirm UX intent: should version detection failure silently degrade or block config extraction?

The suggested refactor is semantically reasonable but requires explicit approval:

Current behavior (blocking): If version lookup fails → entire config extraction fails → command stops.

Suggested behavior (best-effort): If version lookup fails → log gracefully at V(2) level → config extraction continues.

Evidence supports the change being intentional:

  • Function is named logCapabilitySetMayDiffer — it's purely advisory/logging, not critical data extraction
  • Recent commit "NO-JIRA: Include the target version in the logging" indicates this logging was recently added
  • It's reasonable that a logging-only function shouldn't become a hard failure point

However, the change alters error semantics for both callers (lines 1220, 1265), which currently treat errors as fatal. The review comment itself ends with `` asking you to confirm "that changing version-lookup failure from hard-error to best-effort log aligns with intended UX."

Before applying the diff:

  • Confirm this behavior change is intentional
  • If yes, the suggested implementation is sound (version.Info.Major/Minor fields confirmed, regex logic correct, imports present)
pkg/cli/image/extract/extract.go (1)

426-428: Good placement of the callback.

Called immediately after parsing image config and before filters; matches intended usage.

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

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants