diff --git a/pkg/kubelet/dockertools/manager.go b/pkg/kubelet/dockertools/manager.go index 0e511710efe..0244e761ba8 100644 --- a/pkg/kubelet/dockertools/manager.go +++ b/pkg/kubelet/dockertools/manager.go @@ -17,7 +17,6 @@ limitations under the License. package dockertools import ( - "bufio" "bytes" "errors" "fmt" @@ -904,20 +903,16 @@ func (dm *DockerManager) RunInContainer(containerID string, cmd []string) ([]byt return nil, fmt.Errorf("failed to run in container - Exec setup failed - %v", err) } var buf bytes.Buffer - wrBuf := bufio.NewWriter(&buf) startOpts := docker.StartExecOptions{ Detach: false, Tty: false, - OutputStream: wrBuf, - ErrorStream: wrBuf, + OutputStream: &buf, + ErrorStream: &buf, RawTerminal: false, } - errChan := make(chan error, 1) - go func() { - errChan <- dm.client.StartExec(execObj.ID, startOpts) - }() - wrBuf.Flush() - return buf.Bytes(), <-errChan + err = dm.client.StartExec(execObj.ID, startOpts) + + return buf.Bytes(), err } // ExecInContainer uses nsenter to run the command inside the container identified by containerID. diff --git a/pkg/probe/exec/exec.go b/pkg/probe/exec/exec.go index a34db08508b..ce1858d0542 100644 --- a/pkg/probe/exec/exec.go +++ b/pkg/probe/exec/exec.go @@ -43,7 +43,7 @@ func (pr execProber) Probe(e uexec.Cmd) (probe.Result, error) { if err != nil { return probe.Unknown, err } - if strings.ToLower(string(data)) != defaultHealthyOutput { + if !strings.HasPrefix(strings.ToLower(string(data)), defaultHealthyOutput) { return probe.Failure, nil } return probe.Success, nil diff --git a/test/e2e/pods.go b/test/e2e/pods.go index 4eb38deb20b..383472d3a93 100644 --- a/test/e2e/pods.go +++ b/test/e2e/pods.go @@ -34,7 +34,7 @@ import ( . "github.com/onsi/gomega" ) -func runLivenessTest(c *client.Client, podDescr *api.Pod) { +func runLivenessTest(c *client.Client, podDescr *api.Pod, expectRestart bool) { ns := "e2e-test-" + string(util.NewUUID()) By(fmt.Sprintf("Creating pod %s in namespace %s", podDescr.Name, ns)) @@ -62,7 +62,7 @@ func runLivenessTest(c *client.Client, podDescr *api.Pod) { By(fmt.Sprintf("Initial restart count of pod %s is %d", podDescr.Name, initialRestartCount)) // Wait for at most 48 * 5 = 240s = 4 minutes until restartCount is incremented - pass := false + restarts := false for i := 0; i < 48; i++ { // Wait until restartCount is incremented. time.Sleep(5 * time.Second) @@ -72,13 +72,13 @@ func runLivenessTest(c *client.Client, podDescr *api.Pod) { By(fmt.Sprintf("Restart count of pod %s in namespace %s is now %d", podDescr.Name, ns, restartCount)) if restartCount > initialRestartCount { By(fmt.Sprintf("Restart count of pod %s in namespace %s increased from %d to %d during the test", podDescr.Name, ns, initialRestartCount, restartCount)) - pass = true + restarts = true break } } - if !pass { - Fail(fmt.Sprintf("Did not see the restart count of pod %s in namespace %s increase from %d during the test", podDescr.Name, ns, initialRestartCount)) + if restarts != expectRestart { + Fail(fmt.Sprintf("pod %s in namespace %s - expected restarts: %v, found restarts: %v", podDescr.Name, ns, expectRestart, restarts)) } } @@ -433,7 +433,33 @@ var _ = Describe("Pods", func() { }, }, }, - }) + }, true) + }) + + It("should *not* be restarted with a docker exec \"cat /tmp/health\" liveness probe", func() { + runLivenessTest(c, &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: "liveness-exec", + Labels: map[string]string{"test": "liveness"}, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "liveness", + Image: "gcr.io/google_containers/busybox", + Command: []string{"/bin/sh", "-c", "echo ok >/tmp/health; sleep 600"}, + LivenessProbe: &api.Probe{ + Handler: api.Handler{ + Exec: &api.ExecAction{ + Command: []string{"cat", "/tmp/health"}, + }, + }, + InitialDelaySeconds: 15, + }, + }, + }, + }, + }, false) }) It("should be restarted with a /healthz http liveness probe", func() { @@ -460,7 +486,7 @@ var _ = Describe("Pods", func() { }, }, }, - }) + }, true) }) // The following tests for remote command execution and port forwarding are