Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,22 @@ func (h LifeCycleHandler) Handle(ctx context.Context, vdSnapshot *v1alpha2.Virtu
}
}

// Check if we can unfreeze now or need to wait for other VDSnapshots.
canUnfreeze, err := h.snapshotter.CanUnfreezeWithVirtualDiskSnapshot(ctx, vdSnapshot.Name, vm, kvvmi)
if err != nil {
setPhaseConditionToFailed(cb, &vdSnapshot.Status.Phase, err)
return reconcile.Result{}, err
}
if !canUnfreeze {
log.Debug("waiting for other virtual disk snapshots to be ready before unfreezing filesystem")
vdSnapshot.Status.Phase = v1alpha2.VirtualDiskSnapshotPhaseInProgress
cb.
Status(metav1.ConditionFalse).
Reason(vdscondition.Snapshotting).
Message(service.CapitalizeFirstLetter("Waiting for other virtual disk snapshots to be ready before unfreezing filesystem."))
return reconcile.Result{RequeueAfter: 5 * time.Second}, nil
}

err = h.unfreezeFilesystem(ctx, vdSnapshot.Name, vm, kvvmi)
if err != nil {
if k8serrors.IsConflict(err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ var _ = Describe("LifeCycle handler", func() {
SyncFSFreezeRequestFunc: func(_ context.Context, _ *virtv1.VirtualMachineInstance) error {
return nil
},
UnfreezeFunc: func(_ context.Context, _ *virtv1.VirtualMachineInstance) error {
return nil
},
}
})

Expand Down Expand Up @@ -187,7 +190,7 @@ var _ = Describe("LifeCycle handler", func() {
return vs, nil
}
snapshotter.CanUnfreezeWithVirtualDiskSnapshotFunc = func(_ context.Context, _ string, _ *v1alpha2.VirtualMachine, _ *virtv1.VirtualMachineInstance) (bool, error) {
return false, nil
return true, nil
}

h := NewLifeCycleHandler(snapshotter)
Expand All @@ -203,6 +206,34 @@ var _ = Describe("LifeCycle handler", func() {
Expect(ready.Message).To(BeEmpty())
})

It("waits for other VDSnapshots before unfreezing", func() {
vdSnapshot.Status.Phase = v1alpha2.VirtualDiskSnapshotPhaseInProgress
// Set Consistent to skip the early branch that sets consistent=true
vdSnapshot.Status.Consistent = ptr.To(true)

snapshotter.GetVolumeSnapshotFunc = func(_ context.Context, _, _ string) (*vsv1.VolumeSnapshot, error) {
vs.Status = &vsv1.VolumeSnapshotStatus{
ReadyToUse: ptr.To(true),
}
return vs, nil
}
snapshotter.CanUnfreezeWithVirtualDiskSnapshotFunc = func(_ context.Context, _ string, _ *v1alpha2.VirtualMachine, _ *virtv1.VirtualMachineInstance) (bool, error) {
// Simulate other VDSnapshots are still in progress
return false, nil
}

h := NewLifeCycleHandler(snapshotter)

_, err := h.Handle(testContext(), vdSnapshot)
Expect(err).To(BeNil())
// Should stay in InProgress when other snapshots are active
Expect(vdSnapshot.Status.Phase).To(Equal(v1alpha2.VirtualDiskSnapshotPhaseInProgress))
ready, _ := conditions.GetCondition(vdscondition.VirtualDiskSnapshotReadyType, vdSnapshot.Status.Conditions)
Expect(ready.Status).To(Equal(metav1.ConditionFalse))
Expect(ready.Reason).To(Equal(vdscondition.Snapshotting.String()))
Expect(ready.Message).To(ContainSubstring("other virtual disk snapshots"))
})

It("fails when the virtual disk is missing", func() {
snapshotter.GetVirtualDiskFunc = func(_ context.Context, _, _ string) (*v1alpha2.VirtualDisk, error) {
return nil, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"context"

corev1 "k8s.io/api/core/v1"
virtv1 "kubevirt.io/api/core/v1"

"github.com/deckhouse/virtualization/api/core/v1alpha2"
)
Expand All @@ -38,11 +37,4 @@ type Snapshotter interface {
GetPersistentVolumeClaim(ctx context.Context, name, namespace string) (*corev1.PersistentVolumeClaim, error)
GetVirtualDiskSnapshot(ctx context.Context, name, namespace string) (*v1alpha2.VirtualDiskSnapshot, error)
CreateVirtualDiskSnapshot(ctx context.Context, vdSnapshot *v1alpha2.VirtualDiskSnapshot) (*v1alpha2.VirtualDiskSnapshot, error)
Freeze(ctx context.Context, kvvmi *virtv1.VirtualMachineInstance) error
Unfreeze(ctx context.Context, kvvmi *virtv1.VirtualMachineInstance) error
IsFrozen(kvvmi *virtv1.VirtualMachineInstance) (bool, error)
CanFreeze(ctx context.Context, kvvmi *virtv1.VirtualMachineInstance) (bool, error)
CanUnfreezeWithVirtualMachineSnapshot(ctx context.Context, vmSnapshotName string, vm *v1alpha2.VirtualMachine, kvvmi *virtv1.VirtualMachineInstance) (bool, error)
SyncFSFreezeRequest(ctx context.Context, kvvmi *virtv1.VirtualMachineInstance) error
GetVirtualMachineInstance(ctx context.Context, vm *v1alpha2.VirtualMachine) (*virtv1.VirtualMachineInstance, error)
}
Loading
Loading