package plugins import ( "fmt" "os" "os/exec" "path/filepath" hclog "github.com/hashicorp/go-hclog" plugin "github.com/hashicorp/go-plugin" "gitlab.33.cn/link33/sidecar/internal/repo" "gitlab.33.cn/link33/sidecar/tool" ) var logger = hclog.New(&hclog.LoggerOptions{ Name: "plugin", Output: hclog.DefaultOutput, Level: hclog.Trace, }) func CreateClient(sidecarID string, appchainConfig repo.Appchain, extra []byte) (Client, *plugin.Client, error) { // Sidecar is the host. Start by launching the plugin process. rootPath, err := repo.PathRoot() if err != nil { return nil, nil, err } pluginConfigPath := filepath.Join(rootPath, appchainConfig.Config) pluginPath := filepath.Join(rootPath, "plugins", appchainConfig.Plugin) client := plugin.NewClient(&plugin.ClientConfig{ HandshakeConfig: Handshake, Plugins: PluginMap, Cmd: exec.Command("sh", "-c", pluginPath), Logger: logger, AllowedProtocols: []plugin.Protocol{ plugin.ProtocolGRPC, }, // 只支持grpc }) // Connect via RPC rpcClient, err := client.Client() if err != nil { return nil, nil, err } // Request the plugin raw, err := rpcClient.Dispense(appchainConfig.Plugin) if err != nil { return nil, nil, err } var appchain Client switch raw.(type) { case *GRPCClient: appchain = raw.(*GRPCClient) default: return nil, nil, fmt.Errorf("unsupported client type") } // initialize our client plugin err = appchain.Initialize(pluginConfigPath, sidecarID, extra) if err != nil { return nil, nil, err } return appchain, client, nil } func CreateClients(appchainConfigs []repo.Appchain, extra []byte) []Client { // Sidecar is the host. Start by launching the plugin process. rootPath, err := repo.PathRoot() tool.Asset(err) var clients []Client for _, appchainConfig := range appchainConfigs { pluginConfigPath := filepath.Join(rootPath, "plugins", appchainConfig.Config) pluginPath := filepath.Join(rootPath, "plugins", appchainConfig.Plugin) _, err = os.Stat(pluginPath) if err != nil { if os.IsNotExist(err) { tool.Asset(fmt.Errorf("plugin file `%s` is required", pluginPath)) } tool.Asset(fmt.Errorf("get plugin file state error: %w", err)) } kernel := plugin.NewClient(&plugin.ClientConfig{ HandshakeConfig: Handshake, Plugins: map[string]plugin.Plugin{ appchainConfig.Plugin: &AppchainGRPCPlugin{}, // 宿主机进程的插件集 }, Cmd: exec.Command("sh", "-c", pluginPath), Logger: logger, AllowedProtocols: []plugin.Protocol{ plugin.ProtocolGRPC, }, // 只支持grpc }) // Connect via RPC rpcClient, err := kernel.Client() tool.Asset(err) // Request the plugin raw, err := rpcClient.Dispense(appchainConfig.Plugin) tool.Asset(err) var appchain Client switch raw.(type) { case *GRPCClient: appchain = raw.(*GRPCClient) default: tool.Asset(fmt.Errorf("unsupported kernel type")) } // initialize our kernel plugin err = appchain.Initialize(pluginConfigPath, appchainConfig.DID, extra) tool.Asset(err) appchain.Bind(kernel) clients = append(clients, appchain) } return clients }