diff --git a/test/e2e/default_config.yaml b/test/e2e/default_config.yaml index 38339899c9..12942f3649 100644 --- a/test/e2e/default_config.yaml +++ b/test/e2e/default_config.yaml @@ -10,7 +10,6 @@ clusterTransport: helperImages: curlImage: "curlimages/curl" testData: - affinityToleration: "/tmp/testdata/affinity-toleration" complexTest: "/tmp/testdata/complex-test" diskResizing: "/tmp/testdata/disk-resizing" imageHotplug: "/tmp/testdata/image-hotplug" @@ -20,7 +19,6 @@ testData: vmMigration: "/tmp/testdata/vm-migration" vmMigrationCancel: "/tmp/testdata/vm-migration-cancel" vmEvacuation: "/tmp/testdata/vm-evacuation" - vmDiskAttachment: "/tmp/testdata/vm-disk-attachment" vdSnapshots: "/tmp/testdata/vd-snapshots" sshKey: "/tmp/testdata/sshkeys/id_ed" sshUser: "cloud" diff --git a/test/e2e/internal/config/config.go b/test/e2e/internal/config/config.go index d373c59716..40286dc843 100644 --- a/test/e2e/internal/config/config.go +++ b/test/e2e/internal/config/config.go @@ -80,18 +80,17 @@ type Config struct { } type TestData struct { - AffinityToleration string `yaml:"affinityToleration"` - ComplexTest string `yaml:"complexTest"` - DiskResizing string `yaml:"diskResizing"` - ImageHotplug string `yaml:"imageHotplug"` - VMLabelAnnotation string `yaml:"vmLabelAnnotation"` - VMMigration string `yaml:"vmMigration"` - VMMigrationCancel string `yaml:"vmMigrationCancel"` - VMEvacuation string `yaml:"vmEvacuation"` - VMDiskAttachment string `yaml:"vmDiskAttachment"` - VdSnapshots string `yaml:"vdSnapshots"` - Sshkey string `yaml:"sshKey"` - SSHUser string `yaml:"sshUser"` + ComplexTest string `yaml:"complexTest"` + DiskResizing string `yaml:"diskResizing"` + ImageHotplug string `yaml:"imageHotplug"` + VMLabelAnnotation string `yaml:"vmLabelAnnotation"` + VMMigration string `yaml:"vmMigration"` + VMMigrationCancel string `yaml:"vmMigrationCancel"` + VMEvacuation string `yaml:"vmEvacuation"` + VMVersions string `yaml:"vmVersions"` + VdSnapshots string `yaml:"vdSnapshots"` + Sshkey string `yaml:"sshKey"` + SSHUser string `yaml:"sshUser"` } type StorageClass struct { diff --git a/test/e2e/internal/util/block_device.go b/test/e2e/internal/util/block_device.go index 176128fbc3..560f376d75 100644 --- a/test/e2e/internal/util/block_device.go +++ b/test/e2e/internal/util/block_device.go @@ -18,6 +18,7 @@ package util import ( "context" + "encoding/json" "errors" "fmt" "strings" @@ -194,3 +195,34 @@ func GetExpectedDiskPhaseByVolumeBindingMode() string { return string(v1alpha2.DiskReady) } } + +// GetDiskCount returns the number of block devices attached to a VM. +// Uses lsblk --nodeps --json to get the list of block devices. +func GetDiskCount(f *framework.Framework, vmName, vmNamespace string) (int, error) { + cmd := "lsblk --nodeps --json" + result, err := f.SSHCommand(vmName, vmNamespace, cmd) + if err != nil { + return 0, fmt.Errorf("failed to execute command: %w: %s", err, result) + } + + var disks Disks + err = json.Unmarshal([]byte(result), &disks) + if err != nil { + return 0, fmt.Errorf("failed to parse lsblk output: %w", err) + } + + return len(disks.BlockDevices), nil +} + +// Disks represents the JSON output of lsblk --nodeps --json command. +// It contains a list of block devices attached to the VM. +type Disks struct { + BlockDevices []BlockDevice `json:"blockdevices"` +} + +// BlockDevice represents a single block device in the lsblk JSON output. +type BlockDevice struct { + Name string `json:"name"` + Size string `json:"size"` + Type string `json:"type"` +} diff --git a/test/e2e/legacy/image_hotplug.go b/test/e2e/legacy/image_hotplug.go index 565957fc71..bdcfc65a6f 100644 --- a/test/e2e/legacy/image_hotplug.go +++ b/test/e2e/legacy/image_hotplug.go @@ -24,6 +24,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" virtv1 "kubevirt.io/api/core/v1" "github.com/deckhouse/virtualization/api/core/v1alpha2" @@ -33,8 +34,13 @@ import ( kc "github.com/deckhouse/virtualization/test/e2e/internal/kubectl" "github.com/deckhouse/virtualization/test/e2e/internal/label" "github.com/deckhouse/virtualization/test/e2e/internal/object" + "github.com/deckhouse/virtualization/test/e2e/internal/util" ) +const unacceptableCount = -1000 + +var APIVersion = v1alpha2.SchemeGroupVersion.String() + var _ = Describe("ImageHotplug", Ordered, label.Legacy(), func() { const ( viCount = 2 @@ -336,3 +342,76 @@ func IsBlockDeviceReadOnly(vmNamespace, vmName, blockDeviceID string) (bool, err roOpt := options[0] return roOpt == "ro", nil } + +// lsblk JSON output +type Disks struct { + BlockDevices []BlockDevice `json:"blockdevices"` +} + +type BlockDevices struct { + BlockDevices []BlockDevice `json:"blockdevices"` +} + +type BlockDevice struct { + Name string `json:"name"` + Size string `json:"size"` + Type string `json:"type"` +} + +func AttachBlockDevice(vmNamespace, vmName, blockDeviceName string, blockDeviceType v1alpha2.VMBDAObjectRefKind, labels map[string]string, testDataPath string) { + vmbdaFilePath := fmt.Sprintf("%s/vmbda/%s.yaml", testDataPath, blockDeviceName) + err := CreateVMBDAManifest(vmbdaFilePath, vmName, blockDeviceName, blockDeviceType, labels) + Expect(err).NotTo(HaveOccurred(), "%v", err) + + res := kubectl.Apply(kc.ApplyOptions{ + Filename: []string{vmbdaFilePath}, + FilenameOption: kc.Filename, + Namespace: vmNamespace, + }) + Expect(res.Error()).NotTo(HaveOccurred(), res.StdErr()) +} + +func CreateVMBDAManifest(filePath, vmName, blockDeviceName string, blockDeviceType v1alpha2.VMBDAObjectRefKind, labels map[string]string) error { + vmbda := &v1alpha2.VirtualMachineBlockDeviceAttachment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: APIVersion, + Kind: v1alpha2.VirtualMachineBlockDeviceAttachmentKind, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: blockDeviceName, + Labels: labels, + }, + Spec: v1alpha2.VirtualMachineBlockDeviceAttachmentSpec{ + VirtualMachineName: vmName, + BlockDeviceRef: v1alpha2.VMBDAObjectRef{ + Kind: blockDeviceType, + Name: blockDeviceName, + }, + }, + } + + err := util.WriteYamlObject(filePath, vmbda) + if err != nil { + return err + } + + return nil +} + +func GetDisksMetadata(vmNamespace, vmName string, disks *Disks) error { + GinkgoHelper() + cmd := "lsblk --nodeps --json" + res := framework.GetClients().D8Virtualization().SSHCommand(vmName, cmd, d8.SSHOptions{ + Namespace: vmNamespace, + Username: conf.TestData.SSHUser, + IdentityFile: conf.TestData.Sshkey, + }) + if res.Error() != nil { + return fmt.Errorf("cmd: %s\nstderr: %s", res.GetCmd(), res.StdErr()) + } + err := json.Unmarshal(res.StdOutBytes(), disks) + if err != nil { + return fmt.Errorf("failed when getting disk count\nvirtualMachine: %s/%s\nstderr: %s", vmNamespace, vmName, res.StdErr()) + } + return nil +} diff --git a/test/e2e/legacy/testdata/affinity-toleration/kustomization.yaml b/test/e2e/legacy/testdata/affinity-toleration/kustomization.yaml deleted file mode 100644 index 29eb528cd6..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/kustomization.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -namespace: testcases -namePrefix: pr-number-or-commit-hash- -resources: - - ns.yaml - - vmc.yaml - - vm -configurations: - - transformer.yaml -labels: - - includeSelectors: true - pairs: - id: pr-number-or-commit-hash - testcase: affinity-toleration diff --git a/test/e2e/legacy/testdata/affinity-toleration/ns.yaml b/test/e2e/legacy/testdata/affinity-toleration/ns.yaml deleted file mode 100644 index 5efde875b6..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/ns.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: default diff --git a/test/e2e/legacy/testdata/affinity-toleration/transformer.yaml b/test/e2e/legacy/testdata/affinity-toleration/transformer.yaml deleted file mode 100644 index ec70d37fcd..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/transformer.yaml +++ /dev/null @@ -1,52 +0,0 @@ -namespace: - - kind: ClusterVirtualImage - path: spec/dataSource/objectRef/namespace -nameReference: - - kind: VirtualImage - version: v1alpha2 # optional - fieldSpecs: - - path: spec/dataSource/objectRef/name - kind: ClusterVirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualDisk - - path: spec/blockDeviceRefs/name - kind: VirtualMachine - - kind: ClusterVirtualImage - version: v1alpha2 # optional - fieldSpecs: - - path: spec/dataSource/objectRef/name - kind: ClusterVirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualDisk - - path: spec/blockDeviceRefs/name - kind: VirtualMachine - - kind: VirtualDisk - version: v1alpha2 # optional - fieldSpecs: - - path: spec/blockDeviceRefs/name - kind: VirtualMachine - - path: spec/blockDeviceRef/name - kind: VirtualMachineBlockDeviceAttachment - - kind: Secret - fieldSpecs: - - path: spec/provisioning/userDataRef/name - kind: VirtualMachine - - kind: VirtualMachineIPAddress - version: v1alpha2 - fieldSpecs: - - path: spec/virtualMachineIPAddressName - kind: VirtualMachine - - kind: VirtualMachine - version: v1alpha2 - fieldSpecs: - - path: spec/virtualMachineName - kind: VirtualMachineBlockDeviceAttachment - - kind: VirtualMachineClass - version: v1alpha3 - fieldSpecs: - - path: spec/virtualMachineClassName - kind: VirtualMachine diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/base/cfg/cloudinit.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/base/cfg/cloudinit.yaml deleted file mode 100644 index e7ffeb02c8..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/base/cfg/cloudinit.yaml +++ /dev/null @@ -1,58 +0,0 @@ -#cloud-config -package_update: true -packages: - - qemu-guest-agent - - curl - - bash - - sudo - - iputils -users: - - name: cloud - # passwd: cloud - passwd: $6$rounds=4096$vln/.aPHBOI7BMYR$bBMkqQvuGs5Gyd/1H5DP4m9HjQSy.kgrxpaGEHwkX7KEFV8BS.HZWPitAtZ2Vd8ZqIZRqmlykRCagTgPejt1i. - shell: /bin/bash - sudo: ALL=(ALL) NOPASSWD:ALL - lock_passwd: false - ssh_authorized_keys: - # testcases - - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFxcXHmwaGnJ8scJaEN5RzklBPZpVSic4GdaAsKjQoeA your_email@example.com -write_files: - - path: /etc/init.d/ping-service - permissions: "0755" - content: | - #!/sbin/openrc-run - - command="/usr/bin/ping-service.sh" - pidfile="/var/run/${RC_SVCNAME}.pid" - - depend() { - need localmount - after bootmisc - } - - start() { - ebegin "Starting ${RC_SVCNAME}" - start-stop-daemon --start --background --exec $command --pidfile $pidfile -- $command_args - eend $? - } - - stop() { - ebegin "Stopping ${RC_SVCNAME}" - start-stop-daemon --stop --exec $command --pidfile $pidfile - eend $? - } - - path: /usr/bin/ping-service.sh - permissions: "0755" - content: | - #!/bin/bash - - while true; do - ping -W1 -D 1.1.1.1 >> /tmp/ping.log - done -final_message: "\U0001F525\U0001F525\U0001F525 The system is finally up, after ${uptime} seconds \U0001F525\U0001F525\U0001F525" -runcmd: - - "echo \"\U0001F7E1 Starting runcmd at $(date +%H:%M:%S)\"" - - rc-update add ping-service default - - rc-service ping-service start - - "rc-update add qemu-guest-agent && rc-service qemu-guest-agent start" - - "echo \"\U0001F7E1 Finished runcmd at $(date +%H:%M:%S)\"" diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/base/kustomization.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/base/kustomization.yaml deleted file mode 100644 index d820a3f566..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/base/kustomization.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - ./vm.yaml - - ./vd-root.yaml -configurations: - - transformer.yaml -generatorOptions: - disableNameSuffixHash: true -secretGenerator: - - files: - - userData=cfg/cloudinit.yaml - name: cloud-init - type: provisioning.virtualization.deckhouse.io/cloud-init diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/base/transformer.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/base/transformer.yaml deleted file mode 100644 index 1dc146a3af..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/base/transformer.yaml +++ /dev/null @@ -1,54 +0,0 @@ -# https://github.com/kubernetes-sigs/kustomize/blob/master/examples/transformerconfigs/README.md#transformer-configurations - -namespace: - - kind: ClusterVirtualImage - path: spec/dataSource/objectRef/namespace -nameReference: - - kind: VirtualImage - version: v1alpha2 # optional - fieldSpecs: - - path: spec/dataSource/objectRef/name - kind: ClusterVirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualDisk - - path: spec/blockDeviceRefs/name - kind: VirtualMachine - - kind: ClusterVirtualImage - version: v1alpha2 # optional - fieldSpecs: - - path: spec/dataSource/objectRef/name - kind: ClusterVirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualDisk - - path: spec/blockDeviceRefs/name - kind: VirtualMachine - - kind: VirtualDisk - version: v1alpha2 # optional - fieldSpecs: - - path: spec/blockDeviceRefs/name - kind: VirtualMachine - - path: spec/blockDeviceRef/name - kind: VirtualMachineBlockDeviceAttachment - - kind: Secret - fieldSpecs: - - path: spec/provisioning/userDataRef/name - kind: VirtualMachine - - kind: VirtualMachineIPAddress - version: v1alpha2 - fieldSpecs: - - path: spec/virtualMachineIPAddressName - kind: VirtualMachine - - kind: VirtualMachine - version: v1alpha2 - fieldSpecs: - - path: spec/virtualMachineName - kind: VirtualMachineBlockDeviceAttachment - - kind: VirtualMachineClass - version: v1alpha3 - fieldSpecs: - - path: spec/virtualMachineClassName - kind: VirtualMachine diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/base/vd-attach.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/base/vd-attach.yaml deleted file mode 100644 index a68911289e..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/base/vd-attach.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualDisk -metadata: - name: vd-attach -spec: - persistentVolumeClaim: - storageClassName: "{{ .STORAGE_CLASS_NAME }}" - size: 100Mi diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/base/vd-root.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/base/vd-root.yaml deleted file mode 100644 index 7442dd263a..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/base/vd-root.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualDisk -metadata: - name: vd-root -spec: - persistentVolumeClaim: - storageClassName: "{{ .STORAGE_CLASS_NAME }}" - size: 350Mi - dataSource: - type: ObjectRef - objectRef: - kind: ClusterVirtualImage - name: v12n-e2e-alpine-uefi diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/base/vm.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/base/vm.yaml deleted file mode 100644 index fbce6fa32f..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/base/vm.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachine -metadata: - name: vm -spec: - bootloader: EFI - virtualMachineClassName: affinity-toleration-discovery - cpu: - cores: 1 - coreFraction: 50% - memory: - size: 256Mi - disruptions: - restartApprovalMode: Manual - provisioning: - type: UserDataRef - userDataRef: - kind: Secret - name: cloud-init - blockDeviceRefs: - - kind: VirtualDisk - name: vd-root diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/base/vmbda.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/base/vmbda.yaml deleted file mode 100644 index 30a7b6ba4a..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/base/vmbda.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachineBlockDeviceAttachment -metadata: - name: blank-disk-attachment -spec: - virtualMachineName: vm - blockDeviceRef: - kind: VirtualDisk - name: vd-attach diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/kustomization.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/kustomization.yaml deleted file mode 100644 index 3c1f1f10d3..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/kustomization.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - overlays/vm-a-not-b - - overlays/vm-b-not-a - - overlays/vm-c-and-a - - overlays/vm-d - - overlays/vm-node-affinity - - overlays/vm-node-selector diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-a-not-b/kustomization.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-a-not-b/kustomization.yaml deleted file mode 100644 index 1d1a7fbbcb..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-a-not-b/kustomization.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -nameSuffix: -a-not-b -resources: - - ../../base -patches: - - path: vm.affinity.patch.yaml - - path: vm.tolerations.patch.yaml -labels: - - includeSelectors: true - pairs: - vm: vm-a diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-a-not-b/vm.affinity.patch.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-a-not-b/vm.affinity.patch.yaml deleted file mode 100644 index 3cbd144c42..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-a-not-b/vm.affinity.patch.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachine -metadata: - name: vm -spec: - affinity: - virtualMachineAndPodAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: vm - operator: In - values: - - vm-b - topologyKey: kubernetes.io/hostname diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-a-not-b/vm.tolerations.patch.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-a-not-b/vm.tolerations.patch.yaml deleted file mode 100644 index 97af267d8b..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-a-not-b/vm.tolerations.patch.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachine -metadata: - name: vm -spec: - tolerations: - - effect: NoSchedule - operator: Exists diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-b-not-a/kustomization.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-b-not-a/kustomization.yaml deleted file mode 100644 index 3f95ed63cf..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-b-not-a/kustomization.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -nameSuffix: -b-not-a -resources: - - ../../base -patches: - - path: vm.affinity.patch.yaml - - path: vm.tolerations.patch.yaml -labels: - - includeSelectors: true - pairs: - vm: vm-b diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-b-not-a/vm.affinity.patch.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-b-not-a/vm.affinity.patch.yaml deleted file mode 100644 index 8a5727421e..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-b-not-a/vm.affinity.patch.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachine -metadata: - name: vm -spec: - affinity: - virtualMachineAndPodAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: vm - operator: In - values: - - vm-a - topologyKey: kubernetes.io/hostname diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-b-not-a/vm.tolerations.patch.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-b-not-a/vm.tolerations.patch.yaml deleted file mode 100644 index 97af267d8b..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-b-not-a/vm.tolerations.patch.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachine -metadata: - name: vm -spec: - tolerations: - - effect: NoSchedule - operator: Exists diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-c-and-a/kustomization.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-c-and-a/kustomization.yaml deleted file mode 100644 index cd7294acc6..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-c-and-a/kustomization.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -nameSuffix: -c-and-a -resources: - - ../../base -patches: - - path: vm.affinity.patch.yaml - - path: vm.tolerations.patch.yaml -labels: - - includeSelectors: true - pairs: - vm: vm-c diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-c-and-a/vm.affinity.patch.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-c-and-a/vm.affinity.patch.yaml deleted file mode 100644 index 2e1b10803d..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-c-and-a/vm.affinity.patch.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachine -metadata: - name: vm -spec: - affinity: - virtualMachineAndPodAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: vm - operator: In - values: - - vm-a - topologyKey: kubernetes.io/hostname diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-c-and-a/vm.tolerations.patch.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-c-and-a/vm.tolerations.patch.yaml deleted file mode 100644 index 97af267d8b..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-c-and-a/vm.tolerations.patch.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachine -metadata: - name: vm -spec: - tolerations: - - effect: NoSchedule - operator: Exists diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-d/kustomization.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-d/kustomization.yaml deleted file mode 100644 index a9f0096ac6..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-d/kustomization.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -nameSuffix: -d -resources: - - ../../base -patches: - - path: vm.affinity.patch.yaml - - path: vm.tolerations.patch.yaml -labels: - - includeSelectors: true - pairs: - vm: vm-d diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-d/vm.affinity.patch.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-d/vm.affinity.patch.yaml deleted file mode 100644 index b29206e0be..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-d/vm.affinity.patch.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachine -metadata: - name: vm -spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: node.deckhouse.io/group - operator: In - values: - - master diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-d/vm.tolerations.patch.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-d/vm.tolerations.patch.yaml deleted file mode 100644 index 97af267d8b..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-d/vm.tolerations.patch.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachine -metadata: - name: vm -spec: - tolerations: - - effect: NoSchedule - operator: Exists diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-node-affinity/kustomization.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-node-affinity/kustomization.yaml deleted file mode 100644 index 2a5328c7a7..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-node-affinity/kustomization.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -nameSuffix: -node-affinity -resources: - - ../../base -labels: - - includeSelectors: true - pairs: - vm: vm-node-affinity diff --git a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-node-selector/kustomization.yaml b/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-node-selector/kustomization.yaml deleted file mode 100644 index 4ff96bf874..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vm/overlays/vm-node-selector/kustomization.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -nameSuffix: -node-selector -resources: - - ../../base -labels: - - includeSelectors: true - pairs: - vm: vm-node-selector diff --git a/test/e2e/legacy/testdata/affinity-toleration/vmc.yaml b/test/e2e/legacy/testdata/affinity-toleration/vmc.yaml deleted file mode 100644 index 68c1540fca..0000000000 --- a/test/e2e/legacy/testdata/affinity-toleration/vmc.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha3 -kind: VirtualMachineClass -metadata: - name: affinity-toleration-discovery -spec: - cpu: - type: Discovery diff --git a/test/e2e/legacy/testdata/vm-disk-attachment/base/cfg/cloudinit.yaml b/test/e2e/legacy/testdata/vm-disk-attachment/base/cfg/cloudinit.yaml deleted file mode 100644 index 6843d60c8b..0000000000 --- a/test/e2e/legacy/testdata/vm-disk-attachment/base/cfg/cloudinit.yaml +++ /dev/null @@ -1,24 +0,0 @@ -#cloud-config -package_update: true -packages: - - qemu-guest-agent - - curl - - bash - - sudo - - iputils - - util-linux -users: - - name: cloud - # passwd: cloud - passwd: $6$rounds=4096$vln/.aPHBOI7BMYR$bBMkqQvuGs5Gyd/1H5DP4m9HjQSy.kgrxpaGEHwkX7KEFV8BS.HZWPitAtZ2Vd8ZqIZRqmlykRCagTgPejt1i. - shell: /bin/bash - sudo: ALL=(ALL) NOPASSWD:ALL - lock_passwd: false - ssh_authorized_keys: - # testcases - - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFxcXHmwaGnJ8scJaEN5RzklBPZpVSic4GdaAsKjQoeA your_email@example.com -final_message: "\U0001F525\U0001F525\U0001F525 The system is finally up, after ${updame} \U0001F525\U0001F525\U0001F525" -runcmd: - - "echo \"\U0001F7E1 Starting runcmd at $(date +%H:%M:%S)\"" - - "rc-update add qemu-guest-agent && rc-service qemu-guest-agent start" - - "echo \"\U0001F7E1 Finished runcmd at $(date +%H:%M:%S)\"" diff --git a/test/e2e/legacy/testdata/vm-disk-attachment/base/kustomization.yaml b/test/e2e/legacy/testdata/vm-disk-attachment/base/kustomization.yaml deleted file mode 100644 index d820a3f566..0000000000 --- a/test/e2e/legacy/testdata/vm-disk-attachment/base/kustomization.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - ./vm.yaml - - ./vd-root.yaml -configurations: - - transformer.yaml -generatorOptions: - disableNameSuffixHash: true -secretGenerator: - - files: - - userData=cfg/cloudinit.yaml - name: cloud-init - type: provisioning.virtualization.deckhouse.io/cloud-init diff --git a/test/e2e/legacy/testdata/vm-disk-attachment/base/transformer.yaml b/test/e2e/legacy/testdata/vm-disk-attachment/base/transformer.yaml deleted file mode 100644 index 1dc146a3af..0000000000 --- a/test/e2e/legacy/testdata/vm-disk-attachment/base/transformer.yaml +++ /dev/null @@ -1,54 +0,0 @@ -# https://github.com/kubernetes-sigs/kustomize/blob/master/examples/transformerconfigs/README.md#transformer-configurations - -namespace: - - kind: ClusterVirtualImage - path: spec/dataSource/objectRef/namespace -nameReference: - - kind: VirtualImage - version: v1alpha2 # optional - fieldSpecs: - - path: spec/dataSource/objectRef/name - kind: ClusterVirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualDisk - - path: spec/blockDeviceRefs/name - kind: VirtualMachine - - kind: ClusterVirtualImage - version: v1alpha2 # optional - fieldSpecs: - - path: spec/dataSource/objectRef/name - kind: ClusterVirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualDisk - - path: spec/blockDeviceRefs/name - kind: VirtualMachine - - kind: VirtualDisk - version: v1alpha2 # optional - fieldSpecs: - - path: spec/blockDeviceRefs/name - kind: VirtualMachine - - path: spec/blockDeviceRef/name - kind: VirtualMachineBlockDeviceAttachment - - kind: Secret - fieldSpecs: - - path: spec/provisioning/userDataRef/name - kind: VirtualMachine - - kind: VirtualMachineIPAddress - version: v1alpha2 - fieldSpecs: - - path: spec/virtualMachineIPAddressName - kind: VirtualMachine - - kind: VirtualMachine - version: v1alpha2 - fieldSpecs: - - path: spec/virtualMachineName - kind: VirtualMachineBlockDeviceAttachment - - kind: VirtualMachineClass - version: v1alpha3 - fieldSpecs: - - path: spec/virtualMachineClassName - kind: VirtualMachine diff --git a/test/e2e/legacy/testdata/vm-disk-attachment/base/vd-root.yaml b/test/e2e/legacy/testdata/vm-disk-attachment/base/vd-root.yaml deleted file mode 100644 index 5623d567ed..0000000000 --- a/test/e2e/legacy/testdata/vm-disk-attachment/base/vd-root.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualDisk -metadata: - name: vd-root -spec: - persistentVolumeClaim: - storageClassName: "{{ .STORAGE_CLASS_NAME }}" - size: 512Mi - dataSource: - type: ObjectRef - objectRef: - kind: ClusterVirtualImage - name: v12n-e2e-alpine-uefi diff --git a/test/e2e/legacy/testdata/vm-disk-attachment/base/vm.yaml b/test/e2e/legacy/testdata/vm-disk-attachment/base/vm.yaml deleted file mode 100644 index 784fad69f2..0000000000 --- a/test/e2e/legacy/testdata/vm-disk-attachment/base/vm.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachine -metadata: - name: vm -spec: - bootloader: EFI - virtualMachineClassName: generic - cpu: - cores: 1 - coreFraction: 100% - memory: - size: 256Mi - disruptions: - restartApprovalMode: Manual - provisioning: - type: UserDataRef - userDataRef: - kind: Secret - name: cloud-init - blockDeviceRefs: - - kind: VirtualDisk - name: vd-root diff --git a/test/e2e/legacy/testdata/vm-disk-attachment/kustomization.yaml b/test/e2e/legacy/testdata/vm-disk-attachment/kustomization.yaml deleted file mode 100644 index d8a3bc44a9..0000000000 --- a/test/e2e/legacy/testdata/vm-disk-attachment/kustomization.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -namespace: testcases -namePrefix: pr-number-or-commit-hash- -resources: - - ns.yaml - - overlays/vm -configurations: - - transformer.yaml -labels: - - includeSelectors: true - pairs: - id: pr-number-or-commit-hash - testcase: vm-disk-attachment diff --git a/test/e2e/legacy/testdata/vm-disk-attachment/ns.yaml b/test/e2e/legacy/testdata/vm-disk-attachment/ns.yaml deleted file mode 100644 index 5efde875b6..0000000000 --- a/test/e2e/legacy/testdata/vm-disk-attachment/ns.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: default diff --git a/test/e2e/legacy/testdata/vm-disk-attachment/overlays/vm/kustomization.yaml b/test/e2e/legacy/testdata/vm-disk-attachment/overlays/vm/kustomization.yaml deleted file mode 100644 index 16ba42a86d..0000000000 --- a/test/e2e/legacy/testdata/vm-disk-attachment/overlays/vm/kustomization.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - ../../base - - ./vd-attach.yaml -patches: - - patch: |- - - op: replace - path: /spec/runPolicy - value: AlwaysOn - target: - kind: VirtualMachine - name: vm - - patch: |- - - op: replace - path: /spec/disruptions/restartApprovalMode - value: Automatic - target: - kind: VirtualMachine - name: vm diff --git a/test/e2e/legacy/testdata/vm-disk-attachment/overlays/vm/vd-attach.yaml b/test/e2e/legacy/testdata/vm-disk-attachment/overlays/vm/vd-attach.yaml deleted file mode 100644 index aa257ad1cd..0000000000 --- a/test/e2e/legacy/testdata/vm-disk-attachment/overlays/vm/vd-attach.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualDisk -metadata: - name: vd-attach - labels: - hasNoConsumer: "vm-disk-attachment" -spec: - persistentVolumeClaim: - storageClassName: "{{ .STORAGE_CLASS_NAME }}" - size: 100Mi diff --git a/test/e2e/legacy/testdata/vm-disk-attachment/transformer.yaml b/test/e2e/legacy/testdata/vm-disk-attachment/transformer.yaml deleted file mode 100644 index ec70d37fcd..0000000000 --- a/test/e2e/legacy/testdata/vm-disk-attachment/transformer.yaml +++ /dev/null @@ -1,52 +0,0 @@ -namespace: - - kind: ClusterVirtualImage - path: spec/dataSource/objectRef/namespace -nameReference: - - kind: VirtualImage - version: v1alpha2 # optional - fieldSpecs: - - path: spec/dataSource/objectRef/name - kind: ClusterVirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualDisk - - path: spec/blockDeviceRefs/name - kind: VirtualMachine - - kind: ClusterVirtualImage - version: v1alpha2 # optional - fieldSpecs: - - path: spec/dataSource/objectRef/name - kind: ClusterVirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualImage - - path: spec/dataSource/objectRef/name - kind: VirtualDisk - - path: spec/blockDeviceRefs/name - kind: VirtualMachine - - kind: VirtualDisk - version: v1alpha2 # optional - fieldSpecs: - - path: spec/blockDeviceRefs/name - kind: VirtualMachine - - path: spec/blockDeviceRef/name - kind: VirtualMachineBlockDeviceAttachment - - kind: Secret - fieldSpecs: - - path: spec/provisioning/userDataRef/name - kind: VirtualMachine - - kind: VirtualMachineIPAddress - version: v1alpha2 - fieldSpecs: - - path: spec/virtualMachineIPAddressName - kind: VirtualMachine - - kind: VirtualMachine - version: v1alpha2 - fieldSpecs: - - path: spec/virtualMachineName - kind: VirtualMachineBlockDeviceAttachment - - kind: VirtualMachineClass - version: v1alpha3 - fieldSpecs: - - path: spec/virtualMachineClassName - kind: VirtualMachine diff --git a/test/e2e/legacy/testdata/vm-disk-attachment/vmbda/.keep b/test/e2e/legacy/testdata/vm-disk-attachment/vmbda/.keep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/e2e/legacy/vm_disk_attachment.go b/test/e2e/legacy/vm_disk_attachment.go deleted file mode 100644 index d43338e56e..0000000000 --- a/test/e2e/legacy/vm_disk_attachment.go +++ /dev/null @@ -1,263 +0,0 @@ -/* -Copyright 2024 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 legacy - -import ( - "encoding/json" - "fmt" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/deckhouse/virtualization/api/core/v1alpha2" - "github.com/deckhouse/virtualization/test/e2e/internal/config" - "github.com/deckhouse/virtualization/test/e2e/internal/d8" - "github.com/deckhouse/virtualization/test/e2e/internal/framework" - kc "github.com/deckhouse/virtualization/test/e2e/internal/kubectl" - "github.com/deckhouse/virtualization/test/e2e/internal/label" - "github.com/deckhouse/virtualization/test/e2e/internal/util" -) - -const unacceptableCount = -1000 - -var APIVersion = v1alpha2.SchemeGroupVersion.String() - -var _ = Describe("VirtualDiskAttachment", Ordered, label.Legacy(), func() { - var ( - testCaseLabel = map[string]string{"testcase": "vm-disk-attachment"} - hasNoConsumerLabel = map[string]string{"hasNoConsumer": "vm-disk-attachment"} - disksBefore Disks - disksAfter Disks - vdAttach string - vmName string - ns string - phaseByVolumeBindingMode = util.GetExpectedDiskPhaseByVolumeBindingMode() - ) - - BeforeAll(func() { - vdAttach = fmt.Sprintf("%s-vd-attach", namePrefix) - vmName = fmt.Sprintf("%s-vm", namePrefix) - - kustomization := fmt.Sprintf("%s/%s", conf.TestData.VMDiskAttachment, "kustomization.yaml") - var err error - ns, err = kustomize.GetNamespace(kustomization) - Expect(err).NotTo(HaveOccurred(), "%w", err) - - CreateNamespace(ns) - }) - - AfterEach(func() { - if CurrentSpecReport().Failed() { - SaveTestCaseDump(testCaseLabel, CurrentSpecReport().LeafNodeText, ns) - } - }) - - AfterAll(func() { - if config.IsCleanUpNeeded() { - DeleteTestCaseResources(ns, ResourcesToDelete{ - KustomizationDir: conf.TestData.VMDiskAttachment, - }) - } - }) - - Context("When resources are applied", func() { - It("result should be succeeded", func() { - res := kubectl.Apply(kc.ApplyOptions{ - Filename: []string{conf.TestData.VMDiskAttachment}, - FilenameOption: kc.Kustomize, - }) - Expect(res.WasSuccess()).To(Equal(true), res.StdErr()) - }) - }) - - Context("When virtual disks are applied", func() { - It("checks VDs phases", func() { - By(fmt.Sprintf("VDs with consumers should be in %s phases", PhaseReady)) - WaitPhaseByLabel(kc.ResourceVD, PhaseReady, kc.WaitOptions{ - ExcludedLabels: []string{"hasNoConsumer"}, - Labels: testCaseLabel, - Namespace: ns, - Timeout: MaxWaitTimeout, - }) - By(fmt.Sprintf("VDs without consumers should be in %s phases", phaseByVolumeBindingMode)) - WaitPhaseByLabel(kc.ResourceVD, phaseByVolumeBindingMode, kc.WaitOptions{ - Labels: hasNoConsumerLabel, - Namespace: ns, - Timeout: MaxWaitTimeout, - }) - }) - }) - - Context("When virtual machines are applied", func() { - It("checks VMs phases", func() { - By(fmt.Sprintf("VMs should be in the %s phase", v1alpha2.MachineRunning)) - WaitPhaseByLabel(kc.ResourceVM, string(v1alpha2.MachineRunning), kc.WaitOptions{ - Labels: testCaseLabel, - Namespace: ns, - Timeout: MaxWaitTimeout, - }) - }) - }) - - Describe("Attachment", func() { - Context(fmt.Sprintf("When VMs in the %s phase", v1alpha2.MachineRunning), func() { - It("get disk count before attachment", func() { - Eventually(func() error { - return GetDisksMetadata(ns, vmName, &disksBefore) - }).WithTimeout(Timeout).WithPolling(Interval).ShouldNot(HaveOccurred(), "virtualMachine: %s", vmName) - }) - It("attaches virtual disk", func() { - AttachBlockDevice(ns, vmName, vdAttach, v1alpha2.VMBDAObjectRefKindVirtualDisk, testCaseLabel, conf.TestData.VMDiskAttachment) - }) - It("checks VM and VMBDA phases", func() { - By(fmt.Sprintf("VMBDA should be in %s phases", PhaseAttached)) - WaitPhaseByLabel(kc.ResourceVMBDA, PhaseAttached, kc.WaitOptions{ - Labels: testCaseLabel, - Namespace: ns, - Timeout: MaxWaitTimeout, - }) - By(fmt.Sprintf("VMs should be in the %s phase", v1alpha2.MachineRunning)) - WaitPhaseByLabel(kc.ResourceVM, string(v1alpha2.MachineRunning), kc.WaitOptions{ - Labels: testCaseLabel, - Namespace: ns, - Timeout: MaxWaitTimeout, - }) - }) - It("compares disk count before and after attachment", func() { - diskCountBefore := len(disksBefore.BlockDevices) - Eventually(func() (int, error) { - err := GetDisksMetadata(ns, vmName, &disksAfter) - if err != nil { - return unacceptableCount, err - } - diskCountAfter := len(disksAfter.BlockDevices) - return diskCountAfter, nil - }).WithTimeout(Timeout).WithPolling(Interval).Should(Equal(diskCountBefore+1), "comparing error: 'after' must be equal 'before + 1'") - }) - }) - }) - - Describe("Detachment", func() { - Context(fmt.Sprintf("When virtual machines are in %s phases", PhaseRunning), func() { - It("get disk count before detachment", func() { - Eventually(func() error { - return GetDisksMetadata(ns, vmName, &disksBefore) - }).WithTimeout(Timeout).WithPolling(Interval).ShouldNot(HaveOccurred(), "virtual machine: %s", vmName) - }) - It("detaches virtual disk", func() { - res := kubectl.Delete(kc.DeleteOptions{ - Filename: []string{fmt.Sprintf("%s/vmbda", conf.TestData.VMDiskAttachment)}, - FilenameOption: kc.Filename, - Namespace: ns, - }) - Expect(res.Error()).NotTo(HaveOccurred(), res.StdErr()) - }) - It("checks VMs phase", func() { - By(fmt.Sprintf("VMs should be in the %s phase", v1alpha2.MachineRunning)) - WaitPhaseByLabel(kc.ResourceVM, string(v1alpha2.MachineRunning), kc.WaitOptions{ - Labels: testCaseLabel, - Namespace: ns, - Timeout: MaxWaitTimeout, - }) - }) - It("compares disk count before and after detachment", func() { - diskCountBefore := len(disksBefore.BlockDevices) - Eventually(func() (int, error) { - err := GetDisksMetadata(ns, vmName, &disksAfter) - if err != nil { - return unacceptableCount, err - } - return len(disksAfter.BlockDevices), nil - }).WithTimeout(Timeout).WithPolling(Interval).Should(Equal(diskCountBefore-1), "comparing error: 'after' must be equal 'before - 1'") - }) - }) - }) -}) - -// lsblk JSON output -type Disks struct { - BlockDevices []BlockDevice `json:"blockdevices"` -} - -type BlockDevices struct { - BlockDevices []BlockDevice `json:"blockdevices"` -} - -type BlockDevice struct { - Name string `json:"name"` - Size string `json:"size"` - Type string `json:"type"` -} - -func AttachBlockDevice(vmNamespace, vmName, blockDeviceName string, blockDeviceType v1alpha2.VMBDAObjectRefKind, labels map[string]string, testDataPath string) { - vmbdaFilePath := fmt.Sprintf("%s/vmbda/%s.yaml", testDataPath, blockDeviceName) - err := CreateVMBDAManifest(vmbdaFilePath, vmName, blockDeviceName, blockDeviceType, labels) - Expect(err).NotTo(HaveOccurred(), "%v", err) - - res := kubectl.Apply(kc.ApplyOptions{ - Filename: []string{vmbdaFilePath}, - FilenameOption: kc.Filename, - Namespace: vmNamespace, - }) - Expect(res.Error()).NotTo(HaveOccurred(), res.StdErr()) -} - -func CreateVMBDAManifest(filePath, vmName, blockDeviceName string, blockDeviceType v1alpha2.VMBDAObjectRefKind, labels map[string]string) error { - vmbda := &v1alpha2.VirtualMachineBlockDeviceAttachment{ - TypeMeta: metav1.TypeMeta{ - APIVersion: APIVersion, - Kind: v1alpha2.VirtualMachineBlockDeviceAttachmentKind, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: blockDeviceName, - Labels: labels, - }, - Spec: v1alpha2.VirtualMachineBlockDeviceAttachmentSpec{ - VirtualMachineName: vmName, - BlockDeviceRef: v1alpha2.VMBDAObjectRef{ - Kind: blockDeviceType, - Name: blockDeviceName, - }, - }, - } - - err := util.WriteYamlObject(filePath, vmbda) - if err != nil { - return err - } - - return nil -} - -func GetDisksMetadata(vmNamespace, vmName string, disks *Disks) error { - GinkgoHelper() - cmd := "lsblk --nodeps --json" - res := framework.GetClients().D8Virtualization().SSHCommand(vmName, cmd, d8.SSHOptions{ - Namespace: vmNamespace, - Username: conf.TestData.SSHUser, - IdentityFile: conf.TestData.Sshkey, - }) - if res.Error() != nil { - return fmt.Errorf("cmd: %s\nstderr: %s", res.GetCmd(), res.StdErr()) - } - err := json.Unmarshal(res.StdOutBytes(), disks) - if err != nil { - return fmt.Errorf("failed when getting disk count\nvirtualMachine: %s/%s\nstderr: %s", vmNamespace, vmName, res.StdErr()) - } - return nil -} diff --git a/test/e2e/vm/disk_attachment.go b/test/e2e/vm/disk_attachment.go new file mode 100644 index 0000000000..468747b0c6 --- /dev/null +++ b/test/e2e/vm/disk_attachment.go @@ -0,0 +1,148 @@ +/* +Copyright 2026 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 vm + +import ( + "context" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/utils/ptr" + + vdbuilder "github.com/deckhouse/virtualization-controller/pkg/builder/vd" + vmbuilder "github.com/deckhouse/virtualization-controller/pkg/builder/vm" + vmbdabuilder "github.com/deckhouse/virtualization-controller/pkg/builder/vmbda" + "github.com/deckhouse/virtualization/api/core/v1alpha2" + "github.com/deckhouse/virtualization/test/e2e/internal/framework" + "github.com/deckhouse/virtualization/test/e2e/internal/object" + "github.com/deckhouse/virtualization/test/e2e/internal/util" +) + +var _ = Describe("DiskAttachment", func() { + var ( + f *framework.Framework + vdRoot *v1alpha2.VirtualDisk + vdBlank *v1alpha2.VirtualDisk + vm *v1alpha2.VirtualMachine + vmbda *v1alpha2.VirtualMachineBlockDeviceAttachment + + ctx context.Context + + diskCountBeforeAttachment int + diskCountBeforeDetachment int + ) + + BeforeEach(func() { + f = framework.NewFramework("disk-attachment") + ctx = context.Background() + DeferCleanup(f.After) + f.Before() + }) + + It("attaches and detaches a virtual disk to a running VM", func() { + By("Create test resources", func() { + // Create VD from CVI for VM root disk + vdRoot = object.NewVDFromCVI("vd-root", f.Namespace().Name, object.PrecreatedCVIAlpineBIOS, + vdbuilder.WithSize(ptr.To(resource.MustParse("512Mi"))), + ) + + // Create blank VD without consumer (for attachment test) + vdBlank = vdbuilder.New( + vdbuilder.WithName("vd-blank"), + vdbuilder.WithNamespace(f.Namespace().Name), + vdbuilder.WithPersistentVolumeClaim(nil, ptr.To(resource.MustParse("100Mi"))), + ) + + // Create VM with root disk + vm = object.NewMinimalVM("", f.Namespace().Name, + vmbuilder.WithBlockDeviceRefs( + v1alpha2.BlockDeviceSpecRef{ + Kind: v1alpha2.VirtualDiskKind, + Name: vdRoot.Name, + }, + ), + vmbuilder.WithName("vm"), + vmbuilder.WithCPU(1, ptr.To("100%")), + ) + + // Create VMBDA for attachment (to be created later) + vmbda = vmbdabuilder.New( + vmbdabuilder.WithName("vmbda"), + vmbdabuilder.WithNamespace(f.Namespace().Name), + vmbdabuilder.WithVirtualMachineName(vm.Name), + vmbdabuilder.WithBlockDeviceRef(v1alpha2.VMBDAObjectRefKindVirtualDisk, vdBlank.Name), + ) + + // Create VD and VM first + err := f.CreateWithDeferredDeletion(ctx, vdRoot, vdBlank, vm) + Expect(err).NotTo(HaveOccurred()) + + // Get expected phase for VD without consumer based on VolumeBindingMode + expectedDiskPhase := util.GetExpectedDiskPhaseByVolumeBindingMode() + + By("Wait for resources to be ready", func() { + util.UntilObjectPhase(expectedDiskPhase, framework.LongTimeout, vdBlank) + util.UntilObjectPhase(string(v1alpha2.MachineRunning), framework.LongTimeout, vm) + util.UntilSSHReady(f, vm, framework.MiddleTimeout) + }) + }) + + By("Get disk count before attachment", func() { + var err error + diskCountBeforeAttachment, err = util.GetDiskCount(f, vm.Name, vm.Namespace) + Expect(err).NotTo(HaveOccurred()) + }) + + By("Create VMBDA to attach the disk", func() { + err := f.CreateWithDeferredDeletion(ctx, vmbda) + Expect(err).NotTo(HaveOccurred()) + + util.UntilObjectPhase(string(v1alpha2.BlockDeviceAttachmentPhaseAttached), framework.LongTimeout, vmbda) + }) + + By("Verify disk count increased by 1", func() { + Eventually(func(g Gomega) { + diskCountAfterAttachment, err := util.GetDiskCount(f, vm.Name, vm.Namespace) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(diskCountAfterAttachment).To(Equal(diskCountBeforeAttachment+1), + "disk count after attachment should be before + 1") + }).WithTimeout(framework.MiddleTimeout).WithPolling(time.Second).Should(Succeed()) + }) + + By("Get disk count before detachment", func() { + var err error + diskCountBeforeDetachment, err = util.GetDiskCount(f, vm.Name, vm.Namespace) + Expect(err).NotTo(HaveOccurred()) + }) + + By("Detach virtual disk", func() { + err := f.Delete(ctx, vmbda) + Expect(err).NotTo(HaveOccurred()) + }) + + By("Verify disk count decreased by 1", func() { + Eventually(func(g Gomega) { + diskCountAfterDetachment, err := util.GetDiskCount(f, vm.Name, vm.Namespace) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(diskCountAfterDetachment).To(Equal(diskCountBeforeDetachment-1), + "disk count after detachment should be before - 1") + }).WithTimeout(framework.MiddleTimeout).WithPolling(time.Second).Should(Succeed()) + }) + }) +})