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 }