Skip to content

Commit ab83f87

Browse files
authored
Merge pull request moby#5508 from tonistiigi/dockerfile-duplicate-args
dockerfile: fix duplicate keys for same arg in history line
2 parents 247ce1b + e2be8f7 commit ab83f87

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

frontend/dockerfile/dockerfile2llb/convert.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1878,12 +1878,18 @@ func dfCmd(cmd interface{}) llb.ConstraintsOpt {
18781878

18791879
func runCommandString(args []string, buildArgs []instructions.KeyValuePairOptional, env shell.EnvGetter) string {
18801880
var tmpBuildEnv []string
1881+
tmpIdx := map[string]int{}
18811882
for _, arg := range buildArgs {
18821883
v, ok := env.Get(arg.Key)
18831884
if !ok {
18841885
v = arg.ValueString()
18851886
}
1886-
tmpBuildEnv = append(tmpBuildEnv, arg.Key+"="+v)
1887+
if idx, ok := tmpIdx[arg.Key]; ok {
1888+
tmpBuildEnv[idx] = arg.Key + "=" + v
1889+
} else {
1890+
tmpIdx[arg.Key] = len(tmpBuildEnv)
1891+
tmpBuildEnv = append(tmpBuildEnv, arg.Key+"="+v)
1892+
}
18871893
}
18881894
if len(tmpBuildEnv) > 0 {
18891895
tmpBuildEnv = append([]string{fmt.Sprintf("|%d", len(tmpBuildEnv))}, tmpBuildEnv...)

frontend/dockerfile/dockerfile_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ var allTests = integration.TestFuncs(
8585
testDockerfileAddArchive,
8686
testDockerfileScratchConfig,
8787
testExportedHistory,
88+
testExportedHistoryFlattenArgs,
8889
testExposeExpansion,
8990
testUser,
9091
testUserAdditionalGids,
@@ -3625,6 +3626,70 @@ RUN ["ls"]
36253626
require.NotNil(t, ociimg.History[6].Created)
36263627
}
36273628

3629+
// moby/buildkit#5505
3630+
func testExportedHistoryFlattenArgs(t *testing.T, sb integration.Sandbox) {
3631+
integration.SkipOnPlatform(t, "windows")
3632+
f := getFrontend(t, sb)
3633+
f.RequiresBuildctl(t)
3634+
3635+
dockerfile := []byte(`
3636+
FROM busybox
3637+
ARG foo=bar
3638+
ARG bar=123
3639+
ARG foo=bar2
3640+
RUN ls /etc/
3641+
`)
3642+
3643+
dir := integration.Tmpdir(
3644+
t,
3645+
fstest.CreateFile("Dockerfile", dockerfile, 0600),
3646+
)
3647+
3648+
args, trace := f.DFCmdArgs(dir.Name, dir.Name)
3649+
defer os.RemoveAll(trace)
3650+
3651+
workers.CheckFeatureCompat(t, sb, workers.FeatureImageExporter)
3652+
workers.CheckFeatureCompat(t, sb, workers.FeatureDirectPush)
3653+
3654+
registry, err := sb.NewRegistry()
3655+
if errors.Is(err, integration.ErrRequirements) {
3656+
t.Skip(err.Error())
3657+
}
3658+
require.NoError(t, err)
3659+
3660+
target := registry + "/buildkit/testargduplicate:latest"
3661+
cmd := sb.Cmd(args + " --output type=image,push=true,name=" + target)
3662+
require.NoError(t, cmd.Run())
3663+
3664+
desc, provider, err := contentutil.ProviderFromRef(target)
3665+
require.NoError(t, err)
3666+
3667+
imgs, err := testutil.ReadImages(sb.Context(), provider, desc)
3668+
require.NoError(t, err)
3669+
3670+
require.Equal(t, 1, len(imgs.Images))
3671+
3672+
history := imgs.Images[0].Img.History
3673+
3674+
firstNonBase := -1
3675+
for i, h := range history {
3676+
if h.CreatedBy == "ARG foo=bar" {
3677+
firstNonBase = i
3678+
break
3679+
}
3680+
}
3681+
require.Greater(t, firstNonBase, 0)
3682+
3683+
require.Len(t, history, firstNonBase+4)
3684+
require.Contains(t, history[firstNonBase+1].CreatedBy, "ARG bar=123")
3685+
require.Contains(t, history[firstNonBase+2].CreatedBy, "ARG foo=bar2")
3686+
3687+
runLine := history[firstNonBase+3].CreatedBy
3688+
require.Contains(t, runLine, "ls /etc/")
3689+
require.NotContains(t, runLine, "ARG foo=bar")
3690+
require.Contains(t, runLine, "RUN |2 foo=bar2 bar=123 ")
3691+
}
3692+
36283693
func testUser(t *testing.T, sb integration.Sandbox) {
36293694
integration.SkipOnPlatform(t, "windows")
36303695
workers.CheckFeatureCompat(t, sb, workers.FeatureImageExporter)

0 commit comments

Comments
 (0)