Conversation
Assisted-by: OpenCode (Opus 4.5)
Add types for the nodeimageinfo API endpoint: - APINodeImageInfo and APINodeImageStream for full package lists - APINodeImageDiff and APINodeImageStreamDiff for diff responses - APIError for consistent error responses These types support both single-release package queries and two-release diff queries via the ?from= parameter. Assisted-by: OpenCode (Opus 4.5)
Add new JSON API endpoint for Node Image Info:
/api/v1/releasestream/{release}/release/{tag}/nodeimageinfo
Features:
- Returns RPM package list for each CoreOS stream in the release
- Supports ?from= parameter for diff between two releases
- Returns 400 for releases < 4.19
- Validates from and to tags are same minor version
- Validates tag belongs to the specified release stream
- Supports multi-stream releases (rhel-coreos, rhel-coreos-10)
Uses FindPublicImagePullSpec for pullspec construction, consistent
with other handlers. Introduces writeAPIResponse helper to reduce
duplication in JSON response writing.
Assisted-by: OpenCode (Opus 4.5)
📝 WalkthroughWalkthroughA new API endpoint Changes
Sequence DiagramsequenceDiagram
actor Client
participant Handler as apiNodeImageInfo<br/>Handler
participant Tags as Tag Resolution<br/>(findReleaseStreamTags)
participant Images as Image Discovery<br/>(GetImageInfo)
participant Streams as Stream Discovery<br/>(ListMachineOSStreams)
participant RPM as RPM Operations<br/>(RpmListForStream/<br/>RpmDiffForStream)
Client->>Handler: GET /api/v1/releasestream/{release}/release/{tag}/nodeimageinfo?[from=...]
rect rgba(200, 150, 100, 0.5)
Note over Handler: Parse & Validate
Handler->>Handler: Parse tag as semver (tolerant)
Handler->>Handler: Validate tag not <4.19
alt from parameter present
Handler->>Handler: Parse from as semver (tolerant)
Handler->>Handler: Validate both are 4.19+
Handler->>Handler: Validate same major.minor
end
end
rect rgba(100, 150, 200, 0.5)
Note over Handler,Tags: Resolve Tags
Handler->>Tags: findReleaseStreamTags(tag, [from])
Tags-->>Handler: Resolved release tags
Handler->>Handler: Validate tag in {release} stream
end
rect rgba(150, 200, 100, 0.5)
Note over Handler,Images: Fetch Image Info
Handler->>Images: GetImageInfo(target pullspec)
Images-->>Handler: Digest pullspec
alt from parameter present
Handler->>Images: GetImageInfo(from pullspec)
Images-->>Handler: From digest pullspec
end
end
rect rgba(200, 100, 150, 0.5)
Note over Handler,Streams: Discover Streams
Handler->>Streams: ListMachineOSStreams
Streams-->>Handler: Machine OS streams
end
rect rgba(150, 100, 200, 0.5)
Note over Handler,RPM: Process RPM Data
alt from parameter absent
Handler->>RPM: RpmListForStream per stream
RPM-->>Handler: RPM package lists
Handler->>Handler: Build APINodeImageInfo
else from parameter present
Handler->>RPM: RpmDiffForStream per stream
RPM-->>Handler: RPM diffs
Handler->>Handler: Build APINodeImageDiff
end
end
Handler->>Client: Return JSON response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: cverna The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
cmd/release-controller-api/http.go (1)
883-923: Unusedtagparameter.The
tagparameter is passed to this function but never used. Consider removing it or adding debug logging that includes the tag name for troubleshooting.♻️ Option 1: Remove unused parameter
-func (c *Controller) apiNodeImageInfoList(w http.ResponseWriter, tag, pullspec string, streams []releasecontroller.MachineOSStreamInfo) { +func (c *Controller) apiNodeImageInfoList(w http.ResponseWriter, pullspec string, streams []releasecontroller.MachineOSStreamInfo) {And update the call site at line 858:
- c.apiNodeImageInfoList(w, tag, toDigestPullSpec, streams) + c.apiNodeImageInfoList(w, toDigestPullSpec, streams)♻️ Option 2: Add debug logging
func (c *Controller) apiNodeImageInfoList(w http.ResponseWriter, tag, pullspec string, streams []releasecontroller.MachineOSStreamInfo) { var response releasecontroller.APINodeImageInfo + klog.V(4).Infof("Fetching node image info for tag %s", tag)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmd/release-controller-api/http.go` around lines 883 - 923, The apiNodeImageInfoList function has an unused parameter named tag; either remove the tag parameter from the apiNodeImageInfoList signature and update all call sites that pass a tag to this function (so callers no longer provide that argument), or keep the parameter and use it (e.g., add a debug/log line using tag) so it is not unused; locate the function apiNodeImageInfoList and its callers to apply the change consistently (update function signature in Controller and every invocation) or add logging inside apiNodeImageInfoList referencing tag for troubleshooting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmd/release-controller-api/http.go`:
- Around line 731-745: In writeAPIError, the result of w.Write(data) is not
checked; update writeAPIError to capture and log the error from w.Write (and
also from fmt.Fprintln) using klog.Errorf just like writeAPIResponse does: after
marshalling, assign err = w.Write(data) and if err != nil log it with a clear
message referencing writeAPIError, and likewise check the error returned by
fmt.Fprintln(w) and log it if non-nil so both write calls are consistently
logged on failure.
---
Nitpick comments:
In `@cmd/release-controller-api/http.go`:
- Around line 883-923: The apiNodeImageInfoList function has an unused parameter
named tag; either remove the tag parameter from the apiNodeImageInfoList
signature and update all call sites that pass a tag to this function (so callers
no longer provide that argument), or keep the parameter and use it (e.g., add a
debug/log line using tag) so it is not unused; locate the function
apiNodeImageInfoList and its callers to apply the change consistently (update
function signature in Controller and every invocation) or add logging inside
apiNodeImageInfoList referencing tag for troubleshooting.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 4121b9f2-5ab9-4095-ba87-aa08a08daa38
📒 Files selected for processing (2)
cmd/release-controller-api/http.gopkg/release-controller/types.go
| func writeAPIError(w http.ResponseWriter, code int, message string) { | ||
| w.Header().Set("Content-Type", "application/json") | ||
| w.WriteHeader(code) | ||
| response := releasecontroller.APIError{ | ||
| Code: code, | ||
| Message: message, | ||
| } | ||
| data, err := json.MarshalIndent(&response, "", " ") | ||
| if err != nil { | ||
| klog.Errorf("Failed to marshal API error response: %v", err) | ||
| return | ||
| } | ||
| w.Write(data) | ||
| fmt.Fprintln(w) | ||
| } |
There was a problem hiding this comment.
Unchecked w.Write error on line 743.
For consistency with writeAPIResponse (line 753-754), the write error should be logged even though it cannot be recovered from in an error path.
🔧 Proposed fix
- w.Write(data)
+ if _, err := w.Write(data); err != nil {
+ klog.Errorf("Failed to write API error response: %v", err)
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func writeAPIError(w http.ResponseWriter, code int, message string) { | |
| w.Header().Set("Content-Type", "application/json") | |
| w.WriteHeader(code) | |
| response := releasecontroller.APIError{ | |
| Code: code, | |
| Message: message, | |
| } | |
| data, err := json.MarshalIndent(&response, "", " ") | |
| if err != nil { | |
| klog.Errorf("Failed to marshal API error response: %v", err) | |
| return | |
| } | |
| w.Write(data) | |
| fmt.Fprintln(w) | |
| } | |
| func writeAPIError(w http.ResponseWriter, code int, message string) { | |
| w.Header().Set("Content-Type", "application/json") | |
| w.WriteHeader(code) | |
| response := releasecontroller.APIError{ | |
| Code: code, | |
| Message: message, | |
| } | |
| data, err := json.MarshalIndent(&response, "", " ") | |
| if err != nil { | |
| klog.Errorf("Failed to marshal API error response: %v", err) | |
| return | |
| } | |
| if _, err := w.Write(data); err != nil { | |
| klog.Errorf("Failed to write API error response: %v", err) | |
| } | |
| fmt.Fprintln(w) | |
| } |
🧰 Tools
🪛 golangci-lint (2.11.4)
[error] 743-743: Error return value of w.Write is not checked
(errcheck)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@cmd/release-controller-api/http.go` around lines 731 - 745, In writeAPIError,
the result of w.Write(data) is not checked; update writeAPIError to capture and
log the error from w.Write (and also from fmt.Fprintln) using klog.Errorf just
like writeAPIResponse does: after marshalling, assign err = w.Write(data) and if
err != nil log it with a clear message referencing writeAPIError, and likewise
check the error returned by fmt.Fprintln(w) and log it if non-nil so both write
calls are consistently logged on failure.
|
/hold /cc @sdodson |
|
@cverna: The following test failed, say
Full PR test history. Your PR dashboard. DetailsInstructions 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. |
Understood. Still would be super valuable for verifying CVEs and in general getting quick access to the list of packages in RHCOS. It is reusing the same CachingReleaseInfo layer, so repeated requests for the same release won't hit oc. However, I understand first-access load is the concern. |
|
Closing in favor of #750, will wait to see if I can work with this :-) |
Add a new JSON API endpoint that exposes RPM package information for release node images, similar to the "Node Image Info" section shown on release pages. This endpoint would particularly be useful for AI Agents to easily access that information.
Endpoint: /api/v1/releasestream/{release}/release/{tag}/nodeimageinfo
Features
Example Usage
Get package list for a release:
GET /api/v1/releasestream/4.22.0-0.nightly/release/4.22.0-0.nightly-2026-04-14-053105/nodeimageinfoGet package diff between two releases:
GET /api/v1/releasestream/4.22.0-0.nightly/release/4.22.0-0.nightly-2026-04-14-053105/nodeimageinfo?from=4.22.0-0.nightly-2026-04-13-120000Response Format
Without ?from=:
With ?from=:
Summary by CodeRabbit
Release Notes