resolve conflict with PR #1160
This commit is contained in:
		
							parent
							
								
									f720c817c7
								
							
						
					
					
						commit
						e8323441ab
					
				|  | @ -230,23 +230,40 @@ func ResolveCrossStageCommands(cmds []instructions.Command, stageNameToIdx map[s | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| // resolveStagesArgs resolves all the args from list of stages
 | ||||
| func resolveStagesArgs(stages []instructions.Stage, args []string) error { | ||||
| 	for i, s := range stages { | ||||
| 		resolvedBaseName, err := util.ResolveEnvironmentReplacement(s.BaseName, args, false) | ||||
| 		if err != nil { | ||||
| 			return errors.Wrap(err, fmt.Sprintf("resolving base name %s", s.BaseName)) | ||||
| 		} | ||||
| 		if s.BaseName != resolvedBaseName { | ||||
| 			stages[i].BaseName = resolvedBaseName | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func MakeKanikoStages(opts *config.KanikoOptions, stages []instructions.Stage, metaArgs []instructions.ArgCommand) ([]config.KanikoStage, error) { | ||||
| 	targetStage, err := targetStage(stages, opts.Target) | ||||
| 	if err != nil { | ||||
| 		return nil, errors.Wrap(err, "Error finding target stage") | ||||
| 	} | ||||
| 	args := unifyArgs(metaArgs, opts.BuildArgs) | ||||
| 	if err := resolveStagesArgs(stages, args); err != nil { | ||||
| 		return nil, errors.Wrap(err, "resolving args") | ||||
| 	} | ||||
| 	var kanikoStages []config.KanikoStage | ||||
| 	for index, stage := range stages { | ||||
| 		resolvedBaseName, err := util.ResolveEnvironmentReplacement(stage.BaseName, opts.BuildArgs, false) | ||||
| 		if err != nil { | ||||
| 			return nil, errors.Wrap(err, "resolving base name") | ||||
| 		} | ||||
| 		stage.Name = resolvedBaseName | ||||
| 		if len(stage.Name) > 0 { | ||||
| 			logrus.Infof("Resolved base name %s to %s", stage.BaseName, stage.Name) | ||||
| 		} | ||||
| 		baseImageIndex := baseImageIndex(index, stages) | ||||
| 
 | ||||
| 		kanikoStages = append(kanikoStages, config.KanikoStage{ | ||||
| 			Stage:                  stage, | ||||
| 			BaseImageIndex:         baseImageIndex(index, stages), | ||||
| 			BaseImageStoredLocally: (baseImageIndex(index, stages) != -1), | ||||
| 			BaseImageIndex:         baseImageIndex, | ||||
| 			BaseImageStoredLocally: (baseImageIndex != -1), | ||||
| 			SaveStage:              saveStage(index, stages), | ||||
| 			Final:                  index == targetStage, | ||||
| 			MetaArgs:               metaArgs, | ||||
|  | @ -273,3 +290,26 @@ func GetOnBuildInstructions(config *v1.Config, stageNameToIdx map[string]string) | |||
| 	ResolveCrossStageCommands(cmds, stageNameToIdx) | ||||
| 	return cmds, nil | ||||
| } | ||||
| 
 | ||||
| // unifyArgs returns the unified args between metaArgs and --build-arg
 | ||||
| // by default --build-arg overrides metaArgs except when --build-arg is empty
 | ||||
| func unifyArgs(metaArgs []instructions.ArgCommand, buildArgs []string) []string { | ||||
| 	argsMap := make(map[string]string) | ||||
| 	for _, a := range metaArgs { | ||||
| 		if a.Value != nil { | ||||
| 			argsMap[a.Key] = *a.Value | ||||
| 		} | ||||
| 	} | ||||
| 	splitter := "=" | ||||
| 	for _, a := range buildArgs { | ||||
| 		s := strings.Split(a, splitter) | ||||
| 		if len(s) > 1 && s[1] != "" { | ||||
| 			argsMap[s[0]] = s[1] | ||||
| 		} | ||||
| 	} | ||||
| 	var args []string | ||||
| 	for k, v := range argsMap { | ||||
| 		args = append(args, fmt.Sprintf("%s=%s", k, v)) | ||||
| 	} | ||||
| 	return args | ||||
| } | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ limitations under the License. | |||
| package dockerfile | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"reflect" | ||||
|  | @ -427,3 +428,72 @@ func Test_baseImageIndex(t *testing.T) { | |||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func Test_ResolveStagesArgs(t *testing.T) { | ||||
| 	dockerfile := ` | ||||
| 	ARG IMAGE="ubuntu:16.04" | ||||
| 	ARG LAST_STAGE_VARIANT | ||||
| 	FROM ${IMAGE} as base | ||||
| 	RUN echo hi > /hi | ||||
| 	FROM base AS base-dev | ||||
| 	RUN echo dev >> /hi | ||||
| 	FROM base AS base-prod | ||||
| 	RUN echo prod >> /hi | ||||
| 	FROM base-${LAST_STAGE_VARIANT} | ||||
| 	RUN cat /hi | ||||
| 	` | ||||
| 
 | ||||
| 	buildArgLastVariants := []string{"dev", "prod"} | ||||
| 	buildArgImages := []string{"alpine:3.11", ""} | ||||
| 	var expectedImage string | ||||
| 
 | ||||
| 	for _, buildArgLastVariant := range buildArgLastVariants { | ||||
| 		for _, buildArgImage := range buildArgImages { | ||||
| 			if buildArgImage != "" { | ||||
| 				expectedImage = buildArgImage | ||||
| 			} else { | ||||
| 				expectedImage = "ubuntu:16.04" | ||||
| 			} | ||||
| 			buildArgs := []string{fmt.Sprintf("IMAGE=%s", buildArgImage), fmt.Sprintf("LAST_STAGE_VARIANT=%s", buildArgLastVariant)} | ||||
| 
 | ||||
| 			stages, metaArgs, err := Parse([]byte(dockerfile)) | ||||
| 			if err != nil { | ||||
| 				t.Fatal(err) | ||||
| 			} | ||||
| 			stagesLen := len(stages) | ||||
| 
 | ||||
| 			args := unifyArgs(metaArgs, buildArgs) | ||||
| 			if err := resolveStagesArgs(stages, args); err != nil { | ||||
| 				t.Fatalf("fail to resolves args %v: %v", buildArgs, err) | ||||
| 			} | ||||
| 			tests := []struct { | ||||
| 				name               string | ||||
| 				actualSourceCode   string | ||||
| 				actualBaseName     string | ||||
| 				expectedSourceCode string | ||||
| 				expectedBaseName   string | ||||
| 			}{ | ||||
| 				{ | ||||
| 					name:               "Test_BuildArg_From_First_Stage", | ||||
| 					actualSourceCode:   stages[0].SourceCode, | ||||
| 					actualBaseName:     stages[0].BaseName, | ||||
| 					expectedSourceCode: "FROM ${IMAGE} as base", | ||||
| 					expectedBaseName:   expectedImage, | ||||
| 				}, | ||||
| 				{ | ||||
| 					name:               "Test_BuildArg_From_Last_Stage", | ||||
| 					actualSourceCode:   stages[stagesLen-1].SourceCode, | ||||
| 					actualBaseName:     stages[stagesLen-1].BaseName, | ||||
| 					expectedSourceCode: "FROM base-${LAST_STAGE_VARIANT}", | ||||
| 					expectedBaseName:   fmt.Sprintf("base-%s", buildArgLastVariant), | ||||
| 				}, | ||||
| 			} | ||||
| 			for _, test := range tests { | ||||
| 				t.Run(test.name, func(t *testing.T) { | ||||
| 					testutil.CheckDeepEqual(t, test.expectedSourceCode, test.actualSourceCode) | ||||
| 					testutil.CheckDeepEqual(t, test.expectedBaseName, test.actualBaseName) | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue