From 509303c9a939f9af4bb7bc3c2d2795f898395708 Mon Sep 17 00:00:00 2001 From: TomSweeneyRedHat Date: Sat, 6 Feb 2021 20:20:48 -0500 Subject: [PATCH] Don't fail copy to emptydir When a COPY command was being targeted at an empty new directory, the copy would fail. It could be "worked around" by putting a dummy file into the directory. Addresses: #2964 Signed-off-by: TomSweeneyRedHat Signed-off-by: Daniel J Walsh --- add.go | 13 +++++++++++++ tests/bud.bats | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/add.go b/add.go index dd69d45cf3..5842f195dc 100644 --- a/add.go +++ b/add.go @@ -303,6 +303,13 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption renameTarget = filepath.Base(extractDirectory) extractDirectory = filepath.Dir(extractDirectory) } + + // if the destination is a directory that doesn't yet exist, let's copy it. + newDestDirFound := false + if (len(destStats) == 1 || len(destStats[0].Globbed) == 0) && destMustBeDirectory && !destCanBeFile { + newDestDirFound = true + } + if len(destStats) == 1 && len(destStats[0].Globbed) == 1 && destStats[0].Results[destStats[0].Globbed[0]].IsRegular { if destMustBeDirectory { return errors.Errorf("destination %v already exists but is not a directory", destination) @@ -393,6 +400,12 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption // Iterate through every item that matched the glob. itemsCopied := 0 + + // if the destination is a directory that doesn't yet exist, let's copy it. + if newDestDirFound { + itemsCopied++ + } + for _, glob := range localSourceStat.Globbed { rel, err := filepath.Rel(contextDir, glob) if err != nil { diff --git a/tests/bud.bats b/tests/bud.bats index 97a6ffaeb2..3bc3683e57 100644 --- a/tests/bud.bats +++ b/tests/bud.bats @@ -2560,3 +2560,25 @@ _EOF run_buildah manifest inspect testlist expect_output --substring $digest } + +@test "bud test empty newdir" { + _prefetch alpine + mytmpdir=${TESTDIR}/my-dir + mkdir -p ${mytmpdir} +cat > $mytmpdir/Containerfile << _EOF +FROM alpine as galaxy + +RUN mkdir -p /usr/share/ansible/roles /usr/share/ansible/collections +RUN echo "bar" +RUN echo "foo" > /usr/share/ansible/collections/file.txt + +FROM galaxy + +RUN mkdir -p /usr/share/ansible/roles /usr/share/ansible/collections +COPY --from=galaxy /usr/share/ansible/roles /usr/share/ansible/roles +COPY --from=galaxy /usr/share/ansible/collections /usr/share/ansible/collections +_EOF + + run_buildah bud --layers --signature-policy ${TESTSDIR}/policy.json -t testbud $mytmpdir + expect_output --substring "COPY --from=galaxy /usr/share/ansible/collections /usr/share/ansible/collections" +}