Skip to content

Commit 224b7e2

Browse files
parse arg commands at the top of dockerfiles (GoogleContainerTools#404)
* parse arg commands at the top of dockerfiles * fix pointer reference bug and remove debugging * fixing tests * account for meta args with no value * don't take fs snapshot if / is the only changed path * move metaArgs inside KanikoStage * removing unused property * check for any directory instead of just / * remove unnecessary check
1 parent 5ed45ed commit 224b7e2

File tree

11 files changed

+60
-17
lines changed

11 files changed

+60
-17
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
# Bump these on release
1616
VERSION_MAJOR ?= 0
17-
VERSION_MINOR ?= 3
17+
VERSION_MINOR ?= 5
1818
VERSION_BUILD ?= 0
1919

2020
VERSION ?= v$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_BUILD)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
ARG REGISTRY=gcr.io
2+
ARG REPO=google-appengine
3+
ARG WORD=hello
4+
ARG W0RD2=hey
5+
6+
FROM ${REGISTRY}/${REPO}/debian9 as stage1
7+
8+
# Should evaluate WORD and create /tmp/hello
9+
ARG WORD
10+
RUN touch /${WORD}
11+
12+
FROM ${REGISTRY}/${REPO}/debian9
13+
14+
COPY --from=stage1 /hello /tmp
15+
16+
# /tmp/hey should not get created without the ARG statement
17+
RUN touch /tmp/${WORD2}

pkg/commands/arg.go

+6
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,13 @@ func (r *ArgCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bui
4242
return err
4343
}
4444
resolvedValue = &value
45+
} else {
46+
meta := buildArgs.GetAllMeta()
47+
if value, ok := meta[resolvedKey]; ok {
48+
resolvedValue = &value
49+
}
4550
}
51+
4652
buildArgs.AddArg(resolvedKey, resolvedValue)
4753
return nil
4854
}

pkg/config/stage.go

+1
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ type KanikoStage struct {
2525
Final bool
2626
BaseImageStoredLocally bool
2727
SaveStage bool
28+
MetaArgs []instructions.ArgCommand
2829
}

pkg/dockerfile/buildargs.go

+9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"strings"
2121

2222
d "github.com/docker/docker/builder/dockerfile"
23+
"github.com/moby/buildkit/frontend/dockerfile/instructions"
2324
)
2425

2526
type BuildArgs struct {
@@ -53,3 +54,11 @@ func (b *BuildArgs) ReplacementEnvs(envs []string) []string {
5354
filtered := b.FilterAllowed(envs)
5455
return append(envs, filtered...)
5556
}
57+
58+
// AddMetaArgs adds the supplied args map to b's allowedMetaArgs
59+
func (b *BuildArgs) AddMetaArgs(metaArgs []instructions.ArgCommand) {
60+
for _, arg := range metaArgs {
61+
v := arg.Value
62+
b.AddMetaArg(arg.Key, v)
63+
}
64+
}

pkg/dockerfile/dockerfile.go

+8-6
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func Stages(opts *config.KanikoOptions) ([]config.KanikoStage, error) {
3838
if err != nil {
3939
return nil, errors.Wrap(err, fmt.Sprintf("reading dockerfile at path %s", opts.DockerfilePath))
4040
}
41-
stages, err := Parse(d)
41+
stages, metaArgs, err := Parse(d)
4242
if err != nil {
4343
return nil, errors.Wrap(err, "parsing dockerfile")
4444
}
@@ -60,11 +60,13 @@ func Stages(opts *config.KanikoOptions) ([]config.KanikoStage, error) {
6060
BaseImageStoredLocally: (baseImageIndex(index, stages) != -1),
6161
SaveStage: saveStage(index, stages),
6262
Final: index == targetStage,
63+
MetaArgs: metaArgs,
6364
})
6465
if index == targetStage {
6566
break
6667
}
6768
}
69+
6870
return kanikoStages, nil
6971
}
7072

@@ -83,16 +85,16 @@ func baseImageIndex(currentStage int, stages []instructions.Stage) int {
8385
}
8486

