diff --git a/api.go b/api.go index b45f1a35d1..127ad77603 100644 --- a/api.go +++ b/api.go @@ -169,9 +169,7 @@ func getContainersExport(srv *Server, version float64, w http.ResponseWriter, r return fmt.Errorf("Missing parameter") } job := srv.Eng.Job("export", vars["name"]) - if err := job.Stdout.Add(w); err != nil { - return err - } + job.Stdout.Add(w) if err := job.Run(); err != nil { return err } @@ -573,9 +571,7 @@ func getImagesGet(srv *Server, version float64, w http.ResponseWriter, r *http.R w.Header().Set("Content-Type", "application/x-tar") } job := srv.Eng.Job("image_export", vars["name"]) - if err := job.Stdout.Add(w); err != nil { - return err - } + job.Stdout.Add(w) return job.Run() } @@ -806,7 +802,7 @@ func postContainersAttach(srv *Server, version float64, w http.ResponseWriter, r job.Setenv("stderr", r.Form.Get("stderr")) job.Stdin.Add(inStream) job.Stdout.Add(outStream) - job.Stderr.Add(errStream) + job.Stderr.Set(errStream) if err := job.Run(); err != nil { fmt.Fprintf(outStream, "Error: %s\n", err) @@ -836,7 +832,7 @@ func wsContainersAttach(srv *Server, version float64, w http.ResponseWriter, r * job.Setenv("stderr", r.Form.Get("stderr")) job.Stdin.Add(ws) job.Stdout.Add(ws) - job.Stderr.Add(ws) + job.Stderr.Set(ws) if err := job.Run(); err != nil { utils.Errorf("Error: %s", err) } diff --git a/engine/streams.go b/engine/streams.go index 703a56256d..935334c261 100644 --- a/engine/streams.go +++ b/engine/streams.go @@ -31,12 +31,20 @@ func (o *Output) Used() bool { // Add attaches a new destination to the Output. Any data subsequently written // to the output will be written to the new destination in addition to all the others. // This method is thread-safe. -// FIXME: Add cannot fail -func (o *Output) Add(dst io.Writer) error { +func (o *Output) Add(dst io.Writer) { o.Mutex.Lock() defer o.Mutex.Unlock() o.dests = append(o.dests, dst) - return nil +} + +// Set closes and remove existing destination and then attaches a new destination to +// the Output. Any data subsequently written to the output will be written to the new +// destination in addition to all the others. This method is thread-safe. +func (o *Output) Set(dst io.Writer) { + o.Close() + o.Mutex.Lock() + defer o.Mutex.Unlock() + o.dests = []io.Writer{dst} } // AddPipe creates an in-memory pipe with io.Pipe(), adds its writing end as a destination, diff --git a/engine/streams_test.go b/engine/streams_test.go index 37720c61ea..30d31d2952 100644 --- a/engine/streams_test.go +++ b/engine/streams_test.go @@ -95,9 +95,7 @@ func TestOutputAddEnv(t *testing.T) { func TestOutputAddClose(t *testing.T) { o := NewOutput() var s sentinelWriteCloser - if err := o.Add(&s); err != nil { - t.Fatal(err) - } + o.Add(&s) if err := o.Close(); err != nil { t.Fatal(err) }