fs/diff: support symlink to abspath with second-precision mtime

Previously, `Changes()` for a symlink to absolute path, with second-precision
mtime of the link itself always resulted in ENOENT.

This is because `compareFileContent()` was called for the link target path, without changing the root path.

Fix moby/buildkit#172

Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
This commit is contained in:
Akihiro Suda
2017-11-20 09:14:48 +00:00
parent 1bd39d36ed
commit a3aeb398fe
5 changed files with 88 additions and 19 deletions

View File

@@ -71,10 +71,11 @@ func Chown(name string, uid, gid int) Applier {
})
}
// Chtime changes access and mod time of file
func Chtime(name string, t time.Time) Applier {
// Chtimes changes access and mod time of file.
// Use Lchtimes for symbolic links.
func Chtimes(name string, atime, mtime time.Time) Applier {
return applyFn(func(root string) error {
return os.Chtimes(filepath.Join(root, name), t, t)
return os.Chtimes(filepath.Join(root, name), atime, mtime)
})
}

View File

@@ -2,7 +2,13 @@
package fstest
import "github.com/containerd/continuity/sysx"
import (
"path/filepath"
"time"
"github.com/containerd/continuity/sysx"
"golang.org/x/sys/unix"
)
// SetXAttr sets the xatter for the file
func SetXAttr(name, key, value string) Applier {
@@ -10,3 +16,14 @@ func SetXAttr(name, key, value string) Applier {
return sysx.LSetxattr(name, key, []byte(value), 0)
})
}
// Lchtimes changes access and mod time of file without following symlink
func Lchtimes(name string, atime, mtime time.Time) Applier {
return applyFn(func(root string) error {
path := filepath.Join(root, name)
at := unix.NsecToTimespec(atime.UnixNano())
mt := unix.NsecToTimespec(mtime.UnixNano())
utimes := [2]unix.Timespec{at, mt}
return unix.UtimesNanoAt(unix.AT_FDCWD, path, utimes[0:], unix.AT_SYMLINK_NOFOLLOW)
})
}

14
fs/fstest/file_windows.go Normal file
View File

@@ -0,0 +1,14 @@
package fstest
import (
"time"
"github.com/containerd/containerd/errdefs"
)
// Lchtimes changes access and mod time of file without following symlink
func Lchtimes(name string, atime, mtime time.Time) Applier {
return applyFn(func(root string) error {
return errdefs.ErrNotImplemented
})
}