mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Add a stdincloser to container.Attach in order to close the client connection when needed
This commit is contained in:
parent
43484e8b50
commit
6882c78ce4
3 changed files with 39 additions and 16 deletions
16
commands.go
16
commands.go
|
@ -799,7 +799,8 @@ func (srv *Server) CmdAttach(stdin io.ReadCloser, stdout io.Writer, args ...stri
|
|||
if container == nil {
|
||||
return fmt.Errorf("No such container: %s", name)
|
||||
}
|
||||
return <-container.Attach(stdin, stdout, stdout)
|
||||
|
||||
return <-container.Attach(stdin, nil, stdout, stdout)
|
||||
}
|
||||
|
||||
// Ports type - Used to parse multiple -p flags
|
||||
|
@ -901,11 +902,17 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
}
|
||||
}
|
||||
var (
|
||||
cStdin io.Reader
|
||||
cStdin io.ReadCloser
|
||||
cStdout, cStderr io.Writer
|
||||
)
|
||||
if config.AttachStdin {
|
||||
cStdin = stdin
|
||||
r, w := io.Pipe()
|
||||
go func() {
|
||||
defer w.Close()
|
||||
defer Debugf("Closing buffered stdin pipe")
|
||||
io.Copy(w, stdin)
|
||||
}()
|
||||
cStdin = r
|
||||
}
|
||||
if config.AttachStdout {
|
||||
cStdout = stdout
|
||||
|
@ -913,7 +920,8 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
if config.AttachStderr {
|
||||
cStderr = stdout // FIXME: rcli can't differentiate stdout from stderr
|
||||
}
|
||||
attachErr := container.Attach(cStdin, cStdout, cStderr)
|
||||
|
||||
attachErr := container.Attach(cStdin, stdin, cStdout, cStderr)
|
||||
Debugf("Starting\n")
|
||||
if err := container.Start(); err != nil {
|
||||
return err
|
||||
|
|
|
@ -93,9 +93,7 @@ func TestRunExit(t *testing.T) {
|
|||
stdout, stdoutPipe := io.Pipe()
|
||||
c1 := make(chan struct{})
|
||||
go func() {
|
||||
if err := srv.CmdRun(stdin, stdoutPipe, "-i", GetTestImage(runtime).Id, "/bin/cat"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
srv.CmdRun(stdin, stdoutPipe, "-i", GetTestImage(runtime).Id, "/bin/cat")
|
||||
close(c1)
|
||||
}()
|
||||
|
||||
|
@ -123,11 +121,8 @@ func TestRunExit(t *testing.T) {
|
|||
|
||||
// Make sure that the client has been disconnected
|
||||
setTimeout(t, "The client should have been disconnected once the remote process exited.", 2*time.Second, func() {
|
||||
if _, err := stdin.Read([]byte{}); err != nil {
|
||||
if err != io.EOF {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
// Expecting pipe i/o error, just check that read does not block
|
||||
stdin.Read([]byte{})
|
||||
})
|
||||
|
||||
// Cleanup pipes
|
||||
|
@ -293,6 +288,7 @@ func TestAttachDisconnect(t *testing.T) {
|
|||
setTimeout(t, "Waiting for CmdAttach timed out", 2*time.Second, func() {
|
||||
<-c1
|
||||
})
|
||||
|
||||
// We closed stdin, expect /bin/cat to still be running
|
||||
// Wait a little bit to make sure container.monitor() did his thing
|
||||
err = container.WaitTimeout(500 * time.Millisecond)
|
||||
|
|
27
container.go
27
container.go
|
@ -257,9 +257,9 @@ func (container *Container) start() error {
|
|||
return container.cmd.Start()
|
||||
}
|
||||
|
||||
func (container *Container) Attach(stdin io.Reader, stdout io.Writer, stderr io.Writer) chan error {
|
||||
var cStdout io.ReadCloser
|
||||
var cStderr io.ReadCloser
|
||||
func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, stdout io.Writer, stderr io.Writer) chan error {
|
||||
var cStdout, cStderr io.ReadCloser
|
||||
|
||||
var nJobs int
|
||||
errors := make(chan error, 3)
|
||||
if stdin != nil && container.Config.OpenStdin {
|
||||
|
@ -277,7 +277,8 @@ func (container *Container) Attach(stdin io.Reader, stdout io.Writer, stderr io.
|
|||
if err != nil {
|
||||
Debugf("[error] attach stdout: %s\n", err)
|
||||
}
|
||||
errors <- err
|
||||
// Discard error, expecting pipe error
|
||||
errors <- nil
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
@ -290,6 +291,15 @@ func (container *Container) Attach(stdin io.Reader, stdout io.Writer, stderr io.
|
|||
go func() {
|
||||
Debugf("[start] attach stdout\n")
|
||||
defer Debugf("[end] attach stdout\n")
|
||||
// If we are in StdinOnce mode, then close stdin
|
||||
if container.Config.StdinOnce {
|
||||
if stdin != nil {
|
||||
defer stdin.Close()
|
||||
}
|
||||
if stdinCloser != nil {
|
||||
defer stdinCloser.Close()
|
||||
}
|
||||
}
|
||||
_, err := io.Copy(stdout, cStdout)
|
||||
if err != nil {
|
||||
Debugf("[error] attach stdout: %s\n", err)
|
||||
|
@ -307,6 +317,15 @@ func (container *Container) Attach(stdin io.Reader, stdout io.Writer, stderr io.
|
|||
go func() {
|
||||
Debugf("[start] attach stderr\n")
|
||||
defer Debugf("[end] attach stderr\n")
|
||||
// If we are in StdinOnce mode, then close stdin
|
||||
if container.Config.StdinOnce {
|
||||
if stdin != nil {
|
||||
defer stdin.Close()
|
||||
}
|
||||
if stdinCloser != nil {
|
||||
defer stdinCloser.Close()
|
||||
}
|
||||
}
|
||||
_, err := io.Copy(stderr, cStderr)
|
||||
if err != nil {
|
||||
Debugf("[error] attach stderr: %s\n", err)
|
||||
|
|
Loading…
Add table
Reference in a new issue