diff --git a/add.go b/add.go index f17e3a9c943..f4e2943f057 100644 --- a/add.go +++ b/add.go @@ -47,8 +47,10 @@ type AddAndCopyOptions struct { // If the sources include directory trees, Hasher will be passed // tar-format archives of the directory trees. Hasher io.Writer - // Excludes is the contents of the .dockerignore file. + // Excludes is the contents of the .containerignore file. Excludes []string + // IgnoreFile is the path to the .containerignore file. + IgnoreFile string // ContextDir is the base directory for content being copied and // Excludes patterns. ContextDir string @@ -564,7 +566,11 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption } } if itemsCopied == 0 { - return errors.Wrapf(syscall.ENOENT, "no items matching glob %q copied (%d filtered out)", localSourceStat.Glob, len(localSourceStat.Globbed)) + excludesFile := "" + if options.IgnoreFile != "" { + excludesFile = " using " + options.IgnoreFile + } + return errors.Wrapf(syscall.ENOENT, "no items matching glob %q copied (%d filtered out%s)", localSourceStat.Glob, len(localSourceStat.Globbed), excludesFile) } } return nil diff --git a/cmd/buildah/addcopy.go b/cmd/buildah/addcopy.go index 48c14b4934b..a77adb5ad41 100644 --- a/cmd/buildah/addcopy.go +++ b/cmd/buildah/addcopy.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -12,7 +11,6 @@ import ( "github.com/containers/buildah/pkg/parse" "github.com/containers/common/pkg/auth" "github.com/containers/storage" - "github.com/openshift/imagebuilder" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -231,11 +229,8 @@ func addAndCopyCmd(c *cobra.Command, args []string, verb string, iopts addCopyRe } if iopts.contextdir != "" { var excludes []string - if iopts.ignoreFile != "" { - excludes, err = parseIgnore(iopts.ignoreFile) - } else { - excludes, err = imagebuilder.ParseDockerignore(contextdir) - } + + excludes, options.IgnoreFile, err = parse.ContainerIgnoreFile(options.ContextDir, iopts.ignoreFile) if err != nil { return err } @@ -273,18 +268,3 @@ func addAndCopyCmd(c *cobra.Command, args []string, verb string, iopts addCopyRe conditionallyAddHistory(builder, c, "/bin/sh -c #(nop) %s %s%s", verb, contentType, digest.Hex()) return builder.Save() } - -func parseIgnore(ignoreFile string) ([]string, error) { - var excludes []string - ignore, err := ioutil.ReadFile(ignoreFile) - if err != nil { - return excludes, err - } - for _, e := range strings.Split(string(ignore), "\n") { - if len(e) == 0 || e[0] == '#' { - continue - } - excludes = append(excludes, e) - } - return excludes, nil -} diff --git a/cmd/buildah/build.go b/cmd/buildah/build.go index 3bab1637510..bc5898d541d 100644 --- a/cmd/buildah/build.go +++ b/cmd/buildah/build.go @@ -317,7 +317,7 @@ func buildCmd(c *cobra.Command, inputArgs []string, iopts buildOptions) error { var excludes []string if iopts.IgnoreFile != "" { - if excludes, err = parseIgnore(iopts.IgnoreFile); err != nil { + if excludes, _, err = parse.ContainerIgnoreFile(contextDir, iopts.IgnoreFile); err != nil { return err } } @@ -350,6 +350,7 @@ func buildCmd(c *cobra.Command, inputArgs []string, iopts buildOptions) error { IIDFile: iopts.Iidfile, In: stdin, Isolation: isolation, + IgnoreFile: iopts.IgnoreFile, Labels: iopts.Label, Layers: layers, LogRusage: iopts.LogRusage, diff --git a/define/build.go b/define/build.go index c9e3f4a7d73..f5db8a9aaa6 100644 --- a/define/build.go +++ b/define/build.go @@ -227,6 +227,8 @@ type BuildOptions struct { RusageLogFile string // Excludes is a list of excludes to be used instead of the .dockerignore file. Excludes []string + // IgnoreFile is a name of the .containerignore file + IgnoreFile string // From is the image name to use to replace the value specified in the first // FROM instruction in the Containerfile From string diff --git a/imagebuildah/executor.go b/imagebuildah/executor.go index 0afe0a8f72d..ea81cab15a3 100644 --- a/imagebuildah/executor.go +++ b/imagebuildah/executor.go @@ -101,6 +101,7 @@ type Executor struct { rootfsMap map[string]bool // Holds the names of every stage whose rootfs is referenced in a COPY or ADD instruction. blobDirectory string excludes []string + ignoreFile string unusedArgs map[string]struct{} capabilities []string devices define.ContainerDevices @@ -143,7 +144,7 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o excludes := options.Excludes if len(excludes) == 0 { - excludes, err = imagebuilder.ParseDockerignore(options.ContextDirectory) + excludes, options.IgnoreFile, err = parse.ContainerIgnoreFile(options.ContextDirectory, options.IgnoreFile) if err != nil { return nil, err } @@ -208,6 +209,7 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o store: store, contextDir: options.ContextDirectory, excludes: excludes, + ignoreFile: options.IgnoreFile, pullPolicy: options.PullPolicy, registry: options.Registry, ignoreUnrecognizedInstructions: options.IgnoreUnrecognizedInstructions, diff --git a/imagebuildah/stage_executor.go b/imagebuildah/stage_executor.go index 059dbada337..1d1f174bed6 100644 --- a/imagebuildah/stage_executor.go +++ b/imagebuildah/stage_executor.go @@ -401,6 +401,7 @@ func (s *StageExecutor) Copy(excludes []string, copies ...imagebuilder.Copy) err PreserveOwnership: preserveOwnership, ContextDir: contextDir, Excludes: copyExcludes, + IgnoreFile: s.executor.ignoreFile, IDMappingOptions: idMappingOptions, StripSetuidBit: stripSetuid, StripSetgidBit: stripSetgid, diff --git a/pkg/parse/parse.go b/pkg/parse/parse.go index 99aa62b28d4..bde6cf71374 100644 --- a/pkg/parse/parse.go +++ b/pkg/parse/parse.go @@ -22,6 +22,7 @@ import ( "github.com/containers/storage/pkg/unshare" units "github.com/docker/go-units" specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/openshift/imagebuilder" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -1231,3 +1232,20 @@ func SSH(sshSources []string) (map[string]*sshagent.Source, error) { } return parsed, nil } + +func ContainerIgnoreFile(contextDir, path string) ([]string, string, error) { + if path != "" { + excludes, err := imagebuilder.ParseIgnore(path) + return excludes, path, err + } + path = filepath.Join(contextDir, ".containerignore") + excludes, err := imagebuilder.ParseIgnore(path) + if os.IsNotExist(err) { + path = filepath.Join(contextDir, ".dockerignore") + excludes, err = imagebuilder.ParseIgnore(path) + } + if os.IsNotExist(err) { + return excludes, "", nil + } + return excludes, path, err +} diff --git a/tests/bud.bats b/tests/bud.bats index eeb4a338611..3eadf1d2814 100644 --- a/tests/bud.bats +++ b/tests/bud.bats @@ -110,6 +110,7 @@ symlink(subdir)" @test "bud with .dockerignore #2" { run_buildah 125 build -t testbud3 --signature-policy ${TESTSDIR}/policy.json ${TESTSDIR}/bud/dockerignore3 expect_output --substring 'error building.*"COPY test1.txt /upload/test1.txt".*no such file or directory' + expect_output --substring $(realpath "${TESTSDIR}/bud/dockerignore3/.dockerignore") } @test "bud-flags-order-verification" {