Skip to content

Commit

Permalink
Allow Args to be used in Variable Evaluation
Browse files Browse the repository at this point in the history
If the Dockerfile has a `ARG CHOWN_VAL=6173:6173`, then
a `COPY --chown=${CHOWN_VAL} srcFile destFile` will fail.
However if the Dockerfile has a `ENV CHOWN_VAL=6173:6173`
then it succeeds.

The dispatchCopy() and add() functions were only going through the
list of Environment variables to resolve a Variable instead
of the list of Args and Environment variables.  If there's
a trailing equal `=` sign in the arg, assume that we'd a
variable that did not resolve and try to resolve from the
list of args.

At some point I'd like to look into converting the b.Env to
a Map from a slice like b.Args, but didn't want to run this
down now.

Fixes: containers/buildah#2192
       and probably containers/buildah#2345

Signed-off-by: TomSweeneyRedHat <[email protected]>
  • Loading branch information
TomSweeneyRedHat committed May 15, 2020
1 parent e388800 commit 3e0c5ad
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
19 changes: 17 additions & 2 deletions dispatchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ func add(b *Builder, args []string, attributes map[string]bool, flagArgs []strin
var chown string
last := len(args) - 1
dest := makeAbsolute(args[last], b.RunConfig.WorkingDir)
userArgs := makeUserArgs(b)
for _, a := range flagArgs {
arg, err := ProcessWord(a, b.Env)
arg, err := ProcessWord(a, userArgs)
if err != nil {
return err
}
Expand All @@ -181,8 +182,9 @@ func dispatchCopy(b *Builder, args []string, attributes map[string]bool, flagArg
dest := makeAbsolute(args[last], b.RunConfig.WorkingDir)
var chown string
var from string
userArgs := makeUserArgs(b)
for _, a := range flagArgs {
arg, err := ProcessWord(a, b.Env)
arg, err := ProcessWord(a, userArgs)
if err != nil {
return err
}
Expand Down Expand Up @@ -649,3 +651,16 @@ func errTooManyArguments(command string) error {
func errNotJSON(command string) error {
return fmt.Errorf("%s requires the arguments to be in JSON form", command)
}

// makeUserArgs - Package the variables from the Dockerfile defined by
// the ENV aand the ARG statements into one slice so the values
// defined by both can later be evaluated when resolving variables
// such as ${MY_USER}
func makeUserArgs(b *Builder) (userArgs []string) {

userArgs = b.Env
for key, value := range b.Args {
userArgs = append(userArgs, key+"="+value)
}
return userArgs
}
33 changes: 33 additions & 0 deletions dispatchers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,39 @@ func TestDispatchCopyChownWithEnvironment(t *testing.T) {
}
}

func TestDispatchCopyChownWithArg(t *testing.T) {
argsMap := make(map[string]string)
argsMap["CHOWN_VAL"] = "6731:6731"
mybuilder := Builder{
RunConfig: docker.Config{
WorkingDir: "/root",
Cmd: []string{"/bin/sh"},
Image: "alpine",
},
Args: argsMap,
}

args := []string{"/go/src/github.com/kubernetes-incubator/service-catalog/controller-manager", "."}
flagArgs := []string{"--chown=${CHOWN_VAL}"}
original := "COPY --chown=${CHOWN_VAL} /go/src/github.com/kubernetes-incubator/service-catalog/controller-manager ."
if err := dispatchCopy(&mybuilder, args, nil, flagArgs, original); err != nil {
t.Errorf("dispatchCopy error: %v", err)
}

expectedPendingCopies := []Copy{
{
From: "",
Src: []string{"/go/src/github.com/kubernetes-incubator/service-catalog/controller-manager"},
Dest: "/root/", // destination must contain a trailing slash
Download: false,
Chown: "6731:6731",
},
}
if !reflect.DeepEqual(mybuilder.PendingCopies, expectedPendingCopies) {
t.Errorf("Expected %v, to match %v\n", expectedPendingCopies, mybuilder.PendingCopies)
}
}

func TestDispatchAddChown(t *testing.T) {
mybuilder := Builder{
RunConfig: docker.Config{
Expand Down

0 comments on commit 3e0c5ad

Please sign in to comment.