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.

Now add the definitions from the ARG statements to the ones
from the ENV statements and use both when resolving
variables.

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 16, 2020
1 parent e388800 commit 38e0036
Show file tree
Hide file tree
Showing 2 changed files with 83 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
}
66 changes: 66 additions & 0 deletions dispatchers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,39 @@ func TestDispatchAddChownWithEnvironment(t *testing.T) {
}
}

func TestDispatchAddChownWithArg(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 := "ADD --chown=${CHOWN_VAL} /go/src/github.com/kubernetes-incubator/service-catalog/controller-manager ."
if err := add(&mybuilder, args, nil, flagArgs, original); err != nil {
t.Errorf("dispatchAdd 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: true,
Chown: "6731:6731",
},
}
if !reflect.DeepEqual(mybuilder.PendingCopies, expectedPendingCopies) {
t.Errorf("Expected %v, to match %v\n", expectedPendingCopies, mybuilder.PendingCopies)
}
}

func TestDispatchCopyChownWithEnvironment(t *testing.T) {
mybuilder := Builder{
RunConfig: docker.Config{
Expand Down Expand Up @@ -208,6 +241,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 38e0036

Please sign in to comment.