From 13934b618c8183d9bc0daf3a6bd9d1af05238886 Mon Sep 17 00:00:00 2001 From: Boaz Shuster Date: Wed, 17 May 2017 15:30:51 +0300 Subject: [PATCH] Add container environment variables correctly to the health check The health check process doesn't have all the environment varialbes in the container or has them set incorrectly. This patch should fix that problem. Signed-off-by: Boaz Shuster (cherry picked from commit 5836d86ac4d617e837d94010aa60384648ab59ea) Signed-off-by: Eli Uriegas --- components/engine/daemon/health.go | 26 +++++++++++-------- .../integration-cli/docker_cli_health_test.go | 23 ++++++++++++++++ 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/components/engine/daemon/health.go b/components/engine/daemon/health.go index caa8db8447f..48cf4c4255b 100644 --- a/components/engine/daemon/health.go +++ b/components/engine/daemon/health.go @@ -64,31 +64,35 @@ type cmdProbe struct { // exec the healthcheck command in the container. // Returns the exit code and probe output (if any) -func (p *cmdProbe) run(ctx context.Context, d *Daemon, container *container.Container) (*types.HealthcheckResult, error) { - - cmdSlice := strslice.StrSlice(container.Config.Healthcheck.Test)[1:] +func (p *cmdProbe) run(ctx context.Context, d *Daemon, cntr *container.Container) (*types.HealthcheckResult, error) { + cmdSlice := strslice.StrSlice(cntr.Config.Healthcheck.Test)[1:] if p.shell { - cmdSlice = append(getShell(container.Config), cmdSlice...) + cmdSlice = append(getShell(cntr.Config), cmdSlice...) } entrypoint, args := d.getEntrypointAndArgs(strslice.StrSlice{}, cmdSlice) execConfig := exec.NewConfig() execConfig.OpenStdin = false execConfig.OpenStdout = true execConfig.OpenStderr = true - execConfig.ContainerID = container.ID + execConfig.ContainerID = cntr.ID execConfig.DetachKeys = []byte{} execConfig.Entrypoint = entrypoint execConfig.Args = args execConfig.Tty = false execConfig.Privileged = false - execConfig.User = container.Config.User - execConfig.Env = container.Config.Env + execConfig.User = cntr.Config.User + + linkedEnv, err := d.setupLinkedContainers(cntr) + if err != nil { + return nil, err + } + execConfig.Env = container.ReplaceOrAppendEnvValues(cntr.CreateDaemonEnvironment(execConfig.Tty, linkedEnv), execConfig.Env) - d.registerExecCommand(container, execConfig) - d.LogContainerEvent(container, "exec_create: "+execConfig.Entrypoint+" "+strings.Join(execConfig.Args, " ")) + d.registerExecCommand(cntr, execConfig) + d.LogContainerEvent(cntr, "exec_create: "+execConfig.Entrypoint+" "+strings.Join(execConfig.Args, " ")) output := &limitedBuffer{} - err := d.ContainerExecStart(ctx, execConfig.ID, nil, output, output) + err = d.ContainerExecStart(ctx, execConfig.ID, nil, output, output) if err != nil { return nil, err } @@ -97,7 +101,7 @@ func (p *cmdProbe) run(ctx context.Context, d *Daemon, container *container.Cont return nil, err } if info.ExitCode == nil { - return nil, fmt.Errorf("Healthcheck for container %s has no exit code!", container.ID) + return nil, fmt.Errorf("Healthcheck for container %s has no exit code!", cntr.ID) } // Note: Go's json package will handle invalid UTF-8 for us out := output.String() diff --git a/components/engine/integration-cli/docker_cli_health_test.go b/components/engine/integration-cli/docker_cli_health_test.go index 3e9d048f891..0f78a41d872 100644 --- a/components/engine/integration-cli/docker_cli_health_test.go +++ b/components/engine/integration-cli/docker_cli_health_test.go @@ -139,3 +139,26 @@ func (s *DockerSuite) TestHealth(c *check.C) { c.Check(out, checker.Equals, "[CMD cat /my status]\n") } + +// Github #33021 +func (s *DockerSuite) TestUnsetEnvVarHealthCheck(c *check.C) { + testRequires(c, DaemonIsLinux) // busybox doesn't work on Windows + + imageName := "testhealth" + buildImageSuccessfully(c, imageName, build.WithDockerfile(`FROM busybox +HEALTHCHECK --interval=1s --timeout=5s --retries=5 CMD /bin/sh -c "sleep 1" +ENTRYPOINT /bin/sh -c "sleep 600"`)) + + name := "env_test_health" + // No health status before starting + dockerCmd(c, "run", "-d", "--name", name, "-e", "FOO", imageName) + defer func() { + dockerCmd(c, "rm", "-f", name) + dockerCmd(c, "rmi", imageName) + }() + + // Start + dockerCmd(c, "start", name) + waitForHealthStatus(c, name, "starting", "healthy") + +}