Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove race around local-exec Wait #11554

Merged
merged 2 commits into from
Feb 1, 2017
Merged

Conversation

jbardin
Copy link
Member

@jbardin jbardin commented Jan 31, 2017

There was still a race around the local-exec Command, where we were
calling Wait in 2 places which you can't do. There's no need for the
extra goroutine however, since we now have a context that we can pass to
the command itself.

Copy link
Contributor

@mitchellh mitchellh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Didn't realize they added that API. :)

@jbardin jbardin force-pushed the jbardin/local-exec-context branch 11 times, most recently from 95da56d to 9c5b300 Compare January 31, 2017 22:08
There was still a race around the local-exec Command, where we were
calling Wait in 2 places which you can't do.
@jbardin
Copy link
Member Author

jbardin commented Jan 31, 2017

Tests were passing locally on macOS. The problem looks like a Go issue on Linux: golang/go#18874

@jbardin
Copy link
Member Author

jbardin commented Jan 31, 2017

It appears this is completely broken, and we can't Wait on canceled process on Linux right now. This was only working before by returning the wrong error and leaving the process running.

Copy link
Contributor

@mitchellh mitchellh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor thing. LGTM


multiWriter := io.MultiWriter(output, pw)

// now we need an os.Pipe to pump the outout on Linux
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add the link to the Go issue here so we know when we can remove it.

If the shell spawns a subprocess which doesn't close the output file
descriptors, the exec.Cmd will block on Wait() (see
golang.org/issue/18874). Use an os.Pipe to provide the command with a
real file descriptor so the exec package doesn't need to do the copy
manually. This in turn may block our own reading goroutine, but we can
select on that and leave it for cleanup later.
@jbardin
Copy link
Member Author

jbardin commented Feb 1, 2017

Turns out it's not a Linux problem, it just showed up on Linux as /bin/sh there is often symlinked to /bin/dash, and dash always starts a subprocess for commands whereas bash will exec single commands in the same process. I changed the test to make this fail the same way on all systems.

Having the process output to an os.Pipe prevents the exec package from needing to start goroutines to copy the data manually, and shifts the blocked Read into our own code. This lets us conditionally select on the copy goroutine finishing or the context expiring.

@mitchellh: pushed a cleaner much fix to look at

Copy link
Contributor

@mitchellh mitchellh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, LGTM

@jbardin jbardin merged commit 9c1775a into master Feb 1, 2017
@jbardin jbardin deleted the jbardin/local-exec-context branch February 1, 2017 17:39
@ghost
Copy link

ghost commented Apr 17, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants