From bcaf316c60e034077cff7b208be545a234de26ed Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Tue, 10 Sep 2019 02:43:53 +0800 Subject: [PATCH] fix: fail to delete orphane VM in esxi https://kb.vmware.com/s/article/1003742 --- pkg/multicloud/esxi/shell/virtualmachine.go | 16 ++++++++ pkg/multicloud/esxi/storage.go | 9 +++++ pkg/multicloud/esxi/virtualmachine.go | 44 ++++++++++++++++++++- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/pkg/multicloud/esxi/shell/virtualmachine.go b/pkg/multicloud/esxi/shell/virtualmachine.go index 028cfea1ac..d11c192cf1 100644 --- a/pkg/multicloud/esxi/shell/virtualmachine.go +++ b/pkg/multicloud/esxi/shell/virtualmachine.go @@ -135,4 +135,20 @@ func init() { return nil }) + shellutils.R(&VirtualMachineShowOptions{}, "vm-file-status", "Show vm files details", func(cli *esxi.SESXiClient, args *VirtualMachineShowOptions) error { + host, err := cli.FindHostByIp(args.HOSTIP) + if err != nil { + return err + } + vm, err := host.GetIVMById(args.VMID) + if err != nil { + return err + } + err = vm.(*esxi.SVirtualMachine).CheckFileInfo(context.Background()) + if err != nil { + return err + } + return nil + }) + } diff --git a/pkg/multicloud/esxi/storage.go b/pkg/multicloud/esxi/storage.go index cb2a7f2c4c..732902cf95 100644 --- a/pkg/multicloud/esxi/storage.go +++ b/pkg/multicloud/esxi/storage.go @@ -356,6 +356,15 @@ func (self *SDatastore) GetMountPoint() string { return self.GetUrl() } +func (self *SDatastore) HasFile(remotePath string) bool { + dsName := fmt.Sprintf("[%s]", self.SManagedObject.GetName()) + if strings.HasPrefix(remotePath, dsName) { + return true + } else { + return false + } +} + func (self *SDatastore) cleanPath(remotePath string) string { dsName := fmt.Sprintf("[%s]", self.SManagedObject.GetName()) dsUrl := self.GetUrl() diff --git a/pkg/multicloud/esxi/virtualmachine.go b/pkg/multicloud/esxi/virtualmachine.go index 9b35bc357b..998c9e5943 100644 --- a/pkg/multicloud/esxi/virtualmachine.go +++ b/pkg/multicloud/esxi/virtualmachine.go @@ -40,7 +40,7 @@ import ( "yunion.io/x/onecloud/pkg/util/billing" ) -var VIRTUAL_MACHINE_PROPS = []string{"name", "parent", "runtime", "summary", "config", "guest", "resourcePool"} +var VIRTUAL_MACHINE_PROPS = []string{"name", "parent", "runtime", "summary", "config", "guest", "resourcePool", "layoutEx"} type SVirtualMachine struct { SManagedObject @@ -106,6 +106,10 @@ func (self *SVirtualMachine) GetGlobalId() string { } func (self *SVirtualMachine) GetStatus() string { + err := self.CheckFileInfo(context.Background()) + if err != nil { + return api.VM_UNKNOWN + } vm := object.NewVirtualMachine(self.manager.client.Client, self.getVirtualMachine().Self) state, err := vm.PowerState(self.manager.context) if err != nil { @@ -464,7 +468,22 @@ func (self *SVirtualMachine) doDelete(ctx context.Context) error { return task.Wait(ctx) } +func (self *SVirtualMachine) doUnregister(ctx context.Context) error { + vm := self.getVmObj() + + err := vm.Unregister(ctx) + if err != nil { + log.Errorf("vm.Unregister(ctx) fail %s", err) + return err + } + return nil +} + func (self *SVirtualMachine) DeleteVM(ctx context.Context) error { + err := self.CheckFileInfo(ctx) + if err != nil { + return self.doUnregister(ctx) + } for i := 0; i < len(self.vdisks); i += 1 { err := self.doDetachAndDeleteDisk(ctx, &self.vdisks[i]) if err != nil { @@ -838,3 +857,26 @@ func (self *SVirtualMachine) getResourcePool() (*SResourcePool, error) { rp := NewResourcePool(self.manager, &morp, self.datacenter) return rp, nil } + +func (self *SVirtualMachine) CheckFileInfo(ctx context.Context) error { + vm := self.getVirtualMachine() + if vm.LayoutEx != nil && len(vm.LayoutEx.File) > 0 { + file := vm.LayoutEx.File[0] + host := self.GetIHost() + storages, err := host.GetIStorages() + if err != nil { + return errors.Wrap(err, "host.GetIStorages") + } + for i := range storages { + ds := storages[i].(*SDatastore) + if ds.HasFile(file.Name) { + _, err := ds.CheckFile(ctx, file.Name) + if err != nil { + return errors.Wrap(err, "ds.CheckFile") + } + break + } + } + } + return nil +}