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

Various exec fixes #13322

Merged
2 commits merged into from
Sep 4, 2015
Merged

Various exec fixes #13322

2 commits merged into from
Sep 4, 2015

Conversation

ncdc
Copy link
Member

@ncdc ncdc commented Aug 28, 2015

If stdin is noninteractive, the io.Copy from stdin to remoteStdin will
unblock when it finishes reading from stdin. In this case, make sure to
close remoteStdin so the server knows the client won't be sending any
more data. This ensures that the remote process terminates. For example:

echo foo | kubectl exec -i <pod> -- cat

Without this change, the cat process never terminates and kubectl exec hangs.

Fix interactive exec sessions hanging after you type 'exit'.

Add e2e test to cover noninteractive stdin: echo a | kubectl exec -i <pod> cat

Add e2e test to cover psuedo-interactive stdin: kubectl exec -i <pod> bash

Prep for sending multiple data frames over multiple streams in remote command
test, which is more likely to find flakes (requires bump of spdystream
once an issue with the frame worker queues not being fully drained when
a goaway frame is received).

Fixes #13394
Fixes #13395

Release note info
Fixed hanging when using non-interactive stdin data, e.g. echo foo | kubectl exec -i <pod> -- cat
Fixed interactive kubectl exec sessions hanging after you type 'exit'

@ncdc
Copy link
Member Author

ncdc commented Aug 28, 2015

By("executing a command in the container with noninteractive stdin")
execOutput = newKubectlCommand("exec", fmt.Sprintf("--namespace=%v", ns), "-i", simplePodName, "cat").
withStdinData("abcd1234").
exec()
Copy link
Member

Choose a reason for hiding this comment

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

+1 for tests for this scenario

Copy link
Member

Choose a reason for hiding this comment

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

actually, it would be easy to add a withStdin(io.Reader) helper so we could also test an interactive exec with a stdin that sends "echo hello\nexit\n", then blocks

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea. I'll definitely want to add that. Once I figure out why interactive is broken...

Copy link
Member Author

Choose a reason for hiding this comment

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

Blocks via select {} or something else?

Copy link
Member

Choose a reason for hiding this comment

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