8587
// Parse parses the contents of a Dockerfile and returns a list of commands
86-
func Parse(b []byte) ([]instructions.Stage, error) {
88+
func Parse(b []byte) ([]instructions.Stage, []instructions.ArgCommand, error) {
8789
p, err := parser.Parse(bytes.NewReader(b))
8890
if err != nil {
89-
return nil, err
91+
return nil, nil, err
9092
}
91-
stages, _, err := instructions.Parse(p.AST)
93+
stages, metaArgs, err := instructions.Parse(p.AST)
9294
if err != nil {
93-
return nil, err
95+
return nil, nil, err
9496
}
95-
return stages, err
97+
return stages, metaArgs, err
9698
}
9799

98100
// targetStage returns the index of the target stage kaniko is trying to build

pkg/dockerfile/dockerfile_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func Test_resolveStages(t *testing.T) {
3535
FROM scratch
3636
COPY --from=second /hi2 /hi3
3737
`
38-
stages, err := Parse([]byte(dockerfile))
38+
stages, _, err := Parse([]byte(dockerfile))
3939
if err != nil {
4040
t.Fatal(err)
4141
}
@@ -63,7 +63,7 @@ func Test_targetStage(t *testing.T) {
6363
FROM scratch
6464
COPY --from=second /hi2 /hi3
6565
`
66-
stages, err := Parse([]byte(dockerfile))
66+
stages, _, err := Parse([]byte(dockerfile))
6767
if err != nil {
6868
t.Fatal(err)
6969
}
@@ -142,7 +142,7 @@ func Test_SaveStage(t *testing.T) {
142142
expected: false,
143143
},
144144
}
145-
stages, err := Parse([]byte(testutil.Dockerfile))
145+
stages, _, err := Parse([]byte(testutil.Dockerfile))
146146
if err != nil {
147147
t.Fatalf("couldn't retrieve stages from Dockerfile: %v", err)
148148
}
@@ -177,7 +177,7 @@ func Test_baseImageIndex(t *testing.T) {
177177
},
178178
}
179179

180-
stages, err := Parse([]byte(testutil.Dockerfile))
180+
stages, _, err := Parse([]byte(testutil.Dockerfile))
181181
if err != nil {
182182
t.Fatalf("couldn't retrieve stages from Dockerfile: %v", err)
183183
}

pkg/executor/build.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ type stageBuilder struct {
5454

5555
// newStageBuilder returns a new type stageBuilder which contains all the information required to build the stage
5656
func newStageBuilder(opts *config.KanikoOptions, stage config.KanikoStage) (*stageBuilder, error) {
57-
sourceImage, err := util.RetrieveSourceImage(stage, opts.BuildArgs, opts)
57+
sourceImage, err := util.RetrieveSourceImage(stage, opts)
5858
if err != nil {
5959
return nil, err
6060
}
@@ -136,6 +136,7 @@ func (s *stageBuilder) build() error {
136136
}
137137

138138
args := dockerfile.NewBuildArgs(s.opts.BuildArgs)
139+
args.AddMetaArgs(s.stage.MetaArgs)
139140
for index, command := range cmds {
140141
if command == nil {
141142
continue

pkg/executor/build_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func Test_reviewConfig(t *testing.T) {
6666
}
6767

6868
func stage(t *testing.T, d string) config.KanikoStage {
69-
stages, err := dockerfile.Parse([]byte(d))
69+
stages, _, err := dockerfile.Parse([]byte(d))
7070
if err != nil {
7171
t.Fatalf("error parsing dockerfile: %v", err)
7272
}

pkg/util/image_util.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package util
1818

1919
import (
2020
"crypto/tls"
21+
"fmt"
2122
"net/http"
2223
"path/filepath"
2324
"strconv"
@@ -44,7 +45,13 @@ var (
4445
)
4546

4647
// RetrieveSourceImage returns the base image of the stage at index
47-
func RetrieveSourceImage(stage config.KanikoStage, buildArgs []string, opts *config.KanikoOptions) (v1.Image, error) {
48+
func RetrieveSourceImage(stage config.KanikoStage, opts *config.KanikoOptions) (v1.Image, error) {
49+
buildArgs := opts.BuildArgs
50+
var metaArgsString []string
51+
for _, arg := range stage.MetaArgs {
52+
metaArgsString = append(metaArgsString, fmt.Sprintf("%s=%s", arg.Key, arg.ValueString()))
53+
}
54+
buildArgs = append(buildArgs, metaArgsString...)
4855
currentBaseName, err := ResolveEnvironmentReplacement(stage.BaseName, buildArgs, false)
4956
if err != nil {
5057
return nil, err

pkg/util/image_util_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func Test_StandardImage(t *testing.T) {
5757
retrieveRemoteImage = mock
5858
actual, err := RetrieveSourceImage(config.KanikoStage{
5959
Stage: stages[0],
60-
}, nil, &config.KanikoOptions{})
60+
}, &config.KanikoOptions{})
6161
testutil.CheckErrorAndDeepEqual(t, false, err, nil, actual)
6262
}
6363
func Test_ScratchImage(t *testing.T) {
@@ -67,7 +67,7 @@ func Test_ScratchImage(t *testing.T) {
6767
}
6868
actual, err := RetrieveSourceImage(config.KanikoStage{
6969
Stage: stages[1],
70-
}, nil, &config.KanikoOptions{})
70+
}, &config.KanikoOptions{})
7171
expected := empty.Image
7272
testutil.CheckErrorAndDeepEqual(t, false, err, expected, actual)
7373
}
@@ -89,7 +89,7 @@ func Test_TarImage(t *testing.T) {
8989
BaseImageStoredLocally: true,
9090
BaseImageIndex: 0,
9191
Stage: stages[2],
92-
}, nil, &config.KanikoOptions{})
92+
}, &config.KanikoOptions{})
9393
testutil.CheckErrorAndDeepEqual(t, false, err, nil, actual)
9494
}
9595

0 commit comments

Comments
 (0)