communicator/winrm: fix data race in io copy
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 ================== ```
This commit is contained in:
parent
ead4865b7f
commit
9cbaacad32
|
@ -7,6 +7,7 @@ import (
|
|||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/communicator/remote"
|
||||
|
@ -148,10 +149,20 @@ func (c *Communicator) Start(rc *remote.Cmd) error {
|
|||
func runCommand(shell *winrm.Shell, cmd *winrm.Command, rc *remote.Cmd) {
|
||||
defer shell.Close()
|
||||
|
||||
go io.Copy(rc.Stdout, cmd.Stdout)
|
||||
go io.Copy(rc.Stderr, cmd.Stderr)
|
||||
var wg sync.WaitGroup
|
||||
go func() {
|
||||
wg.Add(1)
|
||||
io.Copy(rc.Stdout, cmd.Stdout)
|
||||
wg.Done()
|
||||
}()
|
||||
go func() {
|
||||
wg.Add(1)
|
||||
io.Copy(rc.Stderr, cmd.Stderr)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
cmd.Wait()
|
||||
wg.Wait()
|
||||
rc.SetExited(cmd.ExitCode())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue