/
detach_volume.go
64 lines (59 loc) · 1.92 KB
/
detach_volume.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
package virtualbox
import (
"github.com/sirupsen/logrus"
"github.com/emc-advanced-dev/pkg/errors"
"github.com/solo-io/unik/pkg/providers/virtualbox/virtualboxclient"
"github.com/solo-io/unik/pkg/types"
"path/filepath"
"strconv"
)
func (p *VirtualboxProvider) DetachVolume(id string) error {
volume, err := p.GetVolume(id)
if err != nil {
return errors.New("retrieving volume "+id, err)
}
if volume.Attachment == "" {
return errors.New("volume has no attachment", nil)
}
instanceId := volume.Attachment
instance, err := p.GetInstance(instanceId)
if err != nil {
return errors.New("retrieving instance "+instanceId, err)
}
image, err := p.GetImage(instance.ImageId)
if err != nil {
return errors.New("retrieving image "+instance.ImageId, err)
}
vm, err := virtualboxclient.GetVm(instance.Id)
if err != nil {
return errors.New("retreiving vm from virtualbox", err)
}
var controllerKey string
for _, device := range vm.Devices {
if filepath.Clean(device.DiskFile) == filepath.Clean(getVolumePath(volume.Name)) {
controllerKey = device.ControllerKey
}
}
if controllerKey == "" {
return errors.New("could not find device attached to "+instance.Name+" that matches volume "+getVolumePath(volume.Name), nil)
}
controllerPort, err := strconv.Atoi(controllerKey)
if err != nil {
return errors.New("could not convert "+controllerKey+" to int", err)
}
logrus.Debugf("using storage controller %s", image.RunSpec.StorageDriver)
if err := virtualboxclient.DetachDisk(instance.Id, controllerPort, image.RunSpec.StorageDriver); err != nil {
return errors.New("detaching disk from vm", err)
}
if err := p.state.ModifyVolumes(func(volumes map[string]*types.Volume) error {
volume, ok := volumes[volume.Id]
if !ok {
return errors.New("no record of "+volume.Id+" in the state", nil)
}
volume.Attachment = ""
return nil
}); err != nil {
return errors.New("modifying volume map in state", err)
}
return nil
}