mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-16 16:37:10 +08:00
21
vendor/github.com/tonistiigi/fsutil/.travis.yml
generated
vendored
Normal file
21
vendor/github.com/tonistiigi/fsutil/.travis.yml
generated
vendored
Normal 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
22
vendor/github.com/tonistiigi/fsutil/LICENSE
generated
vendored
Normal 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
20
vendor/github.com/tonistiigi/fsutil/chtimes_linux.go
generated
vendored
Normal 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
20
vendor/github.com/tonistiigi/fsutil/chtimes_nolinux.go
generated
vendored
Normal 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
45
vendor/github.com/tonistiigi/fsutil/diff.go
generated
vendored
Normal 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 := ¤tPath{
|
||||
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
200
vendor/github.com/tonistiigi/fsutil/diff_containerd.go
generated
vendored
Normal 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
|
||||
}
|
||||
}
|
37
vendor/github.com/tonistiigi/fsutil/diff_containerd_linux.go
generated
vendored
Normal file
37
vendor/github.com/tonistiigi/fsutil/diff_containerd_linux.go
generated
vendored
Normal 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
352
vendor/github.com/tonistiigi/fsutil/diskwriter.go
generated
vendored
Normal 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
52
vendor/github.com/tonistiigi/fsutil/diskwriter_unix.go
generated
vendored
Normal 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
|
||||
}
|
18
vendor/github.com/tonistiigi/fsutil/diskwriter_windows.go
generated
vendored
Normal file
18
vendor/github.com/tonistiigi/fsutil/diskwriter_windows.go
generated
vendored
Normal 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
150
vendor/github.com/tonistiigi/fsutil/followlinks.go
generated
vendored
Normal 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
72
vendor/github.com/tonistiigi/fsutil/fs.go
generated
vendored
Normal 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
28
vendor/github.com/tonistiigi/fsutil/go.mod
generated
vendored
Normal 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
71
vendor/github.com/tonistiigi/fsutil/go.sum
generated
vendored
Normal 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
47
vendor/github.com/tonistiigi/fsutil/hardlinks.go
generated
vendored
Normal 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
45
vendor/github.com/tonistiigi/fsutil/readme.md
generated
vendored
Normal 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
276
vendor/github.com/tonistiigi/fsutil/receive.go
generated
vendored
Normal 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 := ¤tPath{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
206
vendor/github.com/tonistiigi/fsutil/send.go
generated
vendored
Normal 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
61
vendor/github.com/tonistiigi/fsutil/stat.go
generated
vendored
Normal 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
71
vendor/github.com/tonistiigi/fsutil/stat_unix.go
generated
vendored
Normal 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
16
vendor/github.com/tonistiigi/fsutil/stat_windows.go
generated
vendored
Normal 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) {
|
||||
}
|
3
vendor/github.com/tonistiigi/fsutil/types/generate.go
generated
vendored
Normal file
3
vendor/github.com/tonistiigi/fsutil/types/generate.go
generated
vendored
Normal 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
909
vendor/github.com/tonistiigi/fsutil/types/stat.pb.go
generated
vendored
Normal 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
19
vendor/github.com/tonistiigi/fsutil/types/stat.proto
generated
vendored
Normal 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
542
vendor/github.com/tonistiigi/fsutil/types/wire.pb.go
generated
vendored
Normal 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
21
vendor/github.com/tonistiigi/fsutil/types/wire.proto
generated
vendored
Normal 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
92
vendor/github.com/tonistiigi/fsutil/validator.go
generated
vendored
Normal 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
230
vendor/github.com/tonistiigi/fsutil/walker.go
generated
vendored
Normal 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
8
vendor/github.com/tonistiigi/units/.travis.yml
generated
vendored
Normal 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
21
vendor/github.com/tonistiigi/units/LICENSE
generated
vendored
Normal 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
125
vendor/github.com/tonistiigi/units/bytes.go
generated
vendored
Normal 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
29
vendor/github.com/tonistiigi/units/readme.md
generated
vendored
Normal 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`
|
Reference in New Issue
Block a user