Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,18 @@ func NewStages(node *parser.Node, b *Builder) (Stages, error) {
}
inheritedArgs := argInstructionsInStages[from]
thisStageArgs := slices.Clone(inheritedArgs)
filteredUserArgs := make(map[string]string)
for k, v := range b.UserArgs {
for _, a := range b.GlobalAllowedArgs {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for this PR, but would it be possible to change GlobalAllowedArgs to a map to improve search efficiency? It looks like we do this loop in at least one other spot.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not used by buildah or podman, but it is part of the exported API, which at this point I'd like to avoid breaking here.

if a == k {
filteredUserArgs[k] = v
}
}
}
userArgs := envMapAsSlice(filteredUserArgs)
userArgs = mergeEnv(envMapAsSlice(b.BuiltinArgDefaults), userArgs)
userArgs = mergeEnv(envMapAsSlice(builtinArgDefaults), userArgs)
userArgs = mergeEnv(envMapAsSlice(b.HeadingArgs), userArgs)
for _, child := range s.Node.Children {
if !strings.EqualFold(child.Value, command.Arg) {
continue
Expand All @@ -329,7 +341,12 @@ func NewStages(node *parser.Node, b *Builder) (Stages, error) {
}
next := child.Next
for next != nil {
thisStageArgs = append(thisStageArgs, next.Value)
processedValue, err := ProcessWord(next.Value, userArgs)
if err != nil {
return fmt.Errorf("processing ARG %q", next.Value)
}
thisStageArgs = append(thisStageArgs, processedValue)
userArgs = mergeEnv(userArgs, []string{processedValue})
next = next.Next
}
}
Expand Down
12 changes: 12 additions & 0 deletions builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,12 @@ func TestMultiStageArgScope(t *testing.T) {
if !builderHasArgument(stages[0].Builder, "SECRET=secretthings") {
t.Fatalf("expected SECRET=secretthings to be contained in first stage arguments list: %v", stages[0].Builder.Arguments())
}
if !builderHasArgument(stages[0].Builder, "QUOTED=words with quotes") {
t.Fatalf(`expected QUOTED="words with quotes" to be present in first stage arguments list: %v`, stages[0].Builder.Arguments())
}
if !builderHasArgument(stages[0].Builder, "REQUOTED=words with quotes") {
t.Fatalf(`expected REQUOTED="words with quotes" to be present in first stage arguments list: %v`, stages[0].Builder.Arguments())
}

secondStageArguments := stages[1].Builder.Arguments()
secretInSecondStage := false
Expand Down Expand Up @@ -591,6 +597,12 @@ func TestMultiStageArgScope(t *testing.T) {
if !unusedInThirdStage {
t.Fatalf("expected UNUSED to be present in third stage")
}
if !builderHasArgument(stages[2].Builder, "QUOTED=words with quotes") {
t.Fatalf(`expected QUOTED=words with quotes to be present in third stage arguments list: %v`, thirdStageArguments)
}
if !builderHasArgument(stages[2].Builder, "REQUOTED=words with quotes") {
t.Fatalf(`expected REQUOTED=words with quotes to be present in third stage arguments list: %v`, thirdStageArguments)
}
}

func TestRun(t *testing.T) {
Expand Down
4 changes: 4 additions & 0 deletions dockerclient/testdata/multistage/Dockerfile.arg-scope
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ FROM mirror.gcr.io/alpine
ARG SECRET
ARG UNUSED
ARG INHERITED=set
ARG QUOTED="words with quotes"
ARG REQUOTED=$QUOTED
RUN echo "$SECRET"

FROM mirror.gcr.io/alpine
Expand All @@ -12,3 +14,5 @@ RUN echo "$SECRET"

FROM 0
RUN echo "$SECRET"
ARG QUOTED
ARG REQUOTED