-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
disk.go
132 lines (113 loc) · 3.75 KB
/
disk.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package ibmcloud
import (
"net/http"
"strings"
"github.com/pkg/errors"
)
func (o *ClusterUninstaller) listDisks() ([]cloudResource, error) {
o.Logger.Infof("Listing disks")
result := []cloudResource{}
clusterOwnedTag := o.clusterLabelFilter()
options := o.vpcSvc.NewListVolumesOptions()
for {
ctx, cancel := o.contextWithTimeout()
defer cancel()
options.SetLimit(100)
resources, _, err := o.vpcSvc.ListVolumesWithContext(ctx, options)
if err != nil {
return nil, errors.Wrap(err, "Listing disks failed")
}
for _, volume := range resources.Volumes {
userTags := strings.Join(volume.UserTags, ",")
if strings.Contains(userTags, clusterOwnedTag) {
o.Logger.Debugf("Found disk: %s", *volume.ID)
result = append(result, cloudResource{
key: *volume.ID,
name: *volume.Name,
status: *volume.Status,
typeName: "disk",
id: *volume.ID,
})
}
}
//This was the last page, please exit the loop.
if resources.Next == nil {
o.Logger.Debugf("All disks fetched")
break
}
//Set the start for the next page.
start, _ := resources.GetNextStart()
o.Logger.Debugf("Listing next page %s", *start)
options.SetStart(*start)
}
return result, nil
}
func (o *ClusterUninstaller) deleteDisk(item cloudResource) error {
o.Logger.Infof("Deleting disk %s", item.id)
ctx, cancel := o.contextWithTimeout()
defer cancel()
options := o.vpcSvc.NewDeleteVolumeOptions(item.id)
details, err := o.vpcSvc.DeleteVolumeWithContext(ctx, options)
if err != nil {
if details == nil || details.StatusCode != http.StatusNotFound {
return fmt.Errorf("Failed to delete disk name=%s, id=%s.If this error continues to persist for more than 20 minutes then please try to manually cleanup the volume using - ibmcloud is vold %s: %w", item.name, item.id, item.id, err)
}
if details.StatusCode == http.StatusNotFound {
// The resource is gone
o.deletePendingItems(item.typeName, []cloudResource{item})
o.Logger.Infof("Deleted disk %s", item.id)
}
}
return nil
}
func (o *ClusterUninstaller) waitForDiskDeletion(item cloudResource) error {
o.Logger.Infof("Waiting for disk %s to be deleted", item.id)
var skip = false
err := o.Retry(func() (error, bool) {
ctx, cancel := o.contextWithTimeout()
defer cancel()
volumeOptions := o.vpcSvc.NewGetVolumeOptions(item.id)
_, response, err := o.vpcSvc.GetVolumeWithContext(ctx, volumeOptions)
// Keep retry, until GetVolume returns volume not found
if err != nil {
if response != nil && response.StatusCode == http.StatusNotFound {
skip = true
return nil, skip
}
}
return err, false // continue retry as we are not seeing error which means volume is available
})
if err == nil && skip {
// The resource is gone
o.deletePendingItems(item.typeName, []cloudResource{item})
o.Logger.Infof("Deleted disk %s", item.id)
} else {
return errors.Wrapf(err, "Failed to delete disk name=%s, id=%s.If this error continues to persist for more than 20 minutes then please try to manually cleanup the volume using - ibmcloud is vold %s", item.name, item.id, item.id)
}
return err
}
// destroyDisks removes all disk resources that have a name prefixed
// with the cluster's infra ID.
func (o *ClusterUninstaller) destroyDisks() error {
found, err := o.listDisks()
if err != nil {
return err
}
items := o.insertPendingItems("disk", found)
for _, item := range items {
err := o.deleteDisk(item)
if err != nil {
o.errorTracker.suppressWarning(item.key, err, o.Logger)
}
}
for _, item := range items {
err := o.waitForDiskDeletion(item)
if err != nil {
o.errorTracker.suppressWarning(item.key, err, o.Logger)
}
}
if items = o.getPendingItems("disk"); len(items) > 0 {
return errors.Errorf("%d items pending", len(items))
}
return nil
}