Fix caching to respect .dockerignore

Previously kaniko would compute the cache key for any copy command by computing
the combined hash of all files in a directory, even if they were listed
as ignored.

With this change, the cache key creation was updated to be aware of ignored
files.

Related issues:
* https://github.com/GoogleContainerTools/kaniko/issues/594
This commit is contained in:
Moritz Wanzenböck 2019-11-11 17:48:03 +01:00 committed by Tejal Desai
parent a2aae6274d
commit 123dcaf83e
5 changed files with 27 additions and 13 deletions

View File

@ -158,8 +158,10 @@ func (s *stageBuilder) populateCompositeKey(command fmt.Stringer, files []string
compositeKey = s.populateCopyCmdCompositeKey(command, v.From(), compositeKey)
}
srcCtx := s.opts.SrcContext
for _, f := range files {
if err := compositeKey.AddPath(f); err != nil {
if err := compositeKey.AddPath(f, srcCtx); err != nil {
return compositeKey, err
}
}

View File

@ -54,14 +54,18 @@ func (s *CompositeCache) Hash() (string, error) {
return util.SHA256(strings.NewReader(s.Key()))
}
func (s *CompositeCache) AddPath(p string) error {
func (s *CompositeCache) AddPath(p, context string) error {
sha := sha256.New()
fi, err := os.Lstat(p)
if err != nil {
return err
}
if util.ExcludeFile(p, context) {
return os.ErrNotExist
}
if fi.Mode().IsDir() {
k, err := HashDir(p)
k, err := HashDir(p, context)
if err != nil {
return err
}
@ -81,12 +85,20 @@ func (s *CompositeCache) AddPath(p string) error {
}
// HashDir returns a hash of the directory.
func HashDir(p string) (string, error) {
func HashDir(p, context string) (string, error) {
sha := sha256.New()
if err := filepath.Walk(p, func(path string, fi os.FileInfo, err error) error {
if err != nil {
return err
}
exclude := util.ExcludeFile(path, context)
if fi.IsDir() && exclude {
return filepath.SkipDir
}
if exclude {
return nil
}
fileHash, err := util.CacheHasher()(path)
if err != nil {
return err

View File

@ -213,7 +213,7 @@ func IsSrcsValid(srcsAndDest instructions.SourcesAndDest, resolvedSources []stri
if !ContainsWildcards(srcs) {
totalSrcs := 0
for _, src := range srcs {
if excludeFile(src, root) {
if ExcludeFile(src, root) {
continue
}
totalSrcs++
@ -250,7 +250,7 @@ func IsSrcsValid(srcsAndDest instructions.SourcesAndDest, resolvedSources []stri
return errors.Wrap(err, "failed to get relative files")
}
for _, file := range files {
if excludeFile(file, root) {
if ExcludeFile(file, root) {
continue
}
totalFiles++

View File

@ -561,7 +561,7 @@ func CopyDir(src, dest, buildcontext string) ([]string, error) {
if err != nil {
return nil, err
}
if excludeFile(fullPath, buildcontext) {
if ExcludeFile(fullPath, buildcontext) {
logrus.Debugf("%s found in .dockerignore, ignoring", src)
continue
}
@ -594,7 +594,7 @@ func CopyDir(src, dest, buildcontext string) ([]string, error) {
// CopySymlink copies the symlink at src to dest
func CopySymlink(src, dest, buildcontext string) (bool, error) {
if excludeFile(src, buildcontext) {
if ExcludeFile(src, buildcontext) {
logrus.Debugf("%s found in .dockerignore, ignoring", src)
return true, nil
}
@ -612,7 +612,7 @@ func CopySymlink(src, dest, buildcontext string) (bool, error) {
// CopyFile copies the file at src to dest
func CopyFile(src, dest, buildcontext string) (bool, error) {
if excludeFile(src, buildcontext) {
if ExcludeFile(src, buildcontext) {
logrus.Debugf("%s found in .dockerignore, ignoring", src)
return true, nil
}
@ -656,8 +656,8 @@ func GetExcludedFiles(dockerfilepath string, buildcontext string) error {
return err
}
// excludeFile returns true if the .dockerignore specified this file should be ignored
func excludeFile(path, buildcontext string) bool {
// ExcludeFile returns true if the .dockerignore specified this file should be ignored
func ExcludeFile(path, buildcontext string) bool {
if HasFilepathPrefix(path, buildcontext, false) {
var err error
path, err = filepath.Rel(buildcontext, path)

View File

@ -919,14 +919,14 @@ func Test_correctDockerignoreFileIsUsed(t *testing.T) {
}
for _, excl := range tt.args.excluded {
t.Run(tt.name+" to exclude "+excl, func(t *testing.T) {
if !excludeFile(excl, tt.args.buildcontext) {
if !ExcludeFile(excl, tt.args.buildcontext) {
t.Errorf("'%v' not excluded", excl)
}
})
}
for _, incl := range tt.args.included {
t.Run(tt.name+" to include "+incl, func(t *testing.T) {
if excludeFile(incl, tt.args.buildcontext) {
if ExcludeFile(incl, tt.args.buildcontext) {
t.Errorf("'%v' not included", incl)
}
})