Skip to content

MTV-5529 | Rework reusing of DI conversion CRs#6846

Open
solenoci wants to merge 8 commits into
kubev2v:mainfrom
solenoci:mtv-5529
Open

MTV-5529 | Rework reusing of DI conversion CRs#6846
solenoci wants to merge 8 commits into
kubev2v:mainfrom
solenoci:mtv-5529

Conversation

@solenoci

@solenoci solenoci commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

Issue: When a plan tries to reuse a deep inspection CR, it doesn't scope it's search to the plan owned/standalone and is reusing old/wring CRs.

Fix: change the search mechanism to first look for plan DI CRs, if not found then look for standalone CRs (with excluding other plans CRs), and if not found create a new plan owned one.

Resolves: MTV-5529
Ref: https://redhat.atlassian.net/browse/MTV-5529

Summary by CodeRabbit

  • Bug Fixes

    • Improved deep inspection conversion resource reuse and lifecycle management during preflight checks.
  • Performance

    • Optimized container image fetching by changing pull policy to fetch images only when not already present locally.
  • Documentation

    • Updated Conversion CR documentation with clearer API endpoint descriptions and warm-migration preflight workflow details.

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 685b74de-048b-443f-a9b7-8070035ab072

📥 Commits

Reviewing files that changed from the base of the PR and between 535a858 and dc5670c.

📒 Files selected for processing (5)
  • docs/conversion-cr.md
  • pkg/controller/conversion/builder.go
  • pkg/controller/conversion/context/doc.go
  • pkg/controller/plan/kubevirt.go
  • pkg/controller/plan/migration.go
💤 Files with no reviewable changes (1)
  • pkg/controller/conversion/context/doc.go

📝 Walkthrough

Walkthrough

The PR refactors deep-inspection Conversion discovery by extracting the lookup logic from Migration's inlined state machine into two new reusable public methods on KubeVirt: GetStandaloneDeepInspectionConversion (with compatibility filtering) and GetPlanDeepInspectionConversion. Migration's PhasePreflightInspection branch now delegates the entire workflow to runPreflightDeepInspection, eliminating code duplication and clarifying the two-phase (plan-owned vs standalone) discovery pattern.

Changes

Deep Inspection Conversion Lookup and Usage

Layer / File(s) Summary
Standalone and Plan-Owned Conversion Lookup APIs
pkg/controller/plan/kubevirt.go
Adds GetStandaloneDeepInspectionConversion and GetPlanDeepInspectionConversion, helper functions for expected disk-encryption, compatibility checks, and phase-priority selection; changes ensureConversion to match exact CR labels (including plan label) and removes retry label stamping in CreateDeepInspectionConversion; refactors GetGuestConversion selector construction.
Migration Preflight Inspection Refactoring
pkg/controller/plan/migration.go
Replaces inline preflight Conversion CR state machine with runPreflightDeepInspection and handleDeepInspectionCR; implements three-stage workflow: plan-owned lookup → standalone lookup with compatibility/phase selection → create plan-owned CR when needed, plus phase-based handling (Succeeded/Failed/Canceled/Pending/Running).
Conversion CR docs and resource placement
docs/conversion-cr.md
Reformats deep-inspection pod endpoints (/ready, /results), rewrites warm-migration PreflightInspection to describe two-phase lookup and decision flow, updates resource placement tables, and simplifies connection-secret keys description.
Builder ImagePullPolicy
pkg/controller/conversion/builder.go
Changes virt-v2v and deep-inspection container ImagePullPolicy from PullAlways to PullIfNotPresent.
Conversion label constants
pkg/controller/conversion/context/doc.go
Removes exported LabelRetryAllowed constant from conversion label key group.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • kubev2v/forklift#6267: Adds XfsCompatibility propagation into the deep-inspection ConversionSpec, which directly aligns with this PR's use of XfsCompatibility for Conversion matching and filtering.

Suggested reviewers

  • yaacov
  • mrnold
  • mnecas

Poem

🐰 I hopped through labels, searches, and phase,
Found plan-owned paths and standalone ways—
Compatibility checked, best-phase crowned,
Docs and pods adjusted, images pulled sound.
A tiny rabbit cheers: migration’s unbound.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: reworking the mechanism for reusing deep-inspection conversion CRs with improved scoping to plan-owned and standalone CRs.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

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

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

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

❤️ Share

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

@codecov-commenter

codecov-commenter commented Jun 1, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 0% with 146 lines in your changes missing coverage. Please review.
✅ Project coverage is 10.80%. Comparing base (f1fe5d0) to head (dc5670c).
⚠️ Report is 2618 commits behind head on main.

Files with missing lines Patch % Lines
pkg/controller/plan/migration.go 0.00% 82 Missing ⚠️
pkg/controller/plan/kubevirt.go 0.00% 62 Missing ⚠️
pkg/controller/conversion/builder.go 0.00% 2 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6846      +/-   ##
==========================================
- Coverage   15.45%   10.80%   -4.65%     
==========================================
  Files         112      521     +409     
  Lines       23377    62539   +39162     
