2026-04-06 15:48:37 +05:30
|
|
|
// Copyright IBM Corp. 2020, 2026
|
2022-03-16 17:04:07 -04:00
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
2023-02-02 17:15:17 -08:00
|
|
|
|
2023-04-08 16:15:14 -07:00
|
|
|
package external_plugins
|
2021-10-14 11:56:08 -04:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"strings"
|
|
|
|
|
|
2026-10-12 10:33:41 -07:00
|
|
|
pb "repo.anhonesthost.net/CyberCoveLLC/threshold/sdk/pbs/plugin"
|
2022-03-16 17:04:07 -04:00
|
|
|
"github.com/hashicorp/go-plugin"
|
|
|
|
|
"github.com/hashicorp/go-secure-stdlib/pluginutil/v2"
|
2021-10-14 11:56:08 -04:00
|
|
|
)
|
|
|
|
|
|
2023-04-08 16:15:14 -07:00
|
|
|
// 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) (pb.HostPluginServiceClient, func() error, error) {
|
|
|
|
|
raw, cleanup, err := createPlugin(ctx, pluginType, hostServicePluginSetName, opt...)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, cleanup, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var ok bool
|
|
|
|
|
hp, ok := raw.(pb.HostPluginServiceClient)
|
|
|
|
|
if !ok {
|
|
|
|
|
return nil, cleanup, fmt.Errorf("error converting rpc storage plugin of type %T to normal wrapper", raw)
|
|
|
|
|
}
|
2021-10-14 11:56:08 -04:00
|
|
|
|
2023-04-08 16:15:14 -07:00
|
|
|
return hp, cleanup, nil
|
2021-10-14 11:56:08 -04:00
|
|
|
}
|
|
|
|
|
|
2023-04-08 16:15:14 -07:00
|
|
|
// CreateStoragePlugin takes in a type, parses the various options to look for a
|
|
|
|
|
// plugin matching that name, and returns a storage plugin client, a cleanup
|
2021-10-14 11:56:08 -04:00
|
|
|
// function to execute on shutdown of the enclosing program, and an error.
|
2023-04-08 16:15:14 -07:00
|
|
|
func CreateStoragePlugin(ctx context.Context, pluginType string, opt ...Option) (pb.StoragePluginServiceClient, func() error, error) {
|
|
|
|
|
raw, cleanup, err := createPlugin(ctx, pluginType, storageServicePluginSetName, opt...)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, cleanup, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var ok bool
|
|
|
|
|
sp, ok := raw.(pb.StoragePluginServiceClient)
|
|
|
|
|
if !ok {
|
|
|
|
|
return nil, cleanup, fmt.Errorf("error converting rpc storage plugin of type %T to normal wrapper", raw)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sp, cleanup, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func createPlugin(
|
2021-10-14 11:56:08 -04:00
|
|
|
ctx context.Context,
|
|
|
|
|
pluginType string,
|
2023-04-08 16:15:14 -07:00
|
|
|
pluginSetName string,
|
2021-10-14 11:56:08 -04:00
|
|
|
opt ...Option,
|
|
|
|
|
) (
|
2023-04-08 16:15:14 -07:00
|
|
|
raw any,
|
2021-10-14 11:56:08 -04:00
|
|
|
cleanup func() error,
|
|
|
|
|
retErr error,
|
|
|
|
|
) {
|
|
|
|
|
defer func() {
|
|
|
|
|
if retErr != nil && cleanup != nil {
|
|
|
|
|
_ = cleanup()
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
pluginType = strings.ToLower(pluginType)
|
|
|
|
|
|
|
|
|
|
opts, err := getOpts(opt...)
|
|
|
|
|
if err != nil {
|
2023-04-08 16:15:14 -07:00
|
|
|
return nil, nil, fmt.Errorf("error parsing plugin options: %w", err)
|
2021-10-14 11:56:08 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// First, scan available plugins, then find the right one to use
|
2022-03-16 17:04:07 -04:00
|
|
|
pluginMap, err := pluginutil.BuildPluginMap(
|
|
|
|
|
append(
|
|
|
|
|
opts.withPluginOptions,
|
|
|
|
|
pluginutil.WithPluginClientCreationFunc(
|
|
|
|
|
func(pluginPath string, _ ...pluginutil.Option) (*plugin.Client, error) {
|
2023-04-08 16:15:14 -07:00
|
|
|
return NewPluginClient(pluginPath, pluginSetName, WithLogger(opts.withLogger))
|
2022-03-16 17:04:07 -04:00
|
|
|
}),
|
|
|
|
|
)...)
|
2021-10-14 11:56:08 -04:00
|
|
|
if err != nil {
|
2022-03-16 17:04:07 -04:00
|
|
|
return nil, nil, fmt.Errorf("error building plugin map: %w", err)
|
2021-10-14 11:56:08 -04:00
|
|
|
}
|
|
|
|
|
|
2022-03-16 17:04:07 -04:00
|
|
|
// Create the plugin and cleanup func
|
2022-06-15 16:16:18 -04:00
|
|
|
plugClient, cleanup, err := pluginutil.CreatePlugin(pluginMap[pluginType], opts.withPluginOptions...)
|
2021-10-14 11:56:08 -04:00
|
|
|
if err != nil {
|
2022-03-16 17:04:07 -04:00
|
|
|
return nil, cleanup, err
|
2021-10-14 11:56:08 -04:00
|
|
|
}
|
|
|
|
|
|
2022-03-16 17:04:07 -04:00
|
|
|
switch client := plugClient.(type) {
|
|
|
|
|
case plugin.ClientProtocol:
|
2023-04-08 16:15:14 -07:00
|
|
|
raw, err = client.Dispense(pluginSetName)
|
2021-10-14 11:56:08 -04:00
|
|
|
if err != nil {
|
2023-04-08 16:15:14 -07:00
|
|
|
return nil, cleanup, fmt.Errorf("error dispensing %q plugin: %w", pluginSetName, err)
|
2021-10-14 11:56:08 -04:00
|
|
|
}
|
2022-03-16 17:04:07 -04:00
|
|
|
default:
|
|
|
|
|
return nil, cleanup, fmt.Errorf("unable to understand type %T of raw plugin", raw)
|
2021-10-14 11:56:08 -04:00
|
|
|
}
|
|
|
|
|
|
2023-04-08 16:15:14 -07:00
|
|
|
return raw, cleanup, nil
|
2021-10-14 11:56:08 -04:00
|
|
|
}
|