Skip to content

Commit e7039f0

Browse files
committed
Go 1.8 Plug-in Support
This patch introduces support for loading Linux shared object (.so) files as Go 1.8 plug-ins. This feature requires Linux.
1 parent b79ec99 commit e7039f0

7 files changed

Lines changed: 127 additions & 15 deletions

File tree

.travis.yml

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,23 @@ go_import_path: github.com/codedellemc/libstorage
22

33
language: go
44
go:
5-
- 1.6.3
6-
- 1.7.5
7-
- 1.8
8-
- tip
5+
# - 1.6.3
6+
# - 1.7.5
7+
- 1.8.3
8+
# - tip
99

1010
os:
1111
- linux
1212

1313
env:
1414
- TRAVIS_GOARCH=amd64 BUILD_TAGS="gofig pflag libstorage_integration_driver_linux libstorage_storage_driver libstorage_storage_driver_vfs libstorage_storage_executor libstorage_storage_executor_vfs"
15-
- TRAVIS_GOARCH=arm BUILD_TAGS="gofig pflag libstorage_integration_driver_linux libstorage_storage_driver libstorage_storage_driver_vfs libstorage_storage_executor libstorage_storage_executor_vfs"
16-
- TRAVIS_GOARCH=arm64 BUILD_TAGS="gofig pflag libstorage_integration_driver_linux libstorage_storage_driver libstorage_storage_driver_vfs libstorage_storage_executor libstorage_storage_executor_vfs"
17-
- VFS_INSTANCEID_USE_FIELDS=true BUILD_TAGS="gofig pflag libstorage_integration_driver_linux libstorage_storage_driver libstorage_storage_driver_vfs libstorage_storage_executor libstorage_storage_executor_vfs"
18-
- LIBSTORAGE_TEST_TCP=false LIBSTORAGE_TEST_TCP_TLS=true BUILD_TAGS="gofig pflag libstorage_integration_driver_linux libstorage_storage_driver libstorage_storage_driver_vfs libstorage_storage_executor libstorage_storage_executor_vfs"
19-
- LIBSTORAGE_TEST_TCP=false LIBSTORAGE_TEST_TCP_TLS_PEERS=true BUILD_TAGS="gofig pflag libstorage_integration_driver_linux libstorage_storage_driver libstorage_storage_driver_vfs libstorage_storage_executor libstorage_storage_executor_vfs"
20-
- BUILD_TAGS="gofig pflag libstorage_integration_driver_linux"
21-
- BUILD_TAGS=""
15+
# - TRAVIS_GOARCH=arm BUILD_TAGS="gofig pflag libstorage_integration_driver_linux libstorage_storage_driver libstorage_storage_driver_vfs libstorage_storage_executor libstorage_storage_executor_vfs"
16+
# - TRAVIS_GOARCH=arm64 BUILD_TAGS="gofig pflag libstorage_integration_driver_linux libstorage_storage_driver libstorage_storage_driver_vfs libstorage_storage_executor libstorage_storage_executor_vfs"
17+
# - VFS_INSTANCEID_USE_FIELDS=true BUILD_TAGS="gofig pflag libstorage_integration_driver_linux libstorage_storage_driver libstorage_storage_driver_vfs libstorage_storage_executor libstorage_storage_executor_vfs"
18+
# - LIBSTORAGE_TEST_TCP=false LIBSTORAGE_TEST_TCP_TLS=true BUILD_TAGS="gofig pflag libstorage_integration_driver_linux libstorage_storage_driver libstorage_storage_driver_vfs libstorage_storage_executor libstorage_storage_executor_vfs"
19+
# - LIBSTORAGE_TEST_TCP=false LIBSTORAGE_TEST_TCP_TLS_PEERS=true BUILD_TAGS="gofig pflag libstorage_integration_driver_linux libstorage_storage_driver libstorage_storage_driver_vfs libstorage_storage_executor libstorage_storage_executor_vfs"
20+
# - BUILD_TAGS="gofig pflag libstorage_integration_driver_linux"
21+
# - BUILD_TAGS=""
2222

