summaryrefslogtreecommitdiff
path: root/vendor/github.com/containerd/continuity/fs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/containerd/continuity/fs')
-rw-r--r--vendor/github.com/containerd/continuity/fs/copy.go176
-rw-r--r--vendor/github.com/containerd/continuity/fs/copy_darwinopenbsdsolaris.go40
-rw-r--r--vendor/github.com/containerd/continuity/fs/copy_freebsd.go42
-rw-r--r--vendor/github.com/containerd/continuity/fs/copy_linux.go147
-rw-r--r--vendor/github.com/containerd/continuity/fs/copy_unix.go102
-rw-r--r--vendor/github.com/containerd/continuity/fs/copy_windows.go49
-rw-r--r--vendor/github.com/containerd/continuity/fs/diff.go326
-rw-r--r--vendor/github.com/containerd/continuity/fs/diff_unix.go74
-rw-r--r--vendor/github.com/containerd/continuity/fs/diff_windows.go48
-rw-r--r--vendor/github.com/containerd/continuity/fs/dtype_linux.go103
-rw-r--r--vendor/github.com/containerd/continuity/fs/du.go38
-rw-r--r--vendor/github.com/containerd/continuity/fs/du_unix.go120
-rw-r--r--vendor/github.com/containerd/continuity/fs/du_windows.go82
-rw-r--r--vendor/github.com/containerd/continuity/fs/hardlink.go43
-rw-r--r--vendor/github.com/containerd/continuity/fs/hardlink_unix.go34
-rw-r--r--vendor/github.com/containerd/continuity/fs/hardlink_windows.go23
-rw-r--r--vendor/github.com/containerd/continuity/fs/path.go311
-rw-r--r--vendor/github.com/containerd/continuity/fs/stat_darwinfreebsd.go44
-rw-r--r--vendor/github.com/containerd/continuity/fs/stat_linuxopenbsd.go45
-rw-r--r--vendor/github.com/containerd/continuity/fs/time.go29
20 files changed, 0 insertions, 1876 deletions
diff --git a/vendor/github.com/containerd/continuity/fs/copy.go b/vendor/github.com/containerd/continuity/fs/copy.go
deleted file mode 100644
index 818bba2cd..000000000
--- a/vendor/github.com/containerd/continuity/fs/copy.go
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "io/ioutil"
- "os"
- "path/filepath"
- "sync"
-
- "github.com/pkg/errors"
-)
-
-var bufferPool = &sync.Pool{
- New: func() interface{} {
- buffer := make([]byte, 32*1024)
- return &buffer
- },
-}
-
-// XAttrErrorHandlers transform a non-nil xattr error.
-// Return nil to ignore an error.
-// xattrKey can be empty for listxattr operation.
-type XAttrErrorHandler func(dst, src, xattrKey string, err error) error
-
-type copyDirOpts struct {
- xeh XAttrErrorHandler
-}
-
-type CopyDirOpt func(*copyDirOpts) error
-
-// WithXAttrErrorHandler allows specifying XAttrErrorHandler
-// If nil XAttrErrorHandler is specified (default), CopyDir stops
-// on a non-nil xattr error.
-func WithXAttrErrorHandler(xeh XAttrErrorHandler) CopyDirOpt {
- return func(o *copyDirOpts) error {
- o.xeh = xeh
- return nil
- }
-}
-
-// WithAllowXAttrErrors allows ignoring xattr errors.
-func WithAllowXAttrErrors() CopyDirOpt {
- xeh := func(dst, src, xattrKey string, err error) error {
- return nil
- }
- return WithXAttrErrorHandler(xeh)
-}
-
-// CopyDir copies the directory from src to dst.
-// Most efficient copy of files is attempted.
-func CopyDir(dst, src string, opts ...CopyDirOpt) error {
- var o copyDirOpts
- for _, opt := range opts {
- if err := opt(&o); err != nil {
- return err
- }
- }
- inodes := map[uint64]string{}
- return copyDirectory(dst, src, inodes, &o)
-}
-
-func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) error {
- stat, err := os.Stat(src)
- if err != nil {
- return errors.Wrapf(err, "failed to stat %s", src)
- }
- if !stat.IsDir() {
- return errors.Errorf("source %s is not directory", src)
- }
-
- if st, err := os.Stat(dst); err != nil {
- if err := os.Mkdir(dst, stat.Mode()); err != nil {
- return errors.Wrapf(err, "failed to mkdir %s", dst)
- }
- } else if !st.IsDir() {
- return errors.Errorf("cannot copy to non-directory: %s", dst)
- } else {
- if err := os.Chmod(dst, stat.Mode()); err != nil {
- return errors.Wrapf(err, "failed to chmod on %s", dst)
- }
- }
-
- fis, err := ioutil.ReadDir(src)
- if err != nil {
- return errors.Wrapf(err, "failed to read %s", src)
- }
-
- if err := copyFileInfo(stat, dst); err != nil {
- return errors.Wrapf(err, "failed to copy file info for %s", dst)
- }
-
- if err := copyXAttrs(dst, src, o.xeh); err != nil {
- return errors.Wrap(err, "failed to copy xattrs")
- }
-
- for _, fi := range fis {
- source := filepath.Join(src, fi.Name())
- target := filepath.Join(dst, fi.Name())
-
- switch {
- case fi.IsDir():
- if err := copyDirectory(target, source, inodes, o); err != nil {
- return err
- }
- continue
- case (fi.Mode() & os.ModeType) == 0:
- link, err := getLinkSource(target, fi, inodes)
- if err != nil {
- return errors.Wrap(err, "failed to get hardlink")
- }
- if link != "" {
- if err := os.Link(link, target); err != nil {
- return errors.Wrap(err, "failed to create hard link")
- }
- } else if err := CopyFile(target, source); err != nil {
- return errors.Wrap(err, "failed to copy files")
- }
- case (fi.Mode() & os.ModeSymlink) == os.ModeSymlink:
- link, err := os.Readlink(source)
- if err != nil {
- return errors.Wrapf(err, "failed to read link: %s", source)
- }
- if err := os.Symlink(link, target); err != nil {
- return errors.Wrapf(err, "failed to create symlink: %s", target)
- }
- case (fi.Mode() & os.ModeDevice) == os.ModeDevice:
- if err := copyDevice(target, fi); err != nil {
- return errors.Wrapf(err, "failed to create device")
- }
- default:
- // TODO: Support pipes and sockets
- return errors.Wrapf(err, "unsupported mode %s", fi.Mode())
- }
- if err := copyFileInfo(fi, target); err != nil {
- return errors.Wrap(err, "failed to copy file info")
- }
-
- if err := copyXAttrs(target, source, o.xeh); err != nil {
- return errors.Wrap(err, "failed to copy xattrs")
- }
- }
-
- return nil
-}
-
-// CopyFile copies the source file to the target.
-// The most efficient means of copying is used for the platform.
-func CopyFile(target, source string) error {
- src, err := os.Open(source)
- if err != nil {
- return errors.Wrapf(err, "failed to open source %s", source)
- }
- defer src.Close()
- tgt, err := os.Create(target)
- if err != nil {
- return errors.Wrapf(err, "failed to open target %s", target)
- }
- defer tgt.Close()
-
- return copyFileContent(tgt, src)
-}
diff --git a/vendor/github.com/containerd/continuity/fs/copy_darwinopenbsdsolaris.go b/vendor/github.com/containerd/continuity/fs/copy_darwinopenbsdsolaris.go
deleted file mode 100644
index 92ccacf9a..000000000
--- a/vendor/github.com/containerd/continuity/fs/copy_darwinopenbsdsolaris.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// +build darwin openbsd solaris
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "os"
- "syscall"
-
- "github.com/pkg/errors"
- "golang.org/x/sys/unix"
-)
-
-func copyDevice(dst string, fi os.FileInfo) error {
- st, ok := fi.Sys().(*syscall.Stat_t)
- if !ok {
- return errors.New("unsupported stat type")
- }
- return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev))
-}
-
-func utimesNano(name string, atime, mtime syscall.Timespec) error {
- timespec := []syscall.Timespec{atime, mtime}
- return syscall.UtimesNano(name, timespec)
-}
diff --git a/vendor/github.com/containerd/continuity/fs/copy_freebsd.go b/vendor/github.com/containerd/continuity/fs/copy_freebsd.go
deleted file mode 100644
index 4b116c95e..000000000
--- a/vendor/github.com/containerd/continuity/fs/copy_freebsd.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// +build freebsd
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "os"
- "syscall"
-
- "github.com/pkg/errors"
- "golang.org/x/sys/unix"
-)
-
-func copyDevice(dst string, fi os.FileInfo) error {
- st, ok := fi.Sys().(*syscall.Stat_t)
- if !ok {
- return errors.New("unsupported stat type")
- }
- return unix.Mknod(dst, uint32(fi.Mode()), st.Rdev)
-}
-
-func utimesNano(name string, atime, mtime syscall.Timespec) error {
- at := unix.NsecToTimespec(atime.Nano())
- mt := unix.NsecToTimespec(mtime.Nano())
- utimes := [2]unix.Timespec{at, mt}
- return unix.UtimesNanoAt(unix.AT_FDCWD, name, utimes[0:], unix.AT_SYMLINK_NOFOLLOW)
-}
diff --git a/vendor/github.com/containerd/continuity/fs/copy_linux.go b/vendor/github.com/containerd/continuity/fs/copy_linux.go
deleted file mode 100644
index 72bae7d4e..000000000
--- a/vendor/github.com/containerd/continuity/fs/copy_linux.go
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "io"
- "os"
- "syscall"
-
- "github.com/containerd/continuity/sysx"
- "github.com/pkg/errors"
- "golang.org/x/sys/unix"
-)
-
-func copyFileInfo(fi os.FileInfo, name string) error {
- st := fi.Sys().(*syscall.Stat_t)
- if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil {
- if os.IsPermission(err) {
- // Normally if uid/gid are the same this would be a no-op, but some
- // filesystems may still return EPERM... for instance NFS does this.
- // In such a case, this is not an error.
- if dstStat, err2 := os.Lstat(name); err2 == nil {
- st2 := dstStat.Sys().(*syscall.Stat_t)
- if st.Uid == st2.Uid && st.Gid == st2.Gid {
- err = nil
- }
- }
- }
- if err != nil {
- return errors.Wrapf(err, "failed to chown %s", name)
- }
- }
-
- if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink {
- if err := os.Chmod(name, fi.Mode()); err != nil {
- return errors.Wrapf(err, "failed to chmod %s", name)
- }
- }
-
- timespec := []unix.Timespec{
- unix.NsecToTimespec(syscall.TimespecToNsec(StatAtime(st))),
- unix.NsecToTimespec(syscall.TimespecToNsec(StatMtime(st))),
- }
- if err := unix.UtimesNanoAt(unix.AT_FDCWD, name, timespec, unix.AT_SYMLINK_NOFOLLOW); err != nil {
- return errors.Wrapf(err, "failed to utime %s", name)
- }
-
- return nil
-}
-
-const maxSSizeT = int64(^uint(0) >> 1)
-
-func copyFileContent(dst, src *os.File) error {
- st, err := src.Stat()
- if err != nil {
- return errors.Wrap(err, "unable to stat source")
- }
-
- size := st.Size()
- first := true
- srcFd := int(src.Fd())
- dstFd := int(dst.Fd())
-
- for size > 0 {
- // Ensure that we are never trying to copy more than SSIZE_MAX at a
- // time and at the same time avoids overflows when the file is larger
- // than 4GB on 32-bit systems.
- var copySize int
- if size > maxSSizeT {
- copySize = int(maxSSizeT)
- } else {
- copySize = int(size)
- }
- n, err := unix.CopyFileRange(srcFd, nil, dstFd, nil, copySize, 0)
- if err != nil {
- if (err != unix.ENOSYS && err != unix.EXDEV) || !first {
- return errors.Wrap(err, "copy file range failed")
- }
-
- buf := bufferPool.Get().(*[]byte)
- _, err = io.CopyBuffer(dst, src, *buf)
- bufferPool.Put(buf)
- return errors.Wrap(err, "userspace copy failed")
- }
-
- first = false
- size -= int64(n)
- }
-
- return nil
-}
-
-func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
- xattrKeys, err := sysx.LListxattr(src)
- if err != nil {
- e := errors.Wrapf(err, "failed to list xattrs on %s", src)
- if xeh != nil {
- e = xeh(dst, src, "", e)
- }
- return e
- }
- for _, xattr := range xattrKeys {
- data, err := sysx.LGetxattr(src, xattr)
- if err != nil {
- e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
- if xeh != nil {
- if e = xeh(dst, src, xattr, e); e == nil {
- continue
- }
- }
- return e
- }
- if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
- e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
- if xeh != nil {
- if e = xeh(dst, src, xattr, e); e == nil {
- continue
- }
- }
- return e
- }
- }
-
- return nil
-}
-
-func copyDevice(dst string, fi os.FileInfo) error {
- st, ok := fi.Sys().(*syscall.Stat_t)
- if !ok {
- return errors.New("unsupported stat type")
- }
- return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev))
-}
diff --git a/vendor/github.com/containerd/continuity/fs/copy_unix.go b/vendor/github.com/containerd/continuity/fs/copy_unix.go
deleted file mode 100644
index dfd857aaa..000000000
--- a/vendor/github.com/containerd/continuity/fs/copy_unix.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// +build darwin freebsd openbsd solaris
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "io"
- "os"
- "syscall"
-
- "github.com/containerd/continuity/sysx"
- "github.com/pkg/errors"
-)
-
-func copyFileInfo(fi os.FileInfo, name string) error {
- st := fi.Sys().(*syscall.Stat_t)
- if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil {
- if os.IsPermission(err) {
- // Normally if uid/gid are the same this would be a no-op, but some
- // filesystems may still return EPERM... for instance NFS does this.
- // In such a case, this is not an error.
- if dstStat, err2 := os.Lstat(name); err2 == nil {
- st2 := dstStat.Sys().(*syscall.Stat_t)
- if st.Uid == st2.Uid && st.Gid == st2.Gid {
- err = nil
- }
- }
- }
- if err != nil {
- return errors.Wrapf(err, "failed to chown %s", name)
- }
- }
-
- if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink {
- if err := os.Chmod(name, fi.Mode()); err != nil {
- return errors.Wrapf(err, "failed to chmod %s", name)
- }
- }
-
- if err := utimesNano(name, StatAtime(st), StatMtime(st)); err != nil {
- return errors.Wrapf(err, "failed to utime %s", name)
- }
-
- return nil
-}
-
-func copyFileContent(dst, src *os.File) error {
- buf := bufferPool.Get().(*[]byte)
- _, err := io.CopyBuffer(dst, src, *buf)
- bufferPool.Put(buf)
-
- return err
-}
-
-func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
- xattrKeys, err := sysx.LListxattr(src)
- if err != nil {
- e := errors.Wrapf(err, "failed to list xattrs on %s", src)
- if xeh != nil {
- e = xeh(dst, src, "", e)
- }
- return e
- }
- for _, xattr := range xattrKeys {
- data, err := sysx.LGetxattr(src, xattr)
- if err != nil {
- e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
- if xeh != nil {
- if e = xeh(dst, src, xattr, e); e == nil {
- continue
- }
- }
- return e
- }
- if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
- e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
- if xeh != nil {
- if e = xeh(dst, src, xattr, e); e == nil {
- continue
- }
- }
- return e
- }
- }
-
- return nil
-}
diff --git a/vendor/github.com/containerd/continuity/fs/copy_windows.go b/vendor/github.com/containerd/continuity/fs/copy_windows.go
deleted file mode 100644
index 27c7d7dbb..000000000
--- a/vendor/github.com/containerd/continuity/fs/copy_windows.go
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "io"
- "os"
-
- "github.com/pkg/errors"
-)
-
-func copyFileInfo(fi os.FileInfo, name string) error {
- if err := os.Chmod(name, fi.Mode()); err != nil {
- return errors.Wrapf(err, "failed to chmod %s", name)
- }
-
- // TODO: copy windows specific metadata
-
- return nil
-}
-
-func copyFileContent(dst, src *os.File) error {
- buf := bufferPool.Get().(*[]byte)
- _, err := io.CopyBuffer(dst, src, *buf)
- bufferPool.Put(buf)
- return err
-}
-
-func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
- return nil
-}
-
-func copyDevice(dst string, fi os.FileInfo) error {
- return errors.New("device copy not supported")
-}
diff --git a/vendor/github.com/containerd/continuity/fs/diff.go b/vendor/github.com/containerd/continuity/fs/diff.go
deleted file mode 100644
index e64f9e73d..000000000
--- a/vendor/github.com/containerd/continuity/fs/diff.go
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "context"
- "os"
- "path/filepath"
- "strings"
-
- "golang.org/x/sync/errgroup"
-
- "github.com/sirupsen/logrus"
-)
-
-// ChangeKind is the type of modification that
-// a change is making.
-type ChangeKind int
-
-const (
- // ChangeKindUnmodified represents an unmodified
- // file
- ChangeKindUnmodified = iota
-
- // ChangeKindAdd represents an addition of
- // a file
- ChangeKindAdd
-
- // ChangeKindModify represents a change to
- // an existing file
- ChangeKindModify
-
- // ChangeKindDelete represents a delete of
- // a file
- ChangeKindDelete
-)
-
-func (k ChangeKind) String() string {
- switch k {
- case ChangeKindUnmodified:
- return "unmodified"
- case ChangeKindAdd:
- return "add"
- case ChangeKindModify:
- return "modify"
- case ChangeKindDelete:
- return "delete"
- default:
- return ""
- }
-}
-
-// Change represents single change between a diff and its parent.
-type Change struct {
- Kind ChangeKind
- Path string
-}
-
-// ChangeFunc is the type of function called for each change
-// computed during a directory changes calculation.
-type ChangeFunc func(ChangeKind, string, os.FileInfo, error) error
-
-// Changes computes changes between two directories calling the
-// given change function for each computed change. The first
-// directory is intended to the base directory and second
-// directory the changed directory.
-//
-// The change callback is called by the order of path names and
-// should be appliable in that order.
-// Due to this apply ordering, the following is true
-// - Removed directory trees only create a single change for the root
-// directory removed. Remaining changes are implied.
-// - A directory which is modified to become a file will not have
-// delete entries for sub-path items, their removal is implied
-// by the removal of the parent directory.
-//
-// Opaque directories will not be treated specially and each file
-// removed from the base directory will show up as a removal.
-//
-// File content comparisons will be done on files which have timestamps
-// which may have been truncated. If either of the files being compared
-// has a zero value nanosecond value, each byte will be compared for
-// differences. If 2 files have the same seconds value but different
-// nanosecond values where one of those values is zero, the files will
-// be considered unchanged if the content is the same. This behavior
-// is to account for timestamp truncation during archiving.
-func Changes(ctx context.Context, a, b string, changeFn ChangeFunc) error {
- if a == "" {
- logrus.Debugf("Using single walk diff for %s", b)
- return addDirChanges(ctx, changeFn, b)
- } else if diffOptions := detectDirDiff(b, a); diffOptions != nil {
- logrus.Debugf("Using single walk diff for %s from %s", diffOptions.diffDir, a)
- return diffDirChanges(ctx, changeFn, a, diffOptions)
- }
-
- logrus.Debugf("Using double walk diff for %s from %s", b, a)
- return doubleWalkDiff(ctx, changeFn, a, b)
-}
-
-func addDirChanges(ctx context.Context, changeFn ChangeFunc, root string) error {
- return filepath.Walk(root, func(path string, f os.FileInfo, err error) error {
- if err != nil {
- return err
- }
-
- // Rebase path
- path, err = filepath.Rel(root, path)
- if err != nil {
- return err
- }
-
- path = filepath.Join(string(os.PathSeparator), path)
-
- // Skip root
- if path == string(os.PathSeparator) {
- return nil
- }
-
- return changeFn(ChangeKindAdd, path, f, nil)
- })
-}
-
-// diffDirOptions is used when the diff can be directly calculated from
-// a diff directory to its base, without walking both trees.
-type diffDirOptions struct {
- diffDir string
- skipChange func(string) (bool, error)
- deleteChange func(string, string, os.FileInfo) (string, error)
-}
-
-// diffDirChanges walks the diff directory and compares changes against the base.
-func diffDirChanges(ctx context.Context, changeFn ChangeFunc, base string, o *diffDirOptions) error {
- changedDirs := make(map[string]struct{})
- return filepath.Walk(o.diffDir, func(path string, f os.FileInfo, err error) error {
- if err != nil {
- return err
- }
-
- // Rebase path
- path, err = filepath.Rel(o.diffDir, path)
- if err != nil {
- return err
- }
-
- path = filepath.Join(string(os.PathSeparator), path)
-
- // Skip root
- if path == string(os.PathSeparator) {
- return nil
- }
-
- // TODO: handle opaqueness, start new double walker at this
- // location to get deletes, and skip tree in single walker
-
- if o.skipChange != nil {
- if skip, err := o.skipChange(path); skip {
- return err
- }
- }
-
- var kind ChangeKind
-
- deletedFile, err := o.deleteChange(o.diffDir, path, f)
- if err != nil {
- return err
- }
-
- // Find out what kind of modification happened
- if deletedFile != "" {
- path = deletedFile
- kind = ChangeKindDelete
- f = nil
- } else {
- // Otherwise, the file was added
- kind = ChangeKindAdd
-
- // ...Unless it already existed in a base, in which case, it's a modification
- stat, err := os.Stat(filepath.Join(base, path))
- if err != nil && !os.IsNotExist(err) {
- return err
- }
- if err == nil {
- // The file existed in the base, so that's a modification
-
- // However, if it's a directory, maybe it wasn't actually modified.
- // If you modify /foo/bar/baz, then /foo will be part of the changed files only because it's the parent of bar
- if stat.IsDir() && f.IsDir() {
- if f.Size() == stat.Size() && f.Mode() == stat.Mode() && sameFsTime(f.ModTime(), stat.ModTime()) {
- // Both directories are the same, don't record the change
- return nil
- }
- }
- kind = ChangeKindModify
- }
- }
-
- // If /foo/bar/file.txt is modified, then /foo/bar must be part of the changed files.
- // This block is here to ensure the change is recorded even if the
- // modify time, mode and size of the parent directory in the rw and ro layers are all equal.
- // Check https://github.com/docker/docker/pull/13590 for details.
- if f.IsDir() {
- changedDirs[path] = struct{}{}
- }
- if kind == ChangeKindAdd || kind == ChangeKindDelete {
- parent := filepath.Dir(path)
- if _, ok := changedDirs[parent]; !ok && parent != "/" {
- pi, err := os.Stat(filepath.Join(o.diffDir, parent))
- if err := changeFn(ChangeKindModify, parent, pi, err); err != nil {
- return err
- }
- changedDirs[parent] = struct{}{}
- }
- }
-
- return changeFn(kind, path, f, nil)
- })
-}
-
-// doubleWalkDiff walks both directories to create a diff
-func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b string) (err error) {
- g, ctx := errgroup.WithContext(ctx)
-
- var (
- c1 = make(chan *currentPath)
- c2 = make(chan *currentPath)
-
- f1, f2 *currentPath
- rmdir string
- )
- g.Go(func() error {
- defer close(c1)
- return pathWalk(ctx, a, c1)
- })
- g.Go(func() error {
- defer close(c2)
- return pathWalk(ctx, b, c2)
- })
- g.Go(func() error {
- for c1 != nil || c2 != nil {
- if f1 == nil && c1 != nil {
- f1, err = nextPath(ctx, c1)
- if err != nil {
- return err
- }
- if f1 == nil {
- c1 = nil
- }
- }
-
- if f2 == nil && c2 != nil {
- f2, err = nextPath(ctx, c2)
- if err != nil {
- return err
- }
- if f2 == nil {
- c2 = nil
- }
- }
- if f1 == nil && f2 == nil {
- continue
- }
-
- var f os.FileInfo
- k, p := pathChange(f1, f2)
- switch k {
- case ChangeKindAdd:
- if rmdir != "" {
- rmdir = ""
- }
- f = f2.f
- f2 = nil
- case ChangeKindDelete:
- // Check if this file is already removed by being
- // under of a removed directory
- if rmdir != "" && strings.HasPrefix(f1.path, rmdir) {
- f1 = nil
- continue
- } else if f1.f.IsDir() {
- rmdir = f1.path + string(os.PathSeparator)
- } else if rmdir != "" {
- rmdir = ""
- }
- f1 = nil
- case ChangeKindModify:
- same, err := sameFile(f1, f2)
- if err != nil {
- return err
- }
- if f1.f.IsDir() && !f2.f.IsDir() {
- rmdir = f1.path + string(os.PathSeparator)
- } else if rmdir != "" {
- rmdir = ""
- }
- f = f2.f
- f1 = nil
- f2 = nil
- if same {
- if !isLinked(f) {
- continue
- }
- k = ChangeKindUnmodified
- }
- }
- if err := changeFn(k, p, f, nil); err != nil {
- return err
- }
- }
- return nil
- })
-
- return g.Wait()
-}
diff --git a/vendor/github.com/containerd/continuity/fs/diff_unix.go b/vendor/github.com/containerd/continuity/fs/diff_unix.go
deleted file mode 100644
index 7913af27d..000000000
--- a/vendor/github.com/containerd/continuity/fs/diff_unix.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// +build !windows
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "bytes"
- "os"
- "syscall"
-
- "github.com/containerd/continuity/sysx"
- "github.com/pkg/errors"
-)
-
-// detectDirDiff returns diff dir options if a directory could
-// be found in the mount info for upper which is the direct
-// diff with the provided lower directory
-func detectDirDiff(upper, lower string) *diffDirOptions {
- // TODO: get mount options for upper
- // TODO: detect AUFS
- // TODO: detect overlay
- return nil
-}
-
-// compareSysStat returns whether the stats are equivalent,
-// whether the files are considered the same file, and
-// an error
-func compareSysStat(s1, s2 interface{}) (bool, error) {
- ls1, ok := s1.(*syscall.Stat_t)
- if !ok {
- return false, nil
- }
- ls2, ok := s2.(*syscall.Stat_t)
- if !ok {
- return false, nil
- }
-
- return ls1.Mode == ls2.Mode && ls1.Uid == ls2.Uid && ls1.Gid == ls2.Gid && ls1.Rdev == ls2.Rdev, nil
-}
-
-func compareCapabilities(p1, p2 string) (bool, error) {
- c1, err := sysx.LGetxattr(p1, "security.capability")
- if err != nil && err != sysx.ENODATA {
- return false, errors.Wrapf(err, "failed to get xattr for %s", p1)
- }
- c2, err := sysx.LGetxattr(p2, "security.capability")
- if err != nil && err != sysx.ENODATA {
- return false, errors.Wrapf(err, "failed to get xattr for %s", p2)
- }
- return bytes.Equal(c1, c2), nil
-}
-
-func isLinked(f os.FileInfo) bool {
- s, ok := f.Sys().(*syscall.Stat_t)
- if !ok {
- return false
- }
- return !f.IsDir() && s.Nlink > 1
-}
diff --git a/vendor/github.com/containerd/continuity/fs/diff_windows.go b/vendor/github.com/containerd/continuity/fs/diff_windows.go
deleted file mode 100644
index 4bfa72d3a..000000000
--- a/vendor/github.com/containerd/continuity/fs/diff_windows.go
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "os"
-
- "golang.org/x/sys/windows"
-)
-
-func detectDirDiff(upper, lower string) *diffDirOptions {
- return nil
-}
-
-func compareSysStat(s1, s2 interface{}) (bool, error) {
- f1, ok := s1.(windows.Win32FileAttributeData)
- if !ok {
- return false, nil
- }
- f2, ok := s2.(windows.Win32FileAttributeData)
- if !ok {
- return false, nil
- }
- return f1.FileAttributes == f2.FileAttributes, nil
-}
-
-func compareCapabilities(p1, p2 string) (bool, error) {
- // TODO: Use windows equivalent
- return true, nil
-}
-
-func isLinked(os.FileInfo) bool {
- return false
-}
diff --git a/vendor/github.com/containerd/continuity/fs/dtype_linux.go b/vendor/github.com/containerd/continuity/fs/dtype_linux.go
deleted file mode 100644
index 10510d8de..000000000
--- a/vendor/github.com/containerd/continuity/fs/dtype_linux.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// +build linux
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "syscall"
- "unsafe"
-)
-
-func locateDummyIfEmpty(path string) (string, error) {
- children, err := ioutil.ReadDir(path)
- if err != nil {
- return "", err
- }
- if len(children) != 0 {
- return "", nil
- }
- dummyFile, err := ioutil.TempFile(path, "fsutils-dummy")
- if err != nil {
- return "", err
- }
- name := dummyFile.Name()
- err = dummyFile.Close()
- return name, err
-}
-
-// SupportsDType returns whether the filesystem mounted on path supports d_type
-func SupportsDType(path string) (bool, error) {
- // locate dummy so that we have at least one dirent
- dummy, err := locateDummyIfEmpty(path)
- if err != nil {
- return false, err
- }
- if dummy != "" {
- defer os.Remove(dummy)
- }
-
- visited := 0
- supportsDType := true
- fn := func(ent *syscall.Dirent) bool {
- visited++
- if ent.Type == syscall.DT_UNKNOWN {
- supportsDType = false
- // stop iteration
- return true
- }
- // continue iteration
- return false
- }
- if err = iterateReadDir(path, fn); err != nil {
- return false, err
- }
- if visited == 0 {
- return false, fmt.Errorf("did not hit any dirent during iteration %s", path)
- }
- return supportsDType, nil
-}
-
-func iterateReadDir(path string, fn func(*syscall.Dirent) bool) error {
- d, err := os.Open(path)
- if err != nil {
- return err
- }
- defer d.Close()
- fd := int(d.Fd())
- buf := make([]byte, 4096)
- for {
- nbytes, err := syscall.ReadDirent(fd, buf)
- if err != nil {
- return err
- }
- if nbytes == 0 {
- break
- }
- for off := 0; off < nbytes; {
- ent := (*syscall.Dirent)(unsafe.Pointer(&buf[off]))
- if stop := fn(ent); stop {
- return nil
- }
- off += int(ent.Reclen)
- }
- }
- return nil
-}
diff --git a/vendor/github.com/containerd/continuity/fs/du.go b/vendor/github.com/containerd/continuity/fs/du.go
deleted file mode 100644
index fccc985dc..000000000
--- a/vendor/github.com/containerd/continuity/fs/du.go
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import "context"
-
-// Usage of disk information
-type Usage struct {
- Inodes int64
- Size int64
-}
-
-// DiskUsage counts the number of inodes and disk usage for the resources under
-// path.
-func DiskUsage(ctx context.Context, roots ...string) (Usage, error) {
- return diskUsage(ctx, roots...)
-}
-
-// DiffUsage counts the numbers of inodes and disk usage in the
-// diff between the 2 directories. The first path is intended
-// as the base directory and the second as the changed directory.
-func DiffUsage(ctx context.Context, a, b string) (Usage, error) {
- return diffUsage(ctx, a, b)
-}
diff --git a/vendor/github.com/containerd/continuity/fs/du_unix.go b/vendor/github.com/containerd/continuity/fs/du_unix.go
deleted file mode 100644
index 9da43d1bc..000000000
--- a/vendor/github.com/containerd/continuity/fs/du_unix.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// +build !windows
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "context"
- "os"
- "path/filepath"
- "syscall"
-)
-
-// blocksUnitSize is the unit used by `st_blocks` in `stat` in bytes.
-// See https://man7.org/linux/man-pages/man2/stat.2.html
-// st_blocks
-// This field indicates the number of blocks allocated to the
-// file, in 512-byte units. (This may be smaller than
-// st_size/512 when the file has holes.)
-const blocksUnitSize = 512
-
-type inode struct {
- // TODO(stevvooe): Can probably reduce memory usage by not tracking
- // device, but we can leave this right for now.
- dev, ino uint64
-}
-
-func newInode(stat *syscall.Stat_t) inode {
- return inode{
- // Dev is uint32 on darwin/bsd, uint64 on linux/solaris/freebsd
- dev: uint64(stat.Dev), // nolint: unconvert
- // Ino is uint32 on bsd, uint64 on darwin/linux/solaris/freebsd
- ino: uint64(stat.Ino), // nolint: unconvert
- }
-}
-
-func diskUsage(ctx context.Context, roots ...string) (Usage, error) {
-
- var (
- size int64
- inodes = map[inode]struct{}{} // expensive!
- )
-
- for _, root := range roots {
- if err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
- if err != nil {
- return err
- }
-
- select {
- case <-ctx.Done():
- return ctx.Err()
- default:
- }
-
- stat := fi.Sys().(*syscall.Stat_t)
- inoKey := newInode(stat)
- if _, ok := inodes[inoKey]; !ok {
- inodes[inoKey] = struct{}{}
- size += stat.Blocks * blocksUnitSize
- }
-
- return nil
- }); err != nil {
- return Usage{}, err
- }
- }
-
- return Usage{
- Inodes: int64(len(inodes)),
- Size: size,
- }, nil
-}
-
-func diffUsage(ctx context.Context, a, b string) (Usage, error) {
- var (
- size int64
- inodes = map[inode]struct{}{} // expensive!
- )
-
- if err := Changes(ctx, a, b, func(kind ChangeKind, _ string, fi os.FileInfo, err error) error {
- if err != nil {
- return err
- }
-
- if kind == ChangeKindAdd || kind == ChangeKindModify {
- stat := fi.Sys().(*syscall.Stat_t)
- inoKey := newInode(stat)
- if _, ok := inodes[inoKey]; !ok {
- inodes[inoKey] = struct{}{}
- size += stat.Blocks * blocksUnitSize
- }
-
- return nil
-
- }
- return nil
- }); err != nil {
- return Usage{}, err
- }
-
- return Usage{
- Inodes: int64(len(inodes)),
- Size: size,
- }, nil
-}
diff --git a/vendor/github.com/containerd/continuity/fs/du_windows.go b/vendor/github.com/containerd/continuity/fs/du_windows.go
deleted file mode 100644
index 8f25ec59c..000000000
--- a/vendor/github.com/containerd/continuity/fs/du_windows.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// +build windows
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "context"
- "os"
- "path/filepath"
-)
-
-func diskUsage(ctx context.Context, roots ...string) (Usage, error) {
- var (
- size int64
- )
-
- // TODO(stevvooe): Support inodes (or equivalent) for windows.
-
- for _, root := range roots {
- if err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
- if err != nil {
- return err
- }
-
- select {
- case <-ctx.Done():
- return ctx.Err()
- default:
- }
-
- size += fi.Size()
- return nil
- }); err != nil {
- return Usage{}, err
- }
- }
-
- return Usage{
- Size: size,
- }, nil
-}
-
-func diffUsage(ctx context.Context, a, b string) (Usage, error) {
- var (
- size int64
- )
-
- if err := Changes(ctx, a, b, func(kind ChangeKind, _ string, fi os.FileInfo, err error) error {
- if err != nil {
- return err
- }
-
- if kind == ChangeKindAdd || kind == ChangeKindModify {
- size += fi.Size()
-
- return nil
-
- }
- return nil
- }); err != nil {
- return Usage{}, err
- }
-
- return Usage{
- Size: size,
- }, nil
-}
diff --git a/vendor/github.com/containerd/continuity/fs/hardlink.go b/vendor/github.com/containerd/continuity/fs/hardlink.go
deleted file mode 100644
index 762aa45e6..000000000
--- a/vendor/github.com/containerd/continuity/fs/hardlink.go
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import "os"
-
-// GetLinkInfo returns an identifier representing the node a hardlink is pointing
-// to. If the file is not hard linked then 0 will be returned.
-func GetLinkInfo(fi os.FileInfo) (uint64, bool) {
- return getLinkInfo(fi)
-}
-
-// getLinkSource returns a path for the given name and
-// file info to its link source in the provided inode
-// map. If the given file name is not in the map and
-// has other links, it is added to the inode map
-// to be a source for other link locations.
-func getLinkSource(name string, fi os.FileInfo, inodes map[uint64]string) (string, error) {
- inode, isHardlink := getLinkInfo(fi)
- if !isHardlink {
- return "", nil
- }
-
- path, ok := inodes[inode]
- if !ok {
- inodes[inode] = name
- }
- return path, nil
-}
diff --git a/vendor/github.com/containerd/continuity/fs/hardlink_unix.go b/vendor/github.com/containerd/continuity/fs/hardlink_unix.go
deleted file mode 100644
index f95f0904c..000000000
--- a/vendor/github.com/containerd/continuity/fs/hardlink_unix.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// +build !windows
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "os"
- "syscall"
-)
-
-func getLinkInfo(fi os.FileInfo) (uint64, bool) {
- s, ok := fi.Sys().(*syscall.Stat_t)
- if !ok {
- return 0, false
- }
-
- // Ino is uint32 on bsd, uint64 on darwin/linux/solaris
- return uint64(s.Ino), !fi.IsDir() && s.Nlink > 1 // nolint: unconvert
-}
diff --git a/vendor/github.com/containerd/continuity/fs/hardlink_windows.go b/vendor/github.com/containerd/continuity/fs/hardlink_windows.go
deleted file mode 100644
index 748554714..000000000
--- a/vendor/github.com/containerd/continuity/fs/hardlink_windows.go
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import "os"
-
-func getLinkInfo(fi os.FileInfo) (uint64, bool) {
- return 0, false
-}
diff --git a/vendor/github.com/containerd/continuity/fs/path.go b/vendor/github.com/containerd/continuity/fs/path.go
deleted file mode 100644
index c26be7989..000000000
--- a/vendor/github.com/containerd/continuity/fs/path.go
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "bytes"
- "context"
- "io"
- "os"
- "path/filepath"
-
- "github.com/pkg/errors"
-)
-
-var (
- errTooManyLinks = errors.New("too many links")
-)
-
-type currentPath struct {
- path string
- f os.FileInfo
- fullPath string
-}
-
-func pathChange(lower, upper *currentPath) (ChangeKind, string) {
- if lower == nil {
- if upper == nil {
- panic("cannot compare nil paths")
- }
- return ChangeKindAdd, upper.path
- }
- if upper == nil {
- return ChangeKindDelete, lower.path
- }
-
- switch i := directoryCompare(lower.path, upper.path); {
- case i < 0:
- // File in lower that is not in upper
- return ChangeKindDelete, lower.path
- case i > 0:
- // File in upper that is not in lower
- return ChangeKindAdd, upper.path
- default:
- return ChangeKindModify, upper.path
- }
-}
-
-func directoryCompare(a, b string) int {
- l := len(a)
- if len(b) < l {
- l = len(b)
- }
- for i := 0; i < l; i++ {
- c1, c2 := a[i], b[i]
- if c1 == filepath.Separator {
- c1 = byte(0)
- }
- if c2 == filepath.Separator {
- c2 = byte(0)
- }
- if c1 < c2 {
- return -1
- }
- if c1 > c2 {
- return +1
- }
- }
- if len(a) < len(b) {
- return -1
- }
- if len(a) > len(b) {
- return +1
- }
- return 0
-}
-
-func sameFile(f1, f2 *currentPath) (bool, error) {
- if os.SameFile(f1.f, f2.f) {
- return true, nil
- }
-
- equalStat, err := compareSysStat(f1.f.Sys(), f2.f.Sys())
- if err != nil || !equalStat {
- return equalStat, err
- }
-
- if eq, err := compareCapabilities(f1.fullPath, f2.fullPath); err != nil || !eq {
- return eq, err
- }
-
- // If not a directory also check size, modtime, and content
- if !f1.f.IsDir() {
- if f1.f.Size() != f2.f.Size() {
- return false, nil
- }
- t1 := f1.f.ModTime()
- t2 := f2.f.ModTime()
-
- if t1.Unix() != t2.Unix() {
- return false, nil
- }
-
- // If the timestamp may have been truncated in both of the
- // files, check content of file to determine difference
- if t1.Nanosecond() == 0 && t2.Nanosecond() == 0 {
- if (f1.f.Mode() & os.ModeSymlink) == os.ModeSymlink {
- return compareSymlinkTarget(f1.fullPath, f2.fullPath)
- }
- if f1.f.Size() == 0 { // if file sizes are zero length, the files are the same by definition
- return true, nil
- }
- return compareFileContent(f1.fullPath, f2.fullPath)
- } else if t1.Nanosecond() != t2.Nanosecond() {
- return false, nil
- }
- }
-
- return true, nil
-}
-
-func compareSymlinkTarget(p1, p2 string) (bool, error) {
- t1, err := os.Readlink(p1)
- if err != nil {
- return false, err
- }
- t2, err := os.Readlink(p2)
- if err != nil {
- return false, err
- }
- return t1 == t2, nil
-}
-
-const compareChuckSize = 32 * 1024
-
-// compareFileContent compares the content of 2 same sized files
-// by comparing each byte.
-func compareFileContent(p1, p2 string) (bool, error) {
- f1, err := os.Open(p1)
- if err != nil {
- return false, err
- }
- defer f1.Close()
- f2, err := os.Open(p2)
- if err != nil {
- return false, err
- }
- defer f2.Close()
-
- b1 := make([]byte, compareChuckSize)
- b2 := make([]byte, compareChuckSize)
- for {
- n1, err1 := f1.Read(b1)
- if err1 != nil && err1 != io.EOF {
- return false, err1
- }
- n2, err2 := f2.Read(b2)
- if err2 != nil && err2 != io.EOF {
- return false, err2
- }
- if n1 != n2 || !bytes.Equal(b1[:n1], b2[:n2]) {
- return false, nil
- }
- if err1 == io.EOF && err2 == io.EOF {
- return true, nil
- }
- }
-}
-
-func pathWalk(ctx context.Context, root string, pathC chan<- *currentPath) error {
- return filepath.Walk(root, func(path string, f os.FileInfo, err error) error {
- if err != nil {
- return err
- }
-
- // Rebase path
- path, err = filepath.Rel(root, path)
- if err != nil {
- return err
- }
-
- path = filepath.Join(string(os.PathSeparator), path)
-
- // Skip root
- if path == string(os.PathSeparator) {
- return nil
- }
-
- p := &currentPath{
- path: path,
- f: f,
- fullPath: filepath.Join(root, path),
- }
-
- select {
- case <-ctx.Done():
- return ctx.Err()
- case pathC <- p:
- return nil
- }
- })
-}
-
-func nextPath(ctx context.Context, pathC <-chan *currentPath) (*currentPath, error) {
- select {
- case <-ctx.Done():
- return nil, ctx.Err()
- case p := <-pathC:
- return p, nil
- }
-}
-
-// RootPath joins a path with a root, evaluating and bounding any
-// symlink to the root directory.
-func RootPath(root, path string) (string, error) {
- if path == "" {
- return root, nil
- }
- var linksWalked int // to protect against cycles
- for {
- i := linksWalked
- newpath, err := walkLinks(root, path, &linksWalked)
- if err != nil {
- return "", err
- }
- path = newpath
- if i == linksWalked {
- newpath = filepath.Join("/", newpath)
- if path == newpath {
- return filepath.Join(root, newpath), nil
- }
- path = newpath
- }
- }
-}
-
-func walkLink(root, path string, linksWalked *int) (newpath string, islink bool, err error) {
- if *linksWalked > 255 {
- return "", false, errTooManyLinks
- }
-
- path = filepath.Join("/", path)
- if path == "/" {
- return path, false, nil
- }
- realPath := filepath.Join(root, path)
-
- fi, err := os.Lstat(realPath)
- if err != nil {
- // If path does not yet exist, treat as non-symlink
- if os.IsNotExist(err) {
- return path, false, nil
- }
- return "", false, err
- }
- if fi.Mode()&os.ModeSymlink == 0 {
- return path, false, nil
- }
- newpath, err = os.Readlink(realPath)
- if err != nil {
- return "", false, err
- }
- *linksWalked++
- return newpath, true, nil
-}
-
-func walkLinks(root, path string, linksWalked *int) (string, error) {
- switch dir, file := filepath.Split(path); {
- case dir == "":
- newpath, _, err := walkLink(root, file, linksWalked)
- return newpath, err
- case file == "":
- if os.IsPathSeparator(dir[len(dir)-1]) {
- if dir == "/" {
- return dir, nil
- }
- return walkLinks(root, dir[:len(dir)-1], linksWalked)
- }
- newpath, _, err := walkLink(root, dir, linksWalked)
- return newpath, err
- default:
- newdir, err := walkLinks(root, dir, linksWalked)
- if err != nil {
- return "", err
- }
- newpath, islink, err := walkLink(root, filepath.Join(newdir, file), linksWalked)
- if err != nil {
- return "", err
- }
- if !islink {
- return newpath, nil
- }
- if filepath.IsAbs(newpath) {
- return newpath, nil
- }
- return filepath.Join(newdir, newpath), nil
- }
-}
diff --git a/vendor/github.com/containerd/continuity/fs/stat_darwinfreebsd.go b/vendor/github.com/containerd/continuity/fs/stat_darwinfreebsd.go
deleted file mode 100644
index cb7400a33..000000000
--- a/vendor/github.com/containerd/continuity/fs/stat_darwinfreebsd.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// +build darwin freebsd
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "syscall"
- "time"
-)
-
-// StatAtime returns the access time from a stat struct
-func StatAtime(st *syscall.Stat_t) syscall.Timespec {
- return st.Atimespec
-}
-
-// StatCtime returns the created time from a stat struct
-func StatCtime(st *syscall.Stat_t) syscall.Timespec {
- return st.Ctimespec
-}
-
-// StatMtime returns the modified time from a stat struct
-func StatMtime(st *syscall.Stat_t) syscall.Timespec {
- return st.Mtimespec
-}
-
-// StatATimeAsTime returns the access time as a time.Time
-func StatATimeAsTime(st *syscall.Stat_t) time.Time {
- return time.Unix(int64(st.Atimespec.Sec), int64(st.Atimespec.Nsec)) // nolint: unconvert
-}
diff --git a/vendor/github.com/containerd/continuity/fs/stat_linuxopenbsd.go b/vendor/github.com/containerd/continuity/fs/stat_linuxopenbsd.go
deleted file mode 100644
index c68df6e58..000000000
--- a/vendor/github.com/containerd/continuity/fs/stat_linuxopenbsd.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// +build linux openbsd
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import (
- "syscall"
- "time"
-)
-
-// StatAtime returns the Atim
-func StatAtime(st *syscall.Stat_t) syscall.Timespec {
- return st.Atim
-}
-
-// StatCtime returns the Ctim
-func StatCtime(st *syscall.Stat_t) syscall.Timespec {
- return st.Ctim
-}
-
-// StatMtime returns the Mtim
-func StatMtime(st *syscall.Stat_t) syscall.Timespec {
- return st.Mtim
-}
-
-// StatATimeAsTime returns st.Atim as a time.Time
-func StatATimeAsTime(st *syscall.Stat_t) time.Time {
- // The int64 conversions ensure the line compiles for 32-bit systems as well.
- return time.Unix(int64(st.Atim.Sec), int64(st.Atim.Nsec)) // nolint: unconvert
-}
diff --git a/vendor/github.com/containerd/continuity/fs/time.go b/vendor/github.com/containerd/continuity/fs/time.go
deleted file mode 100644
index cde456123..000000000
--- a/vendor/github.com/containerd/continuity/fs/time.go
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package fs
-
-import "time"
-
-// Gnu tar and the go tar writer don't have sub-second mtime
-// precision, which is problematic when we apply changes via tar
-// files, we handle this by comparing for exact times, *or* same
-// second count and either a or b having exactly 0 nanoseconds
-func sameFsTime(a, b time.Time) bool {
- return a == b ||
- (a.Unix() == b.Unix() &&
- (a.Nanosecond() == 0 || b.Nanosecond() == 0))
-}