Add e2e test for ImageStream stale cross-namespace tag reference (OVP#443)#2313
Add e2e test for ImageStream stale cross-namespace tag reference (OVP#443)#2313kaovilai wants to merge 1 commit into
Conversation
|
Skipping CI for Draft Pull Request. |
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds OpenShift ImageStream scheme registration, bounded ChangesImageStream stale-reference regression
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant E2ESuite
participant runOC
participant KubernetesAPI
participant Velero
E2ESuite->>runOC: Create and promote ImageStreamTag
runOC->>KubernetesAPI: Apply ImageStream resources
E2ESuite->>runOC: Delete source tag and namespace
E2ESuite->>Velero: Start target namespace backup
Velero->>KubernetesAPI: Read target ImageStream data
Velero-->>E2ESuite: Report backup phase and logs
E2ESuite->>Velero: Restore target namespace when fix is merged
Velero->>KubernetesAPI: Recreate ImageStream resources
E2ESuite->>KubernetesAPI: Read restored TagEvent history
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (3 warnings, 1 inconclusive)
✅ Passed checks (11 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (1)
tests/e2e/imagestream_stale_reference_suite_test.go (1)
60-70: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd diagnostic messages to the Gomega assertions.
Include the resource and operation in each failure message so CI output identifies which setup, backup, restore, or status check failed.
As per coding guidelines, “Ginkgo test assertions should include meaningful failure messages.”
Also applies to: 87-94, 103-117, 132-158
🤖 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 `@tests/e2e/imagestream_stale_reference_suite_test.go` around lines 60 - 70, Add meaningful diagnostic messages to every Gomega assertion in the setup and related checks, including the CreateOrUpdate error assertion and each Eventually assertion in the referenced sections. Identify the specific resource and operation—DPA reconciliation, Velero pod readiness, BSL availability, backup, restore, and status checks—so failures clearly indicate what failed.Source: Coding guidelines
🤖 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.
Inline comments:
In `@tests/e2e/imagestream_stale_reference_suite_test.go`:
- Around line 42-43: Update the TODO comment in the stale reference end-to-end
test to reference openshift/openshift-velero-plugin#444 instead of `#443`,
preserving the existing instruction to un-pend the suite once the fix is merged
and vendored.
- Line 44: Add the [apigroup:image.openshift.io] label to the Ginkgo suite
declaration in PDescribe for the stale cross-namespace ImageStream reference
test, preserving its existing Ordered configuration and behavior.
- Around line 50-52: Replace the public registry image assigned to sourceImage
in the stale-reference suite with an image guaranteed to be available through
the CI mirror/internal registry; if no such image exists, mark the suite as
Skipped:Disconnected so disconnected runs do not attempt the pull.
- Around line 156-158: Update the restored-tag verification in the test to use a
bounded gomega.Eventually around getTagItems(targetNamespace, imageStreamName,
tagName), asserting the returned history becomes non-empty before the timeout.
Preserve the existing namespace, ImageStream name, and tag values, and retain
the current failure expectation once the polling deadline is reached.
- Around line 24-28: Update runOC to execute oc through exec.CommandContext with
a bounded timeout and ensure the context is properly cleaned up. In getTagItems,
distinguish Kubernetes NotFound errors from other client failures: preserve the
existing not-found handling, but return non-NotFound errors to the caller so
polling reports authentication or server failures.
- Around line 151-154: Update the Eventually callback in the restore completion
check to return both the success result and the error from
lib.IsRestoreCompletedSuccessfully instead of discarding the error. Preserve the
existing polling intervals and BeTrue assertion so terminal restore failures
propagate immediately.
- Around line 73-82: Update the ginkgo.AfterAll cleanup to assert that
DeleteNamespace succeeds for both sourceNamespace and targetNamespace instead of
discarding their errors, and delete the generated Backup and Restore custom
resources before completing teardown. Preserve the existing DPA deletion and
Velero wait behavior.
In `@tests/e2e/lib/scheme.go`:
- Line 32: Update init in tests/e2e/lib/scheme.go to handle the error returned
by openshiftimagev1.AddToScheme instead of discarding it. Use utilruntime.Must
or an equivalent explicit setup failure while preserving the existing scheme
registration behavior.
---
Nitpick comments:
In `@tests/e2e/imagestream_stale_reference_suite_test.go`:
- Around line 60-70: Add meaningful diagnostic messages to every Gomega
assertion in the setup and related checks, including the CreateOrUpdate error
assertion and each Eventually assertion in the referenced sections. Identify the
specific resource and operation—DPA reconciliation, Velero pod readiness, BSL
availability, backup, restore, and status checks—so failures clearly indicate
what failed.
🪄 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: Repository: openshift/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: ace42979-3c62-41bc-ab1c-3cdbd32b2930
📒 Files selected for processing (2)
tests/e2e/imagestream_stale_reference_suite_test.gotests/e2e/lib/scheme.go
|
/cherry-pick oadp-1.6 |
|
/cherry-pick oadp-1.5 |
|
@kaovilai: once the present PR merges, I will cherry-pick it on top of DetailsIn response to this:
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. |
|
@kaovilai: once the present PR merges, I will cherry-pick it on top of DetailsIn response to this:
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. |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/e2e/imagestream_stale_reference_suite_test.go (1)
71-71: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winAdd failure messages to
Expect(err).NotTo(HaveOccurred())assertions.Several assertions in this test omit a diagnostic message (e.g. Lines 75, 99, 107, 112, 145, 180, 191, 196, 211, 218, 223), so a failure only reports a generic error with no indication of which step failed. Lines 128, 158, 176 already follow the better pattern by attaching
out.As per coding guidelines, "Ginkgo test assertions should include meaningful failure messages to help diagnose what went wrong. Bad:
Expect(err).NotTo(HaveOccurred()). Good:Expect(err).NotTo(HaveOccurred(), "failed to create test pod")."🩹 Example fix (repeat pattern at the other unmessaged call sites)
- err := dpaCR.CreateOrUpdate(dpaSpec) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + err := dpaCR.CreateOrUpdate(dpaSpec) + gomega.Expect(err).NotTo(gomega.HaveOccurred(), "failed to create/update DPA")Also applies to: 98-99, 106-113, 144-146, 179-180, 190-191, 195-197, 210-211, 217-224
🤖 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 `@tests/e2e/imagestream_stale_reference_suite_test.go` at line 71, Update every unmessaged Expect(err).NotTo(HaveOccurred()) assertion in the test setup and execution flows, including the call sites around lines 75, 99, 107, 112, 145, 180, 191, 196, 211, and 218–223, to pass a meaningful step-specific failure message or the relevant out value. Preserve the existing assertions and follow the already-message-bearing patterns near lines 128, 158, and 176.Source: Coding guidelines
♻️ Duplicate comments (2)
tests/e2e/imagestream_stale_reference_suite_test.go (2)
54-67: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winAdd
[apigroup:image.openshift.io]to the suite title.The suite exercises
ImageStream/ImageStreamTag(animage.openshift.ioAPI not available on MicroShift) but thePDescribetitle still lacks the[apigroup:...]tag, so MicroShift-aware test selection can't exclude it once un-pended.As per coding guidelines, "When MicroShift compatibility is needed, use
[apigroup:...]tags (preferred),[Skipped:MicroShift]labels, orexutil.IsMicroShiftCluster()guards to skip tests on MicroShift."🏷️ Proposed fix
-var _ = ginkgo.PDescribe("ImageStream backup with stale cross-namespace tag reference", ginkgo.Ordered, func() { +var _ = ginkgo.PDescribe("ImageStream backup with stale cross-namespace tag reference [apigroup:image.openshift.io]", ginkgo.Ordered, func() {🤖 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 `@tests/e2e/imagestream_stale_reference_suite_test.go` around lines 54 - 67, Update the Ginkgo suite declaration containing PDescribe for “ImageStream backup with stale cross-namespace tag reference” to include the `[apigroup:image.openshift.io]` marker in its title, preserving the existing Ordered configuration and test body.Source: Coding guidelines
87-102: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winDelete the generated Backup/Restore CRs in
AfterAll.Namespace-delete errors are now correctly surfaced (only
NotFoundis tolerated), butbackupName/restoreNameare still never cleaned up here, so every run leaves aBackupandRestoreCR behind innamespace, accumulating across repeated executions.log.Print("Deleting generated Backup/Restore CRs") if backupName != "" { // delete the Backup CR named backupName in namespace, tolerating NotFound } if restoreName != "" { // delete the Restore CR named restoreName in namespace, tolerating NotFound }#!/bin/bash # Check for existing helpers to delete Backup/Restore CRs used elsewhere in the e2e suite. rg -n 'func Delete(Backup|Restore)\b' tests/e2e/lib rg -n 'velerov1\.(Backup|Restore){}' tests/e2e -g '*.go' -A3 -B3🤖 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 `@tests/e2e/imagestream_stale_reference_suite_test.go` around lines 87 - 102, Extend the ginkgo.AfterAll cleanup to delete the generated Backup and Restore CRs identified by backupName and restoreName in namespace, skipping empty names and tolerating only NotFound errors. Reuse existing e2e deletion helpers or the established Velero client patterns, and surface any other deletion failure through the suite assertions before continuing with DPA cleanup.Source: Coding guidelines
🤖 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.
Outside diff comments:
In `@tests/e2e/imagestream_stale_reference_suite_test.go`:
- Line 71: Update every unmessaged Expect(err).NotTo(HaveOccurred()) assertion
in the test setup and execution flows, including the call sites around lines 75,
99, 107, 112, 145, 180, 191, 196, 211, and 218–223, to pass a meaningful
step-specific failure message or the relevant out value. Preserve the existing
assertions and follow the already-message-bearing patterns near lines 128, 158,
and 176.
---
Duplicate comments:
In `@tests/e2e/imagestream_stale_reference_suite_test.go`:
- Around line 54-67: Update the Ginkgo suite declaration containing PDescribe
for “ImageStream backup with stale cross-namespace tag reference” to include the
`[apigroup:image.openshift.io]` marker in its title, preserving the existing
Ordered configuration and test body.
- Around line 87-102: Extend the ginkgo.AfterAll cleanup to delete the generated
Backup and Restore CRs identified by backupName and restoreName in namespace,
skipping empty names and tolerating only NotFound errors. Reuse existing e2e
deletion helpers or the established Velero client patterns, and surface any
other deletion failure through the suite assertions before continuing with DPA
cleanup.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 2bc3a3e8-21ba-46ba-af3a-52e8412236ab
📒 Files selected for processing (1)
tests/e2e/imagestream_stale_reference_suite_test.go
|
/test all |
|
/test all Note Responses generated with Claude |
1 similar comment
|
/test all Note Responses generated with Claude |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@tests/e2e/imagestream_stale_reference_suite_test.go`:
- Around line 220-229: The backup-deletion poll around lib.GetBackup must
propagate errors other than apierrors.IsNotFound(err) instead of converting them
to false. Update the Eventually callback to return the encountered error
alongside its completion status, while preserving successful completion when the
backup is NotFound.
🪄 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: Repository: openshift/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: f3703c13-602a-44c2-b7f8-4eccec979f60
📒 Files selected for processing (1)
tests/e2e/imagestream_stale_reference_suite_test.go
Verbatim reference tags (`oc tag --reference`) produce status tag events with an internal-registry DockerImageReference but an empty Image field: openshift-apiserver's tagReferenceToTagEvent DockerImage branch sets only DockerImageReference, and reference tags are never imported. Building the copy source from the stream's own repository + digest would produce a malformed "<repo>@" reference for such items and fail the backup. There is nothing content-addressed to copy for these events, and the imagestreamtag restore path restores reference tags as pointers without needing image data, so skip them with a log line instead. Surfaced by e2e work in openshift/oadp-operator#2313, which reproduces the stale-reference scenario with a verbatim reference tag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
CopyLocalImageStreamImages built the copy source path from the status
item's DockerImageReference. When an image was promoted across
namespaces (e.g. `oc tag namespace-dev/imagefoo:v1
namespace-int/imagefoo:v1`), that reference can point at the source
namespace's repository, which stops serving the digest once the source
tag is deleted or pruned ("manifest unknown", or a 500 when the source
imagestream/namespace is gone entirely), failing the whole imagestream
backup item.
The digest is by definition a member of the imagestream being copied,
so build the source path from the stream's own namespace/name instead.
Same-namespace references produce byte-identical paths, and backup
(write to migration registry) and restore (read back) become symmetric.
Tag events with no image digest (verbatim reference tags from
`oc tag --reference`) are skipped with a log line: there is nothing
content-addressed to copy, and the imagestreamtag restore path restores
reference tags as pointers without needing image data. Building the
own-repository path for them would produce a malformed "<repo>@"
reference. Surfaced by e2e work in openshift/oadp-operator#2313.
Fixes openshift#443
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
CopyLocalImageStreamImages built the copy source path from the status
item's DockerImageReference. When an image was promoted across
namespaces (e.g. `oc tag namespace-dev/imagefoo:v1
namespace-int/imagefoo:v1`), that reference can point at the source
namespace's repository, which stops serving the digest once the source
tag is deleted or pruned ("manifest unknown", or a 500 when the source
imagestream/namespace is gone entirely), failing the whole imagestream
backup item.
The digest is by definition a member of the imagestream being copied,
so build the source path from the stream's own namespace/name instead.
Same-namespace references produce byte-identical paths, and backup
(write to migration registry) and restore (read back) become symmetric.
Tag events with no image digest (verbatim reference tags from
`oc tag --reference`) are skipped with a log line: there is nothing
content-addressed to copy, and the imagestreamtag restore path restores
reference tags as pointers without needing image data. Building the
own-repository path for them would produce a malformed "<repo>@"
reference. Surfaced by e2e work in openshift/oadp-operator#2313.
Fixes openshift#443
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
|
/test 4.23-ci-index Note Responses generated with Claude |
…444) CopyLocalImageStreamImages built the copy source path from the status item's DockerImageReference. When an image was promoted across namespaces (e.g. `oc tag namespace-dev/imagefoo:v1 namespace-int/imagefoo:v1`), that reference can point at the source namespace's repository, which stops serving the digest once the source tag is deleted or pruned ("manifest unknown", or a 500 when the source imagestream/namespace is gone entirely), failing the whole imagestream backup item. The digest is by definition a member of the imagestream being copied, so build the source path from the stream's own namespace/name instead. Same-namespace references produce byte-identical paths, and backup (write to migration registry) and restore (read back) become symmetric. Tag events with no image digest (verbatim reference tags from `oc tag --reference`) are skipped with a log line: there is nothing content-addressed to copy, and the imagestreamtag restore path restores reference tags as pointers without needing image data. Building the own-repository path for them would produce a malformed "<repo>@" reference. Surfaced by e2e work in openshift/oadp-operator#2313. Fixes #443 Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
|
/test all Note Responses generated with Claude |
a89ea4b to
99e6913
Compare
|
/test all Note Responses generated with Claude |
99e6913 to
8a40419
Compare
|
/test all Note Responses generated with Claude |
8a40419 to
5922fa6
Compare
|
/test all Note Responses generated with Claude |
|
/test 4.23-ci-index Note Responses generated with Claude |
5922fa6 to
db6714d
Compare
|
/test all Note Responses generated with Claude |
|
/test 4.23-e2e-test-aws Note Responses generated with Claude |
db6714d to
cc19916
Compare
|
/test all Note Responses generated with Claude |
|
/test 4.23-ci-index Note Responses generated with Claude |
…ference
Regression coverage for openshift-velero-plugin#443: backing up an
ImageStream whose tag references another namespace's repository in the
internal registry fails once that source repository's tag is deleted
or pruned, because the plugin built the image-copy source path from
the stale DockerImageReference instead of the stream's own repository.
Fixed upstream by openshift-velero-plugin#444 (merged 2026-07-22).
Test flow (tests/e2e/imagestream_stale_reference_suite_test.go):
1. An in-cluster `oc new-build` pushes a real image into a source
namespace's ImageStream, landing it in the internal registry under
that namespace's own repository (an external `oc tag` import would
record the external pull spec instead, and the plugin would skip it
entirely).
2. Create the target ImageStream directly via the API with a status
tag entry copied from the source stream's resolved digest and
DockerImageReference, reproducing the exact "tag references another
namespace's repository" condition the bug depends on. This mirrors
how openshift-velero-plugin's own restore path recreates ImageStream
status (the only way a restored stream's tags are ever populated),
and sidesteps `oc tag` entirely — see the iteration history below
for why. No spec.tags entry is set: a cross-namespace
Kind=ImageStreamImage spec.tags[].from is validated by the apiserver
on every create (including the one Velero's restore performs), and
fails once the source is gone — a separate, restore-time admission
concern this test isn't targeting. The plugin's copy gate only reads
status.tags, so spec.tags isn't needed to reproduce or fix the
backup-time bug.
3. Delete the source tag and the whole source namespace so the source
repository is definitively unavailable.
4. Back up the target namespace: assert it reaches Completed (not
PartiallyFailed), and assert the backup logs show the image copy
ran from the target stream's own repository.
5. Restore into a fresh namespace and confirm the ImageStream comes
back with its tag history intact.
Also registers github.com/openshift/api/image/v1 in the shared e2e
controller-runtime scheme (tests/e2e/lib/scheme.go).
Validated in CI across six revisions of the arrange phase, each
diagnosed against openshift-velero-plugin's actual
CopyLocalImageStreamImages logic (velero-plugins/imagecopy/imagestream.go):
- Against the unfixed plugin, reproduced PartiallyFailed with the
plugin reading from the stale source-namespace repository.
- `oc tag --source=docker --reference`: the `--reference` flag left the
tag event's Image (digest) field empty. The plugin's only hard skip
condition is exactly `len(tag.Items[i].Image) == 0` ("no image
digest, reference tag") — Kind doesn't gate the copy at all, only
whether the copied image also gets a destination :tag label. Copy
never attempted; false green.
- Plain `oc tag src/x:tag dst/x:tag --reference-policy=local` (no
--source=docker): resolved the digest correctly, but on the test
cluster the apiserver normalized DockerImageReference to the
destination's own repository, so the precondition never held.
- `oc tag --source=docker` without `--reference`: resolves the digest
and retains the stale path in principle, but depends on the image
import controller completing an async import of an internal-registry
reference — this never resolved within 5 minutes, identically across
all three OCP lanes tested in one run, ruling out a one-off flake.
- Constructing the target ImageStream directly via the API sidesteps
oc-tag/import-controller behavior and reliably reproduces the backup-
time bug; against the fixed plugin, the backup completes with a
confirmed copy from the target stream's own repository. An interim
revision also set a matching spec.tags[].from (Kind=ImageStreamImage,
cross-namespace) for realism, but that entry fails apiserver
validation on restore once the source is gone (a separate, restore-
time admission concern) — dropped, since it isn't needed for the
plugin's copy gate.
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
cc19916 to
a604ddf
Compare
|
/test all Note Responses generated with Claude |
|
/test 4.22-ci-index Note Responses generated with Claude |
|
/test 5.0-e2e-test-cli-aws Note Responses generated with Claude |
|
@kaovilai: all tests passed! 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. |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: kaovilai, shubham-pampattiwar The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
…452) CopyLocalImageStreamImages built the copy source path from the status item's DockerImageReference. When an image was promoted across namespaces (e.g. `oc tag namespace-dev/imagefoo:v1 namespace-int/imagefoo:v1`), that reference can point at the source namespace's repository, which stops serving the digest once the source tag is deleted or pruned ("manifest unknown", or a 500 when the source imagestream/namespace is gone entirely), failing the whole imagestream backup item. The digest is by definition a member of the imagestream being copied, so build the source path from the stream's own namespace/name instead. Same-namespace references produce byte-identical paths, and backup (write to migration registry) and restore (read back) become symmetric. Tag events with no image digest (verbatim reference tags from `oc tag --reference`) are skipped with a log line: there is nothing content-addressed to copy, and the imagestreamtag restore path restores reference tags as pointers without needing image data. Building the own-repository path for them would produce a malformed "<repo>@" reference. Surfaced by e2e work in openshift/oadp-operator#2313. Fixes #443 Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com> Co-authored-by: Tiger Kaovilai <tkaovila@redhat.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Note
Responses generated with Claude
What this PR does
Adds an e2e regression test for openshift/openshift-velero-plugin#443: ImageStream backup failed with
manifest unknown/500 when a tag was promoted cross-namespace and the source namespace's tag was later deleted/pruned. Fixed upstream by openshift/openshift-velero-plugin#444 (merged 2026-07-22).Test flow (
tests/e2e/imagestream_stale_reference_suite_test.go):oc new-buildpushes a real image into a source namespace's ImageStream — the build's push (not anoc tagimport) is what lands a managed image in the internal registry under that namespace's own repository.oc tag --source=docker <internal-src-ref> --reference --reference-policy=local— stores the tag event verbatim, skipping the apiserver's cross-namespace localize rewrite, deterministically reproducing the stale cross-namespace reference. A precondition assertion verifies the target'sdockerImageReferencestill points at the source namespace's repository before proceeding.Completed(notPartiallyFailed), and assert the backup logs show the image copy actually ran from the target stream's own repository (guards against a false green if image backup is disabled, and directly asserts the fixed source-path behavior).Also registers
github.com/openshift/api/image/v1in the shared e2e controller-runtime scheme (tests/e2e/lib/scheme.go).Validation
This test was iterated in CI against both the unfixed and fixed plugin before landing on the final form:
PartiallyFailed, reading the copy source from the stale source-namespace repository (image-registry...svc:5000/imagestream-stale-ref-src/imagefoo@sha256:..., HTTP 500).quay.io/konveyor/openshift-velero-plugin:latestmirror caught up): backup completes, image copy log shows the target stream's own repository, and restore succeeds with tag history intact.Test plan
go build ./...andgo vet ./...pass fortests/e2e