Skip to content

OTA-1956: pkg/payload: Add Images map and tolerate unknown template fields during upgrades#1410

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
jhadvig:cvo-images-template-support
Jun 24, 2026
Merged

OTA-1956: pkg/payload: Add Images map and tolerate unknown template fields during upgrades#1410
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
jhadvig:cvo-images-template-support

Conversation

@jhadvig

@jhadvig jhadvig commented Jun 22, 2026

Copy link
Copy Markdown
Member

Summary

Two changes to the CVO manifest template engine:

1. Add Images map to manifestRenderConfig

Populated from the release payload's image-references ImageStream. CVO manifests in /manifests/ can now reference component images by short name using Go template syntax: {{index .Images "component-name"}}.

2. Tolerate unknown template fields during LoadUpdate

When an older CVO binary loads a newer payload that uses template fields the older binary does not know about (e.g. .Images), the manifest is skipped with a warning instead of failing the entire payload load. The new CVO binary re-loads the full payload after replacing the old one at run-level 0.

This is needed for upgrade safety. Without it, adding any new template field to a CVO manifest would break upgrades — the old CVO would fail to load the new payload before it can replace itself.

How it works during upgrade

Old CVO (no .Images) loads new payload:
  ✅ CVO deployment.yaml     → {{.ReleaseImage}} renders fine
  ⚠️  console-plugin.yaml    → {{.Images}} unknown → skipped with warning

Old CVO applies run-level 00 → replaces itself

New CVO (has .Images) re-loads payload:
  ✅ CVO deployment.yaml     → {{.ReleaseImage}} renders fine
  ✅ console-plugin.yaml     → {{.Images}} renders fine → applied

Related

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Improved error handling during manifest preprocessing/template rendering: failed manifests are now skipped with a warning instead of impacting the overall result.
  • Improvements

    • Enhanced manifest rendering by resolving release image references and injecting derived image mappings into template inputs (including OpenShift image stream support).
  • Tests

    • Added coverage to ensure manifests with unknown template fields are skipped.
    • Added unit tests for image-reference-to-template mapping behavior.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

manifestRenderConfig gains an Images map[string]string field populated by a new imagesFromImageRef helper that maps ImageStream tag short names to Docker URIs. Render loads image references and fills this map; LoadUpdate forwards the payload ImageRef to loadPayloadTasks, which uses the same helper. Manifest preprocessing failures are now logged as warnings and skipped rather than accumulated as errors.

Changes

Image reference wiring and preprocessing error handling

