From c44f513248a8b40b1b2221726c7441881383e919 Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Mon, 6 Apr 2015 12:19:38 -0700 Subject: [PATCH] Remove engine usage from attach Signed-off-by: Alexander Morozov --- api/server/server.go | 44 ++++++++--------------- builder/internals.go | 2 +- daemon/attach.go | 86 +++++++++++++++----------------------------- daemon/daemon.go | 1 - daemon/exec.go | 2 +- 5 files changed, 44 insertions(+), 91 deletions(-) diff --git a/api/server/server.go b/api/server/server.go index 502f1ae9e1..95642f992d 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -904,16 +904,12 @@ func postContainersAttach(eng *engine.Engine, version version.Version, w http.Re return fmt.Errorf("Missing parameter") } - var ( - job = eng.Job("container_inspect", vars["name"]) - c, err = job.Stdout.AddEnv() - ) + d := getDaemon(eng) + + cont, err := d.Get(vars["name"]) if err != nil { return err } - if err = job.Run(); err != nil { - return err - } inStream, outStream, err := hijackServer(w) if err != nil { @@ -929,25 +925,17 @@ func postContainersAttach(eng *engine.Engine, version version.Version, w http.Re fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n") } - if c.GetSubEnv("Config") != nil && !c.GetSubEnv("Config").GetBool("Tty") && version.GreaterThanOrEqualTo("1.6") { + if !cont.Config.Tty && version.GreaterThanOrEqualTo("1.6") { errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr) outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout) } else { errStream = outStream } + logs := r.Form.Get("logs") != "" + stream := r.Form.Get("stream") != "" - job = eng.Job("attach", vars["name"]) - job.Setenv("logs", r.Form.Get("logs")) - job.Setenv("stream", r.Form.Get("stream")) - job.Setenv("stdin", r.Form.Get("stdin")) - job.Setenv("stdout", r.Form.Get("stdout")) - job.Setenv("stderr", r.Form.Get("stderr")) - job.Stdin.Add(inStream) - job.Stdout.Add(outStream) - job.Stderr.Set(errStream) - if err := job.Run(); err != nil { + if err := cont.AttachWithLogs(inStream, outStream, errStream, logs, stream); err != nil { fmt.Fprintf(outStream, "Error attaching: %s\n", err) - } return nil } @@ -959,23 +947,19 @@ func wsContainersAttach(eng *engine.Engine, version version.Version, w http.Resp if vars == nil { return fmt.Errorf("Missing parameter") } + d := getDaemon(eng) - if err := eng.Job("container_inspect", vars["name"]).Run(); err != nil { + cont, err := d.Get(vars["name"]) + if err != nil { return err } h := websocket.Handler(func(ws *websocket.Conn) { defer ws.Close() - job := eng.Job("attach", vars["name"]) - job.Setenv("logs", r.Form.Get("logs")) - job.Setenv("stream", r.Form.Get("stream")) - job.Setenv("stdin", r.Form.Get("stdin")) - job.Setenv("stdout", r.Form.Get("stdout")) - job.Setenv("stderr", r.Form.Get("stderr")) - job.Stdin.Add(ws) - job.Stdout.Add(ws) - job.Stderr.Set(ws) - if err := job.Run(); err != nil { + logs := r.Form.Get("logs") != "" + stream := r.Form.Get("stream") != "" + + if err := cont.AttachWithLogs(ws, ws, ws, logs, stream); err != nil { logrus.Errorf("Error attaching websocket: %s", err) } }) diff --git a/builder/internals.go b/builder/internals.go index 0ee6f76a60..e0c7987ca1 100644 --- a/builder/internals.go +++ b/builder/internals.go @@ -573,7 +573,7 @@ func (b *Builder) create() (*daemon.Container, error) { func (b *Builder) run(c *daemon.Container) error { var errCh chan error if b.Verbose { - errCh = b.Daemon.Attach(&c.StreamConfig, c.Config.OpenStdin, c.Config.StdinOnce, c.Config.Tty, nil, b.OutStream, b.ErrStream) + errCh = c.Attach(nil, b.OutStream, b.ErrStream) } //start the container diff --git a/daemon/attach.go b/daemon/attach.go index a479c040be..72f38752e1 100644 --- a/daemon/attach.go +++ b/daemon/attach.go @@ -2,57 +2,36 @@ package daemon import ( "encoding/json" - "fmt" "io" "os" "sync" "time" "github.com/Sirupsen/logrus" - "github.com/docker/docker/engine" "github.com/docker/docker/pkg/jsonlog" "github.com/docker/docker/pkg/promise" "github.com/docker/docker/utils" ) -func (daemon *Daemon) ContainerAttach(job *engine.Job) error { - if len(job.Args) != 1 { - return fmt.Errorf("Usage: %s CONTAINER\n", job.Name) - } - - var ( - name = job.Args[0] - logs = job.GetenvBool("logs") - stream = job.GetenvBool("stream") - stdin = job.GetenvBool("stdin") - stdout = job.GetenvBool("stdout") - stderr = job.GetenvBool("stderr") - ) - - container, err := daemon.Get(name) - if err != nil { - return err - } - - //logs +func (c *Container) AttachWithLogs(stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool) error { if logs { - cLog, err := container.ReadLog("json") + cLog, err := c.ReadLog("json") if err != nil && os.IsNotExist(err) { // Legacy logs logrus.Debugf("Old logs format") - if stdout { - cLog, err := container.ReadLog("stdout") + if stdout != nil { + cLog, err := c.ReadLog("stdout") if err != nil { logrus.Errorf("Error reading logs (stdout): %s", err) - } else if _, err := io.Copy(job.Stdout, cLog); err != nil { + } else if _, err := io.Copy(stdout, cLog); err != nil { logrus.Errorf("Error streaming logs (stdout): %s", err) } } - if stderr { - cLog, err := container.ReadLog("stderr") + if stderr != nil { + cLog, err := c.ReadLog("stderr") if err != nil { logrus.Errorf("Error reading logs (stderr): %s", err) - } else if _, err := io.Copy(job.Stderr, cLog); err != nil { + } else if _, err := io.Copy(stderr, cLog); err != nil { logrus.Errorf("Error streaming logs (stderr): %s", err) } } @@ -69,11 +48,11 @@ func (daemon *Daemon) ContainerAttach(job *engine.Job) error { logrus.Errorf("Error streaming logs: %s", err) break } - if l.Stream == "stdout" && stdout { - io.WriteString(job.Stdout, l.Log) + if l.Stream == "stdout" && stdout != nil { + io.WriteString(stdout, l.Log) } - if l.Stream == "stderr" && stderr { - io.WriteString(job.Stderr, l.Log) + if l.Stream == "stderr" && stderr != nil { + io.WriteString(stderr, l.Log) } } } @@ -81,38 +60,29 @@ func (daemon *Daemon) ContainerAttach(job *engine.Job) error { //stream if stream { - var ( - cStdin io.ReadCloser - cStdout, cStderr io.Writer - ) - - if stdin { - r, w := io.Pipe() - go func() { - defer w.Close() - defer logrus.Debugf("Closing buffered stdin pipe") - io.Copy(w, job.Stdin) - }() - cStdin = r - } - if stdout { - cStdout = job.Stdout - } - if stderr { - cStderr = job.Stderr - } - - <-daemon.Attach(&container.StreamConfig, container.Config.OpenStdin, container.Config.StdinOnce, container.Config.Tty, cStdin, cStdout, cStderr) + var stdinPipe io.ReadCloser + r, w := io.Pipe() + go func() { + defer w.Close() + defer logrus.Debugf("Closing buffered stdin pipe") + io.Copy(w, stdin) + }() + stdinPipe = r + <-c.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) + if c.Config.StdinOnce && !c.Config.Tty { + c.WaitStop(-1 * time.Second) } } return nil } -func (daemon *Daemon) Attach(streamConfig *StreamConfig, openStdin, stdinOnce, tty bool, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) chan error { +func (c *Container) Attach(stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) chan error { + return attach(&c.StreamConfig, c.Config.OpenStdin, c.Config.StdinOnce, c.Config.Tty, stdin, stdout, stderr) +} + +func attach(streamConfig *StreamConfig, openStdin, stdinOnce, tty bool, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) chan error { var ( cStdout, cStderr io.ReadCloser cStdin io.WriteCloser diff --git a/daemon/daemon.go b/daemon/daemon.go index a072fc34a4..b2d149183b 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -115,7 +115,6 @@ type Daemon struct { func (daemon *Daemon) Install(eng *engine.Engine) error { // FIXME: remove ImageDelete's dependency on Daemon, then move to graph/ for name, method := range map[string]engine.Handler{ - "attach": daemon.ContainerAttach, "commit": daemon.ContainerCommit, "container_changes": daemon.ContainerChanges, "container_copy": daemon.ContainerCopy, diff --git a/daemon/exec.go b/daemon/exec.go index c5d4461765..f91600da7a 100644 --- a/daemon/exec.go +++ b/daemon/exec.go @@ -218,7 +218,7 @@ func (d *Daemon) ContainerExecStart(job *engine.Job) error { execConfig.StreamConfig.stdinPipe = ioutils.NopWriteCloser(ioutil.Discard) // Silently drop stdin } - attachErr := d.Attach(&execConfig.StreamConfig, execConfig.OpenStdin, true, execConfig.ProcessConfig.Tty, cStdin, cStdout, cStderr) + attachErr := attach(&execConfig.StreamConfig, execConfig.OpenStdin, true, execConfig.ProcessConfig.Tty, cStdin, cStdout, cStderr) execErr := make(chan error)