|
@@ -6,6 +6,7 @@ import (
|
|
"bytes"
|
|
"bytes"
|
|
"encoding/base64"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"encoding/json"
|
|
|
|
+ "errors"
|
|
"flag"
|
|
"flag"
|
|
"fmt"
|
|
"fmt"
|
|
"github.com/dotcloud/docker/auth"
|
|
"github.com/dotcloud/docker/auth"
|
|
@@ -36,6 +37,10 @@ var (
|
|
VERSION string
|
|
VERSION string
|
|
)
|
|
)
|
|
|
|
|
|
|
|
+var (
|
|
|
|
+ ErrConnectionRefused = errors.New("Can't connect to docker daemon. Is 'docker -d' running on this host?")
|
|
|
|
+)
|
|
|
|
+
|
|
func (cli *DockerCli) getMethod(name string) (reflect.Method, bool) {
|
|
func (cli *DockerCli) getMethod(name string) (reflect.Method, bool) {
|
|
methodName := "Cmd" + strings.ToUpper(name[:1]) + strings.ToLower(name[1:])
|
|
methodName := "Cmd" + strings.ToUpper(name[:1]) + strings.ToLower(name[1:])
|
|
return reflect.TypeOf(cli).MethodByName(methodName)
|
|
return reflect.TypeOf(cli).MethodByName(methodName)
|
|
@@ -1256,7 +1261,7 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
|
|
|
|
|
|
if container.Config.Tty {
|
|
if container.Config.Tty {
|
|
if err := cli.monitorTtySize(cmd.Arg(0)); err != nil {
|
|
if err := cli.monitorTtySize(cmd.Arg(0)); err != nil {
|
|
- return err
|
|
|
|
|
|
+ utils.Debugf("Error monitoring tty size: %s", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1565,12 +1570,12 @@ func (cli *DockerCli) CmdRun(args ...string) error {
|
|
// Detached mode
|
|
// Detached mode
|
|
<-wait
|
|
<-wait
|
|
} else {
|
|
} else {
|
|
- status, err := waitForExit(cli, runResult.ID)
|
|
|
|
|
|
+ status, err := getExitCode(cli, runResult.ID)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
if status != 0 {
|
|
if status != 0 {
|
|
- return &utils.StatusError{status}
|
|
|
|
|
|
+ return &utils.StatusError{Status: status}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1636,7 +1641,7 @@ func (cli *DockerCli) call(method, path string, data interface{}) ([]byte, int,
|
|
dial, err := net.Dial(cli.proto, cli.addr)
|
|
dial, err := net.Dial(cli.proto, cli.addr)
|
|
if err != nil {
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "connection refused") {
|
|
if strings.Contains(err.Error(), "connection refused") {
|
|
- return nil, -1, fmt.Errorf("Can't connect to docker daemon. Is 'docker -d' running on this host?")
|
|
|
|
|
|
+ return nil, -1, ErrConnectionRefused
|
|
}
|
|
}
|
|
return nil, -1, err
|
|
return nil, -1, err
|
|
}
|
|
}
|
|
@@ -1645,7 +1650,7 @@ func (cli *DockerCli) call(method, path string, data interface{}) ([]byte, int,
|
|
defer clientconn.Close()
|
|
defer clientconn.Close()
|
|
if err != nil {
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "connection refused") {
|
|
if strings.Contains(err.Error(), "connection refused") {
|
|
- return nil, -1, fmt.Errorf("Can't connect to docker daemon. Is 'docker -d' running on this host?")
|
|
|
|
|
|
+ return nil, -1, ErrConnectionRefused
|
|
}
|
|
}
|
|
return nil, -1, err
|
|
return nil, -1, err
|
|
}
|
|
}
|
|
@@ -1864,7 +1869,11 @@ func (cli *DockerCli) LoadConfigFile() (err error) {
|
|
func waitForExit(cli *DockerCli, containerId string) (int, error) {
|
|
func waitForExit(cli *DockerCli, containerId string) (int, error) {
|
|
body, _, err := cli.call("POST", "/containers/"+containerId+"/wait", nil)
|
|
body, _, err := cli.call("POST", "/containers/"+containerId+"/wait", nil)
|
|
if err != nil {
|
|
if err != nil {
|
|
- return -1, err
|
|
|
|
|
|
+ // If we can't connect, then the daemon probably died.
|
|
|
|
+ if err != ErrConnectionRefused {
|
|
|
|
+ return -1, err
|
|
|
|
+ }
|
|
|
|
+ return -1, nil
|
|
}
|
|
}
|
|
|
|
|
|
var out APIWait
|
|
var out APIWait
|
|
@@ -1874,6 +1883,22 @@ func waitForExit(cli *DockerCli, containerId string) (int, error) {
|
|
return out.StatusCode, nil
|
|
return out.StatusCode, nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func getExitCode(cli *DockerCli, containerId string) (int, error) {
|
|
|
|
+ body, _, err := cli.call("GET", "/containers/"+containerId+"/json", nil)
|
|
|
|
+ if err != nil {
|
|
|
|
+ // If we can't connect, then the daemon probably died.
|
|
|
|
+ if err != ErrConnectionRefused {
|
|
|
|
+ return -1, err
|
|
|
|
+ }
|
|
|
|
+ return -1, nil
|
|
|
|
+ }
|
|
|
|
+ c := &Container{}
|
|
|
|
+ if err := json.Unmarshal(body, c); err != nil {
|
|
|
|
+ return -1, err
|
|
|
|
+ }
|
|
|
|
+ return c.State.ExitCode, nil
|
|
|
|
+}
|
|
|
|
+
|
|
func NewDockerCli(in io.ReadCloser, out, err io.Writer, proto, addr string) *DockerCli {
|
|
func NewDockerCli(in io.ReadCloser, out, err io.Writer, proto, addr string) *DockerCli {
|
|
var (
|
|
var (
|
|
isTerminal = false
|
|
isTerminal = false
|