Fixes#3605 and adds the functionality suggested in PR #7440.
This PR is using a different appraoch that (IMHO) feels cleaner and (even more important) adds support for Windows at the same time.
Without a seed, the "random" script path locations for the remote-exec
provisioner were actually deterministic!
Every rand.Int31() would return the same pseudorandom chain starting w/
the numbers: 1298498081, 2019727887, 1427131847, 939984059, ...
So here we properly seed the communicators so the script paths are
actually random, and multiple runs on a single remote host have much
less chance of clobbering each other.
Fixes#4186
Kudos to @DustinChaloupka for the correct hunch leading to this fix!
As the command completes, the winrm.Command does not wait for its copy of
the remote.Command streams to report itself completed.
This adds an additional sync.WaitGroup to ensure that copy is finished up
before moving on, solving the data race.
Fixes the following data race:
```
==================
WARNING: DATA RACE
Read by goroutine 6:
github.com/hashicorp/terraform/communicator/winrm.TestStart()
/Users/phinze/go/src/github.com/hashicorp/terraform/communicator/winrm/communicator_test.go:79 +0xa44
testing.tRunner()
/private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:456 +0xdc
Previous write by goroutine 14:
bytes.(*Buffer).ReadFrom()
/private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/bytes/buffer.go:174 +0x465
io.copyBuffer()
/private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/io/io.go:375 +0x1a5
io.Copy()
/private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/io/io.go:351 +0x78
Goroutine 6 (running) created at:
testing.RunTests()
/private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:561 +0xaa3
testing.(*M).Run()
/private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:494 +0xe4
main.main()
github.com/hashicorp/terraform/communicator/winrm/_test/_testmain.go:62 +0x20f
Goroutine 14 (finished) created at:
github.com/hashicorp/terraform/communicator/winrm.runCommand()
/Users/phinze/go/src/github.com/hashicorp/terraform/communicator/winrm/communicator.go:151 +0xf8
==================
```
We've been moving away from config fields expecting file paths that
Terraform will load, instead prefering fields that expect file contents,
leaning on `file()` to do loading from a path.
This helps with consistency and also flexibility - since this makes it
easier to shift sensitive files into environment variables.
Here we add a little helper package to manage the transitional period
for these fields where we support both behaviors.
Also included is the first of several fields being shifted over - SSH
private keys in provisioner connection config.
We're moving to new field names so the behavior is more intuitive, so
instead of `key_file` it's `private_key` now.
Additional field shifts will be included in follow up PRs so they can be
reviewed and discussed individually.
On connections where no second hop is made, there's no problem if the
agent forwarding connection is denied, so we shouldn't treat that as a
fatal error.
In the SSH client configuration, we had SSH Agent authentication listed
before the static PrivateKey loaded from the `key_file` setting.
Switching the default of the `agent` setting exposed the fact that the
SSH agent overrides the `key_file` during the handshake. By listing the
`key_file` first, we catch the provided key before any query goes out to
the agent.
Adds a key-based authentication SSH test to cover this new behavior. It
fails without the reordering on any machine with an SSH agent running.
Fixes#2614
* adds `bastion_*` fields to `connection` which add configuration for a
bastion host
* if `bastion_host` is set, connect to that host first, then jump
through it to make the SSH connection to `host`
* enables SSH Agent forwarding by default
This changes SSH Agent utilization from opt-in to opt-out, bringing
Terraform in line with the behavior of Packer and the `ssh` command
itself.
But skip SSH agent connections if the SSH_AUTH_SOCK env var doesn't exist,
whcih means there's no agent to connect to.
I added a debug log line in the last commit, only to find out it’s now
logging the same info twice. So removed the double entry and tweaked
the existing once.
While fixing the vet warning also tried to improve any feedback by
showing the actual output/error instead of just the error code.
While testing this I noticed only adding stderr output is not enough as
not all error info is send to stderr, but sometimes also to stdout.
Pretty nice test coverage this way, covering all WinRM actions/logic by
using the winrmtest package. I had to extend/update/fix that package a
little here and there, but it now serves a nice purpose for testing
WinRM stuff…
* We now return an error when you set the script_path to
C:\Windows\Temp explaining this is currently not supported
* The fix in PR #1588 is converted to the updated setup in this PR
including the unit tests
Last thing to do is add a few tests for the WinRM communicator…
This is needed as preperation for adding WinRM support. There is still
one error in the tests which needs another look, but other than that it
seems like were now ready to start working on the WinRM part…