aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/go-plugin/server.go
diff options
context:
space:
mode:
authorappilon <apilon@hashicorp.com>2019-02-27 16:43:31 -0500
committerGitHub <noreply@github.com>2019-02-27 16:43:31 -0500
commit844b5a68d8af4791755b8f0ad293cc99f5959183 (patch)
tree255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/hashicorp/go-plugin/server.go
parent303b299eeb6b06e939e35905e4b34cb410dd9dc3 (diff)
parent15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (diff)
downloadterraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.gz
terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.zst
terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.zip
Merge pull request #27 from terraform-providers/go-modules-2019-02-22
[MODULES] Switch to Go Modules
Diffstat (limited to 'vendor/github.com/hashicorp/go-plugin/server.go')
-rw-r--r--vendor/github.com/hashicorp/go-plugin/server.go135
1 files changed, 115 insertions, 20 deletions
diff --git a/vendor/github.com/hashicorp/go-plugin/server.go b/vendor/github.com/hashicorp/go-plugin/server.go
index b5c5270..1e808b9 100644
--- a/vendor/github.com/hashicorp/go-plugin/server.go
+++ b/vendor/github.com/hashicorp/go-plugin/server.go
@@ -1,6 +1,8 @@
1package plugin 1package plugin
2 2
3import ( 3import (
4 "crypto/tls"
5 "encoding/base64"
4 "errors" 6 "errors"
5 "fmt" 7 "fmt"
6 "io/ioutil" 8 "io/ioutil"
@@ -11,6 +13,10 @@ import (
11 "runtime" 13 "runtime"
12 "strconv" 14 "strconv"
13 "sync/atomic" 15 "sync/atomic"
16
17 "github.com/hashicorp/go-hclog"
18
19 "google.golang.org/grpc"
14) 20)
15 21
16// CoreProtocolVersion is the ProtocolVersion of the plugin system itself. 22// CoreProtocolVersion is the ProtocolVersion of the plugin system itself.
@@ -45,14 +51,41 @@ type ServeConfig struct {
45 // HandshakeConfig is the configuration that must match clients. 51 // HandshakeConfig is the configuration that must match clients.
46 HandshakeConfig 52 HandshakeConfig
47 53
54 // TLSProvider is a function that returns a configured tls.Config.
55 TLSProvider func() (*tls.Config, error)
56
48 // Plugins are the plugins that are served. 57 // Plugins are the plugins that are served.
49 Plugins map[string]Plugin 58 Plugins map[string]Plugin
59
60 // GRPCServer should be non-nil to enable serving the plugins over
61 // gRPC. This is a function to create the server when needed with the
62 // given server options. The server options populated by go-plugin will
63 // be for TLS if set. You may modify the input slice.
64 //
65 // Note that the grpc.Server will automatically be registered with
66 // the gRPC health checking service. This is not optional since go-plugin
67 // relies on this to implement Ping().
68 GRPCServer func([]grpc.ServerOption) *grpc.Server
69
70 // Logger is used to pass a logger into the server. If none is provided the
71 // server will create a default logger.
72 Logger hclog.Logger
73}
74
75// Protocol returns the protocol that this server should speak.
76func (c *ServeConfig) Protocol() Protocol {
77 result := ProtocolNetRPC
78 if c.GRPCServer != nil {
79 result = ProtocolGRPC
80 }
81
82 return result
50} 83}
51 84
52// Serve serves the plugins given by ServeConfig. 85// Serve serves the plugins given by ServeConfig.
53// 86//
54// Serve doesn't return until the plugin is done being executed. Any 87// Serve doesn't return until the plugin is done being executed. Any
55// errors will be outputted to the log. 88// errors will be outputted to os.Stderr.
56// 89//
57// This is the method that plugins should call in their main() functions. 90// This is the method that plugins should call in their main() functions.
58func Serve(opts *ServeConfig) { 91func Serve(opts *ServeConfig) {
@@ -77,6 +110,16 @@ func Serve(opts *ServeConfig) {
77 // Logging goes to the original stderr 110 // Logging goes to the original stderr
78 log.SetOutput(os.Stderr) 111 log.SetOutput(os.Stderr)
79 112
113 logger := opts.Logger
114 if logger == nil {
115 // internal logger to os.Stderr
116 logger = hclog.New(&hclog.LoggerOptions{
117 Level: hclog.Trace,
118 Output: os.Stderr,
119 JSONFormat: true,
120 })
121 }
122
80 // Create our new stdout, stderr files. These will override our built-in 123 // Create our new stdout, stderr files. These will override our built-in
81 // stdout/stderr so that it works across the stream boundary. 124 // stdout/stderr so that it works across the stream boundary.
82 stdout_r, stdout_w, err := os.Pipe() 125 stdout_r, stdout_w, err := os.Pipe()
@@ -93,30 +136,86 @@ func Serve(opts *ServeConfig) {
93 // Register a listener so we can accept a connection 136 // Register a listener so we can accept a connection
94 listener, err := serverListener() 137 listener, err := serverListener()
95 if err != nil { 138 if err != nil {
96 log.Printf("[ERR] plugin: plugin init: %s", err) 139 logger.Error("plugin init error", "error", err)
97 return 140 return
98 } 141 }
99 defer listener.Close() 142
143 // Close the listener on return. We wrap this in a func() on purpose
144 // because the "listener" reference may change to TLS.
145 defer func() {
146 listener.Close()
147 }()
148
149 var tlsConfig *tls.Config
150 if opts.TLSProvider != nil {
151 tlsConfig, err = opts.TLSProvider()
152 if err != nil {
153 logger.Error("plugin tls init", "error", err)
154 return
155 }
156 }
100 157
101 // Create the channel to tell us when we're done 158 // Create the channel to tell us when we're done
102 doneCh := make(chan struct{}) 159 doneCh := make(chan struct{})
103 160
104 // Create the RPC server to dispense 161 // Build the server type
105 server := &RPCServer{ 162 var server ServerProtocol
106 Plugins: opts.Plugins, 163 switch opts.Protocol() {
107 Stdout: stdout_r, 164 case ProtocolNetRPC:
108 Stderr: stderr_r, 165 // If we have a TLS configuration then we wrap the listener
109 DoneCh: doneCh, 166 // ourselves and do it at that level.
167 if tlsConfig != nil {
168 listener = tls.NewListener(listener, tlsConfig)
169 }
170
171 // Create the RPC server to dispense
172 server = &RPCServer{
173 Plugins: opts.Plugins,
174 Stdout: stdout_r,
175 Stderr: stderr_r,
176 DoneCh: doneCh,
177 }
178
179 case ProtocolGRPC:
180 // Create the gRPC server
181 server = &GRPCServer{
182 Plugins: opts.Plugins,
183 Server: opts.GRPCServer,
184 TLS: tlsConfig,
185 Stdout: stdout_r,
186 Stderr: stderr_r,
187 DoneCh: doneCh,
188 }
189
190 default:
191 panic("unknown server protocol: " + opts.Protocol())
110 } 192 }
111 193
194 // Initialize the servers
195 if err := server.Init(); err != nil {
196 logger.Error("protocol init", "error", err)
197 return
198 }
199
200 // Build the extra configuration
201 extra := ""
202 if v := server.Config(); v != "" {
203 extra = base64.StdEncoding.EncodeToString([]byte(v))
204 }
205 if extra != "" {
206 extra = "|" + extra
207 }
208
209 logger.Debug("plugin address", "network", listener.Addr().Network(), "address", listener.Addr().String())
210
112 // Output the address and service name to stdout so that core can bring it up. 211 // Output the address and service name to stdout so that core can bring it up.
113 log.Printf("[DEBUG] plugin: plugin address: %s %s\n", 212 fmt.Printf("%d|%d|%s|%s|%s%s\n",
114 listener.Addr().Network(), listener.Addr().String())
115 fmt.Printf("%d|%d|%s|%s\n",
116 CoreProtocolVersion, 213 CoreProtocolVersion,
117 opts.ProtocolVersion, 214 opts.ProtocolVersion,
118 listener.Addr().Network(), 215 listener.Addr().Network(),
119 listener.Addr().String()) 216 listener.Addr().String(),
217 opts.Protocol(),
218 extra)
120 os.Stdout.Sync() 219 os.Stdout.Sync()
121 220
122 // Eat the interrupts 221 // Eat the interrupts
@@ -127,9 +226,7 @@ func Serve(opts *ServeConfig) {
127 for { 226 for {
128 <-ch 227 <-ch
129 newCount := atomic.AddInt32(&count, 1) 228 newCount := atomic.AddInt32(&count, 1)
130 log.Printf( 229 logger.Debug("plugin received interrupt signal, ignoring", "count", newCount)
131 "[DEBUG] plugin: received interrupt signal (count: %d). Ignoring.",
132 newCount)
133 } 230 }
134 }() 231 }()
135 232
@@ -137,10 +234,8 @@ func Serve(opts *ServeConfig) {
137 os.Stdout = stdout_w 234 os.Stdout = stdout_w
138 os.Stderr = stderr_w 235 os.Stderr = stderr_w
139 236
140 // Serve 237 // Accept connections and wait for completion
141 go server.Accept(listener) 238 go server.Serve(listener)
142
143 // Wait for the graceful exit
144 <-doneCh 239 <-doneCh
145} 240}
146 241