Skip to content

Commit

Permalink
Merge pull request kubevirt#12478 from ormergi/use-patch-mig-store-tests
Browse files Browse the repository at this point in the history
e2e, storage-migration: Replace client Update operations with patch
  • Loading branch information
kubevirt-bot authored Sep 9, 2024
2 parents f85a811 + 98f52f6 commit 822dec6
Showing 1 changed file with 57 additions and 49 deletions.
106 changes: 57 additions & 49 deletions tests/storage/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package storage
import (
"context"
"fmt"
"slices"
"strconv"
"time"

Expand All @@ -34,12 +35,14 @@ import (

"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/rand"

virtv1 "kubevirt.io/api/core/v1"
"kubevirt.io/client-go/kubecli"
cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1"

"kubevirt.io/kubevirt/pkg/apimachinery/patch"
"kubevirt.io/kubevirt/pkg/controller"
"kubevirt.io/kubevirt/pkg/libvmi"
"kubevirt.io/kubevirt/pkg/pointer"
Expand Down Expand Up @@ -203,53 +206,58 @@ var _ = SIGDescribe("[Serial]Volumes update with migration", Serial, func() {
return vm
}

updateVMWithPVC := func(vmName, volName, claim string) {
var replacedIndex int
vm, err := virtClient.VirtualMachine(ns).Get(context.Background(), vmName, metav1.GetOptions{})
Expect(err).ShouldNot(HaveOccurred())
// Remove datavolume templates
vm.Spec.DataVolumeTemplates = []virtv1.DataVolumeTemplateSpec{}
updateVMWithPVC := func(vm *virtv1.VirtualMachine, volName, claim string) {
// Replace dst pvc
for i, v := range vm.Spec.Template.Spec.Volumes {
if v.Name == volName {
By(fmt.Sprintf("Replacing volume %s with PVC %s", volName, claim))
vm.Spec.Template.Spec.Volumes[i].VolumeSource.PersistentVolumeClaim = &virtv1.PersistentVolumeClaimVolumeSource{
PersistentVolumeClaimVolumeSource: k8sv1.PersistentVolumeClaimVolumeSource{
ClaimName: claim,
},
}
vm.Spec.Template.Spec.Volumes[i].VolumeSource.DataVolume = nil
replacedIndex = i
break
}
}
vm.Spec.UpdateVolumesStrategy = pointer.P(virtv1.UpdateVolumesStrategyMigration)
vm, err = virtClient.VirtualMachine(ns).Update(context.Background(), vm, metav1.UpdateOptions{})
Expect(err).ShouldNot(HaveOccurred())
Expect(vm.Spec.Template.Spec.Volumes[replacedIndex].VolumeSource.PersistentVolumeClaim.
PersistentVolumeClaimVolumeSource.ClaimName).To(Equal(claim))
i := slices.IndexFunc(vm.Spec.Template.Spec.Volumes, func(volume virtv1.Volume) bool {
return volume.Name == volName
})
Expect(i).To(BeNumerically(">", -1))
By(fmt.Sprintf("Replacing volume %s with PVC %s", volName, claim))

updatedVolume := virtv1.Volume{
Name: volName,
VolumeSource: virtv1.VolumeSource{PersistentVolumeClaim: &virtv1.PersistentVolumeClaimVolumeSource{
PersistentVolumeClaimVolumeSource: k8sv1.PersistentVolumeClaimVolumeSource{
ClaimName: claim,
}}}}

p, err := patch.New(
patch.WithReplace("/spec/dataVolumeTemplates", []virtv1.DataVolumeTemplateSpec{}),
patch.WithReplace(fmt.Sprintf("/spec/template/spec/volumes/%d", i), updatedVolume),
patch.WithReplace("/spec/updateVolumesStrategy", virtv1.UpdateVolumesStrategyMigration),
).GeneratePayload()
Expect(err).ToNot(HaveOccurred())
vm, err = virtClient.VirtualMachine(vm.Namespace).Patch(context.Background(), vm.Name, types.JSONPatchType, p, metav1.PatchOptions{})
Expect(err).ToNot(HaveOccurred())

Expect(vm.Spec.Template.Spec.Volumes[i].VolumeSource.PersistentVolumeClaim.
PersistentVolumeClaimVolumeSource.ClaimName).To(Equal(claim))
}
// TODO: right now, for simplicity, this function assumes the DV in the first position in the datavolumes templata list. Otherwise, we need
// to pass the old name of the DV to be replaces.
updateVMWithDV := func(vmName, volName, name string) {
var replacedIndex int
vm, err := virtClient.VirtualMachine(ns).Get(context.Background(), vmName, metav1.GetOptions{})
Expect(err).ShouldNot(HaveOccurred())
vm.Spec.DataVolumeTemplates[0].Name = name
for i, v := range vm.Spec.Template.Spec.Volumes {
if v.Name == volName {
vm.Spec.Template.Spec.Volumes[i].VolumeSource.DataVolume = &virtv1.DataVolumeSource{
Name: name,
}
replacedIndex = i
break
}
}
vm.Spec.UpdateVolumesStrategy = pointer.P(virtv1.UpdateVolumesStrategyMigration)
vm, err = virtClient.VirtualMachine(ns).Update(context.Background(), vm, metav1.UpdateOptions{})
Expect(err).ShouldNot(HaveOccurred())
Expect(vm.Spec.Template.Spec.Volumes[replacedIndex].VolumeSource.DataVolume.Name).To(Equal(name))
updateVMWithDV := func(vm *virtv1.VirtualMachine, volName, name string) {
i := slices.IndexFunc(vm.Spec.Template.Spec.Volumes, func(volume virtv1.Volume) bool {
return volume.Name == volName
})
Expect(i).To(BeNumerically(">", -1))
By(fmt.Sprintf("Replacing volume %s with DV %s", volName, name))

updatedVolume := virtv1.Volume{
Name: volName,
VolumeSource: virtv1.VolumeSource{DataVolume: &virtv1.DataVolumeSource{
Name: name,
}}}

p, err := patch.New(
patch.WithReplace("/spec/dataVolumeTemplates/0/metadata/name", name),
patch.WithReplace(fmt.Sprintf("/spec/template/spec/volumes/%d", i), updatedVolume),
patch.WithReplace("/spec/updateVolumesStrategy", virtv1.UpdateVolumesStrategyMigration),
).GeneratePayload()
Expect(err).ToNot(HaveOccurred())
vm, err = virtClient.VirtualMachine(vm.Namespace).Patch(context.Background(), vm.Name, types.JSONPatchType, p, metav1.PatchOptions{})
Expect(err).ToNot(HaveOccurred())

Expect(vm.Spec.Template.Spec.Volumes[i].VolumeSource.DataVolume.Name).To(Equal(name))
}

BeforeEach(func() {
Expand All @@ -271,7 +279,7 @@ var _ = SIGDescribe("[Serial]Volumes update with migration", Serial, func() {
Fail("Unrecognized mode")
}
By("Update volumes")
updateVMWithPVC(vm.Name, volName, destPVC)
updateVMWithPVC(vm, volName, destPVC)
Eventually(func() bool {
vmi, err := virtClient.VirtualMachineInstance(ns).Get(context.Background(), vm.Name,
metav1.GetOptions{})
Expand All @@ -290,7 +298,7 @@ var _ = SIGDescribe("[Serial]Volumes update with migration", Serial, func() {
vm := createVMWithDV(createDV(), volName)
destDV := createBlankDV()
By("Update volumes")
updateVMWithDV(vm.Name, volName, destDV.Name)
updateVMWithDV(vm, volName, destDV.Name)
Eventually(func() bool {
vmi, err := virtClient.VirtualMachineInstance(ns).Get(context.Background(), vm.Name,
metav1.GetOptions{})
Expand Down Expand Up @@ -322,7 +330,7 @@ var _ = SIGDescribe("[Serial]Volumes update with migration", Serial, func() {
libwait.WaitForSuccessfulVMIStart(vmi)

By("Update volumes")
updateVMWithPVC(vm.Name, volName, destPVC)
updateVMWithPVC(vm, volName, destPVC)
Eventually(func() bool {
vmi, err := virtClient.VirtualMachineInstance(ns).Get(context.Background(), vm.Name,
metav1.GetOptions{})
Expand All @@ -346,11 +354,11 @@ var _ = SIGDescribe("[Serial]Volumes update with migration", Serial, func() {
// Create dest PVC
createUnschedulablePVC(destPVC, ns, size)
By("Update volumes")
updateVMWithPVC(vm.Name, volName, destPVC)
updateVMWithPVC(vm, volName, destPVC)
waitMigrationToExist(vm.Name, ns)
waitVMIToHaveVolumeChangeCond(vm.Name, ns)
By("Cancel the volume migration")
updateVMWithPVC(vm.Name, volName, dv.Name)
updateVMWithPVC(vm, volName, dv.Name)
// After the volume migration abortion the VMI should have:
// 1. the source volume restored
// 2. condition VolumesChange set to false
Expand All @@ -377,7 +385,7 @@ var _ = SIGDescribe("[Serial]Volumes update with migration", Serial, func() {
vm := createVMWithDV(createDV(), volName)
createSmallImageForDestinationMigration(vm, destPVC, size)
By("Update volume")
updateVMWithPVC(vm.Name, volName, destPVC)
updateVMWithPVC(vm, volName, destPVC)
// let the workload updater creates some migration
time.Sleep(2 * time.Minute)
ls := labels.Set{virtv1.VolumesUpdateMigration: vm.Name}
Expand Down Expand Up @@ -413,7 +421,7 @@ var _ = SIGDescribe("[Serial]Volumes update with migration", Serial, func() {
Eventually(matcher.ThisVM(vm), 360*time.Second, 1*time.Second).Should(matcher.BeReady())
libwait.WaitForSuccessfulVMIStart(vmi)
By("Update volumes")
updateVMWithDV(vm.Name, volName, destDV.Name)
updateVMWithDV(vm, volName, destDV.Name)
Eventually(func() []virtv1.VirtualMachineCondition {
vm, err := virtClient.VirtualMachine(vm.Namespace).Get(context.Background(), vm.Name, metav1.GetOptions{})
Expect(err).ToNot(HaveOccurred())
Expand Down

0 comments on commit 822dec6

Please sign in to comment.