From 5836d86ac4d617e837d94010aa60384648ab59ea 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 --- daemon/health.go | 26 +++++++++++++---------- integration-cli/docker_cli_health_test.go | 23 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/daemon/health.go b/daemon/health.go index caa8db8447f23..48cf4c4255be6 100644 --- a/daemon/health.go +++ b/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/integration-cli/docker_cli_health_test.go b/integration-cli/docker_cli_health_test.go index 3e9d048f89111..0f78a41d872c0 100644 --- a/integration-cli/docker_cli_health_test.go +++ b/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") + +}