From 649a734def30f53246e60c605a52e41b4a6ee81f Mon Sep 17 00:00:00 2001 From: ioito Date: Tue, 23 Jul 2019 10:23:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=B8=E8=BD=BD=E7=A3=81=E7=9B=98=E6=97=B6?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E4=BA=91=E4=B8=8A=E7=A3=81=E7=9B=98=E5=B7=B2?= =?UTF-8?q?=E7=BB=8F=E8=A2=AB=E5=88=A0=E9=99=A4=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/compute/guestdrivers/managedvirtual.go | 7 +++++++ pkg/util/aliyun/instance.go | 8 ++++++-- pkg/util/aliyun/shell/disk.go | 4 ++-- pkg/util/aws/instance.go | 13 ++++++++++++- pkg/util/aws/shell/disk.go | 4 ++-- pkg/util/huawei/instance.go | 7 ++++++- pkg/util/qcloud/instance.go | 10 ++++++++-- pkg/util/ucloud/instance.go | 10 +++++++--- pkg/util/zstack/instance.go | 7 ++++++- pkg/util/zstack/zstack.go | 3 +++ 10 files changed, 59 insertions(+), 14 deletions(-) diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index 80e06efa7f..d78c260ffa 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -161,6 +161,13 @@ func (self *SManagedVirtualizedGuestDriver) RequestDetachDisk(ctx context.Contex if len(disk.ExternalId) == 0 { return nil, nil } + + _, err = disk.GetIDisk() + if err == cloudprovider.ErrNotFound { + //忽略云上磁盘已经被删除错误 + return nil, nil + } + err = iVM.DetachDisk(ctx, disk.ExternalId) if err != nil { return nil, errors.Wrapf(err, "iVM.DetachDisk") diff --git a/pkg/util/aliyun/instance.go b/pkg/util/aliyun/instance.go index 0cf48abc2e..bc7197d442 100644 --- a/pkg/util/aliyun/instance.go +++ b/pkg/util/aliyun/instance.go @@ -18,10 +18,12 @@ import ( "context" "fmt" "sort" + "strings" "time" "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/errors" "yunion.io/x/pkg/util/osprofile" "yunion.io/x/pkg/util/seclib" "yunion.io/x/pkg/utils" @@ -869,8 +871,10 @@ func (self *SRegion) DetachDisk(instanceId string, diskId string) error { log.Infof("Detach instance %s disk %s", instanceId, diskId) _, err := self.ecsRequest("DetachDisk", params) if err != nil { - log.Errorf("DetachDisk %s to %s fail %s", diskId, instanceId, err) - return err + if strings.Contains(err.Error(), "The specified disk has not been attached on the specified instance") { + return nil + } + return errors.Wrap(err, "DetachDisk") } return nil diff --git a/pkg/util/aliyun/shell/disk.go b/pkg/util/aliyun/shell/disk.go index 2e1d4b7ccd..ef6d4723c6 100644 --- a/pkg/util/aliyun/shell/disk.go +++ b/pkg/util/aliyun/shell/disk.go @@ -37,10 +37,10 @@ func init() { }) type DiskDeleteOptions struct { - Instance string `help:"Instance ID"` + ID string `help:"Instance ID"` } shellutils.R(&DiskDeleteOptions{}, "disk-delete", "List disks", func(cli *aliyun.SRegion, args *DiskDeleteOptions) error { - e := cli.DeleteDisk(args.Instance) + e := cli.DeleteDisk(args.ID) if e != nil { return e } diff --git a/pkg/util/aws/instance.go b/pkg/util/aws/instance.go index 420129f192..4b1e9ff446 100644 --- a/pkg/util/aws/instance.go +++ b/pkg/util/aws/instance.go @@ -27,6 +27,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/errors" "yunion.io/x/pkg/util/osprofile" billing_api "yunion.io/x/onecloud/pkg/apis/billing" @@ -1029,7 +1030,17 @@ func (self *SRegion) DetachDisk(instanceId string, diskId string) error { params.SetVolumeId(diskId) log.Debugf("DetachDisk %s", params.String()) _, err := self.ec2Client.DetachVolume(params) - return err + if err != nil { + if strings.Contains(err.Error(), fmt.Sprintf("'%s'is in the 'available' state", diskId)) { + return nil + } + //InvalidVolume.NotFound: The volume 'vol-0a9eeda0a70a8d7fe' does not exist + if strings.Contains(err.Error(), "InvalidVolume.NotFound") { + return nil + } + return errors.Wrap(err, "ec2Client.DetachVolume") + } + return nil } func (self *SRegion) AttachDisk(instanceId string, diskId string, deviceName string) error { diff --git a/pkg/util/aws/shell/disk.go b/pkg/util/aws/shell/disk.go index 61a7bbdbbc..328cbf82f7 100644 --- a/pkg/util/aws/shell/disk.go +++ b/pkg/util/aws/shell/disk.go @@ -37,10 +37,10 @@ func init() { }) type DiskDeleteOptions struct { - Instance string `help:"Instance ID"` + ID string `help:"Disk ID"` } shellutils.R(&DiskDeleteOptions{}, "disk-delete", "List disks", func(cli *aws.SRegion, args *DiskDeleteOptions) error { - e := cli.DeleteDisk(args.Instance) + e := cli.DeleteDisk(args.ID) if e != nil { return e } diff --git a/pkg/util/huawei/instance.go b/pkg/util/huawei/instance.go index c0464859d6..8cd9148dd5 100644 --- a/pkg/util/huawei/instance.go +++ b/pkg/util/huawei/instance.go @@ -1148,7 +1148,12 @@ func (self *SRegion) AttachDisk(instanceId string, diskId string, device string) // 默认非强制卸载。delete_flag=0 func (self *SRegion) DetachDisk(instanceId string, diskId string) error { path := fmt.Sprintf("detachvolume/%s", diskId) - return DoDeleteWithSpec(self.ecsClient.Servers.DeleteInContextWithSpec, nil, instanceId, path, nil, nil) + err := DoDeleteWithSpec(self.ecsClient.Servers.DeleteInContextWithSpec, nil, instanceId, path, nil, nil) + //volume a2091934-2669-4fca-8eb4-a950c1836b3c is not in server 49b053d2-f798-432f-af55-76eb6ef2c769 attach volume list => 磁盘已经被卸载了 + if err != nil && strings.Contains(err.Error(), fmt.Sprintf("is not in server")) && strings.Contains(err.Error(), fmt.Sprintf("attach volume list")) { + return nil + } + return err } // // https://support.huaweicloud.com/api-bpconsole/zh-cn_topic_0082522029.html diff --git a/pkg/util/qcloud/instance.go b/pkg/util/qcloud/instance.go index b587a42d7a..2b7912c3f0 100644 --- a/pkg/util/qcloud/instance.go +++ b/pkg/util/qcloud/instance.go @@ -18,10 +18,12 @@ import ( "context" "fmt" "strconv" + "strings" "time" "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/errors" "yunion.io/x/pkg/utils" billing_api "yunion.io/x/onecloud/pkg/apis/billing" @@ -744,8 +746,12 @@ func (self *SRegion) DetachDisk(instanceId string, diskId string) error { log.Infof("Detach instance %s disk %s", instanceId, diskId) _, err := self.cbsRequest("DetachDisks", params) if err != nil { - log.Errorf("DetachDisks %s to %s fail %s", diskId, instanceId, err) - return err + // 可重复卸载,无报错,若磁盘被删除会有以下错误 + //[TencentCloudSDKError] Code=InvalidDisk.NotSupported, Message=disk(disk-4g5s7zhl) deleted (39a711ce2d17), RequestId=508d7fe3-e64e-4bb8-8ad7-39a711ce2d17 + if strings.Contains(err.Error(), fmt.Sprintf("disk(%s) deleted", diskId)) { + return nil + } + return errors.Wrap(err, "DetachDisks") } return nil diff --git a/pkg/util/ucloud/instance.go b/pkg/util/ucloud/instance.go index 910e8a7c1f..a60922add4 100644 --- a/pkg/util/ucloud/instance.go +++ b/pkg/util/ucloud/instance.go @@ -262,9 +262,13 @@ func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) { } } - disks, err := self.host.zone.region.GetDisks("", "", diskIds) - if err != nil { - return nil, err + disks := []SDisk{} + var err error + if len(diskIds) > 0 { + disks, err = self.host.zone.region.GetDisks("", "", diskIds) + if err != nil { + return nil, err + } } disks = append(disks, localDisks...) diff --git a/pkg/util/zstack/instance.go b/pkg/util/zstack/instance.go index 7696a46ff9..21eb9da543 100644 --- a/pkg/util/zstack/instance.go +++ b/pkg/util/zstack/instance.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "net/url" + "strings" "time" "yunion.io/x/jsonutils" @@ -449,7 +450,11 @@ func (instance *SInstance) DetachDisk(ctx context.Context, diskId string) error func (region *SRegion) DetachDisk(instanceId, diskId string) error { url := fmt.Sprintf("volumes/%s/vm-instances?vmUuid=%s", diskId, instanceId) - return region.client.delete(url, "", "") + err := region.client.delete(url, "", "") + if err != nil && strings.Contains(err.Error(), "is not attached to any vm") { + return nil + } + return err } func (instance *SInstance) DeleteVM(ctx context.Context) error { diff --git a/pkg/util/zstack/zstack.go b/pkg/util/zstack/zstack.go index 38aadae579..dea2f90dad 100644 --- a/pkg/util/zstack/zstack.go +++ b/pkg/util/zstack/zstack.go @@ -357,6 +357,9 @@ func (cli *SZStackClient) wait(client *http.Client, header http.Header, action s } _, result, err := httputils.ParseJSONResponse(resp, err, cli.debug) if err != nil { + if strings.Contains(err.Error(), "not found") { + return nil, cloudprovider.ErrNotFound + } return nil, err } if time.Now().Sub(startTime) > timeout {