Browse code

vendor: update containerd c80284d4b5291a351bb471bcdabb5c1d95e7a583

full diff: https://github.com/containerd/containerd/compare/4d242818bf55542e5d7876ca276fea83029e803c...c80284d4b5291a351bb471bcdabb5c1d95e7a583

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2020/05/06 21:59:30
Showing 43 changed files
... ...
@@ -122,7 +122,7 @@ github.com/googleapis/gax-go                        317e0006254c44a0ac427cc52a0e
122 122
 google.golang.org/genproto                          3f1135a288c9a07e340ae8ba4cc6c7065a3160e8
123 123
 
124 124
 # containerd
125
-github.com/containerd/containerd                    4d242818bf55542e5d7876ca276fea83029e803c
125
+github.com/containerd/containerd                    c80284d4b5291a351bb471bcdabb5c1d95e7a583 # master / v1.4.0-dev
126 126
 github.com/containerd/fifo                          ff969a566b00877c63489baf6e8c35d60af6142c
127 127
 github.com/containerd/continuity                    26c1120b8d4107d2471b93ad78ef7ce1fc84c4c4
128 128
 github.com/containerd/cgroups                       44306b6a1d46985d916b48b4199f93a378af314f
... ...
@@ -1,9 +1,9 @@
1 1
 ![containerd banner](https://raw.githubusercontent.com/cncf/artwork/master/projects/containerd/horizontal/color/containerd-horizontal-color.png)
2 2
 
3 3
 [![GoDoc](https://godoc.org/github.com/containerd/containerd?status.svg)](https://godoc.org/github.com/containerd/containerd)
4
-[![Build Status](https://travis-ci.org/containerd/containerd.svg?branch=master)](https://travis-ci.org/containerd/containerd)
4
+[![Build Status](https://github.com/containerd/containerd/workflows/CI/badge.svg)](https://github.com/containerd/containerd/actions?query=workflow%3ACI)
5 5
 [![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/containerd/containerd?branch=master&svg=true)](https://ci.appveyor.com/project/mlaventure/containerd-3g73f?branch=master)
6
-![](https://github.com/containerd/containerd/workflows/Nightly/badge.svg)
6
+[![Nightlies](https://github.com/containerd/containerd/workflows/Nightly/badge.svg)](https://github.com/containerd/containerd/actions?query=workflow%3ANightly)
7 7
 [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fcontainerd%2Fcontainerd.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fcontainerd%2Fcontainerd?ref=badge_shield)
8 8
 [![Go Report Card](https://goreportcard.com/badge/github.com/containerd/containerd)](https://goreportcard.com/report/github.com/containerd/containerd)
9 9
 [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1271/badge)](https://bestpractices.coreinfrastructure.org/projects/1271)
... ...
@@ -361,7 +361,7 @@ func createTarFile(ctx context.Context, path, extractDir string, hdr *tar.Header
361 361
 		if strings.HasPrefix(key, paxSchilyXattr) {
362 362
 			key = key[len(paxSchilyXattr):]
363 363
 			if err := setxattr(path, key, value); err != nil {
364
-				if errors.Cause(err) == syscall.ENOTSUP {
364
+				if errors.Is(err, syscall.ENOTSUP) {
365 365
 					log.G(ctx).WithError(err).Warnf("ignored xattr %s in archive", key)
366 366
 					continue
367 367
 				}
... ...
@@ -22,12 +22,11 @@ import (
22 22
 	"archive/tar"
23 23
 	"os"
24 24
 	"strings"
25
-	"sync"
26 25
 	"syscall"
27 26
 
27
+	"github.com/containerd/containerd/sys"
28 28
 	"github.com/containerd/continuity/fs"
29 29
 	"github.com/containerd/continuity/sysx"
30
-	"github.com/opencontainers/runc/libcontainer/system"
31 30
 	"github.com/pkg/errors"
32 31
 	"golang.org/x/sys/unix"
33 32
 )
... ...
@@ -84,21 +83,11 @@ func mkdir(path string, perm os.FileMode) error {
84 84
 	return os.Chmod(path, perm)
85 85
 }
86 86
 
87
-var (
88
-	inUserNS bool
89
-	nsOnce   sync.Once
90
-)
91
-
92
-func setInUserNS() {
93
-	inUserNS = system.RunningInUserNS()
94
-}
95
-
96 87
 func skipFile(hdr *tar.Header) bool {
97 88
 	switch hdr.Typeflag {
98 89
 	case tar.TypeBlock, tar.TypeChar:
99 90
 		// cannot create a device if running in user namespace
100
-		nsOnce.Do(setInUserNS)
101
-		return inUserNS
91
+		return sys.RunningInUserNS()
102 92
 	default:
103 93
 		return false
104 94
 	}
... ...
@@ -125,7 +114,7 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
125 125
 func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
126 126
 	if hdr.Typeflag == tar.TypeLink {
127 127
 		if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
128
-			if err := os.Chmod(path, hdrInfo.Mode()); err != nil {
128
+			if err := os.Chmod(path, hdrInfo.Mode()); err != nil && !os.IsNotExist(err) {
129 129
 				return err
130 130
 			}
131 131
 		}
... ...
@@ -58,7 +58,6 @@ import (
58 58
 	"github.com/containerd/containerd/snapshots"
59 59
 	snproxy "github.com/containerd/containerd/snapshots/proxy"
60 60
 	"github.com/containerd/typeurl"
61
-	"github.com/gogo/protobuf/types"
62 61
 	ptypes "github.com/gogo/protobuf/types"
63 62
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
64 63
 	specs "github.com/opencontainers/runtime-spec/specs-go"
... ...
@@ -319,6 +318,9 @@ type RemoteContext struct {
319 319
 	// Snapshotter used for unpacking
320 320
 	Snapshotter string
321 321
 
322
+	// SnapshotterOpts are additional options to be passed to a snapshotter during pull
323
+	SnapshotterOpts []snapshots.Opt
324
+
322 325
 	// Labels to be applied to the created image
323 326
 	Labels map[string]string
324 327
 
... ...
@@ -720,7 +722,7 @@ func (c *Client) Server(ctx context.Context) (ServerInfo, error) {
720 720
 	}
721 721
 	c.connMu.Unlock()
722 722
 
723
-	response, err := c.IntrospectionService().Server(ctx, &types.Empty{})
723
+	response, err := c.IntrospectionService().Server(ctx, &ptypes.Empty{})
724 724
 	if err != nil {
725 725
 		return ServerInfo{}, err
726 726
 	}
... ...
@@ -22,6 +22,8 @@ import (
22 22
 	"github.com/containerd/containerd/images"
23 23
 	"github.com/containerd/containerd/platforms"
24 24
 	"github.com/containerd/containerd/remotes"
25
+	"github.com/containerd/containerd/snapshots"
26
+
25 27
 	"google.golang.org/grpc"
26 28
 )
27 29
 
... ...
@@ -138,10 +140,11 @@ func WithUnpackOpts(opts []UnpackOpt) RemoteOpt {
138 138
 	}
139 139
 }
140 140
 
141
-// WithPullSnapshotter specifies snapshotter name used for unpacking
142
-func WithPullSnapshotter(snapshotterName string) RemoteOpt {
141
+// WithPullSnapshotter specifies snapshotter name used for unpacking.
142
+func WithPullSnapshotter(snapshotterName string, opts ...snapshots.Opt) RemoteOpt {
143 143
 	return func(_ *Client, c *RemoteContext) error {
144 144
 		c.Snapshotter = snapshotterName
145
+		c.SnapshotterOpts = opts
145 146
 		return nil
146 147
 	}
147 148
 }
... ...
@@ -32,6 +32,7 @@ import (
32 32
 	"github.com/containerd/containerd/images"
33 33
 	"github.com/containerd/containerd/oci"
34 34
 	"github.com/containerd/containerd/runtime/v2/runc/options"
35
+	"github.com/containerd/containerd/sys"
35 36
 	"github.com/containerd/typeurl"
36 37
 	prototypes "github.com/gogo/protobuf/types"
37 38
 	ver "github.com/opencontainers/image-spec/specs-go"
... ...
@@ -422,14 +423,33 @@ func attachExistingIO(response *tasks.GetResponse, ioAttach cio.Attach) (cio.IO,
422 422
 
423 423
 // loadFifos loads the containers fifos
424 424
 func loadFifos(response *tasks.GetResponse) *cio.FIFOSet {
425
-	path := getFifoDir([]string{
425
+	fifos := []string{
426 426
 		response.Process.Stdin,
427 427
 		response.Process.Stdout,
428 428
 		response.Process.Stderr,
429
-	})
429
+	}
430 430
 	closer := func() error {
431
-		return os.RemoveAll(path)
431
+		var (
432
+			err  error
433
+			dirs = map[string]struct{}{}
434
+		)
435
+		for _, fifo := range fifos {
436
+			if isFifo, _ := sys.IsFifo(fifo); isFifo {
437
+				if rerr := os.Remove(fifo); err == nil {
438
+					err = rerr
439
+				}
440
+				dirs[filepath.Dir(fifo)] = struct{}{}
441
+			}
442
+		}
443
+		for dir := range dirs {
444
+			// we ignore errors here because we don't
445
+			// want to remove the directory if it isn't
446
+			// empty
447
+			os.Remove(dir)
448
+		}
449
+		return err
432 450
 	}
451
+
433 452
 	return cio.NewFIFOSet(cio.Config{
434 453
 		Stdin:    response.Process.Stdin,
435 454
 		Stdout:   response.Process.Stdout,
... ...
@@ -437,14 +457,3 @@ func loadFifos(response *tasks.GetResponse) *cio.FIFOSet {
437 437
 		Terminal: response.Process.Terminal,
438 438
 	}, closer)
439 439
 }
440
-
441
-// getFifoDir looks for any non-empty path for a stdio fifo
442
-// and returns the dir for where it is located
443
-func getFifoDir(paths []string) string {
444
-	for _, p := range paths {
445
-		if p != "" {
446
-			return filepath.Dir(p)
447
-		}
448
-	}
449
-	return ""
450
-}
... ...
@@ -226,7 +226,7 @@ func WithContainerExtension(name string, extension interface{}) NewContainerOpts
226 226
 
227 227
 		any, err := typeurl.MarshalAny(extension)
228 228
 		if err != nil {
229
-			if errors.Cause(err) == typeurl.ErrNotFound {
229
+			if errors.Is(err, typeurl.ErrNotFound) {
230 230
 				return errors.Wrapf(err, "extension %q is not registered with the typeurl package, see `typeurl.Register`", name)
231 231
 			}
232 232
 			return errors.Wrap(err, "error marshalling extension")
... ...
@@ -92,7 +92,11 @@ func NewLabeledStore(root string, ls LabelStore) (content.Store, error) {
92 92
 }
93 93
 
94 94
 func (s *store) Info(ctx context.Context, dgst digest.Digest) (content.Info, error) {
95
-	p := s.blobPath(dgst)
95
+	p, err := s.blobPath(dgst)
96
+	if err != nil {
97
+		return content.Info{}, errors.Wrapf(err, "calculating blob info path")
98
+	}
99
+
96 100
 	fi, err := os.Stat(p)
97 101
 	if err != nil {
98 102
 		if os.IsNotExist(err) {
... ...
@@ -123,7 +127,10 @@ func (s *store) info(dgst digest.Digest, fi os.FileInfo, labels map[string]strin
123 123
 
124 124
 // ReaderAt returns an io.ReaderAt for the blob.
125 125
 func (s *store) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.ReaderAt, error) {
126
-	p := s.blobPath(desc.Digest)
126
+	p, err := s.blobPath(desc.Digest)
127
+	if err != nil {
128
+		return nil, errors.Wrapf(err, "calculating blob path for ReaderAt")
129
+	}
127 130
 	fi, err := os.Stat(p)
128 131
 	if err != nil {
129 132
 		if !os.IsNotExist(err) {
... ...
@@ -150,7 +157,12 @@ func (s *store) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.
150 150
 // While this is safe to do concurrently, safe exist-removal logic must hold
151 151
 // some global lock on the store.
152 152
 func (s *store) Delete(ctx context.Context, dgst digest.Digest) error {
153
-	if err := os.RemoveAll(s.blobPath(dgst)); err != nil {
153
+	bp, err := s.blobPath(dgst)
154
+	if err != nil {
155
+		return errors.Wrapf(err, "calculating blob path for delete")
156
+	}
157
+
158
+	if err := os.RemoveAll(bp); err != nil {
154 159
 		if !os.IsNotExist(err) {
155 160
 			return err
156 161
 		}
... ...
@@ -166,7 +178,11 @@ func (s *store) Update(ctx context.Context, info content.Info, fieldpaths ...str
166 166
 		return content.Info{}, errors.Wrapf(errdefs.ErrFailedPrecondition, "update not supported on immutable content store")
167 167
 	}
168 168
 
169
-	p := s.blobPath(info.Digest)
169
+	p, err := s.blobPath(info.Digest)
170
+	if err != nil {
171
+		return content.Info{}, errors.Wrapf(err, "calculating blob path for update")
172
+	}
173
+
170 174
 	fi, err := os.Stat(p)
171 175
 	if err != nil {
172 176
 		if os.IsNotExist(err) {
... ...
@@ -512,7 +528,10 @@ func (s *store) writer(ctx context.Context, ref string, total int64, expected di
512 512
 	// TODO(stevvooe): Need to actually store expected here. We have
513 513
 	// code in the service that shouldn't be dealing with this.
514 514
 	if expected != "" {
515
-		p := s.blobPath(expected)
515
+		p, err := s.blobPath(expected)
516
+		if err != nil {
517
+			return nil, errors.Wrap(err, "calculating expected blob path for writer")
518
+		}
516 519
 		if _, err := os.Stat(p); err == nil {
517 520
 			return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v", expected)
518 521
 		}
... ...
@@ -607,11 +626,17 @@ func (s *store) Abort(ctx context.Context, ref string) error {
607 607
 	return nil
608 608
 }
609 609
 
610
-func (s *store) blobPath(dgst digest.Digest) string {
611
-	return filepath.Join(s.root, "blobs", dgst.Algorithm().String(), dgst.Hex())
610
+func (s *store) blobPath(dgst digest.Digest) (string, error) {
611
+	if err := dgst.Validate(); err != nil {
612
+		return "", errors.Wrapf(errdefs.ErrInvalidArgument, "cannot calculate blob path from invalid digest: %v", err)
613
+	}
614
+
615
+	return filepath.Join(s.root, "blobs", dgst.Algorithm().String(), dgst.Hex()), nil
612 616
 }
613 617
 
614 618
 func (s *store) ingestRoot(ref string) string {
619
+	// we take a digest of the ref to keep the ingest paths constant length.
620
+	// Note that this is not the current or potential digest of incoming content.
615 621
 	dgst := digest.FromString(ref)
616 622
 	return filepath.Join(s.root, "ingest", dgst.Hex())
617 623
 }
... ...
@@ -115,8 +115,8 @@ func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest,
115 115
 	}
116 116
 
117 117
 	var (
118
-		ingest = filepath.Join(w.path, "data")
119
-		target = w.s.blobPath(dgst)
118
+		ingest    = filepath.Join(w.path, "data")
119
+		target, _ = w.s.blobPath(dgst) // ignore error because we calculated this dgst
120 120
 	)
121 121
 
122 122
 	// make sure parent directories of blob exist
... ...
@@ -56,7 +56,6 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
56 56
 				"accept4",
57 57
 				"access",
58 58
 				"alarm",
59
-				"alarm",
60 59
 				"bind",
61 60
 				"brk",
62 61
 				"capget",
... ...
@@ -66,8 +65,11 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
66 66
 				"chown",
67 67
 				"chown32",
68 68
 				"clock_getres",
69
+				"clock_getres_time64",
69 70
 				"clock_gettime",
71
+				"clock_gettime64",
70 72
 				"clock_nanosleep",
73
+				"clock_nanosleep_time64",
71 74
 				"close",
72 75
 				"connect",
73 76
 				"copy_file_range",
... ...
@@ -117,6 +119,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
117 117
 				"ftruncate",
118 118
 				"ftruncate64",
119 119
 				"futex",
120
+				"futex_time64",
120 121
 				"futimesat",
121 122
 				"getcpu",
122 123
 				"getcwd",
... ...
@@ -163,6 +166,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
163 163
 				"io_destroy",
164 164
 				"io_getevents",
165 165
 				"io_pgetevents",
166
+				"io_pgetevents_time64",
166 167
 				"ioprio_get",
167 168
 				"ioprio_set",
168 169
 				"io_setup",
... ...
@@ -200,7 +204,9 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
200 200
 				"mq_notify",
201 201
 				"mq_open",
202 202
 				"mq_timedreceive",
203
+				"mq_timedreceive_time64",
203 204
 				"mq_timedsend",
205
+				"mq_timedsend_time64",
204 206
 				"mq_unlink",
205 207
 				"mremap",
206 208
 				"msgctl",
... ...
@@ -221,11 +227,13 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
221 221
 				"pipe2",
222 222
 				"poll",
223 223
 				"ppoll",
224
+				"ppoll_time64",
224 225
 				"prctl",
225 226
 				"pread64",
226 227
 				"preadv",
227 228
 				"prlimit64",
228 229
 				"pselect6",
230
+				"pselect6_time64",
229 231
 				"pwrite64",
230 232
 				"pwritev",
231 233
 				"read",
... ...
@@ -236,6 +244,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
236 236
 				"recv",
237 237
 				"recvfrom",
238 238
 				"recvmmsg",
239
+				"recvmmsg_time64",
239 240
 				"recvmsg",
240 241
 				"remap_file_pages",
241 242
 				"removexattr",
... ...
@@ -251,6 +260,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
251 251
 				"rt_sigreturn",
252 252
 				"rt_sigsuspend",
253 253
 				"rt_sigtimedwait",
254
+				"rt_sigtimedwait_time64",
254 255
 				"rt_tgsigqueueinfo",
255 256
 				"sched_getaffinity",
256 257
 				"sched_getattr",
... ...
@@ -259,6 +269,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
259 259
 				"sched_get_priority_min",
260 260
 				"sched_getscheduler",
261 261
 				"sched_rr_get_interval",
262
+				"sched_rr_get_interval_time64",
262 263
 				"sched_setaffinity",
263 264
 				"sched_setattr",
264 265
 				"sched_setparam",
... ...
@@ -270,6 +281,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
270 270
 				"semget",
271 271
 				"semop",
272 272
 				"semtimedop",
273
+				"semtimedop_time64",
273 274
 				"send",
274 275
 				"sendfile",
275 276
 				"sendfile64",
... ...
@@ -335,12 +347,16 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
335 335
 				"time",
336 336
 				"timer_create",
337 337
 				"timer_delete",
338
-				"timerfd_create",
339
-				"timerfd_gettime",
340
-				"timerfd_settime",
341 338
 				"timer_getoverrun",
342 339
 				"timer_gettime",
340
+				"timer_gettime64",
343 341
 				"timer_settime",
342
+				"timer_settime64",
343
+				"timerfd_create",
344
+				"timerfd_gettime",
345
+				"timerfd_gettime64",
346
+				"timerfd_settime",
347
+				"timerfd_settime64",
344 348
 				"times",
345 349
 				"tkill",
346 350
 				"truncate",
... ...
@@ -352,6 +368,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
352 352
 				"unlinkat",
353 353
 				"utime",
354 354
 				"utimensat",
355
+				"utimensat_time64",
355 356
 				"utimes",
356 357
 				"vfork",
357 358
 				"vmsplice",
... ...
@@ -51,43 +51,43 @@ var (
51 51
 
52 52
 // IsInvalidArgument returns true if the error is due to an invalid argument
53 53
 func IsInvalidArgument(err error) bool {
54
-	return errors.Cause(err) == ErrInvalidArgument
54
+	return errors.Is(err, ErrInvalidArgument)
55 55
 }
56 56
 
57 57
 // IsNotFound returns true if the error is due to a missing object
58 58
 func IsNotFound(err error) bool {
59
-	return errors.Cause(err) == ErrNotFound
59
+	return errors.Is(err, ErrNotFound)
60 60
 }
61 61
 
62 62
 // IsAlreadyExists returns true if the error is due to an already existing
63 63
 // metadata item
64 64
 func IsAlreadyExists(err error) bool {
65
-	return errors.Cause(err) == ErrAlreadyExists
65
+	return errors.Is(err, ErrAlreadyExists)
66 66
 }
67 67
 
68 68
 // IsFailedPrecondition returns true if an operation could not proceed to the
69 69
 // lack of a particular condition
70 70
 func IsFailedPrecondition(err error) bool {
71
-	return errors.Cause(err) == ErrFailedPrecondition
71
+	return errors.Is(err, ErrFailedPrecondition)
72 72
 }
73 73
 
74 74
 // IsUnavailable returns true if the error is due to a resource being unavailable
75 75
 func IsUnavailable(err error) bool {
76
-	return errors.Cause(err) == ErrUnavailable
76
+	return errors.Is(err, ErrUnavailable)
77 77
 }
78 78
 
79 79
 // IsNotImplemented returns true if the error is due to not being implemented
80 80
 func IsNotImplemented(err error) bool {
81
-	return errors.Cause(err) == ErrNotImplemented
81
+	return errors.Is(err, ErrNotImplemented)
82 82
 }
83 83
 
84 84
 // IsCanceled returns true if the error is due to `context.Canceled`.
85 85
 func IsCanceled(err error) bool {
86
-	return errors.Cause(err) == context.Canceled
86
+	return errors.Is(err, context.Canceled)
87 87
 }
88 88
 
89 89
 // IsDeadlineExceeded returns true if the error is due to
90 90
 // `context.DeadlineExceeded`.
91 91
 func IsDeadlineExceeded(err error) bool {
92
-	return errors.Cause(err) == context.DeadlineExceeded
92
+	return errors.Is(err, context.DeadlineExceeded)
93 93
 }
... ...
@@ -64,7 +64,7 @@ func Handlers(handlers ...Handler) HandlerFunc {
64 64
 		for _, handler := range handlers {
65 65
 			ch, err := handler.Handle(ctx, desc)
66 66
 			if err != nil {
67
-				if errors.Cause(err) == ErrStopHandler {
67
+				if errors.Is(err, ErrStopHandler) {
68 68
 					break
69 69
 				}
70 70
 				return nil, err
... ...
@@ -87,7 +87,7 @@ func Walk(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) err
87 87
 
88 88
 		children, err := handler.Handle(ctx, desc)
89 89
 		if err != nil {
90
-			if errors.Cause(err) == ErrSkipDesc {
90
+			if errors.Is(err, ErrSkipDesc) {
91 91
 				continue // don't traverse the children.
92 92
 			}
93 93
 			return err
... ...
@@ -136,7 +136,7 @@ func Dispatch(ctx context.Context, handler Handler, limiter *semaphore.Weighted,
136 136
 				limiter.Release(1)
137 137
 			}
138 138
 			if err != nil {
139
-				if errors.Cause(err) == ErrSkipDesc {
139
+				if errors.Is(err, ErrSkipDesc) {
140 140
 					return nil // don't traverse the children.
141 141
 				}
142 142
 				return err
... ...
@@ -25,11 +25,11 @@ import (
25 25
 
26 26
 // WithLease attaches a lease on the context
27 27
 func (c *Client) WithLease(ctx context.Context, opts ...leases.Opt) (context.Context, func(context.Context) error, error) {
28
+	nop := func(context.Context) error { return nil }
29
+
28 30
 	_, ok := leases.FromContext(ctx)
29 31
 	if ok {
30
-		return ctx, func(context.Context) error {
31
-			return nil
32
-		}, nil
32
+		return ctx, nop, nil
33 33
 	}
34 34
 
35 35
 	ls := c.LeasesService()
... ...
@@ -44,7 +44,7 @@ func (c *Client) WithLease(ctx context.Context, opts ...leases.Opt) (context.Con
44 44
 
45 45
 	l, err := ls.Create(ctx, opts...)
46 46
 	if err != nil {
47
-		return nil, nil, err
47
+		return ctx, nop, err
48 48
 	}
49 49
 
50 50
 	ctx = leases.WithLease(ctx, l.ID)
... ...
@@ -45,10 +45,6 @@ func parseInfoFile(r io.Reader) ([]Info, error) {
45 45
 	out := []Info{}
46 46
 	var err error
47 47
 	for s.Scan() {
48
-		if err = s.Err(); err != nil {
49
-			return nil, err
50
-		}
51
-
52 48
 		/*
53 49
 		   See http://man7.org/linux/man-pages/man5/proc.5.html
54 50
 
... ...
@@ -128,6 +124,10 @@ func parseInfoFile(r io.Reader) ([]Info, error) {
128 128
 
129 129
 		out = append(out, p)
130 130
 	}
131
+	if err = s.Err(); err != nil {
132
+		return nil, err
133
+	}
134
+
131 135
 	return out, nil
132 136
 }
133 137
 
... ...
@@ -91,6 +91,21 @@ func setResources(s *Spec) {
91 91
 	}
92 92
 }
93 93
 
94
+// nolint
95
+func setCPU(s *Spec) {
96
+	setResources(s)
97
+	if s.Linux != nil {
98
+		if s.Linux.Resources.CPU == nil {
99
+			s.Linux.Resources.CPU = &specs.LinuxCPU{}
100
+		}
101
+	}
102
+	if s.Windows != nil {
103
+		if s.Windows.Resources.CPU == nil {
104
+			s.Windows.Resources.CPU = &specs.WindowsCPUResources{}
105
+		}
106
+	}
107
+}
108
+
94 109
 // setCapabilities sets Linux Capabilities to empty if unset
95 110
 func setCapabilities(s *Spec) {
96 111
 	setProcess(s)
... ...
@@ -1223,11 +1238,11 @@ func WithEnvFile(path string) SpecOpts {
1223 1223
 
1224 1224
 		sc := bufio.NewScanner(f)
1225 1225
 		for sc.Scan() {
1226
-			if sc.Err() != nil {
1227
-				return sc.Err()
1228
-			}
1229 1226
 			vars = append(vars, sc.Text())
1230 1227
 		}
1228
+		if err = sc.Err(); err != nil {
1229
+			return err
1230
+		}
1231 1231
 		return WithEnv(vars)(nil, nil, nil, s)
1232 1232
 	}
1233 1233
 }
... ...
@@ -119,3 +119,64 @@ func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
119 119
 		GID:      &stat.Gid,
120 120
 	}, nil
121 121
 }
122
+
123
+// WithMemorySwap sets the container's swap in bytes
124
+func WithMemorySwap(swap int64) SpecOpts {
125
+	return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
126
+		setResources(s)
127
+		if s.Linux.Resources.Memory == nil {
128
+			s.Linux.Resources.Memory = &specs.LinuxMemory{}
129
+		}
130
+		s.Linux.Resources.Memory.Swap = &swap
131
+		return nil
132
+	}
133
+}
134
+
135
+// WithPidsLimit sets the container's pid limit or maximum
136
+func WithPidsLimit(limit int64) SpecOpts {
137
+	return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
138
+		setResources(s)
139
+		if s.Linux.Resources.Pids == nil {
140
+			s.Linux.Resources.Pids = &specs.LinuxPids{}
141
+		}
142
+		s.Linux.Resources.Pids.Limit = limit
143
+		return nil
144
+	}
145
+}
146
+
147
+// WithCPUShares sets the container's cpu shares
148
+func WithCPUShares(shares uint64) SpecOpts {
149
+	return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
150
+		setCPU(s)
151
+		s.Linux.Resources.CPU.Shares = &shares
152
+		return nil
153
+	}
154
+}
155
+
156
+// WithCPUs sets the container's cpus/cores for use by the container
157
+func WithCPUs(cpus string) SpecOpts {
158
+	return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
159
+		setCPU(s)
160
+		s.Linux.Resources.CPU.Cpus = cpus
161
+		return nil
162
+	}
163
+}
164
+
165
+// WithCPUsMems sets the container's cpu mems for use by the container
166
+func WithCPUsMems(mems string) SpecOpts {
167
+	return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
168
+		setCPU(s)
169
+		s.Linux.Resources.CPU.Mems = mems
170
+		return nil
171
+	}
172
+}
173
+
174
+// WithCPUCFS sets the container's Completely fair scheduling (CFS) quota and period
175
+func WithCPUCFS(quota int64, period uint64) SpecOpts {
176
+	return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
177
+		setCPU(s)
178
+		s.Linux.Resources.CPU.Quota = &quota
179
+		s.Linux.Resources.CPU.Period = &period
180
+		return nil
181
+	}
182
+}
... ...
@@ -29,15 +29,20 @@ import (
29 29
 	"sync"
30 30
 	"sync/atomic"
31 31
 	"syscall"
32
+	"time"
32 33
 
33 34
 	"github.com/containerd/containerd/log"
34 35
 	"github.com/containerd/containerd/namespaces"
35 36
 	"github.com/containerd/containerd/pkg/stdio"
37
+	"github.com/containerd/containerd/sys"
36 38
 	"github.com/containerd/fifo"
37 39
 	runc "github.com/containerd/go-runc"
40
+	"github.com/hashicorp/go-multierror"
38 41
 	"github.com/pkg/errors"
39 42
 )
40 43
 
44
+const binaryIOProcTermTimeout = 12 * time.Second // Give logger process solid 10 seconds for cleanup
45
+
41 46
 var bufPool = sync.Pool{
42 47
 	New: func() interface{} {
43 48
 		// setting to 4096 to align with PIPE_BUF
... ...
@@ -174,7 +179,7 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w
174 174
 			},
175 175
 		},
176 176
 	} {
177
-		ok, err := isFifo(i.name)
177
+		ok, err := sys.IsFifo(i.name)
178 178
 		if err != nil {
179 179
 			return err
180 180
 		}
... ...
@@ -240,28 +245,13 @@ func (c *countingWriteCloser) Close() error {
240 240
 	return c.WriteCloser.Close()
241 241
 }
242 242
 
243
-// isFifo checks if a file is a fifo
244
-// if the file does not exist then it returns false
245
-func isFifo(path string) (bool, error) {
246
-	stat, err := os.Stat(path)
247
-	if err != nil {
248
-		if os.IsNotExist(err) {
249
-			return false, nil
250
-		}
251
-		return false, err
252
-	}
253
-	if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
254
-		return true, nil
255
-	}
256
-	return false, nil
257
-}
258
-
259 243
 // NewBinaryIO runs a custom binary process for pluggable shim logging
260
-func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error) {
244
+func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (_ runc.IO, err error) {
261 245
 	ns, err := namespaces.NamespaceRequired(ctx)
262 246
 	if err != nil {
263 247
 		return nil, err
264 248
 	}
249
+
265 250
 	var args []string
266 251
 	for k, vs := range uri.Query() {
267 252
 		args = append(args, k)
... ...
@@ -269,86 +259,146 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error)
269 269
 			args = append(args, vs[0])
270 270
 		}
271 271
 	}
272
-	ctx, cancel := context.WithCancel(ctx)
273
-	cmd := exec.CommandContext(ctx, uri.Path, args...)
274
-	cmd.Env = append(cmd.Env,
275
-		"CONTAINER_ID="+id,
276
-		"CONTAINER_NAMESPACE="+ns,
277
-	)
272
+
273
+	var closers []func() error
274
+	defer func() {
275
+		if err == nil {
276
+			return
277
+		}
278
+		result := multierror.Append(err)
279
+		for _, fn := range closers {
280
+			result = multierror.Append(result, fn())
281
+		}
282
+		err = multierror.Flatten(result)
283
+	}()
284
+
278 285
 	out, err := newPipe()
279 286
 	if err != nil {
280
-		cancel()
281
-		return nil, err
287
+		return nil, errors.Wrap(err, "failed to create stdout pipes")
282 288
 	}
289
+	closers = append(closers, out.Close)
290
+
283 291
 	serr, err := newPipe()
284 292
 	if err != nil {
285
-		cancel()
286
-		return nil, err
293
+		return nil, errors.Wrap(err, "failed to create stderr pipes")
287 294
 	}
295
+	closers = append(closers, serr.Close)
296
+
288 297
 	r, w, err := os.Pipe()
289 298
 	if err != nil {
290
-		cancel()
291 299
 		return nil, err
292 300
 	}
301
+	closers = append(closers, r.Close, w.Close)
302
+
303
+	cmd := exec.Command(uri.Path, args...)
304
+	cmd.Env = append(cmd.Env,
305
+		"CONTAINER_ID="+id,
306
+		"CONTAINER_NAMESPACE="+ns,
307
+	)
308
+
293 309
 	cmd.ExtraFiles = append(cmd.ExtraFiles, out.r, serr.r, w)
294 310
 	// don't need to register this with the reaper or wait when
295 311
 	// running inside a shim
296 312
 	if err := cmd.Start(); err != nil {
297
-		cancel()
298
-		return nil, err
313
+		return nil, errors.Wrap(err, "failed to start binary process")
299 314
 	}
315
+	closers = append(closers, func() error { return cmd.Process.Kill() })
316
+
300 317
 	// close our side of the pipe after start
301 318
 	if err := w.Close(); err != nil {
302
-		cancel()
303
-		return nil, err
319
+		return nil, errors.Wrap(err, "failed to close write pipe after start")
304 320
 	}
321
+
305 322
 	// wait for the logging binary to be ready
306 323
 	b := make([]byte, 1)
307 324
 	if _, err := r.Read(b); err != nil && err != io.EOF {
308
-		cancel()
309
-		return nil, err
325
+		return nil, errors.Wrap(err, "failed to read from logging binary")
310 326
 	}
327
+
311 328
 	return &binaryIO{
312
-		cmd:    cmd,
313
-		cancel: cancel,
314
-		out:    out,
315
-		err:    serr,
329
+		cmd: cmd,
330
+		out: out,
331
+		err: serr,
316 332
 	}, nil
317 333
 }
318 334
 
319 335
 type binaryIO struct {
320 336
 	cmd      *exec.Cmd
321
-	cancel   func()
322 337
 	out, err *pipe
323 338
 }
324 339
 
325
-func (b *binaryIO) CloseAfterStart() (err error) {
326
-	for _, v := range []*pipe{
327
-		b.out,
328
-		b.err,
329
-	} {
340
+func (b *binaryIO) CloseAfterStart() error {
341
+	var (
342
+		result *multierror.Error
343
+	)
344
+
345
+	for _, v := range []*pipe{b.out, b.err} {
330 346
 		if v != nil {
331
-			if cerr := v.r.Close(); err == nil {
332
-				err = cerr
347
+			if err := v.r.Close(); err != nil {
348
+				result = multierror.Append(result, err)
333 349
 			}
334 350
 		}
335 351
 	}
336
-	return err
352
+
353
+	return result.ErrorOrNil()
337 354
 }
338 355
 
339
-func (b *binaryIO) Close() (err error) {
340
-	b.cancel()
341
-	for _, v := range []*pipe{
342
-		b.out,
343
-		b.err,
344
-	} {
356
+func (b *binaryIO) Close() error {
357
+	var (
358
+		result *multierror.Error
359
+	)
360
+
361
+	for _, v := range []*pipe{b.out, b.err} {
345 362
 		if v != nil {
346
-			if cerr := v.Close(); err == nil {
347
-				err = cerr
363
+			if err := v.Close(); err != nil {
364
+				result = multierror.Append(result, err)
348 365
 			}
349 366
 		}
350 367
 	}
351
-	return err
368
+
369
+	if err := b.cancel(); err != nil {
370
+		result = multierror.Append(result, err)
371
+	}
372
+
373
+	return result.ErrorOrNil()
374
+}
375
+
376
+func (b *binaryIO) cancel() error {
377
+	if b.cmd == nil || b.cmd.Process == nil {
378
+		return nil
379
+	}
380
+
381
+	// Send SIGTERM first, so logger process has a chance to flush and exit properly
382
+	if err := b.cmd.Process.Signal(syscall.SIGTERM); err != nil {
383
+		result := multierror.Append(errors.Wrap(err, "failed to send SIGTERM"))
384
+
385
+		log.L.WithError(err).Warn("failed to send SIGTERM signal, killing logging shim")
386
+
387
+		if err := b.cmd.Process.Kill(); err != nil {
388
+			result = multierror.Append(result, errors.Wrap(err, "failed to kill process after faulty SIGTERM"))
389
+		}
390
+
391
+		return result.ErrorOrNil()
392
+	}
393
+
394
+	done := make(chan error)
395
+	go func() {
396
+		done <- b.cmd.Wait()
397
+	}()
398
+
399
+	select {
400
+	case err := <-done:
401
+		return err
402
+	case <-time.After(binaryIOProcTermTimeout):
403
+		log.L.Warn("failed to wait for shim logger process to exit, killing")
404
+
405
+		err := b.cmd.Process.Kill()
406
+		if err != nil {
407
+			return errors.Wrap(err, "failed to kill shim logger process")
408
+		}
409
+
410
+		return nil
411
+	}
352 412
 }
353 413
 
354 414
 func (b *binaryIO) Stdin() io.WriteCloser {
... ...
@@ -389,9 +439,15 @@ type pipe struct {
389 389
 }
390 390
 
391 391
 func (p *pipe) Close() error {
392
-	err := p.w.Close()
393
-	if rerr := p.r.Close(); err == nil {
394
-		err = rerr
392
+	var result *multierror.Error
393
+
394
+	if err := p.w.Close(); err != nil {
395
+		result = multierror.Append(result, errors.Wrap(err, "failed to close write pipe"))
396
+	}
397
+
398
+	if err := p.r.Close(); err != nil {
399
+		result = multierror.Append(result, errors.Wrap(err, "failed to close read pipe"))
395 400
 	}
396
-	return err
401
+
402
+	return multierror.Prefix(result.ErrorOrNil(), "pipe:")
397 403
 }
... ...
@@ -44,7 +44,7 @@ var (
44 44
 
45 45
 // IsSkipPlugin returns true if the error is skipping the plugin
46 46
 func IsSkipPlugin(err error) bool {
47
-	return errors.Cause(err) == ErrSkipPlugin
47
+	return errors.Is(err, ErrSkipPlugin)
48 48
 }
49 49
 
50 50
 // Type is the type of the plugin
... ...
@@ -72,7 +72,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima
72 72
 		if err != nil {
73 73
 			return nil, errors.Wrap(err, "create unpacker")
74 74
 		}
75
-		unpackWrapper, unpackEg = u.handlerWrapper(ctx, &unpacks)
75
+		unpackWrapper, unpackEg = u.handlerWrapper(ctx, pullCtx, &unpacks)
76 76
 		defer func() {
77 77
 			if err := unpackEg.Wait(); err != nil {
78 78
 				if retErr == nil {
... ...
@@ -86,7 +86,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
86 86
 
87 87
 	resp, err := req.doWithRetries(ctx, nil)
88 88
 	if err != nil {
89
-		if errors.Cause(err) != ErrInvalidAuthorization {
89
+		if !errors.Is(err, ErrInvalidAuthorization) {
90 90
 			return nil, err
91 91
 		}
92 92
 		log.G(ctx).WithError(err).Debugf("Unable to check existence, continuing with push")
... ...
@@ -283,7 +283,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
283 283
 			log.G(ctx).Debug("resolving")
284 284
 			resp, err := req.doWithRetries(ctx, nil)
285 285
 			if err != nil {
286
-				if errors.Cause(err) == ErrInvalidAuthorization {
286
+				if errors.Is(err, ErrInvalidAuthorization) {
287 287
 					err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization")
288 288
 				}
289 289
 				// Store the error for referencing later
... ...
@@ -129,7 +129,7 @@ func applyLayers(ctx context.Context, layers []Layer, chain []digest.Digest, sn
129 129
 		mounts, err = sn.Prepare(ctx, key, parent.String(), opts...)
130 130
 		if err != nil {
131 131
 			if errdefs.IsNotFound(err) && len(layers) > 1 {
132
-				if err := applyLayers(ctx, layers[:len(layers)-1], chain[:len(chain)-1], sn, a, nil, applyOpts); err != nil {
132
+				if err := applyLayers(ctx, layers[:len(layers)-1], chain[:len(chain)-1], sn, a, opts, applyOpts); err != nil {
133 133
 					if !errdefs.IsAlreadyExists(err) {
134 134
 						return err
135 135
 					}
... ...
@@ -62,7 +62,7 @@ func (p *Process) State(ctx context.Context) (runtime.State, error) {
62 62
 		ID: p.id,
63 63
 	})
64 64
 	if err != nil {
65
-		if errors.Cause(err) != ttrpc.ErrClosed {
65
+		if !errors.Is(err, ttrpc.ErrClosed) {
66 66
 			return runtime.State{}, errdefs.FromGRPC(err)
67 67
 		}
68 68
 
... ...
@@ -159,7 +159,7 @@ func (t *Task) State(ctx context.Context) (runtime.State, error) {
159 159
 		ID: t.id,
160 160
 	})
161 161
 	if err != nil {
162
-		if errors.Cause(err) != ttrpc.ErrClosed {
162
+		if !errors.Is(err, ttrpc.ErrClosed) {
163 163
 			return runtime.State{}, errdefs.FromGRPC(err)
164 164
 		}
165 165
 		return runtime.State{}, errdefs.ErrNotFound
... ...
@@ -503,67 +503,59 @@ func (s *Service) processExits() {
503 503
 	}
504 504
 }
505 505
 
506
-func (s *Service) allProcesses() []process.Process {
507
-	s.mu.Lock()
508
-	defer s.mu.Unlock()
509
-
510
-	res := make([]process.Process, 0, len(s.processes))
511
-	for _, p := range s.processes {
512
-		res = append(res, p)
513
-	}
514
-	return res
515
-}
516
-
517 506
 func (s *Service) checkProcesses(e runc.Exit) {
518
-	for _, p := range s.allProcesses() {
519
-		if p.Pid() != e.Pid {
520
-			continue
507
+	var p process.Process
508
+	s.mu.Lock()
509
+	for _, proc := range s.processes {
510
+		if proc.Pid() == e.Pid {
511
+			p = proc
512
+			break
521 513
 		}
522
-
523
-		if ip, ok := p.(*process.Init); ok {
524
-			shouldKillAll, err := shouldKillAllOnExit(s.bundle)
525
-			if err != nil {
526
-				log.G(s.context).WithError(err).Error("failed to check shouldKillAll")
527
-			}
528
-
529
-			// Ensure all children are killed
530
-			if shouldKillAll {
531
-				if err := ip.KillAll(s.context); err != nil {
532
-					log.G(s.context).WithError(err).WithField("id", ip.ID()).
533
-						Error("failed to kill init's children")
534
-				}
514
+	}
515
+	s.mu.Unlock()
516
+	if p == nil {
517
+		log.G(s.context).Infof("process with id:%d wasn't found", e.Pid)
518
+		return
519
+	}
520
+	if ip, ok := p.(*process.Init); ok {
521
+		// Ensure all children are killed
522
+		if shouldKillAllOnExit(s.context, s.bundle) {
523
+			if err := ip.KillAll(s.context); err != nil {
524
+				log.G(s.context).WithError(err).WithField("id", ip.ID()).
525
+					Error("failed to kill init's children")
535 526
 			}
536 527
 		}
528
+	}
537 529
 
538
-		p.SetExited(e.Status)
539
-		s.events <- &eventstypes.TaskExit{
540
-			ContainerID: s.id,
541
-			ID:          p.ID(),
542
-			Pid:         uint32(e.Pid),
543
-			ExitStatus:  uint32(e.Status),
544
-			ExitedAt:    p.ExitedAt(),
545
-		}
546
-		return
530
+	p.SetExited(e.Status)
531
+	s.events <- &eventstypes.TaskExit{
532
+		ContainerID: s.id,
533
+		ID:          p.ID(),
534
+		Pid:         uint32(e.Pid),
535
+		ExitStatus:  uint32(e.Status),
536
+		ExitedAt:    p.ExitedAt(),
547 537
 	}
548 538
 }
549 539
 
550
-func shouldKillAllOnExit(bundlePath string) (bool, error) {
540
+func shouldKillAllOnExit(ctx context.Context, bundlePath string) bool {
551 541
 	var bundleSpec specs.Spec
552 542
 	bundleConfigContents, err := ioutil.ReadFile(filepath.Join(bundlePath, "config.json"))
553 543
 	if err != nil {
554
-		return false, err
544
+		log.G(ctx).WithError(err).Error("shouldKillAllOnExit: failed to read config.json")
545
+		return true
546
+	}
547
+	if err := json.Unmarshal(bundleConfigContents, &bundleSpec); err != nil {
548
+		log.G(ctx).WithError(err).Error("shouldKillAllOnExit: failed to unmarshal bundle json")
549
+		return true
555 550
 	}
556
-	json.Unmarshal(bundleConfigContents, &bundleSpec)
557
-
558 551
 	if bundleSpec.Linux != nil {
559 552
 		for _, ns := range bundleSpec.Linux.Namespaces {
560 553
 			if ns.Type == specs.PIDNamespace && ns.Path == "" {
561
-				return false, nil
554
+				return false
562 555
 			}
563 556
 		}
564 557
 	}
565
-
566
-	return true, nil
558
+	return true
567 559
 }
568 560
 
569 561
 func (s *Service) getContainerPids(ctx context.Context, id string) ([]uint32, error) {
... ...
@@ -227,9 +227,6 @@ func copy(wg *sync.WaitGroup, r io.Reader, pri journal.Priority, vars map[string
227 227
 	defer wg.Done()
228 228
 	s := bufio.NewScanner(r)
229 229
 	for s.Scan() {
230
-		if s.Err() != nil {
231
-			return
232
-		}
233 230
 		journal.Send(s.Text(), pri, vars)
234 231
 	}
235 232
 }
... ...
@@ -33,11 +33,7 @@ import (
33 33
 func ParseSignal(rawSignal string) (syscall.Signal, error) {
34 34
 	s, err := strconv.Atoi(rawSignal)
35 35
 	if err == nil {
36
-		signal := syscall.Signal(s)
37
-		if unix.SignalName(signal) != "" {
38
-			return signal, nil
39
-		}
40
-		return -1, fmt.Errorf("unknown signal %q", rawSignal)
36
+		return syscall.Signal(s), nil
41 37
 	}
42 38
 	signal := unix.SignalNum(strings.ToUpper(rawSignal))
43 39
 	if signal == 0 {
... ...
@@ -355,10 +355,17 @@ type Cleaner interface {
355 355
 // Opt allows setting mutable snapshot properties on creation
356 356
 type Opt func(info *Info) error
357 357
 
358
-// WithLabels adds labels to a created snapshot
358
+// WithLabels appends labels to a created snapshot
359 359
 func WithLabels(labels map[string]string) Opt {
360 360
 	return func(info *Info) error {
361
-		info.Labels = labels
361
+		if info.Labels == nil {
362
+			info.Labels = make(map[string]string)
363
+		}
364
+
365
+		for k, v := range labels {
366
+			info.Labels[k] = v
367
+		}
368
+
362 369
 		return nil
363 370
 	}
364 371
 }
... ...
@@ -20,17 +20,14 @@ package sys
20 20
 
21 21
 import "golang.org/x/sys/unix"
22 22
 
23
-// EpollCreate1 directly calls unix.EpollCreate1
24
-func EpollCreate1(flag int) (int, error) {
25
-	return unix.EpollCreate1(flag)
26
-}
27
-
28
-// EpollCtl directly calls unix.EpollCtl
29
-func EpollCtl(epfd int, op int, fd int, event *unix.EpollEvent) error {
30
-	return unix.EpollCtl(epfd, op, fd, event)
31
-}
32
-
33
-// EpollWait directly calls unix.EpollWait
34
-func EpollWait(epfd int, events []unix.EpollEvent, msec int) (int, error) {
35
-	return unix.EpollWait(epfd, events, msec)
36
-}
23
+// EpollCreate1 is an alias for unix.EpollCreate1
24
+// Deprecated: use golang.org/x/sys/unix.EpollCreate1
25
+var EpollCreate1 = unix.EpollCreate1
26
+
27
+// EpollCtl is an alias for unix.EpollCtl
28
+// Deprecated: use golang.org/x/sys/unix.EpollCtl
29
+var EpollCtl = unix.EpollCtl
30
+
31
+// EpollWait is an alias for unix.EpollWait
32
+// Deprecated: use golang.org/x/sys/unix.EpollWait
33
+var EpollWait = unix.EpollWait
37 34
new file mode 100644
... ...
@@ -0,0 +1,35 @@
0
+/*
1
+   Copyright The containerd Authors.
2
+
3
+   Licensed under the Apache License, Version 2.0 (the "License");
4
+   you may not use this file except in compliance with the License.
5
+   You may obtain a copy of the License at
6
+
7
+       http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+   Unless required by applicable law or agreed to in writing, software
10
+   distributed under the License is distributed on an "AS IS" BASIS,
11
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+   See the License for the specific language governing permissions and
13
+   limitations under the License.
14
+*/
15
+
16
+package sys
17
+
18
+import "os"
19
+
20
+// IsFifo checks if a file is a (named pipe) fifo
21
+// if the file does not exist then it returns false
22
+func IsFifo(path string) (bool, error) {
23
+	stat, err := os.Stat(path)
24
+	if err != nil {
25
+		if os.IsNotExist(err) {
26
+			return false, nil
27
+		}
28
+		return false, err
29
+	}
30
+	if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
31
+		return true, nil
32
+	}
33
+	return false, nil
34
+}
... ...
@@ -26,8 +26,8 @@ import (
26 26
 	"syscall"
27 27
 	"unsafe"
28 28
 
29
-	winio "github.com/Microsoft/go-winio"
30 29
 	"github.com/Microsoft/hcsshim"
30
+	"golang.org/x/sys/windows"
31 31
 )
32 32
 
33 33
 const (
... ...
@@ -41,7 +41,8 @@ func MkdirAllWithACL(path string, perm os.FileMode) error {
41 41
 	return mkdirall(path, true)
42 42
 }
43 43
 
44
-// MkdirAll implementation that is volume path aware for Windows.
44
+// MkdirAll implementation that is volume path aware for Windows. It can be used
45
+// as a drop-in replacement for os.MkdirAll()
45 46
 func MkdirAll(path string, _ os.FileMode) error {
46 47
 	return mkdirall(path, false)
47 48
 }
... ...
@@ -111,26 +112,26 @@ func mkdirall(path string, adminAndLocalSystem bool) error {
111 111
 // mkdirWithACL creates a new directory. If there is an error, it will be of
112 112
 // type *PathError. .
113 113
 //
114
-// This is a modified and combined version of os.Mkdir and syscall.Mkdir
114
+// This is a modified and combined version of os.Mkdir and windows.Mkdir
115 115
 // in golang to cater for creating a directory am ACL permitting full
116 116
 // access, with inheritance, to any subfolder/file for Built-in Administrators
117 117
 // and Local System.
118 118
 func mkdirWithACL(name string) error {
119
-	sa := syscall.SecurityAttributes{Length: 0}
120
-	sd, err := winio.SddlToSecurityDescriptor(SddlAdministratorsLocalSystem)
119
+	sa := windows.SecurityAttributes{Length: 0}
120
+	sd, err := windows.SecurityDescriptorFromString(SddlAdministratorsLocalSystem)
121 121
 	if err != nil {
122 122
 		return &os.PathError{Op: "mkdir", Path: name, Err: err}
123 123
 	}
124 124
 	sa.Length = uint32(unsafe.Sizeof(sa))
125 125
 	sa.InheritHandle = 1
126
-	sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
126
+	sa.SecurityDescriptor = sd
127 127
 
128
-	namep, err := syscall.UTF16PtrFromString(name)
128
+	namep, err := windows.UTF16PtrFromString(name)
129 129
 	if err != nil {
130 130
 		return &os.PathError{Op: "mkdir", Path: name, Err: err}
131 131
 	}
132 132
 
133
-	e := syscall.CreateDirectory(namep, &sa)
133
+	e := windows.CreateDirectory(namep, &sa)
134 134
 	if e != nil {
135 135
 		return &os.PathError{Op: "mkdir", Path: name, Err: e}
136 136
 	}
... ...
@@ -153,7 +154,7 @@ func IsAbs(path string) bool {
153 153
 	return true
154 154
 }
155 155
 
156
-// The origin of the functions below here are the golang OS and syscall packages,
156
+// The origin of the functions below here are the golang OS and windows packages,
157 157
 // slightly modified to only cope with files, not directories due to the
158 158
 // specific use case.
159 159
 //
... ...
@@ -185,74 +186,74 @@ func OpenFileSequential(name string, flag int, _ os.FileMode) (*os.File, error)
185 185
 	if name == "" {
186 186
 		return nil, &os.PathError{Op: "open", Path: name, Err: syscall.ENOENT}
187 187
 	}
188
-	r, errf := syscallOpenFileSequential(name, flag, 0)
188
+	r, errf := windowsOpenFileSequential(name, flag, 0)
189 189
 	if errf == nil {
190 190
 		return r, nil
191 191
 	}
192 192
 	return nil, &os.PathError{Op: "open", Path: name, Err: errf}
193 193
 }
194 194
 
195
-func syscallOpenFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) {
196
-	r, e := syscallOpenSequential(name, flag|syscall.O_CLOEXEC, 0)
195
+func windowsOpenFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) {
196
+	r, e := windowsOpenSequential(name, flag|windows.O_CLOEXEC, 0)
197 197
 	if e != nil {
198 198
 		return nil, e
199 199
 	}
200 200
 	return os.NewFile(uintptr(r), name), nil
201 201
 }
202 202
 
203
-func makeInheritSa() *syscall.SecurityAttributes {
204
-	var sa syscall.SecurityAttributes
203
+func makeInheritSa() *windows.SecurityAttributes {
204
+	var sa windows.SecurityAttributes
205 205
 	sa.Length = uint32(unsafe.Sizeof(sa))
206 206
 	sa.InheritHandle = 1
207 207
 	return &sa
208 208
 }
209 209
 
210
-func syscallOpenSequential(path string, mode int, _ uint32) (fd syscall.Handle, err error) {
210
+func windowsOpenSequential(path string, mode int, _ uint32) (fd windows.Handle, err error) {
211 211
 	if len(path) == 0 {
212
-		return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND
212
+		return windows.InvalidHandle, windows.ERROR_FILE_NOT_FOUND
213 213
 	}
214
-	pathp, err := syscall.UTF16PtrFromString(path)
214
+	pathp, err := windows.UTF16PtrFromString(path)
215 215
 	if err != nil {
216
-		return syscall.InvalidHandle, err
216
+		return windows.InvalidHandle, err
217 217
 	}
218 218
 	var access uint32
219
-	switch mode & (syscall.O_RDONLY | syscall.O_WRONLY | syscall.O_RDWR) {
220
-	case syscall.O_RDONLY:
221
-		access = syscall.GENERIC_READ
222
-	case syscall.O_WRONLY:
223
-		access = syscall.GENERIC_WRITE
224
-	case syscall.O_RDWR:
225
-		access = syscall.GENERIC_READ | syscall.GENERIC_WRITE
219
+	switch mode & (windows.O_RDONLY | windows.O_WRONLY | windows.O_RDWR) {
220
+	case windows.O_RDONLY:
221
+		access = windows.GENERIC_READ
222
+	case windows.O_WRONLY:
223
+		access = windows.GENERIC_WRITE
224
+	case windows.O_RDWR:
225
+		access = windows.GENERIC_READ | windows.GENERIC_WRITE
226 226
 	}
227
-	if mode&syscall.O_CREAT != 0 {
228
-		access |= syscall.GENERIC_WRITE
227
+	if mode&windows.O_CREAT != 0 {
228
+		access |= windows.GENERIC_WRITE
229 229
 	}
230
-	if mode&syscall.O_APPEND != 0 {
231
-		access &^= syscall.GENERIC_WRITE
232
-		access |= syscall.FILE_APPEND_DATA
230
+	if mode&windows.O_APPEND != 0 {
231
+		access &^= windows.GENERIC_WRITE
232
+		access |= windows.FILE_APPEND_DATA
233 233
 	}
234
-	sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE)
235
-	var sa *syscall.SecurityAttributes
236
-	if mode&syscall.O_CLOEXEC == 0 {
234
+	sharemode := uint32(windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE)
235
+	var sa *windows.SecurityAttributes
236
+	if mode&windows.O_CLOEXEC == 0 {
237 237
 		sa = makeInheritSa()
238 238
 	}
239 239
 	var createmode uint32
240 240
 	switch {
241
-	case mode&(syscall.O_CREAT|syscall.O_EXCL) == (syscall.O_CREAT | syscall.O_EXCL):
242
-		createmode = syscall.CREATE_NEW
243
-	case mode&(syscall.O_CREAT|syscall.O_TRUNC) == (syscall.O_CREAT | syscall.O_TRUNC):
244
-		createmode = syscall.CREATE_ALWAYS
245
-	case mode&syscall.O_CREAT == syscall.O_CREAT:
246
-		createmode = syscall.OPEN_ALWAYS
247
-	case mode&syscall.O_TRUNC == syscall.O_TRUNC:
248
-		createmode = syscall.TRUNCATE_EXISTING
241
+	case mode&(windows.O_CREAT|windows.O_EXCL) == (windows.O_CREAT | windows.O_EXCL):
242
+		createmode = windows.CREATE_NEW
243
+	case mode&(windows.O_CREAT|windows.O_TRUNC) == (windows.O_CREAT | windows.O_TRUNC):
244
+		createmode = windows.CREATE_ALWAYS
245
+	case mode&windows.O_CREAT == windows.O_CREAT:
246
+		createmode = windows.OPEN_ALWAYS
247
+	case mode&windows.O_TRUNC == windows.O_TRUNC:
248
+		createmode = windows.TRUNCATE_EXISTING
249 249
 	default:
250
-		createmode = syscall.OPEN_EXISTING
250
+		createmode = windows.OPEN_EXISTING
251 251
 	}
252 252
 	// Use FILE_FLAG_SEQUENTIAL_SCAN rather than FILE_ATTRIBUTE_NORMAL as implemented in golang.
253
-	//https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
253
+	// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
254 254
 	const fileFlagSequentialScan = 0x08000000 // FILE_FLAG_SEQUENTIAL_SCAN
255
-	h, e := syscall.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0)
255
+	h, e := windows.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0)
256 256
 	return h, e
257 257
 }
258 258
 
... ...
@@ -21,6 +21,7 @@ import (
21 21
 	"syscall"
22 22
 	"unsafe"
23 23
 
24
+	"github.com/containerd/containerd/log"
24 25
 	"github.com/pkg/errors"
25 26
 	"golang.org/x/sys/unix"
26 27
 )
... ...
@@ -30,9 +31,8 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data
30 30
 	var (
31 31
 		sourceP, targetP, fstypeP, dataP *byte
32 32
 		pid                              uintptr
33
-		ws                               unix.WaitStatus
34 33
 		err                              error
35
-		errno                            syscall.Errno
34
+		errno, status                    syscall.Errno
36 35
 	)
37 36
 
38 37
 	sourceP, err = syscall.BytePtrFromString(source)
... ...
@@ -60,37 +60,62 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data
60 60
 	runtime.LockOSThread()
61 61
 	defer runtime.UnlockOSThread()
62 62
 
63
+	var pipefds [2]int
64
+	if err := syscall.Pipe2(pipefds[:], syscall.O_CLOEXEC); err != nil {
65
+		return errors.Wrap(err, "failed to open pipe")
66
+	}
67
+
68
+	defer func() {
69
+		// close both ends of the pipe in a deferred function, since open file
70
+		// descriptor table is shared with child
71
+		syscall.Close(pipefds[0])
72
+		syscall.Close(pipefds[1])
73
+	}()
74
+
63 75
 	pid, errno = forkAndMountat(dirfd,
64 76
 		uintptr(unsafe.Pointer(sourceP)),
65 77
 		uintptr(unsafe.Pointer(targetP)),
66 78
 		uintptr(unsafe.Pointer(fstypeP)),
67 79
 		flags,
68
-		uintptr(unsafe.Pointer(dataP)))
80
+		uintptr(unsafe.Pointer(dataP)),
81
+		pipefds[1],
82
+	)
69 83
 
70 84
 	if errno != 0 {
71 85
 		return errors.Wrap(errno, "failed to fork thread")
72 86
 	}
73 87
 
74
-	_, err = unix.Wait4(int(pid), &ws, 0, nil)
75
-	for err == syscall.EINTR {
76
-		_, err = unix.Wait4(int(pid), &ws, 0, nil)
77
-	}
88
+	defer func() {
89
+		_, err := unix.Wait4(int(pid), nil, 0, nil)
90
+		for err == syscall.EINTR {
91
+			_, err = unix.Wait4(int(pid), nil, 0, nil)
92
+		}
78 93
 
79
-	if err != nil {
80
-		return errors.Wrapf(err, "failed to find pid=%d process", pid)
81
-	}
94
+		if err != nil {
95
+			log.L.WithError(err).Debugf("failed to find pid=%d process", pid)
96
+		}
97
+	}()
82 98
 
83
-	errno = syscall.Errno(ws.ExitStatus())
99
+	_, _, errno = syscall.RawSyscall(syscall.SYS_READ,
100
+		uintptr(pipefds[0]),
101
+		uintptr(unsafe.Pointer(&status)),
102
+		unsafe.Sizeof(status))
84 103
 	if errno != 0 {
85
-		return errors.Wrap(errno, "failed to mount")
104
+		return errors.Wrap(errno, "failed to read pipe")
86 105
 	}
106
+
107
+	if status != 0 {
108
+		return errors.Wrap(status, "failed to mount")
109
+	}
110
+
87 111
 	return nil
88 112
 }
89 113
 
90 114
 // forkAndMountat will fork thread, change working dir and mount.
91 115
 //
92 116
 // precondition: the runtime OS thread must be locked.
93
-func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr) (pid uintptr, errno syscall.Errno) {
117
+func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr, pipefd int) (pid uintptr, errno syscall.Errno) {
118
+
94 119
 	// block signal during clone
95 120
 	beforeFork()
96 121
 
... ...
@@ -114,6 +139,7 @@ func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr)
114 114
 	_, _, errno = syscall.RawSyscall6(syscall.SYS_MOUNT, source, target, fstype, flags, data, 0)
115 115
 
116 116
 childerr:
117
+	_, _, errno = syscall.RawSyscall(syscall.SYS_WRITE, uintptr(pipefd), uintptr(unsafe.Pointer(&errno)), unsafe.Sizeof(errno))
117 118
 	syscall.RawSyscall(syscall.SYS_EXIT, uintptr(errno), 0, 0)
118 119
 	panic("unreachable")
119 120
 }
... ...
@@ -24,8 +24,6 @@ import (
24 24
 	"os"
25 25
 	"strconv"
26 26
 	"strings"
27
-
28
-	"github.com/opencontainers/runc/libcontainer/system"
29 27
 )
30 28
 
31 29
 // OOMScoreMaxKillable is the maximum score keeping the process killable by the oom killer
... ...
@@ -40,7 +38,7 @@ func SetOOMScore(pid, score int) error {
40 40
 	}
41 41
 	defer f.Close()
42 42
 	if _, err = f.WriteString(strconv.Itoa(score)); err != nil {
43
-		if os.IsPermission(err) && (system.RunningInUserNS() || RunningUnprivileged()) {
43
+		if os.IsPermission(err) && (RunningInUserNS() || RunningUnprivileged()) {
44 44
 			return nil
45 45
 		}
46 46
 		return err
47 47
deleted file mode 100644
... ...
@@ -1,80 +0,0 @@
1
-// +build linux
2
-
3
-/*
4
-   Copyright The containerd Authors.
5
-
6
-   Licensed under the Apache License, Version 2.0 (the "License");
7
-   you may not use this file except in compliance with the License.
8
-   You may obtain a copy of the License at
9
-
10
-       http://www.apache.org/licenses/LICENSE-2.0
11
-
12
-   Unless required by applicable law or agreed to in writing, software
13
-   distributed under the License is distributed on an "AS IS" BASIS,
14
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
-   See the License for the specific language governing permissions and
16
-   limitations under the License.
17
-*/
18
-
19
-package sys
20
-
21
-import (
22
-	"bufio"
23
-	"fmt"
24
-	"os"
25
-	"strconv"
26
-	"strings"
27
-
28
-	"github.com/opencontainers/runc/libcontainer/system"
29
-)
30
-
31
-const nanoSecondsPerSecond = 1e9
32
-
33
-var clockTicksPerSecond = uint64(system.GetClockTicks())
34
-
35
-// GetSystemCPUUsage returns the host system's cpu usage in
36
-// nanoseconds. An error is returned if the format of the underlying
37
-// file does not match.
38
-//
39
-// Uses /proc/stat defined by POSIX. Looks for the cpu
40
-// statistics line and then sums up the first seven fields
41
-// provided. See `man 5 proc` for details on specific field
42
-// information.
43
-func GetSystemCPUUsage() (uint64, error) {
44
-	var line string
45
-	f, err := os.Open("/proc/stat")
46
-	if err != nil {
47
-		return 0, err
48
-	}
49
-	bufReader := bufio.NewReaderSize(nil, 128)
50
-	defer func() {
51
-		bufReader.Reset(nil)
52
-		f.Close()
53
-	}()
54
-	bufReader.Reset(f)
55
-	err = nil
56
-	for err == nil {
57
-		line, err = bufReader.ReadString('\n')
58
-		if err != nil {
59
-			break
60
-		}
61
-		parts := strings.Fields(line)
62
-		switch parts[0] {
63
-		case "cpu":
64
-			if len(parts) < 8 {
65
-				return 0, fmt.Errorf("bad format of cpu stats")
66
-			}
67
-			var totalClockTicks uint64
68
-			for _, i := range parts[1:8] {
69
-				v, err := strconv.ParseUint(i, 10, 64)
70
-				if err != nil {
71
-					return 0, fmt.Errorf("error parsing cpu stats")
72
-				}
73
-				totalClockTicks += v
74
-			}
75
-			return (totalClockTicks * nanoSecondsPerSecond) /
76
-				clockTicksPerSecond, nil
77
-		}
78
-	}
79
-	return 0, fmt.Errorf("bad stats format")
80
-}
81 1
deleted file mode 100644
... ...
@@ -1,69 +0,0 @@
1
-// +build !windows
2
-
3
-/*
4
-   Copyright The containerd Authors.
5
-
6
-   Licensed under the Apache License, Version 2.0 (the "License");
7
-   you may not use this file except in compliance with the License.
8
-   You may obtain a copy of the License at
9
-
10
-       http://www.apache.org/licenses/LICENSE-2.0
11
-
12
-   Unless required by applicable law or agreed to in writing, software
13
-   distributed under the License is distributed on an "AS IS" BASIS,
14
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
-   See the License for the specific language governing permissions and
16
-   limitations under the License.
17
-*/
18
-
19
-package sys
20
-
21
-import (
22
-	"golang.org/x/sys/unix"
23
-)
24
-
25
-// Exit is the wait4 information from an exited process
26
-type Exit struct {
27
-	Pid    int
28
-	Status int
29
-}
30
-
31
-// Reap reaps all child processes for the calling process and returns their
32
-// exit information
33
-func Reap(wait bool) (exits []Exit, err error) {
34
-	var (
35
-		ws  unix.WaitStatus
36
-		rus unix.Rusage
37
-	)
38
-	flag := unix.WNOHANG
39
-	if wait {
40
-		flag = 0
41
-	}
42
-	for {
43
-		pid, err := unix.Wait4(-1, &ws, flag, &rus)
44
-		if err != nil {
45
-			if err == unix.ECHILD {
46
-				return exits, nil
47
-			}
48
-			return exits, err
49
-		}
50
-		if pid <= 0 {
51
-			return exits, nil
52
-		}
53
-		exits = append(exits, Exit{
54
-			Pid:    pid,
55
-			Status: exitStatus(ws),
56
-		})
57
-	}
58
-}
59
-
60
-const exitSignalOffset = 128
61
-
62
-// exitStatus returns the correct exit status for a process based on if it
63
-// was signaled or exited cleanly
64
-func exitStatus(status unix.WaitStatus) int {
65
-	if status.Signaled() {
66
-		return exitSignalOffset + int(status.Signal())
67
-	}
68
-	return status.ExitStatus()
69
-}
... ...
@@ -23,9 +23,9 @@ import (
23 23
 	"sync"
24 24
 	"time"
25 25
 
26
-	"github.com/containerd/containerd/sys"
27 26
 	runc "github.com/containerd/go-runc"
28 27
 	"github.com/pkg/errors"
28
+	"golang.org/x/sys/unix"
29 29
 )
30 30
 
31 31
 // ErrNoSuchProcess is returned when the process no longer exists
... ...
@@ -60,7 +60,7 @@ func (s *subscriber) do(fn func()) {
60 60
 // all exited processes and close their wait channels
61 61
 func Reap() error {
62 62
 	now := time.Now()
63
-	exits, err := sys.Reap(false)
63
+	exits, err := reap(false)
64 64
 	for _, e := range exits {
65 65
 		done := Default.notify(runc.Exit{
66 66
 			Timestamp: now,
... ...
@@ -200,3 +200,49 @@ func stop(timer *time.Timer, recv bool) {
200 200
 		<-timer.C
201 201
 	}
202 202
 }
203
+
204
+// exit is the wait4 information from an exited process
205
+type exit struct {
206
+	Pid    int
207
+	Status int
208
+}
209
+
210
+// reap reaps all child processes for the calling process and returns their
211
+// exit information
212
+func reap(wait bool) (exits []exit, err error) {
213
+	var (
214
+		ws  unix.WaitStatus
215
+		rus unix.Rusage
216
+	)
217
+	flag := unix.WNOHANG
218
+	if wait {
219
+		flag = 0
220
+	}
221
+	for {
222
+		pid, err := unix.Wait4(-1, &ws, flag, &rus)
223
+		if err != nil {
224
+			if err == unix.ECHILD {
225
+				return exits, nil
226
+			}
227
+			return exits, err
228
+		}
229
+		if pid <= 0 {
230
+			return exits, nil
231
+		}
232
+		exits = append(exits, exit{
233
+			Pid:    pid,
234
+			Status: exitStatus(ws),
235
+		})
236
+	}
237
+}
238
+
239
+const exitSignalOffset = 128
240
+
241
+// exitStatus returns the correct exit status for a process based on if it
242
+// was signaled or exited cleanly
243
+func exitStatus(status unix.WaitStatus) int {
244
+	if status.Signaled() {
245
+		return exitSignalOffset + int(status.Signal())
246
+	}
247
+	return status.ExitStatus()
248
+}
203 249
new file mode 100644
... ...
@@ -0,0 +1,39 @@
0
+/*
1
+   Copyright The containerd Authors.
2
+
3
+   Licensed under the Apache License, Version 2.0 (the "License");
4
+   you may not use this file except in compliance with the License.
5
+   You may obtain a copy of the License at
6
+
7
+       http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+   Unless required by applicable law or agreed to in writing, software
10
+   distributed under the License is distributed on an "AS IS" BASIS,
11
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+   See the License for the specific language governing permissions and
13
+   limitations under the License.
14
+*/
15
+
16
+package reaper
17
+
18
+import (
19
+	"unsafe"
20
+
21
+	"golang.org/x/sys/unix"
22
+)
23
+
24
+// SetSubreaper sets the value i as the subreaper setting for the calling process
25
+func SetSubreaper(i int) error {
26
+	return unix.Prctl(unix.PR_SET_CHILD_SUBREAPER, uintptr(i), 0, 0, 0)
27
+}
28
+
29
+// GetSubreaper returns the subreaper setting for the calling process
30
+func GetSubreaper() (int, error) {
31
+	var i uintptr
32
+
33
+	if err := unix.Prctl(unix.PR_GET_CHILD_SUBREAPER, uintptr(unsafe.Pointer(&i)), 0, 0, 0); err != nil {
34
+		return -1, err
35
+	}
36
+
37
+	return int(i), nil
38
+}
0 39
deleted file mode 100644
... ...
@@ -1,52 +0,0 @@
1
-/*
2
-   Copyright The containerd Authors.
3
-
4
-   Licensed under the Apache License, Version 2.0 (the "License");
5
-   you may not use this file except in compliance with the License.
6
-   You may obtain a copy of the License at
7
-
8
-       http://www.apache.org/licenses/LICENSE-2.0
9
-
10
-   Unless required by applicable law or agreed to in writing, software
11
-   distributed under the License is distributed on an "AS IS" BASIS,
12
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
-   See the License for the specific language governing permissions and
14
-   limitations under the License.
15
-*/
16
-
17
-package sys
18
-
19
-import (
20
-	"unsafe"
21
-
22
-	"golang.org/x/sys/unix"
23
-)
24
-
25
-// If arg2 is nonzero, set the "child subreaper" attribute of the
26
-// calling process; if arg2 is zero, unset the attribute.  When a
27
-// process is marked as a child subreaper, all of the children
28
-// that it creates, and their descendants, will be marked as
29
-// having a subreaper.  In effect, a subreaper fulfills the role
30
-// of init(1) for its descendant processes.  Upon termination of
31
-// a process that is orphaned (i.e., its immediate parent has
32
-// already terminated) and marked as having a subreaper, the
33
-// nearest still living ancestor subreaper will receive a SIGCHLD
34
-// signal and be able to wait(2) on the process to discover its
35
-// termination status.
36
-const setChildSubreaper = 36
37
-
38
-// SetSubreaper sets the value i as the subreaper setting for the calling process
39
-func SetSubreaper(i int) error {
40
-	return unix.Prctl(setChildSubreaper, uintptr(i), 0, 0, 0)
41
-}
42
-
43
-// GetSubreaper returns the subreaper setting for the calling process
44
-func GetSubreaper() (int, error) {
45
-	var i uintptr
46
-
47
-	if err := unix.Prctl(unix.PR_GET_CHILD_SUBREAPER, uintptr(unsafe.Pointer(&i)), 0, 0, 0); err != nil {
48
-		return -1, err
49
-	}
50
-
51
-	return int(i), nil
52
-}
53 1
new file mode 100644
... ...
@@ -0,0 +1,62 @@
0
+/*
1
+   Copyright The containerd Authors.
2
+
3
+   Licensed under the Apache License, Version 2.0 (the "License");
4
+   you may not use this file except in compliance with the License.
5
+   You may obtain a copy of the License at
6
+
7
+       http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+   Unless required by applicable law or agreed to in writing, software
10
+   distributed under the License is distributed on an "AS IS" BASIS,
11
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+   See the License for the specific language governing permissions and
13
+   limitations under the License.
14
+*/
15
+
16
+package sys
17
+
18
+import (
19
+	"bufio"
20
+	"fmt"
21
+	"os"
22
+	"sync"
23
+)
24
+
25
+var (
26
+	inUserNS bool
27
+	nsOnce   sync.Once
28
+)
29
+
30
+// RunningInUserNS detects whether we are currently running in a user namespace.
31
+// Originally copied from github.com/lxc/lxd/shared/util.go
32
+func RunningInUserNS() bool {
33
+	nsOnce.Do(func() {
34
+		file, err := os.Open("/proc/self/uid_map")
35
+		if err != nil {
36
+			// This kernel-provided file only exists if user namespaces are supported
37
+			return
38
+		}
39
+		defer file.Close()
40
+
41
+		buf := bufio.NewReader(file)
42
+		l, _, err := buf.ReadLine()
43
+		if err != nil {
44
+			return
45
+		}
46
+
47
+		line := string(l)
48
+		var a, b, c int64
49
+		fmt.Sscanf(line, "%d %d %d", &a, &b, &c)
50
+
51
+		/*
52
+		 * We assume we are in the initial user namespace if we have a full
53
+		 * range - 4294967295 uids starting at uid 0.
54
+		 */
55
+		if a == 0 && b == 0 && c == 4294967295 {
56
+			return
57
+		}
58
+		inUserNS = true
59
+	})
60
+	return inUserNS
61
+}
0 62
new file mode 100644
... ...
@@ -0,0 +1,25 @@
0
+// +build !linux
1
+
2
+/*
3
+   Copyright The containerd Authors.
4
+
5
+   Licensed under the Apache License, Version 2.0 (the "License");
6
+   you may not use this file except in compliance with the License.
7
+   You may obtain a copy of the License at
8
+
9
+       http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+   Unless required by applicable law or agreed to in writing, software
12
+   distributed under the License is distributed on an "AS IS" BASIS,
13
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+   See the License for the specific language governing permissions and
15
+   limitations under the License.
16
+*/
17
+
18
+package sys
19
+
20
+// RunningInUserNS is a stub for non-Linux systems
21
+// Always returns false
22
+func RunningInUserNS() bool {
23
+	return false
24
+}
... ...
@@ -72,7 +72,13 @@ func (c *Client) newUnpacker(ctx context.Context, rCtx *RemoteContext) (*unpacke
72 72
 	}, nil
73 73
 }
74 74
 
75
-func (u *unpacker) unpack(ctx context.Context, h images.Handler, config ocispec.Descriptor, layers []ocispec.Descriptor) error {
75
+func (u *unpacker) unpack(
76
+	ctx context.Context,
77
+	rCtx *RemoteContext,
78
+	h images.Handler,
79
+	config ocispec.Descriptor,
80
+	layers []ocispec.Descriptor,
81
+) error {
76 82
 	p, err := content.ReadBlob(ctx, u.c.ContentStore(), config)
77 83
 	if err != nil {
78 84
 		return err
... ...
@@ -123,17 +129,17 @@ EachLayer:
123 123
 			labels = make(map[string]string)
124 124
 		}
125 125
 		labels[labelSnapshotRef] = chainID
126
-		labelOpt := snapshots.WithLabels(labels)
127 126
 
128 127
 		var (
129 128
 			key    string
130 129
 			mounts []mount.Mount
130
+			opts   = append(rCtx.SnapshotterOpts, snapshots.WithLabels(labels))
131 131
 		)
132 132
 
133 133
 		for try := 1; try <= 3; try++ {
134 134
 			// Prepare snapshot with from parent, label as root
135 135
 			key = fmt.Sprintf("extract-%s %s", uniquePart(), chainID)
136
-			mounts, err = sn.Prepare(ctx, key, parent.String(), labelOpt)
136
+			mounts, err = sn.Prepare(ctx, key, parent.String(), opts...)
137 137
 			if err != nil {
138 138
 				if errdefs.IsAlreadyExists(err) {
139 139
 					if _, err := sn.Stat(ctx, chainID); err != nil {
... ...
@@ -201,7 +207,7 @@ EachLayer:
201 201
 			return errors.Errorf("wrong diff id calculated on extraction %q", diffIDs[i])
202 202
 		}
203 203
 
204
-		if err = sn.Commit(ctx, chainID, key, labelOpt); err != nil {
204
+		if err = sn.Commit(ctx, chainID, key, opts...); err != nil {
205 205
 			abort()
206 206
 			if errdefs.IsAlreadyExists(err) {
207 207
 				continue
... ...
@@ -259,7 +265,7 @@ func (u *unpacker) fetch(ctx context.Context, h images.Handler, layers []ocispec
259 259
 			if u.limiter != nil {
260 260
 				u.limiter.Release(1)
261 261
 			}
262
-			if err != nil && errors.Cause(err) != images.ErrSkipDesc {
262
+			if err != nil && !errors.Is(err, images.ErrSkipDesc) {
263 263
 				return err
264 264
 			}
265 265
 			close(done[i])
... ...
@@ -271,7 +277,11 @@ func (u *unpacker) fetch(ctx context.Context, h images.Handler, layers []ocispec
271 271
 	return eg.Wait()
272 272
 }
273 273
 
274
-func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(images.Handler) images.Handler, *errgroup.Group) {
274
+func (u *unpacker) handlerWrapper(
275
+	uctx context.Context,
276
+	rCtx *RemoteContext,
277
+	unpacks *int32,
278
+) (func(images.Handler) images.Handler, *errgroup.Group) {
275 279
 	eg, uctx := errgroup.WithContext(uctx)
276 280
 	return func(f images.Handler) images.Handler {
277 281
 		var (
... ...
@@ -313,7 +323,7 @@ func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(im
313 313
 				if len(l) > 0 {
314 314
 					atomic.AddInt32(unpacks, 1)
315 315
 					eg.Go(func() error {
316
-						return u.unpack(uctx, f, desc, l)
316
+						return u.unpack(uctx, rCtx, f, desc, l)
317 317
 					})
318 318
 				}
319 319
 			}
... ...
@@ -2,16 +2,16 @@ github.com/beorn7/perks                             37c8de3658fcb183f997c4e13e83
2 2
 github.com/BurntSushi/toml                          3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005 # v0.3.1
3 3
 github.com/cespare/xxhash/v2                        d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1
4 4
 github.com/containerd/btrfs                         153935315f4ab9be5bf03650a1341454b05efa5d
5
-github.com/containerd/cgroups                       7347743e5d1e8500d9f27c8e748e689ed991d92b
6
-github.com/containerd/console                       8375c3424e4d7b114e8a90a4a40c8e1b40d1d4e6
5
+github.com/containerd/cgroups                       b4448137398923af7f4918b8b2ad8249172ca7a6
6
+github.com/containerd/console                       8375c3424e4d7b114e8a90a4a40c8e1b40d1d4e6 # v1.0.0
7 7
 github.com/containerd/continuity                    0ec596719c75bfd42908850990acea594b7593ac
8 8
 github.com/containerd/fifo                          bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
9 9
 github.com/containerd/go-runc                       a5c2862aed5e6358b305b0e16bfce58e0549b1cd
10
-github.com/containerd/ttrpc                         92c8520ef9f86600c650dd540266a007bf03670f
11
-github.com/containerd/typeurl                       a93fcdb778cd272c6e9b3028b2f42d813e785d40
10
+github.com/containerd/ttrpc                         72bb1b21c5b0a4a107f59dd85f6ab58e564b68d6 # v1.0.1
11
+github.com/containerd/typeurl                       cd3ce7159eae562a4f60ceff37dada11a939d247 # v1.0.1
12 12
 github.com/coreos/go-systemd/v22                    2d78030078ef61b3cae27f42ad6d0e46db51b339 # v22.0.0
13 13
 github.com/cpuguy83/go-md2man                       7762f7e404f8416dfa1d9bb6a8c192aa9acb4d19 # v1.0.10
14
-github.com/docker/go-events                         9461782956ad83b30282bf90e31fa6a70c255ba9
14
+github.com/docker/go-events                         e31b211e4f1cd09aa76fe4ac244571fab96ae47f
15 15
 github.com/docker/go-metrics                        b619b3592b65de4f087d9f16863a7e6ff905973c # v0.0.1
16 16
 github.com/docker/go-units                          519db1ee28dcc9fd2474ae59fca29a810482bfb1 # v0.4.0
17 17
 github.com/godbus/dbus/v5                           37bf87eef99d69c4f1d3528bd66e3a87dc201472 # v5.0.3
... ...
@@ -25,65 +25,78 @@ github.com/hashicorp/errwrap                        8a6fb523712970c966eefc6b39ed
25 25
 github.com/hashicorp/go-multierror                  886a7fbe3eb1c874d46f623bfa70af45f425b3d1 # v1.0.0
26 26
 github.com/hashicorp/golang-lru                     7f827b33c0f158ec5dfbba01bb0b14a4541fd81d # v0.5.3
27 27
 github.com/imdario/mergo                            7c29201646fa3de8506f701213473dd407f19646 # v0.3.7
28
-github.com/konsorten/go-windows-terminal-sequences  5c8c8bd35d3832f5d134ae1e1e375b69a4d25242 # v1.0.1
28
+github.com/konsorten/go-windows-terminal-sequences  edb144dfd453055e1e49a3d8b410a660b5a87613 # v1.0.3
29 29
 github.com/matttproud/golang_protobuf_extensions    c12348ce28de40eed0136aa2b644d0ee0650e56c # v1.0.1
30 30
 github.com/Microsoft/go-winio                       6c72808b55902eae4c5943626030429ff20f3b63 # v0.4.14
31
-github.com/Microsoft/hcsshim                        0b571ac85d7c5842b26d2571de4868634a4c39d7 # v0.8.7-24-g0b571ac8
31
+github.com/Microsoft/hcsshim                        5bc557dd210ff2caf615e6e22d398123de77fc11 # v0.8.9
32 32
 github.com/opencontainers/go-digest                 c9281466c8b2f606084ac71339773efd177436e7
33 33
 github.com/opencontainers/image-spec                d60099175f88c47cd379c4738d158884749ed235 # v1.0.1
34 34
 github.com/opencontainers/runc                      dc9208a3303feef5b3839f4323d9beb36df0a9dd # v1.0.0-rc10
35
-github.com/opencontainers/runtime-spec              29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
36
-github.com/pkg/errors                               ba968bfe8b2f7e042a574c888954fccecfa385b4 # v0.8.1
35
+github.com/opencontainers/runtime-spec              c4ee7d12c742ffe806cd9350b6af3b4b19faed6f # v1.0.2
36
+github.com/pkg/errors                               614d223910a179a466c1767a985424175c39b465 # v0.9.1
37 37
 github.com/prometheus/client_golang                 c42bebe5a5cddfc6b28cd639103369d8a75dfa89 # v1.3.0
38 38
 github.com/prometheus/client_model                  d1d2010b5beead3fa1c5f271a5cf626e40b3ad6e # v0.1.0
39 39
 github.com/prometheus/common                        287d3e634a1e550c9e463dd7e5a75a422c614505 # v0.7.0
40 40
 github.com/prometheus/procfs                        6d489fc7f1d9cd890a250f3ea3431b1744b9623f # v0.0.8
41 41
 github.com/russross/blackfriday                     05f3235734ad95d0016f6a23902f06461fcf567a # v1.5.2
42
-github.com/sirupsen/logrus                          8bdbc7bcc01dcbb8ec23dc8a28e332258d25251f # v1.4.1
42
+github.com/sirupsen/logrus                          60c74ad9be0d874af0ab0daef6ab07c5c5911f0d # v1.6.0
43 43
 github.com/syndtr/gocapability                      d98352740cb2c55f81556b63d4a1ec64c5a319c2
44 44
 github.com/urfave/cli                               bfe2e925cfb6d44b40ad3a779165ea7e8aff9212 # v1.22.0
45 45
 go.etcd.io/bbolt                                    a0458a2b35708eef59eb5f620ceb3cd1c01a824d # v1.3.3
46 46
 go.opencensus.io                                    9c377598961b706d1542bd2d84d538b5094d596e # v0.22.0
47 47
 golang.org/x/net                                    f3200d17e092c607f615320ecaad13d87ad9a2b3
48 48
 golang.org/x/sync                                   42b317875d0fa942474b76e1b46a6060d720ae6e
49
-golang.org/x/sys                                    c990c680b611ac1aeb7d8f2af94a825f98d69720 https://github.com/golang/sys
49
+golang.org/x/sys                                    5c8b2ff67527cb88b770f693cebf3799036d8bc0
50 50
 golang.org/x/text                                   19e51611da83d6be54ddafce4a4af510cb3e9ea4
51 51
 google.golang.org/genproto                          e50cd9704f63023d62cd06a1994b98227fc4d21a
52 52
 google.golang.org/grpc                              f495f5b15ae7ccda3b38c53a1bfcde4c1a58a2bc # v1.27.1
53
-gotest.tools                                        1083505acf35a0bd8a696b26837e1fb3187a7a83 # v2.3.0
53
+gotest.tools/v3                                     bb0d8a963040ea5048dcef1a14d8f8b58a33d4b3 # v3.0.2
54
+
55
+# cgroups dependencies
56
+github.com/cilium/ebpf                              4032b1d8aae306b7bb94a2a11002932caf88c644
54 57
 
55 58
 # cri dependencies
56
-github.com/containerd/cri                           c0294ebfe0b4342db85c0faf7727ceb8d8c3afce # master
57
-github.com/containerd/go-cni                        0d360c50b10b350b6bb23863fd4dfb1c232b01c9
58
-github.com/containernetworking/cni                  4cfb7b568922a3c79a23e438dc52fe537fc9687e # v0.7.1
59
-github.com/containernetworking/plugins              9f96827c7cabb03f21d86326000c00f61e181f6a # v0.7.6
59
+github.com/containerd/cri                           65830369b6b2b4edc454bf5cebbd9b76c1c1ac66 # master
60 60
 github.com/davecgh/go-spew                          8991bc29aa16c548c550c7ff78260e27b9ab7c73 # v1.1.1
61 61
 github.com/docker/distribution                      0d3efadf0154c2b8a4e7b6621fff9809655cc580
62
-github.com/docker/docker                            d1d5f6476656c6aad457e2a91d3436e66b6f2251
62
+github.com/docker/docker                            4634ce647cf2ce2c6031129ccd109e557244986f
63 63
 github.com/docker/spdystream                        449fdfce4d962303d702fec724ef0ad181c92528
64 64
 github.com/emicklei/go-restful                      b993709ae1a4f6dd19cfa475232614441b11c9d5 # v2.9.5
65
-github.com/google/gofuzz                            f140a6486e521aad38f5917de355cbf147cc0496 # v1.0.0
65
+github.com/google/gofuzz                            db92cf7ae75e4a7a28abc005addab2b394362888 # v1.1.0
66 66
 github.com/json-iterator/go                         03217c3e97663914aec3faafde50d081f197a0a2 # v1.1.8
67 67
 github.com/modern-go/concurrent                     bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94 # 1.0.3
68 68
 github.com/modern-go/reflect2                       4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd # 1.0.1
69
-github.com/opencontainers/selinux                   5215b1806f52b1fcc2070a8826c542c9d33cd3cf
69
+github.com/opencontainers/selinux                   0d49ba2a6aae052c614dfe5de62a158711a6c461 # 1.5.1
70 70
 github.com/seccomp/libseccomp-golang                689e3c1541a84461afc49c1c87352a6cedf72e9c # v0.9.1
71 71
 github.com/stretchr/testify                         221dbe5ed46703ee255b1da0dec05086f5035f62 # v1.4.0
72 72
 github.com/tchap/go-patricia                        666120de432aea38ab06bd5c818f04f4129882c9 # v2.2.6
73
-golang.org/x/crypto                                 1d94cc7ab1c630336ab82ccb9c9cda72a875c382
73
+golang.org/x/crypto                                 bac4c82f69751a6dd76e702d54b3ceb88adab236
74 74
 golang.org/x/oauth2                                 0f29369cfe4552d0e4bcddc57cc75f4d7e672a33
75 75
 golang.org/x/time                                   9d24e82272b4f38b78bc8cff74fa936d31ccd8ef
76 76
 gopkg.in/inf.v0                                     d2d2541c53f18d2a059457998ce2876cc8e67cbf # v0.9.1
77 77
 gopkg.in/yaml.v2                                    53403b58ad1b561927d19068c655246f2db79d48 # v2.2.8
78
-k8s.io/api                                          7643814f1c97f24ccfb38c2b85a7bb3c7f494346 # kubernetes-1.17.1
79
-k8s.io/apimachinery                                 79c2a76c473a20cdc4ce59cae4b72529b5d9d16b # kubernetes-1.17.1
80
-k8s.io/apiserver                                    5381f05fcb881d39af12eeecab5645364229300c # kubernetes-1.17.1
81
-k8s.io/client-go                                    69012f50f4b0243bccdb82c24402a10224a91f51 # kubernetes-1.17.1
82
-k8s.io/cri-api                                      775aa3c1cf7380ba8b7362f5a52f1e6d2e130bb9 # kubernetes-1.17.1
78
+k8s.io/api                                          d2dce8e1788e4be2be3a62b6439b3eaa087df0df # v0.18.0
79
+k8s.io/apimachinery                                 105e0c6d63f10531ed07f3b5a2195771a0fa444b # v0.18.0
80
+k8s.io/apiserver                                    5c8e895629a454efd75a453d1dea5b8142db0013 # v0.18.0
81
+k8s.io/client-go                                    0b19784585bd0a0ee5509855829ead81feaa2bdc # v0.18.0
82
+k8s.io/cri-api                                      3d1680d8d202aa12c5dc5689170c3c03a488d35b # v0.18.0
83 83
 k8s.io/klog                                         2ca9ad30301bf30a8a6e0fa2110db6b8df699a91 # v1.0.0
84
-k8s.io/kubernetes                                   d224476cd0730baca2b6e357d144171ed74192d6 # v1.17.1
85
-k8s.io/utils                                        e782cd3c129fc98ee807f3c889c0f26eb7c9daf5
86
-sigs.k8s.io/yaml                                    fd68e9863619f6ec2fdd8625fe1f02e7c877e480 # v1.1.0
84
+k8s.io/kubernetes                                   9e991415386e4cf155a24b1da15becaa390438d8 # v1.18.0
85
+k8s.io/utils                                        a9aa75ae1b89e1b992c33383f48e942d97e52dae
86
+sigs.k8s.io/structured-merge-diff/v3                877aee05330847a873a1a8998b40e12a1e0fde25 # v3.0.0
87
+sigs.k8s.io/yaml                                    9fc95527decd95bb9d28cc2eab08179b2d0f6971 # v1.2.0
88
+
89
+# cni dependencies
90
+github.com/containerd/go-cni                        0d360c50b10b350b6bb23863fd4dfb1c232b01c9
91
+github.com/containernetworking/cni                  4cfb7b568922a3c79a23e438dc52fe537fc9687e # v0.7.1
92
+github.com/containernetworking/plugins              9f96827c7cabb03f21d86326000c00f61e181f6a # v0.7.6
93
+github.com/fsnotify/fsnotify                        4bf2d1fec78374803a39307bfb8d340688f4f28e # v1.4.8
94
+
95
+# image decrypt depedencies
96
+github.com/containerd/imgcrypt                      9e761ccd6069fb707ec9493435f31475b5524b38 # v1.0.1
97
+github.com/containers/ocicrypt                      0343cc6053fd65069df55bce6838096e09b4033a # v1.0.1 from containerd/imgcrypt
98
+github.com/fullsailor/pkcs7                         8306686428a5fe132eac8cb7c4848af725098bd4 #        from containers/ocicrypt
99
+gopkg.in/square/go-jose.v2                          730df5f748271903322feb182be83b43ebbbe27d # v2.3.1 from containers/ocicrypt
87 100
 
88 101
 # zfs dependencies
89 102
 github.com/containerd/zfs                           9abf673ca6ff9ab8d9bd776a4ceff8f6dc699c3d
... ...
@@ -91,6 +104,3 @@ github.com/mistifyio/go-zfs                         f784269be439d704d3dfa1906f45
91 91
 
92 92
 # aufs dependencies
93 93
 github.com/containerd/aufs                          371312c1e31c210a21e49bf3dfd3f31729ed9f2f
94
-
95
-# cgroups dependencies
96
-github.com/cilium/ebpf                              60c3aa43f488292fe2ee50fb8b833b383ca8ebbb