Fix resolving arguments over multi-stage build (#1928)

* Fix resolving argument over mulit-stage build

- Building multi-stage Dockerfiles did not correctly resolve
  ARG commands over different stages. Now, each stage depends on the
  build arguments set by the stage before.

Closes: #1911

* Fix resolving empty arg commands
This commit is contained in:
Gabriel Nützi 2022-02-10 18:22:21 +01:00 committed by GitHub
parent 3589382378
commit 2d94d56af7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 5 deletions

View File

@ -0,0 +1,18 @@
ARG OTHER="fix"
FROM alpine:latest as base
ARG NAME="base"
RUN echo "base:: $NAME" >> A.txt
FROM base AS base-dev
ARG NAME="$NAME-dev"
RUN echo "dev:: $NAME" >> B.txt
FROM base-dev as base-custom
ARG NAME
RUN echo "custom:: $NAME" >> C.txt
RUN echo "custom:: $OTHER" >> C.txt
FROM base-custom as base-custom2
ARG OTHER
RUN echo "custom:: $NAME" >> D.txt
RUN echo "custom:: $OTHER" >> D.txt

View File

@ -55,8 +55,9 @@ func ParseArg(key string, val *string, env []string, ba *dockerfile.BuildArgs) (
}
resolvedValue = &value
} else {
meta := ba.GetAllMeta()
if value, ok := meta[resolvedKey]; ok {
if value, ok := ba.GetAllAllowed()[resolvedKey]; ok {
resolvedValue = &value
} else if value, ok := ba.GetAllMeta()[resolvedKey]; ok {
resolvedValue = &value
}
}

View File

@ -84,7 +84,7 @@ type stageBuilder struct {
}
// newStageBuilder returns a new type stageBuilder which contains all the information required to build the stage
func newStageBuilder(opts *config.KanikoOptions, stage config.KanikoStage, crossStageDeps map[int][]string, dcm map[string]string, sid map[string]string, stageNameToIdx map[string]string, fileContext util.FileContext) (*stageBuilder, error) {
func newStageBuilder(args *dockerfile.BuildArgs, opts *config.KanikoOptions, stage config.KanikoStage, crossStageDeps map[int][]string, dcm map[string]string, sid map[string]string, stageNameToIdx map[string]string, fileContext util.FileContext) (*stageBuilder, error) {
sourceImage, err := image_util.RetrieveSourceImage(stage, opts)
if err != nil {
return nil, err
@ -143,7 +143,11 @@ func newStageBuilder(opts *config.KanikoOptions, stage config.KanikoStage, cross
s.cmds = append(s.cmds, command)
}
if args != nil {
s.args = args.Clone()
} else {
s.args = dockerfile.NewBuildArgs(s.opts.BuildArgs)
}
s.args.AddMetaArgs(s.stage.MetaArgs)
return s, nil
}
@ -615,8 +619,13 @@ func DoBuild(opts *config.KanikoOptions) (v1.Image, error) {
}
logrus.Infof("Built cross stage deps: %v", crossStageDependencies)
var args *dockerfile.BuildArgs
for index, stage := range kanikoStages {
sb, err := newStageBuilder(opts, stage, crossStageDependencies, digestToCacheKey, stageIdxToDigest, stageNameToIdx, fileContext)
sb, err := newStageBuilder(args, opts, stage, crossStageDependencies, digestToCacheKey, stageIdxToDigest, stageNameToIdx, fileContext)
args = sb.args
if err != nil {
return nil, err
}