diff --git a/integration/dockerfiles/Dockerfile_test_mv_add b/integration/dockerfiles/Dockerfile_test_mv_add index 2f156edca0..a81e2318a9 100644 --- a/integration/dockerfiles/Dockerfile_test_mv_add +++ b/integration/dockerfiles/Dockerfile_test_mv_add @@ -1,3 +1,4 @@ FROM busybox@sha256:1bd6df27274fef1dd36eb529d0f4c8033f61c675d6b04213dd913f902f7cafb5 ADD context/tars /tmp/tars RUN mv /tmp/tars /foo +RUN echo "hi" diff --git a/pkg/snapshot/layered_map.go b/pkg/snapshot/layered_map.go index e8574e9136..6fd0ca4ac6 100644 --- a/pkg/snapshot/layered_map.go +++ b/pkg/snapshot/layered_map.go @@ -22,8 +22,9 @@ import ( ) type LayeredMap struct { - layers []map[string]string - hasher func(string) (string, error) + layers []map[string]string + whiteouts []map[string]string + hasher func(string) (string, error) } func NewLayeredMap(h func(string) (string, error)) *LayeredMap { @@ -35,6 +36,7 @@ func NewLayeredMap(h func(string) (string, error)) *LayeredMap { } func (l *LayeredMap) Snapshot() { + l.whiteouts = append(l.whiteouts, map[string]string{}) l.layers = append(l.layers, map[string]string{}) } @@ -62,6 +64,24 @@ func (l *LayeredMap) Get(s string) (string, bool) { return "", false } +func (l *LayeredMap) GetWhiteout(s string) (string, bool) { + for i := len(l.whiteouts) - 1; i >= 0; i-- { + if v, ok := l.whiteouts[i][s]; ok { + return v, ok + } + } + return "", false +} + +func (l *LayeredMap) MaybeAddWhiteout(s string) (bool, error) { + whiteout, ok := l.GetWhiteout(s) + if ok && whiteout == s { + return false, nil + } + l.whiteouts[len(l.whiteouts)-1][s] = s + return true, nil +} + func (l *LayeredMap) MaybeAdd(s string) (bool, error) { oldV, ok := l.Get(s) newV, err := l.hasher(s) diff --git a/pkg/snapshot/snapshot.go b/pkg/snapshot/snapshot.go index d6e80dc171..8b17a354dd 100644 --- a/pkg/snapshot/snapshot.go +++ b/pkg/snapshot/snapshot.go @@ -19,12 +19,13 @@ package snapshot import ( "archive/tar" "bytes" - "github.com/GoogleContainerTools/kaniko/pkg/util" - "github.com/sirupsen/logrus" "io" "io/ioutil" "os" "path/filepath" + + "github.com/GoogleContainerTools/kaniko/pkg/util" + "github.com/sirupsen/logrus" ) // Snapshotter holds the root directory from which to take snapshots, and a list of snapshots taken @@ -103,11 +104,11 @@ func (s *Snapshotter) snapshotFiles(f io.Writer, files []string) (bool, error) { return false, err } // Only add to the tar if we add it to the layeredmap. - maybeAdd, err := s.l.MaybeAdd(file) + addFile, err := s.l.MaybeAdd(file) if err != nil { return false, err } - if maybeAdd { + if addFile { filesAdded = true if err := util.AddToTar(file, info, s.hardlinks, w); err != nil { return false, err @@ -141,10 +142,16 @@ func (s *Snapshotter) snapShotFS(f io.Writer) (bool, error) { // Only add the whiteout if the directory for the file still exists. dir := filepath.Dir(path) if _, ok := memFs[dir]; ok { - logrus.Infof("Adding whiteout for %s", path) - filesAdded = true - if err := util.Whiteout(path, w); err != nil { - return false, err + addWhiteout, err := s.l.MaybeAddWhiteout(path) + if err != nil { + return false, nil + } + if addWhiteout { + logrus.Infof("Adding whiteout for %s", path) + filesAdded = true + if err := util.Whiteout(path, w); err != nil { + return false, err + } } } }