diff --git a/commands.go b/commands.go index cd91d07cf..a66e4fb82 100644 --- a/commands.go +++ b/commands.go @@ -3,7 +3,6 @@ package docker import ( "bytes" "encoding/json" - "errors" "fmt" "github.com/dotcloud/docker/auth" "github.com/dotcloud/docker/rcli" @@ -132,7 +131,7 @@ func (srv *Server) CmdLogin(stdin io.ReadCloser, stdout io.Writer, args ...strin password = readString(stdin, stdout) if password == "" { - return errors.New("Error : Password Required\n") + return fmt.Errorf("Error : Password Required") } fmt.Fprint(stdout, "Email (", srv.runtime.authConfig.Email, "): ") @@ -171,7 +170,7 @@ func (srv *Server) CmdWait(stdin io.ReadCloser, stdout io.Writer, args ...string if container := srv.runtime.Get(name); container != nil { fmt.Fprintln(stdout, container.Wait()) } else { - return errors.New("No such container: " + name) + return fmt.Errorf("No such container: %s", name) } } return nil @@ -223,7 +222,7 @@ func (srv *Server) CmdStop(stdin io.ReadCloser, stdout io.Writer, args ...string } fmt.Fprintln(stdout, container.Id) } else { - return errors.New("No such container: " + name) + return fmt.Errorf("No such container: %s", name) } } return nil @@ -245,7 +244,7 @@ func (srv *Server) CmdRestart(stdin io.ReadCloser, stdout io.Writer, args ...str } fmt.Fprintln(stdout, container.Id) } else { - return errors.New("No such container: " + name) + return fmt.Errorf("No such container: %s", name) } } return nil @@ -267,7 +266,7 @@ func (srv *Server) CmdStart(stdin io.ReadCloser, stdout io.Writer, args ...strin } fmt.Fprintln(stdout, container.Id) } else { - return errors.New("No such container: " + name) + return fmt.Errorf("No such container: %s", name) } } return nil @@ -320,7 +319,7 @@ func (srv *Server) CmdPort(stdin io.ReadCloser, stdout io.Writer, args ...string name := cmd.Arg(0) privatePort := cmd.Arg(1) if container := srv.runtime.Get(name); container == nil { - return errors.New("No such container: " + name) + return fmt.Errorf("No such container: %s", name) } else { if frontend, exists := container.NetworkSettings.PortMapping[privatePort]; !exists { return fmt.Errorf("No private port '%s' allocated on %s", privatePort, name) @@ -383,7 +382,7 @@ func (srv *Server) CmdRm(stdin io.ReadCloser, stdout io.Writer, args ...string) for _, name := range cmd.Args() { container := srv.runtime.Get(name) if container == nil { - return errors.New("No such container: " + name) + return fmt.Errorf("No such container: %s", name) } if err := srv.runtime.Destroy(container); err != nil { fmt.Fprintln(stdout, "Error destroying container "+name+": "+err.Error()) @@ -401,7 +400,7 @@ func (srv *Server) CmdKill(stdin io.ReadCloser, stdout io.Writer, args ...string for _, name := range cmd.Args() { container := srv.runtime.Get(name) if container == nil { - return errors.New("No such container: " + name) + return fmt.Errorf("No such container: %s", name) } if err := container.Kill(); err != nil { fmt.Fprintln(stdout, "Error killing container "+name+": "+err.Error()) @@ -420,7 +419,7 @@ func (srv *Server) CmdImport(stdin io.ReadCloser, stdout io.Writer, args ...stri } src := cmd.Arg(0) if src == "" { - return errors.New("Not enough arguments") + return fmt.Errorf("Not enough arguments") } else if src == "-" { archive = stdin } else { @@ -718,7 +717,7 @@ func (srv *Server) CmdExport(stdin io.ReadCloser, stdout io.Writer, args ...stri } return nil } - return errors.New("No such container: " + name) + return fmt.Errorf("No such container: %s", name) } func (srv *Server) CmdDiff(stdin io.ReadCloser, stdout io.Writer, args ...string) error { @@ -729,10 +728,10 @@ func (srv *Server) CmdDiff(stdin io.ReadCloser, stdout io.Writer, args ...string return nil } if cmd.NArg() < 1 { - return errors.New("Not enough arguments") + return fmt.Errorf("Not enough arguments") } if container := srv.runtime.Get(cmd.Arg(0)); container == nil { - return errors.New("No such container") + return fmt.Errorf("No such container") } else { changes, err := container.Changes() if err != nil { @@ -774,7 +773,7 @@ func (srv *Server) CmdLogs(stdin io.ReadCloser, stdout io.Writer, args ...string } return nil } - return errors.New("No such container: " + cmd.Arg(0)) + return fmt.Errorf("No such container: %s", cmd.Arg(0)) } func (srv *Server) CmdAttach(stdin io.ReadCloser, stdout io.Writer, args ...string) error { @@ -789,7 +788,7 @@ func (srv *Server) CmdAttach(stdin io.ReadCloser, stdout io.Writer, args ...stri name := cmd.Arg(0) container := srv.runtime.Get(name) if container == nil { - return errors.New("No such container: " + name) + return fmt.Errorf("No such container: %s", name) } var wg sync.WaitGroup if container.Config.OpenStdin { @@ -798,20 +797,35 @@ func (srv *Server) CmdAttach(stdin io.ReadCloser, stdout io.Writer, args ...stri return err } wg.Add(1) - go func() { io.Copy(cStdin, stdin); wg.Add(-1) }() + go func() { + Debugf("Begin stdin pipe [attach]") + io.Copy(cStdin, stdin) + wg.Add(-1) + Debugf("End of stdin pipe [attach]") + }() } cStdout, err := container.StdoutPipe() if err != nil { return err } wg.Add(1) - go func() { io.Copy(stdout, cStdout); wg.Add(-1) }() + go func() { + Debugf("Begin stdout pipe [attach]") + io.Copy(stdout, cStdout) + wg.Add(-1) + Debugf("End of stdout pipe [attach]") + }() cStderr, err := container.StderrPipe() if err != nil { return err } wg.Add(1) - go func() { io.Copy(stdout, cStderr); wg.Add(-1) }() + go func() { + Debugf("Begin stderr pipe [attach]") + io.Copy(stdout, cStderr) + wg.Add(-1) + Debugf("End of stderr pipe [attach]") + }() wg.Wait() return nil } diff --git a/container.go b/container.go index 629af3a03..d128ce98d 100644 --- a/container.go +++ b/container.go @@ -2,7 +2,6 @@ package docker import ( "encoding/json" - "errors" "fmt" "github.com/dotcloud/docker/rcli" "github.com/kr/pty" @@ -41,9 +40,7 @@ type Container struct { stdin io.ReadCloser stdinPipe io.WriteCloser - stdoutLog *os.File - stderrLog *os.File - runtime *Runtime + runtime *Runtime } type Config struct { @@ -165,12 +162,16 @@ func (container *Container) startPty() error { // Copy the PTYs to our broadcasters go func() { defer container.stdout.Close() + Debugf("[startPty] Begin of stdout pipe") io.Copy(container.stdout, stdoutMaster) + Debugf("[startPty] End of stdout pipe") }() go func() { defer container.stderr.Close() + Debugf("[startPty] Begin of stderr pipe") io.Copy(container.stderr, stderrMaster) + Debugf("[startPty] End of stderr pipe") }() // stdin @@ -186,7 +187,9 @@ func (container *Container) startPty() error { // container.cmd.SysProcAttr = &syscall.SysProcAttr{Setctty: true, Setsid: true} go func() { defer container.stdin.Close() + Debugf("[startPty] Begin of stdin pipe") io.Copy(stdinMaster, container.stdin) + Debugf("[startPty] End of stdin pipe") }() } if err := container.cmd.Start(); err != nil { @@ -210,7 +213,9 @@ func (container *Container) start() error { } go func() { defer stdin.Close() + Debugf("Begin of stdin pipe [start]") io.Copy(stdin, container.stdin) + Debugf("End of stdin pipe [start]") }() } return container.cmd.Start() @@ -356,15 +361,25 @@ func (container *Container) releaseNetwork() error { func (container *Container) monitor() { // Wait for the program to exit - container.cmd.Wait() + Debugf("Waiting for process") + if err := container.cmd.Wait(); err != nil { + // Discard the error as any signals or non 0 returns will generate an error + Debugf("%s: Process: %s", container.Id, err) + } + Debugf("Process finished") + exitCode := container.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() // Cleanup if err := container.releaseNetwork(); err != nil { log.Printf("%v: Failed to release network: %v", container.Id, err) } - container.stdout.Close() - container.stderr.Close() + if err := container.stdout.Close(); err != nil { + Debugf("%s: Error close stdout: %s", container.Id, err) + } + if err := container.stderr.Close(); err != nil { + Debugf("%s: Error close stderr: %s", container.Id, err) + } if err := container.Unmount(); err != nil { log.Printf("%v: Failed to umount filesystem: %v", container.Id, err) } @@ -376,7 +391,9 @@ func (container *Container) monitor() { // Report status back container.State.setStopped(exitCode) - container.ToDisk() + if err := container.ToDisk(); err != nil { + log.Printf("%s: Failed to dump configuration to the disk: %s", container.Id, err) + } } func (container *Container) kill() error { @@ -461,7 +478,7 @@ func (container *Container) WaitTimeout(timeout time.Duration) error { select { case <-time.After(timeout): - return errors.New("Timed Out") + return fmt.Errorf("Timed Out") case <-done: return nil }