github.com/hashicorp/go-plugin@v1.6.0/examples/negotiated/main.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  	"io/ioutil"
     9  	"log"
    10  	"os"
    11  	"os/exec"
    12  
    13  	"github.com/hashicorp/go-plugin"
    14  	"github.com/hashicorp/go-plugin/examples/grpc/shared"
    15  )
    16  
    17  func main() {
    18  	// We don't want to see the plugin logs.
    19  	log.SetOutput(ioutil.Discard)
    20  
    21  	plugins := map[int]plugin.PluginSet{}
    22  
    23  	// Both version can be supported, but switch the implementation to
    24  	// demonstrate version negoation.
    25  	switch os.Getenv("KV_PROTO") {
    26  	case "netrpc":
    27  		plugins[2] = plugin.PluginSet{
    28  			"kv": &shared.KVPlugin{},
    29  		}
    30  	case "grpc":
    31  		plugins[3] = plugin.PluginSet{
    32  			"kv": &shared.KVGRPCPlugin{},
    33  		}
    34  	default:
    35  		fmt.Println("must set KV_PROTO to netrpc or grpc")
    36  		os.Exit(1)
    37  	}
    38  
    39  	// We're a host. Start by launching the plugin process.
    40  	client := plugin.NewClient(&plugin.ClientConfig{
    41  		HandshakeConfig:  shared.Handshake,
    42  		VersionedPlugins: plugins,
    43  		Cmd:              exec.Command("./kv-plugin"),
    44  		AllowedProtocols: []plugin.Protocol{
    45  			plugin.ProtocolNetRPC, plugin.ProtocolGRPC},
    46  	})
    47  	defer client.Kill()
    48  
    49  	rpcClient, err := client.Client()
    50  	if err != nil {
    51  		fmt.Println("Error:", err.Error())
    52  		os.Exit(1)
    53  	}
    54  
    55  	// Request the plugin
    56  	raw, err := rpcClient.Dispense("kv")
    57  	if err != nil {
    58  		fmt.Println("Error:", err.Error())
    59  		os.Exit(1)
    60  	}
    61  
    62  	// We should have a KV store now! This feels like a normal interface
    63  	// implementation but is in fact over an RPC connection.
    64  	kv := raw.(shared.KV)
    65  	os.Args = os.Args[1:]
    66  	switch os.Args[0] {
    67  	case "get":
    68  		result, err := kv.Get(os.Args[1])
    69  		if err != nil {
    70  			fmt.Println("Error:", err.Error())
    71  			os.Exit(1)
    72  		}
    73  
    74  		fmt.Println(string(result))
    75  
    76  	case "put":
    77  		err := kv.Put(os.Args[1], []byte(os.Args[2]))
    78  		if err != nil {
    79  			fmt.Println("Error:", err.Error())
    80  			os.Exit(1)
    81  		}
    82  
    83  	default:
    84  		fmt.Println("Please only use 'get' or 'put'")
    85  		os.Exit(1)
    86  	}
    87  }