06c5fd36 (openshift-install: log debug output to file, 2018-11-15, #689),
the global logrus level has been TraceLevel. Decisions about logging
to a particular target are now made when adding the hook for that
target. This broke our Terraform debug approach, which had been based
on the level for the global logger. Since 06c5fd36, logrus.GetLevel()
== logrus.DebugLevel will never be true.
With this commit, I've replaced that switch and now just push all
Terraform stdout into the default logger at the debug level. A new
LinePrinter provides a shim between Terraform's stdout stream and the
line-based log calls.
I've added a local buffer for stderr, because Run [1] doesn't collect
it automatically like Output does [2].
LinePrinter.Lock protects us from parallel writes, because [3]:
The slice is valid for use only until the next buffer modification
(that is, only until the next call to a method like Read, Write,
Reset, or Truncate).
The docs aren't clear about whether that limitation applies to
ReadString or not [4], but the backing implementation has no internal
lock to protect from changes made before the internal reference is
copied into a new slice [5]. We're unlikely to actually have parallel
writes for our Terraform use-case, but I'd rather be conservative now
and not have to track down a race if someone decides to use
LinePrinter for something concurrent later.
The mutex is embedded at Alex's recommendation [6].
[1]: https://golang.org/pkg/os/exec/#Cmd.Run
[2]: https://golang.org/pkg/os/exec/#Cmd.Output
[3]: https://golang.org/pkg/bytes/#Buffer.Bytes
[4]: https://golang.org/pkg/bytes/#Buffer.ReadString
[5]: https://github.com/golang/go/blob/go1.11.2/src/bytes/buffer.go#L416-L439
[6]: https://github.com/openshift/installer/pull/730#discussion_r237304411