github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/pkg/providers/vsphere/detach_volume.go (about)

     1  package vsphere
     2  
     3  import (
     4  	"github.com/emc-advanced-dev/pkg/errors"
     5  	"github.com/solo-io/unik/pkg/providers/virtualbox/virtualboxclient"
     6  	"github.com/solo-io/unik/pkg/types"
     7  	"path/filepath"
     8  	"strconv"
     9  )
    10  
    11  func (p *VsphereProvider) DetachVolume(id string) error {
    12  	volume, err := p.GetVolume(id)
    13  	if err != nil {
    14  		return errors.New("retrieving volume "+id, err)
    15  	}
    16  	if volume.Attachment == "" {
    17  		return errors.New("volume has no attachment", nil)
    18  	}
    19  	instanceId := volume.Attachment
    20  	instance, err := p.GetInstance(instanceId)
    21  	if err != nil {
    22  		return errors.New("retrieving instance "+instanceId, err)
    23  	}
    24  	image, err := p.GetImage(instance.ImageId)
    25  	if err != nil {
    26  		return errors.New("retrieving image "+instance.ImageId, err)
    27  	}
    28  	vm, err := virtualboxclient.GetVm(instance.Id)
    29  	if err != nil {
    30  		return errors.New("retreiving vm from virtualbox", err)
    31  	}
    32  	var controllerKey string
    33  	for _, device := range vm.Devices {
    34  		if filepath.Clean(device.DiskFile) == filepath.Clean(getVolumeDatastorePath(volume.Name)) {
    35  			controllerKey = device.ControllerKey
    36  		}
    37  	}
    38  	if controllerKey == "" {
    39  		return errors.New("could not find device attached to "+instance.Name+" that matches volume "+getVolumeDatastorePath(volume.Name), nil)
    40  	}
    41  
    42  	controllerPort, err := strconv.Atoi(controllerKey)
    43  	if err != nil {
    44  		return errors.New("could not convert "+controllerKey+" to int", err)
    45  	}
    46  	if err := p.getClient().DetachDisk(instance.Id, controllerPort, image.RunSpec.StorageDriver); err != nil {
    47  		return errors.New("detaching disk from vm", err)
    48  	}
    49  	if err := p.state.ModifyVolumes(func(volumes map[string]*types.Volume) error {
    50  		volume, ok := volumes[volume.Id]
    51  		if !ok {
    52  			return errors.New("no record of "+volume.Id+" in the state", nil)
    53  		}
    54  		volume.Attachment = ""
    55  		return nil
    56  	}); err != nil {
    57  		return errors.New("modifying volume map in state", err)
    58  	}
    59  	return nil
    60  }