From cfd58b854c386379afc66d86747d0ba3c27521c7 Mon Sep 17 00:00:00 2001 From: Bella Khizgiyaev Date: Thu, 13 Jun 2024 17:42:41 +0300 Subject: [PATCH] Change the string passing for rootdisk from disk number to diskname + partition Signed-off-by: Bella Khizgiyaev --- .../crd/bases/forklift.konveyor.io_plans.yaml | 3 +++ pkg/apis/forklift/v1beta1/plan/vm.go | 6 +++-- .../plan/adapter/vsphere/BUILD.bazel | 1 + .../plan/adapter/vsphere/builder.go | 19 ++++++-------- .../adapter/vsphere/vsphere_suite_test.go | 26 +++++++++++++++++++ pkg/controller/plan/kubevirt.go | 18 ++++--------- pkg/controller/plan/util/utils.go | 22 ++++++++++++++++ .../provider/container/vsphere/model.go | 9 ------- .../provider/model/vsphere/model.go | 1 - virt-v2v/cold/entrypoint.go | 18 +++++-------- 10 files changed, 75 insertions(+), 48 deletions(-) diff --git a/operator/config/crd/bases/forklift.konveyor.io_plans.yaml b/operator/config/crd/bases/forklift.konveyor.io_plans.yaml index 784ccbf37..e95471e43 100644 --- a/operator/config/crd/bases/forklift.konveyor.io_plans.yaml +++ b/operator/config/crd/bases/forklift.konveyor.io_plans.yaml @@ -428,6 +428,9 @@ spec: The VM Namespace Only relevant for an openshift source. type: string + rootDisk: + description: Choose the primary disk the VM boots from + type: string type: description: Type used to qualify the name. type: string diff --git a/pkg/apis/forklift/v1beta1/plan/vm.go b/pkg/apis/forklift/v1beta1/plan/vm.go index 21e41c44e..7afaff095 100644 --- a/pkg/apis/forklift/v1beta1/plan/vm.go +++ b/pkg/apis/forklift/v1beta1/plan/vm.go @@ -33,6 +33,9 @@ type VM struct { // Disk decryption LUKS keys // +optional LUKS core.ObjectReference `json:"luks" ref:"Secret"` + // Choose the primary disk the VM boots from + // +optional + RootDisk string `json:"rootDisk,omitempty"` } // Find a Hook for the specified step. @@ -66,8 +69,7 @@ type VMStatus struct { Firmware string `json:"firmware,omitempty"` // The Operating System detected by virt-v2v. OperatingSystem string `json:"operatingSystem,omitempty"` - //Choose the primary disk the VM boots from - RootDisk string `json:"rootDisk,omitempty"` + // Conditions. libcnd.Conditions `json:",inline"` } diff --git a/pkg/controller/plan/adapter/vsphere/BUILD.bazel b/pkg/controller/plan/adapter/vsphere/BUILD.bazel index 380efa315..f5e1062ae 100644 --- a/pkg/controller/plan/adapter/vsphere/BUILD.bazel +++ b/pkg/controller/plan/adapter/vsphere/BUILD.bazel @@ -60,6 +60,7 @@ go_test( "//pkg/apis/forklift/v1beta1/plan", "//pkg/apis/forklift/v1beta1/ref", "//pkg/controller/plan/context", + "//pkg/controller/plan/util", "//pkg/controller/provider/model/vsphere", "//pkg/controller/provider/web", "//pkg/controller/provider/web/vsphere", diff --git a/pkg/controller/plan/adapter/vsphere/builder.go b/pkg/controller/plan/adapter/vsphere/builder.go index 26d10a41b..6f07a5c30 100644 --- a/pkg/controller/plan/adapter/vsphere/builder.go +++ b/pkg/controller/plan/adapter/vsphere/builder.go @@ -9,14 +9,13 @@ import ( "regexp" "sort" "strings" - "strconv" - api "github.com/konveyor/forklift-controller/pkg/apis/forklift/v1beta1" "github.com/konveyor/forklift-controller/pkg/apis/forklift/v1beta1/plan" "github.com/konveyor/forklift-controller/pkg/apis/forklift/v1beta1/ref" planbase "github.com/konveyor/forklift-controller/pkg/controller/plan/adapter/base" plancontext "github.com/konveyor/forklift-controller/pkg/controller/plan/context" + utils "github.com/konveyor/forklift-controller/pkg/controller/plan/util" container "github.com/konveyor/forklift-controller/pkg/controller/provider/container/vsphere" "github.com/konveyor/forklift-controller/pkg/controller/provider/model/vsphere" "github.com/konveyor/forklift-controller/pkg/controller/provider/web" @@ -31,6 +30,7 @@ import ( "github.com/vmware/govmomi/vim25/types" core "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/utils/ptr" cnv "kubevirt.io/api/core/v1" cdi "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -657,17 +657,12 @@ func (r *Builder) mapDisks(vm *model.VM, vmRef ref.Ref, persistentVolumeClaims [ } var bootDisk int - for _, vmConf := range r.Migration.Status.VMs { + for _, vmConf := range r.Plan.Spec.VMs { if vmConf.ID == vmRef.ID { - var err error - bootDisk, err = strconv.Atoi(vmConf.RootDisk) - if err != nil { - bootDisk = 1 - } + bootDisk = utils.GetDeviceNumber(vmConf.RootDisk) break } } - bootOrder := func(order uint) *uint { return &order } for i, disk := range disks { pvc := pvcMap[r.baseVolume(disk.File)] @@ -690,9 +685,11 @@ func (r *Builder) mapDisks(vm *model.VM, vmRef ref.Ref, persistentVolumeClaims [ }, }, } + // For multiboot VMs, if the selected boot device is the current disk, + // set it as the first in the boot order. if bootDisk == i+1 { - kubevirtDisk.BootOrder = bootOrder(1) - } + kubevirtDisk.BootOrder = ptr.To(uint(1)) + } kVolumes = append(kVolumes, volume) kDisks = append(kDisks, kubevirtDisk) } diff --git a/pkg/controller/plan/adapter/vsphere/vsphere_suite_test.go b/pkg/controller/plan/adapter/vsphere/vsphere_suite_test.go index da4192991..8e154039b 100644 --- a/pkg/controller/plan/adapter/vsphere/vsphere_suite_test.go +++ b/pkg/controller/plan/adapter/vsphere/vsphere_suite_test.go @@ -3,6 +3,7 @@ package vsphere import ( "testing" + utils "github.com/konveyor/forklift-controller/pkg/controller/plan/util" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) @@ -11,3 +12,28 @@ func TestVsphere(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "vSphere Suite") } + +func TestGetDeviceNumber(t *testing.T) { + tests := []struct { + input string + expected int + }{ + {"/dev/sda", 1}, + {"/dev/sdb", 2}, + {"/dev/sdz", 26}, + {"/dev/sda1", 1}, + {"/dev/sda5", 1}, + {"/dev/sdb2", 2}, + {"/dev/sdza", 26}, + {"/dev/sdzb", 26}, + {"/dev/sd", 0}, + {"test", 0}, + } + + for _, test := range tests { + result := utils.GetDeviceNumber(test.input) + if result != test.expected { + t.Errorf("For input '%s', expected %d, but got %d", test.input, test.expected, result) + } + } +} diff --git a/pkg/controller/plan/kubevirt.go b/pkg/controller/plan/kubevirt.go index 4ec920b0b..86a735585 100644 --- a/pkg/controller/plan/kubevirt.go +++ b/pkg/controller/plan/kubevirt.go @@ -1610,19 +1610,11 @@ func (r *KubeVirt) guestConversionPod(vm *plan.VMStatus, vmVolumes []cnv.Volume, } if vm.RootDisk != "" { - diskNum, errDisk := strconv.Atoi(vm.RootDisk) - if errDisk != nil { - return - } - - if diskNum > 0 { - - environment = append(environment, - core.EnvVar{ - Name: "V2V_RootDisk", - Value: vm.RootDisk, - }) - } + environment = append(environment, + core.EnvVar{ + Name: "V2V_RootDisk", + Value: vm.RootDisk, + }) } // pod annotations annotations := map[string]string{} diff --git a/pkg/controller/plan/util/utils.go b/pkg/controller/plan/util/utils.go index ae1e8c335..8fd339fcf 100644 --- a/pkg/controller/plan/util/utils.go +++ b/pkg/controller/plan/util/utils.go @@ -2,6 +2,8 @@ package util import ( "math" + "strings" + "unicode" api "github.com/konveyor/forklift-controller/pkg/apis/forklift/v1beta1" "github.com/konveyor/forklift-controller/pkg/settings" @@ -14,6 +16,11 @@ const ( DefaultAlignBlockSize = 1024 * 1024 ) +// RootDisk prefix for boot order. +const ( + diskPrefix = "/dev/sd" +) + func roundUp(requestedSpace, multiple int64) int64 { if multiple == 0 { return requestedSpace @@ -33,4 +40,19 @@ func CalculateSpaceWithOverhead(requestedSpace int64, volumeMode *core.Persisten return spaceWithOverhead } +func GetDeviceNumber(deviceString string) int { + if !(strings.HasPrefix(deviceString, diskPrefix) && len(deviceString) > len(diskPrefix)) { + // In case we encounter an issue detecting the root disk order, + // we will return zero to avoid failing the migration due to boot orde + return 0 + } + + for i := len(diskPrefix); i < len(deviceString); i++ { + if unicode.IsLetter(rune(deviceString[i])) { + return int(deviceString[i] - 'a' + 1) + } + } + return 0 +} + type HostsFunc func() (map[string]*api.Host, error) diff --git a/pkg/controller/provider/container/vsphere/model.go b/pkg/controller/provider/container/vsphere/model.go index a1d915dfb..e388db637 100644 --- a/pkg/controller/provider/container/vsphere/model.go +++ b/pkg/controller/provider/container/vsphere/model.go @@ -701,7 +701,6 @@ func (v *VmAdapter) Apply(u types.ObjectUpdate) { // Update virtual disk devices. func (v *VmAdapter) updateDisks(devArray *types.ArrayOfVirtualDevice) { disks := []model.Disk{} - //var diskNum int32 = 1 for _, dev := range devArray.VirtualDevice { switch dev.(type) { case *types.VirtualDisk: @@ -713,7 +712,6 @@ func (v *VmAdapter) updateDisks(devArray *types.ArrayOfVirtualDevice) { File: backing.FileName, Capacity: disk.CapacityInBytes, Mode: backing.DiskMode, - //Number: diskNum, } if backing.Datastore != nil { datastoreId, _ := sanitize(backing.Datastore.Value) @@ -723,7 +721,6 @@ func (v *VmAdapter) updateDisks(devArray *types.ArrayOfVirtualDevice) { } } disks = append(disks, md) - //diskNum++ case *types.VirtualDiskFlatVer2BackingInfo: md := model.Disk{ Key: disk.Key, @@ -731,7 +728,6 @@ func (v *VmAdapter) updateDisks(devArray *types.ArrayOfVirtualDevice) { Capacity: disk.CapacityInBytes, Shared: backing.Sharing != "sharingNone", Mode: backing.DiskMode, - //Number: diskNum, } if backing.Datastore != nil { datastoreId, _ := sanitize(backing.Datastore.Value) @@ -741,7 +737,6 @@ func (v *VmAdapter) updateDisks(devArray *types.ArrayOfVirtualDevice) { } } disks = append(disks, md) - //diskNum++ case *types.VirtualDiskRawDiskMappingVer1BackingInfo: md := model.Disk{ Key: disk.Key, @@ -750,7 +745,6 @@ func (v *VmAdapter) updateDisks(devArray *types.ArrayOfVirtualDevice) { Shared: backing.Sharing != "sharingNone", Mode: backing.DiskMode, RDM: true, - //Number: diskNum, } if backing.Datastore != nil { datastoreId, _ := sanitize(backing.Datastore.Value) @@ -760,7 +754,6 @@ func (v *VmAdapter) updateDisks(devArray *types.ArrayOfVirtualDevice) { } } disks = append(disks, md) - //diskNum++ case *types.VirtualDiskRawDiskVer2BackingInfo: md := model.Disk{ Key: disk.Key, @@ -768,10 +761,8 @@ func (v *VmAdapter) updateDisks(devArray *types.ArrayOfVirtualDevice) { Capacity: disk.CapacityInBytes, Shared: backing.Sharing != "sharingNone", RDM: true, - //Number: diskNum, } disks = append(disks, md) - //diskNum++ } } } diff --git a/pkg/controller/provider/model/vsphere/model.go b/pkg/controller/provider/model/vsphere/model.go index c33f4cdb0..0fb0cdbe6 100644 --- a/pkg/controller/provider/model/vsphere/model.go +++ b/pkg/controller/provider/model/vsphere/model.go @@ -279,7 +279,6 @@ type Disk struct { Shared bool `json:"shared"` RDM bool `json:"rdm"` Mode string `json:"mode,omitempty"` - //Number int32 `json:"number,omitempty"` } // Virtual Device. diff --git a/virt-v2v/cold/entrypoint.go b/virt-v2v/cold/entrypoint.go index 124a46088..4c38770d1 100644 --- a/virt-v2v/cold/entrypoint.go +++ b/virt-v2v/cold/entrypoint.go @@ -98,20 +98,14 @@ func buildCommand() []string { fmt.Println("Preparing virt-v2v") - if checkEnvVariablesSet("V2V_RootDisk") { - diskNum, err := strconv.Atoi(os.Getenv("V2V_RootDisk")) - if err != nil { - fmt.Println("Error:", err) - os.Exit(1) - } - rootDisk := fmt.Sprintf("/dev/sd%s", genName(diskNum)) - virtV2vArgs = append(virtV2vArgs, "--root", rootDisk) - } else { - virtV2vArgs = append(virtV2vArgs, "--root", "first") - } - switch source { case vSphere: + virtV2vArgs = append(virtV2vArgs, "--root") + if checkEnvVariablesSet("V2V_RootDisk") { + virtV2vArgs = append(virtV2vArgs, os.Getenv("V2V_RootDisk")) + } else { + virtV2vArgs = append(virtV2vArgs, "first") + } virtV2vArgs = append(virtV2vArgs, "-i", "libvirt", "-ic", os.Getenv("V2V_libvirtURL")) case OVA: virtV2vArgs = append(virtV2vArgs, "-i", "ova", os.Getenv("V2V_diskPath"))