github.com/openshift/installer@v1.4.17/pkg/destroy/ibmcloud/disk.go (about)

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