Skip to content

Commit

Permalink
MTV-1717 | Wait for DV status
Browse files Browse the repository at this point in the history
Issue: When CDI is managing lot of DVs at once it can take some time
before the CDI reconciles the DVs status and start the import. In the
function `updateCopyProgress` we check the DV status and if it is paused
we do continue and as next phase we have snapshot removal. So if the DV
is still in paused state and we start the cutover and MTV skips over the
phase thinking it already finished as the DV is in paused.

Fix: Add WaitForDataVolumesStatus phase to wait until the DVs do not have
the paused status.

Ref: https://issues.redhat.com/browse/MTV-1717

https://github.com/kubev2v/forklift/blob/ea83264881b3dcd4a88dd627c1ca75da2483f408/pkg/controller/plan/migration.go#L1573-L1575

Signed-off-by: Martin Necas <[email protected]>
  • Loading branch information
mnecas committed Dec 4, 2024
1 parent 38f14ec commit a5d8249
Showing 1 changed file with 63 additions and 34 deletions.
97 changes: 63 additions & 34 deletions pkg/controller/plan/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,36 +55,38 @@ var (

// Phases.
const (
Started = "Started"
PreHook = "PreHook"
StorePowerState = "StorePowerState"
PowerOffSource = "PowerOffSource"
WaitForPowerOff = "WaitForPowerOff"
CreateDataVolumes = "CreateDataVolumes"
CreateVM = "CreateVM"
CopyDisks = "CopyDisks"
AllocateDisks = "AllocateDisks"
CopyingPaused = "CopyingPaused"
AddCheckpoint = "AddCheckpoint"
AddFinalCheckpoint = "AddFinalCheckpoint"
CreateSnapshot = "CreateSnapshot"
CreateInitialSnapshot = "CreateInitialSnapshot"
CreateFinalSnapshot = "CreateFinalSnapshot"
Finalize = "Finalize"
CreateGuestConversionPod = "CreateGuestConversionPod"
ConvertGuest = "ConvertGuest"
CopyDisksVirtV2V = "CopyDisksVirtV2V"
PostHook = "PostHook"
Completed = "Completed"
WaitForSnapshot = "WaitForSnapshot"
WaitForInitialSnapshot = "WaitForInitialSnapshot"
WaitForFinalSnapshot = "WaitForFinalSnapshot"
ConvertOpenstackSnapshot = "ConvertOpenstackSnapshot"
StoreSnapshotDeltas = "StoreSnapshotDeltas"
StoreInitialSnapshotDeltas = "StoreInitialSnapshotDeltas"
RemovePreviousSnapshot = "RemovePreviousSnapshot"
RemovePenultimateSnapshot = "RemovePenultimateSnapshot"
RemoveFinalSnapshot = "RemoveFinalSnapshot"
Started = "Started"
PreHook = "PreHook"
StorePowerState = "StorePowerState"
PowerOffSource = "PowerOffSource"
WaitForPowerOff = "WaitForPowerOff"
CreateDataVolumes = "CreateDataVolumes"
WaitForDataVolumesStatus = "WaitForDataVolumesStatus"
WaitForFinalDataVolumesStatus = "WaitForFinalDataVolumesStatus"
CreateVM = "CreateVM"
CopyDisks = "CopyDisks"
AllocateDisks = "AllocateDisks"
CopyingPaused = "CopyingPaused"
AddCheckpoint = "AddCheckpoint"
AddFinalCheckpoint = "AddFinalCheckpoint"
CreateSnapshot = "CreateSnapshot"
CreateInitialSnapshot = "CreateInitialSnapshot"
CreateFinalSnapshot = "CreateFinalSnapshot"
Finalize = "Finalize"
CreateGuestConversionPod = "CreateGuestConversionPod"
ConvertGuest = "ConvertGuest"
CopyDisksVirtV2V = "CopyDisksVirtV2V"
PostHook = "PostHook"
Completed = "Completed"
WaitForSnapshot = "WaitForSnapshot"
WaitForInitialSnapshot = "WaitForInitialSnapshot"
WaitForFinalSnapshot = "WaitForFinalSnapshot"
ConvertOpenstackSnapshot = "ConvertOpenstackSnapshot"
StoreSnapshotDeltas = "StoreSnapshotDeltas"
StoreInitialSnapshotDeltas = "StoreInitialSnapshotDeltas"
RemovePreviousSnapshot = "RemovePreviousSnapshot"
RemovePenultimateSnapshot = "RemovePenultimateSnapshot"
RemoveFinalSnapshot = "RemoveFinalSnapshot"
)

// Steps.
Expand Down Expand Up @@ -134,6 +136,7 @@ var (
{Name: WaitForInitialSnapshot},
{Name: StoreInitialSnapshotDeltas, All: VSphere},
{Name: CreateDataVolumes},
{Name: WaitForDataVolumesStatus},
{Name: CopyDisks},
{Name: CopyingPaused},
{Name: RemovePreviousSnapshot, All: VSphere},
Expand All @@ -148,6 +151,7 @@ var (
{Name: CreateFinalSnapshot},
{Name: WaitForFinalSnapshot},
{Name: AddFinalCheckpoint},
{Name: WaitForFinalDataVolumesStatus},
{Name: Finalize},
{Name: RemoveFinalSnapshot, All: VSphere},
{Name: CreateGuestConversionPod, All: RequiresConversion},
Expand Down Expand Up @@ -662,9 +666,9 @@ func (r *Migration) step(vm *plan.VMStatus) (step string) {
step = Initialize
case AllocateDisks:
step = DiskAllocation
case CopyDisks, CopyingPaused, RemovePreviousSnapshot, CreateSnapshot, WaitForSnapshot, StoreSnapshotDeltas, AddCheckpoint, ConvertOpenstackSnapshot:
case CopyDisks, CopyingPaused, RemovePreviousSnapshot, CreateSnapshot, WaitForSnapshot, StoreSnapshotDeltas, AddCheckpoint, ConvertOpenstackSnapshot, WaitForDataVolumesStatus:
step = DiskTransfer
case RemovePenultimateSnapshot, CreateFinalSnapshot, WaitForFinalSnapshot, AddFinalCheckpoint, Finalize, RemoveFinalSnapshot:
case RemovePenultimateSnapshot, CreateFinalSnapshot, WaitForFinalSnapshot, AddFinalCheckpoint, Finalize, RemoveFinalSnapshot, WaitForFinalDataVolumesStatus:
step = Cutover
case CreateGuestConversionPod, ConvertGuest:
step = ImageConversion
Expand Down Expand Up @@ -1039,6 +1043,22 @@ func (r *Migration) execute(vm *plan.VMStatus) (err error) {
if ready {
vm.Phase = r.next(vm.Phase)
}
case WaitForDataVolumesStatus, WaitForFinalDataVolumesStatus:
step, found := vm.FindStep(r.step(vm))
if !found {
vm.AddError(fmt.Sprintf("Step '%s' not found", r.step(vm)))
break
}

dvs, err := r.kubevirt.getDVs(vm)
if err != nil {
step.AddError(err.Error())
err = nil
break
}
if !r.hasPausedDv(dvs) {
vm.Phase = r.next(vm.Phase)
}
case StoreInitialSnapshotDeltas, StoreSnapshotDeltas:
step, found := vm.FindStep(r.step(vm))
if !found {
Expand Down Expand Up @@ -1073,9 +1093,9 @@ func (r *Migration) execute(vm *plan.VMStatus) (err error) {

switch vm.Phase {
case AddCheckpoint:
vm.Phase = CopyDisks
vm.Phase = WaitForDataVolumesStatus
case AddFinalCheckpoint:
vm.Phase = Finalize
vm.Phase = WaitForFinalDataVolumesStatus
}
case StorePowerState:
step, found := vm.FindStep(r.step(vm))
Expand Down Expand Up @@ -1259,6 +1279,15 @@ func (r *Migration) execute(vm *plan.VMStatus) (err error) {
return
}

func (r *Migration) hasPausedDv(dvs []ExtendedDataVolume) bool {
for _, dv := range dvs {
if dv.Status.Phase == Paused {
return true
}
}
return false
}

func (r *Migration) resetPrecopyTasks(vm *plan.VMStatus, step *plan.Step) {
step.Completed = nil
for _, task := range step.Tasks {
Expand Down

0 comments on commit a5d8249

Please sign in to comment.