@@ -194,12 +194,19 @@ func (e *Streamer) doStream() error {
if err != nil {
return err
}
defer remoteStdin.Reset()
Copy link
Member

Choose a reason for hiding this comment

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

don't you still need the deferred remoteStdin.Reset() in the case where the remoteStdin cp never completes, or does the conn.Close() cover that?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll check and see, but it's broken until #13324 lands. I can test w/that locally.

Copy link
Member

Choose a reason for hiding this comment

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

actually, I'm surprised the remote connection was being held open with the deferred Reset() in place previously

Copy link
Member Author

Choose a reason for hiding this comment

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

It's a bit of a chicken and egg game. With this scenario:

echo foo | kubectl exec -i <pod> cat

The cat command won't terminate until it gets EOF from its stdin. Its stdin comes from the spdy stream. The spdy stream gets its stdin from the non interactive input (echo foo). While foo is fully read and closed, doStream won't exit until cat is done, but we aren't resetting remoteStdin until doStream exits, etc etc etc. This makes sure that remoteStdin gets closed/reset as soon as the copy unblocks. Make sense?

Copy link
Member

Choose a reason for hiding this comment

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

interesting, the cp essentially "intercepts" the EOF, so the remote command never sees it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, assuming I merged and rebuilt everything locally correctly, trying to exit an interactive shell is hanging. Grrr....

Copy link
Member

Choose a reason for hiding this comment

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

the deferred remoteStdin.Close() in the goroutine makes sense, but I would keep the deferred Reset() in place

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, added it back.

@k8s-bot
Copy link

k8s-bot commented Aug 28, 2015

GCE e2e build/test passed for commit 969e3dc30b424732e00ff500e045a02d24f1ca9c.

@ncdc ncdc force-pushed the fix-noninteractive-stdin-exec branch from 969e3dc to 51681c1 Compare August 28, 2015 21:05
@k8s-bot
Copy link

k8s-bot commented Aug 28, 2015

GCE e2e build/test failed for commit 51681c18fd7e08d6b27dc848ca97b87a9d7a28fa.

@k8s-github-robot k8s-github-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Sep 2, 2015
@k8s-github-robot
Copy link

Labelling this PR as size/M

@ncdc
Copy link
Member Author

ncdc commented Sep 2, 2015

@liggitt @smarterclayton PR updated. I think I've finally gotten there...

@k8s-github-robot k8s-github-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Sep 2, 2015
@k8s-github-robot
Copy link

Labelling this PR as size/L

@liggitt
Copy link
Member

liggitt commented Sep 2, 2015

LGTM... the additional e2e tests give me a lot more confidence

@k8s-bot
Copy link

k8s-bot commented Sep 2, 2015

GCE e2e build/test passed for commit bfab798919aa7db3b0603be882dc077cb0d4f47c.

@ncdc
Copy link
Member Author

ncdc commented Sep 2, 2015

And e2e passed, woot!

@ncdc ncdc changed the title Ensure remote stdin stream is closed Various exec fixes Sep 2, 2015
@ncdc
Copy link
Member Author

ncdc commented Sep 2, 2015

... oh, for a previous commit. Guess we'll wait a bit longer

@k8s-bot
Copy link

k8s-bot commented Sep 2, 2015

GCE e2e build/test passed for commit 57d4df45975382f754102f5e194e787b2c0c06da.

@k8s-bot
Copy link

k8s-bot commented Sep 2, 2015

GCE e2e build/test failed for commit addece6f95d290f0d62f32591db6a73b683d0dc1.

@ncdc
Copy link
Member Author

ncdc commented Sep 2, 2015

e2e failure looks like flakes:

[Fail] Services [It] should serve multiport endpoints from pods 
/go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/test/e2e/service.go:1147

[Fail] Services [It] should serve a basic endpoint from pods 
/go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/test/e2e/service.go:1147

[Fail] Services [It] should be able to up and down services 
/go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/test/e2e/service.go:247

@k8s-bot test this please

@k8s-bot
Copy link

k8s-bot commented Sep 2, 2015

GCE e2e build/test passed for commit addece6f95d290f0d62f32591db6a73b683d0dc1.

@brendandburns brendandburns removed their assignment Sep 3, 2015
Andy Goldstein added 2 commits September 4, 2015 10:40
If stdin is noninteractive, the io.Copy from stdin to remoteStdin will
unblock when it finishes reading from stdin. In this case, make sure to
close remoteStdin so the server knows the client won't be sending any
more data. This ensures that the remote process terminates. For example:

echo foo | kubectl exec -i <pod> -- cat

Without this change, the `cat` process never terminates and `kubectl
exec` hangs.

Fix interactive exec sessions hanging after you type 'exit'.

Add e2e test to cover noninteractive stdin: `echo a | kubectl exec -i <pod>
cat`

Add e2e test to cover psuedo-interactive stdin: `kubectl exec -i <pod> bash`

Prep for sending multiple data frames over multiple streams in remote command
test, which is more likely to find flakes (requires bump of spdystream
once an issue with the frame worker queues not being fully drained when
a goaway frame is received).
@ncdc ncdc force-pushed the fix-noninteractive-stdin-exec branch from addece6 to c837869 Compare September 4, 2015 14:41
@k8s-bot
Copy link

k8s-bot commented Sep 4, 2015

GCE e2e build/test failed for commit c837869.

@ncdc
Copy link
Member Author

ncdc commented Sep 4, 2015

e2e flake

Fetching upstream changes from https://github.com/kubernetes/kubernetes
 > git --version # timeout=10
 > git -c core.askpass=true fetch --tags --progress https://github.com/kubernetes/kubernetes +refs/pull/*:refs/remotes/origin/pr/* --prune
ERROR: Error fetching remote repo 'origin'
hudson.plugins.git.GitException: Failed to fetch from https://github.com/kubernetes/kubernetes
    at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:763)
    at hudson.plugins.git.GitSCM.retrieveChanges(GitSCM.java:1012)
    at hudson.plugins.git.GitSCM.checkout(GitSCM.java:1043)
    at hudson.scm.SCM.checkout(SCM.java:485)
    at hudson.model.AbstractProject.checkout(AbstractProject.java:1277)
    at hudson.model.AbstractBuild$AbstractBuildExecution.defaultCheckout(AbstractBuild.java:610)
    at jenkins.scm.SCMCheckoutStrategy.checkout(SCMCheckoutStrategy.java:86)
    at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:532)
    at hudson.model.Run.execute(Run.java:1741)
    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
    at hudson.model.ResourceController.execute(ResourceController.java:98)
    at hudson.model.Executor.run(Executor.java:381)
Caused by: hudson.plugins.git.GitException: Command "git -c core.askpass=true fetch --tags --progress https://github.com/kubernetes/kubernetes +refs/pull/*:refs/remotes/origin/pr/* --prune" returned status code 128:
stdout: 
stderr: error: The requested URL returned error: 403 while accessing https://github.com/kubernetes/kubernetes/info/refs
fatal: HTTP request failed

    at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:1600)
    at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandWithCredentials(CliGitAPIImpl.java:1363)
    at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.access$300(CliGitAPIImpl.java:61)
    at org.jenkinsci.plugins.gitclient.CliGitAPIImpl$1.execute(CliGitAPIImpl.java:299)
    at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:761)
    ... 11 more

@k8s-bot test this please

@liggitt
Copy link
Member

liggitt commented Sep 4, 2015

wondering how to kick what appears to be a hung e2e... @k8s-bot test this again please?

@k8s-bot
Copy link

k8s-bot commented Sep 4, 2015

GCE e2e build/test passed for commit c837869.

@ncdc
Copy link
Member Author

ncdc commented Sep 4, 2015

Woot :-)

@smarterclayton smarterclayton added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 4, 2015
ghost pushed a commit that referenced this pull request Sep 4, 2015
@ghost ghost merged commit c324fdd into kubernetes:master Sep 4, 2015
@ncdc ncdc added the release-note Denotes a PR that will be considered when it comes time to generate release notes. label Sep 11, 2015
@ncdc ncdc deleted the fix-noninteractive-stdin-exec branch February 13, 2017 17:25
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
7 participants