Skip to content

Commit

Permalink
Fix arg handling for multi-stage images in COPY instructions.
Browse files Browse the repository at this point in the history
  • Loading branch information
dlorenc committed Mar 18, 2019
1 parent 246cc92 commit d1b4881
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 13 deletions.
12 changes: 12 additions & 0 deletions integration/dockerfiles/Dockerfile_test_arg_multi
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
ARG FILE_NAME=myFile

FROM busybox:latest AS builder
ARG FILE_NAME

RUN echo $FILE_NAME && touch /$FILE_NAME.txt && stat /$FILE_NAME.txt;

FROM busybox:latest
ARG FILE_NAME

RUN echo $FILE_NAME && touch /$FILE_NAME.txt && stat /$FILE_NAME.txt;
COPY --from=builder /$FILE_NAME.txt /
26 changes: 17 additions & 9 deletions pkg/commands/arg.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,35 @@ type ArgCommand struct {

// ExecuteCommand only needs to add this ARG key/value as seen
func (r *ArgCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
replacementEnvs := buildArgs.ReplacementEnvs(config.Env)
resolvedKey, err := util.ResolveEnvironmentReplacement(r.cmd.Key, replacementEnvs, false)
key, val, err := ParseArg(r.cmd.Key, r.cmd.Value, config.Env, buildArgs)
if err != nil {
return err
}

buildArgs.AddArg(key, val)
return nil
}

func ParseArg(key string, val *string, env []string, ba *dockerfile.BuildArgs) (string, *string, error) {
replacementEnvs := ba.ReplacementEnvs(env)
resolvedKey, err := util.ResolveEnvironmentReplacement(key, replacementEnvs, false)
if err != nil {
return "", nil, err
}
var resolvedValue *string
if r.cmd.Value != nil {
value, err := util.ResolveEnvironmentReplacement(*r.cmd.Value, replacementEnvs, false)
if val != nil {
value, err := util.ResolveEnvironmentReplacement(*val, replacementEnvs, false)
if err != nil {
return err
return "", nil, err
}
resolvedValue = &value
} else {
meta := buildArgs.GetAllMeta()
meta := ba.GetAllMeta()
if value, ok := meta[resolvedKey]; ok {
resolvedValue = &value
}
}

buildArgs.AddArg(resolvedKey, resolvedValue)
return nil
return resolvedKey, resolvedValue, nil
}

// String returns some information about the command for the image config history
Expand Down
11 changes: 8 additions & 3 deletions pkg/executor/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,8 +383,7 @@ func CalculateDependencies(opts *config.KanikoOptions) (map[int][]string, error)
return nil, err
}
}
initializeConfig(image)
cfg, err := image.ConfigFile()
cfg, err := initializeConfig(image)
if err != nil {
return nil, err
}
Expand All @@ -396,7 +395,7 @@ func CalculateDependencies(opts *config.KanikoOptions) (map[int][]string, error)
if err != nil {
continue
}
resolved, err := util.ResolveEnvironmentReplacementList(cmd.SourcesAndDest, cfg.Config.Env, true)
resolved, err := util.ResolveEnvironmentReplacementList(cmd.SourcesAndDest, ba.ReplacementEnvs(cfg.Config.Env), true)
if err != nil {
return nil, err
}
Expand All @@ -411,6 +410,12 @@ func CalculateDependencies(opts *config.KanikoOptions) (map[int][]string, error)
if err != nil {
return nil, err
}
case *instructions.ArgCommand:
k, v, err := commands.ParseArg(cmd.Key, cmd.Value, cfg.Config.Env, ba)
if err != nil {
return nil, err
}
ba.AddArg(k, v)
}
}
images = append(images, image)
Expand Down
24 changes: 23 additions & 1 deletion pkg/executor/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,23 @@ RUN bar
},
want: map[int][]string{},
},
{
name: "args",
args: args{
dockerfile: `
ARG myFile=foo
FROM debian as stage1
RUN foo
FROM stage1
ARG myFile
COPY --from=stage1 /tmp/$myFile.txt .
RUN bar
`,
},
want: map[int][]string{
0: {"/tmp/foo.txt"},
},
},
{
name: "simple deps",
args: args{
Expand Down Expand Up @@ -300,7 +317,12 @@ COPY --from=stage2 /bar /bat
DockerfilePath: f.Name(),
}

if got, _ := CalculateDependencies(opts); !reflect.DeepEqual(got, tt.want) {
got, err := CalculateDependencies(opts)
if err != nil {
t.Errorf("got error: %s,", err)
}

if !reflect.DeepEqual(got, tt.want) {
diff := cmp.Diff(got, tt.want)
t.Errorf("CalculateDependencies() = %v, want %v, diff %v", got, tt.want, diff)
}
Expand Down

0 comments on commit d1b4881

Please sign in to comment.