diff --git a/lib/snapshot/copy_op.go b/lib/snapshot/copy_op.go index 26ef53e5..65181577 100644 --- a/lib/snapshot/copy_op.go +++ b/lib/snapshot/copy_op.go @@ -73,12 +73,7 @@ func NewCopyOperation( // Execute performs the actual copying of files specified by the CopyOperation. func (c *CopyOperation) Execute() error { - var err error for _, src := range c.srcs { - src, err = evalSymlinks(src, c.srcRoot) - if err != nil { - return fmt.Errorf("eval symlinks for %s: %s", src, err) - } src = filepath.Join(c.srcRoot, src) fi, err := os.Lstat(src) if err != nil { diff --git a/lib/snapshot/mem_fs.go b/lib/snapshot/mem_fs.go index 994e7b12..a01fdf16 100644 --- a/lib/snapshot/mem_fs.go +++ b/lib/snapshot/mem_fs.go @@ -112,7 +112,7 @@ func (fs *MemFS) Checkpoint(newRoot string, sources []string) error { return fmt.Errorf("trim src %s: %s", src, err) } dst := filepath.Join(newRoot, trimmedSrc) - sourceInfo, err := os.Stat(src) + sourceInfo, err := os.Lstat(src) if err != nil { return fmt.Errorf("stat %s: %s", src, err) } @@ -337,12 +337,11 @@ func (fs *MemFS) createLayerByScan() (*memLayer, error) { // - files copied to dir2 // - contents of dirs copied to dir2 func (fs *MemFS) addToLayer(l *memLayer, c *CopyOperation) error { - var err error createDst := true if len(c.srcs) == 1 { src := filepath.Join(c.srcRoot, c.srcs[0]) - if fi, err := os.Stat(src); err != nil { + if fi, err := os.Lstat(src); err != nil { return fmt.Errorf("stat src %s: %s", src, err) } else if !fi.IsDir() { // Case 1, no need to ensure dst exists explicitly. @@ -363,10 +362,6 @@ func (fs *MemFS) addToLayer(l *memLayer, c *CopyOperation) error { } for _, src := range c.srcs { - src, err = evalSymlinks(src, c.srcRoot) - if err != nil { - return fmt.Errorf("eval symlinks for %s: %s", src, err) - } src = filepath.Join(c.srcRoot, src) if err := walk(src, nil, func(currSrc string, fi os.FileInfo) error { var currDst string @@ -577,13 +572,6 @@ func (fs *MemFS) untarOneItem(path string, header *tar.Header, r *tar.Reader) er if err != nil { return fmt.Errorf("read link %s: %s", linkTarget, err) } - - if filepath.IsAbs(linkTarget) { - linkTarget, err = pathutils.TrimRoot(linkTarget, fs.tree.src) - if err != nil { - return fmt.Errorf("trim link %s: %s", linkTarget, err) - } - } } localHeader, err := tar.FileInfoHeader(localInfo, linkTarget) if err != nil { diff --git a/lib/snapshot/mem_fs_test.go b/lib/snapshot/mem_fs_test.go index cb0ce374..5ed95458 100644 --- a/lib/snapshot/mem_fs_test.go +++ b/lib/snapshot/mem_fs_test.go @@ -55,19 +55,22 @@ func TestUntarFromPath(t *testing.T) { require.NoError(err) err = ioutil.WriteFile(filepath.Join(src, "target.txt"), []byte("TARGET"), 0677) // 6 require.NoError(err) - err = os.Symlink(filepath.Join(src, "target.txt"), filepath.Join(src, "mydir")) // 7 + err = os.Symlink("/target.txt", filepath.Join(src, "mydir")) // 7 require.NoError(err) err = CreateTarFromDirectory(filepath.Join(tmpBase, "archive1.tar"), src) require.NoError(err) - // Files already existing under the memfs root. + // Files already exist under the memfs root. err = os.Mkdir(filepath.Join(tmpRoot, "test1"), os.ModePerm) require.NoError(err) err = ioutil.WriteFile(filepath.Join(tmpRoot, "test1", "test1.txt"), []byte("TEST1"), 0677) require.NoError(err) err = os.Mkdir(filepath.Join(tmpRoot, "mydir"), os.ModePerm) require.NoError(err) + err = os.Symlink(filepath.Join("/test1", "test1.txt"), + filepath.Join(tmpRoot, "test1", "abs_symlink.txt")) + require.NoError(err) clk := clock.NewMock() fs, err := NewMemFS(clk, tmpRoot, pathutils.DefaultBlacklist) @@ -95,7 +98,7 @@ func TestUntarFromPath(t *testing.T) { require.Equal(7, fs.layers[len(fs.layers)-1].count()) - // Whiteout files already existing in the memfs. + // Whiteout files already exist in the memfs. err = os.Mkdir(filepath.Join(src2, ".wh.test.txt"), os.ModePerm) require.NoError(err) err = os.Mkdir(filepath.Join(src2, ".wh.test1"), os.ModePerm) diff --git a/lib/snapshot/mem_layer.go b/lib/snapshot/mem_layer.go index 66ea7892..37c82680 100644 --- a/lib/snapshot/mem_layer.go +++ b/lib/snapshot/mem_layer.go @@ -172,7 +172,7 @@ func (l *memLayer) createHeader(root, src, dst string, fi os.FileInfo) (*tar.Hea } else if !ok { return nil, fmt.Errorf("symlink in tar header but not on disk: %s", src) } else { - if filepath.IsAbs(target) { + if filepath.IsAbs(target) && strings.HasPrefix(target, root) { target, err = pathutils.TrimRoot(target, root) if err != nil { return nil, fmt.Errorf("trim symlink root: %s", err) diff --git a/lib/snapshot/utils.go b/lib/snapshot/utils.go index 19f1582a..7769b725 100644 --- a/lib/snapshot/utils.go +++ b/lib/snapshot/utils.go @@ -148,8 +148,8 @@ func resolveSymlink(p string, fi os.FileInfo) (bool, string, error) { return true, target, nil } -// CreateTarFromDirectory creates a tar archive containing the contents of the given -// directory. It also compresses the contents with given compression level. +// CreateTarFromDirectory creates a tar archive containing the contents of the +// given directory. It also compresses the content with given compression level. func CreateTarFromDirectory(target, dir string) error { file, err := os.Create(target) if err != nil { @@ -178,7 +178,8 @@ func CreateTarFromDirectory(target, dir string) error { }) } -// tarOneItem writes the header and (optionally) data corresponding to p to the tar writer. +// tarOneItem writes the header and (optionally) data corresponding to p to the +// tar writer. func tarOneItem(root, p string, fi os.FileInfo, tw *tar.Writer, inodes map[uint64]string) error { var err error link := fi.Name() @@ -187,10 +188,6 @@ func tarOneItem(root, p string, fi os.FileInfo, tw *tar.Writer, inodes map[uint6 if err != nil { return fmt.Errorf("read link: %s", err) } - link, err = pathutils.TrimRoot(link, root) - if err != nil { - return fmt.Errorf("trim link: %s", err) - } } hdr, err := tar.FileInfoHeader(fi, link) if err != nil {