From 5239bd5f38d3d054c294613f14740877838a5e56 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 4 Jun 2020 20:22:28 -0700 Subject: [PATCH] feat: nice errors when failing to load plugins partially fixes #7305 --- plugin/loader/load_nocgo.go | 17 +++++++++++++++ plugin/loader/load_noplugin.go | 17 +++++++++++++++ plugin/loader/load_unix.go | 40 ++-------------------------------- plugin/loader/loader.go | 36 +++++++++++++++++++++++++++--- test/sharness/t0280-plugin.sh | 10 +++++++++ 5 files changed, 79 insertions(+), 41 deletions(-) create mode 100644 plugin/loader/load_nocgo.go create mode 100644 plugin/loader/load_noplugin.go diff --git a/plugin/loader/load_nocgo.go b/plugin/loader/load_nocgo.go new file mode 100644 index 00000000000..04088fe6cf4 --- /dev/null +++ b/plugin/loader/load_nocgo.go @@ -0,0 +1,17 @@ +// +build linux,!cgo,!noplugin darwin,!cgo,!noplugin + +package loader + +import ( + "errors" + + iplugin "github.com/ipfs/go-ipfs/plugin" +) + +func init() { + loadPluginFunc = nocgoLoadPlugin +} + +func nocgoLoadPlugin(fi string) ([]iplugin.Plugin, error) { + return nil, errors.New("not built with cgo support") +} diff --git a/plugin/loader/load_noplugin.go b/plugin/loader/load_noplugin.go new file mode 100644 index 00000000000..dfe1e3cac35 --- /dev/null +++ b/plugin/loader/load_noplugin.go @@ -0,0 +1,17 @@ +// +build noplugin + +package loader + +import ( + "errors" + + iplugin "github.com/ipfs/go-ipfs/plugin" +) + +func init() { + loadPluginFunc = nopluginLoadPlugin +} + +func nopluginLoadPlugin(string) ([]iplugin.Plugin, error) { + return nil, errors.New("not built with plugin support") +} diff --git a/plugin/loader/load_unix.go b/plugin/loader/load_unix.go index db1eb5d970f..e912d9902d3 100644 --- a/plugin/loader/load_unix.go +++ b/plugin/loader/load_unix.go @@ -5,52 +5,16 @@ package loader import ( "errors" - "fmt" - "os" - "path/filepath" "plugin" iplugin "github.com/ipfs/go-ipfs/plugin" ) func init() { - loadPluginsFunc = linuxLoadFunc + loadPluginFunc = unixLoadPlugin } -func linuxLoadFunc(pluginDir string) ([]iplugin.Plugin, error) { - var plugins []iplugin.Plugin - - err := filepath.Walk(pluginDir, func(fi string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if info.IsDir() { - if fi != pluginDir { - log.Warnf("found directory inside plugins directory: %s", fi) - } - return nil - } - - if info.Mode().Perm()&0111 == 0 { - // file is not executable let's not load it - // this is to prevent loading plugins from for example non-executable - // mounts, some /tmp mounts are marked as such for security - log.Errorf("non-executable file in plugins directory: %s", fi) - return nil - } - - if newPlugins, err := loadPlugin(fi); err == nil { - plugins = append(plugins, newPlugins...) - } else { - return fmt.Errorf("loading plugin %s: %s", fi, err) - } - return nil - }) - - return plugins, err -} - -func loadPlugin(fi string) ([]iplugin.Plugin, error) { +func unixLoadPlugin(fi string) ([]iplugin.Plugin, error) { pl, err := plugin.Open(fi) if err != nil { return nil, err diff --git a/plugin/loader/loader.go b/plugin/loader/loader.go index 9693118ebc6..553e6c7eae1 100644 --- a/plugin/loader/loader.go +++ b/plugin/loader/loader.go @@ -5,6 +5,7 @@ import ( "io" "os" "path/filepath" + "runtime" "strings" config "github.com/ipfs/go-ipfs-config" @@ -30,8 +31,8 @@ func Preload(plugins ...plugin.Plugin) { var log = logging.Logger("plugin/loader") -var loadPluginsFunc = func(string) ([]plugin.Plugin, error) { - return nil, nil +var loadPluginFunc = func(string) ([]plugin.Plugin, error) { + return nil, fmt.Errorf("unsupported platform %s", runtime.GOOS) } type loaderState int @@ -182,7 +183,36 @@ func loadDynamicPlugins(pluginDir string) ([]plugin.Plugin, error) { return nil, err } - return loadPluginsFunc(pluginDir) + var plugins []plugin.Plugin + + err = filepath.Walk(pluginDir, func(fi string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + if fi != pluginDir { + log.Warnf("found directory inside plugins directory: %s", fi) + } + return nil + } + + if info.Mode().Perm()&0111 == 0 { + // file is not executable let's not load it + // this is to prevent loading plugins from for example non-executable + // mounts, some /tmp mounts are marked as such for security + log.Errorf("non-executable file in plugins directory: %s", fi) + return nil + } + + if newPlugins, err := loadPluginFunc(fi); err == nil { + plugins = append(plugins, newPlugins...) + } else { + return fmt.Errorf("loading plugin %s: %s", fi, err) + } + return nil + }) + + return plugins, err } // Initialize initializes all loaded plugins diff --git a/test/sharness/t0280-plugin.sh b/test/sharness/t0280-plugin.sh index a0709ef1b2b..d5b8313e2e7 100755 --- a/test/sharness/t0280-plugin.sh +++ b/test/sharness/t0280-plugin.sh @@ -89,4 +89,14 @@ test_expect_success "configure the plugin" ' test_plugin true "$IPFS_PATH" "foobar" +test_expect_success "noplugin flag works" ' + test_must_fail go run -tags=noplugin github.com/ipfs/go-ipfs/cmd/ipfs id > output 2>&1 + test_should_contain "not built with plugin support" output +' + +test_expect_success "noplugin flag works" ' + CGO_ENABLED=0 test_must_fail go run github.com/ipfs/go-ipfs/cmd/ipfs id > output 2>&1 + test_should_contain "not built with cgo support" output +' + test_done