forked from thecodeteam/libstorage
-
Notifications
You must be signed in to change notification settings - Fork 0
/
scaleio_executor.go
149 lines (124 loc) · 3.33 KB
/
scaleio_executor.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package executor
import (
"github.com/akutz/gofig"
"fmt"
"io/ioutil"
"os/exec"
"path/filepath"
"regexp"
"strings"
"github.com/akutz/goof"
"github.com/emccode/libstorage/api/registry"
"github.com/emccode/libstorage/api/types"
)
const (
// Name is the name of the driver.
Name = "scaleio"
)
// driver is the storage executor for the VFS storage driver.
type driver struct {
Config gofig.Config
instanceID *types.InstanceID
}
func init() {
registry.RegisterStorageExecutor(Name, newdriver)
}
func newdriver() types.StorageExecutor {
return &driver{}
}
func (d *driver) Init(context types.Context, config gofig.Config) error {
d.Config = config
id, err := GetInstanceID()
if err != nil {
return err
}
d.instanceID = id
return nil
}
func (d *driver) Name() string {
return Name
}
// NextDevice returns the next available device.
func (d *driver) NextDevice(
ctx types.Context,
opts types.Store) (string, error) {
return "", nil
}
// LocalDevices returns a map of the system's local devices.
func (d *driver) LocalDevices(
ctx types.Context,
opts *types.LocalDevicesOpts) (*types.LocalDevices, error) {
lvm, err := getLocalVolumeMap()
if err != nil {
return nil, err
}
return &types.LocalDevices{
Driver: Name,
DeviceMap: lvm,
}, nil
}
type sdcMappedVolume struct {
mdmID string
volumeID string
mdmVolumeID string
sdcDevice string
}
func getLocalVolumeMap() (map[string]string, error) {
mappedVolumesMap := make(map[string]*sdcMappedVolume)
volumeMap := make(map[string]string)
out, err := exec.Command("/opt/emc/scaleio/sdc/bin/drv_cfg", "--query_vols").Output()
if err != nil {
return nil, goof.WithError("error querying volumes", err)
}
result := string(out)
lines := strings.Split(result, "\n")
for _, line := range lines {
split := strings.Split(line, " ")
if split[0] == "VOL-ID" {
mappedVolume := &sdcMappedVolume{mdmID: split[3], volumeID: split[1]}
mappedVolume.mdmVolumeID = fmt.Sprintf("%s-%s", mappedVolume.mdmID, mappedVolume.volumeID)
mappedVolumesMap[mappedVolume.mdmVolumeID] = mappedVolume
}
}
diskIDPath := "/dev/disk/by-id"
files, _ := ioutil.ReadDir(diskIDPath)
r, _ := regexp.Compile(`^emc-vol-\w*-\w*$`)
for _, f := range files {
matched := r.MatchString(f.Name())
if matched {
mdmVolumeID := strings.Replace(f.Name(), "emc-vol-", "", 1)
devPath, _ := filepath.EvalSymlinks(fmt.Sprintf("%s/%s", diskIDPath, f.Name()))
if _, ok := mappedVolumesMap[mdmVolumeID]; ok {
volumeID := mappedVolumesMap[mdmVolumeID].volumeID
volumeMap[volumeID] = devPath
}
}
}
return volumeMap, nil
}
// InstanceID returns the local system's InstanceID.
func (d *driver) InstanceID(
ctx types.Context,
opts types.Store) (*types.InstanceID, error) {
return d.instanceID, nil
}
// GetInstanceID returns the instance ID object
func GetInstanceID() (*types.InstanceID, error) {
sg, err := getSdcLocalGUID()
if err != nil {
return nil, err
}
iid := &types.InstanceID{Driver: Name}
if err := iid.MarshalMetadata(sg); err != nil {
return nil, err
}
return iid, nil
}
func getSdcLocalGUID() (sdcGUID string, err error) {
out, err := exec.Command("/opt/emc/scaleio/sdc/bin/drv_cfg", "--query_guid").Output()
if err != nil {
return "", goof.WithError("problem getting sdc guid", err)
}
sdcGUID = strings.Replace(string(out), "\n", "", -1)
return sdcGUID, nil
}