71 lines
2.2 KiB
Go
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
|
|
}
|