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) {
|
func MakeKanikoStages(opts *config.KanikoOptions, stages []instructions.Stage, metaArgs []instructions.ArgCommand) ([]config.KanikoStage, error) {
|
||||||
targetStage, err := targetStage(stages, opts.Target)
|
targetStage, err := targetStage(stages, opts.Target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Error finding target stage")
|
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
|
var kanikoStages []config.KanikoStage
|
||||||
for index, stage := range stages {
|
for index, stage := range stages {
|
||||||
resolvedBaseName, err := util.ResolveEnvironmentReplacement(stage.BaseName, opts.BuildArgs, false)
|
if len(stage.Name) > 0 {
|
||||||
if err != nil {
|
logrus.Infof("Resolved base name %s to %s", stage.BaseName, stage.Name)
|
||||||
return nil, errors.Wrap(err, "resolving base name")
|
|
||||||
}
|
}
|
||||||
stage.Name = resolvedBaseName
|
baseImageIndex := baseImageIndex(index, stages)
|
||||||
logrus.Infof("Resolved base name %s to %s", stage.BaseName, stage.Name)
|
|
||||||
kanikoStages = append(kanikoStages, config.KanikoStage{
|
kanikoStages = append(kanikoStages, config.KanikoStage{
|
||||||
Stage: stage,
|
Stage: stage,
|
||||||
BaseImageIndex: baseImageIndex(index, stages),
|
BaseImageIndex: baseImageIndex,
|
||||||
BaseImageStoredLocally: (baseImageIndex(index, stages) != -1),
|
BaseImageStoredLocally: (baseImageIndex != -1),
|
||||||
SaveStage: saveStage(index, stages),
|
SaveStage: saveStage(index, stages),
|
||||||
Final: index == targetStage,
|
Final: index == targetStage,
|
||||||
MetaArgs: metaArgs,
|
MetaArgs: metaArgs,
|
||||||
|
|
@ -273,3 +290,26 @@ func GetOnBuildInstructions(config *v1.Config, stageNameToIdx map[string]string)
|
||||||
ResolveCrossStageCommands(cmds, stageNameToIdx)
|
ResolveCrossStageCommands(cmds, stageNameToIdx)
|
||||||
return cmds, nil
|
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
|
package dockerfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"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