9e205c
From 49ab77998f85a05f05814f6575b25de264bf8256 Mon Sep 17 00:00:00 2001
9e205c
From: TomSweeneyRedHat <tsweeney@redhat.com>
9e205c
Date: Sat, 18 Jan 2020 15:43:05 -0500
9e205c
Subject: [PATCH] Fix COPY in containerfile with envvar
9e205c
9e205c
If a Containerfile had lines like:
9e205c
9e205c
```
9e205c
FROM alpine
9e205c
ENV VERSION=0.0.1
9e205c
COPY file-${VERSION}.txt /
9e205c
```
9e205c
9e205c
Buildah would not resolve the VERSION variable in the copy statement.
9e205c
If the 'ENV' in the above Containerfile was changed to ARG, then this
9e205c
would work.
9e205c
9e205c
A recent change to the handling of variables now only looks at variables
9e205c
set by 'ARG' and not the ones set by the 'ENV' command.  This PR
9e205c
adds the the variables set by the `ENV` to the list of `ARG` variables
9e205c
when those variables are being resolved by the code.
9e205c
9e205c
This also includes added test to guard against this regression in the future.
9e205c
9e205c
Addresses:  https://github.com/containers/libpod/issues/4878
9e205c
9e205c
Signed-off-by: TomSweeneyRedHat <tsweeney@redhat.com>
9e205c
---
9e205c
 imagebuildah/stage_executor.go       | 13 +++++++------
9e205c
 tests/bud.bats                       | 12 ++++++++++++
9e205c
 tests/bud/copy-envvar/Containerfile  |  3 +++
9e205c
 tests/bud/copy-envvar/file-0.0.1.txt |  0
9e205c
 4 files changed, 22 insertions(+), 6 deletions(-)
9e205c
 create mode 100644 tests/bud/copy-envvar/Containerfile
9e205c
 create mode 100644 tests/bud/copy-envvar/file-0.0.1.txt
9e205c
9e205c
diff --git a/imagebuildah/stage_executor.go b/imagebuildah/stage_executor.go
9e205c
index 4fd630a83..60fa10888 100644
9e205c
--- a/imagebuildah/stage_executor.go
9e205c
+++ b/imagebuildah/stage_executor.go
9e205c
@@ -253,7 +253,7 @@ func (s *StageExecutor) volumeCacheRestore() error {
9e205c
 // don't care about the details of where in the filesystem the content actually
9e205c
 // goes, because we're not actually going to add it here, so this is less
9e205c
 // involved than Copy().
9e205c
-func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []string) (string, error) {
9e205c
+func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []string, envValues []string) (string, error) {
9e205c
 	// No instruction: done.
9e205c
 	if node == nil {
9e205c
 		return "", nil
9e205c
@@ -298,10 +298,11 @@ func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []st
9e205c
 		}
9e205c
 	}
9e205c
 
9e205c
+	varValues := append(argValues, envValues...)
9e205c
 	for _, src := range srcs {
9e205c
 		// If src has an argument within it, resolve it to its
9e205c
 		// value.  Otherwise just return the value found.
9e205c
-		name, err := imagebuilder.ProcessWord(src, argValues)
9e205c
+		name, err := imagebuilder.ProcessWord(src, varValues)
9e205c
 		if err != nil {
9e205c
 			return "", errors.Wrapf(err, "unable to resolve source %q", src)
9e205c
 		}
9e205c
@@ -345,7 +346,7 @@ func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []st
9e205c
 
9e205c
 	// If destination.Value has an argument within it, resolve it to its
9e205c
 	// value.  Otherwise just return the value found.
9e205c
-	destValue, destErr := imagebuilder.ProcessWord(destination.Value, argValues)
9e205c
+	destValue, destErr := imagebuilder.ProcessWord(destination.Value, varValues)
9e205c
 	if destErr != nil {
9e205c
 		return "", errors.Wrapf(destErr, "unable to resolve destination %q", destination.Value)
9e205c
 	}
9e205c
@@ -868,7 +869,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
9e205c
 				return "", nil, errors.Wrapf(err, "error building at STEP \"%s\"", step.Message)
9e205c
 			}
9e205c
 			// In case we added content, retrieve its digest.
9e205c
-			addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments())
9e205c
+			addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments(), ib.Config().Env)
9e205c
 			if err != nil {
9e205c
 				return "", nil, err
9e205c
 			}
9e205c
@@ -917,7 +918,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
9e205c
 		// cached images so far, look for one that matches what we
9e205c
 		// expect to produce for this instruction.
9e205c
 		if checkForLayers && !(s.executor.squash && lastInstruction && lastStage) {
9e205c
-			addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments())
9e205c
+			addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments(), ib.Config().Env)
9e205c
 			if err != nil {
9e205c
 				return "", nil, err
9e205c
 			}
9e205c
@@ -975,7 +976,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
9e205c
 				return "", nil, errors.Wrapf(err, "error building at STEP \"%s\"", step.Message)
9e205c
 			}
9e205c
 			// In case we added content, retrieve its digest.
9e205c
-			addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments())
9e205c
+			addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments(), ib.Config().Env)
9e205c
 			if err != nil {
9e205c
 				return "", nil, err
9e205c
 			}
9e205c
diff --git a/tests/bud.bats b/tests/bud.bats
9e205c
index 022088b72..966864cae 100644
9e205c
--- a/tests/bud.bats
9e205c
+++ b/tests/bud.bats
9e205c
@@ -1882,3 +1882,15 @@ EOM
9e205c
   run_buildah 1 bud --signature-policy ${TESTSDIR}/policy.json -t ${target} -f ${TESTSDIR}/bud/copy/Dockerfile.url ${TESTSDIR}/bud/copy
9e205c
   rm -r ${TESTSDIR}/bud/copy
9e205c
 }
9e205c
+
9e205c
+@test "bud COPY with Env Var in Containerfile" {
9e205c
+  run_buildah bud --signature-policy ${TESTSDIR}/policy.json -t testctr ${TESTSDIR}/bud/copy-envvar
9e205c
+  run_buildah from testctr
9e205c
+  run_buildah run testctr-working-container ls /file-0.0.1.txt
9e205c
+  run_buildah rm -a
9e205c
+
9e205c
+  run_buildah bud --signature-policy ${TESTSDIR}/policy.json --layers -t testctr ${TESTSDIR}/bud/copy-envvar
9e205c
+  run_buildah from testctr
9e205c
+  run_buildah run testctr-working-container ls /file-0.0.1.txt
9e205c
+  run_buildah rm -a
9e205c
+}
9e205c
diff --git a/tests/bud/copy-envvar/Containerfile b/tests/bud/copy-envvar/Containerfile
9e205c
new file mode 100644
9e205c
index 000000000..0e8c9109d
9e205c
--- /dev/null
9e205c
+++ b/tests/bud/copy-envvar/Containerfile
9e205c
@@ -0,0 +1,3 @@
9e205c
+FROM alpine 
9e205c
+ENV VERSION=0.0.1
9e205c
+COPY file-${VERSION}.txt /
9e205c
diff --git a/tests/bud/copy-envvar/file-0.0.1.txt b/tests/bud/copy-envvar/file-0.0.1.txt
9e205c
new file mode 100644
9e205c
index 000000000..e69de29bb