From 3504fae6f2a0db71d9de031252c464487d951f15 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Fri, 16 Aug 2019 14:40:50 -0700 Subject: [PATCH] contenthash: fix symlinks with unscanned parents Signed-off-by: Tonis Tiigi --- cache/contenthash/checksum.go | 15 ++++++------ cache/contenthash/checksum_test.go | 39 ++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/cache/contenthash/checksum.go b/cache/contenthash/checksum.go index 2574eaa2..5d42d041 100644 --- a/cache/contenthash/checksum.go +++ b/cache/contenthash/checksum.go @@ -792,7 +792,7 @@ func getFollowLinksWalk(root *iradix.Node, k []byte, follow bool, linksWalked *i return k, v.(*CacheRecord), nil } if !follow || len(k) == 0 { - return nil, nil, nil + return k, nil, nil } dir, file := splitKey(k) @@ -817,14 +817,13 @@ func getFollowLinksWalk(root *iradix.Node, k []byte, follow bool, linksWalked *i } return getFollowLinksWalk(root, append(convertPathToKey([]byte(link)), file...), follow, linksWalked) } - - k = append(k, file...) - v, ok = root.Get(k) - if ok { - return k, v.(*CacheRecord), nil - } } - return nil, nil, nil + k = append(k, file...) + v, ok = root.Get(k) + if ok { + return k, v.(*CacheRecord), nil + } + return k, nil, nil } func prepareDigest(fp, p string, fi os.FileInfo) (digest.Digest, error) { diff --git a/cache/contenthash/checksum_test.go b/cache/contenthash/checksum_test.go index f07e2c64..5813da3a 100644 --- a/cache/contenthash/checksum_test.go +++ b/cache/contenthash/checksum_test.go @@ -29,6 +29,35 @@ const ( dgstDirD0Modified = digest.Digest("sha256:555ffa3028630d97ba37832b749eda85ab676fd64ffb629fbf0f4ec8c1e3bff1") ) +func TestChecksumSymlinkNoParentScan(t *testing.T) { + t.Parallel() + tmpdir, err := ioutil.TempDir("", "buildkit-state") + require.NoError(t, err) + defer os.RemoveAll(tmpdir) + + snapshotter, err := native.NewSnapshotter(filepath.Join(tmpdir, "snapshots")) + require.NoError(t, err) + cm := setupCacheManager(t, tmpdir, "native", snapshotter) + defer cm.Close() + + ch := []string{ + "ADD aa dir", + "ADD aa/bb dir", + "ADD aa/bb/cc dir", + "ADD aa/bb/cc/dd file data0", + "ADD aa/ln symlink /aa", + } + + ref := createRef(t, cm, ch) + + cc, err := newCacheContext(ref.Metadata(), nil) + require.NoError(t, err) + + dgst, err := cc.Checksum(context.TODO(), ref, "aa/ln/bb/cc/dd", true) + require.NoError(t, err) + require.Equal(t, dgstFileData0, dgst) +} + func TestChecksumHardlinks(t *testing.T) { t.Parallel() tmpdir, err := ioutil.TempDir("", "buildkit-state") @@ -963,11 +992,11 @@ func writeChanges(root string, inp []*change) error { // The snapshot root ('/') is always created with 0755. // We use the same permission mode here. if err := os.Mkdir(p, 0755); err != nil { - return err + return errors.WithStack(err) } } else if c.fi.Mode()&os.ModeSymlink != 0 { if err := os.Symlink(stat.Linkname, p); err != nil { - return err + return errors.WithStack(err) } } else if len(stat.Linkname) > 0 { link := filepath.Join(root, stat.Linkname) @@ -975,16 +1004,16 @@ func writeChanges(root string, inp []*change) error { link = filepath.Join(filepath.Dir(p), stat.Linkname) } if err := os.Link(link, p); err != nil { - return err + return errors.WithStack(err) } } else { f, err := os.Create(p) if err != nil { - return err + return errors.WithStack(err) } if len(c.data) > 0 { if _, err := f.Write([]byte(c.data)); err != nil { - return err + return errors.WithStack(err) } } f.Close()