From aaf306f1065502a710e36ba41f36963f99be6832 Mon Sep 17 00:00:00 2001 From: akutz Date: Wed, 26 Apr 2017 14:19:21 -0500 Subject: [PATCH] VMware vSphere Driver This patch introduces the new VMware vSphere VMDK Driver - "vmdk". The driver uses VMCI Sockets (https://www.vmware.com/support/developer/vmci-sdk/) to communicate directly with a vSphere host, removing the need for the sizeable VMware SDK for Go library dependency. --- .gitignore | 1 + .../storage/vmdk/executor/vmdk_executor.go | 67 +++++ drivers/storage/vmdk/storage/vmdk_storage.go | 278 ++++++++++++++++++ drivers/storage/vmdk/tests/coverage.mk | 2 + drivers/storage/vmdk/tests/vmdk_test.go | 144 +++++++++ drivers/storage/vmdk/vmdk.go | 9 + glide.lock | 83 ++---- glide.yaml | 3 + imports/executors/imports_executor_linux.go | 9 + imports/executors/imports_executor_vmdk.go | 9 + imports/remote/imports_remote.go | 2 +- imports/remote/imports_remote_linux.go | 9 + imports/remote/imports_remote_vmdk.go | 9 + 13 files changed, 571 insertions(+), 54 deletions(-) create mode 100644 drivers/storage/vmdk/executor/vmdk_executor.go create mode 100644 drivers/storage/vmdk/storage/vmdk_storage.go create mode 100644 drivers/storage/vmdk/tests/coverage.mk create mode 100644 drivers/storage/vmdk/tests/vmdk_test.go create mode 100644 drivers/storage/vmdk/vmdk.go create mode 100644 imports/executors/imports_executor_linux.go create mode 100644 imports/executors/imports_executor_vmdk.go create mode 100644 imports/remote/imports_remote_linux.go create mode 100644 imports/remote/imports_remote_vmdk.go diff --git a/.gitignore b/.gitignore index db922810..dc077217 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ *.d *.out got +gob libstorage.paw .site/ site/ diff --git a/drivers/storage/vmdk/executor/vmdk_executor.go b/drivers/storage/vmdk/executor/vmdk_executor.go new file mode 100644 index 00000000..efe2153f --- /dev/null +++ b/drivers/storage/vmdk/executor/vmdk_executor.go @@ -0,0 +1,67 @@ +// +build linux darwin +// +build !libstorage_storage_executor libstorage_storage_executor_vmdk + +package executor + +import ( + gofig "github.com/akutz/gofig/types" + + "github.com/codedellemc/libstorage/api/registry" + "github.com/codedellemc/libstorage/api/types" + + "github.com/codedellemc/libstorage/drivers/storage/vmdk" +) + +type driver struct { + config gofig.Config +} + +func init() { + registry.RegisterStorageExecutor(vmdk.Name, newDriver) +} + +func newDriver() types.StorageExecutor { + return &driver{} +} + +func (d *driver) Name() string { + return vmdk.Name +} + +func (d *driver) Supported( + ctx types.Context, + opts types.Store) (bool, error) { + + return true, nil +} + +func (d *driver) Init(ctx types.Context, config gofig.Config) error { + d.config = config + return nil +} + +// InstanceID returns the local system's InstanceID. +func (d *driver) InstanceID( + ctx types.Context, + opts types.Store) (*types.InstanceID, error) { + + iid := &types.InstanceID{Driver: vmdk.Name} + iid.ID = vmdk.Name + return iid, nil +} + +// 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) { + + return &types.LocalDevices{DeviceMap: map[string]string{}}, nil +} diff --git a/drivers/storage/vmdk/storage/vmdk_storage.go b/drivers/storage/vmdk/storage/vmdk_storage.go new file mode 100644 index 00000000..a3ad65a5 --- /dev/null +++ b/drivers/storage/vmdk/storage/vmdk_storage.go @@ -0,0 +1,278 @@ +// +build !libstorage_storage_driver libstorage_storage_driver_vmdk + +package storage + +import ( + "fmt" + "regexp" + "strconv" + "sync" + + gofig "github.com/akutz/gofig/types" + + "github.com/codedellemc/libstorage/api/registry" + "github.com/codedellemc/libstorage/api/types" + + "github.com/codedellemc/libstorage/drivers/storage/vmdk" + "github.com/vmware/docker-volume-vsphere/vmdk_plugin/drivers/vmdk/vmdkops" +) + +const ( + minSizeGiB = 1 +) + +type driver struct { + ctx types.Context + config gofig.Config + ops vmdkops.VmdkOps +} + +func init() { + registry.RegisterStorageDriver(vmdk.Name, newDriver) +} + +func newDriver() types.StorageDriver { + return &driver{} +} + +func (d *driver) Name() string { + return vmdk.Name +} + +func (d *driver) Type(ctx types.Context) (types.StorageType, error) { + return types.Block, nil +} + +func (d *driver) Init(ctx types.Context, config gofig.Config) error { + d.ctx = ctx + d.config = config + d.ops = vmdkops.VmdkOps{Cmd: vmdkops.EsxVmdkCmd{Mtx: &sync.Mutex{}}} + return nil +} + +func (d *driver) NextDeviceInfo( + ctx types.Context) (*types.NextDeviceInfo, error) { + return &types.NextDeviceInfo{ + Ignore: true, + }, nil +} + +func (d *driver) InstanceInspect( + ctx types.Context, + opts types.Store) (*types.Instance, error) { + + return nil, nil +} + +func (d *driver) Volumes( + ctx types.Context, + opts *types.VolumesOpts) ([]*types.Volume, error) { + + data, err := d.ops.List() + if err != nil { + return nil, err + } + + vols := []*types.Volume{} + for _, v := range data { + vols = append(vols, &types.Volume{ + Name: v.Name, + Fields: v.Attributes, + }) + } + + return vols, nil +} + +func (d *driver) VolumeInspect( + ctx types.Context, + volumeID string, + opts *types.VolumeInspectOpts) (*types.Volume, error) { + + data, err := d.ops.Get(volumeID) + if err != nil { + return nil, err + } + + vol := &types.Volume{ + ID: volumeID, + Name: volumeID, + Fields: map[string]string{}, + } + + for k, v := range data { + switch k { + case "datastore": + if v, ok := v.(string); ok { + vol.Type = v + } + case "capacity": + if v, ok := v.(map[string]interface{}); ok { + if v, ok := v["size"]; ok { + if v == "0" { + vol.Size = 0 + } else if sz, ok := isGB(v); ok { + vol.Size = sz * 1024 * 1024 * 1024 + } else if sz, ok := isMB(v); ok { + vol.Size = sz * 1024 * 1024 + } else if sz, ok := isKB(v); ok { + vol.Size = sz * 1024 + } + } + } + default: + vol.Fields[k] = v + } + } + + return vol, nil +} + +func isSize(rx *regexp.Regexp, s string) (int64, bool) { + m := rx.FindStringSubmatch(s) + if len(m) == 0 { + return 0, false + } + i, err := strconv.Atoi(m[1]) + if err != nil { + return 0, false + } + return int64(i), true +} + +var rxIsKB = regexp.MustCompile(`(?i)^([\d,\.]+)\s*KB\s*$`) + +func isKB(s string) (int64, bool) { + return isSize(rxIsKB, s) +} + +var rxIsMB = regexp.MustCompile(`(?i)^([\d,\.]+)\s*MB\s*$`) + +func isMB(s string) (int64, bool) { + return isSize(rxIsMB, s) +} + +var rxIsGB = regexp.MustCompile(`(?i)^([\d,\.]+)\s*GB\s*$`) + +func isGB(s string) (int64, bool) { + return isSize(rxIsGB, s) +} + +func (d *driver) VolumeCreate( + ctx types.Context, + name string, + opts *types.VolumeCreateOpts) (*types.Volume, error) { + + if opts.Type != nil && *opts.Type != "" { + name = fmt.Sprintf("%s@%s", name, *opts.Type) + } + + createOpts := map[string]string{} + if opts.Size != nil { + createOpts["size"] = fmt.Sprintf("%dgb", *opts.Size) + } + + if err := d.ops.Create(name, createOpts); err != nil { + return nil, err + } + + return d.VolumeInspect(ctx, name, nil) +} + +func (d *driver) VolumeCreateFromSnapshot( + ctx types.Context, + snapshotID, volumeName string, + opts *types.VolumeCreateOpts) (*types.Volume, error) { + + return nil, types.ErrNotImplemented +} + +func (d *driver) VolumeCopy( + ctx types.Context, + volumeID, volumeName string, + opts types.Store) (*types.Volume, error) { + + return nil, types.ErrNotImplemented +} + +func (d *driver) VolumeSnapshot( + ctx types.Context, + volumeID, snapshotName string, + opts types.Store) (*types.Snapshot, error) { + + return nil, types.ErrNotImplemented +} + +func (d *driver) VolumeRemove( + ctx types.Context, + volumeID string, + opts *types.VolumeRemoveOpts) error { + + return d.ops.Remove(volumeID, map[string]string{}) +} + +func (d *driver) VolumeAttach( + ctx types.Context, + volumeID string, + opts *types.VolumeAttachOpts) (*types.Volume, string, error) { + + dev, err := d.ops.Attach(volumeID, nil) + if err != nil { + return nil, "", err + } + + var vol *types.Volume + if vol, err = d.VolumeInspect(ctx, volumeID, nil); err != nil { + return nil, "", err + } + + return vol, string(dev), nil +} + +func (d *driver) VolumeDetach( + ctx types.Context, + volumeID string, + opts *types.VolumeDetachOpts) (*types.Volume, error) { + + if err := d.ops.Detach(volumeID, nil); err != nil { + return nil, err + } + + vol, err := d.VolumeInspect(ctx, volumeID, nil) + if err != nil { + return nil, err + } + + return vol, nil +} + +func (d *driver) Snapshots( + ctx types.Context, + opts types.Store) ([]*types.Snapshot, error) { + + return nil, types.ErrNotImplemented +} + +func (d *driver) SnapshotInspect( + ctx types.Context, + snapshotID string, + opts types.Store) (*types.Snapshot, error) { + + return nil, types.ErrNotImplemented +} + +func (d *driver) SnapshotCopy( + ctx types.Context, + snapshotID, snapshotName, destinationID string, + opts types.Store) (*types.Snapshot, error) { + + return nil, types.ErrNotImplemented +} + +func (d *driver) SnapshotRemove( + ctx types.Context, + snapshotID string, + opts types.Store) error { + + return types.ErrNotImplemented +} diff --git a/drivers/storage/vmdk/tests/coverage.mk b/drivers/storage/vmdk/tests/coverage.mk new file mode 100644 index 00000000..aa277c79 --- /dev/null +++ b/drivers/storage/vmdk/tests/coverage.mk @@ -0,0 +1,2 @@ +VMDK_COVERPKG := $(ROOT_IMPORT_PATH)/drivers/storage/vmdk +TEST_COVERPKG_./drivers/storage/vmdk/tests := $(VMDK_COVERPKG),$(VMDK_COVERPKG)/executor diff --git a/drivers/storage/vmdk/tests/vmdk_test.go b/drivers/storage/vmdk/tests/vmdk_test.go new file mode 100644 index 00000000..7bd6e554 --- /dev/null +++ b/drivers/storage/vmdk/tests/vmdk_test.go @@ -0,0 +1,144 @@ +// +build linux darwin +// +build !libstorage_storage_driver libstorage_storage_driver_vmdk + +package tests + +import ( + "io/ioutil" + "os" + "strconv" + "testing" + + log "github.com/Sirupsen/logrus" + + "github.com/vmware/docker-volume-vsphere/vmdk_plugin/drivers/vmdk/vmdkops" + + "github.com/codedellemc/libstorage/api/context" + "github.com/codedellemc/libstorage/api/registry" + "github.com/codedellemc/libstorage/api/server" + "github.com/codedellemc/libstorage/api/types" + "github.com/codedellemc/libstorage/api/utils" + + // load the driver + _ "github.com/codedellemc/libstorage/drivers/storage/vmdk/storage" +) + +var tCtx types.Context +var vName string +var d types.StorageDriver + +func skipTests() bool { + travis, _ := strconv.ParseBool(os.Getenv("TRAVIS")) + noTest, _ := strconv.ParseBool(os.Getenv("TEST_SKIP_VMDK")) + return travis || noTest +} + +func TestMain(m *testing.M) { + if p, err := strconv.Atoi(os.Getenv("VMDK_PORT")); err == nil { + vmdkops.EsxPort = p + } else { + vmdkops.EsxPort = 1019 + } + + if vName = os.Getenv("VMDK_NAME"); vName == "" { + vName = "vmdkops" + } + + log.SetLevel(log.DebugLevel) + + tmpDir, err := ioutil.TempDir("", "") + if err != nil { + panic(err) + } + defer os.RemoveAll(tmpDir) + + tCtx = context.Background() + pathConfig := utils.NewPathConfig(tCtx, tmpDir, "") + tCtx = context.WithValue(tCtx, context.PathConfigKey, pathConfig) + registry.ProcessRegisteredConfigs(tCtx) + + server.CloseOnAbort() + + d, _ = registry.NewStorageDriver("vmdk") + d.Init(tCtx, nil) + + os.Exit(m.Run()) +} + +func TestVolumeInspect(t *testing.T) { + if skipTests() { + t.SkipNow() + } + + v, err := d.VolumeInspect( + tCtx, vName, &types.VolumeInspectOpts{Opts: utils.NewStore()}) + if err != nil { + t.Fatal(err) + } + t.Logf("%+v", v) +} + +func TestVolumeCreate(t *testing.T) { + if skipTests() { + t.SkipNow() + } + + v, err := d.VolumeCreate( + tCtx, vName, &types.VolumeCreateOpts{Opts: utils.NewStore()}) + if err != nil { + t.Fatal(err) + } + t.Logf("%+v", v) +} + +func TestVolumeAttach(t *testing.T) { + if skipTests() { + t.SkipNow() + } + + v, tok, err := d.VolumeAttach( + tCtx, vName, &types.VolumeAttachOpts{Opts: utils.NewStore()}) + if err != nil { + t.Fatal(err) + } + t.Logf("tok=%v, %+v", tok, v) +} + +func TestVolumeDetach(t *testing.T) { + if skipTests() { + t.SkipNow() + } + + v, err := d.VolumeDetach( + tCtx, vName, &types.VolumeDetachOpts{Opts: utils.NewStore()}) + if err != nil { + t.Fatal(err) + } + t.Logf("%+v", v) +} + +func TestVolumeRemove(t *testing.T) { + if skipTests() { + t.SkipNow() + } + + err := d.VolumeRemove( + tCtx, vName, &types.VolumeRemoveOpts{Opts: utils.NewStore()}) + if err != nil { + t.Fatal(err) + } +} + +func TestVolumeList(t *testing.T) { + if skipTests() { + t.SkipNow() + } + + vols, err := d.Volumes(tCtx, &types.VolumesOpts{Opts: utils.NewStore()}) + if err != nil { + t.Fatal(err) + } + for _, v := range vols { + t.Logf("%+v", v) + } +} diff --git a/drivers/storage/vmdk/vmdk.go b/drivers/storage/vmdk/vmdk.go new file mode 100644 index 00000000..28889d89 --- /dev/null +++ b/drivers/storage/vmdk/vmdk.go @@ -0,0 +1,9 @@ +// +build linux darwin +// +build !libstorage_storage_driver libstorage_storage_driver_vmdk + +package vmdk + +const ( + // Name is the name of the driver. + Name = "vmdk" +) diff --git a/glide.lock b/glide.lock index 1a3a3c72..29999bb3 100644 --- a/glide.lock +++ b/glide.lock @@ -1,11 +1,10 @@ -hash: 6b3161a1086d56cfb657e5b47370ed70cce0aa592d1b095cb885c3e4763f1eb5 -updated: 2017-04-20T15:53:52.320351451-05:00 +hash: 700387c978f5c1c6a395cd63ac084b4b5e2a59bb4592ab46b1481b9a28dadbde +updated: 2017-04-26T12:00:45.474006402-05:00 imports: - name: cloud.google.com/go - version: e4de3dc4493f142c5833f3185e1182025a61f805 + version: 3536fc15a6517d90ba50b7ca76ddcb404e8ff1f3 subpackages: - compute/metadata - - internal - name: github.com/akutz/gofig version: 862741cad5edced279c57d1981e8e3e9fa54e8d5 subpackages: @@ -23,7 +22,7 @@ imports: - vboxwebsrv - virtualboxclient - name: github.com/asaskevich/govalidator - version: 7b3beb6df3c42abd3509abfc3bcacc0fbfb7c877 + version: 4918b99a7cb949bb295f3c7bbaf24b577d806e35 - name: github.com/aws/aws-sdk-go version: 3f8f870ec9939e32b3372abf74d24e468bcd285d repo: https://github.com/aws/aws-sdk-go @@ -104,25 +103,23 @@ imports: - name: github.com/digitalocean/godo version: 84099941ba2381607e1b05ffd4822781af86675e - name: github.com/fsnotify/fsnotify - version: fd9ec7deca8bf46ecd2a795baaacf2b3a9be1197 + version: 4da3e2cfbabc9f751898f250b49f2439785783a1 - name: github.com/go-ini/ini - version: 6e4869b434bd001f6983749881c7ead3545887d8 + version: e7fea39b01aea8d5671f6858f0532f56e8bff3a5 - name: github.com/golang/protobuf - version: 8ee79997227bf9b34611aee7946ae64735e6fd93 + version: 2bba0603135d7d7f5cb73b2125beeda19c09f4ef subpackages: - proto - name: github.com/google/go-querystring version: 53e6ce116135b80d037921a7fdd5138cf32d7a8a subpackages: - query -- name: github.com/googleapis/gax-go - version: da06d194a00e19ce00d9011a13931c3f6f6887c7 - name: github.com/gorilla/context version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42 - name: github.com/gorilla/mux - version: 757bef944d0f21880861c2dd9c871ca543023cba + version: 599cba5e7b6137d46ddf58fb1765f5d928e69604 - name: github.com/hashicorp/hcl - version: f74cf8281543a0797d7b4ab7d88e76e7ba125308 + version: 7fa7fff964d035e8a162cce3a164b3ad02ad651b subpackages: - hcl/ast - hcl/parser @@ -141,12 +138,10 @@ imports: version: 9d302b58e975387d0b4d9be876622c86cefe64be repo: https://github.com/kardianos/osext.git vcs: git -- name: github.com/kr/fs - version: 2788f0dbd16903de03cb8186e5c7d97b69ad387b - name: github.com/magiconair/properties - version: 0723e352fa358f9322c938cc2dadda874e9151a9 + version: 51463bfca2576e06c62a8504b5c0f06d61312647 - name: github.com/mitchellh/mapstructure - version: f3009df150dadf309fdee4a54ed65c124afad715 + version: cc8532a8e9a55ea36402aa21efdf403a60d34096 - name: github.com/onsi/ginkgo version: 77a8c1e5c40d6bb6c5eb4dd4bdce9763564f6298 subpackages: @@ -182,13 +177,9 @@ imports: - matchers/support/goraph/util - types - name: github.com/pelletier/go-buffruneio - version: df1e16fde7fc330a0ca68167c23bf7ed6ac31d6d + version: c37440a7cf42ac63b919c752ca73a85067e05992 - name: github.com/pelletier/go-toml - version: 45932ad32dfdd20826f5671da37a5f3ce9f26a8d -- name: github.com/pkg/errors - version: 248dadf4e9068a0b3e79f02ed0a610d935de5302 -- name: github.com/pkg/sftp - version: 4d0e916071f68db74f8a73926335f809396d6b42 + version: fe206efb84b2bc8e8cfafe6b4c1826622be969e3 - name: github.com/pmezard/go-difflib version: d8ed2627bdf02c080bf22230dbb337003b7aba2d subpackages: @@ -223,46 +214,45 @@ imports: version: 5f376aa629ac60c3215cc368e674bd996093a01a repo: https://github.com/akutz/logrus - name: github.com/spf13/afero - version: 52e4a6cfac46163658bd4f123c49b6ee7dc75f78 + version: 9be650865eab0c12963d8753212f4f9c66cdcf12 subpackages: - mem - - sftp - name: github.com/spf13/cast - version: 2580bc98dc0e62908119e4737030cc2fdfc45e4c + version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4 - name: github.com/spf13/jwalterweatherman - version: 33c24e77fb80341fe7130ee7c594256ff08ccc46 + version: fa7ca7e836cf3a8bb4ebf799f472c12d7e903d66 - name: github.com/spf13/pflag version: d16db1e50e33dff1b6cdf37596cef36742128670 - name: github.com/spf13/viper - version: 651d9d916abc3c3d6a91a12549495caba5edffd2 + version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2 - name: github.com/stretchr/testify version: 4d4bfba8f1d1027c4fdbe371823030df51419987 subpackages: - assert - name: github.com/tent/http-link-go version: ac974c61c2f990f4115b119354b5e0b47550e888 +- name: github.com/vmware/docker-volume-vsphere + version: deeec239792ca20e8874f7dc0ed6a9f2db81a7c8 + subpackages: + - vmdk_plugin/drivers/vmdk/vmdkops + - vmdk_plugin/utils/fs - name: golang.org/x/crypto - version: 453249f01cfeb54c3d549ddb75ff152ca243f9d8 + version: c7af5bf2638a1164f2eb5467c39c6cffbd13a02e repo: https://github.com/golang/crypto.git vcs: git subpackages: - - curve25519 - - ed25519 - - ed25519/internal/edwards25519 - pkcs12 - pkcs12/internal/rc2 - - ssh +- name: golang.org/x/exp + version: d7547cb8f08b1a7db6aecdc9f793fa87e22b03dc + repo: https://go.googlesource.com/exp + subpackages: + - inotify - name: golang.org/x/net version: b336a971b799939dd16ae9b1df8334cb8b977c4d subpackages: - context - context/ctxhttp - - http2 - - http2/hpack - - idna - - internal/timeseries - - lex/httplex - - trace - name: golang.org/x/oauth2 version: 314dd2c0bf3ebd592ec0d20847d27e79d0dbe8dd subpackages: @@ -275,7 +265,7 @@ imports: subpackages: - unix - name: golang.org/x/text - version: 85c29909967d7f171f821e7a42e7b7af76fb9598 + version: a9a820217f98f7c8a207ec1e45a874e1fe12c478 repo: https://github.com/golang/text.git vcs: git subpackages: @@ -291,7 +281,7 @@ imports: - googleapi - googleapi/internal/uritemplates - name: google.golang.org/appengine - version: 2e4a801b39fc199db615bfca7d0b9f8cd9580599 + version: 170382fa85b10b94728989dfcf6cc818b335c952 subpackages: - internal - internal/app_identity @@ -302,19 +292,6 @@ imports: - internal/remote_api - internal/urlfetch - urlfetch -- name: google.golang.org/grpc - version: cbcceb2942a489498cf22b2f918536e819d33f0a - subpackages: - - codes - - credentials - - grpclog - - internal - - metadata - - naming - - peer - - stats - - tap - - transport - name: gopkg.in/yaml.v2 version: bc35f417f8a7664a73d46c9def2933417c03019f repo: https://github.com/akutz/yaml.git diff --git a/glide.yaml b/glide.yaml index e97f8c4e..b6cd1869 100644 --- a/glide.yaml +++ b/glide.yaml @@ -92,6 +92,9 @@ import: ref: 96a0db67ea8209453cfa694bdf03de202d6dd8f8 repo: https://github.com/codenrhoden/go-vhd +### VMware + - package: github.com/vmware/docker-volume-vsphere + ################################################################################ ## Build System Tools ## diff --git a/imports/executors/imports_executor_linux.go b/imports/executors/imports_executor_linux.go new file mode 100644 index 00000000..38dcdf10 --- /dev/null +++ b/imports/executors/imports_executor_linux.go @@ -0,0 +1,9 @@ +// +build linux +// +build !libstorage_storage_driver + +package remote + +import ( + // import to load + _ "github.com/codedellemc/libstorage/drivers/storage/vmdk/executor" +) diff --git a/imports/executors/imports_executor_vmdk.go b/imports/executors/imports_executor_vmdk.go new file mode 100644 index 00000000..5774bf89 --- /dev/null +++ b/imports/executors/imports_executor_vmdk.go @@ -0,0 +1,9 @@ +// +build linux +// +build libstorage_storage_executor,libstorage_storage_executor_vmdk + +package executors + +import ( + // load the packages + _ "github.com/codedellemc/libstorage/drivers/storage/vmdk/executor" +) diff --git a/imports/remote/imports_remote.go b/imports/remote/imports_remote.go index 24b547a2..9ac2648d 100644 --- a/imports/remote/imports_remote.go +++ b/imports/remote/imports_remote.go @@ -3,7 +3,7 @@ package remote import ( - // import to load + // load the storage drivers _ "github.com/codedellemc/libstorage/drivers/storage/azureud/storage" _ "github.com/codedellemc/libstorage/drivers/storage/dobs/storage" _ "github.com/codedellemc/libstorage/drivers/storage/ebs/storage" diff --git a/imports/remote/imports_remote_linux.go b/imports/remote/imports_remote_linux.go new file mode 100644 index 00000000..732253dc --- /dev/null +++ b/imports/remote/imports_remote_linux.go @@ -0,0 +1,9 @@ +// +build linux +// +build !libstorage_storage_driver + +package remote + +import ( + // import to load + _ "github.com/codedellemc/libstorage/drivers/storage/vmdk/storage" +) diff --git a/imports/remote/imports_remote_vmdk.go b/imports/remote/imports_remote_vmdk.go new file mode 100644 index 00000000..67c6e915 --- /dev/null +++ b/imports/remote/imports_remote_vmdk.go @@ -0,0 +1,9 @@ +// +build linux +// +build libstorage_storage_driver,libstorage_storage_driver_vmdk + +package remote + +import ( + // load the packages + _ "github.com/codedellemc/libstorage/drivers/storage/vmdk/storage" +)