diff --git a/CHANGELOG.md b/CHANGELOG.md index 49828295..f70d09bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- `wfx` would not start if it was built without plugins support + ### Changed - Use zstd instead of xz to compress release tarballs diff --git a/cmd/wfx/cmd/root/plugins.go b/cmd/wfx/cmd/root/plugins.go index df2ded51..611f6e7e 100644 --- a/cmd/wfx/cmd/root/plugins.go +++ b/cmd/wfx/cmd/root/plugins.go @@ -1,5 +1,3 @@ -//go:build plugin - package root /* @@ -11,17 +9,7 @@ package root */ import ( - "os" - "path" - "path/filepath" - "sort" - - "github.com/Southclaws/fault" - "github.com/knadh/koanf/v2" - "github.com/rs/zerolog/log" - "github.com/siemens/wfx/internal/errutil" "github.com/siemens/wfx/middleware" - "github.com/siemens/wfx/middleware/plugin" ) func LoadNorthboundPlugins(chQuit chan error) ([]middleware.IntermediateMW, error) { @@ -31,61 +19,3 @@ func LoadNorthboundPlugins(chQuit chan error) ([]middleware.IntermediateMW, erro func LoadSouthboundPlugins(chQuit chan error) ([]middleware.IntermediateMW, error) { return loadPluginSet(clientPluginsDirFlag, chQuit) } - -func loadPluginSet(flag string, chQuit chan error) ([]middleware.IntermediateMW, error) { - var pluginsDir string - k.Read(func(k *koanf.Koanf) { - pluginsDir = k.String(flag) - }) - if pluginsDir == "" { - return []middleware.IntermediateMW{}, nil - } - return errutil.Wrap2(createPluginMiddlewares(pluginsDir, chQuit)) -} - -func createPluginMiddlewares(pluginsDir string, chQuit chan error) ([]middleware.IntermediateMW, error) { - pluginMws, err := loadPlugins(pluginsDir) - if err != nil { - return nil, fault.Wrap(err) - } - result := make([]middleware.IntermediateMW, 0, len(pluginMws)) - for _, p := range pluginMws { - mw, err := plugin.NewMiddleware(p, chQuit) - if err != nil { - return nil, fault.Wrap(err) - } - result = append(result, mw) - } - return result, nil -} - -func loadPlugins(dir string) ([]plugin.Plugin, error) { - log.Debug().Msg("Loading plugins") - entries, err := os.ReadDir(dir) - if err != nil { - return nil, fault.Wrap(err) - } - - result := make([]plugin.Plugin, 0, len(entries)) - for _, entry := range entries { - if !entry.IsDir() { - dest, err := filepath.EvalSymlinks(path.Join(dir, entry.Name())) - if err != nil { - return nil, fault.Wrap(err) - } - info, err := os.Stat(dest) - if err != nil { - return nil, fault.Wrap(err) - } - // check if file is executable - if (info.Mode() & 0o111) != 0 { - result = append(result, plugin.NewFBPlugin(dest)) - } else { - log.Warn().Str("dest", dest).Msg("Ignoring non-executable file") - } - } - } - sort.Slice(result, func(i int, j int) bool { return result[i].Name() < result[j].Name() }) - log.Debug().Int("count", len(result)).Msg("Loaded plugins") - return result, nil -} diff --git a/cmd/wfx/cmd/root/plugins_disabled.go b/cmd/wfx/cmd/root/plugins_disabled.go index a94c685e..0279450c 100644 --- a/cmd/wfx/cmd/root/plugins_disabled.go +++ b/cmd/wfx/cmd/root/plugins_disabled.go @@ -13,13 +13,17 @@ package root import ( "errors" + "github.com/knadh/koanf/v2" "github.com/siemens/wfx/middleware" ) -func LoadNorthboundPlugins(chan error) ([]middleware.IntermediateMW, error) { - return nil, errors.New("this binary was built without plugin support") -} - -func LoadSouthboundPlugins(chan error) ([]middleware.IntermediateMW, error) { - return nil, errors.New("this binary was built without plugin support") +func loadPluginSet(flag string, _chQuit chan error) ([]middleware.IntermediateMW, error) { + var pluginsDir string + k.Read(func(k *koanf.Koanf) { + pluginsDir = k.String(flag) + }) + if pluginsDir != "" { + return nil, errors.New("this binary was built without plugin support") + } + return []middleware.IntermediateMW{}, nil } diff --git a/cmd/wfx/cmd/root/plugins_disabled_test.go b/cmd/wfx/cmd/root/plugins_disabled_test.go index 44a76fbc..d6a54922 100644 --- a/cmd/wfx/cmd/root/plugins_disabled_test.go +++ b/cmd/wfx/cmd/root/plugins_disabled_test.go @@ -13,17 +13,36 @@ package root import ( "testing" + "github.com/knadh/koanf/v2" "github.com/stretchr/testify/assert" ) func TestLoadNorthboundPlugins(t *testing.T) { + k.Write(func(k *koanf.Koanf) { + _ = k.Set(mgmtPluginsDirFlag, "/plugins") + }) mw, err := LoadNorthboundPlugins(nil) assert.Nil(t, mw) assert.ErrorContains(t, err, "this binary was built without plugin support") } +func TestLoadNorthboundPlugins_None(t *testing.T) { + mw, err := LoadNorthboundPlugins(nil) + assert.NoError(t, err) + assert.Empty(t, mw) +} + func TestLoadSouthboundPlugins(t *testing.T) { + k.Write(func(k *koanf.Koanf) { + _ = k.Set(clientPluginsDirFlag, "/plugins") + }) mw, err := LoadSouthboundPlugins(nil) assert.Nil(t, mw) assert.ErrorContains(t, err, "this binary was built without plugin support") } + +func TestLoadSouthboundPlugins_None(t *testing.T) { + mw, err := LoadSouthboundPlugins(nil) + assert.NoError(t, err) + assert.Empty(t, mw) +} diff --git a/cmd/wfx/cmd/root/plugins_enabled.go b/cmd/wfx/cmd/root/plugins_enabled.go new file mode 100644 index 00000000..437ac991 --- /dev/null +++ b/cmd/wfx/cmd/root/plugins_enabled.go @@ -0,0 +1,83 @@ +//go:build plugin + +package root + +/* + * SPDX-FileCopyrightText: 2023 Siemens AG + * + * SPDX-License-Identifier: Apache-2.0 + * + * Author: Michael Adler + */ + +import ( + "os" + "path" + "path/filepath" + "sort" + + "github.com/Southclaws/fault" + "github.com/knadh/koanf/v2" + "github.com/rs/zerolog/log" + "github.com/siemens/wfx/internal/errutil" + "github.com/siemens/wfx/middleware" + "github.com/siemens/wfx/middleware/plugin" +) + +func loadPluginSet(flag string, chQuit chan error) ([]middleware.IntermediateMW, error) { + var pluginsDir string + k.Read(func(k *koanf.Koanf) { + pluginsDir = k.String(flag) + }) + if pluginsDir == "" { + return []middleware.IntermediateMW{}, nil + } + return errutil.Wrap2(createPluginMiddlewares(pluginsDir, chQuit)) +} + +func createPluginMiddlewares(pluginsDir string, chQuit chan error) ([]middleware.IntermediateMW, error) { + pluginMws, err := loadPlugins(pluginsDir) + if err != nil { + return nil, fault.Wrap(err) + } + result := make([]middleware.IntermediateMW, 0, len(pluginMws)) + for _, p := range pluginMws { + mw, err := plugin.NewMiddleware(p, chQuit) + if err != nil { + return nil, fault.Wrap(err) + } + result = append(result, mw) + } + return result, nil +} + +func loadPlugins(dir string) ([]plugin.Plugin, error) { + log.Debug().Msg("Loading plugins") + entries, err := os.ReadDir(dir) + if err != nil { + return nil, fault.Wrap(err) + } + + result := make([]plugin.Plugin, 0, len(entries)) + for _, entry := range entries { + if !entry.IsDir() { + dest, err := filepath.EvalSymlinks(path.Join(dir, entry.Name())) + if err != nil { + return nil, fault.Wrap(err) + } + info, err := os.Stat(dest) + if err != nil { + return nil, fault.Wrap(err) + } + // check if file is executable + if (info.Mode() & 0o111) != 0 { + result = append(result, plugin.NewFBPlugin(dest)) + } else { + log.Warn().Str("dest", dest).Msg("Ignoring non-executable file") + } + } + } + sort.Slice(result, func(i int, j int) bool { return result[i].Name() < result[j].Name() }) + log.Debug().Int("count", len(result)).Msg("Loaded plugins") + return result, nil +}