From 9082d469e7575271ae4e9a8d0ca7b097326403da Mon Sep 17 00:00:00 2001 From: Gianmaria Del Monte Date: Fri, 25 Apr 2025 14:43:03 +0200 Subject: [PATCH] Add support for plugin backends --- cmd/versitygw/main.go | 1 + cmd/versitygw/plugin.go | 60 +++++++++++++++++++++++++++++++++++++++++ plugins/plugins.go | 21 +++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 cmd/versitygw/plugin.go create mode 100644 plugins/plugins.go diff --git a/cmd/versitygw/main.go b/cmd/versitygw/main.go index e0bc39d..32fe3b8 100644 --- a/cmd/versitygw/main.go +++ b/cmd/versitygw/main.go @@ -98,6 +98,7 @@ func main() { scoutfsCommand(), s3Command(), azureCommand(), + pluginCommand(), adminCommand(), testCommand(), utilsCommand(), diff --git a/cmd/versitygw/plugin.go b/cmd/versitygw/plugin.go new file mode 100644 index 0000000..e238ca6 --- /dev/null +++ b/cmd/versitygw/plugin.go @@ -0,0 +1,60 @@ +package main + +import ( + "errors" + "fmt" + "plugin" + + "github.com/urfave/cli/v2" + "github.com/versity/versitygw/plugins" +) + +func pluginCommand() *cli.Command { + return &cli.Command{ + Name: "plugin", + Usage: "load a backend from a plugin", + Description: "Runs a s3 gateway and redirects the requests to the backend defined in the plugin", + Action: runPluginBackend, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "config", + Usage: "location of the config file", + Aliases: []string{"c"}, + }, + }, + } +} + +func runPluginBackend(ctx *cli.Context) error { + if ctx.NArg() == 0 { + return fmt.Errorf("no plugin file provided to be loaded") + } + + pluginPath := ctx.Args().Get(0) + config := ctx.String("config") + + p, err := plugin.Open(pluginPath) + if err != nil { + return err + } + + backendSymbol, err := p.Lookup("Backend") + if err != nil { + return err + } + backendPluginPtr, ok := backendSymbol.(*plugins.BackendPlugin) + if !ok { + return errors.New("plugin is not of type *plugins.BackendPlugin") + } + + if backendPluginPtr == nil { + return errors.New("variable Backend is nil") + } + + be, err := (*backendPluginPtr).New(config) + if err != nil { + return err + } + + return runGateway(ctx.Context, be) +} diff --git a/plugins/plugins.go b/plugins/plugins.go new file mode 100644 index 0000000..a8a3aac --- /dev/null +++ b/plugins/plugins.go @@ -0,0 +1,21 @@ +package plugins + +import "github.com/versity/versitygw/backend" + +// BackendPlugin defines an interface for creating backend +// implementation instances. +// Plugins implementing this interface can be built as shared +// libraries using Go's plugin system (to build use `go build -buildmode=plugin`). +// The shared library should export an instance of +// this interface in a variable named `Backend`. +type BackendPlugin interface { + // New creates and initializes a new backend.Backend instance. + // The config parameter specifies the path of the file containing + // the configuration for the backend. + // + // Implementations of this method should perform the necessary steps to + // establish a connection to the underlying storage system or service + // (e.g., network storage system, distributed storage system, cloud storage) + // and configure it according to the provided configuration. + New(config string) (backend.Backend, error) +}