buildr/modules/plugin/discovery.go
Peter 34c431790e
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/tag Build is failing
refactor: use connect-go instead of regular Google gRPC
- support binary name for plugins
- register plugins for container jobs
2023-09-12 18:43:34 +02:00

71 lines
2.2 KiB
Go

package plugin
import (
"context"
"errors"
"fmt"
"connectrpc.com/connect"
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
wasiv1 "code.icb4dc0.de/buildr/api/generated/wasi/v1"
"code.icb4dc0.de/buildr/api/generated/wasi/v1/rpcv1connect"
"code.icb4dc0.de/buildr/common/wasirpc"
)
var dummyWithResult = func(ctx context.Context, m api.Module, offset, byteCount uint32) (result uint64) { return 0 }
func DiscoverInventory(ctx context.Context, payload []byte) (inventory *wasiv1.PluginInventoryResponse, err error) {
runtimeConfig := wazero.
NewRuntimeConfig().
WithCloseOnContextDone(true)
r := wazero.NewRuntimeWithConfig(ctx, runtimeConfig)
defer func() {
closeCtx, cancel := context.WithTimeout(context.Background(), runtimeClosingTimeout)
defer cancel()
err = errors.Join(err, r.Close(closeCtx))
}()
_, err = r.NewHostModuleBuilder("buildr").
NewFunctionBuilder().WithFunc(dummyWithResult).Export("log_msg").
NewFunctionBuilder().WithFunc(dummyWithResult).Export("get_state").
NewFunctionBuilder().WithFunc(dummyWithResult).Export("set_state").
NewFunctionBuilder().WithFunc(dummyWithResult).Export("exec").
NewFunctionBuilder().WithFunc(dummyWithResult).Export("lookPath").
Instantiate(ctx)
if err != nil {
return nil, fmt.Errorf("failed to instantiate host module builder: %w", err)
}
closer, err := wasi_snapshot_preview1.Instantiate(ctx, r)
if err != nil {
return nil, fmt.Errorf("failed to instantiate wasi snapshot preview1: %w", err)
}
defer func() {
err = errors.Join(err, closer.Close(context.Background()))
}()
mod, err := r.Instantiate(ctx, payload)
if err != nil {
return nil, fmt.Errorf("failed to instantiate WASI plugin: %w", err)
}
moduleClient, err := wasirpc.NewModuleClient(mod)
if err != nil {
return nil, fmt.Errorf("failed to create module client: %w", err)
}
wasiClient := rpcv1connect.NewWasiExecutorServiceClient(moduleClient, "wasi://pluginToBeDiscovered")
resp, err := wasiClient.PluginInventory(ctx, connect.NewRequest(new(wasiv1.PluginInventoryRequest)))
if err != nil {
return nil, fmt.Errorf("failed to call plugin inventory: %w", err)
}
return resp.Msg, nil
}