OSDN Git Service

add package
[bytom/vapor.git] / vendor / github.com / hashicorp / go-plugin / docs / guide-plugin-write-non-go.md
1 # Writing Plugins Without Go
2
3 This guide explains how to write a go-plugin compatible plugin using
4 a programming language other than Go. go-plugin supports plugins using
5 [gRPC](http://www.grpc.io). This makes it relatively simple to write plugins
6 using other languages!
7
8 Minimal knowledge about gRPC is assumed. We recommend reading the
9 [gRPC Go Tutorial](http://www.grpc.io/docs/tutorials/basic/go.html). This
10 alone is enough gRPC knowledge to continue.
11
12 This guide will implement the kv example in Python.
13 Full source code for the examples present in this guide
14 [is available in the examples/grpc folder](https://github.com/hashicorp/go-plugin/tree/master/examples/grpc).
15
16 ## 1. Implement the Service
17
18 The first step is to implement the gRPC server for the protocol buffers
19 service that your plugin defines. This is a standard gRPC server.
20 For the KV service, the service looks like this:
21
22 ```proto
23 service KV {
24     rpc Get(GetRequest) returns (GetResponse);
25     rpc Put(PutRequest) returns (Empty);
26 }
27 ```
28
29 We can implement that using Python as easily as:
30
31 ```python
32 class KVServicer(kv_pb2_grpc.KVServicer):
33     """Implementation of KV service."""
34
35     def Get(self, request, context):
36         filename = "kv_"+request.key
37         with open(filename, 'r') as f:
38             result = kv_pb2.GetResponse()
39             result.value = f.read()
40             return result
41
42     def Put(self, request, context):
43         filename = "kv_"+request.key
44         value = "{0}\n\nWritten from plugin-python".format(request.value)
45         with open(filename, 'w') as f:
46             f.write(value)
47
48         return kv_pb2.Empty()
49
50 ```
51
52 Great! With that, we have a fully functioning implementation of the service.
53 You can test this using standard gRPC testing mechanisms.
54
55 ## 2. Serve the Service
56
57 Next, we need to create a gRPC server and serve the service we just made.
58
59 In Python:
60
61 ```python
62 # Make the server
63 server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
64
65 # Add our service
66 kv_pb2_grpc.add_KVServicer_to_server(KVServicer(), server)
67
68 # Listen on a port
69 server.add_insecure_port(':1234')
70
71 # Start
72 server.start()
73 ```
74
75 You can listen on any TCP address or Unix domain socket. go-plugin does
76 assume that connections are reliable (local), so you should not serve
77 your plugin across the network.
78
79 ## 3. Add the gRPC Health Checking Service
80
81 go-plugin requires the
82 [gRPC Health Checking Service](https://github.com/grpc/grpc/blob/master/doc/health-checking.md)
83 to be registered on your server. You must register the status of "plugin" to be SERVING.
84
85 The health checking service is used by go-plugin to determine if everything
86 is healthy with the connection. If you don't implement this service, your
87 process may be abruptly restarted and your plugins are likely to be unreliable.
88
89 ```
90 health = HealthServicer()
91 health.set("plugin", health_pb2.HealthCheckResponse.ServingStatus.Value('SERVING'))
92 health_pb2_grpc.add_HealthServicer_to_server(health, server)
93 ```
94
95 ## 4. Output Handshake Information
96
97 The final step is to output the handshake information to stdout. go-plugin
98 reads a single line from stdout to determine how to connect to your plugin,
99 what protocol it is using, etc.
100
101
102 The structure is:
103
104 ```
105 CORE-PROTOCOL-VERSION | APP-PROTOCOL-VERSION | NETWORK-TYPE | NETWORK-ADDR | PROTOCOL
106 ```
107
108 Where:
109
110   * `CORE-PROTOCOL-VERSION` is the protocol version for go-plugin itself.
111     The current value is `1`. Please use this value. Any other value will
112     cause your plugin to not load.
113
114   * `APP-PROTOCOL-VERSION` is the protocol version for the application data.
115     This is determined by the application. You must reference the documentation
116     for your application to determine the desired value.
117
118   * `NETWORK-TYPE` and `NETWORK-ADDR` are the networking information for
119     connecting to this plugin. The type must be "unix" or "tcp". The address
120     is a path to the Unix socket for "unix" and an IP address for "tcp".
121
122   * `PROTOCOL` is the named protocol that the connection will use. If this
123     is omitted (older versions), this is "netrpc" for Go net/rpc. This can
124     also be "grpc". This is the protocol that the plugin wants to speak to
125     the host process with.
126
127 For our example that is:
128
129 ```
130 1|1|tcp|127.0.0.1:1234|grpc
131 ```
132
133 The only element you'll have to be careful about is the second one (the
134 `APP-PROTOCOL-VERISON`). This will depend on the application you're
135 building a plugin for. Please reference their documentation for more
136 information.
137
138 ## 5. Done!
139
140 And we're done!
141
142 Configure the host application (the application you're writing a plugin
143 for) to execute your Python application. Configuring plugins is specific
144 to the host application.
145
146 For our example, we used an environmental variable, and it looks like this:
147
148 ```sh
149 $ export KV_PLUGIN="python plugin.py"
150 ```