From 88ab98295a527ae12cdcff618745a82a9d1e276d Mon Sep 17 00:00:00 2001 From: Valeriy Khorunzhin Date: Fri, 12 Sep 2025 14:26:24 +0300 Subject: [PATCH 1/2] tmp Signed-off-by: Valeriy Khorunzhin --- .../pkg/builder/cvi/option.go | 11 + .../pkg/builder/vd/option.go | 12 +- .../pkg/builder/vi/option.go | 36 ++ .../pkg/builder/vm/option.go | 6 + .../pkg/builder/vmbda/option.go | 42 ++ .../pkg/builder/vmbda/vmbda.go | 48 ++ .../pkg/builder/vmop/option.go | 6 + .../pkg/builder/vmsnapshot/option.go | 53 ++ .../pkg/builder/vmsnapshot/vmsnapshot.go | 51 ++ tests/e2e/framework/framework.go | 37 +- tests/e2e/vm_restore_operation_test.go | 539 ++++++++++++++++++ 11 files changed, 837 insertions(+), 4 deletions(-) create mode 100644 images/virtualization-artifact/pkg/builder/vmbda/option.go create mode 100644 images/virtualization-artifact/pkg/builder/vmbda/vmbda.go create mode 100644 images/virtualization-artifact/pkg/builder/vmsnapshot/option.go create mode 100644 images/virtualization-artifact/pkg/builder/vmsnapshot/vmsnapshot.go create mode 100644 tests/e2e/vm_restore_operation_test.go diff --git a/images/virtualization-artifact/pkg/builder/cvi/option.go b/images/virtualization-artifact/pkg/builder/cvi/option.go index 718dff2ff7..8401859dc7 100644 --- a/images/virtualization-artifact/pkg/builder/cvi/option.go +++ b/images/virtualization-artifact/pkg/builder/cvi/option.go @@ -80,6 +80,17 @@ func WithDatasource(datasource v1alpha2.ClusterVirtualImageDataSource) func(cvi } } +func WithDataSourceHTTPWithOnlyURL(url string) Option { + return func(cvi *v1alpha2.ClusterVirtualImage) { + cvi.Spec.DataSource = v1alpha2.ClusterVirtualImageDataSource{ + Type: v1alpha2.DataSourceTypeHTTP, + HTTP: &v1alpha2.DataSourceHTTP{ + URL: url, + }, + } + } +} + func WithPhase(phase v1alpha2.ImagePhase) func(cvi *v1alpha2.ClusterVirtualImage) { return func(cvi *v1alpha2.ClusterVirtualImage) { cvi.Status.Phase = phase diff --git a/images/virtualization-artifact/pkg/builder/vd/option.go b/images/virtualization-artifact/pkg/builder/vd/option.go index 44e4d08bbf..331fdb54ec 100644 --- a/images/virtualization-artifact/pkg/builder/vd/option.go +++ b/images/virtualization-artifact/pkg/builder/vd/option.go @@ -56,6 +56,17 @@ func WithDataSourceHTTP(url string, checksum *v1alpha2.Checksum, caBundle []byte } } +func WithDataSourceHTTPWithOnlyURL(url string) Option { + return func(vd *v1alpha2.VirtualDisk) { + vd.Spec.DataSource = &v1alpha2.VirtualDiskDataSource{ + Type: v1alpha2.DataSourceTypeHTTP, + HTTP: &v1alpha2.DataSourceHTTP{ + URL: url, + }, + } + } +} + func WithDataSourceContainerImage(image, imagePullSecretName string, caBundle []byte) Option { return func(vd *v1alpha2.VirtualDisk) { vd.Spec.DataSource = &v1alpha2.VirtualDiskDataSource{ @@ -70,7 +81,6 @@ func WithDataSourceContainerImage(image, imagePullSecretName string, caBundle [] } } } - func WithDataSourceObjectRef(kind v1alpha2.VirtualDiskObjectRefKind, name string) Option { return func(vd *v1alpha2.VirtualDisk) { vd.Spec.DataSource = &v1alpha2.VirtualDiskDataSource{ diff --git a/images/virtualization-artifact/pkg/builder/vi/option.go b/images/virtualization-artifact/pkg/builder/vi/option.go index 26c0e8d1de..6b7ea834ed 100644 --- a/images/virtualization-artifact/pkg/builder/vi/option.go +++ b/images/virtualization-artifact/pkg/builder/vi/option.go @@ -40,3 +40,39 @@ func WithCDROM(cdrom bool) func(vi *v1alpha2.VirtualImage) { vi.Status.CDROM = cdrom } } + +func WithStorageType(storageType *v1alpha2.StorageType) func(vi *v1alpha2.VirtualImage) { + return func(vi *v1alpha2.VirtualImage) { + vi.Spec.Storage = *storageType + } +} + +func WithDatasource(datasource v1alpha2.VirtualImageDataSource) func(vd *v1alpha2.VirtualImage) { + return func(vi *v1alpha2.VirtualImage) { + vi.Spec.DataSource = datasource + } +} + +func WithDataSourceHTTP(url string, checksum *v1alpha2.Checksum, caBundle []byte) Option { + return func(vi *v1alpha2.VirtualImage) { + vi.Spec.DataSource = v1alpha2.VirtualImageDataSource{ + Type: v1alpha2.DataSourceTypeHTTP, + HTTP: &v1alpha2.DataSourceHTTP{ + URL: url, + Checksum: checksum, + CABundle: caBundle, + }, + } + } +} + +func WithDataSourceHTTPWithOnlyURL(url string) Option { + return func(vi *v1alpha2.VirtualImage) { + vi.Spec.DataSource = v1alpha2.VirtualImageDataSource{ + Type: v1alpha2.DataSourceTypeHTTP, + HTTP: &v1alpha2.DataSourceHTTP{ + URL: url, + }, + } + } +} diff --git a/images/virtualization-artifact/pkg/builder/vm/option.go b/images/virtualization-artifact/pkg/builder/vm/option.go index fb16c535e8..9c7b7a9c08 100644 --- a/images/virtualization-artifact/pkg/builder/vm/option.go +++ b/images/virtualization-artifact/pkg/builder/vm/option.go @@ -86,3 +86,9 @@ func WithVirtualMachineClass(class string) Option { vm.Spec.VirtualMachineClassName = class } } + +func WithProvisioning(provisiong *v1alpha2.Provisioning) Option { + return func(vm *v1alpha2.VirtualMachine) { + vm.Spec.Provisioning = provisiong + } +} diff --git a/images/virtualization-artifact/pkg/builder/vmbda/option.go b/images/virtualization-artifact/pkg/builder/vmbda/option.go new file mode 100644 index 0000000000..284cc6d126 --- /dev/null +++ b/images/virtualization-artifact/pkg/builder/vmbda/option.go @@ -0,0 +1,42 @@ +/* +Copyright 2025 Flant JSC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vmbda + +import ( + "github.com/deckhouse/virtualization-controller/pkg/builder/meta" + "github.com/deckhouse/virtualization/api/core/v1alpha2" +) + +type Option func(vd *v1alpha2.VirtualMachineBlockDeviceAttachment) + +var ( + WithName = meta.WithName[*v1alpha2.VirtualMachineBlockDeviceAttachment] + WithNamespace = meta.WithNamespace[*v1alpha2.VirtualMachineBlockDeviceAttachment] + WithLabel = meta.WithLabel[*v1alpha2.VirtualMachineBlockDeviceAttachment] + WithLabels = meta.WithLabels[*v1alpha2.VirtualMachineBlockDeviceAttachment] + WithAnnotation = meta.WithAnnotation[*v1alpha2.VirtualMachineBlockDeviceAttachment] + WithAnnotations = meta.WithAnnotations[*v1alpha2.VirtualMachineBlockDeviceAttachment] +) + +func WithBlockDeviceRef(bdRef v1alpha2.VMBDAObjectRef) func(vmbda *v1alpha2.VirtualMachineBlockDeviceAttachment) { + return func(vmbda *v1alpha2.VirtualMachineBlockDeviceAttachment) { + vmbda.Spec.BlockDeviceRef = bdRef + } +} + +func WithVMName(vmName string) func(vmbda *v1alpha2.VirtualMachineBlockDeviceAttachment) { + return func(vmbda *v1alpha2.VirtualMachineBlockDeviceAttachment) { + vmbda.Spec.VirtualMachineName = vmName + } +} diff --git a/images/virtualization-artifact/pkg/builder/vmbda/vmbda.go b/images/virtualization-artifact/pkg/builder/vmbda/vmbda.go new file mode 100644 index 0000000000..c0600566aa --- /dev/null +++ b/images/virtualization-artifact/pkg/builder/vmbda/vmbda.go @@ -0,0 +1,48 @@ +/* +Copyright 2025 Flant JSC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vmbda + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/deckhouse/virtualization/api/core/v1alpha2" +) + +func New(options ...Option) *v1alpha2.VirtualMachineBlockDeviceAttachment { + vmbda := NewEmpty("", "") + ApplyOptions(vmbda, options) + return vmbda +} + +func ApplyOptions(vmbda *v1alpha2.VirtualMachineBlockDeviceAttachment, opts []Option) { + if vmbda == nil { + return + } + for _, opt := range opts { + opt(vmbda) + } +} + +func NewEmpty(name, namespace string) *v1alpha2.VirtualMachineBlockDeviceAttachment { + return &v1alpha2.VirtualMachineBlockDeviceAttachment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: v1alpha2.SchemeGroupVersion.String(), + Kind: v1alpha2.VirtualMachineBlockDeviceAttachmentKind, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + } +} diff --git a/images/virtualization-artifact/pkg/builder/vmop/option.go b/images/virtualization-artifact/pkg/builder/vmop/option.go index 22e38dad9d..9ebfdc81ad 100644 --- a/images/virtualization-artifact/pkg/builder/vmop/option.go +++ b/images/virtualization-artifact/pkg/builder/vmop/option.go @@ -51,3 +51,9 @@ func WithForce(force *bool) Option { vmop.Spec.Force = force } } + +func WithRestoreSpec(restoreSpec *v1alpha2.VirtualMachineOperationRestoreSpec) Option { + return func(vmop *v1alpha2.VirtualMachineOperation) { + vmop.Spec.Restore = restoreSpec + } +} diff --git a/images/virtualization-artifact/pkg/builder/vmsnapshot/option.go b/images/virtualization-artifact/pkg/builder/vmsnapshot/option.go new file mode 100644 index 0000000000..b807902edf --- /dev/null +++ b/images/virtualization-artifact/pkg/builder/vmsnapshot/option.go @@ -0,0 +1,53 @@ +/* +Copyright 2025 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vmsnapshot + +import ( + "github.com/deckhouse/virtualization-controller/pkg/builder/meta" + "github.com/deckhouse/virtualization/api/core/v1alpha2" +) + +type Option func(vmop *v1alpha2.VirtualMachineSnapshot) + +var ( + WithName = meta.WithName[*v1alpha2.VirtualMachineSnapshot] + WithGenerateName = meta.WithGenerateName[*v1alpha2.VirtualMachineSnapshot] + WithNamespace = meta.WithNamespace[*v1alpha2.VirtualMachineSnapshot] + WithLabel = meta.WithLabel[*v1alpha2.VirtualMachineSnapshot] + WithLabels = meta.WithLabels[*v1alpha2.VirtualMachineSnapshot] + WithAnnotation = meta.WithAnnotation[*v1alpha2.VirtualMachineSnapshot] + WithAnnotations = meta.WithAnnotations[*v1alpha2.VirtualMachineSnapshot] + WithFinalizer = meta.WithFinalizer[*v1alpha2.VirtualMachineSnapshot] +) + +func WithRequiredConsistency(required bool) Option { + return func(vmop *v1alpha2.VirtualMachineSnapshot) { + vmop.Spec.RequiredConsistency = required + } +} + +func WithVm(vmName string) Option { + return func(vmop *v1alpha2.VirtualMachineSnapshot) { + vmop.Spec.VirtualMachineName = vmName + } +} + +func WithKeepIpAddress(keepIpAddress v1alpha2.KeepIPAddress) Option { + return func(vmop *v1alpha2.VirtualMachineSnapshot) { + vmop.Spec.KeepIPAddress = keepIpAddress + } +} diff --git a/images/virtualization-artifact/pkg/builder/vmsnapshot/vmsnapshot.go b/images/virtualization-artifact/pkg/builder/vmsnapshot/vmsnapshot.go new file mode 100644 index 0000000000..d0e2eae2d5 --- /dev/null +++ b/images/virtualization-artifact/pkg/builder/vmsnapshot/vmsnapshot.go @@ -0,0 +1,51 @@ +/* +Copyright 2025 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vmsnapshot + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/deckhouse/virtualization/api/core/v1alpha2" +) + +func New(options ...Option) *v1alpha2.VirtualMachineSnapshot { + vmSnapshot := NewEmpty("", "") + ApplyOptions(vmSnapshot, options...) + return vmSnapshot +} + +func ApplyOptions(vmSnapshot *v1alpha2.VirtualMachineSnapshot, opts ...Option) { + if vmSnapshot == nil { + return + } + for _, opt := range opts { + opt(vmSnapshot) + } +} + +func NewEmpty(name, namespace string) *v1alpha2.VirtualMachineSnapshot { + return &v1alpha2.VirtualMachineSnapshot{ + TypeMeta: metav1.TypeMeta{ + APIVersion: v1alpha2.SchemeGroupVersion.String(), + Kind: v1alpha2.VirtualMachineOperationKind, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + } +} diff --git a/tests/e2e/framework/framework.go b/tests/e2e/framework/framework.go index a10b77326d..5c268b4c5c 100644 --- a/tests/e2e/framework/framework.go +++ b/tests/e2e/framework/framework.go @@ -20,11 +20,14 @@ import ( "context" "fmt" "maps" + "os/exec" + "strings" "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" ) const ( @@ -40,6 +43,7 @@ type Framework struct { namespace *corev1.Namespace namespacesToDelete []string + resourcesToDelete []client.Object } func NewFramework(namespacePrefix string) *Framework { @@ -73,12 +77,18 @@ func (f *Framework) Before() { gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By(fmt.Sprintf("Created namespace %s", ns.Name)) f.namespace = ns - f.AddNamespaceToDelete(ns.Name) } } func (f *Framework) After() { ginkgo.GinkgoHelper() + + for _, resource := range f.resourcesToDelete { + ginkgo.By(fmt.Sprintf("Delete resource %s", resource.GetName())) + err := f.client.Delete(context.Background(), resource) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } + for _, ns := range f.namespacesToDelete { ginkgo.By(fmt.Sprintf("Delete namespace %s", ns)) err := f.KubeClient().CoreV1().Namespaces().Delete(context.Background(), ns, metav1.DeleteOptions{}) @@ -98,8 +108,8 @@ func (f *Framework) CreateNamespace(prefix string, labels map[string]string) (*c APIVersion: corev1.SchemeGroupVersion.String(), }, ObjectMeta: metav1.ObjectMeta{ - GenerateName: fmt.Sprintf("%s-%s-", NamespaceBasePrefix, prefix), - Labels: nsLabels, + Name: fmt.Sprintf("%s-%s-%s", NamespaceBasePrefix, prefix, GetCommitHash()), + Labels: nsLabels, }, } @@ -118,3 +128,24 @@ func (f *Framework) Namespace() *corev1.Namespace { func (f *Framework) AddNamespaceToDelete(name string) { f.namespacesToDelete = append(f.namespacesToDelete, name) } + +func (f *Framework) AddResourceToDelete(obj client.Object) { + f.resourcesToDelete = append(f.resourcesToDelete, obj) +} + +// func (f *Framework) GetRunHash() string { +// parts := strings.Split(f.Namespace().Name, "-") +// if len(parts) == 0 { +// return "" +// } +// return parts[len(parts)-1] +// } + +func GetCommitHash() string { + ginkgo.GinkgoHelper() + + cmd := exec.Command("git", "rev-parse", "--short", "HEAD") + stdout, err := cmd.Output() + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + return strings.TrimSpace(string(stdout)) +} diff --git a/tests/e2e/vm_restore_operation_test.go b/tests/e2e/vm_restore_operation_test.go new file mode 100644 index 0000000000..335ad2d5f0 --- /dev/null +++ b/tests/e2e/vm_restore_operation_test.go @@ -0,0 +1,539 @@ +/* +Copyright 2025 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package e2e + +import ( + "context" + "fmt" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" + + cvibuilder "github.com/deckhouse/virtualization-controller/pkg/builder/cvi" + vdbuilder "github.com/deckhouse/virtualization-controller/pkg/builder/vd" + vibuilder "github.com/deckhouse/virtualization-controller/pkg/builder/vi" + vmbuilder "github.com/deckhouse/virtualization-controller/pkg/builder/vm" + vmbdabuilder "github.com/deckhouse/virtualization-controller/pkg/builder/vmbda" + vmopbuilder "github.com/deckhouse/virtualization-controller/pkg/builder/vmop" + vmsnapshotbuilder "github.com/deckhouse/virtualization-controller/pkg/builder/vmsnapshot" + "github.com/deckhouse/virtualization-controller/pkg/controller/conditions" + "github.com/deckhouse/virtualization/api/core/v1alpha2" + "github.com/deckhouse/virtualization/api/core/v1alpha2/vmcondition" + "github.com/deckhouse/virtualization/tests/e2e/framework" + "github.com/deckhouse/virtualization/tests/e2e/ginkgoutil" +) + +const ubuntuUrl = "https://cloud-images.ubuntu.com/noble/20250704/noble-server-cloudimg-amd64.img" + +var _ = Describe("VirtualMachineRestoreOperation", Serial, ginkgoutil.CommonE2ETestDecorators(), func() { + frameworkEntity := framework.NewFramework("virtual-machine-restore-operation") + helper := NewVMOPRestoreTestHelper(frameworkEntity) + + BeforeAll(func() { + frameworkEntity.Before() + }) + + AfterAll(func() { + frameworkEntity.After() + }) + + Context("Preparing resources", func() { + It("Applying resources", func() { + helper.GenerateAndCreateOriginalResources() + }) + It("Resorces should be ready", func() { + Eventually(func(g Gomega) { + helper.UpdateState(g) + helper.CheckIfResourcesReady(g) + }, 300*time.Second, 1*time.Second).Should(Succeed()) + }) + }) + + Context("Creating snapshot", func() { + It("Applying snapshot resource", func() { + helper.VMSnapshot = helper.GenerateVMSnapshot( + "vmsnapshot", + frameworkEntity.Namespace().Name, + helper.VM.Name, + true, + v1alpha2.KeepIPAddressAlways, + ) + By(fmt.Sprintf("Creating vm snapshot: %s/%s", helper.VMSnapshot.Namespace, helper.VMSnapshot.Name)) + err := frameworkEntity.Clients.GenericClient().Create(context.Background(), helper.VMSnapshot) + Expect(err).ShouldNot(HaveOccurred()) + }) + + It("Snapshot should be ready", func() { + Eventually(func(g Gomega) { + helper.UpdateState(g) + + g.Expect(helper.VMSnapshot.Status.Phase).Should(Equal(v1alpha2.VirtualMachineSnapshotPhaseReady)) + }, 300*time.Second, 1*time.Second).Should(Succeed()) + }) + }) + + Context("Restore dry run", func() { + It("Creating VMOP", func() { + helper.VMOPDryRun = helper.GenerateRestoreVMOP( + "vmop-dryrun", frameworkEntity.Namespace().Name, + helper.VMSnapshot.Name, + v1alpha2.VMOPRestoreModeDryRun, + ) + err := frameworkEntity.Clients.GenericClient().Create(context.Background(), helper.VMOPDryRun) + Expect(err).ShouldNot(HaveOccurred()) + }) + + It("Dry run restore VMOP must be ???", func() { + Eventually(func(g Gomega) { + // ??? + }, 120*time.Second, 1*time.Second).Should(Succeed()) + }) + }) + + Context("Removing VM", func() { + It("Remove VM", func() { + err := helper.FrameworkEntity.Clients.GenericClient().Delete(context.Background(), helper.VM) + Expect(err).ShouldNot(HaveOccurred()) + }) + + It("VM should not exists", func() { + Eventually(func(g Gomega) { + var vm v1alpha2.VirtualMachine + err := helper.FrameworkEntity.Clients.GenericClient().Get( + context.Background(), + types.NamespacedName{ + Namespace: helper.VM.Namespace, + Name: helper.VM.Name, + }, + &vm, + ) + g.Expect(k8serrors.IsNotFound(err)).Should(BeTrue()) + }, 60*time.Second, time.Second).Should(Succeed()) + }) + }) + + // Context("Restore in ??? mode", func() { + // It("Creating VMOP", func() { + // helper.VMOPDryRun = helper.GenerateRestoreVMOP( + // "vmop-dryrun", frameworkEntity.Namespace().Name, + // helper.VMSnapshot.Name, + // v1alpha2.VMOPRestoreModeDryRun, + // ) + // err := frameworkEntity.Clients.GenericClient().Create(context.Background(), helper.VMOPDryRun) + // Expect(err).ShouldNot(HaveOccurred()) + // }) + + // It("Dry run restore VMOP must be ???", func() { + // Eventually(func(g Gomega) { + // // ??? + // }, 120*time.Second, 1*time.Second).Should(Succeed()) + // }) + // }) + + // Context("Do something", func() { + // // ??? + // }) + + // Context("Restore in ??? mode", func() { + // It("Creating VMOP", func() { + // helper.VMOPDryRun = helper.GenerateRestoreVMOP( + // "vmop-dryrun", frameworkEntity.Namespace().Name, + // helper.VMSnapshot.Name, + // v1alpha2.VMOPRestoreModeDryRun, + // ) + // err := frameworkEntity.Clients.GenericClient().Create(context.Background(), helper.VMOPDryRun) + // Expect(err).ShouldNot(HaveOccurred()) + // }) + + // It("Dry run restore VMOP must be ???", func() { + // Eventually(func(g Gomega) { + // // ??? + // }, 120*time.Second, 1*time.Second).Should(Succeed()) + // }) + // }) + + Context("kek", func() { + time.Sleep(300 * time.Second) + }) +}) + +type VMOPRestoreTestHelper struct { + FrameworkEntity *framework.Framework + VM *v1alpha2.VirtualMachine + CVI *v1alpha2.ClusterVirtualImage + VI *v1alpha2.VirtualImage + VDRoot, VDBlank *v1alpha2.VirtualDisk + VMBDA *v1alpha2.VirtualMachineBlockDeviceAttachment + VMSnapshot *v1alpha2.VirtualMachineSnapshot + VMOPDryRun *v1alpha2.VirtualMachineOperation + VMOPStrict *v1alpha2.VirtualMachineOperation + VMOPBestEffort *v1alpha2.VirtualMachineOperation +} + +func NewVMOPRestoreTestHelper(frameworkEntity *framework.Framework) *VMOPRestoreTestHelper { + return &VMOPRestoreTestHelper{ + FrameworkEntity: frameworkEntity, + } +} + +func (h *VMOPRestoreTestHelper) GenerateAndCreateOriginalResources() { + GinkgoHelper() + h.CVI = h.GenerateCVI("ubuntu-cvi", ubuntuUrl) + h.FrameworkEntity.AddResourceToDelete(h.CVI) + h.VI = h.GenerateVI("ubuntu-vi", h.FrameworkEntity.Namespace().Name, ubuntuUrl) + h.VDRoot = h.GenerateVDFromHttp("vd-root", h.FrameworkEntity.Namespace().Name, "10Gi", ubuntuUrl) + h.VDBlank = h.GenerateVDBlank("vd-blank", h.FrameworkEntity.Namespace().Name, "10Gi") + h.VM = h.GenerateVM( + "ubuntu-vm", + h.FrameworkEntity.Namespace().Name, + v1alpha2.AlwaysSafeMigrationPolicy, + 1, + "10%", + "1Gi", + v1alpha2.BlockDeviceSpecRef{ + Kind: v1alpha2.DiskDevice, + Name: h.VDRoot.Name, + }, + // v1alpha2.BlockDeviceSpecRef{ + // Kind: v1alpha2.ClusterImageDevice, + // Name: h.CVI.Name, + // }, + // v1alpha2.BlockDeviceSpecRef{ + // Kind: v1alpha2.ImageDevice, + // Name: h.VI.Name, + // }, + ) + h.VMBDA = h.GenerateVMBDA( + "vmbda", h.FrameworkEntity.Namespace().Name, h.VM.Name, + v1alpha2.VMBDAObjectRef{ + Kind: v1alpha2.VMBDAObjectRefKindVirtualDisk, + Name: h.VDBlank.Name, + }, + ) + + By(fmt.Sprintf("Creating cvi: %s", h.CVI.Name)) + err := h.FrameworkEntity.GenericClient().Create(context.Background(), h.CVI) + Expect(err).ShouldNot(HaveOccurred()) + By(fmt.Sprintf("Creating vi: %s/%s", h.VI.Namespace, h.VI.Name)) + err = h.FrameworkEntity.GenericClient().Create(context.Background(), h.VI) + Expect(err).ShouldNot(HaveOccurred()) + By(fmt.Sprintf("Creating vd blank: %s/%s", h.VDBlank.Namespace, h.VDBlank.Name)) + err = h.FrameworkEntity.GenericClient().Create(context.Background(), h.VDBlank) + Expect(err).ShouldNot(HaveOccurred()) + By(fmt.Sprintf("Creating vd root: %s/%s", h.VDRoot.Namespace, h.VDRoot.Name)) + err = h.FrameworkEntity.GenericClient().Create(context.Background(), h.VDRoot) + Expect(err).ShouldNot(HaveOccurred()) + By(fmt.Sprintf("Creating vm: %s/%s", h.VM.Namespace, h.VM.Name)) + err = h.FrameworkEntity.GenericClient().Create(context.Background(), h.VM) + Expect(err).ShouldNot(HaveOccurred()) + By(fmt.Sprintf("Creating vmbda: %s/%s", h.VMBDA.Namespace, h.VMBDA.Name)) + err = h.FrameworkEntity.GenericClient().Create(context.Background(), h.VMBDA) + Expect(err).ShouldNot(HaveOccurred()) +} + +func (h *VMOPRestoreTestHelper) GenerateVM( + name, namespace string, + liveMigrationPolicy v1alpha2.LiveMigrationPolicy, + cores int, + coreFraction string, + memorySize string, + blockDeviceRefs ...v1alpha2.BlockDeviceSpecRef, +) *v1alpha2.VirtualMachine { + cloudInit := + `#cloud-config +users: +- name: cloud +passwd: $6$rounds=4096$vln/.aPHBOI7BMYR$bBMkqQvuGs5Gyd/1H5DP4m9HjQSy.kgrxpaGEHwkX7KEFV8BS.HZWPitAtZ2Vd8ZqIZRqmlykRCagTgPejt1i. +shell: /bin/bash +sudo: ALL=(ALL) NOPASSWD:ALL +chpasswd: { expire: False } +lock_passwd: false +ssh_authorized_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDdgocvYNNgs/GkZVCoGUSWI9S4IJ2pvl/f/9k3/QalIwmkIjEqef9ndIpw+hr57MBzxKZbgjkstwedd+iH3Q06Lf3Ne3VsbNJBkQsdaSfCKwelkWng+uAdC/Ol8Kh9VA3pqur4EWsXAdWZ2YtaQD64GF9JPN9ASybwr/r0cIgpBilvC7GqLzgwoGxAlqj/gWWj4RJZzSr4lflXBiiOyqxA0EnLs13jGbxMWzUWGMd35l1B5MkEYIj+brvX9wCtJGBnsmmTU3q2J3dk2wSM8BCNLq1Rg2UoLiZzWdgxRU6tcuMtBJBn+llrbYtfDGs1nj5XlGqa+nwa1KgC8IHbTTsyX/Kde019Q+7QEDnP3ZMd1qVFIn01NjePTRfdSAXgPI6DO1ifemPKuRobgjC3HTGyH3CHhlbkz01XUpP+Pdpj+LKHGBDVBC2qDx2Hr+wwnJJEqxID3RqICYyidR+7Goti/0ike0ddT/wRNd/C+6rMepgTbuOj0uW65l4Bkormrrs= work@work-ThinkPad-T14-Gen-3 + +runcmd: +- [bash, -c, "apt update"] +- [bash, -c, "apt install qemu-guest-agent -y"] +- [bash, -c, "systemctl enable qemu-guest-agent"] +- [bash, -c, "systemctl start qemu-guest-agent"]` + + return vmbuilder.New( + vmbuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vmbuilder.WithNamespace(namespace), + vmbuilder.WithBlockDeviceRefs(blockDeviceRefs...), + vmbuilder.WithLiveMigrationPolicy(liveMigrationPolicy), + vmbuilder.WithCPU(cores, ptr.To(coreFraction)), + vmbuilder.WithMemory(resource.MustParse(memorySize)), + vmbuilder.WithProvisioning( + &v1alpha2.Provisioning{ + Type: v1alpha2.ProvisioningTypeUserData, + UserData: cloudInit, + }, + ), + ) +} + +func (h *VMOPRestoreTestHelper) GenerateVDBlank(name, namespace, size string) *v1alpha2.VirtualDisk { + return vdbuilder.New( + vdbuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vdbuilder.WithNamespace(namespace), + vdbuilder.WithSize(ptr.To(resource.MustParse(size))), + ) +} + +func (h *VMOPRestoreTestHelper) GenerateVDFromHttp(name, namespace, size, url string) *v1alpha2.VirtualDisk { + return vdbuilder.New( + vdbuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vdbuilder.WithNamespace(namespace), + vdbuilder.WithSize(ptr.To(resource.MustParse(size))), + vdbuilder.WithDataSourceHTTPWithOnlyURL(url), + ) +} + +func (h *VMOPRestoreTestHelper) GenerateVI(name, namespace, url string) *v1alpha2.VirtualImage { + return vibuilder.New( + vibuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vibuilder.WithNamespace(namespace), + vibuilder.WithDataSourceHTTPWithOnlyURL(url), + vibuilder.WithStorageType(ptr.To(v1alpha2.StorageContainerRegistry)), + ) +} + +func (h *VMOPRestoreTestHelper) GenerateCVI(name, url string) *v1alpha2.ClusterVirtualImage { + return cvibuilder.New( + cvibuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + cvibuilder.WithDataSourceHTTPWithOnlyURL(url), + ) +} + +func (h *VMOPRestoreTestHelper) GenerateVMBDA(name, namespace, vmName string, bdRef v1alpha2.VMBDAObjectRef) *v1alpha2.VirtualMachineBlockDeviceAttachment { + return vmbdabuilder.New( + vmbdabuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vmbdabuilder.WithNamespace(namespace), + vmbdabuilder.WithVMName(vmName), + vmbdabuilder.WithBlockDeviceRef(bdRef), + ) +} + +func (h *VMOPRestoreTestHelper) GenerateVMSnapshot( + name, namespace, vmName string, + requiredConsistency bool, + keepIpAddress v1alpha2.KeepIPAddress, +) *v1alpha2.VirtualMachineSnapshot { + return vmsnapshotbuilder.New( + vmsnapshotbuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vmsnapshotbuilder.WithNamespace(namespace), + vmsnapshotbuilder.WithVm(vmName), + vmsnapshotbuilder.WithKeepIpAddress(keepIpAddress), + vmsnapshotbuilder.WithRequiredConsistency(requiredConsistency), + ) +} + +func (h *VMOPRestoreTestHelper) GenerateRestoreVMOP(name, namespace, vmSnapshotName string, restoreMode v1alpha2.VMOPRestoreMode) *v1alpha2.VirtualMachineOperation { + restoreSpec := &v1alpha2.VirtualMachineOperationRestoreSpec{ + VirtualMachineSnapshotName: vmSnapshotName, + Mode: restoreMode, + } + + return vmopbuilder.New( + vmopbuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vmopbuilder.WithNamespace(namespace), + vmopbuilder.WithType(v1alpha2.VMOPTypeRestore), + vmopbuilder.WithRestoreSpec(restoreSpec), + ) +} + +func (h *VMOPRestoreTestHelper) UpdateState(g Gomega) { + var err error + + if h.CVI != nil { + var cvi v1alpha2.ClusterVirtualImage + err = h.FrameworkEntity.Clients.GenericClient().Get( + context.Background(), + types.NamespacedName{ + Name: h.CVI.Name, + }, + &cvi, + ) + g.Expect(err).ShouldNot(HaveOccurred()) + if err == nil { + h.CVI = &cvi + } + } + + if h.VI != nil { + var vi v1alpha2.VirtualImage + err = h.FrameworkEntity.Clients.GenericClient().Get( + context.Background(), + types.NamespacedName{ + Namespace: h.VI.Namespace, + Name: h.VI.Name, + }, + &vi, + ) + g.Expect(err).ShouldNot(HaveOccurred()) + if err == nil { + h.VI = &vi + } + } + + if h.VDBlank != nil { + var vdBlank v1alpha2.VirtualDisk + err = h.FrameworkEntity.Clients.GenericClient().Get( + context.Background(), + types.NamespacedName{ + Namespace: h.VDBlank.Namespace, + Name: h.VDBlank.Name, + }, + &vdBlank, + ) + g.Expect(err).ShouldNot(HaveOccurred()) + if err == nil { + h.VDBlank = &vdBlank + } + } + + if h.VDRoot != nil { + var vdRoot v1alpha2.VirtualDisk + err = h.FrameworkEntity.Clients.GenericClient().Get( + context.Background(), + types.NamespacedName{ + Namespace: h.VDRoot.Namespace, + Name: h.VDRoot.Name, + }, + &vdRoot, + ) + g.Expect(err).ShouldNot(HaveOccurred()) + if err == nil { + h.VDRoot = &vdRoot + } + } + + if h.VMBDA != nil { + var vmbda v1alpha2.VirtualMachineBlockDeviceAttachment + err = h.FrameworkEntity.Clients.GenericClient().Get( + context.Background(), + types.NamespacedName{ + Namespace: h.VMBDA.Namespace, + Name: h.VMBDA.Name, + }, + &vmbda, + ) + g.Expect(err).ShouldNot(HaveOccurred()) + if err == nil { + h.VMBDA = &vmbda + } + } + + if h.VM != nil { + var vm v1alpha2.VirtualMachine + err = h.FrameworkEntity.Clients.GenericClient().Get( + context.Background(), + types.NamespacedName{ + Namespace: h.VM.Namespace, + Name: h.VM.Name, + }, + &vm, + ) + g.Expect(err).ShouldNot(HaveOccurred()) + if err == nil { + h.VM = &vm + } + } + + if h.VMSnapshot != nil { + var vmSnapshot v1alpha2.VirtualMachineSnapshot + err = h.FrameworkEntity.Clients.GenericClient().Get( + context.Background(), + types.NamespacedName{ + Namespace: h.VMSnapshot.Namespace, + Name: h.VMSnapshot.Name, + }, + &vmSnapshot, + ) + g.Expect(err).ShouldNot(HaveOccurred()) + if err == nil { + h.VMSnapshot = &vmSnapshot + } + } + + if h.VMOPDryRun != nil { + var vmopDryRun v1alpha2.VirtualMachineOperation + err = h.FrameworkEntity.Clients.GenericClient().Get( + context.Background(), + types.NamespacedName{ + Namespace: h.VMOPDryRun.Namespace, + Name: h.VMOPDryRun.Name, + }, + &vmopDryRun, + ) + g.Expect(err).ShouldNot(HaveOccurred()) + if err == nil { + h.VMOPDryRun = &vmopDryRun + } + } + + if h.VMOPStrict != nil { + var vmopStrict v1alpha2.VirtualMachineOperation + err = h.FrameworkEntity.Clients.GenericClient().Get( + context.Background(), + types.NamespacedName{ + Namespace: h.VMOPStrict.Namespace, + Name: h.VMOPStrict.Name, + }, + &vmopStrict, + ) + g.Expect(err).ShouldNot(HaveOccurred()) + if err == nil { + h.VMOPStrict = &vmopStrict + } + } + + if h.VMOPBestEffort != nil { + var vmopBestEffort v1alpha2.VirtualMachineOperation + err = h.FrameworkEntity.Clients.GenericClient().Get( + context.Background(), + types.NamespacedName{ + Namespace: h.VMOPBestEffort.Namespace, + Name: h.VMOPBestEffort.Name, + }, + &vmopBestEffort, + ) + g.Expect(err).ShouldNot(HaveOccurred()) + if err == nil { + h.VMOPBestEffort = &vmopBestEffort + } + } +} + +func (h *VMOPRestoreTestHelper) CheckIfResourcesReady(g Gomega) { + g.Expect(h.CVI.Status.Phase).Should(Equal(v1alpha2.ImageReady)) + g.Expect(h.VI.Status.Phase).Should(Equal(v1alpha2.ImageReady)) + g.Expect(h.VDBlank.Status.Phase).Should(Equal(v1alpha2.DiskReady)) + g.Expect(h.VDRoot.Status.Phase).Should(Equal(v1alpha2.DiskReady)) + g.Expect(h.VMBDA.Status.Phase).Should(Equal(v1alpha2.BlockDeviceAttachmentPhaseAttached)) + g.Expect(h.VM.Status.Phase).Should(Equal(v1alpha2.MachineRunning)) + + agentReady, _ := conditions.GetCondition(vmcondition.TypeAgentReady, h.VM.Status.Conditions) + g.Expect(agentReady.Status).Should(Equal(metav1.ConditionTrue)) +} From 328e7ac3774b4ec8c75a66f5f5cbeaedc9cd91cb Mon Sep 17 00:00:00 2001 From: Valeriy Khorunzhin Date: Mon, 15 Sep 2025 13:53:58 +0300 Subject: [PATCH 2/2] tmp Signed-off-by: Valeriy Khorunzhin --- tests/e2e/framework/framework.go | 23 +------- tests/e2e/vm_restore_operation_test.go | 74 +++++++++++++------------- 2 files changed, 39 insertions(+), 58 deletions(-) diff --git a/tests/e2e/framework/framework.go b/tests/e2e/framework/framework.go index 5c268b4c5c..d67514bc4d 100644 --- a/tests/e2e/framework/framework.go +++ b/tests/e2e/framework/framework.go @@ -20,8 +20,6 @@ import ( "context" "fmt" "maps" - "os/exec" - "strings" "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" @@ -108,8 +106,8 @@ func (f *Framework) CreateNamespace(prefix string, labels map[string]string) (*c APIVersion: corev1.SchemeGroupVersion.String(), }, ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%s-%s-%s", NamespaceBasePrefix, prefix, GetCommitHash()), - Labels: nsLabels, + GenerateName: fmt.Sprintf("%s-%s-", NamespaceBasePrefix, prefix), + Labels: nsLabels, }, } @@ -132,20 +130,3 @@ func (f *Framework) AddNamespaceToDelete(name string) { func (f *Framework) AddResourceToDelete(obj client.Object) { f.resourcesToDelete = append(f.resourcesToDelete, obj) } - -// func (f *Framework) GetRunHash() string { -// parts := strings.Split(f.Namespace().Name, "-") -// if len(parts) == 0 { -// return "" -// } -// return parts[len(parts)-1] -// } - -func GetCommitHash() string { - ginkgo.GinkgoHelper() - - cmd := exec.Command("git", "rev-parse", "--short", "HEAD") - stdout, err := cmd.Output() - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - return strings.TrimSpace(string(stdout)) -} diff --git a/tests/e2e/vm_restore_operation_test.go b/tests/e2e/vm_restore_operation_test.go index 335ad2d5f0..1f0608ee63 100644 --- a/tests/e2e/vm_restore_operation_test.go +++ b/tests/e2e/vm_restore_operation_test.go @@ -49,13 +49,8 @@ var _ = Describe("VirtualMachineRestoreOperation", Serial, ginkgoutil.CommonE2ET frameworkEntity := framework.NewFramework("virtual-machine-restore-operation") helper := NewVMOPRestoreTestHelper(frameworkEntity) - BeforeAll(func() { - frameworkEntity.Before() - }) - - AfterAll(func() { - frameworkEntity.After() - }) + frameworkEntity.BeforeAll() + frameworkEntity.AfterAll() Context("Preparing resources", func() { It("Applying resources", func() { @@ -97,15 +92,17 @@ var _ = Describe("VirtualMachineRestoreOperation", Serial, ginkgoutil.CommonE2ET helper.VMOPDryRun = helper.GenerateRestoreVMOP( "vmop-dryrun", frameworkEntity.Namespace().Name, helper.VMSnapshot.Name, + helper.VM.Name, v1alpha2.VMOPRestoreModeDryRun, ) err := frameworkEntity.Clients.GenericClient().Create(context.Background(), helper.VMOPDryRun) Expect(err).ShouldNot(HaveOccurred()) }) - It("Dry run restore VMOP must be ???", func() { + It("Dry run restore VMOP must be Completed", func() { Eventually(func(g Gomega) { - // ??? + helper.UpdateState(g) + g.Expect(helper.VMOPDryRun.Status.Phase).Should(Equal(v1alpha2.VMOPPhaseCompleted)) }, 120*time.Second, 1*time.Second).Should(Succeed()) }) }) @@ -132,23 +129,25 @@ var _ = Describe("VirtualMachineRestoreOperation", Serial, ginkgoutil.CommonE2ET }) }) - // Context("Restore in ??? mode", func() { - // It("Creating VMOP", func() { - // helper.VMOPDryRun = helper.GenerateRestoreVMOP( - // "vmop-dryrun", frameworkEntity.Namespace().Name, - // helper.VMSnapshot.Name, - // v1alpha2.VMOPRestoreModeDryRun, - // ) - // err := frameworkEntity.Clients.GenericClient().Create(context.Background(), helper.VMOPDryRun) - // Expect(err).ShouldNot(HaveOccurred()) - // }) + Context("Restore in BestEffort mode", func() { + It("Creating VMOP", func() { + helper.VMOPBestEffort = helper.GenerateRestoreVMOP( + "vmop-besteffort", frameworkEntity.Namespace().Name, + helper.VMSnapshot.Name, + helper.VM.Name, + v1alpha2.VMOPRestoreModeBestEffort, + ) + err := frameworkEntity.Clients.GenericClient().Create(context.Background(), helper.VMOPBestEffort) + Expect(err).ShouldNot(HaveOccurred()) + }) - // It("Dry run restore VMOP must be ???", func() { - // Eventually(func(g Gomega) { - // // ??? - // }, 120*time.Second, 1*time.Second).Should(Succeed()) - // }) - // }) + It("BestEffort restore VMOP must be Completed", func() { + Eventually(func(g Gomega) { + helper.UpdateState(g) + g.Expect(helper.VMOPBestEffort.Status.Phase).Should(Equal(v1alpha2.VMOPPhaseCompleted)) + }, 120*time.Second, 1*time.Second).Should(Succeed()) + }) + }) // Context("Do something", func() { // // ??? @@ -172,9 +171,9 @@ var _ = Describe("VirtualMachineRestoreOperation", Serial, ginkgoutil.CommonE2ET // }) // }) - Context("kek", func() { - time.Sleep(300 * time.Second) - }) + // Context("kek", func() { + // time.Sleep(200 * time.Second) + // }) }) type VMOPRestoreTestHelper struct { @@ -278,7 +277,7 @@ runcmd: - [bash, -c, "systemctl start qemu-guest-agent"]` return vmbuilder.New( - vmbuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vmbuilder.WithName(name), vmbuilder.WithNamespace(namespace), vmbuilder.WithBlockDeviceRefs(blockDeviceRefs...), vmbuilder.WithLiveMigrationPolicy(liveMigrationPolicy), @@ -295,7 +294,7 @@ runcmd: func (h *VMOPRestoreTestHelper) GenerateVDBlank(name, namespace, size string) *v1alpha2.VirtualDisk { return vdbuilder.New( - vdbuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vdbuilder.WithName(name), vdbuilder.WithNamespace(namespace), vdbuilder.WithSize(ptr.To(resource.MustParse(size))), ) @@ -303,7 +302,7 @@ func (h *VMOPRestoreTestHelper) GenerateVDBlank(name, namespace, size string) *v func (h *VMOPRestoreTestHelper) GenerateVDFromHttp(name, namespace, size, url string) *v1alpha2.VirtualDisk { return vdbuilder.New( - vdbuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vdbuilder.WithName(name), vdbuilder.WithNamespace(namespace), vdbuilder.WithSize(ptr.To(resource.MustParse(size))), vdbuilder.WithDataSourceHTTPWithOnlyURL(url), @@ -312,7 +311,7 @@ func (h *VMOPRestoreTestHelper) GenerateVDFromHttp(name, namespace, size, url st func (h *VMOPRestoreTestHelper) GenerateVI(name, namespace, url string) *v1alpha2.VirtualImage { return vibuilder.New( - vibuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vibuilder.WithName(name), vibuilder.WithNamespace(namespace), vibuilder.WithDataSourceHTTPWithOnlyURL(url), vibuilder.WithStorageType(ptr.To(v1alpha2.StorageContainerRegistry)), @@ -321,14 +320,14 @@ func (h *VMOPRestoreTestHelper) GenerateVI(name, namespace, url string) *v1alpha func (h *VMOPRestoreTestHelper) GenerateCVI(name, url string) *v1alpha2.ClusterVirtualImage { return cvibuilder.New( - cvibuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + cvibuilder.WithGenerateName(fmt.Sprintf("%s-", name)), cvibuilder.WithDataSourceHTTPWithOnlyURL(url), ) } func (h *VMOPRestoreTestHelper) GenerateVMBDA(name, namespace, vmName string, bdRef v1alpha2.VMBDAObjectRef) *v1alpha2.VirtualMachineBlockDeviceAttachment { return vmbdabuilder.New( - vmbdabuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vmbdabuilder.WithName(name), vmbdabuilder.WithNamespace(namespace), vmbdabuilder.WithVMName(vmName), vmbdabuilder.WithBlockDeviceRef(bdRef), @@ -341,7 +340,7 @@ func (h *VMOPRestoreTestHelper) GenerateVMSnapshot( keepIpAddress v1alpha2.KeepIPAddress, ) *v1alpha2.VirtualMachineSnapshot { return vmsnapshotbuilder.New( - vmsnapshotbuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vmsnapshotbuilder.WithName(name), vmsnapshotbuilder.WithNamespace(namespace), vmsnapshotbuilder.WithVm(vmName), vmsnapshotbuilder.WithKeepIpAddress(keepIpAddress), @@ -349,17 +348,18 @@ func (h *VMOPRestoreTestHelper) GenerateVMSnapshot( ) } -func (h *VMOPRestoreTestHelper) GenerateRestoreVMOP(name, namespace, vmSnapshotName string, restoreMode v1alpha2.VMOPRestoreMode) *v1alpha2.VirtualMachineOperation { +func (h *VMOPRestoreTestHelper) GenerateRestoreVMOP(name, namespace, vmSnapshotName, vmName string, restoreMode v1alpha2.VMOPRestoreMode) *v1alpha2.VirtualMachineOperation { restoreSpec := &v1alpha2.VirtualMachineOperationRestoreSpec{ VirtualMachineSnapshotName: vmSnapshotName, Mode: restoreMode, } return vmopbuilder.New( - vmopbuilder.WithName(fmt.Sprintf("%s-%s", name, framework.GetCommitHash())), + vmopbuilder.WithName(name), vmopbuilder.WithNamespace(namespace), vmopbuilder.WithType(v1alpha2.VMOPTypeRestore), vmopbuilder.WithRestoreSpec(restoreSpec), + vmopbuilder.WithVirtualMachine(vmName), ) }