Make dry-run also generate cluster-resources#1394
Make dry-run also generate cluster-resources#1394javipolo wants to merge 1 commit intoopenshift:mainfrom
Conversation
Signed-off-by: Javi Polo <jpolo@redhat.com>
WalkthroughDry-run functionality now generates cluster resources after writing image mapping log output. When Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant DryRun as Dry-Run Handler
participant ResourceGen as Cluster Resource Generator
participant IDMS as IDMS/ITMS Generator
participant CatalogGen as Catalog Generator
participant SigGen as Signature ConfigMap Generator
participant UpdateSvcGen as UpdateService Generator
participant FileSystem as File System
User->>DryRun: Execute DryRun
DryRun->>FileSystem: Write mapping.txt
DryRun->>ResourceGen: Trigger cluster resource generation
ResourceGen->>IDMS: Generate IDMS/ITMS
IDMS->>FileSystem: Write IDMS/ITMS resources
ResourceGen->>CatalogGen: Generate catalog source & cluster catalog
CatalogGen->>FileSystem: Write catalog resources
ResourceGen->>SigGen: Attempt signature configmap generation
alt Signature ConfigMap Success
SigGen->>FileSystem: Write signature configmap
else Signature ConfigMap Fails
SigGen->>ResourceGen: Downgrade to warning
end
alt OCP Release Image Present
ResourceGen->>UpdateSvcGen: Generate UpdateService
UpdateSvcGen->>FileSystem: Write UpdateService resource
end
ResourceGen-->>DryRun: Cluster resources complete
DryRun-->>User: Dry-run finished
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 12✅ Passed checks (12 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: javipolo 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: 3
🧹 Nitpick comments (2)
internal/pkg/cli/dryrun.go (1)
77-91: Consider downgrading cluster-resource failures to warnings, and drop theClusterResources == nilguard in favor of test mocks.Two small points:
DryRunpreviously always succeeded when the mapping and (optionally) missing files were produced. Now any failure fromIDMS_ITMSGenerator,CatalogSourceGenerator,ClusterCatalogGenerator, orUpdateServiceGeneratorfails the whole dry-run.GenerateSignatureConfigMapis already correctly downgraded to a warning — consider the same treatment for the others so cluster-resource generation issues don't mask the main dry-run output.- The
if o.ClusterResources == nilcheck (with the comment "e.g., in tests") is production code working around test setup. The existingexecutor_test.gohas aMockClusterResourcesno-op implementation — updating the olderTestDryRunsub-tests to inject that mock (like the new sub-test does withclusterresources.New) removes the need for the nil guard.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/pkg/cli/dryrun.go` around lines 77 - 91, Adjust generateClusterResourcesForDryRun so cluster-resource generator failures are logged as warnings instead of returning errors: for IDMS_ITMSGenerator, CatalogSourceGenerator, ClusterCatalogGenerator, and UpdateServiceGenerator catch errors from their calls, call o.Log.Warnf with a descriptive message and continue (mirroring the existing treatment of GenerateSignatureConfigMap), and return nil at the end unless a non-cluster-resource fatal condition occurs; also remove the if o.ClusterResources == nil guard and update tests to inject MockClusterResources (e.g., in TestDryRun) so production code no longer compensates for test setup.internal/pkg/cli/dryrun_test.go (1)
199-203: Sharedglobalis mutated across sub-tests.
globalis declared once at the top ofTestDryRunand each sub-test doesglobal.WorkingDir = testFolder. That's fine whilet.Runsub-tests execute serially, but it's a foot-gun if anyone later addst.Parallel(). Consider constructing a fresh*mirror.GlobalOptionsper sub-test.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/pkg/cli/dryrun_test.go` around lines 199 - 203, The test mutates the package-level variable global across sub-tests (global.WorkingDir = testFolder), which is unsafe for parallel runs; instead, create a fresh *mirror.GlobalOptions per sub-test (e.g., local := &mirror.GlobalOptions{WorkingDir: testFolder, ...}) inside the t.Run closure and use that local instance in calls that currently rely on the package-global, or assign the package-global once from that local before invoking the code under test. Update uses of global in TestDryRun sub-tests to reference the new local variable (or set global = local at the start of the subtest) so each sub-test has its own independent GlobalOptions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/pkg/cli/dryrun_test.go`:
- Around line 282-289: The test's assertions are too weak — they only check that
cluster-resources/ exists but not that the new manifests are created or correct;
update the test in dryrun_test.go to assert specific files exist under
clusterResourcesDir (e.g., idms-oc-mirror.yaml, itms-oc-mirror.yaml, the catalog
source and cluster catalog manifests, the signature ConfigMap, and the
UpdateService manifest for the OCPRelease image) and then read the UpdateService
manifest file to assert its graph image reference matches the value produced by
constructGraphImageRef (or at least contains the expected repository/name like
"graph-data" and not the hardcoded "localhost:5000"), so the test fails if the
OCP-release path or graph image generation regresses.
In `@internal/pkg/cli/dryrun.go`:
- Around line 142-169: Replace the custom, hardcoded logic in
constructGraphImageRef with a call to the real implementation: invoke
o.Release.GraphImage() and return its result (propagate any error), removing the
unused releaseImageParts split and the bogus localhost:5000 fallback and the
incorrect "openshift/graph-data:latest" name; this ensures the dry-run uses the
same registry and image name (openshift/graph-image) as the real flow and stops
relying on ImageSetConfigurationSpec.Mirror.AdditionalImages parsing.
- Around line 116-137: The test data includes release image Origins with the
"docker://" transport prefix which must be stripped before calling
UpdateServiceGenerator; in the loop that finds v2alpha1.TypeOCPRelease (using
allImages and releaseImage), call strings.TrimPrefix(img.Origin,
consts.DockerProtocol) (or trim releaseImage right after assignment) and pass
that trimmed value to o.ClusterResources.UpdateServiceGenerator(graphImageRef,
releaseImage) (ensure constructGraphImageRef still receives the correct input),
so UpdateServiceGenerator gets the unprefixed release image string matching
production ReleaseImage() behavior.
---
Nitpick comments:
In `@internal/pkg/cli/dryrun_test.go`:
- Around line 199-203: The test mutates the package-level variable global across
sub-tests (global.WorkingDir = testFolder), which is unsafe for parallel runs;
instead, create a fresh *mirror.GlobalOptions per sub-test (e.g., local :=
&mirror.GlobalOptions{WorkingDir: testFolder, ...}) inside the t.Run closure and
use that local instance in calls that currently rely on the package-global, or
assign the package-global once from that local before invoking the code under
test. Update uses of global in TestDryRun sub-tests to reference the new local
variable (or set global = local at the start of the subtest) so each sub-test
has its own independent GlobalOptions.
In `@internal/pkg/cli/dryrun.go`:
- Around line 77-91: Adjust generateClusterResourcesForDryRun so
cluster-resource generator failures are logged as warnings instead of returning
errors: for IDMS_ITMSGenerator, CatalogSourceGenerator, ClusterCatalogGenerator,
and UpdateServiceGenerator catch errors from their calls, call o.Log.Warnf with
a descriptive message and continue (mirroring the existing treatment of
GenerateSignatureConfigMap), and return nil at the end unless a
non-cluster-resource fatal condition occurs; also remove the if
o.ClusterResources == nil guard and update tests to inject MockClusterResources
(e.g., in TestDryRun) so production code no longer compensates for test setup.
🪄 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: e0215fdc-bd4e-4be5-9a4a-e764c5506b54
📒 Files selected for processing (2)
internal/pkg/cli/dryrun.gointernal/pkg/cli/dryrun_test.go
| // Verify that the mapping file is still created (existing functionality) | ||
| mappingPath := filepath.Join(testFolder, dryRunOutDir, "mapping.txt") | ||
| assert.FileExists(t, mappingPath) | ||
|
|
||
| // Verify that cluster-resources directory is created | ||
| clusterResourcesPath := filepath.Join(testFolder, clusterResourcesDir) | ||
| assert.DirExists(t, clusterResourcesPath) | ||
| }) |
There was a problem hiding this comment.
Assertions are too weak to cover the actual feature.
The whole point of this PR is that cluster-resources/ now contains IDMS/ITMS, catalog source, cluster catalog, signature configmap, and UpdateService manifests. Asserting only that the directory exists doesn't verify anything new — an empty directory would pass, as would a run that silently dropped the OCP-release path. At minimum, check that the expected files are created (e.g., idms-oc-mirror.yaml, itms-oc-mirror.yaml, and the UpdateService manifest for the OCPRelease image) and, ideally, spot-check that the UpdateService references a sensible graph image. The latter would have surfaced the hardcoded localhost:5000 / openshift/graph-data:latest problem in constructGraphImageRef.
🧪 Suggested stronger assertions
// Verify that cluster-resources directory is created
clusterResourcesPath := filepath.Join(testFolder, clusterResourcesDir)
assert.DirExists(t, clusterResourcesPath)
+
+ // Verify that the expected manifests were actually generated
+ entries, err := os.ReadDir(clusterResourcesPath)
+ if err != nil {
+ t.Fatalf("failed to read cluster-resources dir: %v", err)
+ }
+ assert.NotEmpty(t, entries, "cluster-resources directory should contain generated manifests")
+
+ // Spot-check that UpdateService manifest references the intended graph image,
+ // not a hardcoded localhost:5000 placeholder.
+ // ... read update-service YAML and assert the image reference matches the destination registry🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@internal/pkg/cli/dryrun_test.go` around lines 282 - 289, The test's
assertions are too weak — they only check that cluster-resources/ exists but not
that the new manifests are created or correct; update the test in dryrun_test.go
to assert specific files exist under clusterResourcesDir (e.g.,
idms-oc-mirror.yaml, itms-oc-mirror.yaml, the catalog source and cluster catalog
manifests, the signature ConfigMap, and the UpdateService manifest for the
OCPRelease image) and then read the UpdateService manifest file to assert its
graph image reference matches the value produced by constructGraphImageRef (or
at least contains the expected repository/name like "graph-data" and not the
hardcoded "localhost:5000"), so the test fails if the OCP-release path or graph
image generation regresses.
| // Generate UpdateService if we have release images | ||
| hasReleaseImages := false | ||
| var releaseImage string | ||
| for _, img := range allImages { | ||
| if img.Type == v2alpha1.TypeOCPRelease { | ||
| hasReleaseImages = true | ||
| releaseImage = img.Origin | ||
| break | ||
| } | ||
| } | ||
|
|
||
| if hasReleaseImages { | ||
| // We need to generate a graph image reference for the update service | ||
| // In dry-run mode, we'll use a placeholder or construct the expected reference | ||
| graphImageRef, err := o.constructGraphImageRef(releaseImage) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| if err := o.ClusterResources.UpdateServiceGenerator(graphImageRef, releaseImage); err != nil { | ||
| return err | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Confirm how the non-dry-run path calls UpdateServiceGenerator — particularly
# the form of the releaseImage argument (with or without docker:// prefix).
rg -nP --type=go -C8 'UpdateServiceGenerator\s*\('
# Check whether the production release flow iterates over multiple releases.
rg -nP --type=go -C5 'TypeOCPRelease' -g '!**/dryrun*.go'Repository: openshift/oc-mirror
Length of output: 50375
🏁 Script executed:
# Find the dryrun test file and see what test data is used
fd -i dryrun -type f | grep test
# Also check what the test data setup looks like in dryrun context
rg -nP --type=go 'Origin.*docker://' -g '**dryrun*' -A2 -B2
# Check how allImages is populated in dryrun context
rg -nP --type=go -B10 'hasReleaseImages.*:=' | grep -A10 'dryrun'
# Check if there's a TrimPrefix or similar for docker:// in the codebase
rg -nP --type=go 'TrimPrefix.*docker|DockerProtocol' | head -20Repository: openshift/oc-mirror
Length of output: 4681
🏁 Script executed:
# Find dryrun test file
git ls-files | grep -i dryrun
# Check for TrimPrefix usage with docker protocol to understand the pattern
rg -nP --type=go 'strings.TrimPrefix.*docker|TrimPrefix.*DockerProtocol' -B2 -A2
# Look for how allImages is built in dryrun context
rg -nP --type=go -B20 'hasReleaseImages := false' internal/pkg/cli/dryrun.goRepository: openshift/oc-mirror
Length of output: 3609
🏁 Script executed:
# Read the dryrun_test.go file to see test data
cat -n internal/pkg/cli/dryrun_test.go | head -200
# Also check how allImages is constructed in the dryrun.go function
rg -nP --type=go -A50 'func.*DryRun' internal/pkg/cli/dryrun.go | head -80Repository: openshift/oc-mirror
Length of output: 11633
🏁 Script executed:
# Look for tests that include TypeOCPRelease in dryrun_test.go context
rg -nP --type=go 'TypeOCPRelease' internal/pkg/cli/dryrun_test.go
# Check the CopyImageSchema struct to understand Origin field
rg -nP --type=go -A5 'type CopyImageSchema struct'
# Search for test data with release images in dryrun test
rg -nP --type=go -B5 -A5 'generateClusterResourcesForDryRun' internal/pkg/cli/dryrun_test.goRepository: openshift/oc-mirror
Length of output: 594
🏁 Script executed:
# Get the full context around line 273 in dryrun_test.go
sed -n '250,300p' internal/pkg/cli/dryrun_test.go
# Get the full CopyImageSchema struct definition
rg -nP --type=go -A15 'type CopyImageSchema struct'
# Check if there's a test for release images in dryrun
rg -nP --type=go -B20 -A20 'TypeOCPRelease' internal/pkg/cli/dryrun_test.goRepository: openshift/oc-mirror
Length of output: 4947
🏁 Script executed:
# Find ReleaseImage() method implementation
rg -nP --type=go 'func.*ReleaseImage\(' -A10
# Check what ReleaseImage returns - look at the Release interface/struct
rg -nP --type=go -B5 'ReleaseImage.*func' | head -40
# Check the clusterresources UpdateServiceGenerator implementation to see what it expects
sed -n '608,650p' internal/pkg/clusterresources/clusterresources.goRepository: openshift/oc-mirror
Length of output: 7847
🏁 Script executed:
# Check the ReleaseImage implementation more carefully - what does it return?
sed -n '451,475p' internal/pkg/release/local_stored_collector.go
# Check if there are scenarios with multiple releases - look for loops over Releases
rg -nP --type=go -B5 -A5 'for.*Releases\[' internal/pkg/release/
# Check how production code handles multiple releases in executor.go around UpdateServiceGenerator calls
sed -n '960,985p' internal/pkg/cli/executor.go
# Look at the production release flow to see if it generates one UpdateService per release
rg -nP --type=go 'UpdateServiceGenerator' -B15 -A5 internal/pkg/cli/executor.go | head -60Repository: openshift/oc-mirror
Length of output: 2784
🏁 Script executed:
# Check ReleaseImage() full implementation to understand what it returns
sed -n '451,480p' internal/pkg/release/local_stored_collector.go
# Check if there are multiple TypeOCPRelease entries in typical scenarios
rg -nP --type=go 'o.Releases\[' -B3 -A3 internal/pkg/release/local_stored_collector.go | head -40
# Look at the actual return value from ReleaseImage
rg -nP --type=go -A20 'func.*ReleaseImage.*Context' internal/pkg/release/local_stored_collector.goRepository: openshift/oc-mirror
Length of output: 4021
🏁 Script executed:
# Get the complete ReleaseImage function - need to see the return statement
sed -n '451,500p' internal/pkg/release/local_stored_collector.go
# Check what identifyReleases returns - specifically the .Image field
rg -nP --type=go -B5 'func.*identifyReleases' -A30 internal/pkg/release/local_stored_collector.go | head -50Repository: openshift/oc-mirror
Length of output: 3333
🏁 Script executed:
# Check if GetReleaseReferenceImages can return multiple releases
rg -nP --type=go -B5 'GetReleaseReferenceImages' | head -50
# Check the Cincinnati interface to understand how multiple releases are handled
rg -nP --type=go 'type Cincinnati interface' -A20
# Verify UpdateServiceGenerator is called only once in production paths or once per release
rg -nP --type=go -B30 'UpdateServiceGenerator' internal/pkg/cli/executor.go | grep -A30 'for.*release\|for.*Release'Repository: openshift/oc-mirror
Length of output: 3806
🏁 Script executed:
# Check if there's a loop over releases in production code for UpdateServiceGenerator
rg -nP --type=go -B50 'UpdateServiceGenerator' internal/pkg/cli/executor.go | grep -B50 'for.*release\|for.*Releases\|for _'
# Check if GetReleaseReferenceImages is called multiple times or if it returns multiple but only first is used
rg -nP --type=go 'GetReleaseReferenceImages' -A10 internal/pkg/release/cincinnati.go | head -80Repository: openshift/oc-mirror
Length of output: 1717
🏁 Script executed:
# Check if there's any documentation or comments about multiple releases handling
rg -nP --type=go 'UpdateService.*release\|release.*UpdateService' -B2 -A2 | head -40
# Look at OpenShift docs link in the code to understand UpdateService requirements
rg -nP --type=go 'update-service-create' -B5 -A5
# Check if there are test scenarios with multiple release images
rg -nP --type=go 'TypeOCPRelease.*TypeOCPRelease' internal/pkg/cli/Repository: openshift/oc-mirror
Length of output: 1239
Strip docker:// prefix before passing releaseImage to UpdateServiceGenerator.
The Origin field from the test data (line 272 of dryrun_test.go) contains the docker:// transport prefix—for example, docker://quay.io/openshift-release-dev/ocp-release:4.14.0-x86_64—and is passed directly to UpdateServiceGenerator(graphImageRef, releaseImage) without removing it. The production code calls o.Release.ReleaseImage(), which returns the unprefixed destination reference. Use strings.TrimPrefix(img.Origin, consts.DockerProtocol) before passing the value to UpdateServiceGenerator.
Regarding the loop breaking on the first release image: this matches production behavior, where ReleaseImage() returns only o.Releases[0], so a single UpdateService per execution is the intended design.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@internal/pkg/cli/dryrun.go` around lines 116 - 137, The test data includes
release image Origins with the "docker://" transport prefix which must be
stripped before calling UpdateServiceGenerator; in the loop that finds
v2alpha1.TypeOCPRelease (using allImages and releaseImage), call
strings.TrimPrefix(img.Origin, consts.DockerProtocol) (or trim releaseImage
right after assignment) and pass that trimmed value to
o.ClusterResources.UpdateServiceGenerator(graphImageRef, releaseImage) (ensure
constructGraphImageRef still receives the correct input), so
UpdateServiceGenerator gets the unprefixed release image string matching
production ReleaseImage() behavior.
| // constructGraphImageRef constructs the graph image reference that would be used for UpdateService | ||
| func (o *ExecutorSchema) constructGraphImageRef(releaseImageRef string) (string, error) { | ||
| // In the normal workflow, the graph image is generated by Release.GraphImage() | ||
| // For dry-run, we need to construct what the reference would be | ||
| releaseImageParts := strings.Split(releaseImageRef, "/") | ||
| if len(releaseImageParts) < 3 { | ||
| return "", fmt.Errorf("invalid release image reference: %s", releaseImageRef) | ||
| } | ||
|
|
||
| // Extract destination registry information from the first image | ||
| var destinationRegistry string | ||
| for _, img := range o.Config.ImageSetConfigurationSpec.Mirror.AdditionalImages { | ||
| if strings.Contains(img.Name, "/") { | ||
| // This is a placeholder - in actual implementation, we'd use the destination registry | ||
| // For now, we'll use localhost as placeholder for dry-run | ||
| destinationRegistry = "localhost:5000" | ||
| break | ||
| } | ||
| } | ||
|
|
||
| if destinationRegistry == "" { | ||
| destinationRegistry = "localhost:5000" // Default for dry-run | ||
| } | ||
|
|
||
| // Construct the graph image reference | ||
| graphImageRef := fmt.Sprintf("%s/openshift/graph-data:latest", destinationRegistry) | ||
| return graphImageRef, nil | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Locate the real graph image reference construction in the codebase so we can compare
# against what constructGraphImageRef invents.
rg -nP --type=go -C3 '\bGraphImage\s*\('
rg -nP --type=go -C3 'graph-data|graph-image'
# Confirm Origin convention: does it carry the docker:// prefix in TypeOCPRelease entries?
ast-grep --pattern $'CopyImageSchema{
$$$
Type: v2alpha1.TypeOCPRelease,
$$$
}'
# Find where UpdateServiceGenerator is invoked in the non-dry-run path to see
# exactly what form of releaseImage/graphImage it expects.
rg -nP --type=go -C5 '\bUpdateServiceGenerator\s*\('Repository: openshift/oc-mirror
Length of output: 30443
constructGraphImageRef hardcodes a bogus destination registry and reinvents the graph image reference instead of reusing the real implementation.
A few compounding problems make this function fundamentally incorrect:
-
Hardcoded
localhost:5000. The registry is always set tolocalhost:5000, regardless of whether the user is running M2D, M2M, or D2M. The loop overo.Config.ImageSetConfigurationSpec.Mirror.AdditionalImagesnever reads any value from the images — it only uses the presence of a/as a trigger to assign the literal"localhost:5000". The resulting UpdateService manifest will reference a registry that has nothing to do with the user's actual destination, producing completely incorrect dry-run artifacts. -
Wrong graph image name. The code constructs
openshift/graph-data:latest, but the actual graph image name isopenshift/graph-image(seeinternal/pkg/release/const.go:10). This mismatch means the dry-run output won't match what the real mirror run produces. -
releaseImagePartsis computed but never used. The split happens at line 146 for validation, but the array is discarded immediately after the length check (line 147). -
Should reuse the real implementation. The non-dry-run flow (executor.go lines 970, 1051) directly calls
o.Release.GraphImage()to get the correct reference based onLocalStorageFQDNand the actual release collector state. Dry-run should do the same—invokeo.Release.GraphImage()so the output matches what the actual mirror run will produce, rather than reimplementing and guessing.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@internal/pkg/cli/dryrun.go` around lines 142 - 169, Replace the custom,
hardcoded logic in constructGraphImageRef with a call to the real
implementation: invoke o.Release.GraphImage() and return its result (propagate
any error), removing the unused releaseImageParts split and the bogus
localhost:5000 fallback and the incorrect "openshift/graph-data:latest" name;
this ensures the dry-run uses the same registry and image name
(openshift/graph-image) as the real flow and stops relying on
ImageSetConfigurationSpec.Mirror.AdditionalImages parsing.
|
@javipolo: 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. |
|
@javipolo could you please have a look on the codeRabbit suggestions and also the linter job that is failing? |
Description
Create cluster-resource manifests while running with
--dry-runflagGithub / Jira issue:
https://redhat.atlassian.net/browse/RFE-4107
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Run
oc-mirrorwith--dry-runand manifests should apear in working-dir/cluster-resourcesIt was tested manually
Expected Outcome
Manifests should be present in
cluster-resourcesdirectorySummary by CodeRabbit