feat: nice errors when failing to load plugins
partially fixes #7305
Steven Allen committed
Jun 4, 2020 at 20:22 UTC
c07b6fb1d1c2b2f1e26b2c72cbed31d03a00bac0
5 files changed
+82
-43
plugin/loader/load_nocgo.go
new
+18
@@ -0,0 +1,18 @@
1
+// +build !cgo,!noplugin
2
+// +build linux darwin
3
+
4
+package loader
5
+
6
+import (
7
+ "errors"
8
+
9
+ iplugin "github.com/ipfs/go-ipfs/plugin"
10
+)
11
+
12
+func init() {
13
+ loadPluginFunc = nocgoLoadPlugin
14
+}
15
+
16
+func nocgoLoadPlugin(fi string) ([]iplugin.Plugin, error) {
17
+ return nil, errors.New("not built with cgo support")
18
+}
plugin/loader/load_noplugin.go
new
+17
@@ -0,0 +1,17 @@
1
+// +build noplugin
2
+
3
+package loader
4
+
5
+import (
6
+ "errors"
7
+
8
+ iplugin "github.com/ipfs/go-ipfs/plugin"
9
+)
10
+
11
+func init() {
12
+ loadPluginFunc = nopluginLoadPlugin
13
+}
14
+
15
+func nopluginLoadPlugin(string) ([]iplugin.Plugin, error) {
16
+ return nil, errors.New("not built with plugin support")
17
+}
plugin/loader/load_unix.go
+4
-40
@@ -1,56 +1,20 @@
1
-// +build !noplugin
2
-// +build linux,cgo darwin,cgo
1
+// +build cgo,!noplugin
2
+// +build linux darwin
3
4
package loader
5
6
import (
7
"errors"
8
- "fmt"
9
- "os"
10
- "path/filepath"
8
"plugin"
9
10
iplugin "github.com/ipfs/go-ipfs/plugin"
11
)
12
13
func init() {
17
- loadPluginsFunc = linuxLoadFunc
14
+ loadPluginFunc = unixLoadPlugin
15
}
16
20
-func linuxLoadFunc(pluginDir string) ([]iplugin.Plugin, error) {
21
- var plugins []iplugin.Plugin
22
-
23
- err := filepath.Walk(pluginDir, func(fi string, info os.FileInfo, err error) error {
24
- if err != nil {
25
- return err
26
- }
27
- if info.IsDir() {
28
- if fi != pluginDir {
29
- log.Warnf("found directory inside plugins directory: %s", fi)
30
- }
31
- return nil
32
- }
33
-
34
- if info.Mode().Perm()&0111 == 0 {
35
- // file is not executable let's not load it
36
- // this is to prevent loading plugins from for example non-executable
37
- // mounts, some /tmp mounts are marked as such for security
38
- log.Errorf("non-executable file in plugins directory: %s", fi)
39
- return nil
40
- }
41
-
42
- if newPlugins, err := loadPlugin(fi); err == nil {
43
- plugins = append(plugins, newPlugins...)
44
- } else {
45
- return fmt.Errorf("loading plugin %s: %s", fi, err)
46
- }
47
- return nil
48
- })
49
-
50
- return plugins, err
51
-}
52
-
53
-func loadPlugin(fi string) ([]iplugin.Plugin, error) {
17
+func unixLoadPlugin(fi string) ([]iplugin.Plugin, error) {
18
pl, err := plugin.Open(fi)
19
if err != nil {
20
return nil, err
plugin/loader/loader.go
+33
-3
@@ -5,6 +5,7 @@ import (
5
"io"
6
"os"
7
"path/filepath"
8
+ "runtime"
9
"strings"
10
11
config "github.com/ipfs/go-ipfs-config"
@@ -30,8 +31,8 @@ func Preload(plugins ...plugin.Plugin) {
31
32
var log = logging.Logger("plugin/loader")
33
33
-var loadPluginsFunc = func(string) ([]plugin.Plugin, error) {
34
- return nil, nil
34
+var loadPluginFunc = func(string) ([]plugin.Plugin, error) {
35
+ return nil, fmt.Errorf("unsupported platform %s", runtime.GOOS)
36
}
37
38
type loaderState int
@@ -182,7 +183,36 @@ func loadDynamicPlugins(pluginDir string) ([]plugin.Plugin, error) {
183
return nil, err
184
}
185
185
- return loadPluginsFunc(pluginDir)
186
+ var plugins []plugin.Plugin
187
+
188
+ err = filepath.Walk(pluginDir, func(fi string, info os.FileInfo, err error) error {
189
+ if err != nil {
190
+ return err
191
+ }
192
+ if info.IsDir() {
193
+ if fi != pluginDir {
194
+ log.Warnf("found directory inside plugins directory: %s", fi)
195
+ }
196
+ return nil
197
+ }
198
+
199
+ if info.Mode().Perm()&0111 == 0 {
200
+ // file is not executable let's not load it
201
+ // this is to prevent loading plugins from for example non-executable
202
+ // mounts, some /tmp mounts are marked as such for security
203
+ log.Errorf("non-executable file in plugins directory: %s", fi)
204
+ return nil
205
+ }
206
+
207
+ if newPlugins, err := loadPluginFunc(fi); err == nil {
208
+ plugins = append(plugins, newPlugins...)
209
+ } else {
210
+ return fmt.Errorf("loading plugin %s: %s", fi, err)
211
+ }
212
+ return nil
213
+ })
214
+
215
+ return plugins, err
216
}
217
218
// Initialize initializes all loaded plugins
test/sharness/t0280-plugin.sh
+10
@@ -89,4 +89,14 @@ test_expect_success "configure the plugin" '
89
90
test_plugin true "$IPFS_PATH" "foobar"
91
92
+test_expect_success "noplugin flag works" '
93
+ test_must_fail go run -tags=noplugin github.com/ipfs/go-ipfs/cmd/ipfs id > output 2>&1
94
+ test_should_contain "not built with plugin support" output
95
+'
96
+
97
+test_expect_success "noplugin flag works" '
98
+ CGO_ENABLED=0 test_must_fail go run github.com/ipfs/go-ipfs/cmd/ipfs id > output 2>&1
99
+ test_should_contain "not built with cgo support" output
100
+'
101
+
102
test_done