Layer / File(s) Summary
Image reference contract and helper function
pkg/payload/render.go
Adds imagev1 import and Images map[string]string field to manifestRenderConfig. Introduces imagesFromImageRef helper that iterates ImageStream.Spec.Tags and selects DockerImage sources to build a short-name → Docker URI map, returning an empty map for nil input.
Render function image reference loading
pkg/payload/render.go
Render calls loadImageReferences(releaseManifestsDir), wraps any load error with context, and populates renderConfig.Images from the loaded ImageStream using imagesFromImageRef before passing config through template rendering pipeline.
LoadUpdate and loadPayloadTasks integration
pkg/payload/payload.go
LoadUpdate forwards the loaded payload.ImageRef to loadPayloadTasks. The function signature is extended to accept imageRef and uses imagesFromImageRef(imageRef) to populate manifestRenderConfig.Images during render configuration construction.
Manifest preprocessing error handling
pkg/payload/payload.go
Individual manifest preprocessing and template rendering failures transition from accumulated errors to logged warnings that skip the affected file and continue processing.
imagesFromImageRef unit tests
pkg/payload/render_test.go
New TestImagesFromImageRef with subtests verifies nil input returns empty map, DockerImage tag references map correctly by name to resolved Docker URIs, and non-DockerImage tag sources are excluded. Includes corev1 and imagev1 imports for test fixtures.
LoadUpdate integration test and testdata
pkg/payload/payload_test.go, pkg/payload/testdata/payload-unknown-template/*
TestLoadUpdateSkipsUnknownTemplateFields confirms LoadUpdate succeeds and loads only valid manifests while skipping those referencing unknown template fields. Testdata includes valid ConfigMap with {{.ReleaseImage}}, invalid manifest with {{index .FutureField "some-key"}}, ImageStream resource, and release metadata.

Sequence Diagram(s)

sequenceDiagram
  participant LoadUpdate
  participant loadPayloadTasks
  participant imagesFromImageRef
  participant Render
  participant loadImageReferences
  
  LoadUpdate->>LoadUpdate: Load payload & imageRef
  LoadUpdate->>loadPayloadTasks: Forward payload.ImageRef
  loadPayloadTasks->>imagesFromImageRef: Convert imageRef to tag→URI map
  imagesFromImageRef-->>loadPayloadTasks: Return Images mapping
  loadPayloadTasks->>loadPayloadTasks: Populate manifestRenderConfig.Images
  
  Render->>loadImageReferences: Load from releaseManifestsDir
  loadImageReferences-->>Render: Return ImageStream
  Render->>imagesFromImageRef: Convert to tag→URI map
  imagesFromImageRef-->>Render: Return Images mapping
  Render->>Render: Set renderConfig.Images
  Render->>Render: Execute template rendering with Images config
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (14 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: adding an Images map and tolerating unknown template fields during upgrades, which directly correspond to the core modifications in the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed PR adds tests using Go's standard testing package (testing.T), not Ginkgo. Custom check is specifically about Ginkgo test names, making it inapplicable to this PR.
Test Structure And Quality ✅ Passed The PR adds only standard Go unit tests using testing.T, not Ginkgo tests. The custom check targets Ginkgo-specific patterns (Describe, It, BeforeEach) which do not apply here.
Microshift Test Compatibility ✅ Passed PR adds only Go unit tests using standard testing framework (func Test*), not Ginkgo e2e tests; MicroShift compatibility check only applies to Ginkgo e2e tests.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PR adds only standard Go unit tests (TestLoadUpdateSkipsUnknownTemplateFields, TestImagesFromImageRef) in pkg/, not Ginkgo e2e tests. Check applies only to Ginkgo e2e tests with Describe/Context/It...
Topology-Aware Scheduling Compatibility ✅ Passed This PR modifies only the template rendering infrastructure (payload.go, render.go) to add an 'Images' map for template substitution. No deployment manifests, operator code, or scheduling constrain...
Ote Binary Stdout Contract ✅ Passed No stdout writes in process-level code. New warning logging uses klog.Warningf (routes to stderr via alsologtostderr=true flag) called only during runtime LoadUpdate operations, not in main/init/Be...
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No Ginkgo e2e tests were added. The PR adds only standard Go unit tests (TestLoadUpdateSkipsUnknownTemplateFields and TestImagesFromImageRef) which are not subject to this check.
No-Weak-Crypto ✅ Passed The PR introduces manifest templating enhancements and image reference mapping. No weak cryptography (MD5, SHA1, DES, RC4, ECB), custom crypto implementations, or non-constant-time secret compariso...
Container-Privileges ✅ Passed No privileged container settings (privileged: true, hostPID, hostNetwork, hostIPC, SYS_ADMIN, allowPrivilegeEscalation) found in any newly added files or code changes.
No-Sensitive-Data-In-Logs ✅ Passed The PR adds one new warning log that outputs only the manifest filename and a template execution error (structural info about missing fields), neither of which contains passwords, tokens, API keys,...

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
pkg/payload/render.go (1)

194-210: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add regression tests for the new Images + missingkey=zero behavior.

Line 210 changes template failure semantics, and Lines 195-205 add filtering logic. Please add focused tests for: nil imageRef, non-DockerImage tags being ignored, and missing image keys rendering empty output. This reduces silent-template regressions.

Suggested test shape
diff --git a/pkg/payload/render_test.go b/pkg/payload/render_test.go
@@
 func TestRenderManifest(t *testing.T) {
   tests := []struct {
@@
+    {
+      name: "missing image key renders empty string",
+      config: manifestRenderConfig{
+        Images: map[string]string{"known": "quay.io/example/known:latest"},
+      },
+      manifestFile:         "./testdata/template_with_images.yaml",
+      expectedManifestFile: "./testdata/template_with_images_expected_missing_key.yaml",
+    },
   }
 }
+
+func TestImagesFromImageRef(t *testing.T) {
+  // cover nil imageRef, DockerImage extraction, and non-DockerImage filtering
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/payload/render.go` around lines 194 - 210, The imagesFromImageRef
function and renderManifest function have new logic that needs test coverage to
prevent regressions. Add unit tests that cover: calling imagesFromImageRef with
a nil imageRef parameter to verify it returns an empty map, calling
imagesFromImageRef with tags that have non-DockerImage Kind values to verify
they are filtered out and not included in the returned map, and calling
renderManifest with template variables that reference missing image keys to
verify the missingkey=zero option causes them to render as empty strings instead
of causing template errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/payload/render.go`:
- Around line 194-210: The imagesFromImageRef function and renderManifest
function have new logic that needs test coverage to prevent regressions. Add
unit tests that cover: calling imagesFromImageRef with a nil imageRef parameter
to verify it returns an empty map, calling imagesFromImageRef with tags that
have non-DockerImage Kind values to verify they are filtered out and not
included in the returned map, and calling renderManifest with template variables
that reference missing image keys to verify the missingkey=zero option causes
them to render as empty strings instead of causing template errors.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: f6c9aa5e-9edb-48df-9c96-5c90eecc01a9

📥 Commits

Reviewing files that changed from the base of the PR and between 810bfc1 and 32c326c.

📒 Files selected for processing (2)
  • pkg/payload/payload.go
  • pkg/payload/render.go

@jhadvig jhadvig force-pushed the cvo-images-template-support branch from 32c326c to 6de1020 Compare June 22, 2026 20:51
@jhadvig jhadvig changed the title pkg/payload: Add Images map to manifest template config pkg/payload: Add Images map and tolerate unknown template fields during upgrades Jun 22, 2026
@jhadvig jhadvig force-pushed the cvo-images-template-support branch 2 times, most recently from 5498765 to ddc7fc1 Compare June 22, 2026 21:00
@jhadvig

jhadvig commented Jun 22, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@jhadvig jhadvig force-pushed the cvo-images-template-support branch from ddc7fc1 to 9579083 Compare June 22, 2026 21:08
@jhadvig

jhadvig commented Jun 22, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
pkg/payload/payload_test.go (1)

159-172: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Strengthen the test by asserting rendered content, not just filename presence.

Right now this can pass even if the valid manifest is loaded without actually rendering {{.ReleaseImage}}. Assert the rendered payload contains image:test for 0000_00_valid.yaml.

Suggested test hardening
 	for _, m := range update.Manifests {
 		if m.OriginalFilename == "0000_00_valid.yaml" {
 			foundValid = true
+			if !bytes.Contains(m.Raw, []byte("release-image: 'image:test'")) &&
+				!bytes.Contains(m.Raw, []byte(`release-image: "image:test"`)) &&
+				!bytes.Contains(m.Raw, []byte("release-image: image:test")) {
+				t.Error("valid manifest should render .ReleaseImage to image:test")
+			}
 		}

As per path instructions, “Test Structure and Quality: ... meaningful assertion messages ...” applies here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/payload/payload_test.go` around lines 159 - 172, The test currently only
verifies that the valid manifest file is loaded by checking its filename, but
does not validate that the template rendering actually occurred. Enhance the
test by checking the rendered content of the manifest with filename
"0000_00_valid.yaml" and asserting that it contains the expected rendered value
"image:test" (the result of rendering the {{.ReleaseImage}} template variable).
Store and inspect the rendered payload content of the valid manifest in addition
to checking its OriginalFilename to ensure template substitution actually
happened.

Source: Path instructions

pkg/payload/render.go (2)

188-192: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider documenting the Images field.

The new Images field in manifestRenderConfig lacks a doc comment explaining its purpose. Adding documentation would help future maintainers understand that this field maps component short names to their resolved Docker image URIs from the release payload's image-references ImageStream.

📝 Suggested documentation
 type manifestRenderConfig struct {
 	ReleaseImage   string
 	ClusterProfile string
+	// Images maps component short names to their resolved Docker image URIs
+	// from the release payload's image-references ImageStream.
 	Images         map[string]string
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/payload/render.go` around lines 188 - 192, Add a doc comment above the
Images field in the manifestRenderConfig struct to document its purpose and
explain that it maps component short names to their resolved Docker image URIs
from the release payload's image-references ImageStream. This will help future
maintainers understand the field's role in the configuration structure.

195-205: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider defensive validation in imagesFromImageRef.

The function correctly filters for DockerImage references and handles nil input, but does not validate against edge cases like:

  • Empty tag.From.Name values (would add empty string to map)
  • Duplicate tag names (second occurrence silently overwrites first)

While these cases are unlikely given ImageStream API constraints, adding defensive checks or documenting these assumptions would make the contract clearer.

🛡️ Optional defensive checks
 func imagesFromImageRef(imageRef *imagev1.ImageStream) map[string]string {
 	images := make(map[string]string)
 	if imageRef == nil {
 		return images
 	}
 	for _, tag := range imageRef.Spec.Tags {
-		if tag.From != nil && tag.From.Kind == "DockerImage" {
+		if tag.From != nil && tag.From.Kind == "DockerImage" && tag.From.Name != "" {
+			if _, exists := images[tag.Name]; exists {
+				klog.Warningf("Duplicate image tag %q in image-references, using last occurrence", tag.Name)
+			}
 			images[tag.Name] = tag.From.Name
 		}
 	}
 	return images
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/payload/render.go` around lines 195 - 205, The imagesFromImageRef
function does not validate that tag.From.Name is not empty before adding it to
the images map, which could result in empty string keys being stored. Add a
defensive check in the loop where images are being added to ensure that
tag.From.Name is not an empty string before adding the tag to the map, so that
only valid image references with non-empty names are stored.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/payload/payload_test.go`:
- Around line 159-172: The test currently only verifies that the valid manifest
file is loaded by checking its filename, but does not validate that the template
rendering actually occurred. Enhance the test by checking the rendered content
of the manifest with filename "0000_00_valid.yaml" and asserting that it
contains the expected rendered value "image:test" (the result of rendering the
{{.ReleaseImage}} template variable). Store and inspect the rendered payload
content of the valid manifest in addition to checking its OriginalFilename to
ensure template substitution actually happened.

In `@pkg/payload/render.go`:
- Around line 188-192: Add a doc comment above the Images field in the
manifestRenderConfig struct to document its purpose and explain that it maps
component short names to their resolved Docker image URIs from the release
payload's image-references ImageStream. This will help future maintainers
understand the field's role in the configuration structure.
- Around line 195-205: The imagesFromImageRef function does not validate that
tag.From.Name is not empty before adding it to the images map, which could
result in empty string keys being stored. Add a defensive check in the loop
where images are being added to ensure that tag.From.Name is not an empty string
before adding the tag to the map, so that only valid image references with
non-empty names are stored.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: a213a67d-c36c-4db5-8b77-d3b3fee32bc8

📥 Commits

Reviewing files that changed from the base of the PR and between 810bfc1 and 9579083.

📒 Files selected for processing (8)
  • pkg/payload/payload.go
  • pkg/payload/payload_test.go
  • pkg/payload/render.go
  • pkg/payload/render_test.go
  • pkg/payload/testdata/payload-unknown-template/manifests/0000_00_valid.yaml
  • pkg/payload/testdata/payload-unknown-template/manifests/0000_50_unknown-field.yaml
  • pkg/payload/testdata/payload-unknown-template/release-manifests/image-references
  • pkg/payload/testdata/payload-unknown-template/release-manifests/release-metadata

@jhadvig

jhadvig commented Jun 23, 2026

Copy link
Copy Markdown
Member Author

/retest

1 similar comment
@jhadvig

jhadvig commented Jun 23, 2026

Copy link
Copy Markdown
Member Author

/retest

Comment thread pkg/payload/render_test.go Outdated
}
images := imagesFromImageRef(imageRef)
if len(images) != 2 {
t.Fatalf("expected 2 images, got %d", len(images))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: I find this kind of error message hard to debug, because... we thought we'd get two, but what did we actually get instead? Knowing the length we got is sometimes not enough to track down the divergence between what we expected to happen and where/why reality is diverging. If we're pinning length and both values, it seems like we'd have less code and easier debugging if we built up an expected map and then asserted cmp.Diff(tt.expected, actual); diff != "" as in this existing example.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good call, switched all three test cases to cmp.Diff with expected maps.

@jhadvig jhadvig Jun 23, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Refactored to table-driven, single slice of cases with one loop calling imagesFromImageRef + cmp.Diff, matching the pattern you linked.

@wking wking left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good; thanks! I have one nit on test structure, but it's minor and I don't think we need to block merging on it. I'll add a hold in case you do want to address that comment pre-merge, but feel free to lift the hold without making changes, and we can always come back and tweak the test approach in a follow-up pull or if we ever fail the test-case and get pulled back into that code (which may never happen).

/hold in case you want to address feedback, fine with me if you lift this hold without addressing feedback

@openshift-ci openshift-ci Bot added do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. lgtm Indicates that a PR is ready to be merged. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Jun 23, 2026
@jhadvig jhadvig changed the title pkg/payload: Add Images map and tolerate unknown template fields during upgrades OTA-1956: pkg/payload: Add Images map and tolerate unknown template fields during upgrades Jun 23, 2026
@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, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

@jhadvig: This pull request references OTA-1956 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 "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

Two changes to the CVO manifest template engine:

1. Add Images map to manifestRenderConfig

Populated from the release payload's image-references ImageStream. CVO manifests in /manifests/ can now reference component images by short name using Go template syntax: {{index .Images "component-name"}}.

2. Tolerate unknown template fields during LoadUpdate

When an older CVO binary loads a newer payload that uses template fields the older binary does not know about (e.g. .Images), the manifest is skipped with a warning instead of failing the entire payload load. The new CVO binary re-loads the full payload after replacing the old one at run-level 0.

This is needed for upgrade safety. Without it, adding any new template field to a CVO manifest would break upgrades — the old CVO would fail to load the new payload before it can replace itself.

How it works during upgrade

Old CVO (no .Images) loads new payload:
 ✅ CVO deployment.yaml     → {{.ReleaseImage}} renders fine
 ⚠️  console-plugin.yaml    → {{.Images}} unknown → skipped with warning

Old CVO applies run-level 00 → replaces itself

New CVO (has .Images) re-loads payload:
 ✅ CVO deployment.yaml     → {{.ReleaseImage}} renders fine
 ✅ console-plugin.yaml     → {{.Images}} renders fine → applied

Related

Summary by CodeRabbit

Release Notes

  • Bug Fixes

  • Improved error handling during manifest preprocessing/template rendering: failed manifests are now skipped with a warning instead of impacting the overall result.

  • Improvements

  • Enhanced manifest rendering by resolving release image references and injecting derived image mappings into template inputs.

  • Improved load/update behavior by forwarding the payload image reference into manifest processing.

  • Tests

  • Added coverage to ensure manifests with unknown template fields are skipped.

  • Added unit tests for image-reference-to-template mapping behavior.

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.

@jhadvig jhadvig force-pushed the cvo-images-template-support branch from 9579083 to ad9ee5a Compare June 23, 2026 20:17
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Jun 23, 2026
…ng upgrades

Add an Images field to manifestRenderConfig, populated from the release
payload's image-references ImageStream. This allows CVO manifests in
/manifests/ to reference component images by short name using Go
template syntax: {{index .Images "component-name"}}.

Make template rendering errors non-fatal during LoadUpdate. When an
older CVO binary loads a newer payload that uses template fields the
older binary does not know about (e.g. .Images), the manifest is
skipped with a warning instead of failing the entire payload load.
The new CVO binary will re-load the full payload after it replaces
the old one at run-level 0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jhadvig jhadvig force-pushed the cvo-images-template-support branch from ad9ee5a to 69db689 Compare June 23, 2026 20:30

@wking wking left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

rerolled slice-of-test-cases in TestImagesFromImageRef as of 69db689 looks great to me; thanks! Refreshing my earlier LGTM:

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jun 23, 2026
@openshift-ci

openshift-ci Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jhadvig, wking

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

The pull request process is described here

Details 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

@jhadvig

jhadvig commented Jun 23, 2026

Copy link
Copy Markdown
Member Author

/verified by CI

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Jun 23, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@jhadvig: This PR has been marked as verified by CI.

Details

In response to this:

/verified by CI

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.

@wking

wking commented Jun 23, 2026

Copy link
Copy Markdown
Member

The nit I'd held for has been addressed (thanks!):

/hold cancel

@openshift-ci openshift-ci Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 23, 2026
@wking

wking commented Jun 23, 2026

Copy link
Copy Markdown
Member

I dunno what the templateinstance readiness test should report ready soon after all annotated objects are ready failure on clusterversions.config.openshift.io "version" is forbidden: User "system:anonymous" cannot get resource "clusterversions" in API group "config.openshift.io" at the cluster scope is about, but that and the other failures in that run are unrelated to this pull:

$ w3m -dump -cols 200 'https://search.dptools.openshift.org/?maxAge=24h&type=junit&search=templateinstance+readiness+test+should+report+ready+soon+after+all+annotated+objects+are+ready' | grep 'failures match'
pull-ci-openshift-cluster-version-operator-main-e2e-agnostic-ovn (all) - 7 runs, 43% failed, 33% of failures match = 14% impact
pull-ci-openshift-origin-main-e2e-gcp-ovn (all) - 14 runs, 64% failed, 11% of failures match = 7% impact
periodic-ci-openshift-multiarch-main-nightly-4.18-ocp-e2e-aws-ovn-multi-x-ax (all) - 4 runs, 50% failed, 50% of failures match = 25% impact
periodic-ci-openshift-hypershift-release-4.19-periodics-e2e-kubevirt-metal-conformance-calico (all) - 1 runs, 100% failed, 100% of failures match = 100% impact
periodic-ci-openshift-hypershift-release-4.19-periodics-mce-e2e-kubevirt-metal-ovn-multinet-default-net (all) - 1 runs, 100% failed, 100% of failures match = 100% impact
periodic-ci-openshift-release-main-ci-5.0-e2e-gcp-ovn-upgrade (all) - 44 runs, 55% failed, 4% of failures match = 2% impact
periodic-ci-openshift-release-main-nightly-4.23-e2e-gcp-ovn-runc (all) - 1 runs, 100% failed, 100% of failures match = 100% impact
periodic-ci-openshift-hypershift-release-4.19-periodics-mce-e2e-aws-ovn-conformance (all) - 1 runs, 100% failed, 100% of failures match = 100% impact

/override ci/prow/e2e-agnostic-ovn

@openshift-ci

openshift-ci Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

@wking: Overrode contexts on behalf of wking: ci/prow/e2e-agnostic-ovn

Details

In response to this:

I dunno what the templateinstance readiness test should report ready soon after all annotated objects are ready failure on clusterversions.config.openshift.io "version" is forbidden: User "system:anonymous" cannot get resource "clusterversions" in API group "config.openshift.io" at the cluster scope is about, but that and the other failures in that run are unrelated to this pull:

$ w3m -dump -cols 200 'https://search.dptools.openshift.org/?maxAge=24h&type=junit&search=templateinstance+readiness+test+should+report+ready+soon+after+all+annotated+objects+are+ready' | grep 'failures match'
pull-ci-openshift-cluster-version-operator-main-e2e-agnostic-ovn (all) - 7 runs, 43% failed, 33% of failures match = 14% impact
pull-ci-openshift-origin-main-e2e-gcp-ovn (all) - 14 runs, 64% failed, 11% of failures match = 7% impact
periodic-ci-openshift-multiarch-main-nightly-4.18-ocp-e2e-aws-ovn-multi-x-ax (all) - 4 runs, 50% failed, 50% of failures match = 25% impact
periodic-ci-openshift-hypershift-release-4.19-periodics-e2e-kubevirt-metal-conformance-calico (all) - 1 runs, 100% failed, 100% of failures match = 100% impact
periodic-ci-openshift-hypershift-release-4.19-periodics-mce-e2e-kubevirt-metal-ovn-multinet-default-net (all) - 1 runs, 100% failed, 100% of failures match = 100% impact
periodic-ci-openshift-release-main-ci-5.0-e2e-gcp-ovn-upgrade (all) - 44 runs, 55% failed, 4% of failures match = 2% impact
periodic-ci-openshift-release-main-nightly-4.23-e2e-gcp-ovn-runc (all) - 1 runs, 100% failed, 100% of failures match = 100% impact
periodic-ci-openshift-hypershift-release-4.19-periodics-mce-e2e-aws-ovn-conformance (all) - 1 runs, 100% failed, 100% of failures match = 100% impact

/override ci/prow/e2e-agnostic-ovn

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.

@wking

wking commented Jun 23, 2026

Copy link
Copy Markdown
Member

OAuth HEAD EOF is a widespread problem unrelated to this pull:

$ w3m -dump -cols 200 'https://search.dptools.openshift.org/?maxAge=24h&type=junit&search=Head..https://test-oauth-route-e2e-test-oauth-expiration-.*EOF' | grep 'failures match'
periodic-ci-openshift-release-main-ci-4.21-upgrade-from-stable-4.20-e2e-azure-ovn-upgrade (all) - 5 runs, 20% failed, 100% of failures match = 20% impact
periodic-ci-openshift-release-main-ci-5.0-e2e-gcp-ovn-upgrade (all) - 44 runs, 55% failed, 4% of failures match = 2% impact
periodic-ci-openshift-release-main-ci-5.0-e2e-azure-ovn-upgrade (all) - 30 runs, 30% failed, 22% of failures match = 7% impact
periodic-ci-openshift-release-main-ci-4.21-upgrade-from-stable-4.20-e2e-aws-ovn-upgrade (all) - 7 runs, 14% failed, 100% of failures match = 14% impact
periodic-ci-openshift-release-main-ci-4.14-e2e-azure-ovn-upgrade (all) - 6 runs, 17% failed, 100% of failures match = 17% impact
pull-ci-openshift-api-master-e2e-aws-ovn (all) - 6 runs, 50% failed, 33% of failures match = 17% impact
pull-ci-openshift-cluster-capi-operator-main-e2e-aws-ovn (all) - 1 runs, 100% failed, 100% of failures match = 100% impact
pull-ci-openshift-cluster-monitoring-operator-main-e2e-aws-ovn-techpreview (all) - 8 runs, 88% failed, 14% of failures match = 13% impact
periodic-ci-openshift-release-main-ci-5.0-upgrade-from-stable-4.22-e2e-azure-ovn-upgrade (all) - 40 runs, 23% failed, 11% of failures match = 3% impact
periodic-ci-openshift-release-main-ci-4.15-upgrade-from-stable-4.14-e2e-azure-sdn-upgrade (all) - 6 runs, 100% failed, 17% of failures match = 17% impact
pull-ci-openshift-cluster-monitoring-operator-main-e2e-aws-ovn (all) - 8 runs, 50% failed, 25% of failures match = 13% impact
periodic-ci-openshift-release-main-ci-4.15-e2e-azure-ovn-upgrade (all) - 5 runs, 40% failed, 50% of failures match = 20% impact
periodic-ci-openshift-release-main-ci-4.19-upgrade-from-stable-4.18-e2e-azure-ovn-upgrade (all) - 4 runs, 25% failed, 100% of failures match = 25% impact
periodic-ci-openshift-release-main-ci-5.0-upgrade-from-stable-4.22-e2e-aws-ovn-upgrade (all) - 40 runs, 18% failed, 14% of failures match = 3% impact
periodic-ci-openshift-release-main-ci-4.18-e2e-azure-ovn-upgrade (all) - 4 runs, 25% failed, 100% of failures match = 25% impact
pull-ci-openshift-origin-main-e2e-aws-ovn-fips (all) - 16 runs, 44% failed, 14% of failures match = 6% impact

/override ci/prow/e2e-aws-ovn-techpreview

@openshift-ci

openshift-ci Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

@wking: Overrode contexts on behalf of wking: ci/prow/e2e-aws-ovn-techpreview

Details

In response to this:

OAuth HEAD EOF is a widespread problem unrelated to this pull:

$ w3m -dump -cols 200 'https://search.dptools.openshift.org/?maxAge=24h&type=junit&search=Head..https://test-oauth-route-e2e-test-oauth-expiration-.*EOF' | grep 'failures match'
periodic-ci-openshift-release-main-ci-4.21-upgrade-from-stable-4.20-e2e-azure-ovn-upgrade (all) - 5 runs, 20% failed, 100% of failures match = 20% impact
periodic-ci-openshift-release-main-ci-5.0-e2e-gcp-ovn-upgrade (all) - 44 runs, 55% failed, 4% of failures match = 2% impact
periodic-ci-openshift-release-main-ci-5.0-e2e-azure-ovn-upgrade (all) - 30 runs, 30% failed, 22% of failures match = 7% impact
periodic-ci-openshift-release-main-ci-4.21-upgrade-from-stable-4.20-e2e-aws-ovn-upgrade (all) - 7 runs, 14% failed, 100% of failures match = 14% impact
periodic-ci-openshift-release-main-ci-4.14-e2e-azure-ovn-upgrade (all) - 6 runs, 17% failed, 100% of failures match = 17% impact
pull-ci-openshift-api-master-e2e-aws-ovn (all) - 6 runs, 50% failed, 33% of failures match = 17% impact
pull-ci-openshift-cluster-capi-operator-main-e2e-aws-ovn (all) - 1 runs, 100% failed, 100% of failures match = 100% impact
pull-ci-openshift-cluster-monitoring-operator-main-e2e-aws-ovn-techpreview (all) - 8 runs, 88% failed, 14% of failures match = 13% impact
periodic-ci-openshift-release-main-ci-5.0-upgrade-from-stable-4.22-e2e-azure-ovn-upgrade (all) - 40 runs, 23% failed, 11% of failures match = 3% impact
periodic-ci-openshift-release-main-ci-4.15-upgrade-from-stable-4.14-e2e-azure-sdn-upgrade (all) - 6 runs, 100% failed, 17% of failures match = 17% impact
pull-ci-openshift-cluster-monitoring-operator-main-e2e-aws-ovn (all) - 8 runs, 50% failed, 25% of failures match = 13% impact
periodic-ci-openshift-release-main-ci-4.15-e2e-azure-ovn-upgrade (all) - 5 runs, 40% failed, 50% of failures match = 20% impact
periodic-ci-openshift-release-main-ci-4.19-upgrade-from-stable-4.18-e2e-azure-ovn-upgrade (all) - 4 runs, 25% failed, 100% of failures match = 25% impact
periodic-ci-openshift-release-main-ci-5.0-upgrade-from-stable-4.22-e2e-aws-ovn-upgrade (all) - 40 runs, 18% failed, 14% of failures match = 3% impact
periodic-ci-openshift-release-main-ci-4.18-e2e-azure-ovn-upgrade (all) - 4 runs, 25% failed, 100% of failures match = 25% impact
pull-ci-openshift-origin-main-e2e-aws-ovn-fips (all) - 16 runs, 44% failed, 14% of failures match = 6% impact

/override ci/prow/e2e-aws-ovn-techpreview

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.

@openshift-ci

openshift-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

@jhadvig: all tests passed!

Full PR test history. Your PR dashboard.

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 kubernetes-sigs/prow repository. I understand the commands that are listed here.

@openshift-merge-bot openshift-merge-bot Bot merged commit 12e4168 into openshift:main Jun 24, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants