Skip to content

Commit

Permalink
Merge pull request #5593 from tonistiigi/fix-onbuild-stage-propagation
Browse files Browse the repository at this point in the history
dockerfile: fix onbuild propagation for child stages
  • Loading branch information
tonistiigi authored Dec 16, 2024
2 parents d4992d5 + 8bf1d78 commit 609aa14
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
2 changes: 2 additions & 0 deletions frontend/dockerfile/dockerfile2llb/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,8 @@ func (ds *dispatchState) init() {
ds.state = ds.base.state
ds.platform = ds.base.platform
ds.image = clone(ds.base.image)
// onbuild triggers to not carry over from base stage
ds.image.Config.OnBuild = nil
ds.baseImg = cloneX(ds.base.baseImg)
// Utilize the same path index as our base image so we propagate
// the paths we use back to the base image.
Expand Down
1 change: 1 addition & 0 deletions frontend/dockerfile/dockerfile2llb/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func clone(src dockerspec.DockerOCIImage) dockerspec.DockerOCIImage {
img.Config.Env = append([]string{}, src.Config.Env...)
img.Config.Cmd = append([]string{}, src.Config.Cmd...)
img.Config.Entrypoint = append([]string{}, src.Config.Entrypoint...)
img.Config.OnBuild = append([]string{}, src.Config.OnBuild...)
return img
}

Expand Down
91 changes: 91 additions & 0 deletions frontend/dockerfile/dockerfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ var allTests = integration.TestFuncs(
testEnvEmptyFormatting,
testCacheMultiPlatformImportExport,
testOnBuildCleared,
testOnBuildWithChildStage,
testOnBuildInheritedStageRun,
testOnBuildInheritedStageWithFrom,
testOnBuildNewDeps,
Expand Down Expand Up @@ -5013,6 +5014,96 @@ ONBUILD RUN mkdir \out && echo 11>> \out\foo
require.Equal(t, integration.UnixOrWindows("11", "11\r\n"), string(dt))
}

// testOnBuildWithChildStage tests that ONBUILD rules from the parent image do
// not run again if another stage inherits from current stage.
// moby/buildkit#5578
func testOnBuildWithChildStage(t *testing.T, sb integration.Sandbox) {
integration.SkipOnPlatform(t, "windows")
workers.CheckFeatureCompat(t, sb, workers.FeatureDirectPush)
f := getFrontend(t, sb)

registry, err := sb.NewRegistry()
if errors.Is(err, integration.ErrRequirements) {
t.Skip(err.Error())
}
require.NoError(t, err)

dockerfile := []byte(`
FROM busybox
ONBUILD RUN mkdir -p /out && echo -n yes >> /out/didrun
`)

dir := integration.Tmpdir(
t,
fstest.CreateFile("Dockerfile", dockerfile, 0600),
)

c, err := client.New(sb.Context(), sb.Address())
require.NoError(t, err)
defer c.Close()

target := registry + "/buildkit/testonbuildstage:base"

_, err = f.Solve(sb.Context(), c, client.SolveOpt{
Exports: []client.ExportEntry{
{
Type: client.ExporterImage,
Attrs: map[string]string{
"push": "true",
"name": target,
},
},
},
LocalMounts: map[string]fsutil.FS{
dockerui.DefaultLocalNameDockerfile: dir,
dockerui.DefaultLocalNameContext: dir,
},
}, nil)
require.NoError(t, err)

dockerfile = []byte(fmt.Sprintf(`
FROM %s AS base
RUN [ -f /out/didrun ] && touch /step1
RUN rm /out/didrun
RUN [ ! -f /out/didrun ] && touch /step2
FROM base AS child
RUN [ ! -f /out/didrun ] && touch /step3
FROM scratch
COPY --from=child /step* /
`, target))

dir = integration.Tmpdir(
t,
fstest.CreateFile("Dockerfile", dockerfile, 0600),
)
destDir := t.TempDir()

_, err = f.Solve(sb.Context(), c, client.SolveOpt{
Exports: []client.ExportEntry{
{
Type: client.ExporterLocal,
OutputDir: destDir,
},
},
LocalMounts: map[string]fsutil.FS{
dockerui.DefaultLocalNameDockerfile: dir,
dockerui.DefaultLocalNameContext: dir,
},
}, nil)
require.NoError(t, err)

_, err = os.Stat(filepath.Join(destDir, "step1"))
require.NoError(t, err)

_, err = os.Stat(filepath.Join(destDir, "step2"))
require.NoError(t, err)

_, err = os.Stat(filepath.Join(destDir, "step3"))
require.NoError(t, err)
}

func testOnBuildNamedContext(t *testing.T, sb integration.Sandbox) {
integration.SkipOnPlatform(t, "windows")
workers.CheckFeatureCompat(t, sb, workers.FeatureOCIExporter, workers.FeatureOCILayout)
Expand Down

0 comments on commit 609aa14

Please sign in to comment.