==========================================
+ Hits         3613     6758    +3145     
- Misses      19479    55208   +35729     
- Partials      285      573     +288     
Flag Coverage Δ
unittests 10.80% <0.00%> (-4.65%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@solenoci

solenoci commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai pls review

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get the PR details and diff
gh pr view 6846 --repo kubev2v/forklift --json title,body,files,additions,deletions

echo "=== PR DIFF ==="
gh pr diff 6846 --repo kubev2v/forklift

Length of output: 28581


🏁 Script executed:

#!/bin/bash
# Check if GetDeepInspectionConversion is still used anywhere outside its definition
rg -n "GetDeepInspectionConversion" --type go

Length of output: 432



Confirmed: GetDeepInspectionConversion (lines 668–670 of pkg/controller/plan/kubevirt.go) has no call sites anywhere in the codebase — it's dead code and can be safely removed to avoid confusion with the new GetPlanDeepInspectionConversion.

Here's a summary of all findings:

Severity Location Issue
🐛 Minor kubevirt.go deepInspectionMatchesPlan Typo: "dsik""disk"
🐛 Minor migration.go runPreflightDeepInspection Incomplete comment: "evaluate it di CR"
🐛 Cleanup kubevirt.go lines 668–670 GetDeepInspectionConversion is dead code — no call sites remain; should be deleted
🔶 Edge case Phase 2 deletion loop Multiple failed standalone CRs cleaned up one-per-reconcile; worth a comment
🔶 Ordering Phase 2 delete-then-create Standalone CR deleted before plan-owned CR is created; a comment on the deliberate ordering would help
🔶 Clarity vmDiskEncType Clevis-over-LUKS priority is implicit; a short comment would help

Otherwise the logic is solid — the scoped lookup correctly prevents cross-plan reuse and the phase decision flow matches the documentation exactly. 🐇

Comment thread pkg/controller/plan/kubevirt.go Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Isn't this a dead code now?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

address from coderabbit review

Comment thread pkg/controller/plan/kubevirt.go Outdated

// deepInspectionMatchesPlan reports whether the Conversion CR is compatible with
// what the plan would create for the given VM. Two fields affect this:
// - DiskEncryption.Type: a CR without dsik encryption can't be used for CR with disk encryption set and vice versa,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Typo: should be disk

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

address from coderabbit review

// All errors are consumed internally and recorded on the step, the caller never
// receives a non-nil error from this method.
func (r *Migration) runPreflightDeepInspection(vm *plan.VMStatus, step *plan.Step) (requeue bool) {
snapshotMoref := vm.Warm.Precopies[0].Snapshot

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add a nil guard here

@Hazanel

Hazanel commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Hey @coderabbitai ensureConversion strips LabelPlan from the lookup labels before matching. Can this cause Phase 3 of one plan to match and overwrite a different plan's CR for the same VM, and if so, should LabelPlan be included in the lookup?

@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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/controller/plan/migration.go (1)

1535-1648: 🏗️ Heavy lift

Missing unit test coverage for new deep inspection methods.

The Codecov report indicates 0% coverage on the patch. The new runPreflightDeepInspection and handlePlanDeepInspectionCR methods, along with the helper functions in kubevirt.go, should have unit tests covering the key scenarios:

  • Plan-owned CR exists (Phase 1 → Phase 3)
  • Standalone CR found and succeeded (Phase 2 reuse)
  • Standalone CR found but failed (Phase 2 delete and create new)
  • Standalone CR in progress (Phase 2 requeue)
  • No existing CR (create new)

As per coding guidelines: "Make sure that the code has unit tests."

🤖 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/controller/plan/migration.go` around lines 1535 - 1648, Add unit tests
covering runPreflightDeepInspection and handlePlanDeepInspectionCR and the new
kubevirt helper methods to restore coverage; specifically write table-driven
tests that mock r.kubevirt responses to exercise: (1) plan-owned CR exists and
transitions to Phase 3 (call handlePlanDeepInspectionCR path), (2) standalone CR
found and succeeded (propagateInspectionConcerns and NextPhase), (3) standalone
CR found but failed (DeleteConversion called and CreateDeepInspectionConversion
invoked), (4) standalone CR in progress (returns requeue true), and (5) no
existing CR (CreateDeepInspectionConversion called and returns requeue true).
Use test doubles/fakes for kubevirt methods (GetPlanDeepInspectionConversion,
GetStandaloneDeepInspectionConversion, DeleteConversion,
CreateDeepInspectionConversion) and assert step.Error/step.AddError behavior,
NextPhase calls, and returned requeue booleans; name tests clearly (e.g.,
TestRunPreflightDeepInspection_PlanOwnedExists, _StandaloneSucceeded,
_StandaloneFailedDeletesAndCreates, _StandaloneInProgressRequeues,
_NoExistingCRCreatesAndRequeues) so CI verifies coverage for these functions.
🤖 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 `@pkg/controller/plan/migration.go`:
- Around line 1556-1558: In runPreflightDeepInspection, add a defensive check
before accessing vm.Warm.Precopies[0] — verify vm != nil, vm.Warm != nil and
len(vm.Warm.Precopies) > 0 before reading vm.Warm.Precopies[0].Snapshot; if the
check fails, log a concise warning (using the controller's logger) and return
requeue=true to avoid a panic and retry later. Ensure you update all code paths
in runPreflightDeepInspection that assume vm.Warm.Precopies[0] so they only run
after the guard passes.

---

Nitpick comments:
In `@pkg/controller/plan/migration.go`:
- Around line 1535-1648: Add unit tests covering runPreflightDeepInspection and
handlePlanDeepInspectionCR and the new kubevirt helper methods to restore
coverage; specifically write table-driven tests that mock r.kubevirt responses
to exercise: (1) plan-owned CR exists and transitions to Phase 3 (call
handlePlanDeepInspectionCR path), (2) standalone CR found and succeeded
(propagateInspectionConcerns and NextPhase), (3) standalone CR found but failed
(DeleteConversion called and CreateDeepInspectionConversion invoked), (4)
standalone CR in progress (returns requeue true), and (5) no existing CR
(CreateDeepInspectionConversion called and returns requeue true). Use test
doubles/fakes for kubevirt methods (GetPlanDeepInspectionConversion,
GetStandaloneDeepInspectionConversion, DeleteConversion,
CreateDeepInspectionConversion) and assert step.Error/step.AddError behavior,
NextPhase calls, and returned requeue booleans; name tests clearly (e.g.,
TestRunPreflightDeepInspection_PlanOwnedExists, _StandaloneSucceeded,
_StandaloneFailedDeletesAndCreates, _StandaloneInProgressRequeues,
_NoExistingCRCreatesAndRequeues) so CI verifies coverage for these functions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ee9aca56-60dd-478d-b2a0-3319011f7a3c

📥 Commits

Reviewing files that changed from the base of the PR and between e96a7f5 and 535a858.

⛔ Files ignored due to path filters (1)
  • docs/conversion-cr.md is excluded by !**/*.md
📒 Files selected for processing (2)
  • pkg/controller/plan/kubevirt.go
  • pkg/controller/plan/migration.go

Comment thread pkg/controller/plan/migration.go
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get the full ensureConversion function and surrounding context
rg -n "ensureConversion\|LabelPlan\|GetPlanDeepInspection\|deepInspectionMatch\|Phase" --type go pkg/controller/plan/kubevirt.go | head -120

echo "=== ensureConversion implementation ==="
ast-grep --pattern 'func ($r) ensureConversion($$$) {
  $$$
}'

echo "=== GetPlanDeepInspectionConversion ==="
ast-grep --pattern 'func ($r) GetPlanDeepInspectionConversion($$$) {
  $$$
}'

echo "=== deepInspectionMatchesPlan ==="
ast-grep --pattern 'func ($r) deepInspectionMatchesPlan($$$) {
  $$$
}'

Length of output: 925


🏁 Script executed:

#!/bin/bash
# Get broader context around ensureConversion in kubevirt.go
grep -n "ensureConversion\|LabelPlan\|label\|Label" pkg/controller/plan/kubevirt.go | head -80

echo "=== Full content around ensureConversion ==="
grep -n "func.*ensureConversion\|func.*DeepInspection\|func.*deepInspection" pkg/controller/plan/kubevirt.go

echo "=== Get the PR diff for kubevirt.go ==="
gh pr diff 6846 --repo kubev2v/forklift -- pkg/controller/plan/kubevirt.go

Length of output: 5868



@Hazanel — yes, this is a real concern. Here's the analysis:

How ensureConversion looks up an existing CR in Phase 3:

// line 585-595 (kubevirt.go)
func (r *KubeVirt) ensureConversion(cr *api.Conversion) (*api.Conversion, error) {
    lookupLabels := make(map[string]string, len(cr.Labels))
    for k, v := range cr.Labels {
        if k != convctx.LabelPlan {   // ← LabelPlan stripped
            lookupLabels[k] = v
        }
    }
    // searches by: LabelVM + LabelConversionType + extra (e.g. LabelRetryAllowed)

When CreateDeepInspectionConversion (Phase 3) calls ensureConversion, the lookup matches on:

Label Included in lookup?
LabelVM (vmID)
LabelConversionType (DeepInspection)
LabelPlan (plan UID) ❌ stripped
LabelRetryAllowed (extra)

The cross-plan overwrite scenario:

If Plan A and Plan B both migrate the same VM and both reach Phase 3 simultaneously:

sequenceDiagram
    participant PlanB
    participant PlanA
    participant Cluster

    PlanB->>Cluster: CreateDeepInspectionConversion(vm=X) → CR with LabelPlan=B
    PlanA->>Cluster: ensureConversion lookup (LabelVM=X, LabelType=DI, no LabelPlan)
    Cluster-->>PlanA: returns Plan B's CR (matches!)
    PlanA->>Cluster: existing.Labels = cr.Labels → stamps LabelPlan=A onto Plan B's CR
Loading

Plan B's DI CR is effectively stolen — its LabelPlan is overwritten with Plan A's UID, meaning Plan B's subsequent GetPlanDeepInspectionConversion will no longer find it.

Why LabelPlan was stripped: The comment says it's intentional for the plan-recreation case — when a plan is deleted and re-created, its UID changes, so ensureConversion needs to find the old CR (same VM, same type) without the old plan UID. That's valid.

Suggested fix: For Phase 3 specifically (creating a new plan-owned CR), the lookup should include LabelPlan, since we already know the current plan UID. The re-creation scenario can be handled with a two-step lookup: first try with LabelPlan, and only fall back to the plan-less lookup if nothing is found. Something like:

// Phase 3 create: first try an exact plan-scoped lookup
existing, err := r.getConversion(cr.Labels) // includes LabelPlan
if err != nil || existing == nil {
    // Fall back to plan-agnostic lookup (handles plan re-creation)
    existing, err = r.getConversion(lookupLabels) // without LabelPlan
}

This would prevent Plan A from matching Plan B's CR while still handling the re-creation case. Would you like me to open a follow-up issue for this?

@solenoci

solenoci commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the logic flow issue. Now the flow looks like this
Screenshot From 2026-06-03 12-02-54

@Hazanel

Hazanel commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

lgtm

solenoci added 7 commits June 8, 2026 15:32
Issue: When a plan tries to reuse a deep inspection CR, it doesn't scope
it's search to the plan owned/standalone and is reusing old/wring CRs.

Fix: change the search mechanism to first look for plan DI CRs, if not
found then look for standalone CRs (with excluding other plans CRs), and
if not found create a new plan owned one.

Resolves: MTV-5529
Ref: https://redhat.atlassian.net/browse/MTV-5529

Signed-off-by: Stefan Olenocin <solenoci@redhat.com>
Signed-off-by: Stefan Olenocin <solenoci@redhat.com>
Signed-off-by: Stefan Olenocin <solenoci@redhat.com>
Signed-off-by: Stefan Olenocin <solenoci@redhat.com>
Signed-off-by: Stefan Olenocin <solenoci@redhat.com>
Signed-off-by: Stefan Olenocin <solenoci@redhat.com>
Signed-off-by: Stefan Olenocin <solenoci@redhat.com>
@solenoci

solenoci commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai PTAL

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== Latest PR diff ==="
gh pr diff 6846 --repo kubev2v/forklift

echo ""
echo "=== Check for GetDeepInspectionConversion (dead code) ==="
rg -n "GetDeepInspectionConversion" --type go

echo ""
echo "=== Check for typo 'dsik' ==="
rg -n "dsik" --type go

echo ""
echo "=== Check incomplete comment 'evaluate it di CR' ==="
rg -n "evaluate it" --type go

echo ""
echo "=== ensureConversion full implementation ==="
rg -n "func.*ensureConversion\|LabelPlan\|lookupLabel" --type go pkg/controller/plan/kubevirt.go | head -60

echo ""
echo "=== Check runPreflightDeepInspection ==="
rg -n "runPreflightDeepInspection\|Phase 1\|Phase 2\|Phase 3" --type go pkg/controller/plan/migration.go | head -40

echo ""
echo "=== vmDiskEncType comment check ==="
rg -n "vmDiskEncType\|Clevis\|LUKS\|clevis" --type go pkg/controller/plan/kubevirt.go | head -20

Length of output: 35075



@solenoci — the latest revision looks great. Here's a pass through everything previously raised and the newly-introduced logic:

All prior issues resolved ✅

# What was flagged Status
Dead code GetDeepInspectionConversion ✅ Removed
Typo dsikdisk ✅ Fixed
Incomplete comment "evaluate it di CR" ✅ Fixed
Cross-plan CR overwrite in ensureConversion (Hazanel's concern) ✅ Fixed — LabelPlan stripping removed; lookup now uses full cr.Labels
LabelRetryAllowed complexity ✅ Entire label+retry-label machinery removed; clean 3-phase design instead

New code observations

  • GetStandaloneDeepInspectionConversion uses selection.DoesNotExist on LabelPlan — correct scoping, prevents cross-plan reuse.
  • GetPlanDeepInspectionConversion pins the lookup to the current plan UID — correctly scoped.
  • bestConversionByPhase priority (Succeeded > Running/Pending > other) is clean and readable.
  • handleDeepInspectionCR correctly differentiates plan-owned vs standalone for both Failed and Canceled cases.
  • Bonus: ImagePullPolicy changed from PullAlways to PullIfNotPresent in both GetVirtV2vPodSpec and GetDeepInspectionPodSpec — good improvement.

One minor doc/code discrepancy

The Phase 2 table in docs/conversion-cr.md says:

Failed/CanceledDelete the standalone CR, then fall through to Phase 3 …

But the code intentionally does not delete standalone CRs in either case (PhaseFailed — just creates the plan-owned CR; PhaseCanceled — explicitly commented "we don't own it so we don't delete it"). The behaviour is functionally correct (Phase 1 finds the plan-owned CR on the next reconcile and the standalone is bypassed), but the doc is inaccurate. Worth a one-line fix:

| `Failed`/`Canceled` | Create a plan owned CR (standalone is not deleted); Phase 1 picks up the new CR on the next reconcile. |

Everything else looks solid. Logic matches the updated flow diagram and the documentation. 🐇


🧠 Learnings used
Learnt from: Hazanel
Repo: kubev2v/forklift PR: 0
File: :0-0
Timestamp: 2026-03-08T15:00:17.774Z
Learning: Repo: kubev2v/forklift PR: 5243 — In `pkg/controller/plan/migration.go` `PhasePreflightInspection` case, `ValidatePreflightInspection` is guarded by `!step.MarkedCompleted()` to prevent repeated HTTP calls to the inspection server across reconcile cycles when the pod is still in Running phase after shutdown is requested.

Learnt from: mnecas
Repo: kubev2v/forklift PR: 6015
File: pkg/controller/plan/kubevirt.go:747-749
Timestamp: 2026-04-28T02:28:15.946Z
Learning: In `pkg/controller/plan/kubevirt.go` (kubev2v/forklift PR `#6015`), `NetAppShiftPVCs` intentionally uses migration-scoped labels (`r.vmLabels(vm.Ref)` which includes `kMigration`) when building PVCs for NetApp Shift StorageClasses. This means a new PVC is provisioned on each migration retry rather than reusing an existing one. This is a deliberate design decision by maintainer mnecas and should not be flagged as an idempotency issue.

Learnt from: Hazanel
Repo: kubev2v/forklift PR: 6938
File: pkg/controller/plan/kubevirt.go:1301-1303
Timestamp: 2026-06-07T10:07:16.868Z
Learning: In kubev2v/forklift, the ConfigMap naming helpers genExtraV2vConfConfigMapName, genVddkConfConfigMapName, and genCustomizationScriptsConfigMapName all use the same pattern `plan.Name-<suffix>` (without plan namespace). When reviewing any of these, do not flag the collision concern for just one of them in isolation — any fix should be applied consistently across all three generators in a dedicated PR. The maintainer (Hazanel) explicitly prefers consistency over piecemeal fixes.

Learnt from: yaacov
Repo: kubev2v/forklift PR: 3204
File: operator/.upstream_manifests:156-181
Timestamp: 2025-10-16T14:11:57.112Z
Learning: Repo: kubev2v/forklift — Maintainer yaacov prefers not to create GitHub follow-up issues (e.g., for re-tightening ForkliftController CRD types after temporary relaxation); such work is tracked in a different system. In future reviews, acknowledge and proceed without proposing GitHub issue creation.

Learnt from: solenoci
Repo: kubev2v/forklift PR: 5882
File: pkg/controller/plan/migration.go:1342-1346
Timestamp: 2026-05-05T23:38:06.330Z
Learning: In kubev2v/forklift, when `CreateDeepInspectionConversion` is called from the plan controller (`pkg/controller/plan/migration.go`), `retryAllowed` is intentionally set to `false`. Only Conversion CRs created directly by a user (outside of a Plan) are allowed to carry `retryAllowed=true`. This is a deliberate design decision: the Plan controller owns the lifecycle of plan-managed Conversion CRs and does not delegate retry authority to the CR itself.

Learnt from: Hazanel
Repo: kubev2v/forklift PR: 0
File: :0-0
Timestamp: 2026-02-24T08:36:41.996Z
Learning: Repo: kubev2v/forklift — In pkg/controller/plan/kubevirt.go, EnsureProviderStoragePVC lists by labels that currently include migration UID (via nfsPVCLabels/smbPVCLabels). Because migration UID changes on retries, ensures won’t find prior provider-storage PVCs across retries, leading to new PVCs. Deterministic naming by Plan UID + VM ID is preferred to guarantee idempotency.

Learnt from: yaacov
Repo: kubev2v/forklift PR: 2694
File: operator/.kustomized_manifests:2522-2524
Timestamp: 2025-09-03T07:08:53.741Z
Learning: Forklift Plan CRD: Both Plan.spec.targetAffinity and Plan.spec.convertorAffinity are intentionally annotated as atomic (+structType=atomic), resulting in x-kubernetes-map-type: atomic in the CRD YAML (operator/.kustomized_manifests and operator/config/crd/bases). Do not flag these as incorrect in future reviews.

Learnt from: Hazanel
Repo: kubev2v/forklift PR: 5505
File: pkg/controller/plan/adapter/converter.go:283-284
Timestamp: 2026-03-18T20:44:53.568Z
Learning: In `pkg/controller/plan/adapter/converter.go`, the `makeScratchDV` function explicitly copies `migration` and `vmID` from the source PVC's **labels** (not annotations) into the scratch DataVolume's annotations. A prior bug used `annotations := r.vmLabels(vm.Ref)` which leaked VM labels into PVC annotations; the fix initializes `annotations := make(map[string]string)` and copies from `pvc.Labels["migration"]` and `pvc.Labels["vmID"]`.

Learnt from: Hazanel
Repo: kubev2v/forklift PR: 0
File: :0-0
Timestamp: 2026-03-22T12:26:00.736Z
Learning: Repo: kubev2v/forklift PR: 5599 — In the oVirt adapter (builder.go), the `da.Disk.Lun.LogicalUnits.LogicalUnit[0]` access in `LunPersistentVolumes` and `LunPersistentVolumeClaims` has no explicit bounds check, but this is intentional and safe: the upstream `isLunMissingSize` validator guarantees at least one LogicalUnit is present before these functions are called.

Learnt from: Hazanel
Repo: kubev2v/forklift PR: 0
File: :0-0
Timestamp: 2026-03-08T15:00:17.774Z
Learning: Repo: kubev2v/forklift PR: 5243 — `stripPartitionSuffix` in `pkg/controller/plan/kubevirt.go` uses a three-layer approach: (1) NVMe-partitioned detection via `p`-separator with digit-boundary checks on both sides, (2) NVMe base-device guard (`strings.HasPrefix(basename, "nvme")` → return unchanged), (3) SCSI/virtio fallback via `strings.TrimRight(device, "0123456789")`.

Learnt from: yaacov
Repo: kubev2v/forklift PR: 5727
File: .coderabbit.yaml:3-3
Timestamp: 2026-04-06T09:43:33.951Z
Learning: In kubev2v/forklift, yaacov prefers the auto review to use `profile: chill` (light pass to catch disasters only), with `auto_incremental_review: false` so CodeRabbit does not re-review on each new push. Manual follow-up questions via coderabbitai mentions are the preferred way to do deeper analysis.

Learnt from: Hazanel
Repo: kubev2v/forklift PR: 0
File: :0-0
Timestamp: 2026-06-05T15:38:13.907Z
Learning: Repo: kubev2v/forklift PR: 6937 — For in-place warm virt-v2v conversions, boot disk detection uses `virt-inspector` (not guestfish) to produce structured XML in a single call. The function `detectBootDiskIndexFromPaths` (unexported) in `pkg/virt-v2v/conversion/conversion.go` parses the XML, prefers `/boot/efi` → `/boot` → root device, and calls `deviceToDiskIndex` to convert `/dev/sdX` names to 0-based indices (supports only sda–sdz, 26 disks max by libguestfs design). The result is served via `/bootdisk` HTTP endpoint (204=not detected, 200+JSON=detected) and consumed by `detectBootDiskFromPod` in `pkg/controller/plan/kubevirt.go` using a 30s timeout context. `BootDiskNotDetected` condition is set for all non-200 responses.

Learnt from: yaacov
Repo: kubev2v/forklift PR: 2540
File: pkg/controller/plan/adapter/vsphere/builder.go:694-699
Timestamp: 2025-08-18T13:45:08.364Z
Learning: The user yaacov prefers not to change existing behavior within the scope of a current PR when additional validation or safety checks are identified, and instead prefers to create follow-up issues to address such improvements separately.

Signed-off-by: Stefan Olenocin <solenoci@redhat.com>
@sonarqubecloud

sonarqubecloud Bot commented Jun 8, 2026

Copy link
Copy Markdown

@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.

Actionable comments posted: 5

🤖 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 `@docs/conversion-cr.md`:
- Around line 213-230: The fenced decision-flow block for
PhasePreflightInspection lacks a language tag causing markdown lint errors;
update the opening fence from ``` to a language-tagged fence such as ```text (or
```flow) for the block that begins with "PhasePreflightInspection" so the
markdown linter recognizes the code block and the content (Phase 1 / Phase 2 /
Phase 3 flow) remains unchanged.
- Line 170: Update the phrasing to use hyphenated compound adjectives: replace
occurrences of “two phase” with “two-phase” and “plan owned” with “plan-owned”
(this applies to the sentence containing “two phase lookup” and the other
occurrences at the indicated locations), ensuring consistency across the phrases
“two-phase lookup” and “plan-owned one” in the docs/conversion-cr.md text.
- Around line 198-206: Update the docs to reflect the actual controller
behavior: replace the table rows and explanatory paragraph so they state that
for standalone CRs in `Failed`/`Canceled` state the controller will create a
plan-owned CR and requeue without deleting the standalone CR (the code path is
implemented in runPreflightDeepInspection and handleDeepInspectionCR), and
adjust the rationale that ensureConversion’s plan-label-agnostic lookup means
the controller intentionally leaves the standalone CR in place while adding a
plan-owned CR rather than deleting it before Phase 3; also mirror this change in
the other referenced block (around lines 222-226) so the documentation matches
ensureConversion, runPreflightDeepInspection, and handleDeepInspectionCR
behavior.

In `@pkg/controller/plan/kubevirt.go`:
- Around line 664-690: GetGuestConversion currently lists Conversion CRs only by
convctx.LabelPlan and convctx.LabelVM, so it can return old conversions; scope
the lookup to the active migration by adding a requirement on
convctx.LabelMigration equal to the current migration identifier (the same value
EnsureConversion sets) before calling r.List. Update GetGuestConversion to
include the convctx.LabelMigration selector (use the same migration ID field
that EnsureConversion stamps, e.g. r.Migration.UID or the migration id variable
EnsureConversion uses) so only conversions for the active migration are
returned.

In `@pkg/controller/plan/migration.go`:
- Around line 1695-1700: The call to r.kubevirt.DeleteConversion(cr) can delete
standalone DI pods/secrets because DeleteConversion currently removes resources
by vmID+conversionType only; change the code so cancellation only deletes
resources owned by that plan CR: add a new method (e.g., DeleteConversionOwned
or extend DeleteConversion to accept an owner UID/flag) that filters deletions
by the CR's ownerReference/UID or an owner label, and use that method here (call
DeleteConversionOwned(cr) or DeleteConversion(cr, ownerUID=true)) so only
resources with an ownerReference/label matching cr are removed, leaving
standalone DI resources intact.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 685b74de-048b-443f-a9b7-8070035ab072

📥 Commits

Reviewing files that changed from the base of the PR and between 535a858 and dc5670c.

📒 Files selected for processing (5)
  • docs/conversion-cr.md
  • pkg/controller/conversion/builder.go
  • pkg/controller/conversion/context/doc.go
  • pkg/controller/plan/kubevirt.go
  • pkg/controller/plan/migration.go
💤 Files with no reviewable changes (1)
  • pkg/controller/conversion/context/doc.go

@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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 5

🤖 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 `@docs/conversion-cr.md`:
- Around line 213-230: The fenced decision-flow block for
PhasePreflightInspection lacks a language tag causing markdown lint errors;
update the opening fence from ``` to a language-tagged fence such as ```text (or
```flow) for the block that begins with "PhasePreflightInspection" so the
markdown linter recognizes the code block and the content (Phase 1 / Phase 2 /
Phase 3 flow) remains unchanged.
- Line 170: Update the phrasing to use hyphenated compound adjectives: replace
occurrences of “two phase” with “two-phase” and “plan owned” with “plan-owned”
(this applies to the sentence containing “two phase lookup” and the other
occurrences at the indicated locations), ensuring consistency across the phrases
“two-phase lookup” and “plan-owned one” in the docs/conversion-cr.md text.
- Around line 198-206: Update the docs to reflect the actual controller
behavior: replace the table rows and explanatory paragraph so they state that
for standalone CRs in `Failed`/`Canceled` state the controller will create a
plan-owned CR and requeue without deleting the standalone CR (the code path is
implemented in runPreflightDeepInspection and handleDeepInspectionCR), and
adjust the rationale that ensureConversion’s plan-label-agnostic lookup means
the controller intentionally leaves the standalone CR in place while adding a
plan-owned CR rather than deleting it before Phase 3; also mirror this change in
the other referenced block (around lines 222-226) so the documentation matches
ensureConversion, runPreflightDeepInspection, and handleDeepInspectionCR
behavior.

In `@pkg/controller/plan/kubevirt.go`:
- Around line 664-690: GetGuestConversion currently lists Conversion CRs only by
convctx.LabelPlan and convctx.LabelVM, so it can return old conversions; scope
the lookup to the active migration by adding a requirement on
convctx.LabelMigration equal to the current migration identifier (the same value
EnsureConversion sets) before calling r.List. Update GetGuestConversion to
include the convctx.LabelMigration selector (use the same migration ID field
that EnsureConversion stamps, e.g. r.Migration.UID or the migration id variable
EnsureConversion uses) so only conversions for the active migration are
returned.

In `@pkg/controller/plan/migration.go`:
- Around line 1695-1700: The call to r.kubevirt.DeleteConversion(cr) can delete
standalone DI pods/secrets because DeleteConversion currently removes resources
by vmID+conversionType only; change the code so cancellation only deletes
resources owned by that plan CR: add a new method (e.g., DeleteConversionOwned
or extend DeleteConversion to accept an owner UID/flag) that filters deletions
by the CR's ownerReference/UID or an owner label, and use that method here (call
DeleteConversionOwned(cr) or DeleteConversion(cr, ownerUID=true)) so only
resources with an ownerReference/label matching cr are removed, leaving
standalone DI resources intact.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 685b74de-048b-443f-a9b7-8070035ab072

📥 Commits

Reviewing files that changed from the base of the PR and between 535a858 and dc5670c.

📒 Files selected for processing (5)
  • docs/conversion-cr.md
  • pkg/controller/conversion/builder.go
  • pkg/controller/conversion/context/doc.go
  • pkg/controller/plan/kubevirt.go
  • pkg/controller/plan/migration.go
💤 Files with no reviewable changes (1)
  • pkg/controller/conversion/context/doc.go
🛑 Comments failed to post (5)
docs/conversion-cr.md (3)

170-170: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix compound adjective hyphenation for phase/ownership terms.

Use hyphenated forms in these edited phrases for consistency/readability: “two-phase”, “plan-owned”.

Also applies to: 196-196, 202-202, 209-209

🧰 Tools
🪛 LanguageTool

[grammar] ~170-~170: Use a hyphen to join words.
Context: ...reflightInspection` step through a two phase lookup that can reuse a compatib...

(QB_NEW_EN_HYPHEN)


[grammar] ~170-~170: Use a hyphen to join words.
Context: ...ndalone CR before falling back to a plan owned one. #### Compatibility check Be...

(QB_NEW_EN_HYPHEN)

🤖 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 `@docs/conversion-cr.md` at line 170, Update the phrasing to use hyphenated
compound adjectives: replace occurrences of “two phase” with “two-phase” and
“plan owned” with “plan-owned” (this applies to the sentence containing “two
phase lookup” and the other occurrences at the indicated locations), ensuring
consistency across the phrases “two-phase lookup” and “plan-owned one” in the
docs/conversion-cr.md text.

Source: Linters/SAST tools


198-206: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Deep-inspection flow docs don’t match controller behavior for standalone Failed/Canceled CRs.

The table/flow says standalone Failed/Canceled CRs are deleted before Phase 3, but runPreflightDeepInspection + handleDeepInspectionCR currently create a plan-owned CR and requeue without deleting the standalone CR. Please align this section (including the “deleted before Phase 3” rationale) with the actual logic to avoid operator confusion.

Also applies to: 222-226

🧰 Tools
🪛 LanguageTool

[grammar] ~202-~202: Use a hyphen to join words.
Context: ...ll through to Phase 3 to create the plan owned CR. | | None found ...

(QB_NEW_EN_HYPHEN)

🤖 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 `@docs/conversion-cr.md` around lines 198 - 206, Update the docs to reflect the
actual controller behavior: replace the table rows and explanatory paragraph so
they state that for standalone CRs in `Failed`/`Canceled` state the controller
will create a plan-owned CR and requeue without deleting the standalone CR (the
code path is implemented in runPreflightDeepInspection and
handleDeepInspectionCR), and adjust the rationale that ensureConversion’s
plan-label-agnostic lookup means the controller intentionally leaves the
standalone CR in place while adding a plan-owned CR rather than deleting it
before Phase 3; also mirror this change in the other referenced block (around
lines 222-226) so the documentation matches ensureConversion,
runPreflightDeepInspection, and handleDeepInspectionCR behavior.

213-230: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language tag to the fenced decision-flow block.

The code fence should specify a language (e.g., ```text) to satisfy markdown linting.

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 213-213: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 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 `@docs/conversion-cr.md` around lines 213 - 230, The fenced decision-flow block
for PhasePreflightInspection lacks a language tag causing markdown lint errors;
update the opening fence from ``` to a language-tagged fence such as ```text (or
```flow) for the block that begins with "PhasePreflightInspection" so the
markdown linter recognizes the code block and the content (Phase 1 / Phase 2 /
Phase 3 flow) remains unchanged.

Source: Linters/SAST tools

pkg/controller/plan/kubevirt.go (1)

664-690: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Scope guest Conversion CR lookup to the active migration.

GetGuestConversion() ignores convctx.LabelMigration, but EnsureConversion() stamps that label when it creates the CR. Because old guest Conversion CRs are not cleaned up here, a later retry/run can leave multiple Remote/InPlace CRs for the same plan+VM. Once the pod is gone, updateConversionProgress() can read an older succeeded/failed CR and complete the current step with the wrong status.

Suggested fix
 func (r *KubeVirt) GetGuestConversion(vm *plan.VMStatus) (*api.Conversion, error) {
 	typeReq, err := k8slabels.NewRequirement(
 		convctx.LabelConversionType,
 		selection.In,
 		[]string{string(api.Remote), string(api.InPlace)},
 	)
 	if err != nil {
 		return nil, liberr.Wrap(err)
 	}
 
-	selector := k8slabels.SelectorFromSet(map[string]string{
-		convctx.LabelPlan: string(r.Plan.UID),
-		convctx.LabelVM:   vm.ID,
-	}).Add(*typeReq)
+	match := map[string]string{
+		convctx.LabelPlan: string(r.Plan.UID),
+		convctx.LabelVM:   vm.ID,
+	}
+	if r.Migration != nil {
+		match[convctx.LabelMigration] = string(r.Migration.UID)
+	}
+	selector := k8slabels.SelectorFromSet(match).Add(*typeReq)
🤖 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/controller/plan/kubevirt.go` around lines 664 - 690, GetGuestConversion
currently lists Conversion CRs only by convctx.LabelPlan and convctx.LabelVM, so
it can return old conversions; scope the lookup to the active migration by
adding a requirement on convctx.LabelMigration equal to the current migration
identifier (the same value EnsureConversion sets) before calling r.List. Update
GetGuestConversion to include the convctx.LabelMigration selector (use the same
migration ID field that EnsureConversion stamps, e.g. r.Migration.UID or the
migration id variable EnsureConversion uses) so only conversions for the active
migration are returned.
pkg/controller/plan/migration.go (1)

1695-1700: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Deleting a canceled plan-owned DI CR can tear down standalone DI resources too.

This new DeleteConversion(cr) path is unsafe for the standalone/plan-owned split introduced here. DeleteConversion() currently deletes pods and secrets by only vmID + conversionType, so canceling a plan-owned deep-inspection CR can also remove a standalone deep-inspection pod/secret for the same VM that this plan does not own.

Suggested fix
// pkg/controller/plan/kubevirt.go

 func (r *KubeVirt) deleteConversionPod(cr *api.Conversion) error {
 	...
 	matchLabels := map[string]string{
 		convctx.LabelVM:             cr.Labels[convctx.LabelVM],
 		convctx.LabelConversionType: string(cr.Spec.Type),
 	}
+	if planID := cr.Labels[convctx.LabelPlan]; planID != "" {
+		matchLabels[convctx.LabelPlan] = planID
+	}
 	...
 }

 func (r *KubeVirt) deleteConversionSecrets(cr *api.Conversion) error {
 	...
 	matchLabels := map[string]string{
 		convctx.LabelVM:             vmID,
 		convctx.LabelConversionType: string(cr.Spec.Type),
 	}
+	if planID := cr.Labels[convctx.LabelPlan]; planID != "" {
+		matchLabels[convctx.LabelPlan] = planID
+	}
 	...
 }
🤖 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/controller/plan/migration.go` around lines 1695 - 1700, The call to
r.kubevirt.DeleteConversion(cr) can delete standalone DI pods/secrets because
DeleteConversion currently removes resources by vmID+conversionType only; change
the code so cancellation only deletes resources owned by that plan CR: add a new
method (e.g., DeleteConversionOwned or extend DeleteConversion to accept an
owner UID/flag) that filters deletions by the CR's ownerReference/UID or an
owner label, and use that method here (call DeleteConversionOwned(cr) or
DeleteConversion(cr, ownerUID=true)) so only resources with an
ownerReference/label matching cr are removed, leaving standalone DI resources
intact.

{
Env: nil, // set by type-specific builder
ImagePullPolicy: core.PullAlways,
ImagePullPolicy: core.PullIfNotPresent,

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.

why do we need this?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

we don't, I used pullAlways for testing purposes and thought that I should adhere to the rest of pod definitions, will revert.

solenoci added a commit to solenoci/forklift that referenced this pull request Jun 8, 2026
Issue: DI conversion CR reusing has a bug where it is reusing wrong
conversions from a different plan. The fix could to properly reuse the
conversions with a defined flow.
kubev2v#6846 However that fix is
complicated and could introduce more bugs.

Fix: Instead of implementing the proper reusing of resources
kubev2v#6846 simplify the logic to not
reuse DI conversions at all for now. Later we can add the proper method
defined in the other PR.

Resolves: MTV-5529

Signed-off-by: Stefan Olenocin <solenoci@redhat.com>
solenoci added a commit to solenoci/forklift that referenced this pull request Jun 8, 2026
Issue: DI conversion CR reusing has a bug where it is reusing wrong
conversions from a different plan. The fix could to properly reuse the
conversions with a defined flow.
kubev2v#6846 However that fix is
complicated and could introduce more bugs.

Fix: Instead of implementing the proper reusing of resources
kubev2v#6846 simplify the logic to not
reuse DI conversions at all for now. Later we can add the proper method
defined in the other PR.

Resolves: MTV-5529

Signed-off-by: Stefan Olenocin <solenoci@redhat.com>
Hazanel pushed a commit that referenced this pull request Jun 8, 2026
Issue: DI conversion CR reusing has a bug where it is reusing wrong
conversions from a different plan. The fix could to properly reuse the
conversions with a defined flow.
#6846 However that fix is
complicated and could introduce more bugs.

Fix: Instead of implementing the proper reusing of resources
#6846 simplify the logic to not
reuse DI conversions at all for now. Later we can add the proper method
defined in the other PR.

Resolves: MTV-5529

---------

Signed-off-by: Stefan Olenocin <solenoci@redhat.com>
solenoci added a commit that referenced this pull request Jun 8, 2026
…Rs (#7019)

**Backport:** #7008

Issue: DI conversion CR reusing has a bug where it is reusing wrong
conversions from a different plan. The fix could to properly reuse the
conversions with a defined flow.
#6846 However that fix is
complicated and could introduce more bugs.

Fix: Instead of implementing the proper reusing of resources
#6846 simplify the logic to not
reuse DI conversions at all for now. Later we can add the proper method
defined in the other PR.

Resolves: MTV-5529

---------

Signed-off-by: Stefan Olenocin <solenoci@redhat.com>
Co-authored-by: Stefan Olenocin <solenoci@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants