vendor: add buildkit

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi
2019-03-23 22:44:59 -07:00
parent 62faee5f07
commit 8b7c38e61a
364 changed files with 78556 additions and 1007 deletions

21
vendor/github.com/tonistiigi/fsutil/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,21 @@
dist: trusty
sudo: required
services:
- docker
language: go
go:
- "1.11.x"
install:
- export GO111MODULE=on
script:
- go build ./...
- go test -c -o test ./
- sudo ./test -test.v
- go test -c -o test ./copy
- sudo ./test -test.v

22
vendor/github.com/tonistiigi/fsutil/LICENSE generated vendored Normal file
View File

@ -0,0 +1,22 @@
MIT
Copyright 2017 Tõnis Tiigi <tonistiigi@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

20
vendor/github.com/tonistiigi/fsutil/chtimes_linux.go generated vendored Normal file
View File

@ -0,0 +1,20 @@
// +build linux
package fsutil
import (
"github.com/pkg/errors"
"golang.org/x/sys/unix"
)
func chtimes(path string, un int64) error {
var utimes [2]unix.Timespec
utimes[0] = unix.NsecToTimespec(un)
utimes[1] = utimes[0]
if err := unix.UtimesNanoAt(unix.AT_FDCWD, path, utimes[0:], unix.AT_SYMLINK_NOFOLLOW); err != nil {
return errors.Wrap(err, "failed call to UtimesNanoAt")
}
return nil
}

20
vendor/github.com/tonistiigi/fsutil/chtimes_nolinux.go generated vendored Normal file
View File

@ -0,0 +1,20 @@
// +build !linux
package fsutil
import (
"os"
"time"
)
func chtimes(path string, un int64) error {
mtime := time.Unix(0, un)
fi, err := os.Lstat(path)
if err != nil {
return err
}
if fi.Mode()&os.ModeSymlink != 0 {
return nil
}
return os.Chtimes(path, mtime, mtime)
}

45
vendor/github.com/tonistiigi/fsutil/diff.go generated vendored Normal file
View File

@ -0,0 +1,45 @@
package fsutil
import (
"context"
"hash"
"os"
"github.com/tonistiigi/fsutil/types"
)
type walkerFn func(ctx context.Context, pathC chan<- *currentPath) error
func Changes(ctx context.Context, a, b walkerFn, changeFn ChangeFunc) error {
return nil
}
type HandleChangeFn func(ChangeKind, string, os.FileInfo, error) error
type ContentHasher func(*types.Stat) (hash.Hash, error)
func GetWalkerFn(root string) walkerFn {
return func(ctx context.Context, pathC chan<- *currentPath) error {
return Walk(ctx, root, nil, func(path string, f os.FileInfo, err error) error {
if err != nil {
return err
}
p := &currentPath{
path: path,
f: f,
}
select {
case <-ctx.Done():
return ctx.Err()
case pathC <- p:
return nil
}
})
}
}
func emptyWalker(ctx context.Context, pathC chan<- *currentPath) error {
return nil
}

200
vendor/github.com/tonistiigi/fsutil/diff_containerd.go generated vendored Normal file
View File

@ -0,0 +1,200 @@
package fsutil
import (
"context"
"os"
"strings"
"github.com/tonistiigi/fsutil/types"
"golang.org/x/sync/errgroup"
)
// Everything below is copied from containerd/fs. TODO: remove duplication @dmcgowan
// Const redefined because containerd/fs doesn't build on !linux
// ChangeKind is the type of modification that
// a change is making.
type ChangeKind int
const (
// ChangeKindAdd represents an addition of
// a file
ChangeKindAdd ChangeKind = iota
// ChangeKindModify represents a change to
// an existing file
ChangeKindModify
// ChangeKindDelete represents a delete of
// a file
ChangeKindDelete
)
// 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
type currentPath struct {
path string
f os.FileInfo
// fullPath string
}
// doubleWalkDiff walks both directories to create a diff
func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b walkerFn) (err error) {
g, ctx := errgroup.WithContext(ctx)
var (
c1 = make(chan *currentPath, 128)
c2 = make(chan *currentPath, 128)
f1, f2 *currentPath
rmdir string
)
g.Go(func() error {
defer close(c1)
return a(ctx, c1)
})
g.Go(func() error {
defer close(c2)
return b(ctx, c2)
})
g.Go(func() error {
loop0:
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 rmdir == "" && 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 {
continue loop0
}
}
if err := changeFn(k, p, f, nil); err != nil {
return err
}
}
return nil
})
return g.Wait()
}
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 := ComparePath(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 sameFile(f1, f2 *currentPath) (same bool, retErr error) {
// 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.UnixNano() != t2.UnixNano() {
return false, nil
}
}
ls1, ok := f1.f.Sys().(*types.Stat)
if !ok {
return false, nil
}
ls2, ok := f2.f.Sys().(*types.Stat)
if !ok {
return false, nil
}
return compareStat(ls1, ls2)
}
// compareStat returns whether the stats are equivalent,
// whether the files are considered the same file, and
// an error
func compareStat(ls1, ls2 *types.Stat) (bool, error) {
return ls1.Mode == ls2.Mode && ls1.Uid == ls2.Uid && ls1.Gid == ls2.Gid && ls1.Devmajor == ls2.Devmajor && ls1.Devminor == ls2.Devminor && ls1.Linkname == ls2.Linkname, 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
}
}

View File

@ -0,0 +1,37 @@
package fsutil
import (
"bytes"
"syscall"
"github.com/containerd/continuity/sysx"
"github.com/pkg/errors"
)
// 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 != syscall.ENODATA {
return false, errors.Wrapf(err, "failed to get xattr for %s", p1)
}
c2, err := sysx.LGetxattr(p2, "security.capability")
if err != nil && err != syscall.ENODATA {
return false, errors.Wrapf(err, "failed to get xattr for %s", p2)
}
return bytes.Equal(c1, c2), nil
}

352
vendor/github.com/tonistiigi/fsutil/diskwriter.go generated vendored Normal file
View File

@ -0,0 +1,352 @@
package fsutil
import (
"context"
"hash"
"io"
"os"
"path/filepath"
"strconv"
"sync"
"time"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
"github.com/tonistiigi/fsutil/types"
"golang.org/x/sync/errgroup"
)
type WriteToFunc func(context.Context, string, io.WriteCloser) error
type DiskWriterOpt struct {
AsyncDataCb WriteToFunc
SyncDataCb WriteToFunc
NotifyCb func(ChangeKind, string, os.FileInfo, error) error
ContentHasher ContentHasher
Filter FilterFunc
}
type FilterFunc func(string, *types.Stat) bool
type DiskWriter struct {
opt DiskWriterOpt
dest string
wg sync.WaitGroup
ctx context.Context
cancel func()
eg *errgroup.Group
filter FilterFunc
}
func NewDiskWriter(ctx context.Context, dest string, opt DiskWriterOpt) (*DiskWriter, error) {
if opt.SyncDataCb == nil && opt.AsyncDataCb == nil {
return nil, errors.New("no data callback specified")
}
if opt.SyncDataCb != nil && opt.AsyncDataCb != nil {
return nil, errors.New("can't specify both sync and async data callbacks")
}
ctx, cancel := context.WithCancel(ctx)
eg, ctx := errgroup.WithContext(ctx)
return &DiskWriter{
opt: opt,
dest: dest,
eg: eg,
ctx: ctx,
cancel: cancel,
filter: opt.Filter,
}, nil
}
func (dw *DiskWriter) Wait(ctx context.Context) error {
return dw.eg.Wait()
}
func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, err error) (retErr error) {
if err != nil {
return err
}
select {
case <-dw.ctx.Done():
return dw.ctx.Err()
default:
}
defer func() {
if retErr != nil {
dw.cancel()
}
}()
destPath := filepath.Join(dw.dest, filepath.FromSlash(p))
if kind == ChangeKindDelete {
if dw.filter != nil {
var empty types.Stat
if ok := dw.filter(p, &empty); !ok {
return nil
}
}
// todo: no need to validate if diff is trusted but is it always?
if err := os.RemoveAll(destPath); err != nil {
return errors.Wrapf(err, "failed to remove: %s", destPath)
}
if dw.opt.NotifyCb != nil {
if err := dw.opt.NotifyCb(kind, p, nil, nil); err != nil {
return err
}
}
return nil
}
stat, ok := fi.Sys().(*types.Stat)
if !ok {
return errors.Errorf("%s invalid change without stat information", p)
}
statCopy := *stat
if dw.filter != nil {
if ok := dw.filter(p, &statCopy); !ok {
return nil
}
}
rename := true
oldFi, err := os.Lstat(destPath)
if err != nil {
if os.IsNotExist(err) {
if kind != ChangeKindAdd {
return errors.Wrapf(err, "invalid addition: %s", destPath)
}
rename = false
} else {
return errors.Wrapf(err, "failed to stat %s", destPath)
}
}
if oldFi != nil && fi.IsDir() && oldFi.IsDir() {
if err := rewriteMetadata(destPath, &statCopy); err != nil {
return errors.Wrapf(err, "error setting dir metadata for %s", destPath)
}
return nil
}
newPath := destPath
if rename {
newPath = filepath.Join(filepath.Dir(destPath), ".tmp."+nextSuffix())
}
isRegularFile := false
switch {
case fi.IsDir():
if err := os.Mkdir(newPath, fi.Mode()); err != nil {
return errors.Wrapf(err, "failed to create dir %s", newPath)
}
case fi.Mode()&os.ModeDevice != 0 || fi.Mode()&os.ModeNamedPipe != 0:
if err := handleTarTypeBlockCharFifo(newPath, &statCopy); err != nil {
return errors.Wrapf(err, "failed to create device %s", newPath)
}
case fi.Mode()&os.ModeSymlink != 0:
if err := os.Symlink(statCopy.Linkname, newPath); err != nil {
return errors.Wrapf(err, "failed to symlink %s", newPath)
}
case statCopy.Linkname != "":
if err := os.Link(filepath.Join(dw.dest, statCopy.Linkname), newPath); err != nil {
return errors.Wrapf(err, "failed to link %s to %s", newPath, statCopy.Linkname)
}
default:
isRegularFile = true
file, err := os.OpenFile(newPath, os.O_CREATE|os.O_WRONLY, fi.Mode()) //todo: windows
if err != nil {
return errors.Wrapf(err, "failed to create %s", newPath)
}
if dw.opt.SyncDataCb != nil {
if err := dw.processChange(ChangeKindAdd, p, fi, file); err != nil {
file.Close()
return err
}
break
}
if err := file.Close(); err != nil {
return errors.Wrapf(err, "failed to close %s", newPath)
}
}
if err := rewriteMetadata(newPath, &statCopy); err != nil {
return errors.Wrapf(err, "error setting metadata for %s", newPath)
}
if rename {
if oldFi.IsDir() != fi.IsDir() {
if err := os.RemoveAll(destPath); err != nil {
return errors.Wrapf(err, "failed to remove %s", destPath)
}
}
if err := os.Rename(newPath, destPath); err != nil {
return errors.Wrapf(err, "failed to rename %s to %s", newPath, destPath)
}
}
if isRegularFile {
if dw.opt.AsyncDataCb != nil {
dw.requestAsyncFileData(p, destPath, fi)
}
} else {
return dw.processChange(kind, p, fi, nil)
}
return nil
}
func (dw *DiskWriter) requestAsyncFileData(p, dest string, fi os.FileInfo) {
// todo: limit worker threads
dw.eg.Go(func() error {
if err := dw.processChange(ChangeKindAdd, p, fi, &lazyFileWriter{
dest: dest,
}); err != nil {
return err
}
return chtimes(dest, fi.ModTime().UnixNano()) // TODO: parent dirs
})
}
func (dw *DiskWriter) processChange(kind ChangeKind, p string, fi os.FileInfo, w io.WriteCloser) error {
origw := w
var hw *hashedWriter
if dw.opt.NotifyCb != nil {
var err error
if hw, err = newHashWriter(dw.opt.ContentHasher, fi, w); err != nil {
return err
}
w = hw
}
if origw != nil {
fn := dw.opt.SyncDataCb
if fn == nil && dw.opt.AsyncDataCb != nil {
fn = dw.opt.AsyncDataCb
}
if err := fn(dw.ctx, p, w); err != nil {
return err
}
} else {
if hw != nil {
hw.Close()
}
}
if hw != nil {
return dw.opt.NotifyCb(kind, p, hw, nil)
}
return nil
}
type hashedWriter struct {
os.FileInfo
io.Writer
h hash.Hash
w io.WriteCloser
dgst digest.Digest
}
func newHashWriter(ch ContentHasher, fi os.FileInfo, w io.WriteCloser) (*hashedWriter, error) {
stat, ok := fi.Sys().(*types.Stat)
if !ok {
return nil, errors.Errorf("invalid change without stat information")
}
h, err := ch(stat)
if err != nil {
return nil, err
}
hw := &hashedWriter{
FileInfo: fi,
Writer: io.MultiWriter(w, h),
h: h,
w: w,
}
return hw, nil
}
func (hw *hashedWriter) Close() error {
hw.dgst = digest.NewDigest(digest.SHA256, hw.h)
if hw.w != nil {
return hw.w.Close()
}
return nil
}
func (hw *hashedWriter) Digest() digest.Digest {
return hw.dgst
}
type lazyFileWriter struct {
dest string
ctx context.Context
f *os.File
fileMode *os.FileMode
}
func (lfw *lazyFileWriter) Write(dt []byte) (int, error) {
if lfw.f == nil {
file, err := os.OpenFile(lfw.dest, os.O_WRONLY, 0) //todo: windows
if os.IsPermission(err) {
// retry after chmod
fi, er := os.Stat(lfw.dest)
if er == nil {
mode := fi.Mode()
lfw.fileMode = &mode
er = os.Chmod(lfw.dest, mode|0222)
if er == nil {
file, err = os.OpenFile(lfw.dest, os.O_WRONLY, 0)
}
}
}
if err != nil {
return 0, errors.Wrapf(err, "failed to open %s", lfw.dest)
}
lfw.f = file
}
return lfw.f.Write(dt)
}
func (lfw *lazyFileWriter) Close() error {
var err error
if lfw.f != nil {
err = lfw.f.Close()
}
if err == nil && lfw.fileMode != nil {
err = os.Chmod(lfw.dest, *lfw.fileMode)
}
return err
}
func mkdev(major int64, minor int64) uint32 {
return uint32(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff))
}
// Random number state.
// We generate random temporary file names so that there's a good
// chance the file doesn't exist yet - keeps the number of tries in
// TempFile to a minimum.
var rand uint32
var randmu sync.Mutex
func reseed() uint32 {
return uint32(time.Now().UnixNano() + int64(os.Getpid()))
}
func nextSuffix() string {
randmu.Lock()
r := rand
if r == 0 {
r = reseed()
}
r = r*1664525 + 1013904223 // constants from Numerical Recipes
rand = r
randmu.Unlock()
return strconv.Itoa(int(1e9 + r%1e9))[1:]
}

52
vendor/github.com/tonistiigi/fsutil/diskwriter_unix.go generated vendored Normal file
View File

@ -0,0 +1,52 @@
// +build !windows
package fsutil
import (
"os"
"syscall"
"github.com/containerd/continuity/sysx"
"github.com/pkg/errors"
"github.com/tonistiigi/fsutil/types"
)
func rewriteMetadata(p string, stat *types.Stat) error {
for key, value := range stat.Xattrs {
sysx.Setxattr(p, key, value, 0)
}
if err := os.Lchown(p, int(stat.Uid), int(stat.Gid)); err != nil {
return errors.Wrapf(err, "failed to lchown %s", p)
}
if os.FileMode(stat.Mode)&os.ModeSymlink == 0 {
if err := os.Chmod(p, os.FileMode(stat.Mode)); err != nil {
return errors.Wrapf(err, "failed to chown %s", p)
}
}
if err := chtimes(p, stat.ModTime); err != nil {
return errors.Wrapf(err, "failed to chtimes %s", p)
}
return nil
}
// handleTarTypeBlockCharFifo is an OS-specific helper function used by
// createTarFile to handle the following types of header: Block; Char; Fifo
func handleTarTypeBlockCharFifo(path string, stat *types.Stat) error {
mode := uint32(stat.Mode & 07777)
if os.FileMode(stat.Mode)&os.ModeCharDevice != 0 {
mode |= syscall.S_IFCHR
} else if os.FileMode(stat.Mode)&os.ModeNamedPipe != 0 {
mode |= syscall.S_IFIFO
} else {
mode |= syscall.S_IFBLK
}
if err := syscall.Mknod(path, mode, int(mkdev(stat.Devmajor, stat.Devminor))); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,18 @@
// +build windows
package fsutil
import (
"github.com/pkg/errors"
"github.com/tonistiigi/fsutil/types"
)
func rewriteMetadata(p string, stat *types.Stat) error {
return chtimes(p, stat.ModTime)
}
// handleTarTypeBlockCharFifo is an OS-specific helper function used by
// createTarFile to handle the following types of header: Block; Char; Fifo
func handleTarTypeBlockCharFifo(path string, stat *types.Stat) error {
return errors.New("Not implemented on windows")
}

150
vendor/github.com/tonistiigi/fsutil/followlinks.go generated vendored Normal file
View File

@ -0,0 +1,150 @@
package fsutil
import (
"io/ioutil"
"os"
"path/filepath"
"runtime"
"sort"
strings "strings"
"github.com/pkg/errors"
)
func FollowLinks(root string, paths []string) ([]string, error) {
r := &symlinkResolver{root: root, resolved: map[string]struct{}{}}
for _, p := range paths {
if err := r.append(p); err != nil {
return nil, err
}
}
res := make([]string, 0, len(r.resolved))
for r := range r.resolved {
res = append(res, r)
}
sort.Strings(res)
return dedupePaths(res), nil
}
type symlinkResolver struct {
root string
resolved map[string]struct{}
}
func (r *symlinkResolver) append(p string) error {
p = filepath.Join(".", p)
current := "."
for {
parts := strings.SplitN(p, string(filepath.Separator), 2)
current = filepath.Join(current, parts[0])
targets, err := r.readSymlink(current, true)
if err != nil {
return err
}
p = ""
if len(parts) == 2 {
p = parts[1]
}
if p == "" || targets != nil {
if _, ok := r.resolved[current]; ok {
return nil
}
}
if targets != nil {
r.resolved[current] = struct{}{}
for _, target := range targets {
if err := r.append(filepath.Join(target, p)); err != nil {
return err
}
}
return nil
}
if p == "" {
r.resolved[current] = struct{}{}
return nil
}
}
}
func (r *symlinkResolver) readSymlink(p string, allowWildcard bool) ([]string, error) {
realPath := filepath.Join(r.root, p)
base := filepath.Base(p)
if allowWildcard && containsWildcards(base) {
fis, err := ioutil.ReadDir(filepath.Dir(realPath))
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, errors.Wrapf(err, "failed to read dir %s", filepath.Dir(realPath))
}
var out []string
for _, f := range fis {
if ok, _ := filepath.Match(base, f.Name()); ok {
res, err := r.readSymlink(filepath.Join(filepath.Dir(p), f.Name()), false)
if err != nil {
return nil, err
}
out = append(out, res...)
}
}
return out, nil
}
fi, err := os.Lstat(realPath)
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, errors.Wrapf(err, "failed to lstat %s", realPath)
}
if fi.Mode()&os.ModeSymlink == 0 {
return nil, nil
}
link, err := os.Readlink(realPath)
if err != nil {
return nil, errors.Wrapf(err, "failed to readlink %s", realPath)
}
link = filepath.Clean(link)
if filepath.IsAbs(link) {
return []string{link}, nil
}
return []string{
filepath.Join(string(filepath.Separator), filepath.Join(filepath.Dir(p), link)),
}, nil
}
func containsWildcards(name string) bool {
isWindows := runtime.GOOS == "windows"
for i := 0; i < len(name); i++ {
ch := name[i]
if ch == '\\' && !isWindows {
i++
} else if ch == '*' || ch == '?' || ch == '[' {
return true
}
}
return false
}
// dedupePaths expects input as a sorted list
func dedupePaths(in []string) []string {
out := make([]string, 0, len(in))
var last string
for _, s := range in {
// if one of the paths is root there is no filter
if s == "." {
return nil
}
if strings.HasPrefix(s, last+string(filepath.Separator)) {
continue
}
out = append(out, s)
last = s
}
return out
}

72
vendor/github.com/tonistiigi/fsutil/fs.go generated vendored Normal file
View File

@ -0,0 +1,72 @@
package fsutil
import (
"context"
"io"
"os"
"path"
"path/filepath"
"strings"
"github.com/pkg/errors"
"github.com/tonistiigi/fsutil/types"
)
type FS interface {
Walk(context.Context, filepath.WalkFunc) error
Open(string) (io.ReadCloser, error)
}
func NewFS(root string, opt *WalkOpt) FS {
return &fs{
root: root,
opt: opt,
}
}
type fs struct {
root string
opt *WalkOpt
}
func (fs *fs) Walk(ctx context.Context, fn filepath.WalkFunc) error {
return Walk(ctx, fs.root, fs.opt, fn)
}
func (fs *fs) Open(p string) (io.ReadCloser, error) {
return os.Open(filepath.Join(fs.root, p))
}
func SubDirFS(fs FS, stat types.Stat) FS {
return &subDirFS{fs: fs, stat: stat}
}
type subDirFS struct {
fs FS
stat types.Stat
}
func (fs *subDirFS) Walk(ctx context.Context, fn filepath.WalkFunc) error {
main := &StatInfo{Stat: &fs.stat}
if !main.IsDir() {
return errors.Errorf("fs subdir not mode directory")
}
if main.Name() != fs.stat.Path {
return errors.Errorf("subdir path must be single file")
}
if err := fn(fs.stat.Path, main, nil); err != nil {
return err
}
return fs.fs.Walk(ctx, func(p string, fi os.FileInfo, err error) error {
stat, ok := fi.Sys().(*types.Stat)
if !ok {
return errors.Wrapf(err, "invalid fileinfo without stat info: %s", p)
}
stat.Path = path.Join(fs.stat.Path, stat.Path)
return fn(filepath.Join(fs.stat.Path, p), &StatInfo{stat}, nil)
})
}
func (fs *subDirFS) Open(p string) (io.ReadCloser, error) {
return fs.fs.Open(strings.TrimPrefix(p, fs.stat.Path+"/"))
}

28
vendor/github.com/tonistiigi/fsutil/go.mod generated vendored Normal file
View File

@ -0,0 +1,28 @@
module github.com/tonistiigi/fsutil
require (
github.com/Microsoft/go-winio v0.4.11 // indirect
github.com/Microsoft/hcsshim v0.8.5 // indirect
github.com/containerd/containerd v1.2.4
github.com/containerd/continuity v0.0.0-20181001140422-bd77b46c8352
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/docker v0.0.0-20180531152204-71cd53e4a197
github.com/docker/go-units v0.3.1 // indirect
github.com/gogo/protobuf v1.0.0
github.com/google/go-cmp v0.2.0 // indirect
github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect
github.com/onsi/ginkgo v1.7.0 // indirect
github.com/onsi/gomega v1.4.3 // indirect
github.com/opencontainers/go-digest v1.0.0-rc1
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/opencontainers/runc v1.0.0-rc6 // indirect
github.com/pkg/errors v0.8.1
github.com/sirupsen/logrus v1.0.3 // indirect
github.com/stretchr/testify v1.3.0
golang.org/x/crypto v0.0.0-20190129210102-0709b304e793 // indirect
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
gotest.tools v2.1.0+incompatible // indirect
)

71
vendor/github.com/tonistiigi/fsutil/go.sum generated vendored Normal file
View File

@ -0,0 +1,71 @@
github.com/Microsoft/go-winio v0.4.11 h1:zoIOcVf0xPN1tnMVbTtEdI+P8OofVk3NObnwOQ6nK2Q=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/hcsshim v0.8.5 h1:kg/pore5Yyf4DXQ5nelSqfaYQG54YIdNeFRKJaPnFiM=
github.com/Microsoft/hcsshim v0.8.5/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/containerd/containerd v1.2.4 h1:qN8LCvw+KA5wVCOnHspD/n2K9cJ34+YOs05qBBWhHiw=
github.com/containerd/containerd v1.2.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/continuity v0.0.0-20181001140422-bd77b46c8352 h1:CdBoaTKPl60tksFVWYc5QnLWwXBcU+XcLiXx8+NcZ9o=
github.com/containerd/continuity v0.0.0-20181001140422-bd77b46c8352/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/docker v0.0.0-20180531152204-71cd53e4a197 h1:raQhUHOMIAZAWHmo3hLEwoIy0aVkKb2uxZdWw/Up+HI=
github.com/docker/docker v0.0.0-20180531152204-71cd53e4a197/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-units v0.3.1 h1:QAFdsA6jLCnglbqE6mUsHuPcJlntY94DkxHf4deHKIU=
github.com/docker/go-units v0.3.1/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM=
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI=
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v1.0.0-rc6 h1:7AoN22rYxxkmsJS48wFaziH/n0OvrZVqL/TglgHKbKQ=
github.com/opencontainers/runc v1.0.0-rc6/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.0.3 h1:B5C/igNWoiULof20pKfY4VntcIPqKuwEmoLZrabbUrc=
github.com/sirupsen/logrus v1.0.3/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20190129210102-0709b304e793 h1:XN3FXXoqhpVVlj/6kSCqFXZoVfu18c8WGW7A8JPiOOk=
golang.org/x/crypto v0.0.0-20190129210102-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.1.0+incompatible h1:5USw7CrJBYKqjg9R7QlA6jzqZKEAtvW82aNmsxxGPxw=
gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=

47
vendor/github.com/tonistiigi/fsutil/hardlinks.go generated vendored Normal file
View File

@ -0,0 +1,47 @@
package fsutil
import (
"os"
"github.com/pkg/errors"
"github.com/tonistiigi/fsutil/types"
)
// Hardlinks validates that all targets for links were part of the changes
type Hardlinks struct {
seenFiles map[string]struct{}
}
func (v *Hardlinks) HandleChange(kind ChangeKind, p string, fi os.FileInfo, err error) error {
if err != nil {
return err
}
if v.seenFiles == nil {
v.seenFiles = make(map[string]struct{})
}
if kind == ChangeKindDelete {
return nil
}
stat, ok := fi.Sys().(*types.Stat)
if !ok {
return errors.Errorf("invalid change without stat info: %s", p)
}
if fi.IsDir() || fi.Mode()&os.ModeSymlink != 0 {
return nil
}
if len(stat.Linkname) > 0 {
if _, ok := v.seenFiles[stat.Linkname]; !ok {
return errors.Errorf("invalid link %s to unknown path: %q", p, stat.Linkname)
}
} else {
v.seenFiles[p] = struct{}{}
}
return nil
}

45
vendor/github.com/tonistiigi/fsutil/readme.md generated vendored Normal file
View File

@ -0,0 +1,45 @@
Incremental file directory sync tools in golang.
```
BENCH_FILE_SIZE=10000 ./bench.test --test.bench .
BenchmarkCopyWithTar10-4 2000 995242 ns/op
BenchmarkCopyWithTar50-4 300 4710021 ns/op
BenchmarkCopyWithTar200-4 100 16627260 ns/op
BenchmarkCopyWithTar1000-4 20 60031459 ns/op
BenchmarkCPA10-4 1000 1678367 ns/op
BenchmarkCPA50-4 500 3690306 ns/op
BenchmarkCPA200-4 200 9495066 ns/op
BenchmarkCPA1000-4 50 29769289 ns/op
BenchmarkDiffCopy10-4 2000 943889 ns/op
BenchmarkDiffCopy50-4 500 3285950 ns/op
BenchmarkDiffCopy200-4 200 8563792 ns/op
BenchmarkDiffCopy1000-4 50 29511340 ns/op
BenchmarkDiffCopyProto10-4 2000 944615 ns/op
BenchmarkDiffCopyProto50-4 500 3334940 ns/op
BenchmarkDiffCopyProto200-4 200 9420038 ns/op
BenchmarkDiffCopyProto1000-4 50 30632429 ns/op
BenchmarkIncrementalDiffCopy10-4 2000 691993 ns/op
BenchmarkIncrementalDiffCopy50-4 1000 1304253 ns/op
BenchmarkIncrementalDiffCopy200-4 500 3306519 ns/op
BenchmarkIncrementalDiffCopy1000-4 200 10211343 ns/op
BenchmarkIncrementalDiffCopy5000-4 20 55194427 ns/op
BenchmarkIncrementalDiffCopy10000-4 20 91759289 ns/op
BenchmarkIncrementalCopyWithTar10-4 2000 1020258 ns/op
BenchmarkIncrementalCopyWithTar50-4 300 5348786 ns/op
BenchmarkIncrementalCopyWithTar200-4 100 19495000 ns/op
BenchmarkIncrementalCopyWithTar1000-4 20 70338507 ns/op
BenchmarkIncrementalRsync10-4 30 45215754 ns/op
BenchmarkIncrementalRsync50-4 30 45837260 ns/op
BenchmarkIncrementalRsync200-4 30 48780614 ns/op
BenchmarkIncrementalRsync1000-4 20 54801892 ns/op
BenchmarkIncrementalRsync5000-4 20 84782542 ns/op
BenchmarkIncrementalRsync10000-4 10 103355108 ns/op
BenchmarkRsync10-4 30 46776470 ns/op
BenchmarkRsync50-4 30 48601555 ns/op
BenchmarkRsync200-4 20 59642691 ns/op
BenchmarkRsync1000-4 20 101343010 ns/op
BenchmarkGnuTar10-4 500 3171448 ns/op
BenchmarkGnuTar50-4 300 5030296 ns/op
BenchmarkGnuTar200-4 100 10464313 ns/op
BenchmarkGnuTar1000-4 50 30375257 ns/op
```

276
vendor/github.com/tonistiigi/fsutil/receive.go generated vendored Normal file
View File

@ -0,0 +1,276 @@
package fsutil
import (
"context"
"io"
"os"
"sync"
"github.com/pkg/errors"
"github.com/tonistiigi/fsutil/types"
"golang.org/x/sync/errgroup"
)
type ReceiveOpt struct {
NotifyHashed ChangeFunc
ContentHasher ContentHasher
ProgressCb func(int, bool)
Merge bool
Filter FilterFunc
}
func Receive(ctx context.Context, conn Stream, dest string, opt ReceiveOpt) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
r := &receiver{
conn: &syncStream{Stream: conn},
dest: dest,
files: make(map[string]uint32),
pipes: make(map[uint32]io.WriteCloser),
notifyHashed: opt.NotifyHashed,
contentHasher: opt.ContentHasher,
progressCb: opt.ProgressCb,
merge: opt.Merge,
filter: opt.Filter,
}
return r.run(ctx)
}
type receiver struct {
dest string
conn Stream
files map[string]uint32
pipes map[uint32]io.WriteCloser
mu sync.RWMutex
muPipes sync.RWMutex
progressCb func(int, bool)
merge bool
filter FilterFunc
notifyHashed ChangeFunc
contentHasher ContentHasher
orderValidator Validator
hlValidator Hardlinks
}
type dynamicWalker struct {
walkChan chan *currentPath
err error
closeCh chan struct{}
}
func newDynamicWalker() *dynamicWalker {
return &dynamicWalker{
walkChan: make(chan *currentPath, 128),
closeCh: make(chan struct{}),
}
}
func (w *dynamicWalker) update(p *currentPath) error {
select {
case <-w.closeCh:
return errors.Wrap(w.err, "walker is closed")
default:
}
if p == nil {
close(w.walkChan)
return nil
}
select {
case w.walkChan <- p:
return nil
case <-w.closeCh:
return errors.Wrap(w.err, "walker is closed")
}
}
func (w *dynamicWalker) fill(ctx context.Context, pathC chan<- *currentPath) error {
for {
select {
case p, ok := <-w.walkChan:
if !ok {
return nil
}
select {
case pathC <- p:
case <-ctx.Done():
w.err = ctx.Err()
close(w.closeCh)
return ctx.Err()
}
case <-ctx.Done():
w.err = ctx.Err()
close(w.closeCh)
return ctx.Err()
}
}
return nil
}
func (r *receiver) run(ctx context.Context) error {
g, ctx := errgroup.WithContext(ctx)
dw, err := NewDiskWriter(ctx, r.dest, DiskWriterOpt{
AsyncDataCb: r.asyncDataFunc,
NotifyCb: r.notifyHashed,
ContentHasher: r.contentHasher,
Filter: r.filter,
})
if err != nil {
return err
}
w := newDynamicWalker()
g.Go(func() (retErr error) {
defer func() {
if retErr != nil {
r.conn.SendMsg(&types.Packet{Type: types.PACKET_ERR, Data: []byte(retErr.Error())})
}
}()
destWalker := emptyWalker
if !r.merge {
destWalker = GetWalkerFn(r.dest)
}
err := doubleWalkDiff(ctx, dw.HandleChange, destWalker, w.fill)
if err != nil {
return err
}
if err := dw.Wait(ctx); err != nil {
return err
}
r.conn.SendMsg(&types.Packet{Type: types.PACKET_FIN})
return nil
})
g.Go(func() error {
var i uint32 = 0
size := 0
if r.progressCb != nil {
defer func() {
r.progressCb(size, true)
}()
}
var p types.Packet
for {
p = types.Packet{Data: p.Data[:0]}
if err := r.conn.RecvMsg(&p); err != nil {
return err
}
if r.progressCb != nil {
size += p.Size()
r.progressCb(size, false)
}
switch p.Type {
case types.PACKET_ERR:
return errors.Errorf("error from sender: %s", p.Data)
case types.PACKET_STAT:
if p.Stat == nil {
if err := w.update(nil); err != nil {
return err
}
break
}
if fileCanRequestData(os.FileMode(p.Stat.Mode)) {
r.mu.Lock()
r.files[p.Stat.Path] = i
r.mu.Unlock()
}
i++
cp := &currentPath{path: p.Stat.Path, f: &StatInfo{p.Stat}}
if err := r.orderValidator.HandleChange(ChangeKindAdd, cp.path, cp.f, nil); err != nil {
return err
}
if err := r.hlValidator.HandleChange(ChangeKindAdd, cp.path, cp.f, nil); err != nil {
return err
}
if err := w.update(cp); err != nil {
return err
}
case types.PACKET_DATA:
r.muPipes.Lock()
pw, ok := r.pipes[p.ID]
r.muPipes.Unlock()
if !ok {
return errors.Errorf("invalid file request %d", p.ID)
}
if len(p.Data) == 0 {
if err := pw.Close(); err != nil {
return err
}
} else {
if _, err := pw.Write(p.Data); err != nil {
return err
}
}
case types.PACKET_FIN:
for {
var p types.Packet
if err := r.conn.RecvMsg(&p); err != nil {
if err == io.EOF {
return nil
}
return err
}
}
}
}
})
return g.Wait()
}
func (r *receiver) asyncDataFunc(ctx context.Context, p string, wc io.WriteCloser) error {
r.mu.Lock()
id, ok := r.files[p]
if !ok {
r.mu.Unlock()
return errors.Errorf("invalid file request %s", p)
}
delete(r.files, p)
r.mu.Unlock()
wwc := newWrappedWriteCloser(wc)
r.muPipes.Lock()
r.pipes[id] = wwc
r.muPipes.Unlock()
if err := r.conn.SendMsg(&types.Packet{Type: types.PACKET_REQ, ID: id}); err != nil {
return err
}
err := wwc.Wait(ctx)
if err != nil {
return err
}
r.muPipes.Lock()
delete(r.pipes, id)
r.muPipes.Unlock()
return nil
}
type wrappedWriteCloser struct {
io.WriteCloser
err error
once sync.Once
done chan struct{}
}
func newWrappedWriteCloser(wc io.WriteCloser) *wrappedWriteCloser {
return &wrappedWriteCloser{WriteCloser: wc, done: make(chan struct{})}
}
func (w *wrappedWriteCloser) Close() error {
w.err = w.WriteCloser.Close()
w.once.Do(func() { close(w.done) })
return w.err
}
func (w *wrappedWriteCloser) Wait(ctx context.Context) error {
select {
case <-ctx.Done():
return ctx.Err()
case <-w.done:
return w.err
}
}

206
vendor/github.com/tonistiigi/fsutil/send.go generated vendored Normal file
View File

@ -0,0 +1,206 @@
package fsutil
import (
"context"
"io"
"os"
"sync"
"github.com/pkg/errors"
"github.com/tonistiigi/fsutil/types"
"golang.org/x/sync/errgroup"
)
var bufPool = sync.Pool{
New: func() interface{} {
return make([]byte, 32*1<<10)
},
}
type Stream interface {
RecvMsg(interface{}) error
SendMsg(m interface{}) error
Context() context.Context
}
func Send(ctx context.Context, conn Stream, fs FS, progressCb func(int, bool)) error {
s := &sender{
conn: &syncStream{Stream: conn},
fs: fs,
files: make(map[uint32]string),
progressCb: progressCb,
sendpipeline: make(chan *sendHandle, 128),
}
return s.run(ctx)
}
type sendHandle struct {
id uint32
path string
}
type sender struct {
conn Stream
fs FS
files map[uint32]string
mu sync.RWMutex
progressCb func(int, bool)
progressCurrent int
sendpipeline chan *sendHandle
}
func (s *sender) run(ctx context.Context) error {
g, ctx := errgroup.WithContext(ctx)
defer s.updateProgress(0, true)
g.Go(func() error {
err := s.walk(ctx)
if err != nil {
s.conn.SendMsg(&types.Packet{Type: types.PACKET_ERR, Data: []byte(err.Error())})
}
return err
})
for i := 0; i < 4; i++ {
g.Go(func() error {
for h := range s.sendpipeline {
select {
case <-ctx.Done():
return ctx.Err()
default:
}
if err := s.sendFile(h); err != nil {
return err
}
}
return nil
})
}
g.Go(func() error {
defer close(s.sendpipeline)
for {
select {
case <-ctx.Done():
return ctx.Err()
default:
}
var p types.Packet
if err := s.conn.RecvMsg(&p); err != nil {
return err
}
switch p.Type {
case types.PACKET_ERR:
return errors.Errorf("error from receiver: %s", p.Data)
case types.PACKET_REQ:
if err := s.queue(p.ID); err != nil {
return err
}
case types.PACKET_FIN:
return s.conn.SendMsg(&types.Packet{Type: types.PACKET_FIN})
}
}
})
return g.Wait()
}
func (s *sender) updateProgress(size int, last bool) {
if s.progressCb != nil {
s.progressCurrent += size
s.progressCb(s.progressCurrent, last)
}
}
func (s *sender) queue(id uint32) error {
s.mu.Lock()
p, ok := s.files[id]
if !ok {
s.mu.Unlock()
return errors.Errorf("invalid file id %d", id)
}
delete(s.files, id)
s.mu.Unlock()
s.sendpipeline <- &sendHandle{id, p}
return nil
}
func (s *sender) sendFile(h *sendHandle) error {
f, err := s.fs.Open(h.path)
if err == nil {
defer f.Close()
buf := bufPool.Get().([]byte)
defer bufPool.Put(buf)
if _, err := io.CopyBuffer(&fileSender{sender: s, id: h.id}, f, buf); err != nil {
return err
}
}
return s.conn.SendMsg(&types.Packet{ID: h.id, Type: types.PACKET_DATA})
}
func (s *sender) walk(ctx context.Context) error {
var i uint32 = 0
err := s.fs.Walk(ctx, func(path string, fi os.FileInfo, err error) error {
if err != nil {
return err
}
stat, ok := fi.Sys().(*types.Stat)
if !ok {
return errors.Wrapf(err, "invalid fileinfo without stat info: %s", path)
}
p := &types.Packet{
Type: types.PACKET_STAT,
Stat: stat,
}
if fileCanRequestData(os.FileMode(stat.Mode)) {
s.mu.Lock()
s.files[i] = stat.Path
s.mu.Unlock()
}
i++
s.updateProgress(p.Size(), false)
return errors.Wrapf(s.conn.SendMsg(p), "failed to send stat %s", path)
})
if err != nil {
return err
}
return errors.Wrapf(s.conn.SendMsg(&types.Packet{Type: types.PACKET_STAT}), "failed to send last stat")
}
func fileCanRequestData(m os.FileMode) bool {
// avoid updating this function as it needs to match between sender/receiver.
// version if needed
return m&os.ModeType == 0
}
type fileSender struct {
sender *sender
id uint32
}
func (fs *fileSender) Write(dt []byte) (int, error) {
if len(dt) == 0 {
return 0, nil
}
p := &types.Packet{Type: types.PACKET_DATA, ID: fs.id, Data: dt}
if err := fs.sender.conn.SendMsg(p); err != nil {
return 0, err
}
fs.sender.updateProgress(p.Size(), false)
return len(dt), nil
}
type syncStream struct {
Stream
mu sync.Mutex
}
func (ss *syncStream) SendMsg(m interface{}) error {
ss.mu.Lock()
err := ss.Stream.SendMsg(m)
ss.mu.Unlock()
return err
}

61
vendor/github.com/tonistiigi/fsutil/stat.go generated vendored Normal file
View File

@ -0,0 +1,61 @@
package fsutil
import (
"os"
"path/filepath"
"runtime"
"github.com/pkg/errors"
"github.com/tonistiigi/fsutil/types"
)
// constructs a Stat object. path is where the path can be found right
// now, relpath is the desired path to be recorded in the stat (so
// relative to whatever base dir is relevant). fi is the os.Stat
// info. inodemap is used to calculate hardlinks over a series of
// mkstat calls and maps inode to the canonical (aka "first") path for
// a set of hardlinks to that inode.
func mkstat(path, relpath string, fi os.FileInfo, inodemap map[uint64]string) (*types.Stat, error) {
relpath = filepath.ToSlash(relpath)
stat := &types.Stat{
Path: relpath,
Mode: uint32(fi.Mode()),
ModTime: fi.ModTime().UnixNano(),
}
setUnixOpt(fi, stat, relpath, inodemap)
if !fi.IsDir() {
stat.Size_ = fi.Size()
if fi.Mode()&os.ModeSymlink != 0 {
link, err := os.Readlink(path)
if err != nil {
return nil, errors.Wrapf(err, "failed to readlink %s", path)
}
stat.Linkname = link
}
}
if err := loadXattr(path, stat); err != nil {
return nil, errors.Wrapf(err, "failed to xattr %s", relpath)
}
if runtime.GOOS == "windows" {
permPart := stat.Mode & uint32(os.ModePerm)
noPermPart := stat.Mode &^ uint32(os.ModePerm)
// Add the x bit: make everything +x from windows
permPart |= 0111
permPart &= 0755
stat.Mode = noPermPart | permPart
}
return stat, nil
}
func Stat(path string) (*types.Stat, error) {
fi, err := os.Lstat(path)
if err != nil {
return nil, errors.Wrap(err, "os stat")
}
return mkstat(path, filepath.Base(path), fi, nil)
}

71
vendor/github.com/tonistiigi/fsutil/stat_unix.go generated vendored Normal file
View File

@ -0,0 +1,71 @@
// +build !windows
package fsutil
import (
"os"
"syscall"
"github.com/containerd/continuity/sysx"
"github.com/pkg/errors"
"github.com/tonistiigi/fsutil/types"
)
func loadXattr(origpath string, stat *types.Stat) error {
xattrs, err := sysx.LListxattr(origpath)
if err != nil {
if errors.Cause(err) == syscall.ENOTSUP {
return nil
}
return errors.Wrapf(err, "failed to xattr %s", origpath)
}
if len(xattrs) > 0 {
m := make(map[string][]byte)
for _, key := range xattrs {
v, err := sysx.LGetxattr(origpath, key)
if err == nil {
m[key] = v
}
}
stat.Xattrs = m
}
return nil
}
func setUnixOpt(fi os.FileInfo, stat *types.Stat, path string, seenFiles map[uint64]string) {
s := fi.Sys().(*syscall.Stat_t)
stat.Uid = s.Uid
stat.Gid = s.Gid
if !fi.IsDir() {
if s.Mode&syscall.S_IFBLK != 0 ||
s.Mode&syscall.S_IFCHR != 0 {
stat.Devmajor = int64(major(uint64(s.Rdev)))
stat.Devminor = int64(minor(uint64(s.Rdev)))
}
ino := s.Ino
linked := false
if seenFiles != nil {
if s.Nlink > 1 {
if oldpath, ok := seenFiles[ino]; ok {
stat.Linkname = oldpath
stat.Size_ = 0
linked = true
}
}
if !linked {
seenFiles[ino] = path
}
}
}
}
func major(device uint64) uint64 {
return (device >> 8) & 0xfff
}
func minor(device uint64) uint64 {
return (device & 0xff) | ((device >> 12) & 0xfff00)
}

16
vendor/github.com/tonistiigi/fsutil/stat_windows.go generated vendored Normal file
View File

@ -0,0 +1,16 @@
// +build windows
package fsutil
import (
"os"
"github.com/tonistiigi/fsutil/types"
)
func loadXattr(_ string, _ *types.Stat) error {
return nil
}
func setUnixOpt(_ os.FileInfo, _ *types.Stat, _ string, _ map[uint64]string) {
}

View File

@ -0,0 +1,3 @@
package types
//go:generate protoc --gogoslick_out=. stat.proto wire.proto

909
vendor/github.com/tonistiigi/fsutil/types/stat.pb.go generated vendored Normal file
View File

@ -0,0 +1,909 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: stat.proto
/*
Package types is a generated protocol buffer package.
It is generated from these files:
stat.proto
wire.proto
It has these top-level messages:
Stat
Packet
*/
package types
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import bytes "bytes"
import strings "strings"
import reflect "reflect"
import sortkeys "github.com/gogo/protobuf/sortkeys"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type Stat struct {
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
Mode uint32 `protobuf:"varint,2,opt,name=mode,proto3" json:"mode,omitempty"`
Uid uint32 `protobuf:"varint,3,opt,name=uid,proto3" json:"uid,omitempty"`
Gid uint32 `protobuf:"varint,4,opt,name=gid,proto3" json:"gid,omitempty"`
Size_ int64 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"`
ModTime int64 `protobuf:"varint,6,opt,name=modTime,proto3" json:"modTime,omitempty"`
// int32 typeflag = 7;
Linkname string `protobuf:"bytes,7,opt,name=linkname,proto3" json:"linkname,omitempty"`
Devmajor int64 `protobuf:"varint,8,opt,name=devmajor,proto3" json:"devmajor,omitempty"`
Devminor int64 `protobuf:"varint,9,opt,name=devminor,proto3" json:"devminor,omitempty"`
Xattrs map[string][]byte `protobuf:"bytes,10,rep,name=xattrs" json:"xattrs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (m *Stat) Reset() { *m = Stat{} }
func (*Stat) ProtoMessage() {}
func (*Stat) Descriptor() ([]byte, []int) { return fileDescriptorStat, []int{0} }
func (m *Stat) GetPath() string {
if m != nil {
return m.Path
}
return ""
}
func (m *Stat) GetMode() uint32 {
if m != nil {
return m.Mode
}
return 0
}
func (m *Stat) GetUid() uint32 {
if m != nil {
return m.Uid
}
return 0
}
func (m *Stat) GetGid() uint32 {
if m != nil {
return m.Gid
}
return 0
}
func (m *Stat) GetSize_() int64 {
if m != nil {
return m.Size_
}
return 0
}
func (m *Stat) GetModTime() int64 {
if m != nil {
return m.ModTime
}
return 0
}
func (m *Stat) GetLinkname() string {
if m != nil {
return m.Linkname
}
return ""
}
func (m *Stat) GetDevmajor() int64 {
if m != nil {
return m.Devmajor
}
return 0
}
func (m *Stat) GetDevminor() int64 {
if m != nil {
return m.Devminor
}
return 0
}
func (m *Stat) GetXattrs() map[string][]byte {
if m != nil {
return m.Xattrs
}
return nil
}
func init() {
proto.RegisterType((*Stat)(nil), "fsutil.types.Stat")
}
func (this *Stat) Equal(that interface{}) bool {
if that == nil {
return this == nil
}
that1, ok := that.(*Stat)
if !ok {
that2, ok := that.(Stat)
if ok {
that1 = &that2
} else {
return false
}
}
if that1 == nil {
return this == nil
} else if this == nil {
return false
}
if this.Path != that1.Path {
return false
}
if this.Mode != that1.Mode {
return false
}
if this.Uid != that1.Uid {
return false
}
if this.Gid != that1.Gid {
return false
}
if this.Size_ != that1.Size_ {
return false
}
if this.ModTime != that1.ModTime {
return false
}
if this.Linkname != that1.Linkname {
return false
}
if this.Devmajor != that1.Devmajor {
return false
}
if this.Devminor != that1.Devminor {
return false
}
if len(this.Xattrs) != len(that1.Xattrs) {
return false
}
for i := range this.Xattrs {
if !bytes.Equal(this.Xattrs[i], that1.Xattrs[i]) {
return false
}
}
return true
}
func (this *Stat) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 14)
s = append(s, "&types.Stat{")
s = append(s, "Path: "+fmt.Sprintf("%#v", this.Path)+",\n")
s = append(s, "Mode: "+fmt.Sprintf("%#v", this.Mode)+",\n")
s = append(s, "Uid: "+fmt.Sprintf("%#v", this.Uid)+",\n")
s = append(s, "Gid: "+fmt.Sprintf("%#v", this.Gid)+",\n")
s = append(s, "Size_: "+fmt.Sprintf("%#v", this.Size_)+",\n")
s = append(s, "ModTime: "+fmt.Sprintf("%#v", this.ModTime)+",\n")
s = append(s, "Linkname: "+fmt.Sprintf("%#v", this.Linkname)+",\n")
s = append(s, "Devmajor: "+fmt.Sprintf("%#v", this.Devmajor)+",\n")
s = append(s, "Devminor: "+fmt.Sprintf("%#v", this.Devminor)+",\n")
keysForXattrs := make([]string, 0, len(this.Xattrs))
for k, _ := range this.Xattrs {
keysForXattrs = append(keysForXattrs, k)
}
sortkeys.Strings(keysForXattrs)
mapStringForXattrs := "map[string][]byte{"
for _, k := range keysForXattrs {
mapStringForXattrs += fmt.Sprintf("%#v: %#v,", k, this.Xattrs[k])
}
mapStringForXattrs += "}"
if this.Xattrs != nil {
s = append(s, "Xattrs: "+mapStringForXattrs+",\n")
}
s = append(s, "}")
return strings.Join(s, "")
}
func valueToGoStringStat(v interface{}, typ string) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func (m *Stat) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Stat) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Path) > 0 {
dAtA[i] = 0xa
i++
i = encodeVarintStat(dAtA, i, uint64(len(m.Path)))
i += copy(dAtA[i:], m.Path)
}
if m.Mode != 0 {
dAtA[i] = 0x10
i++
i = encodeVarintStat(dAtA, i, uint64(m.Mode))
}
if m.Uid != 0 {
dAtA[i] = 0x18
i++
i = encodeVarintStat(dAtA, i, uint64(m.Uid))
}
if m.Gid != 0 {
dAtA[i] = 0x20
i++
i = encodeVarintStat(dAtA, i, uint64(m.Gid))
}
if m.Size_ != 0 {
dAtA[i] = 0x28
i++
i = encodeVarintStat(dAtA, i, uint64(m.Size_))
}
if m.ModTime != 0 {
dAtA[i] = 0x30
i++
i = encodeVarintStat(dAtA, i, uint64(m.ModTime))
}
if len(m.Linkname) > 0 {
dAtA[i] = 0x3a
i++
i = encodeVarintStat(dAtA, i, uint64(len(m.Linkname)))
i += copy(dAtA[i:], m.Linkname)
}
if m.Devmajor != 0 {
dAtA[i] = 0x40
i++
i = encodeVarintStat(dAtA, i, uint64(m.Devmajor))
}
if m.Devminor != 0 {
dAtA[i] = 0x48
i++
i = encodeVarintStat(dAtA, i, uint64(m.Devminor))
}
if len(m.Xattrs) > 0 {
for k, _ := range m.Xattrs {
dAtA[i] = 0x52
i++
v := m.Xattrs[k]
byteSize := 0
if len(v) > 0 {
byteSize = 1 + len(v) + sovStat(uint64(len(v)))
}
mapSize := 1 + len(k) + sovStat(uint64(len(k))) + byteSize
i = encodeVarintStat(dAtA, i, uint64(mapSize))
dAtA[i] = 0xa
i++
i = encodeVarintStat(dAtA, i, uint64(len(k)))
i += copy(dAtA[i:], k)
if len(v) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintStat(dAtA, i, uint64(len(v)))
i += copy(dAtA[i:], v)
}
}
}
return i, nil
}
func encodeVarintStat(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func (m *Stat) Size() (n int) {
var l int
_ = l
l = len(m.Path)
if l > 0 {
n += 1 + l + sovStat(uint64(l))
}
if m.Mode != 0 {
n += 1 + sovStat(uint64(m.Mode))
}
if m.Uid != 0 {
n += 1 + sovStat(uint64(m.Uid))
}
if m.Gid != 0 {
n += 1 + sovStat(uint64(m.Gid))
}
if m.Size_ != 0 {
n += 1 + sovStat(uint64(m.Size_))
}
if m.ModTime != 0 {
n += 1 + sovStat(uint64(m.ModTime))
}
l = len(m.Linkname)
if l > 0 {
n += 1 + l + sovStat(uint64(l))
}
if m.Devmajor != 0 {
n += 1 + sovStat(uint64(m.Devmajor))
}
if m.Devminor != 0 {
n += 1 + sovStat(uint64(m.Devminor))
}
if len(m.Xattrs) > 0 {
for k, v := range m.Xattrs {
_ = k
_ = v
l = 0
if len(v) > 0 {
l = 1 + len(v) + sovStat(uint64(len(v)))
}
mapEntrySize := 1 + len(k) + sovStat(uint64(len(k))) + l
n += mapEntrySize + 1 + sovStat(uint64(mapEntrySize))
}
}
return n
}
func sovStat(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozStat(x uint64) (n int) {
return sovStat(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (this *Stat) String() string {
if this == nil {
return "nil"
}
keysForXattrs := make([]string, 0, len(this.Xattrs))
for k, _ := range this.Xattrs {
keysForXattrs = append(keysForXattrs, k)
}
sortkeys.Strings(keysForXattrs)
mapStringForXattrs := "map[string][]byte{"
for _, k := range keysForXattrs {
mapStringForXattrs += fmt.Sprintf("%v: %v,", k, this.Xattrs[k])
}
mapStringForXattrs += "}"
s := strings.Join([]string{`&Stat{`,
`Path:` + fmt.Sprintf("%v", this.Path) + `,`,
`Mode:` + fmt.Sprintf("%v", this.Mode) + `,`,
`Uid:` + fmt.Sprintf("%v", this.Uid) + `,`,
`Gid:` + fmt.Sprintf("%v", this.Gid) + `,`,
`Size_:` + fmt.Sprintf("%v", this.Size_) + `,`,
`ModTime:` + fmt.Sprintf("%v", this.ModTime) + `,`,
`Linkname:` + fmt.Sprintf("%v", this.Linkname) + `,`,
`Devmajor:` + fmt.Sprintf("%v", this.Devmajor) + `,`,
`Devminor:` + fmt.Sprintf("%v", this.Devminor) + `,`,
`Xattrs:` + mapStringForXattrs + `,`,
`}`,
}, "")
return s
}
func valueToStringStat(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("*%v", pv)
}
func (m *Stat) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Stat: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Stat: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthStat
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Path = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType)
}
m.Mode = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Mode |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Uid", wireType)
}
m.Uid = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Uid |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Gid", wireType)
}
m.Gid = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Gid |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 5:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Size_", wireType)
}
m.Size_ = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Size_ |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ModTime", wireType)
}
m.ModTime = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ModTime |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 7:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Linkname", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthStat
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Linkname = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 8:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Devmajor", wireType)
}
m.Devmajor = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Devmajor |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 9:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Devminor", wireType)
}
m.Devminor = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Devminor |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 10:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Xattrs", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthStat
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Xattrs == nil {
m.Xattrs = make(map[string][]byte)
}
var mapkey string
mapvalue := []byte{}
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthStat
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var mapbyteLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStat
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapbyteLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intMapbyteLen := int(mapbyteLen)
if intMapbyteLen < 0 {
return ErrInvalidLengthStat
}
postbytesIndex := iNdEx + intMapbyteLen
if postbytesIndex > l {
return io.ErrUnexpectedEOF
}
mapvalue = make([]byte, mapbyteLen)
copy(mapvalue, dAtA[iNdEx:postbytesIndex])
iNdEx = postbytesIndex
} else {
iNdEx = entryPreIndex
skippy, err := skipStat(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthStat
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.Xattrs[mapkey] = mapvalue
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipStat(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthStat
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipStat(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowStat
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowStat
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowStat
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthStat
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowStat
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipStat(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthStat = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowStat = fmt.Errorf("proto: integer overflow")
)
func init() { proto.RegisterFile("stat.proto", fileDescriptorStat) }
var fileDescriptorStat = []byte{
// 310 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x91, 0xbd, 0x4e, 0xc3, 0x30,
0x14, 0x85, 0x73, 0x9b, 0xfe, 0xba, 0x45, 0x42, 0x16, 0x83, 0xd5, 0xe1, 0x2a, 0x62, 0xca, 0x94,
0x81, 0x4a, 0x08, 0x18, 0x91, 0x78, 0x81, 0xc0, 0x80, 0xd8, 0x8c, 0x6c, 0x8a, 0x69, 0x13, 0x57,
0x89, 0x5b, 0x51, 0x26, 0x1e, 0x81, 0xc7, 0xe0, 0x4d, 0x60, 0xec, 0xc8, 0x48, 0xcc, 0xc2, 0xd8,
0x47, 0x40, 0x76, 0xda, 0xd2, 0xed, 0x9c, 0xef, 0xdc, 0xab, 0xe4, 0x5c, 0x13, 0x52, 0x1a, 0x6e,
0x92, 0x59, 0xa1, 0x8d, 0xa6, 0x83, 0x87, 0x72, 0x6e, 0xd4, 0x34, 0x31, 0xcb, 0x99, 0x2c, 0x8f,
0x3f, 0x1a, 0xa4, 0x79, 0x6d, 0xb8, 0xa1, 0x94, 0x34, 0x67, 0xdc, 0x3c, 0x32, 0x88, 0x20, 0xee,
0xa5, 0x5e, 0x3b, 0x96, 0x69, 0x21, 0x59, 0x23, 0x82, 0xf8, 0x20, 0xf5, 0x9a, 0x1e, 0x92, 0x70,
0xae, 0x04, 0x0b, 0x3d, 0x72, 0xd2, 0x91, 0xb1, 0x12, 0xac, 0x59, 0x93, 0xb1, 0x12, 0x6e, 0xaf,
0x54, 0x2f, 0x92, 0xb5, 0x22, 0x88, 0xc3, 0xd4, 0x6b, 0xca, 0x48, 0x27, 0xd3, 0xe2, 0x46, 0x65,
0x92, 0xb5, 0x3d, 0xde, 0x5a, 0x3a, 0x24, 0xdd, 0xa9, 0xca, 0x27, 0x39, 0xcf, 0x24, 0xeb, 0xf8,
0xaf, 0xef, 0xbc, 0xcb, 0x84, 0x5c, 0x64, 0xfc, 0x49, 0x17, 0xac, 0xeb, 0xd7, 0x76, 0x7e, 0x9b,
0xa9, 0x5c, 0x17, 0xac, 0xf7, 0x9f, 0x39, 0x4f, 0x4f, 0x49, 0xfb, 0x99, 0x1b, 0x53, 0x94, 0x8c,
0x44, 0x61, 0xdc, 0x3f, 0xc1, 0x64, 0xbf, 0x75, 0xe2, 0x1a, 0x27, 0xb7, 0x7e, 0xe0, 0x2a, 0x37,
0xc5, 0x32, 0xdd, 0x4c, 0x0f, 0xcf, 0x49, 0x7f, 0x0f, 0xbb, 0x6a, 0x13, 0xb9, 0xdc, 0xdc, 0xc4,
0x49, 0x7a, 0x44, 0x5a, 0x0b, 0x3e, 0x9d, 0xd7, 0x37, 0x19, 0xa4, 0xb5, 0xb9, 0x68, 0x9c, 0xc1,
0xe5, 0x68, 0x55, 0x61, 0xf0, 0x55, 0x61, 0xb0, 0xae, 0x10, 0x5e, 0x2d, 0xc2, 0xbb, 0x45, 0xf8,
0xb4, 0x08, 0x2b, 0x8b, 0xf0, 0x6d, 0x11, 0x7e, 0x2d, 0x06, 0x6b, 0x8b, 0xf0, 0xf6, 0x83, 0xc1,
0x5d, 0xcb, 0xff, 0xc8, 0x7d, 0xdb, 0xbf, 0xc9, 0xe8, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x90, 0xc2,
0xcf, 0x79, 0xa1, 0x01, 0x00, 0x00,
}

19
vendor/github.com/tonistiigi/fsutil/types/stat.proto generated vendored Normal file
View File

@ -0,0 +1,19 @@
syntax = "proto3";
package fsutil.types;
option go_package = "types";
message Stat {
string path = 1;
uint32 mode = 2;
uint32 uid = 3;
uint32 gid = 4;
int64 size = 5;
int64 modTime = 6;
// int32 typeflag = 7;
string linkname = 7;
int64 devmajor = 8;
int64 devminor = 9;
map<string, bytes> xattrs = 10;
}

542
vendor/github.com/tonistiigi/fsutil/types/wire.pb.go generated vendored Normal file
View File

@ -0,0 +1,542 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: wire.proto
package types
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import strconv "strconv"
import bytes "bytes"
import strings "strings"
import reflect "reflect"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
type Packet_PacketType int32
const (
PACKET_STAT Packet_PacketType = 0
PACKET_REQ Packet_PacketType = 1
PACKET_DATA Packet_PacketType = 2
PACKET_FIN Packet_PacketType = 3
PACKET_ERR Packet_PacketType = 4
)
var Packet_PacketType_name = map[int32]string{
0: "PACKET_STAT",
1: "PACKET_REQ",
2: "PACKET_DATA",
3: "PACKET_FIN",
4: "PACKET_ERR",
}
var Packet_PacketType_value = map[string]int32{
"PACKET_STAT": 0,
"PACKET_REQ": 1,
"PACKET_DATA": 2,
"PACKET_FIN": 3,
"PACKET_ERR": 4,
}
func (Packet_PacketType) EnumDescriptor() ([]byte, []int) { return fileDescriptorWire, []int{0, 0} }
type Packet struct {
Type Packet_PacketType `protobuf:"varint,1,opt,name=type,proto3,enum=fsutil.types.Packet_PacketType" json:"type,omitempty"`
Stat *Stat `protobuf:"bytes,2,opt,name=stat" json:"stat,omitempty"`
ID uint32 `protobuf:"varint,3,opt,name=ID,proto3" json:"ID,omitempty"`
Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
}
func (m *Packet) Reset() { *m = Packet{} }
func (*Packet) ProtoMessage() {}
func (*Packet) Descriptor() ([]byte, []int) { return fileDescriptorWire, []int{0} }
func (m *Packet) GetType() Packet_PacketType {
if m != nil {
return m.Type
}
return PACKET_STAT
}
func (m *Packet) GetStat() *Stat {
if m != nil {
return m.Stat
}
return nil
}
func (m *Packet) GetID() uint32 {
if m != nil {
return m.ID
}
return 0
}
func (m *Packet) GetData() []byte {
if m != nil {
return m.Data
}
return nil
}
func init() {
proto.RegisterType((*Packet)(nil), "fsutil.types.Packet")
proto.RegisterEnum("fsutil.types.Packet_PacketType", Packet_PacketType_name, Packet_PacketType_value)
}
func (x Packet_PacketType) String() string {
s, ok := Packet_PacketType_name[int32(x)]
if ok {
return s
}
return strconv.Itoa(int(x))
}
func (this *Packet) Equal(that interface{}) bool {
if that == nil {
return this == nil
}
that1, ok := that.(*Packet)
if !ok {
that2, ok := that.(Packet)
if ok {
that1 = &that2
} else {
return false
}
}
if that1 == nil {
return this == nil
} else if this == nil {
return false
}
if this.Type != that1.Type {
return false
}
if !this.Stat.Equal(that1.Stat) {
return false
}
if this.ID != that1.ID {
return false
}
if !bytes.Equal(this.Data, that1.Data) {
return false
}
return true
}
func (this *Packet) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 8)
s = append(s, "&types.Packet{")
s = append(s, "Type: "+fmt.Sprintf("%#v", this.Type)+",\n")
if this.Stat != nil {
s = append(s, "Stat: "+fmt.Sprintf("%#v", this.Stat)+",\n")
}
s = append(s, "ID: "+fmt.Sprintf("%#v", this.ID)+",\n")
s = append(s, "Data: "+fmt.Sprintf("%#v", this.Data)+",\n")
s = append(s, "}")
return strings.Join(s, "")
}
func valueToGoStringWire(v interface{}, typ string) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func (m *Packet) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Packet) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Type != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintWire(dAtA, i, uint64(m.Type))
}
if m.Stat != nil {
dAtA[i] = 0x12
i++
i = encodeVarintWire(dAtA, i, uint64(m.Stat.Size()))
n1, err := m.Stat.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n1
}
if m.ID != 0 {
dAtA[i] = 0x18
i++
i = encodeVarintWire(dAtA, i, uint64(m.ID))
}
if len(m.Data) > 0 {
dAtA[i] = 0x22
i++
i = encodeVarintWire(dAtA, i, uint64(len(m.Data)))
i += copy(dAtA[i:], m.Data)
}
return i, nil
}
func encodeVarintWire(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func (m *Packet) Size() (n int) {
var l int
_ = l
if m.Type != 0 {
n += 1 + sovWire(uint64(m.Type))
}
if m.Stat != nil {
l = m.Stat.Size()
n += 1 + l + sovWire(uint64(l))
}
if m.ID != 0 {
n += 1 + sovWire(uint64(m.ID))
}
l = len(m.Data)
if l > 0 {
n += 1 + l + sovWire(uint64(l))
}
return n
}
func sovWire(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozWire(x uint64) (n int) {
return sovWire(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (this *Packet) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&Packet{`,
`Type:` + fmt.Sprintf("%v", this.Type) + `,`,
`Stat:` + strings.Replace(fmt.Sprintf("%v", this.Stat), "Stat", "Stat", 1) + `,`,
`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
`Data:` + fmt.Sprintf("%v", this.Data) + `,`,
`}`,
}, "")
return s
}
func valueToStringWire(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("*%v", pv)
}
func (m *Packet) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowWire
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Packet: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Packet: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
}
m.Type = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowWire
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Type |= (Packet_PacketType(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Stat", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowWire
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthWire
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Stat == nil {
m.Stat = &Stat{}
}
if err := m.Stat.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
}
m.ID = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowWire
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ID |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowWire
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthWire
}
postIndex := iNdEx + byteLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...)
if m.Data == nil {
m.Data = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipWire(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthWire
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipWire(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowWire
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowWire
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowWire
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthWire
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowWire
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipWire(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthWire = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowWire = fmt.Errorf("proto: integer overflow")
)
func init() { proto.RegisterFile("wire.proto", fileDescriptorWire) }
var fileDescriptorWire = []byte{
// 268 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0xcf, 0x2c, 0x4a,
0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x49, 0x2b, 0x2e, 0x2d, 0xc9, 0xcc, 0xd1, 0x2b,
0xa9, 0x2c, 0x48, 0x2d, 0x96, 0xe2, 0x2a, 0x2e, 0x49, 0x2c, 0x81, 0xc8, 0x28, 0xbd, 0x64, 0xe4,
0x62, 0x0b, 0x48, 0x4c, 0xce, 0x4e, 0x2d, 0x11, 0x32, 0xe6, 0x62, 0x01, 0xc9, 0x4b, 0x30, 0x2a,
0x30, 0x6a, 0xf0, 0x19, 0xc9, 0xeb, 0x21, 0xeb, 0xd1, 0x83, 0xa8, 0x81, 0x52, 0x21, 0x95, 0x05,
0xa9, 0x41, 0x60, 0xc5, 0x42, 0x6a, 0x5c, 0x2c, 0x20, 0xd3, 0x24, 0x98, 0x14, 0x18, 0x35, 0xb8,
0x8d, 0x84, 0x50, 0x35, 0x05, 0x97, 0x24, 0x96, 0x04, 0x81, 0xe5, 0x85, 0xf8, 0xb8, 0x98, 0x3c,
0x5d, 0x24, 0x98, 0x15, 0x18, 0x35, 0x78, 0x83, 0x98, 0x3c, 0x5d, 0x84, 0x84, 0xb8, 0x58, 0x52,
0x12, 0x4b, 0x12, 0x25, 0x58, 0x14, 0x18, 0x35, 0x78, 0x82, 0xc0, 0x6c, 0xa5, 0x38, 0x2e, 0x2e,
0x84, 0xf9, 0x42, 0xfc, 0x5c, 0xdc, 0x01, 0x8e, 0xce, 0xde, 0xae, 0x21, 0xf1, 0xc1, 0x21, 0x8e,
0x21, 0x02, 0x0c, 0x42, 0x7c, 0x5c, 0x5c, 0x50, 0x81, 0x20, 0xd7, 0x40, 0x01, 0x46, 0x24, 0x05,
0x2e, 0x8e, 0x21, 0x8e, 0x02, 0x4c, 0x48, 0x0a, 0xdc, 0x3c, 0xfd, 0x04, 0x98, 0x91, 0xf8, 0xae,
0x41, 0x41, 0x02, 0x2c, 0x4e, 0xc6, 0x17, 0x1e, 0xca, 0x31, 0xdc, 0x78, 0x28, 0xc7, 0xf0, 0xe1,
0xa1, 0x1c, 0x63, 0xc3, 0x23, 0x39, 0xc6, 0x15, 0x8f, 0xe4, 0x18, 0x4f, 0x3c, 0x92, 0x63, 0xbc,
0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x17, 0x8f, 0xe4, 0x18, 0x3e, 0x3c, 0x92, 0x63,
0x9c, 0xf0, 0x58, 0x8e, 0x21, 0x8a, 0x15, 0xec, 0x87, 0x24, 0x36, 0x70, 0x38, 0x19, 0x03, 0x02,
0x00, 0x00, 0xff, 0xff, 0xce, 0x0f, 0xe2, 0x94, 0x4f, 0x01, 0x00, 0x00,
}

21
vendor/github.com/tonistiigi/fsutil/types/wire.proto generated vendored Normal file
View File

@ -0,0 +1,21 @@
syntax = "proto3";
package fsutil.types;
option go_package = "types";
import "stat.proto";
message Packet {
enum PacketType {
PACKET_STAT = 0;
PACKET_REQ = 1;
PACKET_DATA = 2;
PACKET_FIN = 3;
PACKET_ERR = 4;
}
PacketType type = 1;
Stat stat = 2;
uint32 ID = 3;
bytes data = 4;
}

92
vendor/github.com/tonistiigi/fsutil/validator.go generated vendored Normal file
View File

@ -0,0 +1,92 @@
package fsutil
import (
"os"
"path"
"runtime"
"sort"
"strings"
"github.com/pkg/errors"
)
type parent struct {
dir string
last string
}
type Validator struct {
parentDirs []parent
}
func (v *Validator) HandleChange(kind ChangeKind, p string, fi os.FileInfo, err error) (retErr error) {
if err != nil {
return err
}
// test that all paths are in order and all parent dirs were present
if v.parentDirs == nil {
v.parentDirs = make([]parent, 1, 10)
}
if runtime.GOOS == "windows" {
p = strings.Replace(p, "\\", "", -1)
}
if p != path.Clean(p) {
return errors.Errorf("invalid unclean path %s", p)
}
if path.IsAbs(p) {
return errors.Errorf("abolute path %s not allowed", p)
}
dir := path.Dir(p)
base := path.Base(p)
if dir == "." {
dir = ""
}
if dir == ".." || strings.HasPrefix(p, "../") {
return errors.Errorf("invalid path: %s", p)
}
// find a parent dir from saved records
i := sort.Search(len(v.parentDirs), func(i int) bool {
return ComparePath(v.parentDirs[len(v.parentDirs)-1-i].dir, dir) <= 0
})
i = len(v.parentDirs) - 1 - i
if i != len(v.parentDirs)-1 { // skipping back to grandparent
v.parentDirs = v.parentDirs[:i+1]
}
if dir != v.parentDirs[len(v.parentDirs)-1].dir || v.parentDirs[i].last >= base {
return errors.Errorf("changes out of order: %q %q", p, path.Join(v.parentDirs[i].dir, v.parentDirs[i].last))
}
v.parentDirs[i].last = base
if kind != ChangeKindDelete && fi.IsDir() {
v.parentDirs = append(v.parentDirs, parent{
dir: path.Join(dir, base),
last: "",
})
}
// todo: validate invalid mode combinations
return err
}
func ComparePath(p1, p2 string) int {
// byte-by-byte comparison to be compatible with str<>str
min := min(len(p1), len(p2))
for i := 0; i < min; i++ {
switch {
case p1[i] == p2[i]:
continue
case p2[i] != '/' && p1[i] < p2[i] || p1[i] == '/':
return -1
default:
return 1
}
}
return len(p1) - len(p2)
}
func min(x, y int) int {
if x < y {
return x
}
return y
}

230
vendor/github.com/tonistiigi/fsutil/walker.go generated vendored Normal file
View File

@ -0,0 +1,230 @@
package fsutil
import (
"context"
"os"
"path/filepath"
"strings"
"syscall"
"time"
"github.com/docker/docker/pkg/fileutils"
"github.com/pkg/errors"
"github.com/tonistiigi/fsutil/types"
)
type WalkOpt struct {
IncludePatterns []string
ExcludePatterns []string
// FollowPaths contains symlinks that are resolved into include patterns
// before performing the fs walk
FollowPaths []string
Map FilterFunc
}
func Walk(ctx context.Context, p string, opt *WalkOpt, fn filepath.WalkFunc) error {
root, err := filepath.EvalSymlinks(p)
if err != nil {
return errors.Wrapf(err, "failed to resolve %s", root)
}
fi, err := os.Stat(root)
if err != nil {
return errors.Wrapf(err, "failed to stat: %s", root)
}
if !fi.IsDir() {
return errors.Errorf("%s is not a directory", root)
}
var pm *fileutils.PatternMatcher
if opt != nil && opt.ExcludePatterns != nil {
pm, err = fileutils.NewPatternMatcher(opt.ExcludePatterns)
if err != nil {
return errors.Wrapf(err, "invalid excludepaths %s", opt.ExcludePatterns)
}
}
var includePatterns []string
if opt != nil && opt.IncludePatterns != nil {
includePatterns = make([]string, len(opt.IncludePatterns))
for k := range opt.IncludePatterns {
includePatterns[k] = filepath.Clean(opt.IncludePatterns[k])
}
}
if opt != nil && opt.FollowPaths != nil {
targets, err := FollowLinks(p, opt.FollowPaths)
if err != nil {
return err
}
if targets != nil {
includePatterns = append(includePatterns, targets...)
includePatterns = dedupePaths(includePatterns)
}
}
var lastIncludedDir string
seenFiles := make(map[uint64]string)
return filepath.Walk(root, func(path string, fi os.FileInfo, err error) (retErr error) {
if err != nil {
if os.IsNotExist(err) {
return filepath.SkipDir
}
return err
}
defer func() {
if retErr != nil && isNotExist(retErr) {
retErr = filepath.SkipDir
}
}()
origpath := path
path, err = filepath.Rel(root, path)
if err != nil {
return err
}
// Skip root
if path == "." {
return nil
}
if opt != nil {
if includePatterns != nil {
skip := false
if lastIncludedDir != "" {
if strings.HasPrefix(path, lastIncludedDir+string(filepath.Separator)) {
skip = true
}
}
if !skip {
matched := false
partial := true
for _, p := range includePatterns {
if ok, p := matchPrefix(p, path); ok {
matched = true
if !p {
partial = false
break
}
}
}
if !matched {
if fi.IsDir() {
return filepath.SkipDir
}
return nil
}
if !partial && fi.IsDir() {
lastIncludedDir = path
}
}
}
if pm != nil {
m, err := pm.Matches(path)
if err != nil {
return errors.Wrap(err, "failed to match excludepatterns")
}
if m {
if fi.IsDir() {
if !pm.Exclusions() {
return filepath.SkipDir
}
dirSlash := path + string(filepath.Separator)
for _, pat := range pm.Patterns() {
if !pat.Exclusion() {
continue
}
patStr := pat.String() + string(filepath.Separator)
if strings.HasPrefix(patStr, dirSlash) {
goto passedFilter
}
}
return filepath.SkipDir
}
return nil
}
}
}
passedFilter:
stat, err := mkstat(origpath, path, fi, seenFiles)
if err != nil {
return err
}
select {
case <-ctx.Done():
return ctx.Err()
default:
if opt != nil && opt.Map != nil {
if allowed := opt.Map(stat.Path, stat); !allowed {
return nil
}
}
if err := fn(stat.Path, &StatInfo{stat}, nil); err != nil {
return err
}
}
return nil
})
}
type StatInfo struct {
*types.Stat
}
func (s *StatInfo) Name() string {
return filepath.Base(s.Stat.Path)
}
func (s *StatInfo) Size() int64 {
return s.Stat.Size_
}
func (s *StatInfo) Mode() os.FileMode {
return os.FileMode(s.Stat.Mode)
}
func (s *StatInfo) ModTime() time.Time {
return time.Unix(s.Stat.ModTime/1e9, s.Stat.ModTime%1e9)
}
func (s *StatInfo) IsDir() bool {
return s.Mode().IsDir()
}
func (s *StatInfo) Sys() interface{} {
return s.Stat
}
func matchPrefix(pattern, name string) (bool, bool) {
count := strings.Count(name, string(filepath.Separator))
partial := false
if strings.Count(pattern, string(filepath.Separator)) > count {
pattern = trimUntilIndex(pattern, string(filepath.Separator), count)
partial = true
}
m, _ := filepath.Match(pattern, name)
return m, partial
}
func trimUntilIndex(str, sep string, count int) string {
s := str
i := 0
c := 0
for {
idx := strings.Index(s, sep)
s = s[idx+len(sep):]
i += idx + len(sep)
c++
if c > count {
return str[:i-len(sep)]
}
}
}
func isNotExist(err error) bool {
err = errors.Cause(err)
if os.IsNotExist(err) {
return true
}
if pe, ok := err.(*os.PathError); ok {
err = pe.Err
}
return err == syscall.ENOTDIR
}

8
vendor/github.com/tonistiigi/units/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,8 @@
language: go
go:
- 1.8
- 1.9
script:
- go test -v ./

21
vendor/github.com/tonistiigi/units/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Tõnis Tiigi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

125
vendor/github.com/tonistiigi/units/bytes.go generated vendored Normal file
View File

@ -0,0 +1,125 @@
/*
Simple byte size formatting.
This package implements types that can be used in stdlib formatting functions
like `fmt.Printf` to control the output of the expected printed string.
Floating point flags %f and %g print the value in using the correct unit
suffix. Decimal units are default, # switches to binary units. If a value is
best represented as full bytes, integer bytes are printed instead.
Examples:
fmt.Printf("%.2f", 123 * B) => "123B"
fmt.Printf("%.2f", 1234 * B) => "1.23kB"
fmt.Printf("%g", 1200 * B) => "1.2kB"
fmt.Printf("%#g", 1024 * B) => "1KiB"
Integer flag %d always prints the value in bytes. # flag adds an unit prefix.
Examples:
fmt.Printf("%d", 1234 * B) => "1234"
fmt.Printf("%#d", 1234 * B) => "1234B"
%v is equal to %g
*/
package units
import (
"fmt"
"io"
"math"
"math/big"
)
type Bytes int64
const (
B Bytes = 1 << (10 * iota)
KiB
MiB
GiB
TiB
PiB
EiB
KB = 1e3 * B
MB = 1e3 * KB
GB = 1e3 * MB
TB = 1e3 * GB
PB = 1e3 * TB
EB = 1e3 * PB
)
var units = map[bool][]string{
false: []string{
"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB",
},
true: []string{
"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB",
},
}
func (b Bytes) Format(f fmt.State, c rune) {
switch c {
case 'f', 'g':
fv, unit, ok := b.floatValue(f.Flag('#'))
if !ok {
b.formatInt(&noPrecision{f}, 'd', true)
return
}
big.NewFloat(fv).Format(f, c)
io.WriteString(f, unit)
case 'd':
b.formatInt(f, c, f.Flag('#'))
default:
if f.Flag('#') {
fmt.Fprintf(f, "bytes(%d)", int64(b))
} else {
fmt.Fprintf(f, "%g", b)
}
}
}
func (b Bytes) formatInt(f fmt.State, c rune, withUnit bool) {
big.NewInt(int64(b)).Format(f, c)
if withUnit {
io.WriteString(f, "B")
}
}
func (b Bytes) floatValue(binary bool) (float64, string, bool) {
i := 0
var baseUnit Bytes = 1
if b < 0 {
baseUnit *= -1
}
for {
next := baseUnit
if binary {
next *= 1 << 10
} else {
next *= 1e3
}
if (baseUnit > 0 && b >= next) || (baseUnit < 0 && b <= next) {
i++
baseUnit = next
continue
}
if i == 0 {
return 0, "", false
}
return float64(b) / math.Abs(float64(baseUnit)), units[binary][i], true
}
}
type noPrecision struct {
fmt.State
}
func (*noPrecision) Precision() (prec int, ok bool) {
return 0, false
}

29
vendor/github.com/tonistiigi/units/readme.md generated vendored Normal file
View File

@ -0,0 +1,29 @@
#### Simple byte size formatting.
This package implements types that can be used in stdlib formatting functions
like `fmt.Printf` to control the output of the expected printed string.
Floating point flags `%f` and %g print the value in using the correct unit
suffix. Decimal units are default, `#` switches to binary units. If a value is
best represented as full bytes, integer bytes are printed instead.
##### Examples:
```
fmt.Printf("%.2f", 123 * B) => "123B"
fmt.Printf("%.2f", 1234 * B) => "1.23kB"
fmt.Printf("%g", 1200 * B) => "1.2kB"
fmt.Printf("%#g", 1024 * B) => "1KiB"
```
Integer flag `%d` always prints the value in bytes. `#` flag adds an unit prefix.
##### Examples:
```
fmt.Printf("%d", 1234 * B) => "1234"
fmt.Printf("%#d", 1234 * B) => "1234B"
```
`%v` is equal to `%g`