Merge pull request #8748 from duglin/Issue8330
Have .dockerignore support Dockerfile/.dockerignore
This commit is contained in:
commit
73e5a67591
5 changed files with 59 additions and 23 deletions
|
@ -30,11 +30,11 @@ type (
|
||||||
ArchiveReader io.Reader
|
ArchiveReader io.Reader
|
||||||
Compression int
|
Compression int
|
||||||
TarOptions struct {
|
TarOptions struct {
|
||||||
Includes []string
|
IncludeFiles []string
|
||||||
Excludes []string
|
ExcludePatterns []string
|
||||||
Compression Compression
|
Compression Compression
|
||||||
NoLchown bool
|
NoLchown bool
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Archiver allows the reuse of most utility functions of this package
|
// Archiver allows the reuse of most utility functions of this package
|
||||||
|
@ -378,7 +378,7 @@ func escapeName(name string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TarWithOptions creates an archive from the directory at `path`, only including files whose relative
|
// TarWithOptions creates an archive from the directory at `path`, only including files whose relative
|
||||||
// paths are included in `options.Includes` (if non-nil) or not in `options.Excludes`.
|
// paths are included in `options.IncludeFiles` (if non-nil) or not in `options.ExcludePatterns`.
|
||||||
func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) {
|
func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) {
|
||||||
pipeReader, pipeWriter := io.Pipe()
|
pipeReader, pipeWriter := io.Pipe()
|
||||||
|
|
||||||
|
@ -401,12 +401,14 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
|
||||||
// mutating the filesystem and we can see transient errors
|
// mutating the filesystem and we can see transient errors
|
||||||
// from this
|
// from this
|
||||||
|
|
||||||
if options.Includes == nil {
|
if options.IncludeFiles == nil {
|
||||||
options.Includes = []string{"."}
|
options.IncludeFiles = []string{"."}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
seen := make(map[string]bool)
|
||||||
|
|
||||||
var renamedRelFilePath string // For when tar.Options.Name is set
|
var renamedRelFilePath string // For when tar.Options.Name is set
|
||||||
for _, include := range options.Includes {
|
for _, include := range options.IncludeFiles {
|
||||||
filepath.Walk(filepath.Join(srcPath, include), func(filePath string, f os.FileInfo, err error) error {
|
filepath.Walk(filepath.Join(srcPath, include), func(filePath string, f os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("Tar: Can't stat file %s to tar: %s", srcPath, err)
|
log.Debugf("Tar: Can't stat file %s to tar: %s", srcPath, err)
|
||||||
|
@ -420,10 +422,19 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
skip, err := fileutils.Matches(relFilePath, options.Excludes)
|
skip := false
|
||||||
if err != nil {
|
|
||||||
log.Debugf("Error matching %s", relFilePath, err)
|
// If "include" is an exact match for the current file
|
||||||
return err
|
// then even if there's an "excludePatterns" pattern that
|
||||||
|
// matches it, don't skip it. IOW, assume an explicit 'include'
|
||||||
|
// is asking for that file no matter what - which is true
|
||||||
|
// for some files, like .dockerignore and Dockerfile (sometimes)
|
||||||
|
if include != relFilePath {
|
||||||
|
skip, err = fileutils.Matches(relFilePath, options.ExcludePatterns)
|
||||||
|
if err != nil {
|
||||||
|
log.Debugf("Error matching %s", relFilePath, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if skip {
|
if skip {
|
||||||
|
@ -433,6 +444,11 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if seen[relFilePath] {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
seen[relFilePath] = true
|
||||||
|
|
||||||
// Rename the base resource
|
// Rename the base resource
|
||||||
if options.Name != "" && filePath == srcPath+"/"+filepath.Base(relFilePath) {
|
if options.Name != "" && filePath == srcPath+"/"+filepath.Base(relFilePath) {
|
||||||
renamedRelFilePath = relFilePath
|
renamedRelFilePath = relFilePath
|
||||||
|
@ -487,7 +503,7 @@ loop:
|
||||||
// This keeps "../" as-is, but normalizes "/../" to "/"
|
// This keeps "../" as-is, but normalizes "/../" to "/"
|
||||||
hdr.Name = filepath.Clean(hdr.Name)
|
hdr.Name = filepath.Clean(hdr.Name)
|
||||||
|
|
||||||
for _, exclude := range options.Excludes {
|
for _, exclude := range options.ExcludePatterns {
|
||||||
if strings.HasPrefix(hdr.Name, exclude) {
|
if strings.HasPrefix(hdr.Name, exclude) {
|
||||||
continue loop
|
continue loop
|
||||||
}
|
}
|
||||||
|
@ -563,8 +579,8 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error {
|
||||||
if options == nil {
|
if options == nil {
|
||||||
options = &TarOptions{}
|
options = &TarOptions{}
|
||||||
}
|
}
|
||||||
if options.Excludes == nil {
|
if options.ExcludePatterns == nil {
|
||||||
options.Excludes = []string{}
|
options.ExcludePatterns = []string{}
|
||||||
}
|
}
|
||||||
decompressedArchive, err := DecompressStream(archive)
|
decompressedArchive, err := DecompressStream(archive)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -165,8 +165,8 @@ func TestTarUntar(t *testing.T) {
|
||||||
Gzip,
|
Gzip,
|
||||||
} {
|
} {
|
||||||
changes, err := tarUntar(t, origin, &TarOptions{
|
changes, err := tarUntar(t, origin, &TarOptions{
|
||||||
Compression: c,
|
Compression: c,
|
||||||
Excludes: []string{"3"},
|
ExcludePatterns: []string{"3"},
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -196,8 +196,8 @@ func TestTarWithOptions(t *testing.T) {
|
||||||
opts *TarOptions
|
opts *TarOptions
|
||||||
numChanges int
|
numChanges int
|
||||||
}{
|
}{
|
||||||
{&TarOptions{Includes: []string{"1"}}, 1},
|
{&TarOptions{IncludeFiles: []string{"1"}}, 1},
|
||||||
{&TarOptions{Excludes: []string{"2"}}, 1},
|
{&TarOptions{ExcludePatterns: []string{"2"}}, 1},
|
||||||
}
|
}
|
||||||
for _, testCase := range cases {
|
for _, testCase := range cases {
|
||||||
changes, err := tarUntar(t, origin, testCase.opts)
|
changes, err := tarUntar(t, origin, testCase.opts)
|
||||||
|
|
|
@ -50,8 +50,8 @@ func Untar(tarArchive io.Reader, dest string, options *archive.TarOptions) error
|
||||||
if options == nil {
|
if options == nil {
|
||||||
options = &archive.TarOptions{}
|
options = &archive.TarOptions{}
|
||||||
}
|
}
|
||||||
if options.Excludes == nil {
|
if options.ExcludePatterns == nil {
|
||||||
options.Excludes = []string{}
|
options.ExcludePatterns = []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -40,7 +40,7 @@ func TestChrootTarUntar(t *testing.T) {
|
||||||
if err := os.MkdirAll(dest, 0700); err != nil {
|
if err := os.MkdirAll(dest, 0700); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := Untar(stream, dest, &archive.TarOptions{Excludes: []string{"lolo"}}); err != nil {
|
if err := Untar(stream, dest, &archive.TarOptions{ExcludePatterns: []string{"lolo"}}); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
tarsum/builder_context.go
Normal file
20
tarsum/builder_context.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package tarsum
|
||||||
|
|
||||||
|
// This interface extends TarSum by adding the Remove method. In general
|
||||||
|
// there was concern about adding this method to TarSum itself so instead
|
||||||
|
// it is being added just to "BuilderContext" which will then only be used
|
||||||
|
// during the .dockerignore file processing - see builder/evaluator.go
|
||||||
|
type BuilderContext interface {
|
||||||
|
TarSum
|
||||||
|
Remove(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc *tarSum) Remove(filename string) {
|
||||||
|
for i, fis := range bc.sums {
|
||||||
|
if fis.Name() == filename {
|
||||||
|
bc.sums = append(bc.sums[:i], bc.sums[i+1:]...)
|
||||||
|
// Note, we don't just return because there could be
|
||||||
|
// more than one with this name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue