Switch exec to look at exit code not output status.

This commit is contained in:
Brendan Burns
2015-05-08 09:48:31 -07:00
parent 35c644a45f
commit c9324e6e38
8 changed files with 98 additions and 12 deletions

View File

@@ -65,6 +65,7 @@ type DockerInterface interface {
Info() (*docker.Env, error)
CreateExec(docker.CreateExecOptions) (*docker.Exec, error)
StartExec(string, docker.StartExecOptions) error
InspectExec(id string) (*docker.ExecInspect, error)
}
// KubeletContainerName encapsulates a pod name and a Kubernetes container name.

View File

@@ -45,6 +45,7 @@ type FakeDockerClient struct {
RemovedImages util.StringSet
VersionInfo docker.Env
Information docker.Env
ExecInspect *docker.ExecInspect
}
func (f *FakeDockerClient) ClearCalls() {
@@ -285,6 +286,10 @@ func (f *FakeDockerClient) StartExec(_ string, _ docker.StartExecOptions) error
return nil
}
func (f *FakeDockerClient) InspectExec(id string) (*docker.ExecInspect, error) {
return f.ExecInspect, f.popError("inspect_exec")
}
func (f *FakeDockerClient) ListImages(opts docker.ListImagesOptions) ([]docker.APIImages, error) {
err := f.popError("list_images")
return f.Images, err

View File

@@ -153,3 +153,11 @@ func (in instrumentedDockerInterface) StartExec(startExec string, opts docker.St
}()
return in.client.StartExec(startExec, opts)
}
func (in instrumentedDockerInterface) InspectExec(id string) (*docker.ExecInspect, error) {
start := time.Now()
defer func() {
metrics.DockerOperationsLatency.WithLabelValues("inspect_exec").Observe(metrics.SinceInMicroseconds(start))
}()
return in.client.InspectExec(id)
}

View File

@@ -28,6 +28,7 @@ import (
"strconv"
"strings"
"sync"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/capabilities"
@@ -894,10 +895,47 @@ func (dm *DockerManager) RunInContainer(containerID string, cmd []string) ([]byt
RawTerminal: false,
}
err = dm.client.StartExec(execObj.ID, startOpts)
if err != nil {
return nil, err
}
tick := time.Tick(2 * time.Second)
for {
inspect, err2 := dm.client.InspectExec(execObj.ID)
if err2 != nil {
return buf.Bytes(), err2
}
if !inspect.Running {
if inspect.ExitCode != 0 {
err = &dockerExitError{inspect}
}
break
}
<-tick
}
return buf.Bytes(), err
}
type dockerExitError struct {
Inspect *docker.ExecInspect
}
func (d *dockerExitError) String() string {
return d.Error()
}
func (d *dockerExitError) Error() string {
return fmt.Sprintf("Error executing in Docker Container: %d", d.Inspect.ExitCode)
}
func (d *dockerExitError) Exited() bool {
return !d.Inspect.Running
}
func (d *dockerExitError) ExitStatus() int {
return d.Inspect.ExitCode
}
// ExecInContainer uses nsenter to run the command inside the container identified by containerID.
//
// TODO:

View File

@@ -619,3 +619,12 @@ func TestProbeContainer(t *testing.T) {
}
}
}
func TestIsAExitError(t *testing.T) {
var err error
err = &dockerExitError{nil}
_, ok := err.(uexec.ExitError)
if !ok {
t.Error("couldn't cast dockerExitError to exec.ExitError")
}
}