diff --git a/Gopkg.lock b/Gopkg.lock index 27de95555..7780e6a8b 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -225,14 +225,14 @@ revision = "ca137eb4b4389c9bc6f1a6d887f056bf16c00510" [[projects]] - digest = "1:143aae8d04a6133eea9c6400b90a1f47ae1100b48a1636160aba861d1b26c5b2" + digest = "1:980fd2c6afd6c268284d46dd66671771184a4002f6d516492cc596d2ca003543" name = "github.com/hashicorp/go-plugin" packages = [ ".", "internal/plugin", ] pruneopts = "NUT" - revision = "3f118e8ee104b6f22aeb12453fab56aed1356186" + revision = "a1bc61569a26c0f65865932c0d55743b0567c494" [[projects]] branch = "master" diff --git a/Gopkg.toml b/Gopkg.toml index 39874975f..3a2fb8c94 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -115,7 +115,7 @@ [[constraint]] name = "github.com/hashicorp/go-plugin" - revision = "3f118e8ee104b6f22aeb12453fab56aed1356186" + revision = "a1bc61569a26c0f65865932c0d55743b0567c494" [[constraint]] name = "github.com/golang/protobuf" diff --git a/vendor/github.com/hashicorp/go-plugin/client.go b/vendor/github.com/hashicorp/go-plugin/client.go index 2a8b42fc3..bc56559c6 100644 --- a/vendor/github.com/hashicorp/go-plugin/client.go +++ b/vendor/github.com/hashicorp/go-plugin/client.go @@ -87,6 +87,10 @@ type Client struct { // goroutines. clientWaitGroup sync.WaitGroup + // stderrWaitGroup is used to prevent the command's Wait() function from + // being called before we've finished reading from the stderr pipe. + stderrWaitGroup sync.WaitGroup + // processKilled is used for testing only, to flag when the process was // forcefully killed. processKilled bool @@ -590,6 +594,12 @@ func (c *Client) Start() (addr net.Addr, err error) { // Create a context for when we kill c.doneCtx, c.ctxCancel = context.WithCancel(context.Background()) + // Start goroutine that logs the stderr + c.clientWaitGroup.Add(1) + c.stderrWaitGroup.Add(1) + // logStderr calls Done() + go c.logStderr(cmdStderr) + c.clientWaitGroup.Add(1) go func() { // ensure the context is cancelled when we're done @@ -602,6 +612,10 @@ func (c *Client) Start() (addr net.Addr, err error) { pid := c.process.Pid path := cmd.Path + // wait to finish reading from stderr since the stderr pipe reader + // will be closed by the subsequent call to cmd.Wait(). + c.stderrWaitGroup.Wait() + // Wait for the command to end. err := cmd.Wait() @@ -624,11 +638,6 @@ func (c *Client) Start() (addr net.Addr, err error) { c.exited = true }() - // Start goroutine that logs the stderr - c.clientWaitGroup.Add(1) - // logStderr calls Done() - go c.logStderr(cmdStderr) - // Start a goroutine that is going to be reading the lines // out of stdout linesCh := make(chan string) @@ -936,6 +945,7 @@ var stdErrBufferSize = 64 * 1024 func (c *Client) logStderr(r io.Reader) { defer c.clientWaitGroup.Done() + defer c.stderrWaitGroup.Done() l := c.logger.Named(filepath.Base(c.config.Cmd.Path)) reader := bufio.NewReaderSize(r, stdErrBufferSize) @@ -973,7 +983,22 @@ func (c *Client) logStderr(r io.Reader) { entry, err := parseJSON(line) // If output is not JSON format, print directly to Debug if err != nil { - l.Debug(string(line)) + // Attempt to infer the desired log level from the commonly used + // string prefixes + switch line := string(line); { + case strings.HasPrefix(line, "[TRACE]"): + l.Trace(line) + case strings.HasPrefix(line, "[DEBUG]"): + l.Debug(line) + case strings.HasPrefix(line, "[INFO]"): + l.Info(line) + case strings.HasPrefix(line, "[WARN]"): + l.Warn(line) + case strings.HasPrefix(line, "[ERROR]"): + l.Error(line) + default: + l.Debug(line) + } } else { out := flattenKVPairs(entry.KVPairs) @@ -989,6 +1014,11 @@ func (c *Client) logStderr(r io.Reader) { l.Warn(entry.Message, out...) case hclog.Error: l.Error(entry.Message, out...) + default: + // if there was no log level, it's likely this is unexpected + // json from something other than hclog, and we should output + // it verbatim. + l.Debug(string(line)) } } } diff --git a/vendor/github.com/hashicorp/go-plugin/server.go b/vendor/github.com/hashicorp/go-plugin/server.go index fc9f05a9f..4c230e3ab 100644 --- a/vendor/github.com/hashicorp/go-plugin/server.go +++ b/vendor/github.com/hashicorp/go-plugin/server.go @@ -363,14 +363,34 @@ func serverListener() (net.Listener, error) { } func serverListener_tcp() (net.Listener, error) { - minPort, err := strconv.ParseInt(os.Getenv("PLUGIN_MIN_PORT"), 10, 32) - if err != nil { - return nil, err + envMinPort := os.Getenv("PLUGIN_MIN_PORT") + envMaxPort := os.Getenv("PLUGIN_MAX_PORT") + + var minPort, maxPort int64 + var err error + + switch { + case len(envMinPort) == 0: + minPort = 0 + default: + minPort, err = strconv.ParseInt(envMinPort, 10, 32) + if err != nil { + return nil, fmt.Errorf("Couldn't get value from PLUGIN_MIN_PORT: %v", err) + } } - maxPort, err := strconv.ParseInt(os.Getenv("PLUGIN_MAX_PORT"), 10, 32) - if err != nil { - return nil, err + switch { + case len(envMaxPort) == 0: + maxPort = 0 + default: + maxPort, err = strconv.ParseInt(envMaxPort, 10, 32) + if err != nil { + return nil, fmt.Errorf("Couldn't get value from PLUGIN_MAX_PORT: %v", err) + } + } + + if minPort > maxPort { + return nil, fmt.Errorf("ENV_MIN_PORT value of %d is greater than PLUGIN_MAX_PORT value of %d", minPort, maxPort) } for port := minPort; port <= maxPort; port++ {