Merge pull request #3726 from vieux/attach_stderr

don't user os.Stderr in attach
This commit is contained in:
Victor Vieux 2014-01-24 10:55:55 -08:00
commit 56ec121925
3 changed files with 24 additions and 22 deletions

12
api.go
View File

@ -169,9 +169,7 @@ func getContainersExport(srv *Server, version float64, w http.ResponseWriter, r
return fmt.Errorf("Missing parameter") return fmt.Errorf("Missing parameter")
} }
job := srv.Eng.Job("export", vars["name"]) job := srv.Eng.Job("export", vars["name"])
if err := job.Stdout.Add(w); err != nil { job.Stdout.Add(w)
return err
}
if err := job.Run(); err != nil { if err := job.Run(); err != nil {
return err 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") w.Header().Set("Content-Type", "application/x-tar")
} }
job := srv.Eng.Job("image_export", vars["name"]) job := srv.Eng.Job("image_export", vars["name"])
if err := job.Stdout.Add(w); err != nil { job.Stdout.Add(w)
return err
}
return job.Run() 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.Setenv("stderr", r.Form.Get("stderr"))
job.Stdin.Add(inStream) job.Stdin.Add(inStream)
job.Stdout.Add(outStream) job.Stdout.Add(outStream)
job.Stderr.Add(errStream) job.Stderr.Set(errStream)
if err := job.Run(); err != nil { if err := job.Run(); err != nil {
fmt.Fprintf(outStream, "Error: %s\n", err) 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.Setenv("stderr", r.Form.Get("stderr"))
job.Stdin.Add(ws) job.Stdin.Add(ws)
job.Stdout.Add(ws) job.Stdout.Add(ws)
job.Stderr.Add(ws) job.Stderr.Set(ws)
if err := job.Run(); err != nil { if err := job.Run(); err != nil {
utils.Errorf("Error: %s", err) utils.Errorf("Error: %s", err)
} }

View File

@ -23,20 +23,28 @@ func NewOutput() *Output {
// Return true if something was written on this output // Return true if something was written on this output
func (o *Output) Used() bool { func (o *Output) Used() bool {
o.Mutex.Lock() o.Lock()
defer o.Mutex.Unlock() defer o.Unlock()
return o.used return o.used
} }
// Add attaches a new destination to the Output. Any data subsequently written // 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. // to the output will be written to the new destination in addition to all the others.
// This method is thread-safe. // This method is thread-safe.
// FIXME: Add cannot fail func (o *Output) Add(dst io.Writer) {
func (o *Output) Add(dst io.Writer) error { o.Lock()
o.Mutex.Lock() defer o.Unlock()
defer o.Mutex.Unlock()
o.dests = append(o.dests, dst) 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.Lock()
defer o.Unlock()
o.dests = []io.Writer{dst}
} }
// AddPipe creates an in-memory pipe with io.Pipe(), adds its writing end as a destination, // AddPipe creates an in-memory pipe with io.Pipe(), adds its writing end as a destination,
@ -88,8 +96,8 @@ func (o *Output) AddString(dst *string) error {
// Write writes the same data to all registered destinations. // Write writes the same data to all registered destinations.
// This method is thread-safe. // This method is thread-safe.
func (o *Output) Write(p []byte) (n int, err error) { func (o *Output) Write(p []byte) (n int, err error) {
o.Mutex.Lock() o.Lock()
defer o.Mutex.Unlock() defer o.Unlock()
o.used = true o.used = true
var firstErr error var firstErr error
for _, dst := range o.dests { for _, dst := range o.dests {
@ -105,8 +113,8 @@ func (o *Output) Write(p []byte) (n int, err error) {
// AddTail and AddString tasks to complete. // AddTail and AddString tasks to complete.
// The Close method of each destination is called if it exists. // The Close method of each destination is called if it exists.
func (o *Output) Close() error { func (o *Output) Close() error {
o.Mutex.Lock() o.Lock()
defer o.Mutex.Unlock() defer o.Unlock()
var firstErr error var firstErr error
for _, dst := range o.dests { for _, dst := range o.dests {
if closer, ok := dst.(io.WriteCloser); ok { if closer, ok := dst.(io.WriteCloser); ok {

View File

@ -95,9 +95,7 @@ func TestOutputAddEnv(t *testing.T) {
func TestOutputAddClose(t *testing.T) { func TestOutputAddClose(t *testing.T) {
o := NewOutput() o := NewOutput()
var s sentinelWriteCloser var s sentinelWriteCloser
if err := o.Add(&s); err != nil { o.Add(&s)
t.Fatal(err)
}
if err := o.Close(); err != nil { if err := o.Close(); err != nil {
t.Fatal(err) t.Fatal(err)
} }