Browse code

bump up buildkit

Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>

Akihiro Suda authored on 2018/10/05 18:04:52
Showing 66 changed files
... ...
@@ -22,6 +22,7 @@ import (
22 22
 	"github.com/pkg/errors"
23 23
 	"github.com/sirupsen/logrus"
24 24
 	"github.com/tonistiigi/fsutil"
25
+	fsutiltypes "github.com/tonistiigi/fsutil/types"
25 26
 	bolt "go.etcd.io/bbolt"
26 27
 	"golang.org/x/sync/singleflight"
27 28
 )
... ...
@@ -614,7 +615,7 @@ func (s sortableCacheSources) Swap(i, j int) {
614 614
 	s[i], s[j] = s[j], s[i]
615 615
 }
616 616
 
617
-func newTarsumHash(stat *fsutil.Stat) (hash.Hash, error) {
617
+func newTarsumHash(stat *fsutiltypes.Stat) (hash.Hash, error) {
618 618
 	fi := &fsutil.StatInfo{Stat: stat}
619 619
 	p := stat.Path
620 620
 	if fi.IsDir() {
... ...
@@ -26,8 +26,8 @@ github.com/imdario/mergo v0.3.6
26 26
 golang.org/x/sync 1d60e4601c6fd243af51cc01ddf169918a5407ca
27 27
 
28 28
 # buildkit
29
-github.com/moby/buildkit 8f4dff0d16ea91cb43315d5f5aa4b27f4fe4e1f2
30
-github.com/tonistiigi/fsutil b19464cd1b6a00773b4f2eb7acf9c30426f9df42
29
+github.com/moby/buildkit 520201006c9dc676da9cf9655337ac711f7f127d 
30
+github.com/tonistiigi/fsutil f567071bed2416e4d87d260d3162722651182317
31 31
 github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
32 32
 github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
33 33
 github.com/google/shlex 6f45313302b9c56850fc17f99e40caebce98c716
... ...
@@ -130,7 +130,7 @@ github.com/gogo/protobuf v1.0.0
130 130
 github.com/cloudflare/cfssl 1.3.2
131 131
 github.com/fernet/fernet-go 1b2437bc582b3cfbb341ee5a29f8ef5b42912ff2
132 132
 github.com/google/certificate-transparency-go v1.0.20
133
-golang.org/x/crypto a2144134853fc9a27a7b1e3eb4f19f1a76df13c9
133
+golang.org/x/crypto 0709b304e793a5edb4a2c0145f281ecdc20838a4
134 134
 golang.org/x/time fbb02b2291d28baffd63558aa44b4b56f178d650
135 135
 github.com/hashicorp/go-memdb cb9a474f84cc5e41b273b20c6927680b2a8776ad
136 136
 github.com/hashicorp/go-immutable-radix 826af9ccf0feeee615d546d69b11f8e98da8c8f1 git://github.com/tonistiigi/go-immutable-radix.git
... ...
@@ -19,6 +19,7 @@ import (
19 19
 	digest "github.com/opencontainers/go-digest"
20 20
 	"github.com/pkg/errors"
21 21
 	"github.com/tonistiigi/fsutil"
22
+	fstypes "github.com/tonistiigi/fsutil/types"
22 23
 )
23 24
 
24 25
 var errNotFound = errors.Errorf("not found")
... ...
@@ -274,7 +275,7 @@ func (cc *cacheContext) HandleChange(kind fsutil.ChangeKind, p string, fi os.Fil
274 274
 		return
275 275
 	}
276 276
 
277
-	stat, ok := fi.Sys().(*fsutil.Stat)
277
+	stat, ok := fi.Sys().(*fstypes.Stat)
278 278
 	if !ok {
279 279
 		return errors.Errorf("%s invalid change without stat information", p)
280 280
 	}
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"path/filepath"
9 9
 	"time"
10 10
 
11
-	"github.com/tonistiigi/fsutil"
11
+	fstypes "github.com/tonistiigi/fsutil/types"
12 12
 )
13 13
 
14 14
 // NewFileHash returns new hash that is used for the builder cache keys
... ...
@@ -22,7 +22,7 @@ func NewFileHash(path string, fi os.FileInfo) (hash.Hash, error) {
22 22
 		}
23 23
 	}
24 24
 
25
-	stat := &fsutil.Stat{
25
+	stat := &fstypes.Stat{
26 26
 		Mode:     uint32(fi.Mode()),
27 27
 		Size_:    fi.Size(),
28 28
 		ModTime:  fi.ModTime().UnixNano(),
... ...
@@ -39,7 +39,7 @@ func NewFileHash(path string, fi os.FileInfo) (hash.Hash, error) {
39 39
 	return NewFromStat(stat)
40 40
 }
41 41
 
42
-func NewFromStat(stat *fsutil.Stat) (hash.Hash, error) {
42
+func NewFromStat(stat *fstypes.Stat) (hash.Hash, error) {
43 43
 	fi := &statInfo{stat}
44 44
 	hdr, err := tar.FileInfoHeader(fi, stat.Linkname)
45 45
 	if err != nil {
... ...
@@ -75,7 +75,7 @@ func (tsh *tarsumHash) Reset() {
75 75
 }
76 76
 
77 77
 type statInfo struct {
78
-	*fsutil.Stat
78
+	*fstypes.Stat
79 79
 }
80 80
 
81 81
 func (s *statInfo) Name() string {
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"syscall"
8 8
 
9 9
 	"github.com/containerd/continuity/sysx"
10
-	"github.com/tonistiigi/fsutil"
10
+	fstypes "github.com/tonistiigi/fsutil/types"
11 11
 
12 12
 	"golang.org/x/sys/unix"
13 13
 )
... ...
@@ -16,7 +16,7 @@ func chmodWindowsTarEntry(perm os.FileMode) os.FileMode {
16 16
 	return perm
17 17
 }
18 18
 
19
-func setUnixOpt(path string, fi os.FileInfo, stat *fsutil.Stat) error {
19
+func setUnixOpt(path string, fi os.FileInfo, stat *fstypes.Stat) error {
20 20
 	s := fi.Sys().(*syscall.Stat_t)
21 21
 
22 22
 	stat.Uid = s.Uid
... ...
@@ -5,7 +5,7 @@ package contenthash
5 5
 import (
6 6
 	"os"
7 7
 
8
-	"github.com/tonistiigi/fsutil"
8
+	fstypes "github.com/tonistiigi/fsutil/types"
9 9
 )
10 10
 
11 11
 // chmodWindowsTarEntry is used to adjust the file permissions used in tar
... ...
@@ -18,6 +18,6 @@ func chmodWindowsTarEntry(perm os.FileMode) os.FileMode {
18 18
 	return perm
19 19
 }
20 20
 
21
-func setUnixOpt(path string, fi os.FileInfo, stat *fsutil.Stat) error {
21
+func setUnixOpt(path string, fi os.FileInfo, stat *fstypes.Stat) error {
22 22
 	return nil
23 23
 }
24 24
deleted file mode 100644
... ...
@@ -1,71 +0,0 @@
1
-package cache
2
-
3
-import (
4
-	"context"
5
-	"io"
6
-	"io/ioutil"
7
-	"os"
8
-
9
-	"github.com/containerd/continuity/fs"
10
-	"github.com/moby/buildkit/snapshot"
11
-)
12
-
13
-type ReadRequest struct {
14
-	Filename string
15
-	Range    *FileRange
16
-}
17
-
18
-type FileRange struct {
19
-	Offset int
20
-	Length int
21
-}
22
-
23
-func ReadFile(ctx context.Context, ref ImmutableRef, req ReadRequest) ([]byte, error) {
24
-	mount, err := ref.Mount(ctx, true)
25
-	if err != nil {
26
-		return nil, err
27
-	}
28
-
29
-	lm := snapshot.LocalMounter(mount)
30
-
31
-	root, err := lm.Mount()
32
-	if err != nil {
33
-		return nil, err
34
-	}
35
-
36
-	defer func() {
37
-		if lm != nil {
38
-			lm.Unmount()
39
-		}
40
-	}()
41
-
42
-	fp, err := fs.RootPath(root, req.Filename)
43
-	if err != nil {
44
-		return nil, err
45
-	}
46
-
47
-	var dt []byte
48
-
49
-	if req.Range == nil {
50
-		dt, err = ioutil.ReadFile(fp)
51
-		if err != nil {
52
-			return nil, err
53
-		}
54
-	} else {
55
-		f, err := os.Open(fp)
56
-		if err != nil {
57
-			return nil, err
58
-		}
59
-		dt, err = ioutil.ReadAll(io.NewSectionReader(f, int64(req.Range.Offset), int64(req.Range.Length)))
60
-		f.Close()
61
-		if err != nil {
62
-			return nil, err
63
-		}
64
-	}
65
-
66
-	if err := lm.Unmount(); err != nil {
67
-		return nil, err
68
-	}
69
-	lm = nil
70
-	return dt, err
71
-}
72 1
new file mode 100644
... ...
@@ -0,0 +1,139 @@
0
+package util
1
+
2
+import (
3
+	"context"
4
+	"io"
5
+	"io/ioutil"
6
+	"os"
7
+	"path/filepath"
8
+
9
+	"github.com/containerd/continuity/fs"
10
+	"github.com/moby/buildkit/cache"
11
+	"github.com/moby/buildkit/snapshot"
12
+	"github.com/pkg/errors"
13
+	"github.com/tonistiigi/fsutil"
14
+	fstypes "github.com/tonistiigi/fsutil/types"
15
+)
16
+
17
+type ReadRequest struct {
18
+	Filename string
19
+	Range    *FileRange
20
+}
21
+
22
+type FileRange struct {
23
+	Offset int
24
+	Length int
25
+}
26
+
27
+func withMount(ctx context.Context, ref cache.ImmutableRef, cb func(string) error) error {
28
+	mount, err := ref.Mount(ctx, true)
29
+	if err != nil {
30
+		return err
31
+	}
32
+
33
+	lm := snapshot.LocalMounter(mount)
34
+
35
+	root, err := lm.Mount()
36
+	if err != nil {
37
+		return err
38
+	}
39
+
40
+	defer func() {
41
+		if lm != nil {
42
+			lm.Unmount()
43
+		}
44
+	}()
45
+
46
+	if err := cb(root); err != nil {
47
+		return err
48
+	}
49
+
50
+	if err := lm.Unmount(); err != nil {
51
+		return err
52
+	}
53
+	lm = nil
54
+	return nil
55
+}
56
+
57
+func ReadFile(ctx context.Context, ref cache.ImmutableRef, req ReadRequest) ([]byte, error) {
58
+	var dt []byte
59
+
60
+	err := withMount(ctx, ref, func(root string) error {
61
+		fp, err := fs.RootPath(root, req.Filename)
62
+		if err != nil {
63
+			return err
64
+		}
65
+
66
+		if req.Range == nil {
67
+			dt, err = ioutil.ReadFile(fp)
68
+			if err != nil {
69
+				return err
70
+			}
71
+		} else {
72
+			f, err := os.Open(fp)
73
+			if err != nil {
74
+				return err
75
+			}
76
+			dt, err = ioutil.ReadAll(io.NewSectionReader(f, int64(req.Range.Offset), int64(req.Range.Length)))
77
+			f.Close()
78
+			if err != nil {
79
+				return err
80
+			}
81
+		}
82
+		return nil
83
+	})
84
+	return dt, err
85
+}
86
+
87
+type ReadDirRequest struct {
88
+	Path           string
89
+	IncludePattern string
90
+}
91
+
92
+func ReadDir(ctx context.Context, ref cache.ImmutableRef, req ReadDirRequest) ([]*fstypes.Stat, error) {
93
+	var (
94
+		rd []*fstypes.Stat
95
+		wo fsutil.WalkOpt
96
+	)
97
+	if req.IncludePattern != "" {
98
+		wo.IncludePatterns = append(wo.IncludePatterns, req.IncludePattern)
99
+	}
100
+	err := withMount(ctx, ref, func(root string) error {
101
+		fp, err := fs.RootPath(root, req.Path)
102
+		if err != nil {
103
+			return err
104
+		}
105
+		return fsutil.Walk(ctx, fp, &wo, func(path string, info os.FileInfo, err error) error {
106
+			if err != nil {
107
+				return errors.Wrapf(err, "walking %q", root)
108
+			}
109
+			stat, ok := info.Sys().(*fstypes.Stat)
110
+			if !ok {
111
+				// This "can't happen(tm)".
112
+				return errors.Errorf("expected a *fsutil.Stat but got %T", info.Sys())
113
+			}
114
+			rd = append(rd, stat)
115
+
116
+			if info.IsDir() {
117
+				return filepath.SkipDir
118
+			}
119
+			return nil
120
+		})
121
+	})
122
+	return rd, err
123
+}
124
+
125
+func StatFile(ctx context.Context, ref cache.ImmutableRef, path string) (*fstypes.Stat, error) {
126
+	var st *fstypes.Stat
127
+	err := withMount(ctx, ref, func(root string) error {
128
+		fp, err := fs.RootPath(root, path)
129
+		if err != nil {
130
+			return err
131
+		}
132
+		if st, err = fsutil.Stat(fp); err != nil {
133
+			return err
134
+		}
135
+		return nil
136
+	})
137
+	return st, err
138
+}
... ...
@@ -84,6 +84,16 @@ func (g *gatewayClientForBuild) ReadFile(ctx context.Context, in *gatewayapi.Rea
84 84
 	return g.gateway.ReadFile(ctx, in, opts...)
85 85
 }
86 86
 
87
+func (g *gatewayClientForBuild) ReadDir(ctx context.Context, in *gatewayapi.ReadDirRequest, opts ...grpc.CallOption) (*gatewayapi.ReadDirResponse, error) {
88
+	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
89
+	return g.gateway.ReadDir(ctx, in, opts...)
90
+}
91
+
92
+func (g *gatewayClientForBuild) StatFile(ctx context.Context, in *gatewayapi.StatFileRequest, opts ...grpc.CallOption) (*gatewayapi.StatFileResponse, error) {
93
+	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
94
+	return g.gateway.StatFile(ctx, in, opts...)
95
+}
96
+
87 97
 func (g *gatewayClientForBuild) Ping(ctx context.Context, in *gatewayapi.PingRequest, opts ...grpc.CallOption) (*gatewayapi.PongResponse, error) {
88 98
 	ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
89 99
 	return g.gateway.Ping(ctx, in, opts...)
... ...
@@ -7,6 +7,7 @@ import (
7 7
 	"sort"
8 8
 
9 9
 	"github.com/moby/buildkit/solver/pb"
10
+	"github.com/moby/buildkit/util/system"
10 11
 	digest "github.com/opencontainers/go-digest"
11 12
 	"github.com/pkg/errors"
12 13
 )
... ...
@@ -142,6 +143,13 @@ func (e *ExecOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata,
142 142
 			e.meta.Env = e.meta.Env.AddOrReplace("SSH_AUTH_SOCK", e.ssh[0].Target)
143 143
 		}
144 144
 	}
145
+	if c.Caps != nil {
146
+		if err := c.Caps.Supports(pb.CapExecMetaSetsDefaultPath); err != nil {
147
+			e.meta.Env = e.meta.Env.SetDefault("PATH", system.DefaultPathEnv)
148
+		} else {
149
+			addCap(&e.constraints, pb.CapExecMetaSetsDefaultPath)
150
+		}
151
+	}
145 152
 
146 153
 	meta := &pb.Meta{
147 154
 		Args: e.meta.Args,
... ...
@@ -191,6 +199,14 @@ func (e *ExecOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata,
191 191
 		}
192 192
 	}
193 193
 
194
+	if len(e.secrets) > 0 {
195
+		addCap(&e.constraints, pb.CapExecMountSecret)
196
+	}
197
+
198
+	if len(e.ssh) > 0 {
199
+		addCap(&e.constraints, pb.CapExecMountSSH)
200
+	}
201
+
194 202
 	pop, md := MarshalConstraints(c, &e.constraints)
195 203
 	pop.Op = &pb.Op_Exec{
196 204
 		Exec: peo,
... ...
@@ -258,10 +274,6 @@ func (e *ExecOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata,
258 258
 		peo.Mounts = append(peo.Mounts, pm)
259 259
 	}
260 260
 
261
-	if len(e.secrets) > 0 {
262
-		addCap(&e.constraints, pb.CapMountSecret)
263
-	}
264
-
265 261
 	for _, s := range e.secrets {
266 262
 		pm := &pb.Mount{
267 263
 			Dest:      s.Target,
... ...
@@ -488,6 +500,12 @@ func SSHID(id string) SSHOption {
488 488
 	})
489 489
 }
490 490
 
491
+func SSHSocketTarget(target string) SSHOption {
492
+	return sshOptionFunc(func(si *SSHInfo) {
493
+		si.Target = target
494
+	})
495
+}
496
+
491 497
 func SSHSocketOpt(target string, uid, gid, mode int) SSHOption {
492 498
 	return sshOptionFunc(func(si *SSHInfo) {
493 499
 		si.Target = target
... ...
@@ -23,10 +23,6 @@ var (
23 23
 	keyNetwork   = contextKeyT("llb.network")
24 24
 )
25 25
 
26
-func addEnv(key, value string) StateOption {
27
-	return addEnvf(key, value)
28
-}
29
-
30 26
 func addEnvf(key, value string, v ...interface{}) StateOption {
31 27
 	return func(s State) State {
32 28
 		return s.WithValue(keyEnv, getEnv(s).AddOrReplace(key, fmt.Sprintf(value, v...)))
... ...
@@ -175,6 +171,13 @@ func (e EnvList) AddOrReplace(k, v string) EnvList {
175 175
 	return e
176 176
 }
177 177
 
178
+func (e EnvList) SetDefault(k, v string) EnvList {
179
+	if _, ok := e.Get(k); !ok {
180
+		e = append(e, KeyValue{key: k, value: v})
181
+	}
182
+	return e
183
+}
184
+
178 185
 func (e EnvList) Delete(k string) EnvList {
179 186
 	e = append([]KeyValue(nil), e...)
180 187
 	if i, ok := e.Index(k); ok {
... ...
@@ -9,7 +9,6 @@ import (
9 9
 	"github.com/moby/buildkit/identity"
10 10
 	"github.com/moby/buildkit/solver/pb"
11 11
 	"github.com/moby/buildkit/util/apicaps"
12
-	"github.com/moby/buildkit/util/system"
13 12
 	digest "github.com/opencontainers/go-digest"
14 13
 	specs "github.com/opencontainers/image-spec/specs-go/v1"
15 14
 )
... ...
@@ -34,7 +33,6 @@ func NewState(o Output) State {
34 34
 		ctx: context.Background(),
35 35
 	}
36 36
 	s = dir("/")(s)
37
-	s = addEnv("PATH", system.DefaultPathEnv)(s)
38 37
 	s = s.ensurePlatform()
39 38
 	return s
40 39
 }
... ...
@@ -19,7 +19,7 @@ import (
19 19
 	opentracing "github.com/opentracing/opentracing-go"
20 20
 	"github.com/pkg/errors"
21 21
 	"github.com/sirupsen/logrus"
22
-	"github.com/tonistiigi/fsutil"
22
+	fstypes "github.com/tonistiigi/fsutil/types"
23 23
 	"golang.org/x/sync/errgroup"
24 24
 )
25 25
 
... ...
@@ -256,7 +256,7 @@ func prepareSyncedDirs(def *llb.Definition, localDirs map[string]string) ([]file
256 256
 			return nil, errors.Errorf("%s not a directory", d)
257 257
 		}
258 258
 	}
259
-	resetUIDAndGID := func(st *fsutil.Stat) bool {
259
+	resetUIDAndGID := func(st *fstypes.Stat) bool {
260 260
 		st.Uid = 0
261 261
 		st.Gid = 0
262 262
 		return true
... ...
@@ -125,3 +125,19 @@ func (gwf *GatewayForwarder) Return(ctx context.Context, req *gwapi.ReturnReques
125 125
 	res, err := fwd.Return(ctx, req)
126 126
 	return res, err
127 127
 }
128
+
129
+func (gwf *GatewayForwarder) ReadDir(ctx context.Context, req *gwapi.ReadDirRequest) (*gwapi.ReadDirResponse, error) {
130
+	fwd, err := gwf.lookupForwarder(ctx)
131
+	if err != nil {
132
+		return nil, errors.Wrap(err, "forwarding ReadDir")
133
+	}
134
+	return fwd.ReadDir(ctx, req)
135
+}
136
+
137
+func (gwf *GatewayForwarder) StatFile(ctx context.Context, req *gwapi.StatFileRequest) (*gwapi.StatFileResponse, error) {
138
+	fwd, err := gwf.lookupForwarder(ctx)
139
+	if err != nil {
140
+		return nil, errors.Wrap(err, "forwarding StatFile")
141
+	}
142
+	return fwd.StatFile(ctx, req)
143
+}
... ...
@@ -13,7 +13,7 @@ import (
13 13
 )
14 14
 
15 15
 const hostsContent = `
16
-127.0.0.1	localhost
16
+127.0.0.1	localhost buildkitsandbox
17 17
 ::1	localhost ip6-localhost ip6-loopback
18 18
 `
19 19
 
... ...
@@ -44,11 +44,21 @@ func GenerateSpec(ctx context.Context, meta executor.Meta, mounts []executor.Mou
44 44
 	s.Process.Args = meta.Args
45 45
 	s.Process.Env = meta.Env
46 46
 	s.Process.Cwd = meta.Cwd
47
+	s.Process.Rlimits = nil // reset open files limit
48
+	s.Hostname = "buildkitsandbox"
47 49
 
48 50
 	s.Mounts = GetMounts(ctx,
49 51
 		withROBind(resolvConf, "/etc/resolv.conf"),
50 52
 		withROBind(hostsFile, "/etc/hosts"),
51 53
 	)
54
+
55
+	s.Mounts = append(s.Mounts, specs.Mount{
56
+		Destination: "/sys/fs/cgroup",
57
+		Type:        "cgroup",
58
+		Source:      "cgroup",
59
+		Options:     []string{"ro", "nosuid", "noexec", "nodev"},
60
+	})
61
+
52 62
 	// TODO: User
53 63
 
54 64
 	sm := &submounts{}
... ...
@@ -85,6 +85,10 @@ func New(opt Opt, networkProviders map[pb.NetMode]network.Provider) (executor.Ex
85 85
 		return nil, err
86 86
 	}
87 87
 
88
+	// clean up old hosts/resolv.conf file. ignore errors
89
+	os.RemoveAll(filepath.Join(root, "hosts"))
90
+	os.RemoveAll(filepath.Join(root, "resolv.conf"))
91
+
88 92
 	runtime := &runc.Runc{
89 93
 		Command:      cmd,
90 94
 		Log:          filepath.Join(root, "runc-log.json"),
... ...
@@ -96,10 +96,7 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) {
96 96
 		}
97 97
 	}
98 98
 
99
-	name := "load Dockerfile"
100
-	if filename != "Dockerfile" {
101
-		name += " from " + filename
102
-	}
99
+	name := "load build definition from " + filename
103 100
 
104 101
 	src := llb.Local(LocalNameDockerfile,
105 102
 		llb.IncludePatterns([]string{filename}),
... ...
@@ -608,8 +608,10 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE
608 608
 	if c.PrependShell {
609 609
 		args = withShell(d.image, args)
610 610
 	}
611
+	env := d.state.Env()
611 612
 	opt := []llb.RunOption{llb.Args(args)}
612 613
 	for _, arg := range d.buildArgs {
614
+		env = append(env, fmt.Sprintf("%s=%s", arg.Key, arg.ValueString()))
613 615
 		opt = append(opt, llb.AddEnv(arg.Key, arg.ValueString()))
614 616
 	}
615 617
 	opt = append(opt, dfCmd(c))
... ...
@@ -625,7 +627,7 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE
625 625
 		return err
626 626
 	}
627 627
 	opt = append(opt, runMounts...)
628
-	opt = append(opt, llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(dopt.shlex, c.String(), d.state.Run(opt...).Env())), d.prefixPlatform, d.state.GetPlatform())))
628
+	opt = append(opt, llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(dopt.shlex, c.String(), env)), d.prefixPlatform, d.state.GetPlatform())))
629 629
 	for _, h := range dopt.extraHosts {
630 630
 		opt = append(opt, llb.AddExtraHost(h.Host, h.IP))
631 631
 	}
632 632
new file mode 100644
... ...
@@ -0,0 +1,13 @@
0
+// +build dfrunmount,!dfssh
1
+
2
+package dockerfile2llb
3
+
4
+import (
5
+	"github.com/moby/buildkit/client/llb"
6
+	"github.com/moby/buildkit/frontend/dockerfile/instructions"
7
+	"github.com/pkg/errors"
8
+)
9
+
10
+func dispatchSSH(m *instructions.Mount) (llb.RunOption, error) {
11
+	return nil, errors.Errorf("ssh mounts not allowed")
12
+}
... ...
@@ -65,6 +65,14 @@ func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*
65 65
 			out = append(out, secret)
66 66
 			continue
67 67
 		}
68
+		if mount.Type == instructions.MountTypeSSH {
69
+			ssh, err := dispatchSSH(mount)
70
+			if err != nil {
71
+				return nil, err
72
+			}
73
+			out = append(out, ssh)
74
+			continue
75
+		}
68 76
 		if mount.ReadOnly {
69 77
 			mountOpts = append(mountOpts, llb.Readonly)
70 78
 		}
71 79
new file mode 100644
... ...
@@ -0,0 +1,27 @@
0
+// +build dfssh dfextall
1
+
2
+package dockerfile2llb
3
+
4
+import (
5
+	"github.com/moby/buildkit/client/llb"
6
+	"github.com/moby/buildkit/frontend/dockerfile/instructions"
7
+	"github.com/pkg/errors"
8
+)
9
+
10
+func dispatchSSH(m *instructions.Mount) (llb.RunOption, error) {
11
+	if m.Source != "" {
12
+		return nil, errors.Errorf("ssh does not support source")
13
+	}
14
+	opts := []llb.SSHOption{llb.SSHID(m.CacheID)}
15
+
16
+	if m.Target != "" {
17
+		// TODO(AkihiroSuda): support specifying permission bits
18
+		opts = append(opts, llb.SSHSocketTarget(m.Target))
19
+	}
20
+
21
+	if !m.Required {
22
+		opts = append(opts, llb.SSHOptional)
23
+	}
24
+
25
+	return llb.AddSSHSocket(opts...), nil
26
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !dfsecrets
1
+// +build !dfsecrets,!dfextall
2 2
 
3 3
 package instructions
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+// +build !dfssh,!dfextall
1
+
2
+package instructions
3
+
4
+func isSSHMountsSupported() bool {
5
+	return false
6
+}
... ...
@@ -14,12 +14,14 @@ const MountTypeBind = "bind"
14 14
 const MountTypeCache = "cache"
15 15
 const MountTypeTmpfs = "tmpfs"
16 16
 const MountTypeSecret = "secret"
17
+const MountTypeSSH = "ssh"
17 18
 
18 19
 var allowedMountTypes = map[string]struct{}{
19 20
 	MountTypeBind:   {},
20 21
 	MountTypeCache:  {},
21 22
 	MountTypeTmpfs:  {},
22 23
 	MountTypeSecret: {},
24
+	MountTypeSSH:    {},
23 25
 }
24 26
 
25 27
 const MountSharingShared = "shared"
... ...
@@ -47,6 +49,11 @@ func isValidMountType(s string) bool {
47 47
 			return false
48 48
 		}
49 49
 	}
50
+	if s == "ssh" {
51
+		if !isSSHMountsSupported() {
52
+			return false
53
+		}
54
+	}
50 55
 	_, ok := allowedMountTypes[s]
51 56
 	return ok
52 57
 }
53 58
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+// +build dfssh dfextall
1
+
2
+package instructions
3
+
4
+func isSSHMountsSupported() bool {
5
+	return true
6
+}
... ...
@@ -7,6 +7,7 @@ import (
7 7
 	"github.com/moby/buildkit/util/apicaps"
8 8
 	digest "github.com/opencontainers/go-digest"
9 9
 	specs "github.com/opencontainers/image-spec/specs-go/v1"
10
+	fstypes "github.com/tonistiigi/fsutil/types"
10 11
 )
11 12
 
12 13
 type Client interface {
... ...
@@ -17,8 +18,8 @@ type Client interface {
17 17
 
18 18
 type Reference interface {
19 19
 	ReadFile(ctx context.Context, req ReadRequest) ([]byte, error)
20
-	// StatFile(ctx context.Context, req StatRequest) (*StatResponse, error)
21
-	// ReadDir(ctx context.Context, req ReadDirRequest) ([]*StatResponse, error)
20
+	StatFile(ctx context.Context, req StatRequest) (*fstypes.Stat, error)
21
+	ReadDir(ctx context.Context, req ReadDirRequest) ([]*fstypes.Stat, error)
22 22
 }
23 23
 
24 24
 type ReadRequest struct {
... ...
@@ -31,6 +32,15 @@ type FileRange struct {
31 31
 	Length int
32 32
 }
33 33
 
34
+type ReadDirRequest struct {
35
+	Path           string
36
+	IncludePattern string
37
+}
38
+
39
+type StatRequest struct {
40
+	Path string
41
+}
42
+
34 43
 // SolveRequest is same as frontend.SolveRequest but avoiding dependency
35 44
 type SolveRequest struct {
36 45
 	Definition      *pb.Definition
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"sync"
6 6
 
7 7
 	"github.com/moby/buildkit/cache"
8
+	cacheutil "github.com/moby/buildkit/cache/util"
8 9
 	clienttypes "github.com/moby/buildkit/client"
9 10
 	"github.com/moby/buildkit/frontend"
10 11
 	"github.com/moby/buildkit/frontend/gateway/client"
... ...
@@ -15,6 +16,7 @@ import (
15 15
 	"github.com/moby/buildkit/util/apicaps"
16 16
 	"github.com/moby/buildkit/worker"
17 17
 	"github.com/pkg/errors"
18
+	fstypes "github.com/tonistiigi/fsutil/types"
18 19
 )
19 20
 
20 21
 func llbBridgeToGatewayClient(ctx context.Context, llbBridge frontend.FrontendLLBBridge, opts map[string]string, workerInfos []clienttypes.WorkerInfo) (*bridgeClient, error) {
... ...
@@ -136,16 +138,36 @@ func (r *ref) ReadFile(ctx context.Context, req client.ReadRequest) ([]byte, err
136 136
 	if err != nil {
137 137
 		return nil, err
138 138
 	}
139
-	newReq := cache.ReadRequest{
139
+	newReq := cacheutil.ReadRequest{
140 140
 		Filename: req.Filename,
141 141
 	}
142 142
 	if r := req.Range; r != nil {
143
-		newReq.Range = &cache.FileRange{
143
+		newReq.Range = &cacheutil.FileRange{
144 144
 			Offset: r.Offset,
145 145
 			Length: r.Length,
146 146
 		}
147 147
 	}
148
-	return cache.ReadFile(ctx, ref, newReq)
148
+	return cacheutil.ReadFile(ctx, ref, newReq)
149
+}
150
+
151
+func (r *ref) ReadDir(ctx context.Context, req client.ReadDirRequest) ([]*fstypes.Stat, error) {
152
+	ref, err := r.getImmutableRef()
153
+	if err != nil {
154
+		return nil, err
155
+	}
156
+	newReq := cacheutil.ReadDirRequest{
157
+		Path:           req.Path,
158
+		IncludePattern: req.IncludePattern,
159
+	}
160
+	return cacheutil.ReadDir(ctx, ref, newReq)
161
+}
162
+
163
+func (r *ref) StatFile(ctx context.Context, req client.StatRequest) (*fstypes.Stat, error) {
164
+	ref, err := r.getImmutableRef()
165
+	if err != nil {
166
+		return nil, err
167
+	}
168
+	return cacheutil.StatFile(ctx, ref, req.Path)
149 169
 }
150 170
 
151 171
 func (r *ref) getImmutableRef() (cache.ImmutableRef, error) {
... ...
@@ -14,6 +14,7 @@ import (
14 14
 	"github.com/docker/distribution/reference"
15 15
 	apitypes "github.com/moby/buildkit/api/types"
16 16
 	"github.com/moby/buildkit/cache"
17
+	cacheutil "github.com/moby/buildkit/cache/util"
17 18
 	"github.com/moby/buildkit/client"
18 19
 	"github.com/moby/buildkit/client/llb"
19 20
 	"github.com/moby/buildkit/executor"
... ...
@@ -479,24 +480,24 @@ func (lbf *llbBridgeForwarder) ReadFile(ctx context.Context, req *pb.ReadFileReq
479 479
 		return nil, errors.Errorf("no such ref: %v", req.Ref)
480 480
 	}
481 481
 	if ref == nil {
482
-		return nil, errors.Wrapf(os.ErrNotExist, "%s no found", req.FilePath)
482
+		return nil, errors.Wrapf(os.ErrNotExist, "%s not found", req.FilePath)
483 483
 	}
484 484
 	workerRef, ok := ref.Sys().(*worker.WorkerRef)
485 485
 	if !ok {
486 486
 		return nil, errors.Errorf("invalid ref: %T", ref.Sys())
487 487
 	}
488 488
 
489
-	newReq := cache.ReadRequest{
489
+	newReq := cacheutil.ReadRequest{
490 490
 		Filename: req.FilePath,
491 491
 	}
492 492
 	if r := req.Range; r != nil {
493
-		newReq.Range = &cache.FileRange{
493
+		newReq.Range = &cacheutil.FileRange{
494 494
 			Offset: int(r.Offset),
495 495
 			Length: int(r.Length),
496 496
 		}
497 497
 	}
498 498
 
499
-	dt, err := cache.ReadFile(ctx, workerRef.ImmutableRef, newReq)
499
+	dt, err := cacheutil.ReadFile(ctx, workerRef.ImmutableRef, newReq)
500 500
 	if err != nil {
501 501
 		return nil, err
502 502
 	}
... ...
@@ -504,6 +505,58 @@ func (lbf *llbBridgeForwarder) ReadFile(ctx context.Context, req *pb.ReadFileReq
504 504
 	return &pb.ReadFileResponse{Data: dt}, nil
505 505
 }
506 506
 
507
+func (lbf *llbBridgeForwarder) ReadDir(ctx context.Context, req *pb.ReadDirRequest) (*pb.ReadDirResponse, error) {
508
+	ctx = tracing.ContextWithSpanFromContext(ctx, lbf.callCtx)
509
+	lbf.mu.Lock()
510
+	ref, ok := lbf.refs[req.Ref]
511
+	lbf.mu.Unlock()
512
+	if !ok {
513
+		return nil, errors.Errorf("no such ref: %v", req.Ref)
514
+	}
515
+	if ref == nil {
516
+		return nil, errors.Wrapf(os.ErrNotExist, "%s not found", req.DirPath)
517
+	}
518
+	workerRef, ok := ref.Sys().(*worker.WorkerRef)
519
+	if !ok {
520
+		return nil, errors.Errorf("invalid ref: %T", ref.Sys())
521
+	}
522
+
523
+	newReq := cacheutil.ReadDirRequest{
524
+		Path:           req.DirPath,
525
+		IncludePattern: req.IncludePattern,
526
+	}
527
+	entries, err := cacheutil.ReadDir(ctx, workerRef.ImmutableRef, newReq)
528
+	if err != nil {
529
+		return nil, err
530
+	}
531
+
532
+	return &pb.ReadDirResponse{Entries: entries}, nil
533
+}
534
+
535
+func (lbf *llbBridgeForwarder) StatFile(ctx context.Context, req *pb.StatFileRequest) (*pb.StatFileResponse, error) {
536
+	ctx = tracing.ContextWithSpanFromContext(ctx, lbf.callCtx)
537
+	lbf.mu.Lock()
538
+	ref, ok := lbf.refs[req.Ref]
539
+	lbf.mu.Unlock()
540
+	if !ok {
541
+		return nil, errors.Errorf("no such ref: %v", req.Ref)
542
+	}
543
+	if ref == nil {
544
+		return nil, errors.Wrapf(os.ErrNotExist, "%s not found", req.Path)
545
+	}
546
+	workerRef, ok := ref.Sys().(*worker.WorkerRef)
547
+	if !ok {
548
+		return nil, errors.Errorf("invalid ref: %T", ref.Sys())
549
+	}
550
+
551
+	st, err := cacheutil.StatFile(ctx, workerRef.ImmutableRef, req.Path)
552
+	if err != nil {
553
+		return nil, err
554
+	}
555
+
556
+	return &pb.StatFileResponse{Stat: st}, nil
557
+}
558
+
507 559
 func (lbf *llbBridgeForwarder) Ping(context.Context, *pb.PingRequest) (*pb.PongResponse, error) {
508 560
 
509 561
 	workers := lbf.workers.WorkerInfos()
... ...
@@ -16,6 +16,7 @@ import (
16 16
 	"github.com/moby/buildkit/util/apicaps"
17 17
 	digest "github.com/opencontainers/go-digest"
18 18
 	"github.com/pkg/errors"
19
+	fstypes "github.com/tonistiigi/fsutil/types"
19 20
 	"google.golang.org/grpc"
20 21
 	"google.golang.org/grpc/status"
21 22
 )
... ...
@@ -207,7 +208,7 @@ func defaultLLBCaps() []apicaps.PBCap {
207 207
 		{ID: string(opspb.CapExecMountCacheSharing), Enabled: true},
208 208
 		{ID: string(opspb.CapExecMountSelector), Enabled: true},
209 209
 		{ID: string(opspb.CapExecMountTmpfs), Enabled: true},
210
-		{ID: string(opspb.CapMountSecret), Enabled: true},
210
+		{ID: string(opspb.CapExecMountSecret), Enabled: true},
211 211
 		{ID: string(opspb.CapConstraints), Enabled: true},
212 212
 		{ID: string(opspb.CapPlatform), Enabled: true},
213 213
 		{ID: string(opspb.CapMetaIgnoreCache), Enabled: true},
... ...
@@ -354,6 +355,31 @@ func (r *reference) ReadFile(ctx context.Context, req client.ReadRequest) ([]byt
354 354
 	return resp.Data, nil
355 355
 }
356 356
 
357
+func (r *reference) ReadDir(ctx context.Context, req client.ReadDirRequest) ([]*fstypes.Stat, error) {
358
+	rdr := &pb.ReadDirRequest{
359
+		DirPath:        req.Path,
360
+		IncludePattern: req.IncludePattern,
361
+		Ref:            r.id,
362
+	}
363
+	resp, err := r.c.client.ReadDir(ctx, rdr)
364
+	if err != nil {
365
+		return nil, err
366
+	}
367
+	return resp.Entries, nil
368
+}
369
+
370
+func (r *reference) StatFile(ctx context.Context, req client.StatRequest) (*fstypes.Stat, error) {
371
+	rdr := &pb.StatFileRequest{
372
+		Path: req.Path,
373
+		Ref:  r.id,
374
+	}
375
+	resp, err := r.c.client.StatFile(ctx, rdr)
376
+	if err != nil {
377
+		return nil, err
378
+	}
379
+	return resp.Stat, nil
380
+}
381
+
357 382
 func grpcClientConn(ctx context.Context) (context.Context, *grpc.ClientConn, error) {
358 383
 	dialOpt := grpc.WithDialer(func(addr string, d time.Duration) (net.Conn, error) {
359 384
 		return stdioConn(), nil
... ...
@@ -16,6 +16,8 @@ const (
16 16
 	CapReadFile                apicaps.CapID = "readfile"
17 17
 	CapReturnResult            apicaps.CapID = "return"
18 18
 	CapReturnMap               apicaps.CapID = "returnmap"
19
+	CapReadDir                 apicaps.CapID = "readdir"
20
+	CapStatFile                apicaps.CapID = "statfile"
19 21
 )
20 22
 
21 23
 func init() {
... ...
@@ -69,4 +71,17 @@ func init() {
69 69
 		Status:  apicaps.CapStatusExperimental,
70 70
 	})
71 71
 
72
+	Caps.Init(apicaps.Cap{
73
+		ID:      CapReadDir,
74
+		Name:    "read static directory",
75
+		Enabled: true,
76
+		Status:  apicaps.CapStatusExperimental,
77
+	})
78
+
79
+	Caps.Init(apicaps.Cap{
80
+		ID:      CapStatFile,
81
+		Name:    "stat a file",
82
+		Enabled: true,
83
+		Status:  apicaps.CapStatusExperimental,
84
+	})
72 85
 }
... ...
@@ -19,6 +19,10 @@
19 19
 		ReadFileRequest
20 20
 		FileRange
21 21
 		ReadFileResponse
22
+		ReadDirRequest
23
+		ReadDirResponse
24
+		StatFileRequest
25
+		StatFileResponse
22 26
 		PingRequest
23 27
 		PongResponse
24 28
 */
... ...
@@ -32,6 +36,7 @@ import google_rpc "github.com/gogo/googleapis/google/rpc"
32 32
 import pb "github.com/moby/buildkit/solver/pb"
33 33
 import moby_buildkit_v1_types "github.com/moby/buildkit/api/types"
34 34
 import moby_buildkit_v1_apicaps "github.com/moby/buildkit/util/apicaps/pb"
35
+import fsutil_types "github.com/tonistiigi/fsutil/types"
35 36
 
36 37
 import github_com_opencontainers_go_digest "github.com/opencontainers/go-digest"
37 38
 
... ...
@@ -448,13 +453,101 @@ func (m *ReadFileResponse) GetData() []byte {
448 448
 	return nil
449 449
 }
450 450
 
451
+type ReadDirRequest struct {
452
+	Ref            string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
453
+	DirPath        string `protobuf:"bytes,2,opt,name=DirPath,proto3" json:"DirPath,omitempty"`
454
+	IncludePattern string `protobuf:"bytes,3,opt,name=IncludePattern,proto3" json:"IncludePattern,omitempty"`
455
+}
456
+
457
+func (m *ReadDirRequest) Reset()                    { *m = ReadDirRequest{} }
458
+func (m *ReadDirRequest) String() string            { return proto.CompactTextString(m) }
459
+func (*ReadDirRequest) ProtoMessage()               {}
460
+func (*ReadDirRequest) Descriptor() ([]byte, []int) { return fileDescriptorGateway, []int{11} }
461
+
462
+func (m *ReadDirRequest) GetRef() string {
463
+	if m != nil {
464
+		return m.Ref
465
+	}
466
+	return ""
467
+}
468
+
469
+func (m *ReadDirRequest) GetDirPath() string {
470
+	if m != nil {
471
+		return m.DirPath
472
+	}
473
+	return ""
474
+}
475
+
476
+func (m *ReadDirRequest) GetIncludePattern() string {
477
+	if m != nil {
478
+		return m.IncludePattern
479
+	}
480
+	return ""
481
+}
482
+
483
+type ReadDirResponse struct {
484
+	Entries []*fsutil_types.Stat `protobuf:"bytes,1,rep,name=entries" json:"entries,omitempty"`
485
+}
486
+
487
+func (m *ReadDirResponse) Reset()                    { *m = ReadDirResponse{} }
488
+func (m *ReadDirResponse) String() string            { return proto.CompactTextString(m) }
489
+func (*ReadDirResponse) ProtoMessage()               {}
490
+func (*ReadDirResponse) Descriptor() ([]byte, []int) { return fileDescriptorGateway, []int{12} }
491
+
492
+func (m *ReadDirResponse) GetEntries() []*fsutil_types.Stat {
493
+	if m != nil {
494
+		return m.Entries
495
+	}
496
+	return nil
497
+}
498
+
499
+type StatFileRequest struct {
500
+	Ref  string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
501
+	Path string `protobuf:"bytes,2,opt,name=Path,proto3" json:"Path,omitempty"`
502
+}
503
+
504
+func (m *StatFileRequest) Reset()                    { *m = StatFileRequest{} }
505
+func (m *StatFileRequest) String() string            { return proto.CompactTextString(m) }
506
+func (*StatFileRequest) ProtoMessage()               {}
507
+func (*StatFileRequest) Descriptor() ([]byte, []int) { return fileDescriptorGateway, []int{13} }
508
+
509
+func (m *StatFileRequest) GetRef() string {
510
+	if m != nil {
511
+		return m.Ref
512
+	}
513
+	return ""
514
+}
515
+
516
+func (m *StatFileRequest) GetPath() string {
517
+	if m != nil {
518
+		return m.Path
519
+	}
520
+	return ""
521
+}
522
+
523
+type StatFileResponse struct {
524
+	Stat *fsutil_types.Stat `protobuf:"bytes,1,opt,name=stat" json:"stat,omitempty"`
525
+}
526
+
527
+func (m *StatFileResponse) Reset()                    { *m = StatFileResponse{} }
528
+func (m *StatFileResponse) String() string            { return proto.CompactTextString(m) }
529
+func (*StatFileResponse) ProtoMessage()               {}
530
+func (*StatFileResponse) Descriptor() ([]byte, []int) { return fileDescriptorGateway, []int{14} }
531
+
532
+func (m *StatFileResponse) GetStat() *fsutil_types.Stat {
533
+	if m != nil {
534
+		return m.Stat
535
+	}
536
+	return nil
537
+}
538
+
451 539
 type PingRequest struct {
452 540
 }
453 541
 
454 542
 func (m *PingRequest) Reset()                    { *m = PingRequest{} }
455 543
 func (m *PingRequest) String() string            { return proto.CompactTextString(m) }
456 544
 func (*PingRequest) ProtoMessage()               {}
457
-func (*PingRequest) Descriptor() ([]byte, []int) { return fileDescriptorGateway, []int{11} }
545
+func (*PingRequest) Descriptor() ([]byte, []int) { return fileDescriptorGateway, []int{15} }
458 546
 
459 547
 type PongResponse struct {
460 548
 	FrontendAPICaps []moby_buildkit_v1_apicaps.APICap      `protobuf:"bytes,1,rep,name=FrontendAPICaps" json:"FrontendAPICaps"`
... ...
@@ -465,7 +558,7 @@ type PongResponse struct {
465 465
 func (m *PongResponse) Reset()                    { *m = PongResponse{} }
466 466
 func (m *PongResponse) String() string            { return proto.CompactTextString(m) }
467 467
 func (*PongResponse) ProtoMessage()               {}
468
-func (*PongResponse) Descriptor() ([]byte, []int) { return fileDescriptorGateway, []int{12} }
468
+func (*PongResponse) Descriptor() ([]byte, []int) { return fileDescriptorGateway, []int{16} }
469 469
 
470 470
 func (m *PongResponse) GetFrontendAPICaps() []moby_buildkit_v1_apicaps.APICap {
471 471
 	if m != nil {
... ...
@@ -500,6 +593,10 @@ func init() {
500 500
 	proto.RegisterType((*ReadFileRequest)(nil), "moby.buildkit.v1.frontend.ReadFileRequest")
501 501
 	proto.RegisterType((*FileRange)(nil), "moby.buildkit.v1.frontend.FileRange")
502 502
 	proto.RegisterType((*ReadFileResponse)(nil), "moby.buildkit.v1.frontend.ReadFileResponse")
503
+	proto.RegisterType((*ReadDirRequest)(nil), "moby.buildkit.v1.frontend.ReadDirRequest")
504
+	proto.RegisterType((*ReadDirResponse)(nil), "moby.buildkit.v1.frontend.ReadDirResponse")
505
+	proto.RegisterType((*StatFileRequest)(nil), "moby.buildkit.v1.frontend.StatFileRequest")
506
+	proto.RegisterType((*StatFileResponse)(nil), "moby.buildkit.v1.frontend.StatFileResponse")
503 507
 	proto.RegisterType((*PingRequest)(nil), "moby.buildkit.v1.frontend.PingRequest")
504 508
 	proto.RegisterType((*PongResponse)(nil), "moby.buildkit.v1.frontend.PongResponse")
505 509
 }
... ...
@@ -521,6 +618,10 @@ type LLBBridgeClient interface {
521 521
 	Solve(ctx context.Context, in *SolveRequest, opts ...grpc.CallOption) (*SolveResponse, error)
522 522
 	// apicaps:CapReadFile
523 523
 	ReadFile(ctx context.Context, in *ReadFileRequest, opts ...grpc.CallOption) (*ReadFileResponse, error)
524
+	// apicaps:CapReadDir
525
+	ReadDir(ctx context.Context, in *ReadDirRequest, opts ...grpc.CallOption) (*ReadDirResponse, error)
526
+	// apicaps:CapStatFile
527
+	StatFile(ctx context.Context, in *StatFileRequest, opts ...grpc.CallOption) (*StatFileResponse, error)
524 528
 	Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PongResponse, error)
525 529
 	Return(ctx context.Context, in *ReturnRequest, opts ...grpc.CallOption) (*ReturnResponse, error)
526 530
 }
... ...
@@ -560,6 +661,24 @@ func (c *lLBBridgeClient) ReadFile(ctx context.Context, in *ReadFileRequest, opt
560 560
 	return out, nil
561 561
 }
562 562
 
563
+func (c *lLBBridgeClient) ReadDir(ctx context.Context, in *ReadDirRequest, opts ...grpc.CallOption) (*ReadDirResponse, error) {
564
+	out := new(ReadDirResponse)
565
+	err := grpc.Invoke(ctx, "/moby.buildkit.v1.frontend.LLBBridge/ReadDir", in, out, c.cc, opts...)
566
+	if err != nil {
567
+		return nil, err
568
+	}
569
+	return out, nil
570
+}
571
+
572
+func (c *lLBBridgeClient) StatFile(ctx context.Context, in *StatFileRequest, opts ...grpc.CallOption) (*StatFileResponse, error) {
573
+	out := new(StatFileResponse)
574
+	err := grpc.Invoke(ctx, "/moby.buildkit.v1.frontend.LLBBridge/StatFile", in, out, c.cc, opts...)
575
+	if err != nil {
576
+		return nil, err
577
+	}
578
+	return out, nil
579
+}
580
+
563 581
 func (c *lLBBridgeClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PongResponse, error) {
564 582
 	out := new(PongResponse)
565 583
 	err := grpc.Invoke(ctx, "/moby.buildkit.v1.frontend.LLBBridge/Ping", in, out, c.cc, opts...)
... ...
@@ -587,6 +706,10 @@ type LLBBridgeServer interface {
587 587
 	Solve(context.Context, *SolveRequest) (*SolveResponse, error)
588 588
 	// apicaps:CapReadFile
589 589
 	ReadFile(context.Context, *ReadFileRequest) (*ReadFileResponse, error)
590
+	// apicaps:CapReadDir
591
+	ReadDir(context.Context, *ReadDirRequest) (*ReadDirResponse, error)
592
+	// apicaps:CapStatFile
593
+	StatFile(context.Context, *StatFileRequest) (*StatFileResponse, error)
590 594
 	Ping(context.Context, *PingRequest) (*PongResponse, error)
591 595
 	Return(context.Context, *ReturnRequest) (*ReturnResponse, error)
592 596
 }
... ...
@@ -649,6 +772,42 @@ func _LLBBridge_ReadFile_Handler(srv interface{}, ctx context.Context, dec func(
649 649
 	return interceptor(ctx, in, info, handler)
650 650
 }
651 651
 
652
+func _LLBBridge_ReadDir_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
653
+	in := new(ReadDirRequest)
654
+	if err := dec(in); err != nil {
655
+		return nil, err
656
+	}
657
+	if interceptor == nil {
658
+		return srv.(LLBBridgeServer).ReadDir(ctx, in)
659
+	}
660
+	info := &grpc.UnaryServerInfo{
661
+		Server:     srv,
662
+		FullMethod: "/moby.buildkit.v1.frontend.LLBBridge/ReadDir",
663
+	}
664
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
665
+		return srv.(LLBBridgeServer).ReadDir(ctx, req.(*ReadDirRequest))
666
+	}
667
+	return interceptor(ctx, in, info, handler)
668
+}
669
+
670
+func _LLBBridge_StatFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
671
+	in := new(StatFileRequest)
672
+	if err := dec(in); err != nil {
673
+		return nil, err
674
+	}
675
+	if interceptor == nil {
676
+		return srv.(LLBBridgeServer).StatFile(ctx, in)
677
+	}
678
+	info := &grpc.UnaryServerInfo{
679
+		Server:     srv,
680
+		FullMethod: "/moby.buildkit.v1.frontend.LLBBridge/StatFile",
681
+	}
682
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
683
+		return srv.(LLBBridgeServer).StatFile(ctx, req.(*StatFileRequest))
684
+	}
685
+	return interceptor(ctx, in, info, handler)
686
+}
687
+
652 688
 func _LLBBridge_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
653 689
 	in := new(PingRequest)
654 690
 	if err := dec(in); err != nil {
... ...
@@ -702,6 +861,14 @@ var _LLBBridge_serviceDesc = grpc.ServiceDesc{
702 702
 			Handler:    _LLBBridge_ReadFile_Handler,
703 703
 		},
704 704
 		{
705
+			MethodName: "ReadDir",
706
+			Handler:    _LLBBridge_ReadDir_Handler,
707
+		},
708
+		{
709
+			MethodName: "StatFile",
710
+			Handler:    _LLBBridge_StatFile_Handler,
711
+		},
712
+		{
705 713
 			MethodName: "Ping",
706 714
 			Handler:    _LLBBridge_Ping_Handler,
707 715
 		},
... ...
@@ -1169,6 +1336,130 @@ func (m *ReadFileResponse) MarshalTo(dAtA []byte) (int, error) {
1169 1169
 	return i, nil
1170 1170
 }
1171 1171
 
1172
+func (m *ReadDirRequest) Marshal() (dAtA []byte, err error) {
1173
+	size := m.Size()
1174
+	dAtA = make([]byte, size)
1175
+	n, err := m.MarshalTo(dAtA)
1176
+	if err != nil {
1177
+		return nil, err
1178
+	}
1179
+	return dAtA[:n], nil
1180
+}
1181
+
1182
+func (m *ReadDirRequest) MarshalTo(dAtA []byte) (int, error) {
1183
+	var i int
1184
+	_ = i
1185
+	var l int
1186
+	_ = l
1187
+	if len(m.Ref) > 0 {
1188
+		dAtA[i] = 0xa
1189
+		i++
1190
+		i = encodeVarintGateway(dAtA, i, uint64(len(m.Ref)))
1191
+		i += copy(dAtA[i:], m.Ref)
1192
+	}
1193
+	if len(m.DirPath) > 0 {
1194
+		dAtA[i] = 0x12
1195
+		i++
1196
+		i = encodeVarintGateway(dAtA, i, uint64(len(m.DirPath)))
1197
+		i += copy(dAtA[i:], m.DirPath)
1198
+	}
1199
+	if len(m.IncludePattern) > 0 {
1200
+		dAtA[i] = 0x1a
1201
+		i++
1202
+		i = encodeVarintGateway(dAtA, i, uint64(len(m.IncludePattern)))
1203
+		i += copy(dAtA[i:], m.IncludePattern)
1204
+	}
1205
+	return i, nil
1206
+}
1207
+
1208
+func (m *ReadDirResponse) Marshal() (dAtA []byte, err error) {
1209
+	size := m.Size()
1210
+	dAtA = make([]byte, size)
1211
+	n, err := m.MarshalTo(dAtA)
1212
+	if err != nil {
1213
+		return nil, err
1214
+	}
1215
+	return dAtA[:n], nil
1216
+}
1217
+
1218
+func (m *ReadDirResponse) MarshalTo(dAtA []byte) (int, error) {
1219
+	var i int
1220
+	_ = i
1221
+	var l int
1222
+	_ = l
1223
+	if len(m.Entries) > 0 {
1224
+		for _, msg := range m.Entries {
1225
+			dAtA[i] = 0xa
1226
+			i++
1227
+			i = encodeVarintGateway(dAtA, i, uint64(msg.Size()))
1228
+			n, err := msg.MarshalTo(dAtA[i:])
1229
+			if err != nil {
1230
+				return 0, err
1231
+			}
1232
+			i += n
1233
+		}
1234
+	}
1235
+	return i, nil
1236
+}
1237
+
1238
+func (m *StatFileRequest) Marshal() (dAtA []byte, err error) {
1239
+	size := m.Size()
1240
+	dAtA = make([]byte, size)
1241
+	n, err := m.MarshalTo(dAtA)
1242
+	if err != nil {
1243
+		return nil, err
1244
+	}
1245
+	return dAtA[:n], nil
1246
+}
1247
+
1248
+func (m *StatFileRequest) MarshalTo(dAtA []byte) (int, error) {
1249
+	var i int
1250
+	_ = i
1251
+	var l int
1252
+	_ = l
1253
+	if len(m.Ref) > 0 {
1254
+		dAtA[i] = 0xa
1255
+		i++
1256
+		i = encodeVarintGateway(dAtA, i, uint64(len(m.Ref)))
1257
+		i += copy(dAtA[i:], m.Ref)
1258
+	}
1259
+	if len(m.Path) > 0 {
1260
+		dAtA[i] = 0x12
1261
+		i++
1262
+		i = encodeVarintGateway(dAtA, i, uint64(len(m.Path)))
1263
+		i += copy(dAtA[i:], m.Path)
1264
+	}
1265
+	return i, nil
1266
+}
1267
+
1268
+func (m *StatFileResponse) Marshal() (dAtA []byte, err error) {
1269
+	size := m.Size()
1270
+	dAtA = make([]byte, size)
1271
+	n, err := m.MarshalTo(dAtA)
1272
+	if err != nil {
1273
+		return nil, err
1274
+	}
1275
+	return dAtA[:n], nil
1276
+}
1277
+
1278
+func (m *StatFileResponse) MarshalTo(dAtA []byte) (int, error) {
1279
+	var i int
1280
+	_ = i
1281
+	var l int
1282
+	_ = l
1283
+	if m.Stat != nil {
1284
+		dAtA[i] = 0xa
1285
+		i++
1286
+		i = encodeVarintGateway(dAtA, i, uint64(m.Stat.Size()))
1287
+		n9, err := m.Stat.MarshalTo(dAtA[i:])
1288
+		if err != nil {
1289
+			return 0, err
1290
+		}
1291
+		i += n9
1292
+	}
1293
+	return i, nil
1294
+}
1295
+
1172 1296
 func (m *PingRequest) Marshal() (dAtA []byte, err error) {
1173 1297
 	size := m.Size()
1174 1298
 	dAtA = make([]byte, size)
... ...
@@ -1449,6 +1740,60 @@ func (m *ReadFileResponse) Size() (n int) {
1449 1449
 	return n
1450 1450
 }
1451 1451
 
1452
+func (m *ReadDirRequest) Size() (n int) {
1453
+	var l int
1454
+	_ = l
1455
+	l = len(m.Ref)
1456
+	if l > 0 {
1457
+		n += 1 + l + sovGateway(uint64(l))
1458
+	}
1459
+	l = len(m.DirPath)
1460
+	if l > 0 {
1461
+		n += 1 + l + sovGateway(uint64(l))
1462
+	}
1463
+	l = len(m.IncludePattern)
1464
+	if l > 0 {
1465
+		n += 1 + l + sovGateway(uint64(l))
1466
+	}
1467
+	return n
1468
+}
1469
+
1470
+func (m *ReadDirResponse) Size() (n int) {
1471
+	var l int
1472
+	_ = l
1473
+	if len(m.Entries) > 0 {
1474
+		for _, e := range m.Entries {
1475
+			l = e.Size()
1476
+			n += 1 + l + sovGateway(uint64(l))
1477
+		}
1478
+	}
1479
+	return n
1480
+}
1481
+
1482
+func (m *StatFileRequest) Size() (n int) {
1483
+	var l int
1484
+	_ = l
1485
+	l = len(m.Ref)
1486
+	if l > 0 {
1487
+		n += 1 + l + sovGateway(uint64(l))
1488
+	}
1489
+	l = len(m.Path)
1490
+	if l > 0 {
1491
+		n += 1 + l + sovGateway(uint64(l))
1492
+	}
1493
+	return n
1494
+}
1495
+
1496
+func (m *StatFileResponse) Size() (n int) {
1497
+	var l int
1498
+	_ = l
1499
+	if m.Stat != nil {
1500
+		l = m.Stat.Size()
1501
+		n += 1 + l + sovGateway(uint64(l))
1502
+	}
1503
+	return n
1504
+}
1505
+
1452 1506
 func (m *PingRequest) Size() (n int) {
1453 1507
 	var l int
1454 1508
 	_ = l
... ...
@@ -3088,6 +3433,415 @@ func (m *ReadFileResponse) Unmarshal(dAtA []byte) error {
3088 3088
 	}
3089 3089
 	return nil
3090 3090
 }
3091
+func (m *ReadDirRequest) Unmarshal(dAtA []byte) error {
3092
+	l := len(dAtA)
3093
+	iNdEx := 0
3094
+	for iNdEx < l {
3095
+		preIndex := iNdEx
3096
+		var wire uint64
3097
+		for shift := uint(0); ; shift += 7 {
3098
+			if shift >= 64 {
3099
+				return ErrIntOverflowGateway
3100
+			}
3101
+			if iNdEx >= l {
3102
+				return io.ErrUnexpectedEOF
3103
+			}
3104
+			b := dAtA[iNdEx]
3105
+			iNdEx++
3106
+			wire |= (uint64(b) & 0x7F) << shift
3107
+			if b < 0x80 {
3108
+				break
3109
+			}
3110
+		}
3111
+		fieldNum := int32(wire >> 3)
3112
+		wireType := int(wire & 0x7)
3113
+		if wireType == 4 {
3114
+			return fmt.Errorf("proto: ReadDirRequest: wiretype end group for non-group")
3115
+		}
3116
+		if fieldNum <= 0 {
3117
+			return fmt.Errorf("proto: ReadDirRequest: illegal tag %d (wire type %d)", fieldNum, wire)
3118
+		}
3119
+		switch fieldNum {
3120
+		case 1:
3121
+			if wireType != 2 {
3122
+				return fmt.Errorf("proto: wrong wireType = %d for field Ref", wireType)
3123
+			}
3124
+			var stringLen uint64
3125
+			for shift := uint(0); ; shift += 7 {
3126
+				if shift >= 64 {
3127
+					return ErrIntOverflowGateway
3128
+				}
3129
+				if iNdEx >= l {
3130
+					return io.ErrUnexpectedEOF
3131
+				}
3132
+				b := dAtA[iNdEx]
3133
+				iNdEx++
3134
+				stringLen |= (uint64(b) & 0x7F) << shift
3135
+				if b < 0x80 {
3136
+					break
3137
+				}
3138
+			}
3139
+			intStringLen := int(stringLen)
3140
+			if intStringLen < 0 {
3141
+				return ErrInvalidLengthGateway
3142
+			}
3143
+			postIndex := iNdEx + intStringLen
3144
+			if postIndex > l {
3145
+				return io.ErrUnexpectedEOF
3146
+			}
3147
+			m.Ref = string(dAtA[iNdEx:postIndex])
3148
+			iNdEx = postIndex
3149
+		case 2:
3150
+			if wireType != 2 {
3151
+				return fmt.Errorf("proto: wrong wireType = %d for field DirPath", wireType)
3152
+			}
3153
+			var stringLen uint64
3154
+			for shift := uint(0); ; shift += 7 {
3155
+				if shift >= 64 {
3156
+					return ErrIntOverflowGateway
3157
+				}
3158
+				if iNdEx >= l {
3159
+					return io.ErrUnexpectedEOF
3160
+				}
3161
+				b := dAtA[iNdEx]
3162
+				iNdEx++
3163
+				stringLen |= (uint64(b) & 0x7F) << shift
3164
+				if b < 0x80 {
3165
+					break
3166
+				}
3167
+			}
3168
+			intStringLen := int(stringLen)
3169
+			if intStringLen < 0 {
3170
+				return ErrInvalidLengthGateway
3171
+			}
3172
+			postIndex := iNdEx + intStringLen
3173
+			if postIndex > l {
3174
+				return io.ErrUnexpectedEOF
3175
+			}
3176
+			m.DirPath = string(dAtA[iNdEx:postIndex])
3177
+			iNdEx = postIndex
3178
+		case 3:
3179
+			if wireType != 2 {
3180
+				return fmt.Errorf("proto: wrong wireType = %d for field IncludePattern", wireType)
3181
+			}
3182
+			var stringLen uint64
3183
+			for shift := uint(0); ; shift += 7 {
3184
+				if shift >= 64 {
3185
+					return ErrIntOverflowGateway
3186
+				}
3187
+				if iNdEx >= l {
3188
+					return io.ErrUnexpectedEOF
3189
+				}
3190
+				b := dAtA[iNdEx]
3191
+				iNdEx++
3192
+				stringLen |= (uint64(b) & 0x7F) << shift
3193
+				if b < 0x80 {
3194
+					break
3195
+				}
3196
+			}
3197
+			intStringLen := int(stringLen)
3198
+			if intStringLen < 0 {
3199
+				return ErrInvalidLengthGateway
3200
+			}
3201
+			postIndex := iNdEx + intStringLen
3202
+			if postIndex > l {
3203
+				return io.ErrUnexpectedEOF
3204
+			}
3205
+			m.IncludePattern = string(dAtA[iNdEx:postIndex])
3206
+			iNdEx = postIndex
3207
+		default:
3208
+			iNdEx = preIndex
3209
+			skippy, err := skipGateway(dAtA[iNdEx:])
3210
+			if err != nil {
3211
+				return err
3212
+			}
3213
+			if skippy < 0 {
3214
+				return ErrInvalidLengthGateway
3215
+			}
3216
+			if (iNdEx + skippy) > l {
3217
+				return io.ErrUnexpectedEOF
3218
+			}
3219
+			iNdEx += skippy
3220
+		}
3221
+	}
3222
+
3223
+	if iNdEx > l {
3224
+		return io.ErrUnexpectedEOF
3225
+	}
3226
+	return nil
3227
+}
3228
+func (m *ReadDirResponse) Unmarshal(dAtA []byte) error {
3229
+	l := len(dAtA)
3230
+	iNdEx := 0
3231
+	for iNdEx < l {
3232
+		preIndex := iNdEx
3233
+		var wire uint64
3234
+		for shift := uint(0); ; shift += 7 {
3235
+			if shift >= 64 {
3236
+				return ErrIntOverflowGateway
3237
+			}
3238
+			if iNdEx >= l {
3239
+				return io.ErrUnexpectedEOF
3240
+			}
3241
+			b := dAtA[iNdEx]
3242
+			iNdEx++
3243
+			wire |= (uint64(b) & 0x7F) << shift
3244
+			if b < 0x80 {
3245
+				break
3246
+			}
3247
+		}
3248
+		fieldNum := int32(wire >> 3)
3249
+		wireType := int(wire & 0x7)
3250
+		if wireType == 4 {
3251
+			return fmt.Errorf("proto: ReadDirResponse: wiretype end group for non-group")
3252
+		}
3253
+		if fieldNum <= 0 {
3254
+			return fmt.Errorf("proto: ReadDirResponse: illegal tag %d (wire type %d)", fieldNum, wire)
3255
+		}
3256
+		switch fieldNum {
3257
+		case 1:
3258
+			if wireType != 2 {
3259
+				return fmt.Errorf("proto: wrong wireType = %d for field Entries", wireType)
3260
+			}
3261
+			var msglen int
3262
+			for shift := uint(0); ; shift += 7 {
3263
+				if shift >= 64 {
3264
+					return ErrIntOverflowGateway
3265
+				}
3266
+				if iNdEx >= l {
3267
+					return io.ErrUnexpectedEOF
3268
+				}
3269
+				b := dAtA[iNdEx]
3270
+				iNdEx++
3271
+				msglen |= (int(b) & 0x7F) << shift
3272
+				if b < 0x80 {
3273
+					break
3274
+				}
3275
+			}
3276
+			if msglen < 0 {
3277
+				return ErrInvalidLengthGateway
3278
+			}
3279
+			postIndex := iNdEx + msglen
3280
+			if postIndex > l {
3281
+				return io.ErrUnexpectedEOF
3282
+			}
3283
+			m.Entries = append(m.Entries, &fsutil_types.Stat{})
3284
+			if err := m.Entries[len(m.Entries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
3285
+				return err
3286
+			}
3287
+			iNdEx = postIndex
3288
+		default:
3289
+			iNdEx = preIndex
3290
+			skippy, err := skipGateway(dAtA[iNdEx:])
3291
+			if err != nil {
3292
+				return err
3293
+			}
3294
+			if skippy < 0 {
3295
+				return ErrInvalidLengthGateway
3296
+			}
3297
+			if (iNdEx + skippy) > l {
3298
+				return io.ErrUnexpectedEOF
3299
+			}
3300
+			iNdEx += skippy
3301
+		}
3302
+	}
3303
+
3304
+	if iNdEx > l {
3305
+		return io.ErrUnexpectedEOF
3306
+	}
3307
+	return nil
3308
+}
3309
+func (m *StatFileRequest) Unmarshal(dAtA []byte) error {
3310
+	l := len(dAtA)
3311
+	iNdEx := 0
3312
+	for iNdEx < l {
3313
+		preIndex := iNdEx
3314
+		var wire uint64
3315
+		for shift := uint(0); ; shift += 7 {
3316
+			if shift >= 64 {
3317
+				return ErrIntOverflowGateway
3318
+			}
3319
+			if iNdEx >= l {
3320
+				return io.ErrUnexpectedEOF
3321
+			}
3322
+			b := dAtA[iNdEx]
3323
+			iNdEx++
3324
+			wire |= (uint64(b) & 0x7F) << shift
3325
+			if b < 0x80 {
3326
+				break
3327
+			}
3328
+		}
3329
+		fieldNum := int32(wire >> 3)
3330
+		wireType := int(wire & 0x7)
3331
+		if wireType == 4 {
3332
+			return fmt.Errorf("proto: StatFileRequest: wiretype end group for non-group")
3333
+		}
3334
+		if fieldNum <= 0 {
3335
+			return fmt.Errorf("proto: StatFileRequest: illegal tag %d (wire type %d)", fieldNum, wire)
3336
+		}
3337
+		switch fieldNum {
3338
+		case 1:
3339
+			if wireType != 2 {
3340
+				return fmt.Errorf("proto: wrong wireType = %d for field Ref", wireType)
3341
+			}
3342
+			var stringLen uint64
3343
+			for shift := uint(0); ; shift += 7 {
3344
+				if shift >= 64 {
3345
+					return ErrIntOverflowGateway
3346
+				}
3347
+				if iNdEx >= l {
3348
+					return io.ErrUnexpectedEOF
3349
+				}
3350
+				b := dAtA[iNdEx]
3351
+				iNdEx++
3352
+				stringLen |= (uint64(b) & 0x7F) << shift
3353
+				if b < 0x80 {
3354
+					break
3355
+				}
3356
+			}
3357
+			intStringLen := int(stringLen)
3358
+			if intStringLen < 0 {
3359
+				return ErrInvalidLengthGateway
3360
+			}
3361
+			postIndex := iNdEx + intStringLen
3362
+			if postIndex > l {
3363
+				return io.ErrUnexpectedEOF
3364
+			}
3365
+			m.Ref = string(dAtA[iNdEx:postIndex])
3366
+			iNdEx = postIndex
3367
+		case 2:
3368
+			if wireType != 2 {
3369
+				return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType)
3370
+			}
3371
+			var stringLen uint64
3372
+			for shift := uint(0); ; shift += 7 {
3373
+				if shift >= 64 {
3374
+					return ErrIntOverflowGateway
3375
+				}
3376
+				if iNdEx >= l {
3377
+					return io.ErrUnexpectedEOF
3378
+				}
3379
+				b := dAtA[iNdEx]
3380
+				iNdEx++
3381
+				stringLen |= (uint64(b) & 0x7F) << shift
3382
+				if b < 0x80 {
3383
+					break
3384
+				}
3385
+			}
3386
+			intStringLen := int(stringLen)
3387
+			if intStringLen < 0 {
3388
+				return ErrInvalidLengthGateway
3389
+			}
3390
+			postIndex := iNdEx + intStringLen
3391
+			if postIndex > l {
3392
+				return io.ErrUnexpectedEOF
3393
+			}
3394
+			m.Path = string(dAtA[iNdEx:postIndex])
3395
+			iNdEx = postIndex
3396
+		default:
3397
+			iNdEx = preIndex
3398
+			skippy, err := skipGateway(dAtA[iNdEx:])
3399
+			if err != nil {
3400
+				return err
3401
+			}
3402
+			if skippy < 0 {
3403
+				return ErrInvalidLengthGateway
3404
+			}
3405
+			if (iNdEx + skippy) > l {
3406
+				return io.ErrUnexpectedEOF
3407
+			}
3408
+			iNdEx += skippy
3409
+		}
3410
+	}
3411
+
3412
+	if iNdEx > l {
3413
+		return io.ErrUnexpectedEOF
3414
+	}
3415
+	return nil
3416
+}
3417
+func (m *StatFileResponse) Unmarshal(dAtA []byte) error {
3418
+	l := len(dAtA)
3419
+	iNdEx := 0
3420
+	for iNdEx < l {
3421
+		preIndex := iNdEx
3422
+		var wire uint64
3423
+		for shift := uint(0); ; shift += 7 {
3424
+			if shift >= 64 {
3425
+				return ErrIntOverflowGateway
3426
+			}
3427
+			if iNdEx >= l {
3428
+				return io.ErrUnexpectedEOF
3429
+			}
3430
+			b := dAtA[iNdEx]
3431
+			iNdEx++
3432
+			wire |= (uint64(b) & 0x7F) << shift
3433
+			if b < 0x80 {
3434
+				break
3435
+			}
3436
+		}
3437
+		fieldNum := int32(wire >> 3)
3438
+		wireType := int(wire & 0x7)
3439
+		if wireType == 4 {
3440
+			return fmt.Errorf("proto: StatFileResponse: wiretype end group for non-group")
3441
+		}
3442
+		if fieldNum <= 0 {
3443
+			return fmt.Errorf("proto: StatFileResponse: illegal tag %d (wire type %d)", fieldNum, wire)
3444
+		}
3445
+		switch fieldNum {
3446
+		case 1:
3447
+			if wireType != 2 {
3448
+				return fmt.Errorf("proto: wrong wireType = %d for field Stat", wireType)
3449
+			}
3450
+			var msglen int
3451
+			for shift := uint(0); ; shift += 7 {
3452
+				if shift >= 64 {
3453
+					return ErrIntOverflowGateway
3454
+				}
3455
+				if iNdEx >= l {
3456
+					return io.ErrUnexpectedEOF
3457
+				}
3458
+				b := dAtA[iNdEx]
3459
+				iNdEx++
3460
+				msglen |= (int(b) & 0x7F) << shift
3461
+				if b < 0x80 {
3462
+					break
3463
+				}
3464
+			}
3465
+			if msglen < 0 {
3466
+				return ErrInvalidLengthGateway
3467
+			}
3468
+			postIndex := iNdEx + msglen
3469
+			if postIndex > l {
3470
+				return io.ErrUnexpectedEOF
3471
+			}
3472
+			if m.Stat == nil {
3473
+				m.Stat = &fsutil_types.Stat{}
3474
+			}
3475
+			if err := m.Stat.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
3476
+				return err
3477
+			}
3478
+			iNdEx = postIndex
3479
+		default:
3480
+			iNdEx = preIndex
3481
+			skippy, err := skipGateway(dAtA[iNdEx:])
3482
+			if err != nil {
3483
+				return err
3484
+			}
3485
+			if skippy < 0 {
3486
+				return ErrInvalidLengthGateway
3487
+			}
3488
+			if (iNdEx + skippy) > l {
3489
+				return io.ErrUnexpectedEOF
3490
+			}
3491
+			iNdEx += skippy
3492
+		}
3493
+	}
3494
+
3495
+	if iNdEx > l {
3496
+		return io.ErrUnexpectedEOF
3497
+	}
3498
+	return nil
3499
+}
3091 3500
 func (m *PingRequest) Unmarshal(dAtA []byte) error {
3092 3501
 	l := len(dAtA)
3093 3502
 	iNdEx := 0
... ...
@@ -3389,68 +4143,77 @@ var (
3389 3389
 func init() { proto.RegisterFile("gateway.proto", fileDescriptorGateway) }
3390 3390
 
3391 3391
 var fileDescriptorGateway = []byte{
3392
-	// 999 bytes of a gzipped FileDescriptorProto
3393
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xcf, 0x6f, 0xdb, 0x36,
3394
-	0x14, 0x8e, 0x22, 0xdb, 0xb1, 0x9f, 0xed, 0xc6, 0x23, 0x86, 0x41, 0xd5, 0x21, 0xf5, 0x84, 0xa1,
3395
-	0xd3, 0xfa, 0x43, 0xc2, 0xdc, 0x0d, 0xed, 0x5a, 0xa0, 0x5b, 0x9d, 0x34, 0x68, 0x36, 0x67, 0x35,
3396
-	0xd8, 0x43, 0x81, 0x62, 0x3b, 0xd0, 0x36, 0xa5, 0x08, 0x91, 0x45, 0x8d, 0xa2, 0x93, 0x19, 0xbb,
3397
-	0x6c, 0x3b, 0xf5, 0xbe, 0x7f, 0xaa, 0xc7, 0x9d, 0x77, 0x08, 0x86, 0xdc, 0xf6, 0x5f, 0x0c, 0xa4,
3398
-	0x28, 0x47, 0xf9, 0xe5, 0x24, 0x27, 0xf3, 0x51, 0xef, 0x7b, 0xef, 0xe3, 0x7b, 0xdf, 0x23, 0x0d,
3399
-	0xed, 0x90, 0x08, 0x7a, 0x48, 0xe6, 0x5e, 0xca, 0x99, 0x60, 0xe8, 0xf6, 0x94, 0x8d, 0xe6, 0xde,
3400
-	0x68, 0x16, 0xc5, 0x93, 0xfd, 0x48, 0x78, 0x07, 0x5f, 0x7a, 0x01, 0x67, 0x89, 0xa0, 0xc9, 0xc4,
3401
-	0x7e, 0x18, 0x46, 0x62, 0x6f, 0x36, 0xf2, 0xc6, 0x6c, 0xea, 0x87, 0x2c, 0x64, 0xbe, 0x42, 0x8c,
3402
-	0x66, 0x81, 0xb2, 0x94, 0xa1, 0x56, 0x79, 0x24, 0xbb, 0x77, 0xd6, 0x3d, 0x64, 0x2c, 0x8c, 0x29,
3403
-	0x49, 0xa3, 0x4c, 0x2f, 0x7d, 0x9e, 0x8e, 0xfd, 0x4c, 0x10, 0x31, 0xcb, 0x34, 0xe6, 0x41, 0x09,
3404
-	0x23, 0x89, 0xf8, 0x05, 0x11, 0x3f, 0x63, 0xf1, 0x01, 0xe5, 0x7e, 0x3a, 0xf2, 0x59, 0x5a, 0x78,
3405
-	0xfb, 0x97, 0x7a, 0x93, 0x34, 0xf2, 0xc5, 0x3c, 0xa5, 0x99, 0x7f, 0xc8, 0xf8, 0x3e, 0xe5, 0x1a,
3406
-	0xf0, 0xe8, 0x52, 0xc0, 0x4c, 0x44, 0xb1, 0x44, 0x8d, 0x49, 0x9a, 0xc9, 0x24, 0xf2, 0x37, 0x07,
3407
-	0x39, 0xff, 0x19, 0x50, 0xc3, 0x34, 0x9b, 0xc5, 0x02, 0x21, 0x30, 0x39, 0x0d, 0x2c, 0xa3, 0x6b,
3408
-	0xb8, 0x8d, 0x57, 0x2b, 0x58, 0x1a, 0xe8, 0x31, 0x54, 0x38, 0x0d, 0x32, 0x6b, 0xb5, 0x6b, 0xb8,
3409
-	0xcd, 0xde, 0xa7, 0xde, 0xa5, 0xf5, 0xf3, 0x30, 0x0d, 0x76, 0x49, 0xfa, 0x6a, 0x05, 0x2b, 0x00,
3410
-	0xfa, 0x01, 0xea, 0x53, 0x2a, 0xc8, 0x84, 0x08, 0x62, 0x41, 0xd7, 0x74, 0x9b, 0x3d, 0x7f, 0x29,
3411
-	0x58, 0x32, 0xf0, 0x76, 0x35, 0xe2, 0x65, 0x22, 0xf8, 0x1c, 0x2f, 0x02, 0xd8, 0xcf, 0xa0, 0x7d,
3412
-	0xea, 0x13, 0xea, 0x80, 0xb9, 0x4f, 0xe7, 0x39, 0x55, 0x2c, 0x97, 0xe8, 0x63, 0xa8, 0x1e, 0x90,
3413
-	0x78, 0x46, 0x15, 0xd3, 0x16, 0xce, 0x8d, 0xa7, 0xab, 0x4f, 0x8c, 0x7e, 0x1d, 0x6a, 0x5c, 0x85,
3414
-	0x77, 0xfe, 0x54, 0x67, 0x95, 0x34, 0xd1, 0xb7, 0xfa, 0x5c, 0x86, 0xa2, 0x76, 0xff, 0xca, 0x73,
3415
-	0xc9, 0x9f, 0x2c, 0xa7, 0xa5, 0x80, 0xf6, 0x63, 0x68, 0x2c, 0xb6, 0xae, 0xa2, 0xd3, 0x28, 0xd1,
3416
-	0x71, 0x04, 0xb4, 0x31, 0x15, 0x33, 0x9e, 0x60, 0xfa, 0xcb, 0x8c, 0x66, 0x02, 0x7d, 0x53, 0xf0,
3417
-	0x53, 0xf8, 0xab, 0x8a, 0x2c, 0x1d, 0xb1, 0x06, 0x20, 0x17, 0xaa, 0x94, 0x73, 0xc6, 0x75, 0x7b,
3418
-	0x90, 0x97, 0x2b, 0xcf, 0xe3, 0xe9, 0xd8, 0x7b, 0xa3, 0x94, 0x87, 0x73, 0x07, 0xa7, 0x03, 0xb7,
3419
-	0x8a, 0xac, 0x59, 0xca, 0x92, 0x8c, 0x3a, 0x7f, 0x19, 0x70, 0x1b, 0x53, 0x25, 0xbc, 0x9d, 0x29,
3420
-	0x09, 0xe9, 0x26, 0x4b, 0x82, 0x28, 0x2c, 0x48, 0x75, 0xc0, 0xc4, 0x85, 0x16, 0xb0, 0x5c, 0x22,
3421
-	0x17, 0xea, 0xc3, 0x98, 0x88, 0x80, 0xf1, 0xa9, 0x4e, 0xd7, 0xf2, 0xd2, 0x91, 0x57, 0xec, 0xe1,
3422
-	0xc5, 0x57, 0xd4, 0x85, 0xa6, 0x0e, 0xbc, 0xcb, 0x26, 0xd4, 0x32, 0x55, 0x8c, 0xf2, 0x16, 0xb2,
3423
-	0x60, 0x6d, 0xc0, 0xc2, 0x1f, 0xc9, 0x94, 0x5a, 0x15, 0xf5, 0xb5, 0x30, 0x9d, 0xdf, 0x0d, 0xb0,
3424
-	0x2f, 0x62, 0x95, 0x93, 0x46, 0xdf, 0x43, 0x6d, 0x2b, 0x0a, 0x69, 0x96, 0xd7, 0xaa, 0xd1, 0xef,
3425
-	0x7d, 0x38, 0xba, 0xb3, 0xf2, 0xcf, 0xd1, 0x9d, 0x7b, 0x25, 0xe9, 0xb3, 0x94, 0x26, 0x63, 0x96,
3426
-	0x08, 0x12, 0x25, 0x94, 0xcb, 0x61, 0x7c, 0x38, 0x51, 0x10, 0x2f, 0x47, 0x62, 0x1d, 0x01, 0x7d,
3427
-	0x02, 0xb5, 0x3c, 0xba, 0x96, 0x8c, 0xb6, 0x9c, 0xf7, 0x26, 0xb4, 0xde, 0x48, 0x02, 0x45, 0x2d,
3428
-	0x3c, 0x80, 0x2d, 0x1a, 0x44, 0x49, 0x24, 0x22, 0x96, 0xe8, 0x26, 0xdd, 0x92, 0x67, 0x3f, 0xd9,
3429
-	0xc5, 0x25, 0x0f, 0x64, 0x43, 0x7d, 0x5b, 0x37, 0x4c, 0xb7, 0x7f, 0x61, 0xa3, 0x77, 0xd0, 0x2c,
3430
-	0xd6, 0xaf, 0x53, 0x61, 0x99, 0x4a, 0x7e, 0x4f, 0x96, 0x74, 0xbc, 0xcc, 0xc4, 0x2b, 0x41, 0x73,
3431
-	0x2d, 0x96, 0x83, 0x21, 0x17, 0xd6, 0x77, 0xa6, 0x29, 0xe3, 0x62, 0x93, 0x8c, 0xf7, 0xa8, 0x54,
3432
-	0xa7, 0x55, 0xe9, 0x9a, 0x6e, 0x03, 0x9f, 0xdd, 0x46, 0x0f, 0xe0, 0x23, 0x12, 0xc7, 0xec, 0x50,
3433
-	0xcb, 0x49, 0x09, 0xc3, 0xaa, 0x76, 0x0d, 0xb7, 0x8e, 0xcf, 0x7f, 0x90, 0x5a, 0xde, 0x8e, 0x12,
3434
-	0x12, 0x5b, 0xa0, 0x3c, 0x72, 0x03, 0x39, 0xd0, 0x7a, 0xf9, 0xab, 0x0c, 0x4b, 0xf9, 0x0b, 0x21,
3435
-	0xb8, 0xd5, 0x54, 0x45, 0x3c, 0xb5, 0x67, 0x3f, 0x87, 0xce, 0x59, 0xca, 0x37, 0x9a, 0x95, 0x9f,
3436
-	0xa0, 0xad, 0xcf, 0xaf, 0xfb, 0xdf, 0x29, 0x5d, 0x51, 0xf9, 0x05, 0x75, 0x32, 0x3d, 0xe6, 0x0d,
3437
-	0xa7, 0xc7, 0xf9, 0x0d, 0xd6, 0x31, 0x25, 0x93, 0xed, 0x28, 0xa6, 0x97, 0xcb, 0x5e, 0x36, 0x33,
3438
-	0x8a, 0xe9, 0x90, 0x88, 0xbd, 0x45, 0x33, 0xb5, 0x8d, 0x9e, 0x42, 0x15, 0x93, 0x24, 0xa4, 0x3a,
3439
-	0xf5, 0x67, 0x4b, 0x52, 0xab, 0x24, 0xd2, 0x17, 0xe7, 0x10, 0xe7, 0x19, 0x34, 0x16, 0x7b, 0x52,
3440
-	0x8a, 0xaf, 0x83, 0x20, 0xa3, 0xb9, 0xac, 0x4d, 0xac, 0x2d, 0xb9, 0x3f, 0xa0, 0x49, 0xa8, 0x53,
3441
-	0x9b, 0x58, 0x5b, 0xce, 0x5d, 0xe8, 0x9c, 0x30, 0xd7, 0xa5, 0x41, 0x50, 0xd9, 0x92, 0x97, 0xad,
3442
-	0xa1, 0xfa, 0xa0, 0xd6, 0x4e, 0x1b, 0x9a, 0xc3, 0x28, 0x29, 0x86, 0xda, 0x39, 0x36, 0xa0, 0x35,
3443
-	0x64, 0xc9, 0xc9, 0x38, 0x0d, 0x61, 0xbd, 0xe8, 0xcf, 0x8b, 0xe1, 0xce, 0x26, 0x49, 0x8b, 0x0b,
3444
-	0xb1, 0x7b, 0xfe, 0x28, 0xfa, 0xf9, 0xf0, 0x72, 0xc7, 0x7e, 0x45, 0x4e, 0x1e, 0x3e, 0x0b, 0x47,
3445
-	0xdf, 0xc1, 0xda, 0x60, 0xd0, 0x57, 0x91, 0x56, 0x6f, 0x14, 0xa9, 0x80, 0xa1, 0xe7, 0xb0, 0xf6,
3446
-	0x56, 0xbd, 0x6a, 0x99, 0x9e, 0x8e, 0x0b, 0xca, 0xaa, 0x1e, 0x3f, 0x2f, 0x77, 0xc3, 0x74, 0xcc,
3447
-	0xf8, 0x04, 0x17, 0xa0, 0xde, 0xfb, 0x0a, 0x34, 0x06, 0x83, 0x7e, 0x9f, 0x47, 0x93, 0x90, 0xa2,
3448
-	0x3f, 0x0c, 0x40, 0xe7, 0xef, 0x13, 0xf4, 0xd5, 0x72, 0x95, 0x5c, 0x7c, 0x29, 0xda, 0x5f, 0xdf,
3449
-	0x10, 0xa5, 0xab, 0xfc, 0x0e, 0xaa, 0x4a, 0xc5, 0xe8, 0xf3, 0x6b, 0xce, 0xb9, 0xed, 0x5e, 0xed,
3450
-	0xa8, 0x63, 0x8f, 0xa1, 0x5e, 0x28, 0x01, 0xdd, 0x5b, 0x4a, 0xef, 0x94, 0xd0, 0xed, 0xfb, 0xd7,
3451
-	0xf2, 0xd5, 0x49, 0xde, 0x42, 0x45, 0xca, 0x08, 0xdd, 0x5d, 0x02, 0x2a, 0xe9, 0xcc, 0x5e, 0x76,
3452
-	0xce, 0x53, 0xfa, 0xfb, 0x59, 0xbe, 0xc7, 0xea, 0x8e, 0x71, 0x97, 0xf2, 0x29, 0x3d, 0x97, 0xf6,
3453
-	0x17, 0xd7, 0xf0, 0xcc, 0xc3, 0xf7, 0x5b, 0x1f, 0x8e, 0x37, 0x8c, 0xbf, 0x8f, 0x37, 0x8c, 0x7f,
3454
-	0x8f, 0x37, 0x8c, 0x51, 0x4d, 0xfd, 0xe1, 0x79, 0xf4, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f,
3455
-	0xfd, 0x24, 0x08, 0x13, 0x0a, 0x00, 0x00,
3392
+	// 1144 bytes of a gzipped FileDescriptorProto
3393
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xcf, 0x4f, 0x1b, 0xc7,
3394
+	0x17, 0x67, 0xb1, 0x8d, 0xed, 0x67, 0x03, 0xfe, 0x8e, 0xbe, 0xaa, 0x36, 0x7b, 0x20, 0xee, 0xaa,
3395
+	0xa2, 0x0e, 0x21, 0xbb, 0x2a, 0x69, 0x45, 0x4a, 0xa4, 0xa4, 0x31, 0x04, 0x85, 0xd6, 0x34, 0xd6,
3396
+	0xe4, 0x10, 0x29, 0x6a, 0xa5, 0xae, 0xed, 0xf1, 0x32, 0x62, 0xbd, 0xb3, 0x9d, 0x1d, 0x43, 0x51,
3397
+	0x2f, 0x6d, 0x4f, 0xbd, 0xf7, 0x9f, 0xca, 0xad, 0x3d, 0xf7, 0x10, 0x55, 0xdc, 0xfa, 0x5f, 0x54,
3398
+	0xf3, 0x63, 0xed, 0xc5, 0x80, 0x81, 0xd3, 0xce, 0x9b, 0x79, 0x9f, 0xf7, 0x3e, 0x6f, 0xde, 0x8f,
3399
+	0x59, 0x58, 0x0e, 0x03, 0x41, 0x4e, 0x83, 0x33, 0x2f, 0xe1, 0x4c, 0x30, 0x74, 0x6f, 0xc4, 0x7a,
3400
+	0x67, 0x5e, 0x6f, 0x4c, 0xa3, 0xc1, 0x31, 0x15, 0xde, 0xc9, 0x67, 0xde, 0x90, 0xb3, 0x58, 0x90,
3401
+	0x78, 0xe0, 0x3c, 0x0a, 0xa9, 0x38, 0x1a, 0xf7, 0xbc, 0x3e, 0x1b, 0xf9, 0x21, 0x0b, 0x99, 0xaf,
3402
+	0x10, 0xbd, 0xf1, 0x50, 0x49, 0x4a, 0x50, 0x2b, 0x6d, 0xc9, 0xd9, 0x9a, 0x55, 0x0f, 0x19, 0x0b,
3403
+	0x23, 0x12, 0x24, 0x34, 0x35, 0x4b, 0x9f, 0x27, 0x7d, 0x3f, 0x15, 0x81, 0x18, 0xa7, 0x06, 0xb3,
3404
+	0x99, 0xc3, 0x48, 0x22, 0x7e, 0x46, 0xc4, 0x4f, 0x59, 0x74, 0x42, 0xb8, 0x9f, 0xf4, 0x7c, 0x96,
3405
+	0x64, 0xda, 0xfe, 0xb5, 0xda, 0x41, 0x42, 0x7d, 0x71, 0x96, 0x90, 0xd4, 0x3f, 0x65, 0xfc, 0x98,
3406
+	0x70, 0x03, 0x78, 0x7c, 0x2d, 0x60, 0x2c, 0x68, 0x24, 0x51, 0xfd, 0x20, 0x49, 0xa5, 0x13, 0xf9,
3407
+	0x35, 0xa0, 0x7c, 0xd8, 0x82, 0xc5, 0x34, 0x15, 0x94, 0x86, 0xd4, 0x1f, 0xa6, 0x0a, 0xa3, 0xbd,
3408
+	0xc8, 0x20, 0xb4, 0xba, 0xfb, 0xaf, 0x05, 0x4b, 0x98, 0xa4, 0xe3, 0x48, 0x20, 0x04, 0x05, 0x4e,
3409
+	0x86, 0xb6, 0xd5, 0xb4, 0x5a, 0xd5, 0x57, 0x0b, 0x58, 0x0a, 0x68, 0x1b, 0x8a, 0x9c, 0x0c, 0x53,
3410
+	0x7b, 0xb1, 0x69, 0xb5, 0x6a, 0x5b, 0x1f, 0x7b, 0xd7, 0x5e, 0xb7, 0x87, 0xc9, 0xf0, 0x30, 0x48,
3411
+	0x5e, 0x2d, 0x60, 0x05, 0x40, 0xdf, 0x40, 0x65, 0x44, 0x44, 0x30, 0x08, 0x44, 0x60, 0x43, 0xb3,
3412
+	0xd0, 0xaa, 0x6d, 0xf9, 0x73, 0xc1, 0x92, 0x81, 0x77, 0x68, 0x10, 0x2f, 0x63, 0xc1, 0xcf, 0xf0,
3413
+	0xc4, 0x80, 0xf3, 0x14, 0x96, 0x2f, 0x1c, 0xa1, 0x06, 0x14, 0x8e, 0xc9, 0x99, 0xa6, 0x8a, 0xe5,
3414
+	0x12, 0xfd, 0x1f, 0x4a, 0x27, 0x41, 0x34, 0x26, 0x8a, 0x69, 0x1d, 0x6b, 0x61, 0x67, 0xf1, 0x89,
3415
+	0xd5, 0xae, 0xc0, 0x12, 0x57, 0xe6, 0xdd, 0xdf, 0x54, 0xac, 0x92, 0x26, 0x7a, 0x6e, 0xe2, 0xb2,
3416
+	0x14, 0xb5, 0x87, 0x37, 0xc6, 0x25, 0x3f, 0xa9, 0xa6, 0xa5, 0x80, 0xce, 0x36, 0x54, 0x27, 0x5b,
3417
+	0x37, 0xd1, 0xa9, 0xe6, 0xe8, 0xb8, 0x02, 0x96, 0x31, 0x11, 0x63, 0x1e, 0x63, 0xf2, 0xe3, 0x98,
3418
+	0xa4, 0x02, 0x7d, 0x99, 0xf1, 0x53, 0xf8, 0x9b, 0x2e, 0x59, 0x2a, 0x62, 0x03, 0x40, 0x2d, 0x28,
3419
+	0x11, 0xce, 0x19, 0x37, 0xe9, 0x41, 0x9e, 0x2e, 0x54, 0x8f, 0x27, 0x7d, 0xef, 0x8d, 0x2a, 0x54,
3420
+	0xac, 0x15, 0xdc, 0x06, 0xac, 0x64, 0x5e, 0xd3, 0x84, 0xc5, 0x29, 0x71, 0xff, 0xb0, 0xe0, 0x1e,
3421
+	0x26, 0xaa, 0x4e, 0x0f, 0x46, 0x41, 0x48, 0x76, 0x59, 0x3c, 0xa4, 0x61, 0x46, 0xaa, 0x01, 0x05,
3422
+	0x9c, 0xd5, 0x02, 0x96, 0x4b, 0xd4, 0x82, 0x4a, 0x37, 0x0a, 0xc4, 0x90, 0xf1, 0x91, 0x71, 0x57,
3423
+	0xf7, 0x92, 0x9e, 0x97, 0xed, 0xe1, 0xc9, 0x29, 0x6a, 0x42, 0xcd, 0x18, 0x3e, 0x64, 0x03, 0x62,
3424
+	0x17, 0x94, 0x8d, 0xfc, 0x16, 0xb2, 0xa1, 0xdc, 0x61, 0xe1, 0xb7, 0xc1, 0x88, 0xd8, 0x45, 0x75,
3425
+	0x9a, 0x89, 0xee, 0x2f, 0x16, 0x38, 0x57, 0xb1, 0xd2, 0xa4, 0xd1, 0xd7, 0xb0, 0xb4, 0x47, 0x43,
3426
+	0x92, 0xea, 0xbb, 0xaa, 0xb6, 0xb7, 0xde, 0x7f, 0xb8, 0xbf, 0xf0, 0xf7, 0x87, 0xfb, 0x1b, 0xb9,
3427
+	0xa2, 0x67, 0x09, 0x89, 0xfb, 0x2c, 0x16, 0x01, 0x8d, 0x09, 0x97, 0xbd, 0xfb, 0x68, 0xa0, 0x20,
3428
+	0x9e, 0x46, 0x62, 0x63, 0x01, 0x7d, 0x04, 0x4b, 0xda, 0xba, 0x29, 0x19, 0x23, 0xb9, 0xbf, 0x17,
3429
+	0xa0, 0xfe, 0x46, 0x12, 0xc8, 0xee, 0xc2, 0x03, 0xd8, 0x23, 0x43, 0x1a, 0x53, 0x41, 0x59, 0x6c,
3430
+	0x92, 0xb4, 0x22, 0x63, 0x9f, 0xee, 0xe2, 0x9c, 0x06, 0x72, 0xa0, 0xb2, 0x6f, 0x12, 0x66, 0xd2,
3431
+	0x3f, 0x91, 0xd1, 0x3b, 0xa8, 0x65, 0xeb, 0xd7, 0x89, 0xb0, 0x0b, 0xaa, 0xfc, 0x9e, 0xcc, 0xc9,
3432
+	0x78, 0x9e, 0x89, 0x97, 0x83, 0xea, 0x5a, 0xcc, 0x1b, 0x43, 0x2d, 0x58, 0x3d, 0x18, 0x25, 0x8c,
3433
+	0x8b, 0xdd, 0xa0, 0x7f, 0x44, 0x64, 0x75, 0xda, 0xc5, 0x66, 0xa1, 0x55, 0xc5, 0xb3, 0xdb, 0x68,
3434
+	0x13, 0xfe, 0x17, 0x44, 0x11, 0x3b, 0x35, 0xe5, 0xa4, 0x0a, 0xc3, 0x2e, 0x35, 0xad, 0x56, 0x05,
3435
+	0x5f, 0x3e, 0x90, 0xb5, 0xbc, 0x4f, 0xe3, 0x20, 0xb2, 0x41, 0x69, 0x68, 0x01, 0xb9, 0x50, 0x7f,
3436
+	0xf9, 0x93, 0x34, 0x4b, 0xf8, 0x0b, 0x21, 0xb8, 0x5d, 0x53, 0x97, 0x78, 0x61, 0xcf, 0x79, 0x06,
3437
+	0x8d, 0x59, 0xca, 0x77, 0xea, 0x95, 0xef, 0x60, 0xd9, 0xc4, 0x6f, 0xf2, 0xdf, 0xc8, 0x8d, 0x28,
3438
+	0x3d, 0xa0, 0xa6, 0xdd, 0x53, 0xb8, 0x63, 0xf7, 0xb8, 0x3f, 0xc3, 0x2a, 0x26, 0xc1, 0x60, 0x9f,
3439
+	0x46, 0xe4, 0xfa, 0xb2, 0x97, 0xc9, 0xa4, 0x11, 0xe9, 0x06, 0xe2, 0x68, 0x92, 0x4c, 0x23, 0xa3,
3440
+	0x1d, 0x28, 0xe1, 0x20, 0x0e, 0x89, 0x71, 0xfd, 0xc9, 0x1c, 0xd7, 0xca, 0x89, 0xd4, 0xc5, 0x1a,
3441
+	0xe2, 0x3e, 0x85, 0xea, 0x64, 0x4f, 0x96, 0xe2, 0xeb, 0xe1, 0x30, 0x25, 0xba, 0xac, 0x0b, 0xd8,
3442
+	0x48, 0x72, 0xbf, 0x43, 0xe2, 0xd0, 0xb8, 0x2e, 0x60, 0x23, 0xb9, 0xeb, 0xd0, 0x98, 0x32, 0x37,
3443
+	0x57, 0x83, 0xa0, 0xb8, 0x27, 0x87, 0xad, 0xa5, 0xf2, 0xa0, 0xd6, 0xee, 0x40, 0x76, 0x7d, 0x30,
3444
+	0xd8, 0xa3, 0xfc, 0xfa, 0x00, 0x6d, 0x28, 0xef, 0x51, 0x9e, 0x8b, 0x2f, 0x13, 0xd1, 0x3a, 0xac,
3445
+	0x1c, 0xc4, 0xfd, 0x68, 0x3c, 0x90, 0xd1, 0x0a, 0xc2, 0x63, 0xd3, 0xca, 0x33, 0xbb, 0xee, 0x73,
3446
+	0x7d, 0x8f, 0xca, 0x8b, 0x21, 0xb3, 0x09, 0x65, 0x12, 0x0b, 0x4e, 0x49, 0x36, 0x61, 0x91, 0xa7,
3447
+	0x1f, 0x20, 0x4f, 0x3d, 0x40, 0x6a, 0x38, 0xe1, 0x4c, 0xc5, 0xdd, 0x86, 0x55, 0xb9, 0x31, 0x3f,
3448
+	0x11, 0x08, 0x8a, 0x39, 0x92, 0x6a, 0xed, 0xee, 0x40, 0x63, 0x0a, 0x34, 0xae, 0xd7, 0xa1, 0x28,
3449
+	0x9f, 0x37, 0xd3, 0xa7, 0x57, 0xf9, 0x55, 0xe7, 0xee, 0x32, 0xd4, 0xba, 0x34, 0xce, 0x06, 0x9e,
3450
+	0x7b, 0x6e, 0x41, 0xbd, 0xcb, 0xe2, 0xe9, 0xa8, 0xe9, 0xc2, 0x6a, 0x56, 0xbb, 0x2f, 0xba, 0x07,
3451
+	0xbb, 0x41, 0x92, 0x85, 0xd2, 0xbc, 0x9c, 0x66, 0xf3, 0x12, 0x7b, 0x5a, 0xb1, 0x5d, 0x94, 0x53,
3452
+	0x09, 0xcf, 0xc2, 0xd1, 0x57, 0x50, 0xee, 0x74, 0xda, 0xca, 0xd2, 0xe2, 0x9d, 0x2c, 0x65, 0x30,
3453
+	0xf4, 0x0c, 0xca, 0x6f, 0xd5, 0x0f, 0x42, 0x6a, 0x26, 0xc7, 0x15, 0x25, 0xa7, 0x03, 0xd5, 0x6a,
3454
+	0x98, 0xf4, 0x19, 0x1f, 0xe0, 0x0c, 0xb4, 0xf5, 0x67, 0x09, 0xaa, 0x9d, 0x4e, 0xbb, 0xcd, 0xe9,
3455
+	0x20, 0x24, 0xe8, 0x57, 0x0b, 0xd0, 0xe5, 0x59, 0x8b, 0x3e, 0x9f, 0xdf, 0x41, 0x57, 0x3f, 0x18,
3456
+	0xce, 0x17, 0x77, 0x44, 0x99, 0x5b, 0x7e, 0x07, 0x25, 0xd5, 0xe1, 0xe8, 0xd3, 0x5b, 0xce, 0x40,
3457
+	0xa7, 0x75, 0xb3, 0xa2, 0xb1, 0xdd, 0x87, 0x4a, 0xd6, 0x25, 0x68, 0x63, 0x2e, 0xbd, 0x0b, 0x43,
3458
+	0xc0, 0x79, 0x78, 0x2b, 0x5d, 0xe3, 0xe4, 0x07, 0x28, 0x9b, 0xe2, 0x47, 0x0f, 0x6e, 0xc0, 0x4d,
3459
+	0xdb, 0xd0, 0xd9, 0xb8, 0x8d, 0xea, 0x34, 0x8c, 0xac, 0xc8, 0xe7, 0x86, 0x31, 0xd3, 0x42, 0x73,
3460
+	0xc3, 0xb8, 0xd4, 0x35, 0x6f, 0xa1, 0x28, 0xbb, 0x01, 0xad, 0xcf, 0x01, 0xe5, 0xda, 0xc5, 0x99,
3461
+	0x97, 0xae, 0x0b, 0x6d, 0xf4, 0xbd, 0xfc, 0xe5, 0x52, 0xcf, 0x48, 0x6b, 0x6e, 0xcc, 0xb9, 0x3f,
3462
+	0x22, 0xe7, 0xc1, 0x2d, 0x34, 0xb5, 0xf9, 0x76, 0xfd, 0xfd, 0xf9, 0x9a, 0xf5, 0xd7, 0xf9, 0x9a,
3463
+	0xf5, 0xcf, 0xf9, 0x9a, 0xd5, 0x5b, 0x52, 0xff, 0xb4, 0x8f, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff,
3464
+	0x80, 0x7e, 0xd2, 0xb5, 0x25, 0x0c, 0x00, 0x00,
3456 3465
 }
... ...
@@ -7,6 +7,7 @@ import "github.com/gogo/googleapis/google/rpc/status.proto";
7 7
 import "github.com/moby/buildkit/solver/pb/ops.proto";
8 8
 import "github.com/moby/buildkit/api/types/worker.proto";
9 9
 import "github.com/moby/buildkit/util/apicaps/pb/caps.proto";
10
+import "github.com/tonistiigi/fsutil/types/stat.proto";
10 11
 
11 12
 option (gogoproto.sizer_all) = true;
12 13
 option (gogoproto.marshaler_all) = true;
... ...
@@ -19,6 +20,10 @@ service LLBBridge {
19 19
 	rpc Solve(SolveRequest) returns (SolveResponse);
20 20
 	// apicaps:CapReadFile
21 21
 	rpc ReadFile(ReadFileRequest) returns (ReadFileResponse);
22
+	// apicaps:CapReadDir
23
+	rpc ReadDir(ReadDirRequest) returns (ReadDirResponse);
24
+	// apicaps:CapStatFile
25
+	rpc StatFile(StatFileRequest) returns (StatFileResponse);
22 26
 	rpc Ping(PingRequest) returns (PongResponse);
23 27
 	rpc Return(ReturnRequest) returns (ReturnResponse);
24 28
 }
... ...
@@ -92,6 +97,25 @@ message ReadFileResponse {
92 92
 	bytes Data = 1;
93 93
 }
94 94
 
95
+message ReadDirRequest {
96
+	string Ref = 1;
97
+	string DirPath = 2;
98
+	string IncludePattern = 3;
99
+}
100
+
101
+message ReadDirResponse {
102
+	repeated fsutil.types.Stat entries = 1;
103
+}
104
+
105
+message StatFileRequest {
106
+	string Ref = 1;
107
+	string Path = 2;
108
+}
109
+
110
+message StatFileResponse {
111
+	fsutil.types.Stat stat = 1;
112
+}
113
+
95 114
 message PingRequest{
96 115
 }
97 116
 message PongResponse{
... ...
@@ -9,6 +9,7 @@ import (
9 9
 	"github.com/pkg/errors"
10 10
 	"github.com/sirupsen/logrus"
11 11
 	"github.com/tonistiigi/fsutil"
12
+	fstypes "github.com/tonistiigi/fsutil/types"
12 13
 	"google.golang.org/grpc"
13 14
 )
14 15
 
... ...
@@ -81,10 +82,10 @@ func syncTargetDiffCopy(ds grpc.Stream, dest string) error {
81 81
 	}
82 82
 	return fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{
83 83
 		Merge: true,
84
-		Filter: func() func(*fsutil.Stat) bool {
84
+		Filter: func() func(*fstypes.Stat) bool {
85 85
 			uid := os.Getuid()
86 86
 			gid := os.Getgid()
87
-			return func(st *fsutil.Stat) bool {
87
+			return func(st *fstypes.Stat) bool {
88 88
 				st.Uid = uint32(uid)
89 89
 				st.Gid = uint32(gid)
90 90
 				return true
... ...
@@ -10,6 +10,7 @@ import (
10 10
 	"github.com/moby/buildkit/session"
11 11
 	"github.com/pkg/errors"
12 12
 	"github.com/tonistiigi/fsutil"
13
+	fstypes "github.com/tonistiigi/fsutil/types"
13 14
 	"google.golang.org/grpc"
14 15
 	"google.golang.org/grpc/codes"
15 16
 	"google.golang.org/grpc/metadata"
... ...
@@ -34,7 +35,7 @@ type SyncedDir struct {
34 34
 	Name     string
35 35
 	Dir      string
36 36
 	Excludes []string
37
-	Map      func(*fsutil.Stat) bool
37
+	Map      func(*fstypes.Stat) bool
38 38
 }
39 39
 
40 40
 // NewFSSyncProvider creates a new provider for sending files from client
... ...
@@ -13,6 +13,7 @@ import (
13 13
 	"github.com/moby/buildkit/util/progress"
14 14
 	"github.com/moby/buildkit/util/tracing"
15 15
 	digest "github.com/opencontainers/go-digest"
16
+	opentracing "github.com/opentracing/opentracing-go"
16 17
 	"github.com/pkg/errors"
17 18
 )
18 19
 
... ...
@@ -45,8 +46,10 @@ type state struct {
45 45
 	parents  map[digest.Digest]struct{}
46 46
 	childVtx map[digest.Digest]struct{}
47 47
 
48
-	mpw   *progress.MultiWriter
49
-	allPw map[progress.Writer]struct{}
48
+	mpw     *progress.MultiWriter
49
+	allPw   map[progress.Writer]struct{}
50
+	mspan   *tracing.MultiSpan
51
+	allSpan map[opentracing.Span]struct{}
50 52
 
51 53
 	vtx          Vertex
52 54
 	clientVertex client.Vertex
... ...
@@ -168,7 +171,7 @@ func (sb *subBuilder) Build(ctx context.Context, e Edge) (CachedResult, error) {
168 168
 }
169 169
 
170 170
 func (sb *subBuilder) Context(ctx context.Context) context.Context {
171
-	return progress.WithProgress(ctx, sb.mpw)
171
+	return opentracing.ContextWithSpan(progress.WithProgress(ctx, sb.mpw), sb.mspan)
172 172
 }
173 173
 
174 174
 func (sb *subBuilder) EachValue(ctx context.Context, key string, fn func(interface{}) error) error {
... ...
@@ -186,6 +189,7 @@ type Job struct {
186 186
 	list   *Solver
187 187
 	pr     *progress.MultiReader
188 188
 	pw     progress.Writer
189
+	span   opentracing.Span
189 190
 	values sync.Map
190 191
 
191 192
 	progressCloser func()
... ...
@@ -303,7 +307,9 @@ func (jl *Solver) loadUnlocked(v, parent Vertex, j *Job, cache map[Vertex]Vertex
303 303
 			parents:      map[digest.Digest]struct{}{},
304 304
 			childVtx:     map[digest.Digest]struct{}{},
305 305
 			allPw:        map[progress.Writer]struct{}{},
306
+			allSpan:      map[opentracing.Span]struct{}{},
306 307
 			mpw:          progress.NewMultiWriter(progress.WithMetadata("vertex", dgst)),
308
+			mspan:        tracing.NewMultiSpan(),
307 309
 			vtx:          v,
308 310
 			clientVertex: initClientVertex(v),
309 311
 			edges:        map[Index]*edge{},
... ...
@@ -357,6 +363,8 @@ func (jl *Solver) connectProgressFromState(target, src *state) {
357 357
 			target.mpw.Add(j.pw)
358 358
 			target.allPw[j.pw] = struct{}{}
359 359
 			j.pw.Write(target.clientVertex.Digest.String(), target.clientVertex)
360
+			target.mspan.Add(j.span)
361
+			target.allSpan[j.span] = struct{}{}
360 362
 		}
361 363
 	}
362 364
 	for p := range src.parents {
... ...
@@ -380,6 +388,7 @@ func (jl *Solver) NewJob(id string) (*Job, error) {
380 380
 		pr:             progress.NewMultiReader(pr),
381 381
 		pw:             pw,
382 382
 		progressCloser: progressCloser,
383
+		span:           (&opentracing.NoopTracer{}).StartSpan(""),
383 384
 	}
384 385
 	jl.jobs[id] = j
385 386
 
... ...
@@ -428,6 +437,10 @@ func (jl *Solver) deleteIfUnreferenced(k digest.Digest, st *state) {
428 428
 }
429 429
 
430 430
 func (j *Job) Build(ctx context.Context, e Edge) (CachedResult, error) {
431
+	if span := opentracing.SpanFromContext(ctx); span != nil {
432
+		j.span = span
433
+	}
434
+
431 435
 	v, err := j.list.load(e.Vertex, nil, j)
432 436
 	if err != nil {
433 437
 		return nil, err
... ...
@@ -453,6 +466,9 @@ func (j *Job) Discard() error {
453 453
 		if _, ok := st.allPw[j.pw]; ok {
454 454
 			delete(st.allPw, j.pw)
455 455
 		}
456
+		if _, ok := st.allSpan[j.span]; ok {
457
+			delete(st.allSpan, j.span)
458
+		}
456 459
 		st.mu.Unlock()
457 460
 	}
458 461
 	return nil
... ...
@@ -534,7 +550,7 @@ func (s *sharedOp) Cache() CacheManager {
534 534
 }
535 535
 
536 536
 func (s *sharedOp) LoadCache(ctx context.Context, rec *CacheRecord) (Result, error) {
537
-	ctx = progress.WithProgress(ctx, s.st.mpw)
537
+	ctx = opentracing.ContextWithSpan(progress.WithProgress(ctx, s.st.mpw), s.st.mspan)
538 538
 	// no cache hit. start evaluating the node
539 539
 	span, ctx := tracing.StartSpan(ctx, "load cache: "+s.st.vtx.Name())
540 540
 	notifyStarted(ctx, &s.st.clientVertex, true)
... ...
@@ -557,7 +573,7 @@ func (s *sharedOp) CalcSlowCache(ctx context.Context, index Index, f ResultBased
557 557
 			return err, nil
558 558
 		}
559 559
 		s.slowMu.Unlock()
560
-		ctx = progress.WithProgress(ctx, s.st.mpw)
560
+		ctx = opentracing.ContextWithSpan(progress.WithProgress(ctx, s.st.mpw), s.st.mspan)
561 561
 		key, err := f(ctx, res)
562 562
 		complete := true
563 563
 		if err != nil {
... ...
@@ -581,7 +597,7 @@ func (s *sharedOp) CalcSlowCache(ctx context.Context, index Index, f ResultBased
581 581
 		return key, err
582 582
 	})
583 583
 	if err != nil {
584
-		ctx = progress.WithProgress(ctx, s.st.mpw)
584
+		ctx = opentracing.ContextWithSpan(progress.WithProgress(ctx, s.st.mpw), s.st.mspan)
585 585
 		notifyStarted(ctx, &s.st.clientVertex, false)
586 586
 		notifyCompleted(ctx, &s.st.clientVertex, err, false)
587 587
 		return "", err
... ...
@@ -601,7 +617,7 @@ func (s *sharedOp) CacheMap(ctx context.Context, index int) (*cacheMapResp, erro
601 601
 		if s.cacheErr != nil {
602 602
 			return nil, s.cacheErr
603 603
 		}
604
-		ctx = progress.WithProgress(ctx, s.st.mpw)
604
+		ctx = opentracing.ContextWithSpan(progress.WithProgress(ctx, s.st.mpw), s.st.mspan)
605 605
 		ctx = session.NewContext(ctx, s.st.getSessionID())
606 606
 		if len(s.st.vtx.Inputs()) == 0 {
607 607
 			// no cache hit. start evaluating the node
... ...
@@ -654,7 +670,7 @@ func (s *sharedOp) Exec(ctx context.Context, inputs []Result) (outputs []Result,
654 654
 			return s.execRes, s.execErr
655 655
 		}
656 656
 
657
-		ctx = progress.WithProgress(ctx, s.st.mpw)
657
+		ctx = opentracing.ContextWithSpan(progress.WithProgress(ctx, s.st.mpw), s.st.mspan)
658 658
 		ctx = session.NewContext(ctx, s.st.getSessionID())
659 659
 
660 660
 		// no cache hit. start evaluating the node
... ...
@@ -31,6 +31,7 @@ import (
31 31
 	"github.com/moby/buildkit/solver/llbsolver"
32 32
 	"github.com/moby/buildkit/solver/pb"
33 33
 	"github.com/moby/buildkit/util/progress/logs"
34
+	utilsystem "github.com/moby/buildkit/util/system"
34 35
 	"github.com/moby/buildkit/worker"
35 36
 	digest "github.com/opencontainers/go-digest"
36 37
 	"github.com/opencontainers/runc/libcontainer/system"
... ...
@@ -467,6 +468,15 @@ func (sm *secretMountInstance) Release() error {
467 467
 	return nil
468 468
 }
469 469
 
470
+func addDefaultEnvvar(env []string, k, v string) []string {
471
+	for _, e := range env {
472
+		if strings.HasPrefix(e, k+"=") {
473
+			return env
474
+		}
475
+	}
476
+	return append(env, k+"="+v)
477
+}
478
+
470 479
 func (e *execOp) Exec(ctx context.Context, inputs []solver.Result) ([]solver.Result, error) {
471 480
 	var mounts []executor.Mount
472 481
 	var root cache.Mountable
... ...
@@ -626,6 +636,7 @@ func (e *execOp) Exec(ctx context.Context, inputs []solver.Result) ([]solver.Res
626 626
 	if e.op.Meta.ProxyEnv != nil {
627 627
 		meta.Env = append(meta.Env, proxyEnvList(e.op.Meta.ProxyEnv)...)
628 628
 	}
629
+	meta.Env = addDefaultEnvvar(meta.Env, "PATH", utilsystem.DefaultPathEnv)
629 630
 
630 631
 	stdout, stderr := logs.NewLogStreams(ctx, os.Getenv("BUILDKIT_DEBUG_EXEC_OUTPUT") == "1")
631 632
 	defer stdout.Close()
... ...
@@ -30,15 +30,18 @@ const (
30 30
 
31 31
 	CapBuildOpLLBFileName apicaps.CapID = "source.buildop.llbfilename"
32 32
 
33
-	CapExecMetaBase          apicaps.CapID = "exec.meta.base"
34
-	CapExecMetaProxy         apicaps.CapID = "exec.meta.proxyenv"
35
-	CapExecMetaNetwork       apicaps.CapID = "exec.meta.network"
36
-	CapExecMountBind         apicaps.CapID = "exec.mount.bind"
37
-	CapExecMountCache        apicaps.CapID = "exec.mount.cache"
38
-	CapExecMountCacheSharing apicaps.CapID = "exec.mount.cache.sharing"
39
-	CapExecMountSelector     apicaps.CapID = "exec.mount.selector"
40
-	CapExecMountTmpfs        apicaps.CapID = "exec.mount.tmpfs"
41
-	CapMountSecret           apicaps.CapID = "exec.mount.secret"
33
+	CapExecMetaBase            apicaps.CapID = "exec.meta.base"
34
+	CapExecMetaProxy           apicaps.CapID = "exec.meta.proxyenv"
35
+	CapExecMetaNetwork         apicaps.CapID = "exec.meta.network"
36
+	CapExecMetaSetsDefaultPath apicaps.CapID = "exec.meta.setsdefaultpath"
37
+	CapExecMountBind           apicaps.CapID = "exec.mount.bind"
38
+	CapExecMountCache          apicaps.CapID = "exec.mount.cache"
39
+	CapExecMountCacheSharing   apicaps.CapID = "exec.mount.cache.sharing"
40
+	CapExecMountSelector       apicaps.CapID = "exec.mount.selector"
41
+	CapExecMountTmpfs          apicaps.CapID = "exec.mount.tmpfs"
42
+	CapExecMountSecret         apicaps.CapID = "exec.mount.secret"
43
+	CapExecMountSSH            apicaps.CapID = "exec.mount.ssh"
44
+	CapExecCgroupsMounted      apicaps.CapID = "exec.cgroup"
42 45
 
43 46
 	CapConstraints apicaps.CapID = "constraints"
44 47
 	CapPlatform    apicaps.CapID = "platform"
... ...
@@ -170,6 +173,12 @@ func init() {
170 170
 	})
171 171
 
172 172
 	Caps.Init(apicaps.Cap{
173
+		ID:      CapExecMetaSetsDefaultPath,
174
+		Enabled: true,
175
+		Status:  apicaps.CapStatusExperimental,
176
+	})
177
+
178
+	Caps.Init(apicaps.Cap{
173 179
 		ID:      CapExecMountBind,
174 180
 		Enabled: true,
175 181
 		Status:  apicaps.CapStatusExperimental,
... ...
@@ -200,7 +209,19 @@ func init() {
200 200
 	})
201 201
 
202 202
 	Caps.Init(apicaps.Cap{
203
-		ID:      CapMountSecret,
203
+		ID:      CapExecMountSecret,
204
+		Enabled: true,
205
+		Status:  apicaps.CapStatusExperimental,
206
+	})
207
+
208
+	Caps.Init(apicaps.Cap{
209
+		ID:      CapExecMountSSH,
210
+		Enabled: true,
211
+		Status:  apicaps.CapStatusExperimental,
212
+	})
213
+
214
+	Caps.Init(apicaps.Cap{
215
+		ID:      CapExecCgroupsMounted,
204 216
 		Enabled: true,
205 217
 		Status:  apicaps.CapStatusExperimental,
206 218
 	})
... ...
@@ -15,7 +15,10 @@ import (
15 15
 // flightcontrol is like singleflight but with support for cancellation and
16 16
 // nested progress reporting
17 17
 
18
-var errRetry = errors.Errorf("retry")
18
+var (
19
+	errRetry        = errors.Errorf("retry")
20
+	errRetryTimeout = errors.Errorf("exceeded retry timeout")
21
+)
19 22
 
20 23
 type contextKeyT string
21 24
 
... ...
@@ -29,12 +32,28 @@ type Group struct {
29 29
 
30 30
 // Do executes a context function syncronized by the key
31 31
 func (g *Group) Do(ctx context.Context, key string, fn func(ctx context.Context) (interface{}, error)) (v interface{}, err error) {
32
-	defer func() {
33
-		if errors.Cause(err) == errRetry {
34
-			runtime.Gosched()
35
-			v, err = g.Do(ctx, key, fn)
32
+	var backoff time.Duration
33
+	for {
34
+		v, err = g.do(ctx, key, fn)
35
+		if err == nil || errors.Cause(err) != errRetry {
36
+			return v, err
36 37
 		}
37
-	}()
38
+		// backoff logic
39
+		if backoff >= 3*time.Second {
40
+			err = errors.Wrapf(errRetryTimeout, "flightcontrol")
41
+			return v, err
42
+		}
43
+		runtime.Gosched()
44
+		if backoff > 0 {
45
+			time.Sleep(backoff)
46
+			backoff *= 2
47
+		} else {
48
+			backoff = time.Millisecond
49
+		}
50
+	}
51
+}
52
+
53
+func (g *Group) do(ctx context.Context, key string, fn func(ctx context.Context) (interface{}, error)) (interface{}, error) {
38 54
 	g.mu.Lock()
39 55
 	if g.m == nil {
40 56
 		g.m = make(map[string]*call)
41 57
new file mode 100644
... ...
@@ -0,0 +1,22 @@
0
+package tracing
1
+
2
+import (
3
+	opentracing "github.com/opentracing/opentracing-go"
4
+)
5
+
6
+// MultiSpan allows shared tracing to multiple spans.
7
+// TODO: This is a temporary solution and doesn't really support shared tracing yet. Instead the first always wins.
8
+
9
+type MultiSpan struct {
10
+	opentracing.Span
11
+}
12
+
13
+func NewMultiSpan() *MultiSpan {
14
+	return &MultiSpan{}
15
+}
16
+
17
+func (ms *MultiSpan) Add(s opentracing.Span) {
18
+	if ms.Span == nil {
19
+		ms.Span = s
20
+	}
21
+}
... ...
@@ -40,7 +40,7 @@ golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631
40 40
 github.com/docker/docker 71cd53e4a197b303c6ba086bd584ffd67a884281
41 41
 github.com/pkg/profile 5b67d428864e92711fcbd2f8629456121a56d91f
42 42
 
43
-github.com/tonistiigi/fsutil 7e391b0e788f9b925f22bd3cf88e0210d1643673
43
+github.com/tonistiigi/fsutil f567071bed2416e4d87d260d3162722651182317
44 44
 github.com/hashicorp/go-immutable-radix 826af9ccf0feeee615d546d69b11f8e98da8c8f1 git://github.com/tonistiigi/go-immutable-radix.git
45 45
 github.com/hashicorp/golang-lru a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4
46 46
 github.com/mitchellh/hashstructure 2bca23e0e452137f789efbc8610126fd8b94f73b
... ...
@@ -4,6 +4,8 @@ import (
4 4
 	"context"
5 5
 	"hash"
6 6
 	"os"
7
+
8
+	"github.com/tonistiigi/fsutil/types"
7 9
 )
8 10
 
9 11
 type walkerFn func(ctx context.Context, pathC chan<- *currentPath) error
... ...
@@ -14,7 +16,7 @@ func Changes(ctx context.Context, a, b walkerFn, changeFn ChangeFunc) error {
14 14
 
15 15
 type HandleChangeFn func(ChangeKind, string, os.FileInfo, error) error
16 16
 
17
-type ContentHasher func(*Stat) (hash.Hash, error)
17
+type ContentHasher func(*types.Stat) (hash.Hash, error)
18 18
 
19 19
 func GetWalkerFn(root string) walkerFn {
20 20
 	return func(ctx context.Context, pathC chan<- *currentPath) error {
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"os"
6 6
 	"strings"
7 7
 
8
+	"github.com/tonistiigi/fsutil/types"
8 9
 	"golang.org/x/sync/errgroup"
9 10
 )
10 11
 
... ...
@@ -170,11 +171,11 @@ func sameFile(f1, f2 *currentPath) (same bool, retErr error) {
170 170
 		}
171 171
 	}
172 172
 
173
-	ls1, ok := f1.f.Sys().(*Stat)
173
+	ls1, ok := f1.f.Sys().(*types.Stat)
174 174
 	if !ok {
175 175
 		return false, nil
176 176
 	}
177
-	ls2, ok := f2.f.Sys().(*Stat)
177
+	ls2, ok := f2.f.Sys().(*types.Stat)
178 178
 	if !ok {
179 179
 		return false, nil
180 180
 	}
... ...
@@ -185,7 +186,7 @@ func sameFile(f1, f2 *currentPath) (same bool, retErr error) {
185 185
 // compareStat returns whether the stats are equivalent,
186 186
 // whether the files are considered the same file, and
187 187
 // an error
188
-func compareStat(ls1, ls2 *Stat) (bool, error) {
188
+func compareStat(ls1, ls2 *types.Stat) (bool, error) {
189 189
 	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
190 190
 }
191 191
 
... ...
@@ -12,6 +12,7 @@ import (
12 12
 
13 13
 	"github.com/opencontainers/go-digest"
14 14
 	"github.com/pkg/errors"
15
+	"github.com/tonistiigi/fsutil/types"
15 16
 	"golang.org/x/sync/errgroup"
16 17
 )
17 18
 
... ...
@@ -25,7 +26,7 @@ type DiskWriterOpt struct {
25 25
 	Filter        FilterFunc
26 26
 }
27 27
 
28
-type FilterFunc func(*Stat) bool
28
+type FilterFunc func(*types.Stat) bool
29 29
 
30 30
 type DiskWriter struct {
31 31
 	opt  DiskWriterOpt
... ...
@@ -95,7 +96,7 @@ func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, er
95 95
 		return nil
96 96
 	}
97 97
 
98
-	stat, ok := fi.Sys().(*Stat)
98
+	stat, ok := fi.Sys().(*types.Stat)
99 99
 	if !ok {
100 100
 		return errors.Errorf("%s invalid change without stat information", p)
101 101
 	}
... ...
@@ -246,7 +247,7 @@ type hashedWriter struct {
246 246
 }
247 247
 
248 248
 func newHashWriter(ch ContentHasher, fi os.FileInfo, w io.WriteCloser) (*hashedWriter, error) {
249
-	stat, ok := fi.Sys().(*Stat)
249
+	stat, ok := fi.Sys().(*types.Stat)
250 250
 	if !ok {
251 251
 		return nil, errors.Errorf("invalid change without stat information")
252 252
 	}
... ...
@@ -8,9 +8,10 @@ import (
8 8
 
9 9
 	"github.com/containerd/continuity/sysx"
10 10
 	"github.com/pkg/errors"
11
+	"github.com/tonistiigi/fsutil/types"
11 12
 )
12 13
 
13
-func rewriteMetadata(p string, stat *Stat) error {
14
+func rewriteMetadata(p string, stat *types.Stat) error {
14 15
 	for key, value := range stat.Xattrs {
15 16
 		sysx.Setxattr(p, key, value, 0)
16 17
 	}
... ...
@@ -34,7 +35,7 @@ func rewriteMetadata(p string, stat *Stat) error {
34 34
 
35 35
 // handleTarTypeBlockCharFifo is an OS-specific helper function used by
36 36
 // createTarFile to handle the following types of header: Block; Char; Fifo
37
-func handleTarTypeBlockCharFifo(path string, stat *Stat) error {
37
+func handleTarTypeBlockCharFifo(path string, stat *types.Stat) error {
38 38
 	mode := uint32(stat.Mode & 07777)
39 39
 	if os.FileMode(stat.Mode)&os.ModeCharDevice != 0 {
40 40
 		mode |= syscall.S_IFCHR
... ...
@@ -4,14 +4,15 @@ package fsutil
4 4
 
5 5
 import (
6 6
 	"github.com/pkg/errors"
7
+	"github.com/tonistiigi/fsutil/types"
7 8
 )
8 9
 
9
-func rewriteMetadata(p string, stat *Stat) error {
10
+func rewriteMetadata(p string, stat *types.Stat) error {
10 11
 	return chtimes(p, stat.ModTime)
11 12
 }
12 13
 
13 14
 // handleTarTypeBlockCharFifo is an OS-specific helper function used by
14 15
 // createTarFile to handle the following types of header: Block; Char; Fifo
15
-func handleTarTypeBlockCharFifo(path string, stat *Stat) error {
16
+func handleTarTypeBlockCharFifo(path string, stat *types.Stat) error {
16 17
 	return errors.New("Not implemented on windows")
17 18
 }
... ...
@@ -9,6 +9,7 @@ import (
9 9
 	"strings"
10 10
 
11 11
 	"github.com/pkg/errors"
12
+	"github.com/tonistiigi/fsutil/types"
12 13
 )
13 14
 
14 15
 type FS interface {
... ...
@@ -36,13 +37,13 @@ func (fs *fs) Open(p string) (io.ReadCloser, error) {
36 36
 	return os.Open(filepath.Join(fs.root, p))
37 37
 }
38 38
 
39
-func SubDirFS(fs FS, stat Stat) FS {
39
+func SubDirFS(fs FS, stat types.Stat) FS {
40 40
 	return &subDirFS{fs: fs, stat: stat}
41 41
 }
42 42
 
43 43
 type subDirFS struct {
44 44
 	fs   FS
45
-	stat Stat
45
+	stat types.Stat
46 46
 }
47 47
 
48 48
 func (fs *subDirFS) Walk(ctx context.Context, fn filepath.WalkFunc) error {
... ...
@@ -57,7 +58,7 @@ func (fs *subDirFS) Walk(ctx context.Context, fn filepath.WalkFunc) error {
57 57
 		return err
58 58
 	}
59 59
 	return fs.fs.Walk(ctx, func(p string, fi os.FileInfo, err error) error {
60
-		stat, ok := fi.Sys().(*Stat)
60
+		stat, ok := fi.Sys().(*types.Stat)
61 61
 		if !ok {
62 62
 			return errors.Wrapf(err, "invalid fileinfo without stat info: %s", p)
63 63
 		}
64 64
deleted file mode 100644
... ...
@@ -1,3 +0,0 @@
1
-package fsutil
2
-
3
-//go:generate protoc --gogoslick_out=. stat.proto wire.proto
... ...
@@ -4,6 +4,7 @@ import (
4 4
 	"os"
5 5
 
6 6
 	"github.com/pkg/errors"
7
+	"github.com/tonistiigi/fsutil/types"
7 8
 )
8 9
 
9 10
 // Hardlinks validates that all targets for links were part of the changes
... ...
@@ -25,7 +26,7 @@ func (v *Hardlinks) HandleChange(kind ChangeKind, p string, fi os.FileInfo, err
25 25
 		return nil
26 26
 	}
27 27
 
28
-	stat, ok := fi.Sys().(*Stat)
28
+	stat, ok := fi.Sys().(*types.Stat)
29 29
 	if !ok {
30 30
 		return errors.Errorf("invalid change without stat info: %s", p)
31 31
 	}
... ...
@@ -7,6 +7,7 @@ import (
7 7
 	"sync"
8 8
 
9 9
 	"github.com/pkg/errors"
10
+	"github.com/tonistiigi/fsutil/types"
10 11
 	"golang.org/x/sync/errgroup"
11 12
 )
12 13
 
... ...
@@ -119,7 +120,7 @@ func (r *receiver) run(ctx context.Context) error {
119 119
 	g.Go(func() (retErr error) {
120 120
 		defer func() {
121 121
 			if retErr != nil {
122
-				r.conn.SendMsg(&Packet{Type: PACKET_ERR, Data: []byte(retErr.Error())})
122
+				r.conn.SendMsg(&types.Packet{Type: types.PACKET_ERR, Data: []byte(retErr.Error())})
123 123
 			}
124 124
 		}()
125 125
 		destWalker := emptyWalker
... ...
@@ -133,7 +134,7 @@ func (r *receiver) run(ctx context.Context) error {
133 133
 		if err := dw.Wait(ctx); err != nil {
134 134
 			return err
135 135
 		}
136
-		r.conn.SendMsg(&Packet{Type: PACKET_FIN})
136
+		r.conn.SendMsg(&types.Packet{Type: types.PACKET_FIN})
137 137
 		return nil
138 138
 	})
139 139
 
... ...
@@ -146,9 +147,9 @@ func (r *receiver) run(ctx context.Context) error {
146 146
 				r.progressCb(size, true)
147 147
 			}()
148 148
 		}
149
-		var p Packet
149
+		var p types.Packet
150 150
 		for {
151
-			p = Packet{Data: p.Data[:0]}
151
+			p = types.Packet{Data: p.Data[:0]}
152 152
 			if err := r.conn.RecvMsg(&p); err != nil {
153 153
 				return err
154 154
 			}
... ...
@@ -158,9 +159,9 @@ func (r *receiver) run(ctx context.Context) error {
158 158
 			}
159 159
 
160 160
 			switch p.Type {
161
-			case PACKET_ERR:
161
+			case types.PACKET_ERR:
162 162
 				return errors.Errorf("error from sender: %s", p.Data)
163
-			case PACKET_STAT:
163
+			case types.PACKET_STAT:
164 164
 				if p.Stat == nil {
165 165
 					if err := w.update(nil); err != nil {
166 166
 						return err
... ...
@@ -183,12 +184,12 @@ func (r *receiver) run(ctx context.Context) error {
183 183
 				if err := w.update(cp); err != nil {
184 184
 					return err
185 185
 				}
186
-			case PACKET_DATA:
186
+			case types.PACKET_DATA:
187 187
 				r.muPipes.Lock()
188 188
 				pw, ok := r.pipes[p.ID]
189 189
 				r.muPipes.Unlock()
190 190
 				if !ok {
191
-					return errors.Errorf("invalid file request %s", p.ID)
191
+					return errors.Errorf("invalid file request %d", p.ID)
192 192
 				}
193 193
 				if len(p.Data) == 0 {
194 194
 					if err := pw.Close(); err != nil {
... ...
@@ -199,9 +200,9 @@ func (r *receiver) run(ctx context.Context) error {
199 199
 						return err
200 200
 					}
201 201
 				}
202
-			case PACKET_FIN:
202
+			case types.PACKET_FIN:
203 203
 				for {
204
-					var p Packet
204
+					var p types.Packet
205 205
 					if err := r.conn.RecvMsg(&p); err != nil {
206 206
 						if err == io.EOF {
207 207
 							return nil
... ...
@@ -229,7 +230,7 @@ func (r *receiver) asyncDataFunc(ctx context.Context, p string, wc io.WriteClose
229 229
 	r.muPipes.Lock()
230 230
 	r.pipes[id] = wwc
231 231
 	r.muPipes.Unlock()
232
-	if err := r.conn.SendMsg(&Packet{Type: PACKET_REQ, ID: id}); err != nil {
232
+	if err := r.conn.SendMsg(&types.Packet{Type: types.PACKET_REQ, ID: id}); err != nil {
233 233
 		return err
234 234
 	}
235 235
 	err := wwc.Wait(ctx)
... ...
@@ -7,6 +7,7 @@ import (
7 7
 	"sync"
8 8
 
9 9
 	"github.com/pkg/errors"
10
+	"github.com/tonistiigi/fsutil/types"
10 11
 	"golang.org/x/sync/errgroup"
11 12
 )
12 13
 
... ...
@@ -56,7 +57,7 @@ func (s *sender) run(ctx context.Context) error {
56 56
 	g.Go(func() error {
57 57
 		err := s.walk(ctx)
58 58
 		if err != nil {
59
-			s.conn.SendMsg(&Packet{Type: PACKET_ERR, Data: []byte(err.Error())})
59
+			s.conn.SendMsg(&types.Packet{Type: types.PACKET_ERR, Data: []byte(err.Error())})
60 60
 		}
61 61
 		return err
62 62
 	})
... ...
@@ -86,19 +87,19 @@ func (s *sender) run(ctx context.Context) error {
86 86
 				return ctx.Err()
87 87
 			default:
88 88
 			}
89
-			var p Packet
89
+			var p types.Packet
90 90
 			if err := s.conn.RecvMsg(&p); err != nil {
91 91
 				return err
92 92
 			}
93 93
 			switch p.Type {
94
-			case PACKET_ERR:
94
+			case types.PACKET_ERR:
95 95
 				return errors.Errorf("error from receiver: %s", p.Data)
96
-			case PACKET_REQ:
96
+			case types.PACKET_REQ:
97 97
 				if err := s.queue(p.ID); err != nil {
98 98
 					return err
99 99
 				}
100
-			case PACKET_FIN:
101
-				return s.conn.SendMsg(&Packet{Type: PACKET_FIN})
100
+			case types.PACKET_FIN:
101
+				return s.conn.SendMsg(&types.Packet{Type: types.PACKET_FIN})
102 102
 			}
103 103
 		}
104 104
 	})
... ...
@@ -136,7 +137,7 @@ func (s *sender) sendFile(h *sendHandle) error {
136 136
 			return err
137 137
 		}
138 138
 	}
139
-	return s.conn.SendMsg(&Packet{ID: h.id, Type: PACKET_DATA})
139
+	return s.conn.SendMsg(&types.Packet{ID: h.id, Type: types.PACKET_DATA})
140 140
 }
141 141
 
142 142
 func (s *sender) walk(ctx context.Context) error {
... ...
@@ -145,13 +146,13 @@ func (s *sender) walk(ctx context.Context) error {
145 145
 		if err != nil {
146 146
 			return err
147 147
 		}
148
-		stat, ok := fi.Sys().(*Stat)
148
+		stat, ok := fi.Sys().(*types.Stat)
149 149
 		if !ok {
150 150
 			return errors.Wrapf(err, "invalid fileinfo without stat info: %s", path)
151 151
 		}
152 152
 
153
-		p := &Packet{
154
-			Type: PACKET_STAT,
153
+		p := &types.Packet{
154
+			Type: types.PACKET_STAT,
155 155
 			Stat: stat,
156 156
 		}
157 157
 		if fileCanRequestData(os.FileMode(stat.Mode)) {
... ...
@@ -166,7 +167,7 @@ func (s *sender) walk(ctx context.Context) error {
166 166
 	if err != nil {
167 167
 		return err
168 168
 	}
169
-	return errors.Wrapf(s.conn.SendMsg(&Packet{Type: PACKET_STAT}), "failed to send last stat")
169
+	return errors.Wrapf(s.conn.SendMsg(&types.Packet{Type: types.PACKET_STAT}), "failed to send last stat")
170 170
 }
171 171
 
172 172
 func fileCanRequestData(m os.FileMode) bool {
... ...
@@ -184,7 +185,7 @@ func (fs *fileSender) Write(dt []byte) (int, error) {
184 184
 	if len(dt) == 0 {
185 185
 		return 0, nil
186 186
 	}
187
-	p := &Packet{Type: PACKET_DATA, ID: fs.id, Data: dt}
187
+	p := &types.Packet{Type: types.PACKET_DATA, ID: fs.id, Data: dt}
188 188
 	if err := fs.sender.conn.SendMsg(p); err != nil {
189 189
 		return 0, err
190 190
 	}
191 191
new file mode 100644
... ...
@@ -0,0 +1,61 @@
0
+package fsutil
1
+
2
+import (
3
+	"os"
4
+	"path/filepath"
5
+	"runtime"
6
+
7
+	"github.com/pkg/errors"
8
+	"github.com/tonistiigi/fsutil/types"
9
+)
10
+
11
+// constructs a Stat object. path is where the path can be found right
12
+// now, relpath is the desired path to be recorded in the stat (so
13
+// relative to whatever base dir is relevant). fi is the os.Stat
14
+// info. inodemap is used to calculate hardlinks over a series of
15
+// mkstat calls and maps inode to the canonical (aka "first") path for
16
+// a set of hardlinks to that inode.
17
+func mkstat(path, relpath string, fi os.FileInfo, inodemap map[uint64]string) (*types.Stat, error) {
18
+	relpath = filepath.ToSlash(relpath)
19
+
20
+	stat := &types.Stat{
21
+		Path:    relpath,
22
+		Mode:    uint32(fi.Mode()),
23
+		ModTime: fi.ModTime().UnixNano(),
24
+	}
25
+
26
+	setUnixOpt(fi, stat, relpath, inodemap)
27
+
28
+	if !fi.IsDir() {
29
+		stat.Size_ = fi.Size()
30
+		if fi.Mode()&os.ModeSymlink != 0 {
31
+			link, err := os.Readlink(path)
32
+			if err != nil {
33
+				return nil, errors.Wrapf(err, "failed to readlink %s", path)
34
+			}
35
+			stat.Linkname = link
36
+		}
37
+	}
38
+	if err := loadXattr(path, stat); err != nil {
39
+		return nil, errors.Wrapf(err, "failed to xattr %s", relpath)
40
+	}
41
+
42
+	if runtime.GOOS == "windows" {
43
+		permPart := stat.Mode & uint32(os.ModePerm)
44
+		noPermPart := stat.Mode &^ uint32(os.ModePerm)
45
+		// Add the x bit: make everything +x from windows
46
+		permPart |= 0111
47
+		permPart &= 0755
48
+		stat.Mode = noPermPart | permPart
49
+	}
50
+
51
+	return stat, nil
52
+}
53
+
54
+func Stat(path string) (*types.Stat, error) {
55
+	fi, err := os.Lstat(path)
56
+	if err != nil {
57
+		return nil, errors.Wrap(err, "os stat")
58
+	}
59
+	return mkstat(path, filepath.Base(path), fi, nil)
60
+}
0 61
deleted file mode 100644
... ...
@@ -1,931 +0,0 @@
1
-// Code generated by protoc-gen-gogo.
2
-// source: stat.proto
3
-// DO NOT EDIT!
4
-
5
-/*
6
-	Package fsutil is a generated protocol buffer package.
7
-
8
-	It is generated from these files:
9
-		stat.proto
10
-		wire.proto
11
-
12
-	It has these top-level messages:
13
-		Stat
14
-		Packet
15
-*/
16
-package fsutil
17
-
18
-import proto "github.com/gogo/protobuf/proto"
19
-import fmt "fmt"
20
-import math "math"
21
-
22
-import bytes "bytes"
23
-
24
-import strings "strings"
25
-import reflect "reflect"
26
-import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys"
27
-
28
-import io "io"
29
-
30
-// Reference imports to suppress errors if they are not otherwise used.
31
-var _ = proto.Marshal
32
-var _ = fmt.Errorf
33
-var _ = math.Inf
34
-
35
-// This is a compile-time assertion to ensure that this generated file
36
-// is compatible with the proto package it is being compiled against.
37
-// A compilation error at this line likely means your copy of the
38
-// proto package needs to be updated.
39
-const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
40
-
41
-type Stat struct {
42
-	Path    string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
43
-	Mode    uint32 `protobuf:"varint,2,opt,name=mode,proto3" json:"mode,omitempty"`
44
-	Uid     uint32 `protobuf:"varint,3,opt,name=uid,proto3" json:"uid,omitempty"`
45
-	Gid     uint32 `protobuf:"varint,4,opt,name=gid,proto3" json:"gid,omitempty"`
46
-	Size_   int64  `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"`
47
-	ModTime int64  `protobuf:"varint,6,opt,name=modTime,proto3" json:"modTime,omitempty"`
48
-	// int32 typeflag = 7;
49
-	Linkname string            `protobuf:"bytes,7,opt,name=linkname,proto3" json:"linkname,omitempty"`
50
-	Devmajor int64             `protobuf:"varint,8,opt,name=devmajor,proto3" json:"devmajor,omitempty"`
51
-	Devminor int64             `protobuf:"varint,9,opt,name=devminor,proto3" json:"devminor,omitempty"`
52
-	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"`
53
-}
54
-
55
-func (m *Stat) Reset()                    { *m = Stat{} }
56
-func (*Stat) ProtoMessage()               {}
57
-func (*Stat) Descriptor() ([]byte, []int) { return fileDescriptorStat, []int{0} }
58
-
59
-func (m *Stat) GetPath() string {
60
-	if m != nil {
61
-		return m.Path
62
-	}
63
-	return ""
64
-}
65
-
66
-func (m *Stat) GetMode() uint32 {
67
-	if m != nil {
68
-		return m.Mode
69
-	}
70
-	return 0
71
-}
72
-
73
-func (m *Stat) GetUid() uint32 {
74
-	if m != nil {
75
-		return m.Uid
76
-	}
77
-	return 0
78
-}
79
-
80
-func (m *Stat) GetGid() uint32 {
81
-	if m != nil {
82
-		return m.Gid
83
-	}
84
-	return 0
85
-}
86
-
87
-func (m *Stat) GetSize_() int64 {
88
-	if m != nil {
89
-		return m.Size_
90
-	}
91
-	return 0
92
-}
93
-
94
-func (m *Stat) GetModTime() int64 {
95
-	if m != nil {
96
-		return m.ModTime
97
-	}
98
-	return 0
99
-}
100
-
101
-func (m *Stat) GetLinkname() string {
102
-	if m != nil {
103
-		return m.Linkname
104
-	}
105
-	return ""
106
-}
107
-
108
-func (m *Stat) GetDevmajor() int64 {
109
-	if m != nil {
110
-		return m.Devmajor
111
-	}
112
-	return 0
113
-}
114
-
115
-func (m *Stat) GetDevminor() int64 {
116
-	if m != nil {
117
-		return m.Devminor
118
-	}
119
-	return 0
120
-}
121
-
122
-func (m *Stat) GetXattrs() map[string][]byte {
123
-	if m != nil {
124
-		return m.Xattrs
125
-	}
126
-	return nil
127
-}
128
-
129
-func init() {
130
-	proto.RegisterType((*Stat)(nil), "fsutil.Stat")
131
-}
132
-func (this *Stat) Equal(that interface{}) bool {
133
-	if that == nil {
134
-		if this == nil {
135
-			return true
136
-		}
137
-		return false
138
-	}
139
-
140
-	that1, ok := that.(*Stat)
141
-	if !ok {
142
-		that2, ok := that.(Stat)
143
-		if ok {
144
-			that1 = &that2
145
-		} else {
146
-			return false
147
-		}
148
-	}
149
-	if that1 == nil {
150
-		if this == nil {
151
-			return true
152
-		}
153
-		return false
154
-	} else if this == nil {
155
-		return false
156
-	}
157
-	if this.Path != that1.Path {
158
-		return false
159
-	}
160
-	if this.Mode != that1.Mode {
161
-		return false
162
-	}
163
-	if this.Uid != that1.Uid {
164
-		return false
165
-	}
166
-	if this.Gid != that1.Gid {
167
-		return false
168
-	}
169
-	if this.Size_ != that1.Size_ {
170
-		return false
171
-	}
172
-	if this.ModTime != that1.ModTime {
173
-		return false
174
-	}
175
-	if this.Linkname != that1.Linkname {
176
-		return false
177
-	}
178
-	if this.Devmajor != that1.Devmajor {
179
-		return false
180
-	}
181
-	if this.Devminor != that1.Devminor {
182
-		return false
183
-	}
184
-	if len(this.Xattrs) != len(that1.Xattrs) {
185
-		return false
186
-	}
187
-	for i := range this.Xattrs {
188
-		if !bytes.Equal(this.Xattrs[i], that1.Xattrs[i]) {
189
-			return false
190
-		}
191
-	}
192
-	return true
193
-}
194
-func (this *Stat) GoString() string {
195
-	if this == nil {
196
-		return "nil"
197
-	}
198
-	s := make([]string, 0, 14)
199
-	s = append(s, "&fsutil.Stat{")
200
-	s = append(s, "Path: "+fmt.Sprintf("%#v", this.Path)+",\n")
201
-	s = append(s, "Mode: "+fmt.Sprintf("%#v", this.Mode)+",\n")
202
-	s = append(s, "Uid: "+fmt.Sprintf("%#v", this.Uid)+",\n")
203
-	s = append(s, "Gid: "+fmt.Sprintf("%#v", this.Gid)+",\n")
204
-	s = append(s, "Size_: "+fmt.Sprintf("%#v", this.Size_)+",\n")
205
-	s = append(s, "ModTime: "+fmt.Sprintf("%#v", this.ModTime)+",\n")
206
-	s = append(s, "Linkname: "+fmt.Sprintf("%#v", this.Linkname)+",\n")
207
-	s = append(s, "Devmajor: "+fmt.Sprintf("%#v", this.Devmajor)+",\n")
208
-	s = append(s, "Devminor: "+fmt.Sprintf("%#v", this.Devminor)+",\n")
209
-	keysForXattrs := make([]string, 0, len(this.Xattrs))
210
-	for k, _ := range this.Xattrs {
211
-		keysForXattrs = append(keysForXattrs, k)
212
-	}
213
-	github_com_gogo_protobuf_sortkeys.Strings(keysForXattrs)
214
-	mapStringForXattrs := "map[string][]byte{"
215
-	for _, k := range keysForXattrs {
216
-		mapStringForXattrs += fmt.Sprintf("%#v: %#v,", k, this.Xattrs[k])
217
-	}
218
-	mapStringForXattrs += "}"
219
-	if this.Xattrs != nil {
220
-		s = append(s, "Xattrs: "+mapStringForXattrs+",\n")
221
-	}
222
-	s = append(s, "}")
223
-	return strings.Join(s, "")
224
-}
225
-func valueToGoStringStat(v interface{}, typ string) string {
226
-	rv := reflect.ValueOf(v)
227
-	if rv.IsNil() {
228
-		return "nil"
229
-	}
230
-	pv := reflect.Indirect(rv).Interface()
231
-	return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
232
-}
233
-func (m *Stat) Marshal() (dAtA []byte, err error) {
234
-	size := m.Size()
235
-	dAtA = make([]byte, size)
236
-	n, err := m.MarshalTo(dAtA)
237
-	if err != nil {
238
-		return nil, err
239
-	}
240
-	return dAtA[:n], nil
241
-}
242
-
243
-func (m *Stat) MarshalTo(dAtA []byte) (int, error) {
244
-	var i int
245
-	_ = i
246
-	var l int
247
-	_ = l
248
-	if len(m.Path) > 0 {
249
-		dAtA[i] = 0xa
250
-		i++
251
-		i = encodeVarintStat(dAtA, i, uint64(len(m.Path)))
252
-		i += copy(dAtA[i:], m.Path)
253
-	}
254
-	if m.Mode != 0 {
255
-		dAtA[i] = 0x10
256
-		i++
257
-		i = encodeVarintStat(dAtA, i, uint64(m.Mode))
258
-	}
259
-	if m.Uid != 0 {
260
-		dAtA[i] = 0x18
261
-		i++
262
-		i = encodeVarintStat(dAtA, i, uint64(m.Uid))
263
-	}
264
-	if m.Gid != 0 {
265
-		dAtA[i] = 0x20
266
-		i++
267
-		i = encodeVarintStat(dAtA, i, uint64(m.Gid))
268
-	}
269
-	if m.Size_ != 0 {
270
-		dAtA[i] = 0x28
271
-		i++
272
-		i = encodeVarintStat(dAtA, i, uint64(m.Size_))
273
-	}
274
-	if m.ModTime != 0 {
275
-		dAtA[i] = 0x30
276
-		i++
277
-		i = encodeVarintStat(dAtA, i, uint64(m.ModTime))
278
-	}
279
-	if len(m.Linkname) > 0 {
280
-		dAtA[i] = 0x3a
281
-		i++
282
-		i = encodeVarintStat(dAtA, i, uint64(len(m.Linkname)))
283
-		i += copy(dAtA[i:], m.Linkname)
284
-	}
285
-	if m.Devmajor != 0 {
286
-		dAtA[i] = 0x40
287
-		i++
288
-		i = encodeVarintStat(dAtA, i, uint64(m.Devmajor))
289
-	}
290
-	if m.Devminor != 0 {
291
-		dAtA[i] = 0x48
292
-		i++
293
-		i = encodeVarintStat(dAtA, i, uint64(m.Devminor))
294
-	}
295
-	if len(m.Xattrs) > 0 {
296
-		for k, _ := range m.Xattrs {
297
-			dAtA[i] = 0x52
298
-			i++
299
-			v := m.Xattrs[k]
300
-			byteSize := 0
301
-			if len(v) > 0 {
302
-				byteSize = 1 + len(v) + sovStat(uint64(len(v)))
303
-			}
304
-			mapSize := 1 + len(k) + sovStat(uint64(len(k))) + byteSize
305
-			i = encodeVarintStat(dAtA, i, uint64(mapSize))
306
-			dAtA[i] = 0xa
307
-			i++
308
-			i = encodeVarintStat(dAtA, i, uint64(len(k)))
309
-			i += copy(dAtA[i:], k)
310
-			if len(v) > 0 {
311
-				dAtA[i] = 0x12
312
-				i++
313
-				i = encodeVarintStat(dAtA, i, uint64(len(v)))
314
-				i += copy(dAtA[i:], v)
315
-			}
316
-		}
317
-	}
318
-	return i, nil
319
-}
320
-
321
-func encodeFixed64Stat(dAtA []byte, offset int, v uint64) int {
322
-	dAtA[offset] = uint8(v)
323
-	dAtA[offset+1] = uint8(v >> 8)
324
-	dAtA[offset+2] = uint8(v >> 16)
325
-	dAtA[offset+3] = uint8(v >> 24)
326
-	dAtA[offset+4] = uint8(v >> 32)
327
-	dAtA[offset+5] = uint8(v >> 40)
328
-	dAtA[offset+6] = uint8(v >> 48)
329
-	dAtA[offset+7] = uint8(v >> 56)
330
-	return offset + 8
331
-}
332
-func encodeFixed32Stat(dAtA []byte, offset int, v uint32) int {
333
-	dAtA[offset] = uint8(v)
334
-	dAtA[offset+1] = uint8(v >> 8)
335
-	dAtA[offset+2] = uint8(v >> 16)
336
-	dAtA[offset+3] = uint8(v >> 24)
337
-	return offset + 4
338
-}
339
-func encodeVarintStat(dAtA []byte, offset int, v uint64) int {
340
-	for v >= 1<<7 {
341
-		dAtA[offset] = uint8(v&0x7f | 0x80)
342
-		v >>= 7
343
-		offset++
344
-	}
345
-	dAtA[offset] = uint8(v)
346
-	return offset + 1
347
-}
348
-func (m *Stat) Size() (n int) {
349
-	var l int
350
-	_ = l
351
-	l = len(m.Path)
352
-	if l > 0 {
353
-		n += 1 + l + sovStat(uint64(l))
354
-	}
355
-	if m.Mode != 0 {
356
-		n += 1 + sovStat(uint64(m.Mode))
357
-	}
358
-	if m.Uid != 0 {
359
-		n += 1 + sovStat(uint64(m.Uid))
360
-	}
361
-	if m.Gid != 0 {
362
-		n += 1 + sovStat(uint64(m.Gid))
363
-	}
364
-	if m.Size_ != 0 {
365
-		n += 1 + sovStat(uint64(m.Size_))
366
-	}
367
-	if m.ModTime != 0 {
368
-		n += 1 + sovStat(uint64(m.ModTime))
369
-	}
370
-	l = len(m.Linkname)
371
-	if l > 0 {
372
-		n += 1 + l + sovStat(uint64(l))
373
-	}
374
-	if m.Devmajor != 0 {
375
-		n += 1 + sovStat(uint64(m.Devmajor))
376
-	}
377
-	if m.Devminor != 0 {
378
-		n += 1 + sovStat(uint64(m.Devminor))
379
-	}
380
-	if len(m.Xattrs) > 0 {
381
-		for k, v := range m.Xattrs {
382
-			_ = k
383
-			_ = v
384
-			l = 0
385
-			if len(v) > 0 {
386
-				l = 1 + len(v) + sovStat(uint64(len(v)))
387
-			}
388
-			mapEntrySize := 1 + len(k) + sovStat(uint64(len(k))) + l
389
-			n += mapEntrySize + 1 + sovStat(uint64(mapEntrySize))
390
-		}
391
-	}
392
-	return n
393
-}
394
-
395
-func sovStat(x uint64) (n int) {
396
-	for {
397
-		n++
398
-		x >>= 7
399
-		if x == 0 {
400
-			break
401
-		}
402
-	}
403
-	return n
404
-}
405
-func sozStat(x uint64) (n int) {
406
-	return sovStat(uint64((x << 1) ^ uint64((int64(x) >> 63))))
407
-}
408
-func (this *Stat) String() string {
409
-	if this == nil {
410
-		return "nil"
411
-	}
412
-	keysForXattrs := make([]string, 0, len(this.Xattrs))
413
-	for k, _ := range this.Xattrs {
414
-		keysForXattrs = append(keysForXattrs, k)
415
-	}
416
-	github_com_gogo_protobuf_sortkeys.Strings(keysForXattrs)
417
-	mapStringForXattrs := "map[string][]byte{"
418
-	for _, k := range keysForXattrs {
419
-		mapStringForXattrs += fmt.Sprintf("%v: %v,", k, this.Xattrs[k])
420
-	}
421
-	mapStringForXattrs += "}"
422
-	s := strings.Join([]string{`&Stat{`,
423
-		`Path:` + fmt.Sprintf("%v", this.Path) + `,`,
424
-		`Mode:` + fmt.Sprintf("%v", this.Mode) + `,`,
425
-		`Uid:` + fmt.Sprintf("%v", this.Uid) + `,`,
426
-		`Gid:` + fmt.Sprintf("%v", this.Gid) + `,`,
427
-		`Size_:` + fmt.Sprintf("%v", this.Size_) + `,`,
428
-		`ModTime:` + fmt.Sprintf("%v", this.ModTime) + `,`,
429
-		`Linkname:` + fmt.Sprintf("%v", this.Linkname) + `,`,
430
-		`Devmajor:` + fmt.Sprintf("%v", this.Devmajor) + `,`,
431
-		`Devminor:` + fmt.Sprintf("%v", this.Devminor) + `,`,
432
-		`Xattrs:` + mapStringForXattrs + `,`,
433
-		`}`,
434
-	}, "")
435
-	return s
436
-}
437
-func valueToStringStat(v interface{}) string {
438
-	rv := reflect.ValueOf(v)
439
-	if rv.IsNil() {
440
-		return "nil"
441
-	}
442
-	pv := reflect.Indirect(rv).Interface()
443
-	return fmt.Sprintf("*%v", pv)
444
-}
445
-func (m *Stat) Unmarshal(dAtA []byte) error {
446
-	l := len(dAtA)
447
-	iNdEx := 0
448
-	for iNdEx < l {
449
-		preIndex := iNdEx
450
-		var wire uint64
451
-		for shift := uint(0); ; shift += 7 {
452
-			if shift >= 64 {
453
-				return ErrIntOverflowStat
454
-			}
455
-			if iNdEx >= l {
456
-				return io.ErrUnexpectedEOF
457
-			}
458
-			b := dAtA[iNdEx]
459
-			iNdEx++
460
-			wire |= (uint64(b) & 0x7F) << shift
461
-			if b < 0x80 {
462
-				break
463
-			}
464
-		}
465
-		fieldNum := int32(wire >> 3)
466
-		wireType := int(wire & 0x7)
467
-		if wireType == 4 {
468
-			return fmt.Errorf("proto: Stat: wiretype end group for non-group")
469
-		}
470
-		if fieldNum <= 0 {
471
-			return fmt.Errorf("proto: Stat: illegal tag %d (wire type %d)", fieldNum, wire)
472
-		}
473
-		switch fieldNum {
474
-		case 1:
475
-			if wireType != 2 {
476
-				return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType)
477
-			}
478
-			var stringLen uint64
479
-			for shift := uint(0); ; shift += 7 {
480
-				if shift >= 64 {
481
-					return ErrIntOverflowStat
482
-				}
483
-				if iNdEx >= l {
484
-					return io.ErrUnexpectedEOF
485
-				}
486
-				b := dAtA[iNdEx]
487
-				iNdEx++
488
-				stringLen |= (uint64(b) & 0x7F) << shift
489
-				if b < 0x80 {
490
-					break
491
-				}
492
-			}
493
-			intStringLen := int(stringLen)
494
-			if intStringLen < 0 {
495
-				return ErrInvalidLengthStat
496
-			}
497
-			postIndex := iNdEx + intStringLen
498
-			if postIndex > l {
499
-				return io.ErrUnexpectedEOF
500
-			}
501
-			m.Path = string(dAtA[iNdEx:postIndex])
502
-			iNdEx = postIndex
503
-		case 2:
504
-			if wireType != 0 {
505
-				return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType)
506
-			}
507
-			m.Mode = 0
508
-			for shift := uint(0); ; shift += 7 {
509
-				if shift >= 64 {
510
-					return ErrIntOverflowStat
511
-				}
512
-				if iNdEx >= l {
513
-					return io.ErrUnexpectedEOF
514
-				}
515
-				b := dAtA[iNdEx]
516
-				iNdEx++
517
-				m.Mode |= (uint32(b) & 0x7F) << shift
518
-				if b < 0x80 {
519
-					break
520
-				}
521
-			}
522
-		case 3:
523
-			if wireType != 0 {
524
-				return fmt.Errorf("proto: wrong wireType = %d for field Uid", wireType)
525
-			}
526
-			m.Uid = 0
527
-			for shift := uint(0); ; shift += 7 {
528
-				if shift >= 64 {
529
-					return ErrIntOverflowStat
530
-				}
531
-				if iNdEx >= l {
532
-					return io.ErrUnexpectedEOF
533
-				}
534
-				b := dAtA[iNdEx]
535
-				iNdEx++
536
-				m.Uid |= (uint32(b) & 0x7F) << shift
537
-				if b < 0x80 {
538
-					break
539
-				}
540
-			}
541
-		case 4:
542
-			if wireType != 0 {
543
-				return fmt.Errorf("proto: wrong wireType = %d for field Gid", wireType)
544
-			}
545
-			m.Gid = 0
546
-			for shift := uint(0); ; shift += 7 {
547
-				if shift >= 64 {
548
-					return ErrIntOverflowStat
549
-				}
550
-				if iNdEx >= l {
551
-					return io.ErrUnexpectedEOF
552
-				}
553
-				b := dAtA[iNdEx]
554
-				iNdEx++
555
-				m.Gid |= (uint32(b) & 0x7F) << shift
556
-				if b < 0x80 {
557
-					break
558
-				}
559
-			}
560
-		case 5:
561
-			if wireType != 0 {
562
-				return fmt.Errorf("proto: wrong wireType = %d for field Size_", wireType)
563
-			}
564
-			m.Size_ = 0
565
-			for shift := uint(0); ; shift += 7 {
566
-				if shift >= 64 {
567
-					return ErrIntOverflowStat
568
-				}
569
-				if iNdEx >= l {
570
-					return io.ErrUnexpectedEOF
571
-				}
572
-				b := dAtA[iNdEx]
573
-				iNdEx++
574
-				m.Size_ |= (int64(b) & 0x7F) << shift
575
-				if b < 0x80 {
576
-					break
577
-				}
578
-			}
579
-		case 6:
580
-			if wireType != 0 {
581
-				return fmt.Errorf("proto: wrong wireType = %d for field ModTime", wireType)
582
-			}
583
-			m.ModTime = 0
584
-			for shift := uint(0); ; shift += 7 {
585
-				if shift >= 64 {
586
-					return ErrIntOverflowStat
587
-				}
588
-				if iNdEx >= l {
589
-					return io.ErrUnexpectedEOF
590
-				}
591
-				b := dAtA[iNdEx]
592
-				iNdEx++
593
-				m.ModTime |= (int64(b) & 0x7F) << shift
594
-				if b < 0x80 {
595
-					break
596
-				}
597
-			}
598
-		case 7:
599
-			if wireType != 2 {
600
-				return fmt.Errorf("proto: wrong wireType = %d for field Linkname", wireType)
601
-			}
602
-			var stringLen uint64
603
-			for shift := uint(0); ; shift += 7 {
604
-				if shift >= 64 {
605
-					return ErrIntOverflowStat
606
-				}
607
-				if iNdEx >= l {
608
-					return io.ErrUnexpectedEOF
609
-				}
610
-				b := dAtA[iNdEx]
611
-				iNdEx++
612
-				stringLen |= (uint64(b) & 0x7F) << shift
613
-				if b < 0x80 {
614
-					break
615
-				}
616
-			}
617
-			intStringLen := int(stringLen)
618
-			if intStringLen < 0 {
619
-				return ErrInvalidLengthStat
620
-			}
621
-			postIndex := iNdEx + intStringLen
622
-			if postIndex > l {
623
-				return io.ErrUnexpectedEOF
624
-			}
625
-			m.Linkname = string(dAtA[iNdEx:postIndex])
626
-			iNdEx = postIndex
627
-		case 8:
628
-			if wireType != 0 {
629
-				return fmt.Errorf("proto: wrong wireType = %d for field Devmajor", wireType)
630
-			}
631
-			m.Devmajor = 0
632
-			for shift := uint(0); ; shift += 7 {
633
-				if shift >= 64 {
634
-					return ErrIntOverflowStat
635
-				}
636
-				if iNdEx >= l {
637
-					return io.ErrUnexpectedEOF
638
-				}
639
-				b := dAtA[iNdEx]
640
-				iNdEx++
641
-				m.Devmajor |= (int64(b) & 0x7F) << shift
642
-				if b < 0x80 {
643
-					break
644
-				}
645
-			}
646
-		case 9:
647
-			if wireType != 0 {
648
-				return fmt.Errorf("proto: wrong wireType = %d for field Devminor", wireType)
649
-			}
650
-			m.Devminor = 0
651
-			for shift := uint(0); ; shift += 7 {
652
-				if shift >= 64 {
653
-					return ErrIntOverflowStat
654
-				}
655
-				if iNdEx >= l {
656
-					return io.ErrUnexpectedEOF
657
-				}
658
-				b := dAtA[iNdEx]
659
-				iNdEx++
660
-				m.Devminor |= (int64(b) & 0x7F) << shift
661
-				if b < 0x80 {
662
-					break
663
-				}
664
-			}
665
-		case 10:
666
-			if wireType != 2 {
667
-				return fmt.Errorf("proto: wrong wireType = %d for field Xattrs", wireType)
668
-			}
669
-			var msglen int
670
-			for shift := uint(0); ; shift += 7 {
671
-				if shift >= 64 {
672
-					return ErrIntOverflowStat
673
-				}
674
-				if iNdEx >= l {
675
-					return io.ErrUnexpectedEOF
676
-				}
677
-				b := dAtA[iNdEx]
678
-				iNdEx++
679
-				msglen |= (int(b) & 0x7F) << shift
680
-				if b < 0x80 {
681
-					break
682
-				}
683
-			}
684
-			if msglen < 0 {
685
-				return ErrInvalidLengthStat
686
-			}
687
-			postIndex := iNdEx + msglen
688
-			if postIndex > l {
689
-				return io.ErrUnexpectedEOF
690
-			}
691
-			var keykey uint64
692
-			for shift := uint(0); ; shift += 7 {
693
-				if shift >= 64 {
694
-					return ErrIntOverflowStat
695
-				}
696
-				if iNdEx >= l {
697
-					return io.ErrUnexpectedEOF
698
-				}
699
-				b := dAtA[iNdEx]
700
-				iNdEx++
701
-				keykey |= (uint64(b) & 0x7F) << shift
702
-				if b < 0x80 {
703
-					break
704
-				}
705
-			}
706
-			var stringLenmapkey uint64
707
-			for shift := uint(0); ; shift += 7 {
708
-				if shift >= 64 {
709
-					return ErrIntOverflowStat
710
-				}
711
-				if iNdEx >= l {
712
-					return io.ErrUnexpectedEOF
713
-				}
714
-				b := dAtA[iNdEx]
715
-				iNdEx++
716
-				stringLenmapkey |= (uint64(b) & 0x7F) << shift
717
-				if b < 0x80 {
718
-					break
719
-				}
720
-			}
721
-			intStringLenmapkey := int(stringLenmapkey)
722
-			if intStringLenmapkey < 0 {
723
-				return ErrInvalidLengthStat
724
-			}
725
-			postStringIndexmapkey := iNdEx + intStringLenmapkey
726
-			if postStringIndexmapkey > l {
727
-				return io.ErrUnexpectedEOF
728
-			}
729
-			mapkey := string(dAtA[iNdEx:postStringIndexmapkey])
730
-			iNdEx = postStringIndexmapkey
731
-			if m.Xattrs == nil {
732
-				m.Xattrs = make(map[string][]byte)
733
-			}
734
-			if iNdEx < postIndex {
735
-				var valuekey uint64
736
-				for shift := uint(0); ; shift += 7 {
737
-					if shift >= 64 {
738
-						return ErrIntOverflowStat
739
-					}
740
-					if iNdEx >= l {
741
-						return io.ErrUnexpectedEOF
742
-					}
743
-					b := dAtA[iNdEx]
744
-					iNdEx++
745
-					valuekey |= (uint64(b) & 0x7F) << shift
746
-					if b < 0x80 {
747
-						break
748
-					}
749
-				}
750
-				var mapbyteLen uint64
751
-				for shift := uint(0); ; shift += 7 {
752
-					if shift >= 64 {
753
-						return ErrIntOverflowStat
754
-					}
755
-					if iNdEx >= l {
756
-						return io.ErrUnexpectedEOF
757
-					}
758
-					b := dAtA[iNdEx]
759
-					iNdEx++
760
-					mapbyteLen |= (uint64(b) & 0x7F) << shift
761
-					if b < 0x80 {
762
-						break
763
-					}
764
-				}
765
-				intMapbyteLen := int(mapbyteLen)
766
-				if intMapbyteLen < 0 {
767
-					return ErrInvalidLengthStat
768
-				}
769
-				postbytesIndex := iNdEx + intMapbyteLen
770
-				if postbytesIndex > l {
771
-					return io.ErrUnexpectedEOF
772
-				}
773
-				mapvalue := make([]byte, mapbyteLen)
774
-				copy(mapvalue, dAtA[iNdEx:postbytesIndex])
775
-				iNdEx = postbytesIndex
776
-				m.Xattrs[mapkey] = mapvalue
777
-			} else {
778
-				var mapvalue []byte
779
-				m.Xattrs[mapkey] = mapvalue
780
-			}
781
-			iNdEx = postIndex
782
-		default:
783
-			iNdEx = preIndex
784
-			skippy, err := skipStat(dAtA[iNdEx:])
785
-			if err != nil {
786
-				return err
787
-			}
788
-			if skippy < 0 {
789
-				return ErrInvalidLengthStat
790
-			}
791
-			if (iNdEx + skippy) > l {
792
-				return io.ErrUnexpectedEOF
793
-			}
794
-			iNdEx += skippy
795
-		}
796
-	}
797
-
798
-	if iNdEx > l {
799
-		return io.ErrUnexpectedEOF
800
-	}
801
-	return nil
802
-}
803
-func skipStat(dAtA []byte) (n int, err error) {
804
-	l := len(dAtA)
805
-	iNdEx := 0
806
-	for iNdEx < l {
807
-		var wire uint64
808
-		for shift := uint(0); ; shift += 7 {
809
-			if shift >= 64 {
810
-				return 0, ErrIntOverflowStat
811
-			}
812
-			if iNdEx >= l {
813
-				return 0, io.ErrUnexpectedEOF
814
-			}
815
-			b := dAtA[iNdEx]
816
-			iNdEx++
817
-			wire |= (uint64(b) & 0x7F) << shift
818
-			if b < 0x80 {
819
-				break
820
-			}
821
-		}
822
-		wireType := int(wire & 0x7)
823
-		switch wireType {
824
-		case 0:
825
-			for shift := uint(0); ; shift += 7 {
826
-				if shift >= 64 {
827
-					return 0, ErrIntOverflowStat
828
-				}
829
-				if iNdEx >= l {
830
-					return 0, io.ErrUnexpectedEOF
831
-				}
832
-				iNdEx++
833
-				if dAtA[iNdEx-1] < 0x80 {
834
-					break
835
-				}
836
-			}
837
-			return iNdEx, nil
838
-		case 1:
839
-			iNdEx += 8
840
-			return iNdEx, nil
841
-		case 2:
842
-			var length int
843
-			for shift := uint(0); ; shift += 7 {
844
-				if shift >= 64 {
845
-					return 0, ErrIntOverflowStat
846
-				}
847
-				if iNdEx >= l {
848
-					return 0, io.ErrUnexpectedEOF
849
-				}
850
-				b := dAtA[iNdEx]
851
-				iNdEx++
852
-				length |= (int(b) & 0x7F) << shift
853
-				if b < 0x80 {
854
-					break
855
-				}
856
-			}
857
-			iNdEx += length
858
-			if length < 0 {
859
-				return 0, ErrInvalidLengthStat
860
-			}
861
-			return iNdEx, nil
862
-		case 3:
863
-			for {
864
-				var innerWire uint64
865
-				var start int = iNdEx
866
-				for shift := uint(0); ; shift += 7 {
867
-					if shift >= 64 {
868
-						return 0, ErrIntOverflowStat
869
-					}
870
-					if iNdEx >= l {
871
-						return 0, io.ErrUnexpectedEOF
872
-					}
873
-					b := dAtA[iNdEx]
874
-					iNdEx++
875
-					innerWire |= (uint64(b) & 0x7F) << shift
876
-					if b < 0x80 {
877
-						break
878
-					}
879
-				}
880
-				innerWireType := int(innerWire & 0x7)
881
-				if innerWireType == 4 {
882
-					break
883
-				}
884
-				next, err := skipStat(dAtA[start:])
885
-				if err != nil {
886
-					return 0, err
887
-				}
888
-				iNdEx = start + next
889
-			}
890
-			return iNdEx, nil
891
-		case 4:
892
-			return iNdEx, nil
893
-		case 5:
894
-			iNdEx += 4
895
-			return iNdEx, nil
896
-		default:
897
-			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
898
-		}
899
-	}
900
-	panic("unreachable")
901
-}
902
-
903
-var (
904
-	ErrInvalidLengthStat = fmt.Errorf("proto: negative length found during unmarshaling")
905
-	ErrIntOverflowStat   = fmt.Errorf("proto: integer overflow")
906
-)
907
-
908
-func init() { proto.RegisterFile("stat.proto", fileDescriptorStat) }
909
-
910
-var fileDescriptorStat = []byte{
911
-	// 303 bytes of a gzipped FileDescriptorProto
912
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x4c, 0x91, 0xb1, 0x4e, 0xf3, 0x30,
913
-	0x14, 0x85, 0x73, 0x9b, 0x36, 0x6d, 0xdd, 0xff, 0x97, 0x90, 0xc5, 0x70, 0xd5, 0xc1, 0x8a, 0x98,
914
-	0x32, 0xa0, 0x08, 0xc1, 0x02, 0x8c, 0x48, 0xbc, 0x40, 0x60, 0x60, 0x35, 0xb2, 0x29, 0xa6, 0x4d,
915
-	0x5c, 0x25, 0x4e, 0x45, 0x99, 0x78, 0x04, 0x1e, 0x83, 0xd7, 0x60, 0x63, 0xec, 0xc8, 0x48, 0xcc,
916
-	0xc2, 0xd8, 0x47, 0x40, 0x76, 0xda, 0xc2, 0x76, 0xce, 0x77, 0x7c, 0x65, 0x9d, 0x7b, 0x09, 0xa9,
917
-	0x0c, 0x37, 0xe9, 0xbc, 0xd4, 0x46, 0xd3, 0xe8, 0xae, 0xaa, 0x8d, 0x9a, 0x1d, 0xbc, 0x75, 0x48,
918
-	0xf7, 0xca, 0x70, 0x43, 0x29, 0xe9, 0xce, 0xb9, 0xb9, 0x47, 0x88, 0x21, 0x19, 0x66, 0x5e, 0x3b,
919
-	0x96, 0x6b, 0x21, 0xb1, 0x13, 0x43, 0xf2, 0x3f, 0xf3, 0x9a, 0xee, 0x91, 0xb0, 0x56, 0x02, 0x43,
920
-	0x8f, 0x9c, 0x74, 0x64, 0xa2, 0x04, 0x76, 0x5b, 0x32, 0x51, 0xc2, 0xcd, 0x55, 0xea, 0x49, 0x62,
921
-	0x2f, 0x86, 0x24, 0xcc, 0xbc, 0xa6, 0x48, 0xfa, 0xb9, 0x16, 0xd7, 0x2a, 0x97, 0x18, 0x79, 0xbc,
922
-	0xb5, 0x74, 0x4c, 0x06, 0x33, 0x55, 0x4c, 0x0b, 0x9e, 0x4b, 0xec, 0xfb, 0xdf, 0x77, 0xde, 0x65,
923
-	0x42, 0x2e, 0x72, 0xfe, 0xa0, 0x4b, 0x1c, 0xf8, 0xb1, 0x9d, 0xdf, 0x66, 0xaa, 0xd0, 0x25, 0x0e,
924
-	0x7f, 0x33, 0xe7, 0xe9, 0x11, 0x89, 0x1e, 0xb9, 0x31, 0x65, 0x85, 0x24, 0x0e, 0x93, 0xd1, 0x31,
925
-	0xa6, 0x6d, 0xdf, 0xd4, 0x75, 0x4d, 0x6f, 0x7c, 0x74, 0x59, 0x98, 0x72, 0x99, 0x6d, 0xde, 0x8d,
926
-	0xcf, 0xc8, 0xe8, 0x0f, 0x76, 0xa5, 0xa6, 0x72, 0xb9, 0xd9, 0x86, 0x93, 0x74, 0x9f, 0xf4, 0x16,
927
-	0x7c, 0x56, 0xb7, 0xdb, 0xf8, 0x97, 0xb5, 0xe6, 0xbc, 0x73, 0x0a, 0x17, 0x87, 0xab, 0x86, 0x05,
928
-	0x1f, 0x0d, 0x0b, 0xd6, 0x0d, 0x83, 0x67, 0xcb, 0xe0, 0xd5, 0x32, 0x78, 0xb7, 0x0c, 0x56, 0x96,
929
-	0xc1, 0xa7, 0x65, 0xf0, 0x6d, 0x59, 0xb0, 0xb6, 0x0c, 0x5e, 0xbe, 0x58, 0x70, 0x1b, 0xf9, 0x03,
930
-	0x9c, 0xfc, 0x04, 0x00, 0x00, 0xff, 0xff, 0x19, 0x97, 0x14, 0xf4, 0x8e, 0x01, 0x00, 0x00,
931
-}
932 1
deleted file mode 100644
... ...
@@ -1,17 +0,0 @@
1
-syntax = "proto3";
2
-
3
-package fsutil;
4
-
5
-message Stat {
6
-  string path = 1;
7
-  uint32 mode = 2;
8
-  uint32 uid = 3;
9
-  uint32 gid = 4;
10
-  int64 size = 5;
11
-  int64 modTime = 6;
12
-  // int32 typeflag = 7;
13
-  string linkname = 7;
14
-  int64 devmajor = 8;
15
-  int64 devminor = 9;
16
-  map<string, bytes> xattrs = 10;
17
-}
18 1
\ No newline at end of file
19 2
new file mode 100644
... ...
@@ -0,0 +1,67 @@
0
+// +build !windows
1
+
2
+package fsutil
3
+
4
+import (
5
+	"os"
6
+	"syscall"
7
+
8
+	"github.com/containerd/continuity/sysx"
9
+	"github.com/pkg/errors"
10
+	"github.com/tonistiigi/fsutil/types"
11
+)
12
+
13
+func loadXattr(origpath string, stat *types.Stat) error {
14
+	xattrs, err := sysx.LListxattr(origpath)
15
+	if err != nil {
16
+		if errors.Cause(err) == syscall.ENOTSUP {
17
+			return nil
18
+		}
19
+		return errors.Wrapf(err, "failed to xattr %s", origpath)
20
+	}
21
+	if len(xattrs) > 0 {
22
+		m := make(map[string][]byte)
23
+		for _, key := range xattrs {
24
+			v, err := sysx.LGetxattr(origpath, key)
25
+			if err == nil {
26
+				m[key] = v
27
+			}
28
+		}
29
+		stat.Xattrs = m
30
+	}
31
+	return nil
32
+}
33
+
34
+func setUnixOpt(fi os.FileInfo, stat *types.Stat, path string, seenFiles map[uint64]string) {
35
+	s := fi.Sys().(*syscall.Stat_t)
36
+
37
+	stat.Uid = s.Uid
38
+	stat.Gid = s.Gid
39
+
40
+	if !fi.IsDir() {
41
+		if s.Mode&syscall.S_IFBLK != 0 ||
42
+			s.Mode&syscall.S_IFCHR != 0 {
43
+			stat.Devmajor = int64(major(uint64(s.Rdev)))
44
+			stat.Devminor = int64(minor(uint64(s.Rdev)))
45
+		}
46
+
47
+		ino := s.Ino
48
+		if seenFiles != nil {
49
+			if s.Nlink > 1 {
50
+				if oldpath, ok := seenFiles[ino]; ok {
51
+					stat.Linkname = oldpath
52
+					stat.Size_ = 0
53
+				}
54
+			}
55
+			seenFiles[ino] = path
56
+		}
57
+	}
58
+}
59
+
60
+func major(device uint64) uint64 {
61
+	return (device >> 8) & 0xfff
62
+}
63
+
64
+func minor(device uint64) uint64 {
65
+	return (device & 0xff) | ((device >> 12) & 0xfff00)
66
+}
0 67
new file mode 100644
... ...
@@ -0,0 +1,16 @@
0
+// +build windows
1
+
2
+package fsutil
3
+
4
+import (
5
+	"os"
6
+
7
+	"github.com/tonistiigi/fsutil/types"
8
+)
9
+
10
+func loadXattr(_ string, _ *types.Stat) error {
11
+	return nil
12
+}
13
+
14
+func setUnixOpt(_ os.FileInfo, _ *types.Stat, _ string, _ map[uint64]string) {
15
+}
0 16
new file mode 100644
... ...
@@ -0,0 +1,3 @@
0
+package types
1
+
2
+//go:generate protoc --gogoslick_out=. stat.proto wire.proto
0 3
new file mode 100644
... ...
@@ -0,0 +1,909 @@
0
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
1
+// source: stat.proto
2
+
3
+/*
4
+	Package types is a generated protocol buffer package.
5
+
6
+	It is generated from these files:
7
+		stat.proto
8
+		wire.proto
9
+
10
+	It has these top-level messages:
11
+		Stat
12
+		Packet
13
+*/
14
+package types
15
+
16
+import proto "github.com/gogo/protobuf/proto"
17
+import fmt "fmt"
18
+import math "math"
19
+
20
+import bytes "bytes"
21
+
22
+import strings "strings"
23
+import reflect "reflect"
24
+import sortkeys "github.com/gogo/protobuf/sortkeys"
25
+
26
+import io "io"
27
+
28
+// Reference imports to suppress errors if they are not otherwise used.
29
+var _ = proto.Marshal
30
+var _ = fmt.Errorf
31
+var _ = math.Inf
32
+
33
+// This is a compile-time assertion to ensure that this generated file
34
+// is compatible with the proto package it is being compiled against.
35
+// A compilation error at this line likely means your copy of the
36
+// proto package needs to be updated.
37
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
38
+
39
+type Stat struct {
40
+	Path    string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
41
+	Mode    uint32 `protobuf:"varint,2,opt,name=mode,proto3" json:"mode,omitempty"`
42
+	Uid     uint32 `protobuf:"varint,3,opt,name=uid,proto3" json:"uid,omitempty"`
43
+	Gid     uint32 `protobuf:"varint,4,opt,name=gid,proto3" json:"gid,omitempty"`
44
+	Size_   int64  `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"`
45
+	ModTime int64  `protobuf:"varint,6,opt,name=modTime,proto3" json:"modTime,omitempty"`
46
+	// int32 typeflag = 7;
47
+	Linkname string            `protobuf:"bytes,7,opt,name=linkname,proto3" json:"linkname,omitempty"`
48
+	Devmajor int64             `protobuf:"varint,8,opt,name=devmajor,proto3" json:"devmajor,omitempty"`
49
+	Devminor int64             `protobuf:"varint,9,opt,name=devminor,proto3" json:"devminor,omitempty"`
50
+	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"`
51
+}
52
+
53
+func (m *Stat) Reset()                    { *m = Stat{} }
54
+func (*Stat) ProtoMessage()               {}
55
+func (*Stat) Descriptor() ([]byte, []int) { return fileDescriptorStat, []int{0} }
56
+
57
+func (m *Stat) GetPath() string {
58
+	if m != nil {
59
+		return m.Path
60
+	}
61
+	return ""
62
+}
63
+
64
+func (m *Stat) GetMode() uint32 {
65
+	if m != nil {
66
+		return m.Mode
67
+	}
68
+	return 0
69
+}
70
+
71
+func (m *Stat) GetUid() uint32 {
72
+	if m != nil {
73
+		return m.Uid
74
+	}
75
+	return 0
76
+}
77
+
78
+func (m *Stat) GetGid() uint32 {
79
+	if m != nil {
80
+		return m.Gid
81
+	}
82
+	return 0
83
+}
84
+
85
+func (m *Stat) GetSize_() int64 {
86
+	if m != nil {
87
+		return m.Size_
88
+	}
89
+	return 0
90
+}
91
+
92
+func (m *Stat) GetModTime() int64 {
93
+	if m != nil {
94
+		return m.ModTime
95
+	}
96
+	return 0
97
+}
98
+
99
+func (m *Stat) GetLinkname() string {
100
+	if m != nil {
101
+		return m.Linkname
102
+	}
103
+	return ""
104
+}
105
+
106
+func (m *Stat) GetDevmajor() int64 {
107
+	if m != nil {
108
+		return m.Devmajor
109
+	}
110
+	return 0
111
+}
112
+
113
+func (m *Stat) GetDevminor() int64 {
114
+	if m != nil {
115
+		return m.Devminor
116
+	}
117
+	return 0
118
+}
119
+
120
+func (m *Stat) GetXattrs() map[string][]byte {
121
+	if m != nil {
122
+		return m.Xattrs
123
+	}
124
+	return nil
125
+}
126
+
127
+func init() {
128
+	proto.RegisterType((*Stat)(nil), "fsutil.types.Stat")
129
+}
130
+func (this *Stat) Equal(that interface{}) bool {
131
+	if that == nil {
132
+		return this == nil
133
+	}
134
+
135
+	that1, ok := that.(*Stat)
136
+	if !ok {
137
+		that2, ok := that.(Stat)
138
+		if ok {
139
+			that1 = &that2
140
+		} else {
141
+			return false
142
+		}
143
+	}
144
+	if that1 == nil {
145
+		return this == nil
146
+	} else if this == nil {
147
+		return false
148
+	}
149
+	if this.Path != that1.Path {
150
+		return false
151
+	}
152
+	if this.Mode != that1.Mode {
153
+		return false
154
+	}
155
+	if this.Uid != that1.Uid {
156
+		return false
157
+	}
158
+	if this.Gid != that1.Gid {
159
+		return false
160
+	}
161
+	if this.Size_ != that1.Size_ {
162
+		return false
163
+	}
164
+	if this.ModTime != that1.ModTime {
165
+		return false
166
+	}
167
+	if this.Linkname != that1.Linkname {
168
+		return false
169
+	}
170
+	if this.Devmajor != that1.Devmajor {
171
+		return false
172
+	}
173
+	if this.Devminor != that1.Devminor {
174
+		return false
175
+	}
176
+	if len(this.Xattrs) != len(that1.Xattrs) {
177
+		return false
178
+	}
179
+	for i := range this.Xattrs {
180
+		if !bytes.Equal(this.Xattrs[i], that1.Xattrs[i]) {
181
+			return false
182
+		}
183
+	}
184
+	return true
185
+}
186
+func (this *Stat) GoString() string {
187
+	if this == nil {
188
+		return "nil"
189
+	}
190
+	s := make([]string, 0, 14)
191
+	s = append(s, "&types.Stat{")
192
+	s = append(s, "Path: "+fmt.Sprintf("%#v", this.Path)+",\n")
193
+	s = append(s, "Mode: "+fmt.Sprintf("%#v", this.Mode)+",\n")
194
+	s = append(s, "Uid: "+fmt.Sprintf("%#v", this.Uid)+",\n")
195
+	s = append(s, "Gid: "+fmt.Sprintf("%#v", this.Gid)+",\n")
196
+	s = append(s, "Size_: "+fmt.Sprintf("%#v", this.Size_)+",\n")
197
+	s = append(s, "ModTime: "+fmt.Sprintf("%#v", this.ModTime)+",\n")
198
+	s = append(s, "Linkname: "+fmt.Sprintf("%#v", this.Linkname)+",\n")
199
+	s = append(s, "Devmajor: "+fmt.Sprintf("%#v", this.Devmajor)+",\n")
200
+	s = append(s, "Devminor: "+fmt.Sprintf("%#v", this.Devminor)+",\n")
201
+	keysForXattrs := make([]string, 0, len(this.Xattrs))
202
+	for k, _ := range this.Xattrs {
203
+		keysForXattrs = append(keysForXattrs, k)
204
+	}
205
+	sortkeys.Strings(keysForXattrs)
206
+	mapStringForXattrs := "map[string][]byte{"
207
+	for _, k := range keysForXattrs {
208
+		mapStringForXattrs += fmt.Sprintf("%#v: %#v,", k, this.Xattrs[k])
209
+	}
210
+	mapStringForXattrs += "}"
211
+	if this.Xattrs != nil {
212
+		s = append(s, "Xattrs: "+mapStringForXattrs+",\n")
213
+	}
214
+	s = append(s, "}")
215
+	return strings.Join(s, "")
216
+}
217
+func valueToGoStringStat(v interface{}, typ string) string {
218
+	rv := reflect.ValueOf(v)
219
+	if rv.IsNil() {
220
+		return "nil"
221
+	}
222
+	pv := reflect.Indirect(rv).Interface()
223
+	return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
224
+}
225
+func (m *Stat) Marshal() (dAtA []byte, err error) {
226
+	size := m.Size()
227
+	dAtA = make([]byte, size)
228
+	n, err := m.MarshalTo(dAtA)
229
+	if err != nil {
230
+		return nil, err
231
+	}
232
+	return dAtA[:n], nil
233
+}
234
+
235
+func (m *Stat) MarshalTo(dAtA []byte) (int, error) {
236
+	var i int
237
+	_ = i
238
+	var l int
239
+	_ = l
240
+	if len(m.Path) > 0 {
241
+		dAtA[i] = 0xa
242
+		i++
243
+		i = encodeVarintStat(dAtA, i, uint64(len(m.Path)))
244
+		i += copy(dAtA[i:], m.Path)
245
+	}
246
+	if m.Mode != 0 {
247
+		dAtA[i] = 0x10
248
+		i++
249
+		i = encodeVarintStat(dAtA, i, uint64(m.Mode))
250
+	}
251
+	if m.Uid != 0 {
252
+		dAtA[i] = 0x18
253
+		i++
254
+		i = encodeVarintStat(dAtA, i, uint64(m.Uid))
255
+	}
256
+	if m.Gid != 0 {
257
+		dAtA[i] = 0x20
258
+		i++
259
+		i = encodeVarintStat(dAtA, i, uint64(m.Gid))
260
+	}
261
+	if m.Size_ != 0 {
262
+		dAtA[i] = 0x28
263
+		i++
264
+		i = encodeVarintStat(dAtA, i, uint64(m.Size_))
265
+	}
266
+	if m.ModTime != 0 {
267
+		dAtA[i] = 0x30
268
+		i++
269
+		i = encodeVarintStat(dAtA, i, uint64(m.ModTime))
270
+	}
271
+	if len(m.Linkname) > 0 {
272
+		dAtA[i] = 0x3a
273
+		i++
274
+		i = encodeVarintStat(dAtA, i, uint64(len(m.Linkname)))
275
+		i += copy(dAtA[i:], m.Linkname)
276
+	}
277
+	if m.Devmajor != 0 {
278
+		dAtA[i] = 0x40
279
+		i++
280
+		i = encodeVarintStat(dAtA, i, uint64(m.Devmajor))
281
+	}
282
+	if m.Devminor != 0 {
283
+		dAtA[i] = 0x48
284
+		i++
285
+		i = encodeVarintStat(dAtA, i, uint64(m.Devminor))
286
+	}
287
+	if len(m.Xattrs) > 0 {
288
+		for k, _ := range m.Xattrs {
289
+			dAtA[i] = 0x52
290
+			i++
291
+			v := m.Xattrs[k]
292
+			byteSize := 0
293
+			if len(v) > 0 {
294
+				byteSize = 1 + len(v) + sovStat(uint64(len(v)))
295
+			}
296
+			mapSize := 1 + len(k) + sovStat(uint64(len(k))) + byteSize
297
+			i = encodeVarintStat(dAtA, i, uint64(mapSize))
298
+			dAtA[i] = 0xa
299
+			i++
300
+			i = encodeVarintStat(dAtA, i, uint64(len(k)))
301
+			i += copy(dAtA[i:], k)
302
+			if len(v) > 0 {
303
+				dAtA[i] = 0x12
304
+				i++
305
+				i = encodeVarintStat(dAtA, i, uint64(len(v)))
306
+				i += copy(dAtA[i:], v)
307
+			}
308
+		}
309
+	}
310
+	return i, nil
311
+}
312
+
313
+func encodeVarintStat(dAtA []byte, offset int, v uint64) int {
314
+	for v >= 1<<7 {
315
+		dAtA[offset] = uint8(v&0x7f | 0x80)
316
+		v >>= 7
317
+		offset++
318
+	}
319
+	dAtA[offset] = uint8(v)
320
+	return offset + 1
321
+}
322
+func (m *Stat) Size() (n int) {
323
+	var l int
324
+	_ = l
325
+	l = len(m.Path)
326
+	if l > 0 {
327
+		n += 1 + l + sovStat(uint64(l))
328
+	}
329
+	if m.Mode != 0 {
330
+		n += 1 + sovStat(uint64(m.Mode))
331
+	}
332
+	if m.Uid != 0 {
333
+		n += 1 + sovStat(uint64(m.Uid))
334
+	}
335
+	if m.Gid != 0 {
336
+		n += 1 + sovStat(uint64(m.Gid))
337
+	}
338
+	if m.Size_ != 0 {
339
+		n += 1 + sovStat(uint64(m.Size_))
340
+	}
341
+	if m.ModTime != 0 {
342
+		n += 1 + sovStat(uint64(m.ModTime))
343
+	}
344
+	l = len(m.Linkname)
345
+	if l > 0 {
346
+		n += 1 + l + sovStat(uint64(l))
347
+	}
348
+	if m.Devmajor != 0 {
349
+		n += 1 + sovStat(uint64(m.Devmajor))
350
+	}
351
+	if m.Devminor != 0 {
352
+		n += 1 + sovStat(uint64(m.Devminor))
353
+	}
354
+	if len(m.Xattrs) > 0 {
355
+		for k, v := range m.Xattrs {
356
+			_ = k
357
+			_ = v
358
+			l = 0
359
+			if len(v) > 0 {
360
+				l = 1 + len(v) + sovStat(uint64(len(v)))
361
+			}
362
+			mapEntrySize := 1 + len(k) + sovStat(uint64(len(k))) + l
363
+			n += mapEntrySize + 1 + sovStat(uint64(mapEntrySize))
364
+		}
365
+	}
366
+	return n
367
+}
368
+
369
+func sovStat(x uint64) (n int) {
370
+	for {
371
+		n++
372
+		x >>= 7
373
+		if x == 0 {
374
+			break
375
+		}
376
+	}
377
+	return n
378
+}
379
+func sozStat(x uint64) (n int) {
380
+	return sovStat(uint64((x << 1) ^ uint64((int64(x) >> 63))))
381
+}
382
+func (this *Stat) String() string {
383
+	if this == nil {
384
+		return "nil"
385
+	}
386
+	keysForXattrs := make([]string, 0, len(this.Xattrs))
387
+	for k, _ := range this.Xattrs {
388
+		keysForXattrs = append(keysForXattrs, k)
389
+	}
390
+	sortkeys.Strings(keysForXattrs)
391
+	mapStringForXattrs := "map[string][]byte{"
392
+	for _, k := range keysForXattrs {
393
+		mapStringForXattrs += fmt.Sprintf("%v: %v,", k, this.Xattrs[k])
394
+	}
395
+	mapStringForXattrs += "}"
396
+	s := strings.Join([]string{`&Stat{`,
397
+		`Path:` + fmt.Sprintf("%v", this.Path) + `,`,
398
+		`Mode:` + fmt.Sprintf("%v", this.Mode) + `,`,
399
+		`Uid:` + fmt.Sprintf("%v", this.Uid) + `,`,
400
+		`Gid:` + fmt.Sprintf("%v", this.Gid) + `,`,
401
+		`Size_:` + fmt.Sprintf("%v", this.Size_) + `,`,
402
+		`ModTime:` + fmt.Sprintf("%v", this.ModTime) + `,`,
403
+		`Linkname:` + fmt.Sprintf("%v", this.Linkname) + `,`,
404
+		`Devmajor:` + fmt.Sprintf("%v", this.Devmajor) + `,`,
405
+		`Devminor:` + fmt.Sprintf("%v", this.Devminor) + `,`,
406
+		`Xattrs:` + mapStringForXattrs + `,`,
407
+		`}`,
408
+	}, "")
409
+	return s
410
+}
411
+func valueToStringStat(v interface{}) string {
412
+	rv := reflect.ValueOf(v)
413
+	if rv.IsNil() {
414
+		return "nil"
415
+	}
416
+	pv := reflect.Indirect(rv).Interface()
417
+	return fmt.Sprintf("*%v", pv)
418
+}
419
+func (m *Stat) Unmarshal(dAtA []byte) error {
420
+	l := len(dAtA)
421
+	iNdEx := 0
422
+	for iNdEx < l {
423
+		preIndex := iNdEx
424
+		var wire uint64
425
+		for shift := uint(0); ; shift += 7 {
426
+			if shift >= 64 {
427
+				return ErrIntOverflowStat
428
+			}
429
+			if iNdEx >= l {
430
+				return io.ErrUnexpectedEOF
431
+			}
432
+			b := dAtA[iNdEx]
433
+			iNdEx++
434
+			wire |= (uint64(b) & 0x7F) << shift
435
+			if b < 0x80 {
436
+				break
437
+			}
438
+		}
439
+		fieldNum := int32(wire >> 3)
440
+		wireType := int(wire & 0x7)
441
+		if wireType == 4 {
442
+			return fmt.Errorf("proto: Stat: wiretype end group for non-group")
443
+		}
444
+		if fieldNum <= 0 {
445
+			return fmt.Errorf("proto: Stat: illegal tag %d (wire type %d)", fieldNum, wire)
446
+		}
447
+		switch fieldNum {
448
+		case 1:
449
+			if wireType != 2 {
450
+				return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType)
451
+			}
452
+			var stringLen uint64
453
+			for shift := uint(0); ; shift += 7 {
454
+				if shift >= 64 {
455
+					return ErrIntOverflowStat
456
+				}
457
+				if iNdEx >= l {
458
+					return io.ErrUnexpectedEOF
459
+				}
460
+				b := dAtA[iNdEx]
461
+				iNdEx++
462
+				stringLen |= (uint64(b) & 0x7F) << shift
463
+				if b < 0x80 {
464
+					break
465
+				}
466
+			}
467
+			intStringLen := int(stringLen)
468
+			if intStringLen < 0 {
469
+				return ErrInvalidLengthStat
470
+			}
471
+			postIndex := iNdEx + intStringLen
472
+			if postIndex > l {
473
+				return io.ErrUnexpectedEOF
474
+			}
475
+			m.Path = string(dAtA[iNdEx:postIndex])
476
+			iNdEx = postIndex
477
+		case 2:
478
+			if wireType != 0 {
479
+				return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType)
480
+			}
481
+			m.Mode = 0
482
+			for shift := uint(0); ; shift += 7 {
483
+				if shift >= 64 {
484
+					return ErrIntOverflowStat
485
+				}
486
+				if iNdEx >= l {
487
+					return io.ErrUnexpectedEOF
488
+				}
489
+				b := dAtA[iNdEx]
490
+				iNdEx++
491
+				m.Mode |= (uint32(b) & 0x7F) << shift
492
+				if b < 0x80 {
493
+					break
494
+				}
495
+			}
496
+		case 3:
497
+			if wireType != 0 {
498
+				return fmt.Errorf("proto: wrong wireType = %d for field Uid", wireType)
499
+			}
500
+			m.Uid = 0
501
+			for shift := uint(0); ; shift += 7 {
502
+				if shift >= 64 {
503
+					return ErrIntOverflowStat
504
+				}
505
+				if iNdEx >= l {
506
+					return io.ErrUnexpectedEOF
507
+				}
508
+				b := dAtA[iNdEx]
509
+				iNdEx++
510
+				m.Uid |= (uint32(b) & 0x7F) << shift
511
+				if b < 0x80 {
512
+					break
513
+				}
514
+			}
515
+		case 4:
516
+			if wireType != 0 {
517
+				return fmt.Errorf("proto: wrong wireType = %d for field Gid", wireType)
518
+			}
519
+			m.Gid = 0
520
+			for shift := uint(0); ; shift += 7 {
521
+				if shift >= 64 {
522
+					return ErrIntOverflowStat
523
+				}
524
+				if iNdEx >= l {
525
+					return io.ErrUnexpectedEOF
526
+				}
527
+				b := dAtA[iNdEx]
528
+				iNdEx++
529
+				m.Gid |= (uint32(b) & 0x7F) << shift
530
+				if b < 0x80 {
531
+					break
532
+				}
533
+			}
534
+		case 5:
535
+			if wireType != 0 {
536
+				return fmt.Errorf("proto: wrong wireType = %d for field Size_", wireType)
537
+			}
538
+			m.Size_ = 0
539
+			for shift := uint(0); ; shift += 7 {
540
+				if shift >= 64 {
541
+					return ErrIntOverflowStat
542
+				}
543
+				if iNdEx >= l {
544
+					return io.ErrUnexpectedEOF
545
+				}
546
+				b := dAtA[iNdEx]
547
+				iNdEx++
548
+				m.Size_ |= (int64(b) & 0x7F) << shift
549
+				if b < 0x80 {
550
+					break
551
+				}
552
+			}
553
+		case 6:
554
+			if wireType != 0 {
555
+				return fmt.Errorf("proto: wrong wireType = %d for field ModTime", wireType)
556
+			}
557
+			m.ModTime = 0
558
+			for shift := uint(0); ; shift += 7 {
559
+				if shift >= 64 {
560
+					return ErrIntOverflowStat
561
+				}
562
+				if iNdEx >= l {
563
+					return io.ErrUnexpectedEOF
564
+				}
565
+				b := dAtA[iNdEx]
566
+				iNdEx++
567
+				m.ModTime |= (int64(b) & 0x7F) << shift
568
+				if b < 0x80 {
569
+					break
570
+				}
571
+			}
572
+		case 7:
573
+			if wireType != 2 {
574
+				return fmt.Errorf("proto: wrong wireType = %d for field Linkname", wireType)
575
+			}
576
+			var stringLen uint64
577
+			for shift := uint(0); ; shift += 7 {
578
+				if shift >= 64 {
579
+					return ErrIntOverflowStat
580
+				}
581
+				if iNdEx >= l {
582
+					return io.ErrUnexpectedEOF
583
+				}
584
+				b := dAtA[iNdEx]
585
+				iNdEx++
586
+				stringLen |= (uint64(b) & 0x7F) << shift
587
+				if b < 0x80 {
588
+					break
589
+				}
590
+			}
591
+			intStringLen := int(stringLen)
592
+			if intStringLen < 0 {
593
+				return ErrInvalidLengthStat
594
+			}
595
+			postIndex := iNdEx + intStringLen
596
+			if postIndex > l {
597
+				return io.ErrUnexpectedEOF
598
+			}
599
+			m.Linkname = string(dAtA[iNdEx:postIndex])
600
+			iNdEx = postIndex
601
+		case 8:
602
+			if wireType != 0 {
603
+				return fmt.Errorf("proto: wrong wireType = %d for field Devmajor", wireType)
604
+			}
605
+			m.Devmajor = 0
606
+			for shift := uint(0); ; shift += 7 {
607
+				if shift >= 64 {
608
+					return ErrIntOverflowStat
609
+				}
610
+				if iNdEx >= l {
611
+					return io.ErrUnexpectedEOF
612
+				}
613
+				b := dAtA[iNdEx]
614
+				iNdEx++
615
+				m.Devmajor |= (int64(b) & 0x7F) << shift
616
+				if b < 0x80 {
617
+					break
618
+				}
619
+			}
620
+		case 9:
621
+			if wireType != 0 {
622
+				return fmt.Errorf("proto: wrong wireType = %d for field Devminor", wireType)
623
+			}
624
+			m.Devminor = 0
625
+			for shift := uint(0); ; shift += 7 {
626
+				if shift >= 64 {
627
+					return ErrIntOverflowStat
628
+				}
629
+				if iNdEx >= l {
630
+					return io.ErrUnexpectedEOF
631
+				}
632
+				b := dAtA[iNdEx]
633
+				iNdEx++
634
+				m.Devminor |= (int64(b) & 0x7F) << shift
635
+				if b < 0x80 {
636
+					break
637
+				}
638
+			}
639
+		case 10:
640
+			if wireType != 2 {
641
+				return fmt.Errorf("proto: wrong wireType = %d for field Xattrs", wireType)
642
+			}
643
+			var msglen int
644
+			for shift := uint(0); ; shift += 7 {
645
+				if shift >= 64 {
646
+					return ErrIntOverflowStat
647
+				}
648
+				if iNdEx >= l {
649
+					return io.ErrUnexpectedEOF
650
+				}
651
+				b := dAtA[iNdEx]
652
+				iNdEx++
653
+				msglen |= (int(b) & 0x7F) << shift
654
+				if b < 0x80 {
655
+					break
656
+				}
657
+			}
658
+			if msglen < 0 {
659
+				return ErrInvalidLengthStat
660
+			}
661
+			postIndex := iNdEx + msglen
662
+			if postIndex > l {
663
+				return io.ErrUnexpectedEOF
664
+			}
665
+			if m.Xattrs == nil {
666
+				m.Xattrs = make(map[string][]byte)
667
+			}
668
+			var mapkey string
669
+			mapvalue := []byte{}
670
+			for iNdEx < postIndex {
671
+				entryPreIndex := iNdEx
672
+				var wire uint64
673
+				for shift := uint(0); ; shift += 7 {
674
+					if shift >= 64 {
675
+						return ErrIntOverflowStat
676
+					}
677
+					if iNdEx >= l {
678
+						return io.ErrUnexpectedEOF
679
+					}
680
+					b := dAtA[iNdEx]
681
+					iNdEx++
682
+					wire |= (uint64(b) & 0x7F) << shift
683
+					if b < 0x80 {
684
+						break
685
+					}
686
+				}
687
+				fieldNum := int32(wire >> 3)
688
+				if fieldNum == 1 {
689
+					var stringLenmapkey uint64
690
+					for shift := uint(0); ; shift += 7 {
691
+						if shift >= 64 {
692
+							return ErrIntOverflowStat
693
+						}
694
+						if iNdEx >= l {
695
+							return io.ErrUnexpectedEOF
696
+						}
697
+						b := dAtA[iNdEx]
698
+						iNdEx++
699
+						stringLenmapkey |= (uint64(b) & 0x7F) << shift
700
+						if b < 0x80 {
701
+							break
702
+						}
703
+					}
704
+					intStringLenmapkey := int(stringLenmapkey)
705
+					if intStringLenmapkey < 0 {
706
+						return ErrInvalidLengthStat
707
+					}
708
+					postStringIndexmapkey := iNdEx + intStringLenmapkey
709
+					if postStringIndexmapkey > l {
710
+						return io.ErrUnexpectedEOF
711
+					}
712
+					mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
713
+					iNdEx = postStringIndexmapkey
714
+				} else if fieldNum == 2 {
715
+					var mapbyteLen uint64
716
+					for shift := uint(0); ; shift += 7 {
717
+						if shift >= 64 {
718
+							return ErrIntOverflowStat
719
+						}
720
+						if iNdEx >= l {
721
+							return io.ErrUnexpectedEOF
722
+						}
723
+						b := dAtA[iNdEx]
724
+						iNdEx++
725
+						mapbyteLen |= (uint64(b) & 0x7F) << shift
726
+						if b < 0x80 {
727
+							break
728
+						}
729
+					}
730
+					intMapbyteLen := int(mapbyteLen)
731
+					if intMapbyteLen < 0 {
732
+						return ErrInvalidLengthStat
733
+					}
734
+					postbytesIndex := iNdEx + intMapbyteLen
735
+					if postbytesIndex > l {
736
+						return io.ErrUnexpectedEOF
737
+					}
738
+					mapvalue = make([]byte, mapbyteLen)
739
+					copy(mapvalue, dAtA[iNdEx:postbytesIndex])
740
+					iNdEx = postbytesIndex
741
+				} else {
742
+					iNdEx = entryPreIndex
743
+					skippy, err := skipStat(dAtA[iNdEx:])
744
+					if err != nil {
745
+						return err
746
+					}
747
+					if skippy < 0 {
748
+						return ErrInvalidLengthStat
749
+					}
750
+					if (iNdEx + skippy) > postIndex {
751
+						return io.ErrUnexpectedEOF
752
+					}
753
+					iNdEx += skippy
754
+				}
755
+			}
756
+			m.Xattrs[mapkey] = mapvalue
757
+			iNdEx = postIndex
758
+		default:
759
+			iNdEx = preIndex
760
+			skippy, err := skipStat(dAtA[iNdEx:])
761
+			if err != nil {
762
+				return err
763
+			}
764
+			if skippy < 0 {
765
+				return ErrInvalidLengthStat
766
+			}
767
+			if (iNdEx + skippy) > l {
768
+				return io.ErrUnexpectedEOF
769
+			}
770
+			iNdEx += skippy
771
+		}
772
+	}
773
+
774
+	if iNdEx > l {
775
+		return io.ErrUnexpectedEOF
776
+	}
777
+	return nil
778
+}
779
+func skipStat(dAtA []byte) (n int, err error) {
780
+	l := len(dAtA)
781
+	iNdEx := 0
782
+	for iNdEx < l {
783
+		var wire uint64
784
+		for shift := uint(0); ; shift += 7 {
785
+			if shift >= 64 {
786
+				return 0, ErrIntOverflowStat
787
+			}
788
+			if iNdEx >= l {
789
+				return 0, io.ErrUnexpectedEOF
790
+			}
791
+			b := dAtA[iNdEx]
792
+			iNdEx++
793
+			wire |= (uint64(b) & 0x7F) << shift
794
+			if b < 0x80 {
795
+				break
796
+			}
797
+		}
798
+		wireType := int(wire & 0x7)
799
+		switch wireType {
800
+		case 0:
801
+			for shift := uint(0); ; shift += 7 {
802
+				if shift >= 64 {
803
+					return 0, ErrIntOverflowStat
804
+				}
805
+				if iNdEx >= l {
806
+					return 0, io.ErrUnexpectedEOF
807
+				}
808
+				iNdEx++
809
+				if dAtA[iNdEx-1] < 0x80 {
810
+					break
811
+				}
812
+			}
813
+			return iNdEx, nil
814
+		case 1:
815
+			iNdEx += 8
816
+			return iNdEx, nil
817
+		case 2:
818
+			var length int
819
+			for shift := uint(0); ; shift += 7 {
820
+				if shift >= 64 {
821
+					return 0, ErrIntOverflowStat
822
+				}
823
+				if iNdEx >= l {
824
+					return 0, io.ErrUnexpectedEOF
825
+				}
826
+				b := dAtA[iNdEx]
827
+				iNdEx++
828
+				length |= (int(b) & 0x7F) << shift
829
+				if b < 0x80 {
830
+					break
831
+				}
832
+			}
833
+			iNdEx += length
834
+			if length < 0 {
835
+				return 0, ErrInvalidLengthStat
836
+			}
837
+			return iNdEx, nil
838
+		case 3:
839
+			for {
840
+				var innerWire uint64
841
+				var start int = iNdEx
842
+				for shift := uint(0); ; shift += 7 {
843
+					if shift >= 64 {
844
+						return 0, ErrIntOverflowStat
845
+					}
846
+					if iNdEx >= l {
847
+						return 0, io.ErrUnexpectedEOF
848
+					}
849
+					b := dAtA[iNdEx]
850
+					iNdEx++
851
+					innerWire |= (uint64(b) & 0x7F) << shift
852
+					if b < 0x80 {
853
+						break
854
+					}
855
+				}
856
+				innerWireType := int(innerWire & 0x7)
857
+				if innerWireType == 4 {
858
+					break
859
+				}
860
+				next, err := skipStat(dAtA[start:])
861
+				if err != nil {
862
+					return 0, err
863
+				}
864
+				iNdEx = start + next
865
+			}
866
+			return iNdEx, nil
867
+		case 4:
868
+			return iNdEx, nil
869
+		case 5:
870
+			iNdEx += 4
871
+			return iNdEx, nil
872
+		default:
873
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
874
+		}
875
+	}
876
+	panic("unreachable")
877
+}
878
+
879
+var (
880
+	ErrInvalidLengthStat = fmt.Errorf("proto: negative length found during unmarshaling")
881
+	ErrIntOverflowStat   = fmt.Errorf("proto: integer overflow")
882
+)
883
+
884
+func init() { proto.RegisterFile("stat.proto", fileDescriptorStat) }
885
+
886
+var fileDescriptorStat = []byte{
887
+	// 310 bytes of a gzipped FileDescriptorProto
888
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x91, 0xbd, 0x4e, 0xc3, 0x30,
889
+	0x14, 0x85, 0x73, 0x9b, 0xfe, 0xba, 0x45, 0x42, 0x16, 0x83, 0xd5, 0xe1, 0x2a, 0x62, 0xca, 0x94,
890
+	0x81, 0x4a, 0x08, 0x18, 0x91, 0x78, 0x81, 0xc0, 0x80, 0xd8, 0x8c, 0x6c, 0x8a, 0x69, 0x13, 0x57,
891
+	0x89, 0x5b, 0x51, 0x26, 0x1e, 0x81, 0xc7, 0xe0, 0x4d, 0x60, 0xec, 0xc8, 0x48, 0xcc, 0xc2, 0xd8,
892
+	0x47, 0x40, 0x76, 0xda, 0xd2, 0xed, 0x9c, 0xef, 0xdc, 0xab, 0xe4, 0x5c, 0x13, 0x52, 0x1a, 0x6e,
893
+	0x92, 0x59, 0xa1, 0x8d, 0xa6, 0x83, 0x87, 0x72, 0x6e, 0xd4, 0x34, 0x31, 0xcb, 0x99, 0x2c, 0x8f,
894
+	0x3f, 0x1a, 0xa4, 0x79, 0x6d, 0xb8, 0xa1, 0x94, 0x34, 0x67, 0xdc, 0x3c, 0x32, 0x88, 0x20, 0xee,
895
+	0xa5, 0x5e, 0x3b, 0x96, 0x69, 0x21, 0x59, 0x23, 0x82, 0xf8, 0x20, 0xf5, 0x9a, 0x1e, 0x92, 0x70,
896
+	0xae, 0x04, 0x0b, 0x3d, 0x72, 0xd2, 0x91, 0xb1, 0x12, 0xac, 0x59, 0x93, 0xb1, 0x12, 0x6e, 0xaf,
897
+	0x54, 0x2f, 0x92, 0xb5, 0x22, 0x88, 0xc3, 0xd4, 0x6b, 0xca, 0x48, 0x27, 0xd3, 0xe2, 0x46, 0x65,
898
+	0x92, 0xb5, 0x3d, 0xde, 0x5a, 0x3a, 0x24, 0xdd, 0xa9, 0xca, 0x27, 0x39, 0xcf, 0x24, 0xeb, 0xf8,
899
+	0xaf, 0xef, 0xbc, 0xcb, 0x84, 0x5c, 0x64, 0xfc, 0x49, 0x17, 0xac, 0xeb, 0xd7, 0x76, 0x7e, 0x9b,
900
+	0xa9, 0x5c, 0x17, 0xac, 0xf7, 0x9f, 0x39, 0x4f, 0x4f, 0x49, 0xfb, 0x99, 0x1b, 0x53, 0x94, 0x8c,
901
+	0x44, 0x61, 0xdc, 0x3f, 0xc1, 0x64, 0xbf, 0x75, 0xe2, 0x1a, 0x27, 0xb7, 0x7e, 0xe0, 0x2a, 0x37,
902
+	0xc5, 0x32, 0xdd, 0x4c, 0x0f, 0xcf, 0x49, 0x7f, 0x0f, 0xbb, 0x6a, 0x13, 0xb9, 0xdc, 0xdc, 0xc4,
903
+	0x49, 0x7a, 0x44, 0x5a, 0x0b, 0x3e, 0x9d, 0xd7, 0x37, 0x19, 0xa4, 0xb5, 0xb9, 0x68, 0x9c, 0xc1,
904
+	0xe5, 0x68, 0x55, 0x61, 0xf0, 0x55, 0x61, 0xb0, 0xae, 0x10, 0x5e, 0x2d, 0xc2, 0xbb, 0x45, 0xf8,
905
+	0xb4, 0x08, 0x2b, 0x8b, 0xf0, 0x6d, 0x11, 0x7e, 0x2d, 0x06, 0x6b, 0x8b, 0xf0, 0xf6, 0x83, 0xc1,
906
+	0x5d, 0xcb, 0xff, 0xc8, 0x7d, 0xdb, 0xbf, 0xc9, 0xe8, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x90, 0xc2,
907
+	0xcf, 0x79, 0xa1, 0x01, 0x00, 0x00,
908
+}
0 909
new file mode 100644
... ...
@@ -0,0 +1,19 @@
0
+syntax = "proto3";
1
+
2
+package fsutil.types;
3
+
4
+option go_package = "types";
5
+
6
+message Stat {
7
+  string path = 1;
8
+  uint32 mode = 2;
9
+  uint32 uid = 3;
10
+  uint32 gid = 4;
11
+  int64 size = 5;
12
+  int64 modTime = 6;
13
+  // int32 typeflag = 7;
14
+  string linkname = 7;
15
+  int64 devmajor = 8;
16
+  int64 devminor = 9;
17
+  map<string, bytes> xattrs = 10;
18
+}
0 19
\ No newline at end of file
1 20
new file mode 100644
... ...
@@ -0,0 +1,542 @@
0
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
1
+// source: wire.proto
2
+
3
+package types
4
+
5
+import proto "github.com/gogo/protobuf/proto"
6
+import fmt "fmt"
7
+import math "math"
8
+
9
+import strconv "strconv"
10
+
11
+import bytes "bytes"
12
+
13
+import strings "strings"
14
+import reflect "reflect"
15
+
16
+import io "io"
17
+
18
+// Reference imports to suppress errors if they are not otherwise used.
19
+var _ = proto.Marshal
20
+var _ = fmt.Errorf
21
+var _ = math.Inf
22
+
23
+type Packet_PacketType int32
24
+
25
+const (
26
+	PACKET_STAT Packet_PacketType = 0
27
+	PACKET_REQ  Packet_PacketType = 1
28
+	PACKET_DATA Packet_PacketType = 2
29
+	PACKET_FIN  Packet_PacketType = 3
30
+	PACKET_ERR  Packet_PacketType = 4
31
+)
32
+
33
+var Packet_PacketType_name = map[int32]string{
34
+	0: "PACKET_STAT",
35
+	1: "PACKET_REQ",
36
+	2: "PACKET_DATA",
37
+	3: "PACKET_FIN",
38
+	4: "PACKET_ERR",
39
+}
40
+var Packet_PacketType_value = map[string]int32{
41
+	"PACKET_STAT": 0,
42
+	"PACKET_REQ":  1,
43
+	"PACKET_DATA": 2,
44
+	"PACKET_FIN":  3,
45
+	"PACKET_ERR":  4,
46
+}
47
+
48
+func (Packet_PacketType) EnumDescriptor() ([]byte, []int) { return fileDescriptorWire, []int{0, 0} }
49
+
50
+type Packet struct {
51
+	Type Packet_PacketType `protobuf:"varint,1,opt,name=type,proto3,enum=fsutil.types.Packet_PacketType" json:"type,omitempty"`
52
+	Stat *Stat             `protobuf:"bytes,2,opt,name=stat" json:"stat,omitempty"`
53
+	ID   uint32            `protobuf:"varint,3,opt,name=ID,proto3" json:"ID,omitempty"`
54
+	Data []byte            `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
55
+}
56
+
57
+func (m *Packet) Reset()                    { *m = Packet{} }
58
+func (*Packet) ProtoMessage()               {}
59
+func (*Packet) Descriptor() ([]byte, []int) { return fileDescriptorWire, []int{0} }
60
+
61
+func (m *Packet) GetType() Packet_PacketType {
62
+	if m != nil {
63
+		return m.Type
64
+	}
65
+	return PACKET_STAT
66
+}
67
+
68
+func (m *Packet) GetStat() *Stat {
69
+	if m != nil {
70
+		return m.Stat
71
+	}
72
+	return nil
73
+}
74
+
75
+func (m *Packet) GetID() uint32 {
76
+	if m != nil {
77
+		return m.ID
78
+	}
79
+	return 0
80
+}
81
+
82
+func (m *Packet) GetData() []byte {
83
+	if m != nil {
84
+		return m.Data
85
+	}
86
+	return nil
87
+}
88
+
89
+func init() {
90
+	proto.RegisterType((*Packet)(nil), "fsutil.types.Packet")
91
+	proto.RegisterEnum("fsutil.types.Packet_PacketType", Packet_PacketType_name, Packet_PacketType_value)
92
+}
93
+func (x Packet_PacketType) String() string {
94
+	s, ok := Packet_PacketType_name[int32(x)]
95
+	if ok {
96
+		return s
97
+	}
98
+	return strconv.Itoa(int(x))
99
+}
100
+func (this *Packet) Equal(that interface{}) bool {
101
+	if that == nil {
102
+		return this == nil
103
+	}
104
+
105
+	that1, ok := that.(*Packet)
106
+	if !ok {
107
+		that2, ok := that.(Packet)
108
+		if ok {
109
+			that1 = &that2
110
+		} else {
111
+			return false
112
+		}
113
+	}
114
+	if that1 == nil {
115
+		return this == nil
116
+	} else if this == nil {
117
+		return false
118
+	}
119
+	if this.Type != that1.Type {
120
+		return false
121
+	}
122
+	if !this.Stat.Equal(that1.Stat) {
123
+		return false
124
+	}
125
+	if this.ID != that1.ID {
126
+		return false
127
+	}
128
+	if !bytes.Equal(this.Data, that1.Data) {
129
+		return false
130
+	}
131
+	return true
132
+}
133
+func (this *Packet) GoString() string {
134
+	if this == nil {
135
+		return "nil"
136
+	}
137
+	s := make([]string, 0, 8)
138
+	s = append(s, "&types.Packet{")
139
+	s = append(s, "Type: "+fmt.Sprintf("%#v", this.Type)+",\n")
140
+	if this.Stat != nil {
141
+		s = append(s, "Stat: "+fmt.Sprintf("%#v", this.Stat)+",\n")
142
+	}
143
+	s = append(s, "ID: "+fmt.Sprintf("%#v", this.ID)+",\n")
144
+	s = append(s, "Data: "+fmt.Sprintf("%#v", this.Data)+",\n")
145
+	s = append(s, "}")
146
+	return strings.Join(s, "")
147
+}
148
+func valueToGoStringWire(v interface{}, typ string) string {
149
+	rv := reflect.ValueOf(v)
150
+	if rv.IsNil() {
151
+		return "nil"
152
+	}
153
+	pv := reflect.Indirect(rv).Interface()
154
+	return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
155
+}
156
+func (m *Packet) Marshal() (dAtA []byte, err error) {
157
+	size := m.Size()
158
+	dAtA = make([]byte, size)
159
+	n, err := m.MarshalTo(dAtA)
160
+	if err != nil {
161
+		return nil, err
162
+	}
163
+	return dAtA[:n], nil
164
+}
165
+
166
+func (m *Packet) MarshalTo(dAtA []byte) (int, error) {
167
+	var i int
168
+	_ = i
169
+	var l int
170
+	_ = l
171
+	if m.Type != 0 {
172
+		dAtA[i] = 0x8
173
+		i++
174
+		i = encodeVarintWire(dAtA, i, uint64(m.Type))
175
+	}
176
+	if m.Stat != nil {
177
+		dAtA[i] = 0x12
178
+		i++
179
+		i = encodeVarintWire(dAtA, i, uint64(m.Stat.Size()))
180
+		n1, err := m.Stat.MarshalTo(dAtA[i:])
181
+		if err != nil {
182
+			return 0, err
183
+		}
184
+		i += n1
185
+	}
186
+	if m.ID != 0 {
187
+		dAtA[i] = 0x18
188
+		i++
189
+		i = encodeVarintWire(dAtA, i, uint64(m.ID))
190
+	}
191
+	if len(m.Data) > 0 {
192
+		dAtA[i] = 0x22
193
+		i++
194
+		i = encodeVarintWire(dAtA, i, uint64(len(m.Data)))
195
+		i += copy(dAtA[i:], m.Data)
196
+	}
197
+	return i, nil
198
+}
199
+
200
+func encodeVarintWire(dAtA []byte, offset int, v uint64) int {
201
+	for v >= 1<<7 {
202
+		dAtA[offset] = uint8(v&0x7f | 0x80)
203
+		v >>= 7
204
+		offset++
205
+	}
206
+	dAtA[offset] = uint8(v)
207
+	return offset + 1
208
+}
209
+func (m *Packet) Size() (n int) {
210
+	var l int
211
+	_ = l
212
+	if m.Type != 0 {
213
+		n += 1 + sovWire(uint64(m.Type))
214
+	}
215
+	if m.Stat != nil {
216
+		l = m.Stat.Size()
217
+		n += 1 + l + sovWire(uint64(l))
218
+	}
219
+	if m.ID != 0 {
220
+		n += 1 + sovWire(uint64(m.ID))
221
+	}
222
+	l = len(m.Data)
223
+	if l > 0 {
224
+		n += 1 + l + sovWire(uint64(l))
225
+	}
226
+	return n
227
+}
228
+
229
+func sovWire(x uint64) (n int) {
230
+	for {
231
+		n++
232
+		x >>= 7
233
+		if x == 0 {
234
+			break
235
+		}
236
+	}
237
+	return n
238
+}
239
+func sozWire(x uint64) (n int) {
240
+	return sovWire(uint64((x << 1) ^ uint64((int64(x) >> 63))))
241
+}
242
+func (this *Packet) String() string {
243
+	if this == nil {
244
+		return "nil"
245
+	}
246
+	s := strings.Join([]string{`&Packet{`,
247
+		`Type:` + fmt.Sprintf("%v", this.Type) + `,`,
248
+		`Stat:` + strings.Replace(fmt.Sprintf("%v", this.Stat), "Stat", "Stat", 1) + `,`,
249
+		`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
250
+		`Data:` + fmt.Sprintf("%v", this.Data) + `,`,
251
+		`}`,
252
+	}, "")
253
+	return s
254
+}
255
+func valueToStringWire(v interface{}) string {
256
+	rv := reflect.ValueOf(v)
257
+	if rv.IsNil() {
258
+		return "nil"
259
+	}
260
+	pv := reflect.Indirect(rv).Interface()
261
+	return fmt.Sprintf("*%v", pv)
262
+}
263
+func (m *Packet) Unmarshal(dAtA []byte) error {
264
+	l := len(dAtA)
265
+	iNdEx := 0
266
+	for iNdEx < l {
267
+		preIndex := iNdEx
268
+		var wire uint64
269
+		for shift := uint(0); ; shift += 7 {
270
+			if shift >= 64 {
271
+				return ErrIntOverflowWire
272
+			}
273
+			if iNdEx >= l {
274
+				return io.ErrUnexpectedEOF
275
+			}
276
+			b := dAtA[iNdEx]
277
+			iNdEx++
278
+			wire |= (uint64(b) & 0x7F) << shift
279
+			if b < 0x80 {
280
+				break
281
+			}
282
+		}
283
+		fieldNum := int32(wire >> 3)
284
+		wireType := int(wire & 0x7)
285
+		if wireType == 4 {
286
+			return fmt.Errorf("proto: Packet: wiretype end group for non-group")
287
+		}
288
+		if fieldNum <= 0 {
289
+			return fmt.Errorf("proto: Packet: illegal tag %d (wire type %d)", fieldNum, wire)
290
+		}
291
+		switch fieldNum {
292
+		case 1:
293
+			if wireType != 0 {
294
+				return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
295
+			}
296
+			m.Type = 0
297
+			for shift := uint(0); ; shift += 7 {
298
+				if shift >= 64 {
299
+					return ErrIntOverflowWire
300
+				}
301
+				if iNdEx >= l {
302
+					return io.ErrUnexpectedEOF
303
+				}
304
+				b := dAtA[iNdEx]
305
+				iNdEx++
306
+				m.Type |= (Packet_PacketType(b) & 0x7F) << shift
307
+				if b < 0x80 {
308
+					break
309
+				}
310
+			}
311
+		case 2:
312
+			if wireType != 2 {
313
+				return fmt.Errorf("proto: wrong wireType = %d for field Stat", wireType)
314
+			}
315
+			var msglen int
316
+			for shift := uint(0); ; shift += 7 {
317
+				if shift >= 64 {
318
+					return ErrIntOverflowWire
319
+				}
320
+				if iNdEx >= l {
321
+					return io.ErrUnexpectedEOF
322
+				}
323
+				b := dAtA[iNdEx]
324
+				iNdEx++
325
+				msglen |= (int(b) & 0x7F) << shift
326
+				if b < 0x80 {
327
+					break
328
+				}
329
+			}
330
+			if msglen < 0 {
331
+				return ErrInvalidLengthWire
332
+			}
333
+			postIndex := iNdEx + msglen
334
+			if postIndex > l {
335
+				return io.ErrUnexpectedEOF
336
+			}
337
+			if m.Stat == nil {
338
+				m.Stat = &Stat{}
339
+			}
340
+			if err := m.Stat.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
341
+				return err
342
+			}
343
+			iNdEx = postIndex
344
+		case 3:
345
+			if wireType != 0 {
346
+				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
347
+			}
348
+			m.ID = 0
349
+			for shift := uint(0); ; shift += 7 {
350
+				if shift >= 64 {
351
+					return ErrIntOverflowWire
352
+				}
353
+				if iNdEx >= l {
354
+					return io.ErrUnexpectedEOF
355
+				}
356
+				b := dAtA[iNdEx]
357
+				iNdEx++
358
+				m.ID |= (uint32(b) & 0x7F) << shift
359
+				if b < 0x80 {
360
+					break
361
+				}
362
+			}
363
+		case 4:
364
+			if wireType != 2 {
365
+				return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
366
+			}
367
+			var byteLen int
368
+			for shift := uint(0); ; shift += 7 {
369
+				if shift >= 64 {
370
+					return ErrIntOverflowWire
371
+				}
372
+				if iNdEx >= l {
373
+					return io.ErrUnexpectedEOF
374
+				}
375
+				b := dAtA[iNdEx]
376
+				iNdEx++
377
+				byteLen |= (int(b) & 0x7F) << shift
378
+				if b < 0x80 {
379
+					break
380
+				}
381
+			}
382
+			if byteLen < 0 {
383
+				return ErrInvalidLengthWire
384
+			}
385
+			postIndex := iNdEx + byteLen
386
+			if postIndex > l {
387
+				return io.ErrUnexpectedEOF
388
+			}
389
+			m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...)
390
+			if m.Data == nil {
391
+				m.Data = []byte{}
392
+			}
393
+			iNdEx = postIndex
394
+		default:
395
+			iNdEx = preIndex
396
+			skippy, err := skipWire(dAtA[iNdEx:])
397
+			if err != nil {
398
+				return err
399
+			}
400
+			if skippy < 0 {
401
+				return ErrInvalidLengthWire
402
+			}
403
+			if (iNdEx + skippy) > l {
404
+				return io.ErrUnexpectedEOF
405
+			}
406
+			iNdEx += skippy
407
+		}
408
+	}
409
+
410
+	if iNdEx > l {
411
+		return io.ErrUnexpectedEOF
412
+	}
413
+	return nil
414
+}
415
+func skipWire(dAtA []byte) (n int, err error) {
416
+	l := len(dAtA)
417
+	iNdEx := 0
418
+	for iNdEx < l {
419
+		var wire uint64
420
+		for shift := uint(0); ; shift += 7 {
421
+			if shift >= 64 {
422
+				return 0, ErrIntOverflowWire
423
+			}
424
+			if iNdEx >= l {
425
+				return 0, io.ErrUnexpectedEOF
426
+			}
427
+			b := dAtA[iNdEx]
428
+			iNdEx++
429
+			wire |= (uint64(b) & 0x7F) << shift
430
+			if b < 0x80 {
431
+				break
432
+			}
433
+		}
434
+		wireType := int(wire & 0x7)
435
+		switch wireType {
436
+		case 0:
437
+			for shift := uint(0); ; shift += 7 {
438
+				if shift >= 64 {
439
+					return 0, ErrIntOverflowWire
440
+				}
441
+				if iNdEx >= l {
442
+					return 0, io.ErrUnexpectedEOF
443
+				}
444
+				iNdEx++
445
+				if dAtA[iNdEx-1] < 0x80 {
446
+					break
447
+				}
448
+			}
449
+			return iNdEx, nil
450
+		case 1:
451
+			iNdEx += 8
452
+			return iNdEx, nil
453
+		case 2:
454
+			var length int
455
+			for shift := uint(0); ; shift += 7 {
456
+				if shift >= 64 {
457
+					return 0, ErrIntOverflowWire
458
+				}
459
+				if iNdEx >= l {
460
+					return 0, io.ErrUnexpectedEOF
461
+				}
462
+				b := dAtA[iNdEx]
463
+				iNdEx++
464
+				length |= (int(b) & 0x7F) << shift
465
+				if b < 0x80 {
466
+					break
467
+				}
468
+			}
469
+			iNdEx += length
470
+			if length < 0 {
471
+				return 0, ErrInvalidLengthWire
472
+			}
473
+			return iNdEx, nil
474
+		case 3:
475
+			for {
476
+				var innerWire uint64
477
+				var start int = iNdEx
478
+				for shift := uint(0); ; shift += 7 {
479
+					if shift >= 64 {
480
+						return 0, ErrIntOverflowWire
481
+					}
482
+					if iNdEx >= l {
483
+						return 0, io.ErrUnexpectedEOF
484
+					}
485
+					b := dAtA[iNdEx]
486
+					iNdEx++
487
+					innerWire |= (uint64(b) & 0x7F) << shift
488
+					if b < 0x80 {
489
+						break
490
+					}
491
+				}
492
+				innerWireType := int(innerWire & 0x7)
493
+				if innerWireType == 4 {
494
+					break
495
+				}
496
+				next, err := skipWire(dAtA[start:])
497
+				if err != nil {
498
+					return 0, err
499
+				}
500
+				iNdEx = start + next
501
+			}
502
+			return iNdEx, nil
503
+		case 4:
504
+			return iNdEx, nil
505
+		case 5:
506
+			iNdEx += 4
507
+			return iNdEx, nil
508
+		default:
509
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
510
+		}
511
+	}
512
+	panic("unreachable")
513
+}
514
+
515
+var (
516
+	ErrInvalidLengthWire = fmt.Errorf("proto: negative length found during unmarshaling")
517
+	ErrIntOverflowWire   = fmt.Errorf("proto: integer overflow")
518
+)
519
+
520
+func init() { proto.RegisterFile("wire.proto", fileDescriptorWire) }
521
+
522
+var fileDescriptorWire = []byte{
523
+	// 268 bytes of a gzipped FileDescriptorProto
524
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0xcf, 0x2c, 0x4a,
525
+	0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x49, 0x2b, 0x2e, 0x2d, 0xc9, 0xcc, 0xd1, 0x2b,
526
+	0xa9, 0x2c, 0x48, 0x2d, 0x96, 0xe2, 0x2a, 0x2e, 0x49, 0x2c, 0x81, 0xc8, 0x28, 0xbd, 0x64, 0xe4,
527
+	0x62, 0x0b, 0x48, 0x4c, 0xce, 0x4e, 0x2d, 0x11, 0x32, 0xe6, 0x62, 0x01, 0xc9, 0x4b, 0x30, 0x2a,
528
+	0x30, 0x6a, 0xf0, 0x19, 0xc9, 0xeb, 0x21, 0xeb, 0xd1, 0x83, 0xa8, 0x81, 0x52, 0x21, 0x95, 0x05,
529
+	0xa9, 0x41, 0x60, 0xc5, 0x42, 0x6a, 0x5c, 0x2c, 0x20, 0xd3, 0x24, 0x98, 0x14, 0x18, 0x35, 0xb8,
530
+	0x8d, 0x84, 0x50, 0x35, 0x05, 0x97, 0x24, 0x96, 0x04, 0x81, 0xe5, 0x85, 0xf8, 0xb8, 0x98, 0x3c,
531
+	0x5d, 0x24, 0x98, 0x15, 0x18, 0x35, 0x78, 0x83, 0x98, 0x3c, 0x5d, 0x84, 0x84, 0xb8, 0x58, 0x52,
532
+	0x12, 0x4b, 0x12, 0x25, 0x58, 0x14, 0x18, 0x35, 0x78, 0x82, 0xc0, 0x6c, 0xa5, 0x38, 0x2e, 0x2e,
533
+	0x84, 0xf9, 0x42, 0xfc, 0x5c, 0xdc, 0x01, 0x8e, 0xce, 0xde, 0xae, 0x21, 0xf1, 0xc1, 0x21, 0x8e,
534
+	0x21, 0x02, 0x0c, 0x42, 0x7c, 0x5c, 0x5c, 0x50, 0x81, 0x20, 0xd7, 0x40, 0x01, 0x46, 0x24, 0x05,
535
+	0x2e, 0x8e, 0x21, 0x8e, 0x02, 0x4c, 0x48, 0x0a, 0xdc, 0x3c, 0xfd, 0x04, 0x98, 0x91, 0xf8, 0xae,
536
+	0x41, 0x41, 0x02, 0x2c, 0x4e, 0xc6, 0x17, 0x1e, 0xca, 0x31, 0xdc, 0x78, 0x28, 0xc7, 0xf0, 0xe1,
537
+	0xa1, 0x1c, 0x63, 0xc3, 0x23, 0x39, 0xc6, 0x15, 0x8f, 0xe4, 0x18, 0x4f, 0x3c, 0x92, 0x63, 0xbc,
538
+	0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x17, 0x8f, 0xe4, 0x18, 0x3e, 0x3c, 0x92, 0x63,
539
+	0x9c, 0xf0, 0x58, 0x8e, 0x21, 0x8a, 0x15, 0xec, 0x87, 0x24, 0x36, 0x70, 0x38, 0x19, 0x03, 0x02,
540
+	0x00, 0x00, 0xff, 0xff, 0xce, 0x0f, 0xe2, 0x94, 0x4f, 0x01, 0x00, 0x00,
541
+}
0 542
new file mode 100644
... ...
@@ -0,0 +1,21 @@
0
+syntax = "proto3";
1
+
2
+package fsutil.types;
3
+
4
+option go_package = "types";
5
+
6
+import "stat.proto";
7
+
8
+message Packet {
9
+  enum PacketType {
10
+      PACKET_STAT = 0;
11
+      PACKET_REQ = 1;
12
+      PACKET_DATA = 2;
13
+      PACKET_FIN = 3;
14
+      PACKET_ERR = 4;
15
+    }
16
+  PacketType type = 1;
17
+  Stat stat = 2;
18
+  uint32 ID = 3;
19
+  bytes data = 4;
20
+}
... ...
@@ -4,12 +4,12 @@ import (
4 4
 	"context"
5 5
 	"os"
6 6
 	"path/filepath"
7
-	"runtime"
8 7
 	"strings"
9 8
 	"time"
10 9
 
11 10
 	"github.com/docker/docker/pkg/fileutils"
12 11
 	"github.com/pkg/errors"
12
+	"github.com/tonistiigi/fsutil/types"
13 13
 )
14 14
 
15 15
 type WalkOpt struct {
... ...
@@ -18,7 +18,7 @@ type WalkOpt struct {
18 18
 	// FollowPaths contains symlinks that are resolved into include patterns
19 19
 	// before performing the fs walk
20 20
 	FollowPaths []string
21
-	Map         func(*Stat) bool
21
+	Map         func(*types.Stat) bool
22 22
 }
23 23
 
24 24
 func Walk(ctx context.Context, p string, opt *WalkOpt, fn filepath.WalkFunc) error {
... ...
@@ -146,37 +146,9 @@ func Walk(ctx context.Context, p string, opt *WalkOpt, fn filepath.WalkFunc) err
146 146
 		}
147 147
 
148 148
 	passedFilter:
149
-		path = filepath.ToSlash(path)
150
-
151
-		stat := &Stat{
152
-			Path:    path,
153
-			Mode:    uint32(fi.Mode()),
154
-			ModTime: fi.ModTime().UnixNano(),
155
-		}
156
-
157
-		setUnixOpt(fi, stat, path, seenFiles)
158
-
159
-		if !fi.IsDir() {
160
-			stat.Size_ = fi.Size()
161
-			if fi.Mode()&os.ModeSymlink != 0 {
162
-				link, err := os.Readlink(origpath)
163
-				if err != nil {
164
-					return errors.Wrapf(err, "failed to readlink %s", origpath)
165
-				}
166
-				stat.Linkname = link
167
-			}
168
-		}
169
-		if err := loadXattr(origpath, stat); err != nil {
170
-			return errors.Wrapf(err, "failed to xattr %s", path)
171
-		}
172
-
173
-		if runtime.GOOS == "windows" {
174
-			permPart := stat.Mode & uint32(os.ModePerm)
175
-			noPermPart := stat.Mode &^ uint32(os.ModePerm)
176
-			// Add the x bit: make everything +x from windows
177
-			permPart |= 0111
178
-			permPart &= 0755
179
-			stat.Mode = noPermPart | permPart
149
+		stat, err := mkstat(origpath, path, fi, seenFiles)
150
+		if err != nil {
151
+			return err
180 152
 		}
181 153
 
182 154
 		select {
... ...
@@ -197,7 +169,7 @@ func Walk(ctx context.Context, p string, opt *WalkOpt, fn filepath.WalkFunc) err
197 197
 }
198 198
 
199 199
 type StatInfo struct {
200
-	*Stat
200
+	*types.Stat
201 201
 }
202 202
 
203 203
 func (s *StatInfo) Name() string {
204 204
deleted file mode 100644
... ...
@@ -1,61 +0,0 @@
1
-// +build !windows
2
-
3
-package fsutil
4
-
5
-import (
6
-	"os"
7
-	"syscall"
8
-
9
-	"github.com/containerd/continuity/sysx"
10
-	"github.com/pkg/errors"
11
-)
12
-
13
-func loadXattr(origpath string, stat *Stat) error {
14
-	xattrs, err := sysx.LListxattr(origpath)
15
-	if err != nil {
16
-		return errors.Wrapf(err, "failed to xattr %s", origpath)
17
-	}
18
-	if len(xattrs) > 0 {
19
-		m := make(map[string][]byte)
20
-		for _, key := range xattrs {
21
-			v, err := sysx.LGetxattr(origpath, key)
22
-			if err == nil {
23
-				m[key] = v
24
-			}
25
-		}
26
-		stat.Xattrs = m
27
-	}
28
-	return nil
29
-}
30
-
31
-func setUnixOpt(fi os.FileInfo, stat *Stat, path string, seenFiles map[uint64]string) {
32
-	s := fi.Sys().(*syscall.Stat_t)
33
-
34
-	stat.Uid = s.Uid
35
-	stat.Gid = s.Gid
36
-
37
-	if !fi.IsDir() {
38
-		if s.Mode&syscall.S_IFBLK != 0 ||
39
-			s.Mode&syscall.S_IFCHR != 0 {
40
-			stat.Devmajor = int64(major(uint64(s.Rdev)))
41
-			stat.Devminor = int64(minor(uint64(s.Rdev)))
42
-		}
43
-
44
-		ino := s.Ino
45
-		if s.Nlink > 1 {
46
-			if oldpath, ok := seenFiles[ino]; ok {
47
-				stat.Linkname = oldpath
48
-				stat.Size_ = 0
49
-			}
50
-		}
51
-		seenFiles[ino] = path
52
-	}
53
-}
54
-
55
-func major(device uint64) uint64 {
56
-	return (device >> 8) & 0xfff
57
-}
58
-
59
-func minor(device uint64) uint64 {
60
-	return (device & 0xff) | ((device >> 12) & 0xfff00)
61
-}
62 1
deleted file mode 100644
... ...
@@ -1,14 +0,0 @@
1
-// +build windows
2
-
3
-package fsutil
4
-
5
-import (
6
-	"os"
7
-)
8
-
9
-func loadXattr(_ string, _ *Stat) error {
10
-	return nil
11
-}
12
-
13
-func setUnixOpt(_ os.FileInfo, _ *Stat, _ string, _ map[uint64]string) {
14
-}
15 1
deleted file mode 100644
... ...
@@ -1,567 +0,0 @@
1
-// Code generated by protoc-gen-gogo.
2
-// source: wire.proto
3
-// DO NOT EDIT!
4
-
5
-package fsutil
6
-
7
-import proto "github.com/gogo/protobuf/proto"
8
-import fmt "fmt"
9
-import math "math"
10
-
11
-import strconv "strconv"
12
-
13
-import bytes "bytes"
14
-
15
-import strings "strings"
16
-import reflect "reflect"
17
-
18
-import io "io"
19
-
20
-// Reference imports to suppress errors if they are not otherwise used.
21
-var _ = proto.Marshal
22
-var _ = fmt.Errorf
23
-var _ = math.Inf
24
-
25
-type Packet_PacketType int32
26
-
27
-const (
28
-	PACKET_STAT Packet_PacketType = 0
29
-	PACKET_REQ  Packet_PacketType = 1
30
-	PACKET_DATA Packet_PacketType = 2
31
-	PACKET_FIN  Packet_PacketType = 3
32
-	PACKET_ERR  Packet_PacketType = 4
33
-)
34
-
35
-var Packet_PacketType_name = map[int32]string{
36
-	0: "PACKET_STAT",
37
-	1: "PACKET_REQ",
38
-	2: "PACKET_DATA",
39
-	3: "PACKET_FIN",
40
-	4: "PACKET_ERR",
41
-}
42
-var Packet_PacketType_value = map[string]int32{
43
-	"PACKET_STAT": 0,
44
-	"PACKET_REQ":  1,
45
-	"PACKET_DATA": 2,
46
-	"PACKET_FIN":  3,
47
-	"PACKET_ERR":  4,
48
-}
49
-
50
-func (Packet_PacketType) EnumDescriptor() ([]byte, []int) { return fileDescriptorWire, []int{0, 0} }
51
-
52
-type Packet struct {
53
-	Type Packet_PacketType `protobuf:"varint,1,opt,name=type,proto3,enum=fsutil.Packet_PacketType" json:"type,omitempty"`
54
-	Stat *Stat             `protobuf:"bytes,2,opt,name=stat" json:"stat,omitempty"`
55
-	ID   uint32            `protobuf:"varint,3,opt,name=ID,proto3" json:"ID,omitempty"`
56
-	Data []byte            `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
57
-}
58
-
59
-func (m *Packet) Reset()                    { *m = Packet{} }
60
-func (*Packet) ProtoMessage()               {}
61
-func (*Packet) Descriptor() ([]byte, []int) { return fileDescriptorWire, []int{0} }
62
-
63
-func (m *Packet) GetType() Packet_PacketType {
64
-	if m != nil {
65
-		return m.Type
66
-	}
67
-	return PACKET_STAT
68
-}
69
-
70
-func (m *Packet) GetStat() *Stat {
71
-	if m != nil {
72
-		return m.Stat
73
-	}
74
-	return nil
75
-}
76
-
77
-func (m *Packet) GetID() uint32 {
78
-	if m != nil {
79
-		return m.ID
80
-	}
81
-	return 0
82
-}
83
-
84
-func (m *Packet) GetData() []byte {
85
-	if m != nil {
86
-		return m.Data
87
-	}
88
-	return nil
89
-}
90
-
91
-func init() {
92
-	proto.RegisterType((*Packet)(nil), "fsutil.Packet")
93
-	proto.RegisterEnum("fsutil.Packet_PacketType", Packet_PacketType_name, Packet_PacketType_value)
94
-}
95
-func (x Packet_PacketType) String() string {
96
-	s, ok := Packet_PacketType_name[int32(x)]
97
-	if ok {
98
-		return s
99
-	}
100
-	return strconv.Itoa(int(x))
101
-}
102
-func (this *Packet) Equal(that interface{}) bool {
103
-	if that == nil {
104
-		if this == nil {
105
-			return true
106
-		}
107
-		return false
108
-	}
109
-
110
-	that1, ok := that.(*Packet)
111
-	if !ok {
112
-		that2, ok := that.(Packet)
113
-		if ok {
114
-			that1 = &that2
115
-		} else {
116
-			return false
117
-		}
118
-	}
119
-	if that1 == nil {
120
-		if this == nil {
121
-			return true
122
-		}
123
-		return false
124
-	} else if this == nil {
125
-		return false
126
-	}
127
-	if this.Type != that1.Type {
128
-		return false
129
-	}
130
-	if !this.Stat.Equal(that1.Stat) {
131
-		return false
132
-	}
133
-	if this.ID != that1.ID {
134
-		return false
135
-	}
136
-	if !bytes.Equal(this.Data, that1.Data) {
137
-		return false
138
-	}
139
-	return true
140
-}
141
-func (this *Packet) GoString() string {
142
-	if this == nil {
143
-		return "nil"
144
-	}
145
-	s := make([]string, 0, 8)
146
-	s = append(s, "&fsutil.Packet{")
147
-	s = append(s, "Type: "+fmt.Sprintf("%#v", this.Type)+",\n")
148
-	if this.Stat != nil {
149
-		s = append(s, "Stat: "+fmt.Sprintf("%#v", this.Stat)+",\n")
150
-	}
151
-	s = append(s, "ID: "+fmt.Sprintf("%#v", this.ID)+",\n")
152
-	s = append(s, "Data: "+fmt.Sprintf("%#v", this.Data)+",\n")
153
-	s = append(s, "}")
154
-	return strings.Join(s, "")
155
-}
156
-func valueToGoStringWire(v interface{}, typ string) string {
157
-	rv := reflect.ValueOf(v)
158
-	if rv.IsNil() {
159
-		return "nil"
160
-	}
161
-	pv := reflect.Indirect(rv).Interface()
162
-	return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
163
-}
164
-func (m *Packet) Marshal() (dAtA []byte, err error) {
165
-	size := m.Size()
166
-	dAtA = make([]byte, size)
167
-	n, err := m.MarshalTo(dAtA)
168
-	if err != nil {
169
-		return nil, err
170
-	}
171
-	return dAtA[:n], nil
172
-}
173
-
174
-func (m *Packet) MarshalTo(dAtA []byte) (int, error) {
175
-	var i int
176
-	_ = i
177
-	var l int
178
-	_ = l
179
-	if m.Type != 0 {
180
-		dAtA[i] = 0x8
181
-		i++
182
-		i = encodeVarintWire(dAtA, i, uint64(m.Type))
183
-	}
184
-	if m.Stat != nil {
185
-		dAtA[i] = 0x12
186
-		i++
187
-		i = encodeVarintWire(dAtA, i, uint64(m.Stat.Size()))
188
-		n1, err := m.Stat.MarshalTo(dAtA[i:])
189
-		if err != nil {
190
-			return 0, err
191
-		}
192
-		i += n1
193
-	}
194
-	if m.ID != 0 {
195
-		dAtA[i] = 0x18
196
-		i++
197
-		i = encodeVarintWire(dAtA, i, uint64(m.ID))
198
-	}
199
-	if len(m.Data) > 0 {
200
-		dAtA[i] = 0x22
201
-		i++
202
-		i = encodeVarintWire(dAtA, i, uint64(len(m.Data)))
203
-		i += copy(dAtA[i:], m.Data)
204
-	}
205
-	return i, nil
206
-}
207
-
208
-func encodeFixed64Wire(dAtA []byte, offset int, v uint64) int {
209
-	dAtA[offset] = uint8(v)
210
-	dAtA[offset+1] = uint8(v >> 8)
211
-	dAtA[offset+2] = uint8(v >> 16)
212
-	dAtA[offset+3] = uint8(v >> 24)
213
-	dAtA[offset+4] = uint8(v >> 32)
214
-	dAtA[offset+5] = uint8(v >> 40)
215
-	dAtA[offset+6] = uint8(v >> 48)
216
-	dAtA[offset+7] = uint8(v >> 56)
217
-	return offset + 8
218
-}
219
-func encodeFixed32Wire(dAtA []byte, offset int, v uint32) int {
220
-	dAtA[offset] = uint8(v)
221
-	dAtA[offset+1] = uint8(v >> 8)
222
-	dAtA[offset+2] = uint8(v >> 16)
223
-	dAtA[offset+3] = uint8(v >> 24)
224
-	return offset + 4
225
-}
226
-func encodeVarintWire(dAtA []byte, offset int, v uint64) int {
227
-	for v >= 1<<7 {
228
-		dAtA[offset] = uint8(v&0x7f | 0x80)
229
-		v >>= 7
230
-		offset++
231
-	}
232
-	dAtA[offset] = uint8(v)
233
-	return offset + 1
234
-}
235
-func (m *Packet) Size() (n int) {
236
-	var l int
237
-	_ = l
238
-	if m.Type != 0 {
239
-		n += 1 + sovWire(uint64(m.Type))
240
-	}
241
-	if m.Stat != nil {
242
-		l = m.Stat.Size()
243
-		n += 1 + l + sovWire(uint64(l))
244
-	}
245
-	if m.ID != 0 {
246
-		n += 1 + sovWire(uint64(m.ID))
247
-	}
248
-	l = len(m.Data)
249
-	if l > 0 {
250
-		n += 1 + l + sovWire(uint64(l))
251
-	}
252
-	return n
253
-}
254
-
255
-func sovWire(x uint64) (n int) {
256
-	for {
257
-		n++
258
-		x >>= 7
259
-		if x == 0 {
260
-			break
261
-		}
262
-	}
263
-	return n
264
-}
265
-func sozWire(x uint64) (n int) {
266
-	return sovWire(uint64((x << 1) ^ uint64((int64(x) >> 63))))
267
-}
268
-func (this *Packet) String() string {
269
-	if this == nil {
270
-		return "nil"
271
-	}
272
-	s := strings.Join([]string{`&Packet{`,
273
-		`Type:` + fmt.Sprintf("%v", this.Type) + `,`,
274
-		`Stat:` + strings.Replace(fmt.Sprintf("%v", this.Stat), "Stat", "Stat", 1) + `,`,
275
-		`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
276
-		`Data:` + fmt.Sprintf("%v", this.Data) + `,`,
277
-		`}`,
278
-	}, "")
279
-	return s
280
-}
281
-func valueToStringWire(v interface{}) string {
282
-	rv := reflect.ValueOf(v)
283
-	if rv.IsNil() {
284
-		return "nil"
285
-	}
286
-	pv := reflect.Indirect(rv).Interface()
287
-	return fmt.Sprintf("*%v", pv)
288
-}
289
-func (m *Packet) Unmarshal(dAtA []byte) error {
290
-	l := len(dAtA)
291
-	iNdEx := 0
292
-	for iNdEx < l {
293
-		preIndex := iNdEx
294
-		var wire uint64
295
-		for shift := uint(0); ; shift += 7 {
296
-			if shift >= 64 {
297
-				return ErrIntOverflowWire
298
-			}
299
-			if iNdEx >= l {
300
-				return io.ErrUnexpectedEOF
301
-			}
302
-			b := dAtA[iNdEx]
303
-			iNdEx++
304
-			wire |= (uint64(b) & 0x7F) << shift
305
-			if b < 0x80 {
306
-				break
307
-			}
308
-		}
309
-		fieldNum := int32(wire >> 3)
310
-		wireType := int(wire & 0x7)
311
-		if wireType == 4 {
312
-			return fmt.Errorf("proto: Packet: wiretype end group for non-group")
313
-		}
314
-		if fieldNum <= 0 {
315
-			return fmt.Errorf("proto: Packet: illegal tag %d (wire type %d)", fieldNum, wire)
316
-		}
317
-		switch fieldNum {
318
-		case 1:
319
-			if wireType != 0 {
320
-				return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
321
-			}
322
-			m.Type = 0
323
-			for shift := uint(0); ; shift += 7 {
324
-				if shift >= 64 {
325
-					return ErrIntOverflowWire
326
-				}
327
-				if iNdEx >= l {
328
-					return io.ErrUnexpectedEOF
329
-				}
330
-				b := dAtA[iNdEx]
331
-				iNdEx++
332
-				m.Type |= (Packet_PacketType(b) & 0x7F) << shift
333
-				if b < 0x80 {
334
-					break
335
-				}
336
-			}
337
-		case 2:
338
-			if wireType != 2 {
339
-				return fmt.Errorf("proto: wrong wireType = %d for field Stat", wireType)
340
-			}
341
-			var msglen int
342
-			for shift := uint(0); ; shift += 7 {
343
-				if shift >= 64 {
344
-					return ErrIntOverflowWire
345
-				}
346
-				if iNdEx >= l {
347
-					return io.ErrUnexpectedEOF
348
-				}
349
-				b := dAtA[iNdEx]
350
-				iNdEx++
351
-				msglen |= (int(b) & 0x7F) << shift
352
-				if b < 0x80 {
353
-					break
354
-				}
355
-			}
356
-			if msglen < 0 {
357
-				return ErrInvalidLengthWire
358
-			}
359
-			postIndex := iNdEx + msglen
360
-			if postIndex > l {
361
-				return io.ErrUnexpectedEOF
362
-			}
363
-			if m.Stat == nil {
364
-				m.Stat = &Stat{}
365
-			}
366
-			if err := m.Stat.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
367
-				return err
368
-			}
369
-			iNdEx = postIndex
370
-		case 3:
371
-			if wireType != 0 {
372
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
373
-			}
374
-			m.ID = 0
375
-			for shift := uint(0); ; shift += 7 {
376
-				if shift >= 64 {
377
-					return ErrIntOverflowWire
378
-				}
379
-				if iNdEx >= l {
380
-					return io.ErrUnexpectedEOF
381
-				}
382
-				b := dAtA[iNdEx]
383
-				iNdEx++
384
-				m.ID |= (uint32(b) & 0x7F) << shift
385
-				if b < 0x80 {
386
-					break
387
-				}
388
-			}
389
-		case 4:
390
-			if wireType != 2 {
391
-				return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
392
-			}
393
-			var byteLen int
394
-			for shift := uint(0); ; shift += 7 {
395
-				if shift >= 64 {
396
-					return ErrIntOverflowWire
397
-				}
398
-				if iNdEx >= l {
399
-					return io.ErrUnexpectedEOF
400
-				}
401
-				b := dAtA[iNdEx]
402
-				iNdEx++
403
-				byteLen |= (int(b) & 0x7F) << shift
404
-				if b < 0x80 {
405
-					break
406
-				}
407
-			}
408
-			if byteLen < 0 {
409
-				return ErrInvalidLengthWire
410
-			}
411
-			postIndex := iNdEx + byteLen
412
-			if postIndex > l {
413
-				return io.ErrUnexpectedEOF
414
-			}
415
-			m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...)
416
-			if m.Data == nil {
417
-				m.Data = []byte{}
418
-			}
419
-			iNdEx = postIndex
420
-		default:
421
-			iNdEx = preIndex
422
-			skippy, err := skipWire(dAtA[iNdEx:])
423
-			if err != nil {
424
-				return err
425
-			}
426
-			if skippy < 0 {
427
-				return ErrInvalidLengthWire
428
-			}
429
-			if (iNdEx + skippy) > l {
430
-				return io.ErrUnexpectedEOF
431
-			}
432
-			iNdEx += skippy
433
-		}
434
-	}
435
-
436
-	if iNdEx > l {
437
-		return io.ErrUnexpectedEOF
438
-	}
439
-	return nil
440
-}
441
-func skipWire(dAtA []byte) (n int, err error) {
442
-	l := len(dAtA)
443
-	iNdEx := 0
444
-	for iNdEx < l {
445
-		var wire uint64
446
-		for shift := uint(0); ; shift += 7 {
447
-			if shift >= 64 {
448
-				return 0, ErrIntOverflowWire
449
-			}
450
-			if iNdEx >= l {
451
-				return 0, io.ErrUnexpectedEOF
452
-			}
453
-			b := dAtA[iNdEx]
454
-			iNdEx++
455
-			wire |= (uint64(b) & 0x7F) << shift
456
-			if b < 0x80 {
457
-				break
458
-			}
459
-		}
460
-		wireType := int(wire & 0x7)
461
-		switch wireType {
462
-		case 0:
463
-			for shift := uint(0); ; shift += 7 {
464
-				if shift >= 64 {
465
-					return 0, ErrIntOverflowWire
466
-				}
467
-				if iNdEx >= l {
468
-					return 0, io.ErrUnexpectedEOF
469
-				}
470
-				iNdEx++
471
-				if dAtA[iNdEx-1] < 0x80 {
472
-					break
473
-				}
474
-			}
475
-			return iNdEx, nil
476
-		case 1:
477
-			iNdEx += 8
478
-			return iNdEx, nil
479
-		case 2:
480
-			var length int
481
-			for shift := uint(0); ; shift += 7 {
482
-				if shift >= 64 {
483
-					return 0, ErrIntOverflowWire
484
-				}
485
-				if iNdEx >= l {
486
-					return 0, io.ErrUnexpectedEOF
487
-				}
488
-				b := dAtA[iNdEx]
489
-				iNdEx++
490
-				length |= (int(b) & 0x7F) << shift
491
-				if b < 0x80 {
492
-					break
493
-				}
494
-			}
495
-			iNdEx += length
496
-			if length < 0 {
497
-				return 0, ErrInvalidLengthWire
498
-			}
499
-			return iNdEx, nil
500
-		case 3:
501
-			for {
502
-				var innerWire uint64
503
-				var start int = iNdEx
504
-				for shift := uint(0); ; shift += 7 {
505
-					if shift >= 64 {
506
-						return 0, ErrIntOverflowWire
507
-					}
508
-					if iNdEx >= l {
509
-						return 0, io.ErrUnexpectedEOF
510
-					}
511
-					b := dAtA[iNdEx]
512
-					iNdEx++
513
-					innerWire |= (uint64(b) & 0x7F) << shift
514
-					if b < 0x80 {
515
-						break
516
-					}
517
-				}
518
-				innerWireType := int(innerWire & 0x7)
519
-				if innerWireType == 4 {
520
-					break
521
-				}
522
-				next, err := skipWire(dAtA[start:])
523
-				if err != nil {
524
-					return 0, err
525
-				}
526
-				iNdEx = start + next
527
-			}
528
-			return iNdEx, nil
529
-		case 4:
530
-			return iNdEx, nil
531
-		case 5:
532
-			iNdEx += 4
533
-			return iNdEx, nil
534
-		default:
535
-			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
536
-		}
537
-	}
538
-	panic("unreachable")
539
-}
540
-
541
-var (
542
-	ErrInvalidLengthWire = fmt.Errorf("proto: negative length found during unmarshaling")
543
-	ErrIntOverflowWire   = fmt.Errorf("proto: integer overflow")
544
-)
545
-
546
-func init() { proto.RegisterFile("wire.proto", fileDescriptorWire) }
547
-
548
-var fileDescriptorWire = []byte{
549
-	// 259 bytes of a gzipped FileDescriptorProto
550
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0xcf, 0x2c, 0x4a,
551
-	0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x4b, 0x2b, 0x2e, 0x2d, 0xc9, 0xcc, 0x91, 0xe2,
552
-	0x2a, 0x2e, 0x49, 0x2c, 0x81, 0x88, 0x29, 0xdd, 0x65, 0xe4, 0x62, 0x0b, 0x48, 0x4c, 0xce, 0x4e,
553
-	0x2d, 0x11, 0xd2, 0xe5, 0x62, 0x29, 0xa9, 0x2c, 0x48, 0x95, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x33,
554
-	0x92, 0xd4, 0x83, 0xa8, 0xd6, 0x83, 0xc8, 0x42, 0xa9, 0x90, 0xca, 0x82, 0xd4, 0x20, 0xb0, 0x32,
555
-	0x21, 0x05, 0x2e, 0x16, 0x90, 0x39, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xdc, 0x46, 0x3c, 0x30, 0xe5,
556
-	0xc1, 0x25, 0x89, 0x25, 0x41, 0x60, 0x19, 0x21, 0x3e, 0x2e, 0x26, 0x4f, 0x17, 0x09, 0x66, 0x05,
557
-	0x46, 0x0d, 0xde, 0x20, 0x26, 0x4f, 0x17, 0x21, 0x21, 0x2e, 0x96, 0x94, 0xc4, 0x92, 0x44, 0x09,
558
-	0x16, 0x05, 0x46, 0x0d, 0x9e, 0x20, 0x30, 0x5b, 0x29, 0x8e, 0x8b, 0x0b, 0x61, 0xb2, 0x10, 0x3f,
559
-	0x17, 0x77, 0x80, 0xa3, 0xb3, 0xb7, 0x6b, 0x48, 0x7c, 0x70, 0x88, 0x63, 0x88, 0x00, 0x83, 0x10,
560
-	0x1f, 0x17, 0x17, 0x54, 0x20, 0xc8, 0x35, 0x50, 0x80, 0x11, 0x49, 0x81, 0x8b, 0x63, 0x88, 0xa3,
561
-	0x00, 0x13, 0x92, 0x02, 0x37, 0x4f, 0x3f, 0x01, 0x66, 0x24, 0xbe, 0x6b, 0x50, 0x90, 0x00, 0x8b,
562
-	0x93, 0xce, 0x85, 0x87, 0x72, 0x0c, 0x37, 0x1e, 0xca, 0x31, 0x7c, 0x78, 0x28, 0xc7, 0xd8, 0xf0,
563
-	0x48, 0x8e, 0x71, 0xc5, 0x23, 0x39, 0xc6, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c,
564
-	0xf0, 0x48, 0x8e, 0xf1, 0xc5, 0x23, 0x39, 0x86, 0x0f, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63,
565
-	0x48, 0x62, 0x03, 0x07, 0x8a, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x8b, 0xce, 0x55, 0x3b, 0x36,
566
-	0x01, 0x00, 0x00,
567
-}
568 1
deleted file mode 100644
... ...
@@ -1,19 +0,0 @@
1
-syntax = "proto3";
2
-
3
-package fsutil;
4
-
5
-import "stat.proto";
6
-
7
-message Packet {
8
-  enum PacketType {
9
-      PACKET_STAT = 0;
10
-      PACKET_REQ = 1;
11
-      PACKET_DATA = 2;
12
-      PACKET_FIN = 3;
13
-      PACKET_ERR = 4;
14
-    }
15
-  PacketType type = 1;
16
-  Stat stat = 2;
17
-  uint32 ID = 3;
18
-  bytes data = 4;
19
-}