Switch exec to look at exit code not output status.
This commit is contained in:
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -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:
|
||||
|
@@ -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")
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user