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) compositeKey = s.populateCopyCmdCompositeKey(command, v.From(), compositeKey)
} }
srcCtx := s.opts.SrcContext
for _, f := range files { for _, f := range files {
if err := compositeKey.AddPath(f); err != nil { if err := compositeKey.AddPath(f, srcCtx); err != nil {
return compositeKey, err return compositeKey, err
} }
} }

View File

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

View File

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

View File

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

View File

@ -919,14 +919,14 @@ func Test_correctDockerignoreFileIsUsed(t *testing.T) {
} }
for _, excl := range tt.args.excluded { for _, excl := range tt.args.excluded {
t.Run(tt.name+" to exclude "+excl, func(t *testing.T) { 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) t.Errorf("'%v' not excluded", excl)
} }
}) })
} }
for _, incl := range tt.args.included { for _, incl := range tt.args.included {
t.Run(tt.name+" to include "+incl, func(t *testing.T) { 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) t.Errorf("'%v' not included", incl)
} }
}) })