Skip to content
This repository has been archived by the owner on Oct 13, 2023. It is now read-only.

Commit

Permalink
Ensure RUN instruction to run without Healthcheck
Browse files Browse the repository at this point in the history
Before this commit Healthcheck run if HEALTHCHECK
instruction appears before RUN instruction.
By passing `withoutHealthcheck` to `copyRunConfig`,
always RUN instruction run without Healthcheck.

Fix: moby/moby#37362

Signed-off-by: Yuichiro Kaneko <spiketeika@gmail.com>
(cherry picked from commit 44e08d8a7d1249a1956018c6c3d3655642a4f273)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 160be68bbd6974eef7a4aebcfce2af5971baafe7
Component: engine
  • Loading branch information
yui-knk authored and thaJeztah committed Jul 11, 2018
1 parent 98dc20f commit 0d419b5
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
3 changes: 2 additions & 1 deletion components/engine/builder/dockerfile/dispatchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,8 @@ func dispatchRun(d dispatchRequest, c *instructions.RunCommand) error {
runConfig := copyRunConfig(stateRunConfig,
withCmd(cmdFromArgs),
withEnv(append(stateRunConfig.Env, buildArgs...)),
withEntrypointOverride(saveCmd, strslice.StrSlice{""}))
withEntrypointOverride(saveCmd, strslice.StrSlice{""}),
withoutHealthcheck())

// set config as already being escaped, this prevents double escaping on windows
runConfig.ArgsEscaped = true
Expand Down
61 changes: 61 additions & 0 deletions components/engine/builder/dockerfile/dispatchers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,3 +473,64 @@ func TestRunWithBuildArgs(t *testing.T) {
// Check that runConfig.Cmd has not been modified by run
assert.Check(t, is.DeepEqual(origCmd, sb.state.runConfig.Cmd))
}

func TestRunIgnoresHealthcheck(t *testing.T) {
b := newBuilderWithMockBackend()
args := NewBuildArgs(make(map[string]*string))
sb := newDispatchRequest(b, '`', nil, args, newStagesBuildResults())
b.disableCommit = false

origCmd := strslice.StrSlice([]string{"cmd", "in", "from", "image"})

imageCache := &mockImageCache{
getCacheFunc: func(parentID string, cfg *container.Config) (string, error) {
return "", nil
},
}

mockBackend := b.docker.(*MockBackend)
mockBackend.makeImageCacheFunc = func(_ []string) builder.ImageCache {
return imageCache
}
b.imageProber = newImageProber(mockBackend, nil, false)
mockBackend.getImageFunc = func(_ string) (builder.Image, builder.ROLayer, error) {
return &mockImage{
id: "abcdef",
config: &container.Config{Cmd: origCmd},
}, nil, nil
}
mockBackend.containerCreateFunc = func(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error) {
return container.ContainerCreateCreatedBody{ID: "12345"}, nil
}
mockBackend.commitFunc = func(cfg backend.CommitConfig) (image.ID, error) {
return "", nil
}
from := &instructions.Stage{BaseName: "abcdef"}
err := initializeStage(sb, from)
assert.NilError(t, err)

expectedTest := []string{"CMD-SHELL", "curl -f http://localhost/ || exit 1"}
cmd := &instructions.HealthCheckCommand{
Health: &container.HealthConfig{
Test: expectedTest,
},
}
assert.NilError(t, dispatch(sb, cmd))
assert.Assert(t, sb.state.runConfig.Healthcheck != nil)

mockBackend.containerCreateFunc = func(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error) {
// Check the Healthcheck is disabled.
assert.Check(t, is.DeepEqual([]string{"NONE"}, config.Config.Healthcheck.Test))
return container.ContainerCreateCreatedBody{ID: "123456"}, nil
}

sb.state.buildArgs.AddArg("one", strPtr("two"))
run := &instructions.RunCommand{
ShellDependantCmdLine: instructions.ShellDependantCmdLine{
CmdLine: strslice.StrSlice{"echo foo"},
PrependShell: true,
},
}
assert.NilError(t, dispatch(sb, run))
assert.Check(t, is.DeepEqual(expectedTest, sb.state.runConfig.Healthcheck.Test))
}
12 changes: 12 additions & 0 deletions components/engine/builder/dockerfile/internals.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,18 @@ func withEntrypointOverride(cmd []string, entrypoint []string) runConfigModifier
}
}

// withoutHealthcheck disables healthcheck.
//
// The dockerfile RUN instruction expect to run without healthcheck
// so the runConfig Healthcheck needs to be disabled.
func withoutHealthcheck() runConfigModifier {
return func(runConfig *container.Config) {
runConfig.Healthcheck = &container.HealthConfig{
Test: []string{"NONE"},
}
}
}

func copyRunConfig(runConfig *container.Config, modifiers ...runConfigModifier) *container.Config {
copy := *runConfig
copy.Cmd = copyStringSlice(runConfig.Cmd)
Expand Down

0 comments on commit 0d419b5

Please sign in to comment.