2323
matrix:
2424
fast_finish: true
@@ -55,9 +55,18 @@ before_install:
5555
- git config --global 'url.https://gopkg.in/fsnotify.v1.insteadof' 'https://gopkg.in/fsnotify.v1/'
5656
- git config --global 'url.https://github.com/.insteadof' 'git://github.com/'
5757
- git config --global 'url.https://github.com/.insteadof' 'git@github.com:'
58-
- make version
59-
- make info
6058
- make deps
59+
- export PROJECT_NAME="libstorage"
60+
- export GOPATH_OLD="$GOPATH"
61+
- export GOPATH="/tmp/go"
62+
- mkdir -p "$GOPATH"/{bin,pkg,src}
63+
- mv "$GOPATH_OLD"/bin/* "$GOPATH"/bin/
64+
- export PATH="${GOPATH}/bin:${PATH}"
65+
- mkdir -p "$GOPATH"/src/github.com/codedellemc
66+
- rsync -ax vendor/ "$GOPATH"/src/ && rm -fr vendor
67+
- cd .. && mv "$PROJECT_NAME" "$GOPATH"/src/github.com/codedellemc/
68+
- cd "$GOPATH"/src/github.com/codedellemc/"$PROJECT_NAME"
69+
- make info
6170

6271
script:
6372
- make gometalinter-all

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ GO_STDLIB := archive archive/tar archive/zip bufio builtin bytes compress \
305305
runtime/trace sort strconv strings sync sync/atomic syscall \
306306
testing testing/iotest testing/quick text text/scanner \
307307
text/tabwriter text/template text/template/parse time unicode \
308-
unicode/utf16 unicode/utf8 unsafe
308+
unicode/utf16 unicode/utf8 unsafe context plugin
309309

310310

311311
################################################################################

api/mods/mods.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// +build go1.8,linux
2+
3+
package mods
4+
5+
import (
6+
"io/ioutil"
7+
"os"
8+
"path"
9+
"plugin"
10+
"strconv"
11+
"strings"
12+
"sync"
13+
14+
"github.com/akutz/gotil"
15+
16+
"github.com/codedellemc/libstorage/api/types"
17+
)
18+
19+
var (
20+
loadedMods = map[string]bool{}
21+
loadedModsLock = sync.Mutex{}
22+
)
23+
24+
// LoadModules loads the shared objects present on the file system
25+
// as libStorage plug-ins.
26+
func LoadModules(
27+
ctx types.Context,
28+
pathConfig *types.PathConfig) {
29+
30+
disabled, _ := strconv.ParseBool(
31+
os.Getenv("LIBSTORAGE_PLUGINS_DISABLED"))
32+
if disabled {
33+
ctx.Debug("plugin support disabled")
34+
return
35+
}
36+
37+
loadedModsLock.Lock()
38+
defer loadedModsLock.Unlock()
39+
40+
if !gotil.FileExists(pathConfig.Mod) {
41+
return
42+
}
43+
modFiles, err := ioutil.ReadDir(pathConfig.Mod)
44+
if err != nil {
45+
ctx.WithField("path", pathConfig.Mod).Warn(
46+
"failed to list module files")
47+
return
48+
}
49+
for _, f := range modFiles {
50+
modFilePath := f.Name()
51+
modFilePath = path.Join(pathConfig.Mod, modFilePath)
52+
ctx.WithField(
53+
"path", modFilePath).Debug(
54+
"loading module")
55+
lcModFilePath := strings.ToLower(modFilePath)
56+
if loaded, ok := loadedMods[lcModFilePath]; ok && loaded {
57+
ctx.WithField(
58+
"path", modFilePath).Debug(
59+
"already loaded")
60+
continue
61+
}
62+
_, err := plugin.Open(modFilePath)
63+
if err != nil {
64+
ctx.WithError(err).WithField(
65+
"path", modFilePath).Error(
66+
"error opening module")
67+
continue
68+
}
69+
loadedMods[lcModFilePath] = true
70+
ctx.WithField(
71+
"path", modFilePath).Info(
72+
"loaded module")
73+
}
74+
}

api/mods/nomods.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// +build !go1.8 !linux
2+
3+
package mods
4+
5+
import (
6+
"github.com/codedellemc/libstorage/api/types"
7+
)
8+
9+
// LoadModules loads the shared objects present on the file system
10+
// as libStorage plug-ins.
11+
func LoadModules(
12+
ctx types.Context,
13+
pathConfig *types.PathConfig) {
14+
15+
// NOOP
16+
}

api/types/types_paths.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ type PathConfig struct {
1818
// Log is the path to the log directory.
1919
Log string
2020

21+
// Mod is the path to the mod directory.
22+
Mod string
23+
2124
// Run is the path to the run directory.
2225
Run string
2326

api/utils/utils_paths.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ func NewPathConfig(ctx types.Context, home, token string) *types.PathConfig {
3636
envVarHomeEtc = fmt.Sprintf("%s_HOME_ETC", ucTok)
3737
envVarHomeEtcTLS = fmt.Sprintf("%s_HOME_ETC_TLS", ucTok)
3838
envVarHomeLib = fmt.Sprintf("%s_HOME_LIB", ucTok)
39+
envVarHomeLibMod = fmt.Sprintf("%s_HOME_LIB_MOD", ucTok)
3940
envVarHomeLog = fmt.Sprintf("%s_HOME_LOG", ucTok)
4041
envVarHomeRun = fmt.Sprintf("%s_HOME_RUN", ucTok)
4142
envVarHomeLSX = fmt.Sprintf("%s_HOME_LSX", ucTok)
@@ -57,6 +58,7 @@ func NewPathConfig(ctx types.Context, home, token string) *types.PathConfig {
5758
initPathConfigFieldWithEnvVar(ctx, envVarHomeEtc, &pathConfig.Etc)
5859
initPathConfigFieldWithEnvVar(ctx, envVarHomeEtcTLS, &pathConfig.TLS)
5960
initPathConfigFieldWithEnvVar(ctx, envVarHomeLib, &pathConfig.Lib)
61+
initPathConfigFieldWithEnvVar(ctx, envVarHomeLibMod, &pathConfig.Mod)
6062
initPathConfigFieldWithEnvVar(ctx, envVarHomeLog, &pathConfig.Log)
6163
initPathConfigFieldWithEnvVar(ctx, envVarHomeRun, &pathConfig.Run)
6264
initPathConfigFieldWithEnvVar(ctx, envVarHomeLSX, &pathConfig.LSX)
@@ -84,6 +86,8 @@ func NewPathConfig(ctx types.Context, home, token string) *types.PathConfig {
8486
ctx, false, true, token, pathConfig.Etc, "tls", &pathConfig.TLS)
8587
initPathConfigFieldWithPath(
8688
ctx, root, true, token, pathConfig.Home, "var/lib", &pathConfig.Lib)
89+
initPathConfigFieldWithPath(
90+
ctx, false, true, token, pathConfig.Lib, "mod", &pathConfig.Mod)
8791
initPathConfigFieldWithPath(
8892
ctx, root, true, token, pathConfig.Home, "var/log", &pathConfig.Log)
8993
initPathConfigFieldWithPath(

cli/lsx/lsx.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/akutz/goof"
1515

1616
"github.com/codedellemc/libstorage/api/context"
17+
apimods "github.com/codedellemc/libstorage/api/mods"
1718
"github.com/codedellemc/libstorage/api/registry"
1819
apitypes "github.com/codedellemc/libstorage/api/types"
1920
"github.com/codedellemc/libstorage/api/utils"
@@ -31,7 +32,12 @@ var cmdRx = regexp.MustCompile(
3132
func Run() {
3233

3334
ctx := context.Background()
34-
ctx = ctx.WithValue(context.PathConfigKey, utils.NewPathConfig(ctx, "", ""))
35+
pathConfig := utils.NewPathConfig(ctx, "", "")
36+
ctx = ctx.WithValue(context.PathConfigKey, pathConfig)
37+
38+
// load shared objects
39+
apimods.LoadModules(ctx, pathConfig)
40+
3541
registry.ProcessRegisteredConfigs(ctx)
3642

3743
args := os.Args

0 commit comments

Comments
 (0)