Browse code

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 <ripcurld.github@gmail.com>

Boaz Shuster authored on 2017/05/17 21:30:51
Showing 2 changed files
... ...
@@ -64,31 +64,35 @@ type cmdProbe struct {
64 64
 
65 65
 // exec the healthcheck command in the container.
66 66
 // Returns the exit code and probe output (if any)
67
-func (p *cmdProbe) run(ctx context.Context, d *Daemon, container *container.Container) (*types.HealthcheckResult, error) {
68
-
69
-	cmdSlice := strslice.StrSlice(container.Config.Healthcheck.Test)[1:]
67
+func (p *cmdProbe) run(ctx context.Context, d *Daemon, cntr *container.Container) (*types.HealthcheckResult, error) {
68
+	cmdSlice := strslice.StrSlice(cntr.Config.Healthcheck.Test)[1:]
70 69
 	if p.shell {
71
-		cmdSlice = append(getShell(container.Config), cmdSlice...)
70
+		cmdSlice = append(getShell(cntr.Config), cmdSlice...)
72 71
 	}
73 72
 	entrypoint, args := d.getEntrypointAndArgs(strslice.StrSlice{}, cmdSlice)
74 73
 	execConfig := exec.NewConfig()
75 74
 	execConfig.OpenStdin = false
76 75
 	execConfig.OpenStdout = true
77 76
 	execConfig.OpenStderr = true
78
-	execConfig.ContainerID = container.ID
77
+	execConfig.ContainerID = cntr.ID
79 78
 	execConfig.DetachKeys = []byte{}
80 79
 	execConfig.Entrypoint = entrypoint
81 80
 	execConfig.Args = args
82 81
 	execConfig.Tty = false
83 82
 	execConfig.Privileged = false
84
-	execConfig.User = container.Config.User
85
-	execConfig.Env = container.Config.Env
83
+	execConfig.User = cntr.Config.User
84
+
85
+	linkedEnv, err := d.setupLinkedContainers(cntr)
86
+	if err != nil {
87
+		return nil, err
88
+	}
89
+	execConfig.Env = container.ReplaceOrAppendEnvValues(cntr.CreateDaemonEnvironment(execConfig.Tty, linkedEnv), execConfig.Env)
86 90
 
87
-	d.registerExecCommand(container, execConfig)
88
-	d.LogContainerEvent(container, "exec_create: "+execConfig.Entrypoint+" "+strings.Join(execConfig.Args, " "))
91
+	d.registerExecCommand(cntr, execConfig)
92
+	d.LogContainerEvent(cntr, "exec_create: "+execConfig.Entrypoint+" "+strings.Join(execConfig.Args, " "))
89 93
 
90 94
 	output := &limitedBuffer{}
91
-	err := d.ContainerExecStart(ctx, execConfig.ID, nil, output, output)
95
+	err = d.ContainerExecStart(ctx, execConfig.ID, nil, output, output)
92 96
 	if err != nil {
93 97
 		return nil, err
94 98
 	}
... ...
@@ -97,7 +101,7 @@ func (p *cmdProbe) run(ctx context.Context, d *Daemon, container *container.Cont
97 97
 		return nil, err
98 98
 	}
99 99
 	if info.ExitCode == nil {
100
-		return nil, fmt.Errorf("Healthcheck for container %s has no exit code!", container.ID)
100
+		return nil, fmt.Errorf("Healthcheck for container %s has no exit code!", cntr.ID)
101 101
 	}
102 102
 	// Note: Go's json package will handle invalid UTF-8 for us
103 103
 	out := output.String()
... ...
@@ -139,3 +139,26 @@ func (s *DockerSuite) TestHealth(c *check.C) {
139 139
 	c.Check(out, checker.Equals, "[CMD cat /my status]\n")
140 140
 
141 141
 }
142
+
143
+// Github #33021
144
+func (s *DockerSuite) TestUnsetEnvVarHealthCheck(c *check.C) {
145
+	testRequires(c, DaemonIsLinux) // busybox doesn't work on Windows
146
+
147
+	imageName := "testhealth"
148
+	buildImageSuccessfully(c, imageName, build.WithDockerfile(`FROM busybox
149
+HEALTHCHECK --interval=1s --timeout=5s --retries=5 CMD /bin/sh -c "sleep 1"
150
+ENTRYPOINT /bin/sh -c "sleep 600"`))
151
+
152
+	name := "env_test_health"
153
+	// No health status before starting
154
+	dockerCmd(c, "run", "-d", "--name", name, "-e", "FOO", imageName)
155
+	defer func() {
156
+		dockerCmd(c, "rm", "-f", name)
157
+		dockerCmd(c, "rmi", imageName)
158
+	}()
159
+
160
+	// Start
161
+	dockerCmd(c, "start", name)
162
+	waitForHealthStatus(c, name, "starting", "healthy")
163
+
164
+}