Skip to content

Plugin Developer

Ben McClelland edited this page Sep 18, 2026 · 2 revisions

VersityGW can load an out-of-tree backend through Go's plugin system. A plugin exports a factory implementing plugins.BackendPlugin; the factory returns a normal backend.Backend.

package plugins

type BackendPlugin interface {
	New(config string) (backend.Backend, error)
}

Plugin entry point

The shared library must export a variable named Backend. Its dynamic type must implement plugins.BackendPlugin:

package main

import (
	"github.com/versity/versitygw/backend"
	"github.com/versity/versitygw/plugins"
)

var Backend plugins.BackendPlugin = &pluginFactory{}

type pluginFactory struct{}

func (p *pluginFactory) New(config string) (backend.Backend, error) {
	return newBackend(config)
}

The plugin package must be main. The configuration string is the path passed with --config; its format is owned by the plugin.

Implement the returned backend as described in Adding a Backend. Embedding backend.BackendUnsupported is useful for an intentionally partial backend.

Build and run

Build the plugin from the repository root:

go build -buildmode=plugin -o mystorage.so ./path/to/plugin

Start VersityGW with it:

versitygw [global options] plugin \
  --config /etc/versitygw/mystorage.yaml \
  ./mystorage.so

VGW_PLUGIN_CONFIG is the environment-variable equivalent of --config. The repository's plugins/noop implementation is a complete buildable example:

make -C plugins/noop
./versitygw --access test-access --secret test-secret \
  plugin ./plugins/noop/noop.so

Compatibility constraints

Go plugins have strict binary compatibility requirements. Build the gateway and plugin with:

  • The same Go toolchain version.
  • The same dependency versions.
  • The same build tags.
  • Compatible compiler flags and environment.
  • The exact same backend.Backend and plugins.BackendPlugin definitions.

Rebuild plugins for every VersityGW release. If backend.Backend changes, an older plugin will not load safely even if its methods appear similar.

Go plugins are supported only on platforms supported by Go's plugin package, currently Linux, FreeBSD, and macOS. They are not a portable option for Windows deployments. See the Go plugin warnings.

Lifecycle and errors

  • New should parse configuration, initialize clients, and return errors immediately when setup is invalid.
  • The gateway calls the backend's Shutdown method during normal shutdown; use it to stop workers and close backend-owned resources.
  • Backend methods should honor their request contexts.
  • Return s3err errors for expected S3 failures and wrapped Go errors for internal failures.
  • Do not log secrets or include them in returned errors.

The plugin command loads the file with plugin.Open, looks up the exported Backend symbol, calls New, and passes the resulting backend into the same embedgw lifecycle used by built-in backends.

Related documentation

Clone this wiki locally