From b6ce495d4fdba4d45930cd9c5311d5b97a76adc0 Mon Sep 17 00:00:00 2001 From: rainzm Date: Wed, 20 May 2020 15:33:13 +0800 Subject: [PATCH 1/5] fix(esxi): Separate detach disk and delete disk when rebuilding. In previous versions, set `removeSpec.FileOperation = types.VirtualDeviceConfigSpecFileOperationDestroy' to delete disk indirectly. But, when its parent has only one child, the parent will be deleted along with it. And the consequence is failure to reinstall the system. Now, detach disk without deleteing backing file and then remove backing --- pkg/multicloud/esxi/storage.go | 22 ++++++++++++++++++++++ pkg/multicloud/esxi/vdisk.go | 2 +- pkg/multicloud/esxi/virtualmachine.go | 9 ++++----- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/pkg/multicloud/esxi/storage.go b/pkg/multicloud/esxi/storage.go index 76e34f590e..4e451eb6ce 100644 --- a/pkg/multicloud/esxi/storage.go +++ b/pkg/multicloud/esxi/storage.go @@ -610,6 +610,28 @@ func (self *SDatastore) FilePutContent(ctx context.Context, remotePath string, c return self.Upload(ctx, remotePath, strings.NewReader(content)) } +// Delete2 can delete file from this Datastore. +// isNamespace: remotePath is uuid of namespace on vsan datastore +// force: ignore nonexistent files and arguments +func (self *SDatastore) Delete2(ctx context.Context, remotePath string, isNamespace, force bool) error { + var err error + ds := self.getDatastoreObj() + dc := self.datacenter.getObjectDatacenter() + if isNamespace { + nm := object.NewDatastoreNamespaceManager(self.manager.client.Client) + err = nm.DeleteDirectory(ctx, dc, remotePath) + } else { + fm := ds.NewFileManager(dc, force) + err = fm.Delete(ctx, remotePath) + } + + if err != nil && types.IsFileNotFound(err) && force { + // Ignore error + return nil + } + return err +} + func (self *SDatastore) Delete(ctx context.Context, remotePath string) error { url := self.GetPathUrl(remotePath) diff --git a/pkg/multicloud/esxi/vdisk.go b/pkg/multicloud/esxi/vdisk.go index 74965e9574..a753b4fa01 100644 --- a/pkg/multicloud/esxi/vdisk.go +++ b/pkg/multicloud/esxi/vdisk.go @@ -296,7 +296,7 @@ func (disk *SVirtualDisk) Delete(ctx context.Context) error { return err } ds := istorage.(*SDatastore) - return ds.DeleteVmdk(ctx, disk.getBackingInfo().GetFileName()) + return ds.Delete2(ctx, disk.getBackingInfo().GetFileName(), false, false) } func (disk *SVirtualDisk) CreateISnapshot(ctx context.Context, name string, desc string) (cloudprovider.ICloudSnapshot, error) { diff --git a/pkg/multicloud/esxi/virtualmachine.go b/pkg/multicloud/esxi/virtualmachine.go index 9adaa95037..ce6b265376 100644 --- a/pkg/multicloud/esxi/virtualmachine.go +++ b/pkg/multicloud/esxi/virtualmachine.go @@ -547,10 +547,6 @@ func (self *SVirtualMachine) doDetachDisk(ctx context.Context, vdisk *SVirtualDi removeSpec.Operation = types.VirtualDeviceConfigSpecOperationRemove removeSpec.Device = vdisk.dev - if remove { - removeSpec.FileOperation = types.VirtualDeviceConfigSpecFileOperationDestroy - } - spec := types.VirtualMachineConfigSpec{} spec.DeviceChange = []types.BaseVirtualDeviceConfigSpec{&removeSpec} @@ -568,7 +564,10 @@ func (self *SVirtualMachine) doDetachDisk(ctx context.Context, vdisk *SVirtualDi return err } - return nil + if !remove { + return nil + } + return vdisk.Delete(ctx) } func (self *SVirtualMachine) GetVNCInfo() (jsonutils.JSONObject, error) { From dae02ec019583e990fb44e50f276f6ec12ae6932 Mon Sep 17 00:00:00 2001 From: rainzm Date: Wed, 20 May 2020 15:36:25 +0800 Subject: [PATCH 2/5] fix(esxi): Remove 'Destory' operation that is unnecessary for VirtualDiskManager --- pkg/multicloud/esxi/storage.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/multicloud/esxi/storage.go b/pkg/multicloud/esxi/storage.go index 4e451eb6ce..5d2da10f33 100644 --- a/pkg/multicloud/esxi/storage.go +++ b/pkg/multicloud/esxi/storage.go @@ -694,7 +694,6 @@ func (self *SDatastore) GetVmdkInfo(ctx context.Context, remotePath string) (*vm func (self *SDatastore) CheckVmdk(ctx context.Context, remotePath string) error { dm := object.NewVirtualDiskManager(self.manager.client.Client) - defer dm.Destroy(ctx) dc, err := self.GetDatacenter() if err != nil { From ff2fc744012f25cfde529cab7b60db346b0ff76e Mon Sep 17 00:00:00 2001 From: rainzm Date: Wed, 20 May 2020 15:39:44 +0800 Subject: [PATCH 3/5] Kill processes in time & Add debug info --- pkg/hostman/diskutils/vddk.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/hostman/diskutils/vddk.go b/pkg/hostman/diskutils/vddk.go index 62ee001801..7aa1ef97bc 100644 --- a/pkg/hostman/diskutils/vddk.go +++ b/pkg/hostman/diskutils/vddk.go @@ -116,8 +116,8 @@ func (c *Command) Wait() error { return <-c.done } -func (c *Command) Kill() { - c.Process.Kill() +func (c *Command) Kill() error { + return c.Process.Kill() } func execpath() string { @@ -155,7 +155,12 @@ func (vd *VDDKDisk) MountRootfs() fsdriver.IRootFsDriver { log.Errorf("VDDKDisk Mount failed: %s", err) } // something is wrong - vd.UmountRootfs(nil) + if vd.Proc != nil { + err := vd.Proc.Kill() + if err != nil { + log.Errorf("unable to kill proc: %s", err.Error()) + } + } return nil } @@ -337,6 +342,7 @@ Loop: } backup := vd.Proc.stdouterr.String() + log.Debugf(backup) err := vd.ParsePartitions(backup) if err != nil { return errors.Wrap(err, "VDDKDisk.ParsePartitions") From 9bb7320771c514048c7a7958e8f978cc699fb00c Mon Sep 17 00:00:00 2001 From: rainzm Date: Wed, 20 May 2020 15:41:11 +0800 Subject: [PATCH 4/5] fix(esxi): Detach all disk first when deleting vm --- pkg/multicloud/esxi/virtualmachine.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/multicloud/esxi/virtualmachine.go b/pkg/multicloud/esxi/virtualmachine.go index ce6b265376..1359ee6642 100644 --- a/pkg/multicloud/esxi/virtualmachine.go +++ b/pkg/multicloud/esxi/virtualmachine.go @@ -510,6 +510,13 @@ func (self *SVirtualMachine) shutdownVM(ctx context.Context) error { func (self *SVirtualMachine) doDelete(ctx context.Context) error { vm := self.getVmObj() + // detach all disks first + for i := range self.vdisks { + err := self.doDetachAndDeleteDisk(ctx, &self.vdisks[i]) + if err != nil { + return errors.Wrap(err, "doDetachAndDeteteDisk") + } + } task, err := vm.Destroy(ctx) if err != nil { From d710248496bca37a7113462bfffa9047264f3871 Mon Sep 17 00:00:00 2001 From: rainzm Date: Wed, 20 May 2020 15:51:00 +0800 Subject: [PATCH 5/5] fix(esxi): Modify the disk size correctly when creating vm --- pkg/multicloud/esxi/host.go | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/pkg/multicloud/esxi/host.go b/pkg/multicloud/esxi/host.go index 235b8dbd7b..a9453392bb 100644 --- a/pkg/multicloud/esxi/host.go +++ b/pkg/multicloud/esxi/host.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "regexp" + "sort" "strings" "time" @@ -765,9 +766,8 @@ func (self *SHost) DoCreateVM(ctx context.Context, ds *SDatastore, params SCreat ) for _, disk := range disks { imagePath := disk.ImagePath - var size int64 = 0 + var size = disk.Size if len(imagePath) == 0 { - size = disk.Size if size == 0 { size = 30 * 1024 } @@ -928,6 +928,7 @@ func (host *SHost) CloneVM(ctx context.Context, from *SVirtualMachine, ds *SData ctlKey = minDevKey(scsiDevs) } // change disk if set + newSizes := make([]int64, 0, len(from.vdisks)) if params.Disks != nil && len(params.Disks) > 0 { var ( i int @@ -941,15 +942,9 @@ func (host *SHost) CloneVM(ctx context.Context, from *SVirtualMachine, ds *SData } size := disk.Size if size == 0 { - continue + size = 30 * 1024 } - dev := from.vdisks[i].getVirtualDisk() - dev.CapacityInKB = size * 1024 - - deviceChange = append(deviceChange, &types.VirtualDeviceConfigSpec{ - Operation: types.VirtualDeviceConfigSpecOperationEdit, - Device: dev, - }) + newSizes = append(newSizes, size) } // create new disk @@ -1020,7 +1015,7 @@ func (host *SHost) CloneVM(ctx context.Context, from *SVirtualMachine, ds *SData MemoryMB: int64(params.Mem), } cloneSpec.Config = &spec - task, err := ovm.Clone(ctx, folders.VmFolder, params.Name, *cloneSpec) + task, err := ovm.Clone(ctx, folders.VmFolder, name, *cloneSpec) if err != nil { return nil, errors.Wrap(err, "object.VirtualMachine.Clone") } @@ -1035,7 +1030,16 @@ func (host *SHost) CloneVM(ctx context.Context, from *SVirtualMachine, ds *SData return nil, errors.Wrap(err, "fail to fetch virtual machine just created") } - return NewVirtualMachine(host.manager, &moVM, host.datacenter), nil + // resize the disk + vm := NewVirtualMachine(host.manager, &moVM, host.datacenter) + sort.Sort(byDiskType(vm.vdisks)) + for i, s := range newSizes { + err := vm.vdisks[i].Resize(ctx, s) + if err != nil { + log.Errorf("no.%d vdisk.Resize failed: %s", i, err.Error()) + } + } + return vm, nil } func (host *SHost) changeNic(device types.BaseVirtualDevice, update types.BaseVirtualDevice) {