Files
threshold/sdk/plugins/host/load.go
T
Johan Brandhorst-Satzkorn d06ac0d370 Propagate plugin execution dir to CreatePlugin (#2183)
* fix: Propagate plugin options to CreatePlugin

Plugin options were previously only applied to the
BuildPluginMap call, resulting in the plugin
execution_dir variable being ineffective.

Also add a test to verify functionality

* fix: Support plugin execution_dir for all plugins

Previously, only external host plugins would respect
the plugin execution dir. Now, all uses of the embedded
plugins respect the configuration.
2022-06-15 16:16:18 -04:00

87 lines
2.3 KiB
Go

package external_host_plugins
import (
"context"
"fmt"
"io/fs"
"strings"
pb "github.com/hashicorp/boundary/sdk/pbs/plugin"
"github.com/hashicorp/go-plugin"
"github.com/hashicorp/go-secure-stdlib/pluginutil/v2"
)
// NOTE: This package could probably use some reflect based bits to allow
// loading other types of plugins later. That is an exercise left for future
// refactoring, but worth calling out now.
type pluginInfo struct {
containerFs fs.FS
filename string
creationFunc func() (pb.HostPluginServiceClient, error)
}
// CreateHostPlugin takes in a type, parses the various options to look for a
// plugin matching that name, and returns a host plugin client, a cleanup
// function to execute on shutdown of the enclosing program, and an error.
func CreateHostPlugin(
ctx context.Context,
pluginType string,
opt ...Option,
) (
hp pb.HostPluginServiceClient,
cleanup func() error,
retErr error,
) {
defer func() {
if retErr != nil && cleanup != nil {
_ = cleanup()
}
}()
pluginType = strings.ToLower(pluginType)
opts, err := getOpts(opt...)
if err != nil {
return nil, nil, fmt.Errorf("error parsing host plugin options: %w", err)
}
// First, scan available plugins, then find the right one to use
pluginMap, err := pluginutil.BuildPluginMap(
append(
opts.withPluginOptions,
pluginutil.WithPluginClientCreationFunc(
func(pluginPath string, _ ...pluginutil.Option) (*plugin.Client, error) {
return NewHostPluginClient(pluginPath, WithLogger(opts.withLogger))
}),
)...)
if err != nil {
return nil, nil, fmt.Errorf("error building plugin map: %w", err)
}
// Create the plugin and cleanup func
plugClient, cleanup, err := pluginutil.CreatePlugin(pluginMap[pluginType], opts.withPluginOptions...)
if err != nil {
return nil, cleanup, err
}
var raw interface{}
switch client := plugClient.(type) {
case plugin.ClientProtocol:
raw, err = client.Dispense(hostServicePluginSetName)
if err != nil {
return nil, cleanup, fmt.Errorf("error dispensing host plugin: %w", err)
}
default:
return nil, cleanup, fmt.Errorf("unable to understand type %T of raw plugin", raw)
}
var ok bool
hp, ok = raw.(pb.HostPluginServiceClient)
if !ok {
return nil, cleanup, fmt.Errorf("error converting rpc host plugin of type %T to normal wrapper", raw)
}
return hp, cleanup, nil
}