Browse code

Merge pull request #316 from thaJeztah/19.03_backport_buildkit_userns_remap_take2

[19.03 backport] builder-next: userns remap support and honor daemon's DNS config

Andrew Hsu authored on 2019/08/09 05:35:34
Showing 26 changed files
... ...
@@ -26,9 +26,10 @@ var keySize = []byte("size")
26 26
 
27 27
 // Opt defines options for creating the snapshotter
28 28
 type Opt struct {
29
-	GraphDriver graphdriver.Driver
30
-	LayerStore  layer.Store
31
-	Root        string
29
+	GraphDriver     graphdriver.Driver
30
+	LayerStore      layer.Store
31
+	Root            string
32
+	IdentityMapping *idtools.IdentityMapping
32 33
 }
33 34
 
34 35
 type graphIDRegistrar interface {
... ...
@@ -79,7 +80,7 @@ func (s *snapshotter) Name() string {
79 79
 }
80 80
 
81 81
 func (s *snapshotter) IdentityMapping() *idtools.IdentityMapping {
82
-	return nil
82
+	return s.opt.IdentityMapping
83 83
 }
84 84
 
85 85
 func (s *snapshotter) Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) error {
... ...
@@ -253,6 +254,7 @@ func (s *snapshotter) Mounts(ctx context.Context, key string) (snapshot.Mountabl
253 253
 		id := identity.NewID()
254 254
 		var rwlayer layer.RWLayer
255 255
 		return &mountable{
256
+			idmap: s.opt.IdentityMapping,
256 257
 			acquire: func() ([]mount.Mount, error) {
257 258
 				rwlayer, err = s.opt.LayerStore.CreateRWLayer(id, l.ChainID(), nil)
258 259
 				if err != nil {
... ...
@@ -278,6 +280,7 @@ func (s *snapshotter) Mounts(ctx context.Context, key string) (snapshot.Mountabl
278 278
 	id, _ := s.getGraphDriverID(key)
279 279
 
280 280
 	return &mountable{
281
+		idmap: s.opt.IdentityMapping,
281 282
 		acquire: func() ([]mount.Mount, error) {
282 283
 			rootfs, err := s.opt.GraphDriver.Get(id, "")
283 284
 			if err != nil {
... ...
@@ -440,6 +443,7 @@ type mountable struct {
440 440
 	acquire  func() ([]mount.Mount, error)
441 441
 	release  func() error
442 442
 	refCount int
443
+	idmap    *idtools.IdentityMapping
443 444
 }
444 445
 
445 446
 func (m *mountable) Mount() ([]mount.Mount, error) {
... ...
@@ -480,5 +484,5 @@ func (m *mountable) Release() error {
480 480
 }
481 481
 
482 482
 func (m *mountable) IdentityMapping() *idtools.IdentityMapping {
483
-	return nil
483
+	return m.idmap
484 484
 }
... ...
@@ -17,6 +17,7 @@ import (
17 17
 	"github.com/docker/docker/builder"
18 18
 	"github.com/docker/docker/daemon/config"
19 19
 	"github.com/docker/docker/daemon/images"
20
+	"github.com/docker/docker/pkg/idtools"
20 21
 	"github.com/docker/docker/pkg/streamformatter"
21 22
 	"github.com/docker/docker/pkg/system"
22 23
 	"github.com/docker/libnetwork"
... ...
@@ -73,6 +74,8 @@ type Opt struct {
73 73
 	ResolverOpt         resolver.ResolveOptionsFunc
74 74
 	BuilderConfig       config.BuilderConfig
75 75
 	Rootless            bool
76
+	IdentityMapping     *idtools.IdentityMapping
77
+	DNSConfig           config.DNSConfig
76 78
 }
77 79
 
78 80
 // Builder can build using BuildKit backend
... ...
@@ -88,6 +91,10 @@ type Builder struct {
88 88
 func New(opt Opt) (*Builder, error) {
89 89
 	reqHandler := newReqBodyHandler(tracing.DefaultTransport)
90 90
 
91
+	if opt.IdentityMapping != nil && opt.IdentityMapping.Empty() {
92
+		opt.IdentityMapping = nil
93
+	}
94
+
91 95
 	c, err := newController(reqHandler, opt)
92 96
 	if err != nil {
93 97
 		return nil, err
... ...
@@ -38,7 +38,7 @@ import (
38 38
 )
39 39
 
40 40
 func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
41
-	if err := os.MkdirAll(opt.Root, 0700); err != nil {
41
+	if err := os.MkdirAll(opt.Root, 0711); err != nil {
42 42
 		return nil, err
43 43
 	}
44 44
 
... ...
@@ -55,9 +55,10 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
55 55
 	}
56 56
 
57 57
 	sbase, err := snapshot.NewSnapshotter(snapshot.Opt{
58
-		GraphDriver: driver,
59
-		LayerStore:  dist.LayerStore,
60
-		Root:        root,
58
+		GraphDriver:     driver,
59
+		LayerStore:      dist.LayerStore,
60
+		Root:            root,
61
+		IdentityMapping: opt.IdentityMapping,
61 62
 	})
62 63
 	if err != nil {
63 64
 		return nil, err
... ...
@@ -112,7 +113,9 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
112 112
 		return nil, err
113 113
 	}
114 114
 
115
-	exec, err := newExecutor(root, opt.DefaultCgroupParent, opt.NetworkController, opt.Rootless)
115
+	dns := getDNSConfig(opt.DNSConfig)
116
+
117
+	exec, err := newExecutor(root, opt.DefaultCgroupParent, opt.NetworkController, dns, opt.Rootless, opt.IdentityMapping)
116 118
 	if err != nil {
117 119
 		return nil, err
118 120
 	}
... ...
@@ -8,8 +8,11 @@ import (
8 8
 	"strconv"
9 9
 	"sync"
10 10
 
11
+	"github.com/docker/docker/daemon/config"
12
+	"github.com/docker/docker/pkg/idtools"
11 13
 	"github.com/docker/libnetwork"
12 14
 	"github.com/moby/buildkit/executor"
15
+	"github.com/moby/buildkit/executor/oci"
13 16
 	"github.com/moby/buildkit/executor/runcexecutor"
14 17
 	"github.com/moby/buildkit/identity"
15 18
 	"github.com/moby/buildkit/solver/pb"
... ...
@@ -20,7 +23,7 @@ import (
20 20
 
21 21
 const networkName = "bridge"
22 22
 
23
-func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, rootless bool) (executor.Executor, error) {
23
+func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, dnsConfig *oci.DNSConfig, rootless bool, idmap *idtools.IdentityMapping) (executor.Executor, error) {
24 24
 	networkProviders := map[pb.NetMode]network.Provider{
25 25
 		pb.NetMode_UNSET: &bridgeProvider{NetworkController: net, Root: filepath.Join(root, "net")},
26 26
 		pb.NetMode_HOST:  network.NewHostProvider(),
... ...
@@ -32,6 +35,8 @@ func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, ro
32 32
 		DefaultCgroupParent: cgroupParent,
33 33
 		Rootless:            rootless,
34 34
 		NoPivot:             os.Getenv("DOCKER_RAMDISK") != "",
35
+		IdentityMapping:     idmap,
36
+		DNS:                 dnsConfig,
35 37
 	}, networkProviders)
36 38
 }
37 39
 
... ...
@@ -115,3 +120,14 @@ func (iface *lnInterface) Close() error {
115 115
 	}
116 116
 	return iface.err
117 117
 }
118
+
119
+func getDNSConfig(cfg config.DNSConfig) *oci.DNSConfig {
120
+	if cfg.DNS != nil || cfg.DNSSearch != nil || cfg.DNSOptions != nil {
121
+		return &oci.DNSConfig{
122
+			Nameservers:   cfg.DNS,
123
+			SearchDomains: cfg.DNSSearch,
124
+			Options:       cfg.DNSOptions,
125
+		}
126
+	}
127
+	return nil
128
+}
... ...
@@ -5,12 +5,15 @@ import (
5 5
 	"errors"
6 6
 	"io"
7 7
 
8
+	"github.com/docker/docker/daemon/config"
9
+	"github.com/docker/docker/pkg/idtools"
8 10
 	"github.com/docker/libnetwork"
9 11
 	"github.com/moby/buildkit/cache"
10 12
 	"github.com/moby/buildkit/executor"
13
+	"github.com/moby/buildkit/executor/oci"
11 14
 )
12 15
 
13
-func newExecutor(_, _ string, _ libnetwork.NetworkController, _ bool) (executor.Executor, error) {
16
+func newExecutor(_, _ string, _ libnetwork.NetworkController, _ *oci.DNSConfig, _ bool, _ *idtools.IdentityMapping) (executor.Executor, error) {
14 17
 	return &winExecutor{}, nil
15 18
 }
16 19
 
... ...
@@ -20,3 +23,7 @@ type winExecutor struct {
20 20
 func (e *winExecutor) Exec(ctx context.Context, meta executor.Meta, rootfs cache.Mountable, mounts []executor.Mount, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error {
21 21
 	return errors.New("buildkit executor not implemented for windows")
22 22
 }
23
+
24
+func getDNSConfig(config.DNSConfig) *oci.DNSConfig {
25
+	return nil
26
+}
... ...
@@ -318,6 +318,8 @@ func newRouterOptions(config *config.Config, d *daemon.Daemon) (routerOptions, e
318 318
 		ResolverOpt:         d.NewResolveOptionsFunc(),
319 319
 		BuilderConfig:       config.Builder,
320 320
 		Rootless:            d.Rootless(),
321
+		IdentityMapping:     d.IdentityMapping(),
322
+		DNSConfig:           config.DNSConfig,
321 323
 	})
322 324
 	if err != nil {
323 325
 		return opts, err
... ...
@@ -109,6 +109,13 @@ type CommonTLSOptions struct {
109 109
 	KeyFile  string `json:"tlskey,omitempty"`
110 110
 }
111 111
 
112
+// DNSConfig defines the DNS configurations.
113
+type DNSConfig struct {
114
+	DNS        []string `json:"dns,omitempty"`
115
+	DNSOptions []string `json:"dns-opts,omitempty"`
116
+	DNSSearch  []string `json:"dns-search,omitempty"`
117
+}
118
+
112 119
 // CommonConfig defines the configuration of a docker daemon which is
113 120
 // common across platforms.
114 121
 // It includes json tags to deserialize configuration from a file
... ...
@@ -119,9 +126,6 @@ type CommonConfig struct {
119 119
 	AutoRestart           bool                      `json:"-"`
120 120
 	Context               map[string][]string       `json:"-"`
121 121
 	DisableBridge         bool                      `json:"-"`
122
-	DNS                   []string                  `json:"dns,omitempty"`
123
-	DNSOptions            []string                  `json:"dns-opts,omitempty"`
124
-	DNSSearch             []string                  `json:"dns-search,omitempty"`
125 122
 	ExecOptions           []string                  `json:"exec-opts,omitempty"`
126 123
 	GraphDriver           string                    `json:"storage-driver,omitempty"`
127 124
 	GraphOptions          []string                  `json:"storage-opts,omitempty"`
... ...
@@ -200,6 +204,7 @@ type CommonConfig struct {
200 200
 
201 201
 	MetricsAddress string `json:"metrics-addr"`
202 202
 
203
+	DNSConfig
203 204
 	LogConfig
204 205
 	BridgeConfig // bridgeConfig holds bridge network specific configuration.
205 206
 	NetworkConfig
... ...
@@ -244,28 +244,36 @@ func TestValidateConfigurationErrors(t *testing.T) {
244 244
 		{
245 245
 			config: &Config{
246 246
 				CommonConfig: CommonConfig{
247
-					DNS: []string{"1.1.1.1o"},
247
+					DNSConfig: DNSConfig{
248
+						DNS: []string{"1.1.1.1o"},
249
+					},
248 250
 				},
249 251
 			},
250 252
 		},
251 253
 		{
252 254
 			config: &Config{
253 255
 				CommonConfig: CommonConfig{
254
-					DNS: []string{"2.2.2.2", "1.1.1.1o"},
256
+					DNSConfig: DNSConfig{
257
+						DNS: []string{"2.2.2.2", "1.1.1.1o"},
258
+					},
255 259
 				},
256 260
 			},
257 261
 		},
258 262
 		{
259 263
 			config: &Config{
260 264
 				CommonConfig: CommonConfig{
261
-					DNSSearch: []string{"123456"},
265
+					DNSConfig: DNSConfig{
266
+						DNSSearch: []string{"123456"},
267
+					},
262 268
 				},
263 269
 			},
264 270
 		},
265 271
 		{
266 272
 			config: &Config{
267 273
 				CommonConfig: CommonConfig{
268
-					DNSSearch: []string{"a.b.c", "123456"},
274
+					DNSConfig: DNSConfig{
275
+						DNSSearch: []string{"a.b.c", "123456"},
276
+					},
269 277
 				},
270 278
 			},
271 279
 		},
... ...
@@ -329,14 +337,18 @@ func TestValidateConfiguration(t *testing.T) {
329 329
 		{
330 330
 			config: &Config{
331 331
 				CommonConfig: CommonConfig{
332
-					DNS: []string{"1.1.1.1"},
332
+					DNSConfig: DNSConfig{
333
+						DNS: []string{"1.1.1.1"},
334
+					},
333 335
 				},
334 336
 			},
335 337
 		},
336 338
 		{
337 339
 			config: &Config{
338 340
 				CommonConfig: CommonConfig{
339
-					DNSSearch: []string{"a.b.c"},
341
+					DNSConfig: DNSConfig{
342
+						DNSSearch: []string{"a.b.c"},
343
+					},
340 344
 				},
341 345
 			},
342 346
 		},
... ...
@@ -1,6 +1,6 @@
1 1
 #!/bin/sh
2 2
 
3
-VNDR_COMMIT=81cb8916aad3c8d06193f008dba3e16f82851f52
3
+VNDR_COMMIT=f5ab8fc5fb64d66b5c6e55a0bcb58b2e92362fa0
4 4
 
5 5
 install_vndr() {
6 6
 	echo "Install vndr version $VNDR_COMMIT"
7 7
new file mode 100644
... ...
@@ -0,0 +1,5 @@
0
+module github.com/gogo/googleapis
1
+
2
+go 1.12
3
+
4
+require github.com/gogo/protobuf v1.2.1
0 5
new file mode 100644
... ...
@@ -0,0 +1,3 @@
0
+module github.com/gogo/protobuf
1
+
2
+require github.com/kisielk/errcheck v1.1.0 // indirect
0 3
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+module github.com/google/uuid
0 1
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+module github.com/gorilla/mux
0 1
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+module github.com/hashicorp/golang-lru
0 1
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+module github.com/konsorten/go-windows-terminal-sequences
0 1
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+module github.com/kr/pty
0 1
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+module github.com/mattn/go-shellwords
0 1
new file mode 100644
... ...
@@ -0,0 +1,77 @@
0
+module github.com/moby/buildkit
1
+
2
+go 1.11
3
+
4
+require (
5
+	github.com/BurntSushi/toml v0.3.1
6
+	github.com/Microsoft/go-winio v0.4.13-0.20190408173621-84b4ab48a507
7
+	github.com/apache/thrift v0.0.0-20161221203622-b2a4d4ae21c7 // indirect
8
+	github.com/codahale/hdrhistogram v0.0.0-20160425231609-f8ad88b59a58 // indirect
9
+	github.com/containerd/cgroups v0.0.0-20190226200435-dbea6f2bd416 // indirect
10
+	github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50
11
+	github.com/containerd/containerd v1.3.0-0.20190507210959-7c1e88399ec0
12
+	github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc
13
+	github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260 // indirect
14
+	github.com/containerd/go-cni v0.0.0-20190610170741-5a4663dad645
15
+	github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3
16
+	github.com/containerd/ttrpc v0.0.0-20190411181408-699c4e40d1e7 // indirect
17
+	github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd // indirect
18
+	github.com/containernetworking/cni v0.6.1-0.20180218032124-142cde0c766c // indirect
19
+	github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
20
+	github.com/docker/cli v0.0.0-20190321234815-f40f9c240ab0
21
+	github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible
22
+	github.com/docker/docker v1.14.0-0.20190319215453-e7b5f7dbe98c
23
+	github.com/docker/docker-credential-helpers v0.6.0 // indirect
24
+	github.com/docker/go-connections v0.3.0
25
+	github.com/docker/go-events v0.0.0-20170721190031-9461782956ad // indirect
26
+	github.com/docker/libnetwork v0.8.0-dev.2.0.20190604151032-3c26b4e7495e
27
+	github.com/godbus/dbus v4.1.0+incompatible // indirect
28
+	github.com/gofrs/flock v0.7.0
29
+	github.com/gogo/googleapis v1.1.0
30
+	github.com/gogo/protobuf v1.2.0
31
+	github.com/golang/protobuf v1.2.0
32
+	github.com/google/go-cmp v0.2.0
33
+	github.com/google/shlex v0.0.0-20150127133951-6f45313302b9
34
+	github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645
35
+	github.com/hashicorp/go-immutable-radix v1.0.0
36
+	github.com/hashicorp/golang-lru v0.0.0-20160207214719-a0d98a5f2880
37
+	github.com/hashicorp/uuid v0.0.0-20160311170451-ebb0a03e909c // indirect
38
+	github.com/ishidawataru/sctp v0.0.0-20180213033435-07191f837fed // indirect
39
+	github.com/jaguilar/vt100 v0.0.0-20150826170717-2703a27b14ea
40
+	github.com/kr/pretty v0.1.0 // indirect
41
+	github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452
42
+	github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c
43
+	github.com/opencontainers/go-digest v1.0.0-rc1
44
+	github.com/opencontainers/image-spec v1.0.1
45
+	github.com/opencontainers/runc v1.0.0-rc8
46
+	github.com/opencontainers/runtime-spec v0.0.0-20180909173843-eba862dc2470
47
+	github.com/opentracing-contrib/go-stdlib v0.0.0-20171029140428-b1a47cfbdd75
48
+	github.com/opentracing/opentracing-go v0.0.0-20171003133519-1361b9cd60be
49
+	github.com/pkg/errors v0.8.1
50
+	github.com/pkg/profile v1.2.1
51
+	github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002
52
+	github.com/sirupsen/logrus v1.3.0
53
+	github.com/stretchr/testify v1.3.0
54
+	github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 // indirect
55
+	github.com/tonistiigi/fsutil v0.0.0-20190327153851-3bbb99cdbd76
56
+	github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea
57
+	github.com/uber/jaeger-client-go v0.0.0-20180103221425-e02c85f9069e
58
+	github.com/uber/jaeger-lib v1.2.1 // indirect
59
+	github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5
60
+	github.com/vishvananda/netlink v1.0.0 // indirect
61
+	github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc // indirect
62
+	go.etcd.io/bbolt v1.3.2
63
+	golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
64
+	golang.org/x/net v0.0.0-20190311183353-d8887717615a
65
+	golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f
66
+	golang.org/x/sys v0.0.0-20190303122642-d455e41777fc
67
+	golang.org/x/time v0.0.0-20161028155119-f51c12702a4d
68
+	google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8
69
+	google.golang.org/grpc v1.20.1
70
+	gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
71
+	gotest.tools v2.2.0+incompatible
72
+)
73
+
74
+replace github.com/hashicorp/go-immutable-radix => github.com/tonistiigi/go-immutable-radix v0.0.0-20170803185627-826af9ccf0fe
75
+
76
+replace github.com/jaguilar/vt100 => github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305
0 77
new file mode 100644
... ...
@@ -0,0 +1,10 @@
0
+module github.com/sirupsen/logrus
1
+
2
+require (
3
+	github.com/davecgh/go-spew v1.1.1 // indirect
4
+	github.com/konsorten/go-windows-terminal-sequences v1.0.1
5
+	github.com/pmezard/go-difflib v1.0.0 // indirect
6
+	github.com/stretchr/objx v0.1.1 // indirect
7
+	github.com/stretchr/testify v1.2.2
8
+	golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33
9
+)
0 10
new file mode 100644
... ...
@@ -0,0 +1,28 @@
0
+module github.com/tonistiigi/fsutil
1
+
2
+require (
3
+	github.com/Microsoft/go-winio v0.4.11 // indirect
4
+	github.com/Microsoft/hcsshim v0.8.5 // indirect
5
+	github.com/containerd/containerd v1.2.4
6
+	github.com/containerd/continuity v0.0.0-20181001140422-bd77b46c8352
7
+	github.com/davecgh/go-spew v1.1.1 // indirect
8
+	github.com/docker/docker v0.0.0-20180531152204-71cd53e4a197
9
+	github.com/docker/go-units v0.3.1 // indirect
10
+	github.com/gogo/protobuf v1.0.0
11
+	github.com/google/go-cmp v0.2.0 // indirect
12
+	github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect
13
+	github.com/onsi/ginkgo v1.7.0 // indirect
14
+	github.com/onsi/gomega v1.4.3 // indirect
15
+	github.com/opencontainers/go-digest v1.0.0-rc1
16
+	github.com/opencontainers/image-spec v1.0.1 // indirect
17
+	github.com/opencontainers/runc v1.0.0-rc6 // indirect
18
+	github.com/pkg/errors v0.8.1
19
+	github.com/sirupsen/logrus v1.0.3 // indirect
20
+	github.com/stretchr/testify v1.3.0
21
+	golang.org/x/crypto v0.0.0-20190129210102-0709b304e793 // indirect
22
+	golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f
23
+	golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e
24
+	gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
25
+	gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
26
+	gotest.tools v2.1.0+incompatible // indirect
27
+)
0 28
new file mode 100644
... ...
@@ -0,0 +1,3 @@
0
+module golang.org/x/crypto
1
+
2
+require golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e
0 3
new file mode 100644
... ...
@@ -0,0 +1,6 @@
0
+module golang.org/x/net
1
+
2
+require (
3
+	golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
4
+	golang.org/x/text v0.3.0
5
+)
0 6
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+module golang.org/x/sync
0 1
new file mode 100644
... ...
@@ -0,0 +1,3 @@
0
+module golang.org/x/sys
1
+
2
+go 1.12
0 3
new file mode 100644
... ...
@@ -0,0 +1,19 @@
0
+module google.golang.org/grpc
1
+
2
+require (
3
+	cloud.google.com/go v0.26.0 // indirect
4
+	github.com/BurntSushi/toml v0.3.1 // indirect
5
+	github.com/client9/misspell v0.3.4
6
+	github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
7
+	github.com/golang/mock v1.1.1
8
+	github.com/golang/protobuf v1.2.0
9
+	golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3
10
+	golang.org/x/net v0.0.0-20190311183353-d8887717615a
11
+	golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
12
+	golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f // indirect
13
+	golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
14
+	golang.org/x/tools v0.0.0-20190311212946-11955173bddd
15
+	google.golang.org/appengine v1.1.0 // indirect
16
+	google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8
17
+	honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099
18
+)
0 19
new file mode 100644
... ...
@@ -0,0 +1,8 @@
0
+module gotest.tools
1
+
2
+require (
3
+	github.com/google/go-cmp v0.2.0
4
+	github.com/pkg/errors v0.8.0
5
+	github.com/spf13/pflag v1.0.3
6
+	golang.org/x/tools v0.0.0-20180810170437-e96c4e24768d
7
+)