diff --git a/integration/dockerfiles/Dockerfile_test_arg_multi b/integration/dockerfiles/Dockerfile_test_arg_multi new file mode 100644 index 000000000..a81e47e50 --- /dev/null +++ b/integration/dockerfiles/Dockerfile_test_arg_multi @@ -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 / \ No newline at end of file diff --git a/pkg/commands/arg.go b/pkg/commands/arg.go index 6b890cff0..e17767338 100644 --- a/pkg/commands/arg.go +++ b/pkg/commands/arg.go @@ -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 diff --git a/pkg/executor/build.go b/pkg/executor/build.go index 7b6ecf14c..2fbf592ce 100644 --- a/pkg/executor/build.go +++ b/pkg/executor/build.go @@ -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 } @@ -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 } @@ -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) diff --git a/pkg/executor/build_test.go b/pkg/executor/build_test.go index b0cd34d0f..c48e4bb26 100644 --- a/pkg/executor/build_test.go +++ b/pkg/executor/build_test.go @@ -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{ @@ -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) }