diff options
author | David Calavera <david.calavera@gmail.com> | 2015-11-03 12:33:13 -0500 |
---|---|---|
committer | David Calavera <david.calavera@gmail.com> | 2015-11-04 12:27:48 -0500 |
commit | ca5ede2d0a23cb84cac3b863c363d0269e6438df (patch) | |
tree | 401deee3f41f901c3c42e8cdd7a9985e6bc25ce3 /daemon/attach.go | |
parent | 2c72015ce3b78b45e33529368fb1c5a724415d87 (diff) | |
download | docker-ca5ede2d0a23cb84cac3b863c363d0269e6438df.tar.gz |
Decouple daemon and container to log events.
Create a supervisor interface to let the container monitor to emit events.
Signed-off-by: David Calavera <david.calavera@gmail.com>
Diffstat (limited to 'daemon/attach.go')
-rw-r--r-- | daemon/attach.go | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/daemon/attach.go b/daemon/attach.go index 44198788ce..64a1223a4d 100644 --- a/daemon/attach.go +++ b/daemon/attach.go @@ -2,7 +2,10 @@ package daemon import ( "io" + "time" + "github.com/Sirupsen/logrus" + "github.com/docker/docker/daemon/logger" "github.com/docker/docker/pkg/stdcopy" ) @@ -43,7 +46,7 @@ func (daemon *Daemon) ContainerAttachWithLogs(prefixOrName string, c *ContainerA stderr = errStream } - return container.attachWithLogs(stdin, stdout, stderr, c.Logs, c.Stream) + return daemon.attachWithLogs(container, stdin, stdout, stderr, c.Logs, c.Stream) } // ContainerWsAttachWithLogsConfig attach with websockets, since all @@ -60,5 +63,61 @@ func (daemon *Daemon) ContainerWsAttachWithLogs(prefixOrName string, c *Containe if err != nil { return err } - return container.attachWithLogs(c.InStream, c.OutStream, c.ErrStream, c.Logs, c.Stream) + return daemon.attachWithLogs(container, c.InStream, c.OutStream, c.ErrStream, c.Logs, c.Stream) +} + +func (daemon *Daemon) attachWithLogs(container *Container, stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool) error { + if logs { + logDriver, err := container.getLogger() + if err != nil { + return err + } + cLog, ok := logDriver.(logger.LogReader) + if !ok { + return logger.ErrReadLogsNotSupported + } + logs := cLog.ReadLogs(logger.ReadConfig{Tail: -1}) + + LogLoop: + for { + select { + case msg, ok := <-logs.Msg: + if !ok { + break LogLoop + } + if msg.Source == "stdout" && stdout != nil { + stdout.Write(msg.Line) + } + if msg.Source == "stderr" && stderr != nil { + stderr.Write(msg.Line) + } + case err := <-logs.Err: + logrus.Errorf("Error streaming logs: %v", err) + break LogLoop + } + } + } + + daemon.LogContainerEvent(container, "attach") + + //stream + if stream { + var stdinPipe io.ReadCloser + if stdin != nil { + r, w := io.Pipe() + go func() { + defer w.Close() + defer logrus.Debugf("Closing buffered stdin pipe") + io.Copy(w, stdin) + }() + stdinPipe = r + } + <-container.Attach(stdinPipe, stdout, stderr) + // If we are in stdinonce mode, wait for the process to end + // otherwise, simply return + if container.Config.StdinOnce && !container.Config.Tty { + container.WaitStop(-1 * time.Second) + } + } + return nil } |