فهرست منبع

vendor: github.com/containerd/containerd v1.5.2

full diff: https://github.com/containerd/containerd/compare/19ee068f93c91f7b9b2a858457f1af2cabc7bc06...v1.5.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn 4 سال پیش
والد
کامیت
7c1c123555
76فایلهای تغییر یافته به همراه1550 افزوده شده و 738 حذف شده
  1. 2 2
      plugin/backend_linux.go
  2. 1 1
      vendor.conf
  3. 88 0
      vendor/github.com/Microsoft/hcsshim/pkg/ociwclayer/export.go
  4. 148 0
      vendor/github.com/Microsoft/hcsshim/pkg/ociwclayer/import.go
  5. 2 1
      vendor/github.com/containerd/containerd/README.md
  6. 23 2
      vendor/github.com/containerd/containerd/archive/tar.go
  7. 1 1
      vendor/github.com/containerd/containerd/archive/tar_freebsd.go
  8. 10 0
      vendor/github.com/containerd/containerd/archive/tar_opts.go
  9. 43 0
      vendor/github.com/containerd/containerd/archive/tar_opts_windows.go
  10. 2 2
      vendor/github.com/containerd/containerd/archive/tar_unix.go
  11. 0 137
      vendor/github.com/containerd/containerd/archive/tar_windows.go
  12. 1 1
      vendor/github.com/containerd/containerd/cio/io.go
  13. 10 12
      vendor/github.com/containerd/containerd/cio/io_unix.go
  14. 12 24
      vendor/github.com/containerd/containerd/cio/io_windows.go
  15. 19 1
      vendor/github.com/containerd/containerd/client.go
  16. 8 0
      vendor/github.com/containerd/containerd/client_opts.go
  17. 5 5
      vendor/github.com/containerd/containerd/container.go
  18. 1 1
      vendor/github.com/containerd/containerd/content/adaptor.go
  19. 1 1
      vendor/github.com/containerd/containerd/content/content.go
  20. 28 0
      vendor/github.com/containerd/containerd/content/local/readerat.go
  21. 4 16
      vendor/github.com/containerd/containerd/content/local/store.go
  22. 8 1
      vendor/github.com/containerd/containerd/content/proxy/content_writer.go
  23. 2 0
      vendor/github.com/containerd/containerd/defaults/defaults_unix.go
  24. 3 0
      vendor/github.com/containerd/containerd/defaults/defaults_windows.go
  25. 4 0
      vendor/github.com/containerd/containerd/diff/stream.go
  26. 42 37
      vendor/github.com/containerd/containerd/go.mod
  27. 4 3
      vendor/github.com/containerd/containerd/images/diffid.go
  28. 3 0
      vendor/github.com/containerd/containerd/images/mediatypes.go
  29. 88 0
      vendor/github.com/containerd/containerd/metadata/boltutil/helpers.go
  30. 11 58
      vendor/github.com/containerd/containerd/metadata/containers.go
  31. 30 19
      vendor/github.com/containerd/containerd/metadata/namespaces.go
  32. 30 18
      vendor/github.com/containerd/containerd/mount/losetup_linux.go
  33. 4 2
      vendor/github.com/containerd/containerd/mount/mount_linux.go
  34. 31 44
      vendor/github.com/containerd/containerd/oci/spec_opts.go
  35. 42 79
      vendor/github.com/containerd/containerd/oci/spec_opts_linux.go
  36. 38 0
      vendor/github.com/containerd/containerd/oci/spec_opts_nonlinux.go
  37. 10 79
      vendor/github.com/containerd/containerd/oci/spec_opts_unix.go
  38. 1 1
      vendor/github.com/containerd/containerd/oci/spec_opts_windows.go
  39. 137 0
      vendor/github.com/containerd/containerd/oci/utils_unix.go
  40. 6 27
      vendor/github.com/containerd/containerd/pkg/apparmor/apparmor.go
  41. 48 0
      vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_linux.go
  42. 1 2
      vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_unsupported.go
  43. 192 0
      vendor/github.com/containerd/containerd/pkg/cap/cap_linux.go
  44. 6 2
      vendor/github.com/containerd/containerd/pkg/process/init.go
  45. 2 16
      vendor/github.com/containerd/containerd/pkg/process/io.go
  46. 1 1
      vendor/github.com/containerd/containerd/pkg/process/io_util.go
  47. 1 1
      vendor/github.com/containerd/containerd/pkg/process/utils.go
  48. 1 1
      vendor/github.com/containerd/containerd/pkg/userns/userns_linux.go
  49. 1 1
      vendor/github.com/containerd/containerd/pkg/userns/userns_unsupported.go
  50. 53 5
      vendor/github.com/containerd/containerd/platforms/defaults_windows.go
  51. 45 7
      vendor/github.com/containerd/containerd/remotes/docker/pusher.go
  52. 37 4
      vendor/github.com/containerd/containerd/remotes/docker/registry.go
  53. 2 0
      vendor/github.com/containerd/containerd/remotes/docker/resolver.go
  54. 21 1
      vendor/github.com/containerd/containerd/remotes/docker/status.go
  55. 14 4
      vendor/github.com/containerd/containerd/remotes/errors/errors.go
  56. 32 9
      vendor/github.com/containerd/containerd/remotes/handlers.go
  57. 2 0
      vendor/github.com/containerd/containerd/remotes/resolver.go
  58. 2 2
      vendor/github.com/containerd/containerd/rootfs/init.go
  59. 5 5
      vendor/github.com/containerd/containerd/runtime/runtime.go
  60. 17 17
      vendor/github.com/containerd/containerd/runtime/task.go
  61. 1 1
      vendor/github.com/containerd/containerd/runtime/v1/linux/runtime.go
  62. 1 4
      vendor/github.com/containerd/containerd/runtime/v1/shim/client/client.go
  63. 3 0
      vendor/github.com/containerd/containerd/runtime/v1/shim/service.go
  64. 3 3
      vendor/github.com/containerd/containerd/runtime/v1/shim/service_linux.go
  65. 3 4
      vendor/github.com/containerd/containerd/runtime/v1/shim/service_unix.go
  66. 2 0
      vendor/github.com/containerd/containerd/services/introspection/introspection.go
  67. 4 0
      vendor/github.com/containerd/containerd/services/introspection/local.go
  68. 20 7
      vendor/github.com/containerd/containerd/services/server/config/config.go
  69. 2 1
      vendor/github.com/containerd/containerd/snapshots/snapshotter.go
  70. 0 35
      vendor/github.com/containerd/containerd/sys/filesys.go
  71. 66 4
      vendor/github.com/containerd/containerd/sys/filesys_windows.go
  72. 29 7
      vendor/github.com/containerd/containerd/sys/oom_linux.go
  73. 13 1
      vendor/github.com/containerd/containerd/sys/oom_unsupported.go
  74. 4 14
      vendor/github.com/containerd/containerd/sys/userns_deprecated.go
  75. 12 3
      vendor/github.com/containerd/containerd/task.go
  76. 1 1
      vendor/github.com/containerd/containerd/version/version.go

+ 2 - 2
plugin/backend_linux.go

@@ -421,7 +421,7 @@ func (pm *Manager) Push(ctx context.Context, name string, metaHeader http.Header
 
 	// Make sure we can authenticate the request since the auth scope for plugin repos is different than a normal repo.
 	ctx = docker.WithScope(ctx, scope(ref, true))
-	if err := remotes.PushContent(ctx, pusher, desc, pm.blobStore, nil, func(h images.Handler) images.Handler {
+	if err := remotes.PushContent(ctx, pusher, desc, pm.blobStore, nil, nil, func(h images.Handler) images.Handler {
 		return images.Handlers(progressHandler, h)
 	}); err != nil {
 		// Try fallback to http.
@@ -433,7 +433,7 @@ func (pm *Manager) Push(ctx context.Context, name string, metaHeader http.Header
 			pusher, _ := resolver.Pusher(ctx, ref.String())
 			if pusher != nil {
 				logrus.WithField("ref", ref).Debug("Re-attmpting push with http-fallback")
-				err2 := remotes.PushContent(ctx, pusher, desc, pm.blobStore, nil, func(h images.Handler) images.Handler {
+				err2 := remotes.PushContent(ctx, pusher, desc, pm.blobStore, nil, nil, func(h images.Handler) images.Handler {
 					return images.Handlers(progressHandler, h)
 				})
 				if err2 == nil {

+ 1 - 1
vendor.conf

@@ -132,7 +132,7 @@ github.com/googleapis/gax-go                        bd5b16380fd03dc758d11cef74ba
 google.golang.org/genproto                          3f1135a288c9a07e340ae8ba4cc6c7065a3160e8
 
 # containerd
-github.com/containerd/containerd                    19ee068f93c91f7b9b2a858457f1af2cabc7bc06 # master (v1.5.0-dev)
+github.com/containerd/containerd                    36cc874494a56a253cd181a1a685b44b58a2e34a # v1.5.2
 github.com/containerd/fifo                          650e8a8a179d040123db61f016cb133143e7a581 # v1.0.0
 github.com/containerd/continuity                    bce1c3f9669b6f3e7f6656ee715b0b4d75fa64a6 # v0.1.0
 github.com/containerd/cgroups                       b9de8a2212026c07cec67baf3323f1fc0121e048 # v1.0.1

+ 88 - 0
vendor/github.com/Microsoft/hcsshim/pkg/ociwclayer/export.go

@@ -0,0 +1,88 @@
+// Package ociwclayer provides functions for importing and exporting Windows
+// container layers from and to their OCI tar representation.
+package ociwclayer
+
+import (
+	"archive/tar"
+	"context"
+	"io"
+	"path/filepath"
+
+	"github.com/Microsoft/go-winio/backuptar"
+	"github.com/Microsoft/hcsshim"
+)
+
+var driverInfo = hcsshim.DriverInfo{}
+
+// ExportLayerToTar writes an OCI layer tar stream from the provided on-disk layer.
+// The caller must specify the parent layers, if any, ordered from lowest to
+// highest layer.
+//
+// The layer will be mounted for this process, so the caller should ensure that
+// it is not currently mounted.
+func ExportLayerToTar(ctx context.Context, w io.Writer, path string, parentLayerPaths []string) error {
+	err := hcsshim.ActivateLayer(driverInfo, path)
+	if err != nil {
+		return err
+	}
+	defer func() {
+		_ = hcsshim.DeactivateLayer(driverInfo, path)
+	}()
+
+	// Prepare and unprepare the layer to ensure that it has been initialized.
+	err = hcsshim.PrepareLayer(driverInfo, path, parentLayerPaths)
+	if err != nil {
+		return err
+	}
+	err = hcsshim.UnprepareLayer(driverInfo, path)
+	if err != nil {
+		return err
+	}
+
+	r, err := hcsshim.NewLayerReader(driverInfo, path, parentLayerPaths)
+	if err != nil {
+		return err
+	}
+
+	err = writeTarFromLayer(ctx, r, w)
+	cerr := r.Close()
+	if err != nil {
+		return err
+	}
+	return cerr
+}
+
+func writeTarFromLayer(ctx context.Context, r hcsshim.LayerReader, w io.Writer) error {
+	t := tar.NewWriter(w)
+	for {
+		select {
+		case <-ctx.Done():
+			return ctx.Err()
+		default:
+		}
+
+		name, size, fileInfo, err := r.Next()
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			return err
+		}
+		if fileInfo == nil {
+			// Write a whiteout file.
+			hdr := &tar.Header{
+				Name: filepath.ToSlash(filepath.Join(filepath.Dir(name), whiteoutPrefix+filepath.Base(name))),
+			}
+			err := t.WriteHeader(hdr)
+			if err != nil {
+				return err
+			}
+		} else {
+			err = backuptar.WriteTarFileFromBackupStream(t, r, name, size, fileInfo)
+			if err != nil {
+				return err
+			}
+		}
+	}
+	return t.Close()
+}

+ 148 - 0
vendor/github.com/Microsoft/hcsshim/pkg/ociwclayer/import.go

@@ -0,0 +1,148 @@
+package ociwclayer
+
+import (
+	"archive/tar"
+	"bufio"
+	"context"
+	"io"
+	"os"
+	"path"
+	"path/filepath"
+	"strings"
+
+	winio "github.com/Microsoft/go-winio"
+	"github.com/Microsoft/go-winio/backuptar"
+	"github.com/Microsoft/hcsshim"
+)
+
+const whiteoutPrefix = ".wh."
+
+var (
+	// mutatedFiles is a list of files that are mutated by the import process
+	// and must be backed up and restored.
+	mutatedFiles = map[string]string{
+		"UtilityVM/Files/EFI/Microsoft/Boot/BCD":      "bcd.bak",
+		"UtilityVM/Files/EFI/Microsoft/Boot/BCD.LOG":  "bcd.log.bak",
+		"UtilityVM/Files/EFI/Microsoft/Boot/BCD.LOG1": "bcd.log1.bak",
+		"UtilityVM/Files/EFI/Microsoft/Boot/BCD.LOG2": "bcd.log2.bak",
+	}
+)
+
+// ImportLayerFromTar  reads a layer from an OCI layer tar stream and extracts it to the
+// specified path. The caller must specify the parent layers, if any, ordered
+// from lowest to highest layer.
+//
+// The caller must ensure that the thread or process has acquired backup and
+// restore privileges.
+//
+// This function returns the total size of the layer's files, in bytes.
+func ImportLayerFromTar(ctx context.Context, r io.Reader, path string, parentLayerPaths []string) (int64, error) {
+	err := os.MkdirAll(path, 0)
+	if err != nil {
+		return 0, err
+	}
+	w, err := hcsshim.NewLayerWriter(hcsshim.DriverInfo{}, path, parentLayerPaths)
+	if err != nil {
+		return 0, err
+	}
+	n, err := writeLayerFromTar(ctx, r, w, path)
+	cerr := w.Close()
+	if err != nil {
+		return 0, err
+	}
+	if cerr != nil {
+		return 0, cerr
+	}
+	return n, nil
+}
+
+func writeLayerFromTar(ctx context.Context, r io.Reader, w hcsshim.LayerWriter, root string) (int64, error) {
+	t := tar.NewReader(r)
+	hdr, err := t.Next()
+	totalSize := int64(0)
+	buf := bufio.NewWriter(nil)
+	for err == nil {
+		select {
+		case <-ctx.Done():
+			return 0, ctx.Err()
+		default:
+		}
+
+		base := path.Base(hdr.Name)
+		if strings.HasPrefix(base, whiteoutPrefix) {
+			name := path.Join(path.Dir(hdr.Name), base[len(whiteoutPrefix):])
+			err = w.Remove(filepath.FromSlash(name))
+			if err != nil {
+				return 0, err
+			}
+			hdr, err = t.Next()
+		} else if hdr.Typeflag == tar.TypeLink {
+			err = w.AddLink(filepath.FromSlash(hdr.Name), filepath.FromSlash(hdr.Linkname))
+			if err != nil {
+				return 0, err
+			}
+			hdr, err = t.Next()
+		} else {
+			var (
+				name     string
+				size     int64
+				fileInfo *winio.FileBasicInfo
+			)
+			name, size, fileInfo, err = backuptar.FileInfoFromHeader(hdr)
+			if err != nil {
+				return 0, err
+			}
+			err = w.Add(filepath.FromSlash(name), fileInfo)
+			if err != nil {
+				return 0, err
+			}
+			hdr, err = writeBackupStreamFromTarAndSaveMutatedFiles(buf, w, t, hdr, root)
+			totalSize += size
+		}
+	}
+	if err != io.EOF {
+		return 0, err
+	}
+	return totalSize, nil
+}
+
+// writeBackupStreamFromTarAndSaveMutatedFiles reads data from a tar stream and
+// writes it to a backup stream, and also saves any files that will be mutated
+// by the import layer process to a backup location.
+func writeBackupStreamFromTarAndSaveMutatedFiles(buf *bufio.Writer, w io.Writer, t *tar.Reader, hdr *tar.Header, root string) (nextHdr *tar.Header, err error) {
+	var bcdBackup *os.File
+	var bcdBackupWriter *winio.BackupFileWriter
+	if backupPath, ok := mutatedFiles[hdr.Name]; ok {
+		bcdBackup, err = os.Create(filepath.Join(root, backupPath))
+		if err != nil {
+			return nil, err
+		}
+		defer func() {
+			cerr := bcdBackup.Close()
+			if err == nil {
+				err = cerr
+			}
+		}()
+
+		bcdBackupWriter = winio.NewBackupFileWriter(bcdBackup, false)
+		defer func() {
+			cerr := bcdBackupWriter.Close()
+			if err == nil {
+				err = cerr
+			}
+		}()
+
+		buf.Reset(io.MultiWriter(w, bcdBackupWriter))
+	} else {
+		buf.Reset(w)
+	}
+
+	defer func() {
+		ferr := buf.Flush()
+		if err == nil {
+			err = ferr
+		}
+	}()
+
+	return backuptar.WriteBackupStreamFromTarFile(buf, t, hdr)
+}

+ 2 - 1
vendor/github.com/containerd/containerd/README.md

@@ -49,7 +49,8 @@ Please be aware: nightly builds might have critical bugs, it's not recommended f
 
 Runtime requirements for containerd are very minimal. Most interactions with
 the Linux and Windows container feature sets are handled via [runc](https://github.com/opencontainers/runc) and/or
-OS-specific libraries (e.g. [hcsshim](https://github.com/Microsoft/hcsshim) for Microsoft). The current required version of `runc` is always listed in [RUNC.md](/docs/RUNC.md).
+OS-specific libraries (e.g. [hcsshim](https://github.com/Microsoft/hcsshim) for Microsoft).
+The current required version of `runc` is described in [RUNC.md](docs/RUNC.md).
 
 There are specific features
 used by containerd core code and snapshotters that will require a minimum kernel

+ 23 - 2
vendor/github.com/containerd/containerd/archive/tar.go

@@ -63,13 +63,34 @@ func Diff(ctx context.Context, a, b string) io.ReadCloser {
 }
 
 // WriteDiff writes a tar stream of the computed difference between the
-// provided directories.
+// provided paths.
 //
 // Produces a tar using OCI style file markers for deletions. Deleted
 // files will be prepended with the prefix ".wh.". This style is
 // based off AUFS whiteouts.
 // See https://github.com/opencontainers/image-spec/blob/master/layer.md
-func WriteDiff(ctx context.Context, w io.Writer, a, b string) error {
+func WriteDiff(ctx context.Context, w io.Writer, a, b string, opts ...WriteDiffOpt) error {
+	var options WriteDiffOptions
+	for _, opt := range opts {
+		if err := opt(&options); err != nil {
+			return errors.Wrap(err, "failed to apply option")
+		}
+	}
+	if options.writeDiffFunc == nil {
+		options.writeDiffFunc = writeDiffNaive
+	}
+
+	return options.writeDiffFunc(ctx, w, a, b, options)
+}
+
+// writeDiffNaive writes a tar stream of the computed difference between the
+// provided directories on disk.
+//
+// Produces a tar using OCI style file markers for deletions. Deleted
+// files will be prepended with the prefix ".wh.". This style is
+// based off AUFS whiteouts.
+// See https://github.com/opencontainers/image-spec/blob/master/layer.md
+func writeDiffNaive(ctx context.Context, w io.Writer, a, b string, _ WriteDiffOptions) error {
 	cw := newChangeWriter(w, b)
 	err := fs.Changes(ctx, a, b, cw.HandleChange)
 	if err != nil {

+ 1 - 1
vendor/github.com/containerd/containerd/archive/tar_freebsd.go

@@ -29,7 +29,7 @@ func mknod(path string, mode uint32, dev uint64) error {
 // lsetxattrCreate wraps unix.Lsetxattr with FreeBSD-specific flags and errors
 func lsetxattrCreate(link string, attr string, data []byte) error {
 	err := unix.Lsetxattr(link, attr, data, 0)
-	if err == unix.ENOTSUP|| err == unix.EEXIST {
+	if err == unix.ENOTSUP || err == unix.EEXIST {
 		return nil
 	}
 	return err

+ 10 - 0
vendor/github.com/containerd/containerd/archive/tar_opts.go

@@ -73,3 +73,13 @@ func WithParents(p []string) ApplyOpt {
 		return nil
 	}
 }
+
+// WriteDiffOptions provides additional options for a WriteDiff operation
+type WriteDiffOptions struct {
+	ParentLayers []string // Windows needs the full list of parent layers
+
+	writeDiffFunc func(context.Context, io.Writer, string, string, WriteDiffOptions) error
+}
+
+// WriteDiffOpt allows setting mutable archive write properties on creation
+type WriteDiffOpt func(options *WriteDiffOptions) error

+ 43 - 0
vendor/github.com/containerd/containerd/archive/tar_opts_windows.go

@@ -18,6 +18,19 @@
 
 package archive
 
+import (
+	"context"
+	"io"
+
+	"github.com/Microsoft/hcsshim/pkg/ociwclayer"
+)
+
+// applyWindowsLayer applies a tar stream of an OCI style diff tar of a Windows layer
+// See https://github.com/opencontainers/image-spec/blob/master/layer.md#applying-changesets
+func applyWindowsLayer(ctx context.Context, root string, r io.Reader, options ApplyOptions) (size int64, err error) {
+	return ociwclayer.ImportLayerFromTar(ctx, r, root, options.Parents)
+}
+
 // AsWindowsContainerLayer indicates that the tar stream to apply is that of
 // a Windows Container Layer. The caller must be holding SeBackupPrivilege and
 // SeRestorePrivilege.
@@ -27,3 +40,33 @@ func AsWindowsContainerLayer() ApplyOpt {
 		return nil
 	}
 }
+
+// writeDiffWindowsLayers writes a tar stream of the computed difference between the
+// provided Windows layers
+//
+// Produces a tar using OCI style file markers for deletions. Deleted
+// files will be prepended with the prefix ".wh.". This style is
+// based off AUFS whiteouts.
+// See https://github.com/opencontainers/image-spec/blob/master/layer.md
+func writeDiffWindowsLayers(ctx context.Context, w io.Writer, _, layer string, options WriteDiffOptions) error {
+	return ociwclayer.ExportLayerToTar(ctx, w, layer, options.ParentLayers)
+}
+
+// AsWindowsContainerLayerPair indicates that the paths to diff are a pair of
+// Windows Container Layers. The caller must be holding SeBackupPrivilege.
+func AsWindowsContainerLayerPair() WriteDiffOpt {
+	return func(options *WriteDiffOptions) error {
+		options.writeDiffFunc = writeDiffWindowsLayers
+		return nil
+	}
+}
+
+// WithParentLayers provides the Windows Container Layers that are the parents
+// of the target (right-hand, "upper") layer, if any. The source (left-hand, "lower")
+// layer passed to WriteDiff should be "" in this case.
+func WithParentLayers(p []string) WriteDiffOpt {
+	return func(options *WriteDiffOptions) error {
+		options.ParentLayers = p
+		return nil
+	}
+}

+ 2 - 2
vendor/github.com/containerd/containerd/archive/tar_unix.go

@@ -24,7 +24,7 @@ import (
 	"strings"
 	"syscall"
 
-	"github.com/containerd/containerd/sys"
+	"github.com/containerd/containerd/pkg/userns"
 	"github.com/containerd/continuity/fs"
 	"github.com/containerd/continuity/sysx"
 	"github.com/pkg/errors"
@@ -87,7 +87,7 @@ func skipFile(hdr *tar.Header) bool {
 	switch hdr.Typeflag {
 	case tar.TypeBlock, tar.TypeChar:
 		// cannot create a device if running in user namespace
-		return sys.RunningInUserNS()
+		return userns.RunningInUserNS()
 	default:
 		return false
 	}

+ 0 - 137
vendor/github.com/containerd/containerd/archive/tar_windows.go

@@ -20,33 +20,14 @@ package archive
 
 import (
 	"archive/tar"
-	"bufio"
-	"context"
 	"fmt"
-	"io"
 	"os"
-	"path"
-	"path/filepath"
 	"strings"
 
-	"github.com/Microsoft/go-winio"
-	"github.com/Microsoft/go-winio/backuptar"
-	"github.com/Microsoft/hcsshim"
 	"github.com/containerd/containerd/sys"
 	"github.com/pkg/errors"
 )
 
-var (
-	// mutatedFiles is a list of files that are mutated by the import process
-	// and must be backed up and restored.
-	mutatedFiles = map[string]string{
-		"UtilityVM/Files/EFI/Microsoft/Boot/BCD":      "bcd.bak",
-		"UtilityVM/Files/EFI/Microsoft/Boot/BCD.LOG":  "bcd.log.bak",
-		"UtilityVM/Files/EFI/Microsoft/Boot/BCD.LOG1": "bcd.log1.bak",
-		"UtilityVM/Files/EFI/Microsoft/Boot/BCD.LOG2": "bcd.log2.bak",
-	}
-)
-
 // tarName returns platform-specific filepath
 // to canonical posix-style path for tar archival. p is relative
 // path.
@@ -141,121 +122,3 @@ func copyDirInfo(fi os.FileInfo, path string) error {
 func copyUpXAttrs(dst, src string) error {
 	return nil
 }
-
-// applyWindowsLayer applies a tar stream of an OCI style diff tar of a Windows
-// layer using the hcsshim layer writer and backup streams.
-// See https://github.com/opencontainers/image-spec/blob/master/layer.md#applying-changesets
-func applyWindowsLayer(ctx context.Context, root string, r io.Reader, options ApplyOptions) (size int64, err error) {
-	home, id := filepath.Split(root)
-	info := hcsshim.DriverInfo{
-		HomeDir: home,
-	}
-
-	w, err := hcsshim.NewLayerWriter(info, id, options.Parents)
-	if err != nil {
-		return 0, err
-	}
-	defer func() {
-		if err2 := w.Close(); err2 != nil {
-			// This error should not be discarded as a failure here
-			// could result in an invalid layer on disk
-			if err == nil {
-				err = err2
-			}
-		}
-	}()
-
-	tr := tar.NewReader(r)
-	buf := bufio.NewWriter(nil)
-	hdr, nextErr := tr.Next()
-	// Iterate through the files in the archive.
-	for {
-		select {
-		case <-ctx.Done():
-			return 0, ctx.Err()
-		default:
-		}
-
-		if nextErr == io.EOF {
-			// end of tar archive
-			break
-		}
-		if nextErr != nil {
-			return 0, nextErr
-		}
-
-		// Note: path is used instead of filepath to prevent OS specific handling
-		// of the tar path
-		base := path.Base(hdr.Name)
-		if strings.HasPrefix(base, whiteoutPrefix) {
-			dir := path.Dir(hdr.Name)
-			originalBase := base[len(whiteoutPrefix):]
-			originalPath := path.Join(dir, originalBase)
-			if err := w.Remove(filepath.FromSlash(originalPath)); err != nil {
-				return 0, err
-			}
-			hdr, nextErr = tr.Next()
-		} else if hdr.Typeflag == tar.TypeLink {
-			err := w.AddLink(filepath.FromSlash(hdr.Name), filepath.FromSlash(hdr.Linkname))
-			if err != nil {
-				return 0, err
-			}
-			hdr, nextErr = tr.Next()
-		} else {
-			name, fileSize, fileInfo, err := backuptar.FileInfoFromHeader(hdr)
-			if err != nil {
-				return 0, err
-			}
-			if err := w.Add(filepath.FromSlash(name), fileInfo); err != nil {
-				return 0, err
-			}
-			size += fileSize
-			hdr, nextErr = tarToBackupStreamWithMutatedFiles(buf, w, tr, hdr, root)
-		}
-	}
-
-	return
-}
-
-// tarToBackupStreamWithMutatedFiles reads data from a tar stream and
-// writes it to a backup stream, and also saves any files that will be mutated
-// by the import layer process to a backup location.
-func tarToBackupStreamWithMutatedFiles(buf *bufio.Writer, w io.Writer, t *tar.Reader, hdr *tar.Header, root string) (nextHdr *tar.Header, err error) {
-	var (
-		bcdBackup       *os.File
-		bcdBackupWriter *winio.BackupFileWriter
-	)
-	if backupPath, ok := mutatedFiles[hdr.Name]; ok {
-		bcdBackup, err = os.Create(filepath.Join(root, backupPath))
-		if err != nil {
-			return nil, err
-		}
-		defer func() {
-			cerr := bcdBackup.Close()
-			if err == nil {
-				err = cerr
-			}
-		}()
-
-		bcdBackupWriter = winio.NewBackupFileWriter(bcdBackup, false)
-		defer func() {
-			cerr := bcdBackupWriter.Close()
-			if err == nil {
-				err = cerr
-			}
-		}()
-
-		buf.Reset(io.MultiWriter(w, bcdBackupWriter))
-	} else {
-		buf.Reset(w)
-	}
-
-	defer func() {
-		ferr := buf.Flush()
-		if err == nil {
-			err = ferr
-		}
-	}()
-
-	return backuptar.WriteBackupStreamFromTarFile(buf, t, hdr)
-}

+ 1 - 1
vendor/github.com/containerd/containerd/cio/io.go

@@ -80,7 +80,7 @@ type FIFOSet struct {
 
 // Close the FIFOSet
 func (f *FIFOSet) Close() error {
-	if f.close != nil {
+	if f != nil && f.close != nil {
 		return f.close()
 	}
 	return nil

+ 10 - 12
vendor/github.com/containerd/containerd/cio/io_unix.go

@@ -103,38 +103,36 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) {
 	}, nil
 }
 
-func openFifos(ctx context.Context, fifos *FIFOSet) (pipes, error) {
-	var err error
+func openFifos(ctx context.Context, fifos *FIFOSet) (f pipes, retErr error) {
 	defer func() {
-		if err != nil {
+		if retErr != nil {
 			fifos.Close()
 		}
 	}()
 
-	var f pipes
 	if fifos.Stdin != "" {
-		if f.Stdin, err = fifo.OpenFifo(ctx, fifos.Stdin, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil {
-			return f, errors.Wrapf(err, "failed to open stdin fifo")
+		if f.Stdin, retErr = fifo.OpenFifo(ctx, fifos.Stdin, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); retErr != nil {
+			return f, errors.Wrapf(retErr, "failed to open stdin fifo")
 		}
 		defer func() {
-			if err != nil && f.Stdin != nil {
+			if retErr != nil && f.Stdin != nil {
 				f.Stdin.Close()
 			}
 		}()
 	}
 	if fifos.Stdout != "" {
-		if f.Stdout, err = fifo.OpenFifo(ctx, fifos.Stdout, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil {
-			return f, errors.Wrapf(err, "failed to open stdout fifo")
+		if f.Stdout, retErr = fifo.OpenFifo(ctx, fifos.Stdout, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); retErr != nil {
+			return f, errors.Wrapf(retErr, "failed to open stdout fifo")
 		}
 		defer func() {
-			if err != nil && f.Stdout != nil {
+			if retErr != nil && f.Stdout != nil {
 				f.Stdout.Close()
 			}
 		}()
 	}
 	if !fifos.Terminal && fifos.Stderr != "" {
-		if f.Stderr, err = fifo.OpenFifo(ctx, fifos.Stderr, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil {
-			return f, errors.Wrapf(err, "failed to open stderr fifo")
+		if f.Stderr, retErr = fifo.OpenFifo(ctx, fifos.Stderr, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); retErr != nil {
+			return f, errors.Wrapf(retErr, "failed to open stderr fifo")
 		}
 	}
 	return f, nil

+ 12 - 24
vendor/github.com/containerd/containerd/cio/io_windows.go

@@ -20,7 +20,6 @@ import (
 	"context"
 	"fmt"
 	"io"
-	"net"
 
 	winio "github.com/Microsoft/go-winio"
 	"github.com/containerd/containerd/log"
@@ -43,22 +42,21 @@ func NewFIFOSetInDir(_, id string, terminal bool) (*FIFOSet, error) {
 	}, nil), nil
 }
 
-func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) {
-	var (
-		set []io.Closer
-	)
+func copyIO(fifos *FIFOSet, ioset *Streams) (_ *cio, retErr error) {
+	cios := &cio{config: fifos.Config}
+
+	defer func() {
+		if retErr != nil {
+			_ = cios.Close()
+		}
+	}()
 
 	if fifos.Stdin != "" {
 		l, err := winio.ListenPipe(fifos.Stdin, nil)
 		if err != nil {
 			return nil, errors.Wrapf(err, "failed to create stdin pipe %s", fifos.Stdin)
 		}
-		defer func(l net.Listener) {
-			if err != nil {
-				l.Close()
-			}
-		}(l)
-		set = append(set, l)
+		cios.closers = append(cios.closers, l)
 
 		go func() {
 			c, err := l.Accept()
@@ -81,12 +79,7 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) {
 		if err != nil {
 			return nil, errors.Wrapf(err, "failed to create stdout pipe %s", fifos.Stdout)
 		}
-		defer func(l net.Listener) {
-			if err != nil {
-				l.Close()
-			}
-		}(l)
-		set = append(set, l)
+		cios.closers = append(cios.closers, l)
 
 		go func() {
 			c, err := l.Accept()
@@ -109,12 +102,7 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) {
 		if err != nil {
 			return nil, errors.Wrapf(err, "failed to create stderr pipe %s", fifos.Stderr)
 		}
-		defer func(l net.Listener) {
-			if err != nil {
-				l.Close()
-			}
-		}(l)
-		set = append(set, l)
+		cios.closers = append(cios.closers, l)
 
 		go func() {
 			c, err := l.Accept()
@@ -132,7 +120,7 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) {
 		}()
 	}
 
-	return &cio{config: fifos.Config, closers: set}, nil
+	return cios, nil
 }
 
 // NewDirectIO returns an IO implementation that exposes the IO streams as io.ReadCloser

+ 19 - 1
vendor/github.com/containerd/containerd/client.go

@@ -63,6 +63,7 @@ import (
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
 	"github.com/pkg/errors"
+	"golang.org/x/sync/semaphore"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/backoff"
 	"google.golang.org/grpc/health/grpc_health_v1"
@@ -226,6 +227,11 @@ func (c *Client) Reconnect() error {
 	return nil
 }
 
+// Runtime returns the name of the runtime being used
+func (c *Client) Runtime() string {
+	return c.runtime
+}
+
 // IsServing returns true if the client can successfully connect to the
 // containerd daemon and the healthcheck service returns the SERVING
 // response.
@@ -350,6 +356,9 @@ type RemoteContext struct {
 	// MaxConcurrentDownloads is the max concurrent content downloads for each pull.
 	MaxConcurrentDownloads int
 
+	// MaxConcurrentUploadedLayers is the max concurrent uploaded layers for each push.
+	MaxConcurrentUploadedLayers int
+
 	// AllMetadata downloads all manifests and known-configuration files
 	AllMetadata bool
 
@@ -458,7 +467,12 @@ func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor,
 		wrapper = pushCtx.HandlerWrapper
 	}
 
-	return remotes.PushContent(ctx, pusher, desc, c.ContentStore(), pushCtx.PlatformMatcher, wrapper)
+	var limiter *semaphore.Weighted
+	if pushCtx.MaxConcurrentUploadedLayers > 0 {
+		limiter = semaphore.NewWeighted(int64(pushCtx.MaxConcurrentUploadedLayers))
+	}
+
+	return remotes.PushContent(ctx, pusher, desc, c.ContentStore(), limiter, pushCtx.PlatformMatcher, wrapper)
 }
 
 // GetImage returns an existing image
@@ -715,10 +729,12 @@ func (c *Client) Version(ctx context.Context) (Version, error) {
 	}, nil
 }
 
+// ServerInfo represents the introspected server information
 type ServerInfo struct {
 	UUID string
 }
 
+// Server returns server information from the introspection service
 func (c *Client) Server(ctx context.Context) (ServerInfo, error) {
 	c.connMu.Lock()
 	if c.conn == nil {
@@ -784,6 +800,8 @@ func CheckRuntime(current, expected string) bool {
 	return true
 }
 
+// GetSnapshotterSupportedPlatforms returns a platform matchers which represents the
+// supported platforms for the given snapshotters
 func (c *Client) GetSnapshotterSupportedPlatforms(ctx context.Context, snapshotterName string) (platforms.MatchComparer, error) {
 	filters := []string{fmt.Sprintf("type==%s, id==%s", plugin.SnapshotPlugin, snapshotterName)}
 	in := c.IntrospectionService()

+ 8 - 0
vendor/github.com/containerd/containerd/client_opts.go

@@ -228,6 +228,14 @@ func WithMaxConcurrentDownloads(max int) RemoteOpt {
 	}
 }
 
+// WithMaxConcurrentUploadedLayers sets max concurrent uploaded layer limit.
+func WithMaxConcurrentUploadedLayers(max int) RemoteOpt {
+	return func(client *Client, c *RemoteContext) error {
+		c.MaxConcurrentUploadedLayers = max
+		return nil
+	}
+}
+
 // WithAllMetadata downloads all manifests and known-configuration files
 func WithAllMetadata() RemoteOpt {
 	return func(_ *Client, c *RemoteContext) error {

+ 5 - 5
vendor/github.com/containerd/containerd/container.go

@@ -32,7 +32,7 @@ import (
 	"github.com/containerd/containerd/images"
 	"github.com/containerd/containerd/oci"
 	"github.com/containerd/containerd/runtime/v2/runc/options"
-	"github.com/containerd/containerd/sys"
+	"github.com/containerd/fifo"
 	"github.com/containerd/typeurl"
 	prototypes "github.com/gogo/protobuf/types"
 	ver "github.com/opencontainers/image-spec/specs-go"
@@ -435,12 +435,12 @@ func loadFifos(response *tasks.GetResponse) *cio.FIFOSet {
 			err  error
 			dirs = map[string]struct{}{}
 		)
-		for _, fifo := range fifos {
-			if isFifo, _ := sys.IsFifo(fifo); isFifo {
-				if rerr := os.Remove(fifo); err == nil {
+		for _, f := range fifos {
+			if isFifo, _ := fifo.IsFifo(f); isFifo {
+				if rerr := os.Remove(f); err == nil {
 					err = rerr
 				}
-				dirs[filepath.Dir(fifo)] = struct{}{}
+				dirs[filepath.Dir(f)] = struct{}{}
 			}
 		}
 		for dir := range dirs {

+ 1 - 1
vendor/github.com/containerd/containerd/content/adaptor.go

@@ -22,7 +22,7 @@ import (
 	"github.com/containerd/containerd/filters"
 )
 
-// AdoptInfo returns `filters.Adaptor` that handles `content.Info`.
+// AdaptInfo returns `filters.Adaptor` that handles `content.Info`.
 func AdaptInfo(info Info) filters.Adaptor {
 	return filters.AdapterFunc(func(fieldpath []string) (string, bool) {
 		if len(fieldpath) == 0 {

+ 1 - 1
vendor/github.com/containerd/containerd/content/content.go

@@ -37,7 +37,7 @@ type Provider interface {
 	// ReaderAt only requires desc.Digest to be set.
 	// Other fields in the descriptor may be used internally for resolving
 	// the location of the actual data.
-	ReaderAt(ctx context.Context, dec ocispec.Descriptor) (ReaderAt, error)
+	ReaderAt(ctx context.Context, desc ocispec.Descriptor) (ReaderAt, error)
 }
 
 // Ingester writes content

+ 28 - 0
vendor/github.com/containerd/containerd/content/local/readerat.go

@@ -18,6 +18,11 @@ package local
 
 import (
 	"os"
+
+	"github.com/pkg/errors"
+
+	"github.com/containerd/containerd/content"
+	"github.com/containerd/containerd/errdefs"
 )
 
 // readerat implements io.ReaderAt in a completely stateless manner by opening
@@ -27,6 +32,29 @@ type sizeReaderAt struct {
 	fp   *os.File
 }
 
+// OpenReader creates ReaderAt from a file
+func OpenReader(p string) (content.ReaderAt, error) {
+	fi, err := os.Stat(p)
+	if err != nil {
+		if !os.IsNotExist(err) {
+			return nil, err
+		}
+
+		return nil, errors.Wrap(errdefs.ErrNotFound, "blob not found")
+	}
+
+	fp, err := os.Open(p)
+	if err != nil {
+		if !os.IsNotExist(err) {
+			return nil, err
+		}
+
+		return nil, errors.Wrap(errdefs.ErrNotFound, "blob not found")
+	}
+
+	return sizeReaderAt{size: fi.Size(), fp: fp}, nil
+}
+
 func (ra sizeReaderAt) ReadAt(p []byte, offset int64) (int, error) {
 	return ra.fp.ReadAt(p, offset)
 }

+ 4 - 16
vendor/github.com/containerd/containerd/content/local/store.go

@@ -131,25 +131,13 @@ func (s *store) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.
 	if err != nil {
 		return nil, errors.Wrapf(err, "calculating blob path for ReaderAt")
 	}
-	fi, err := os.Stat(p)
-	if err != nil {
-		if !os.IsNotExist(err) {
-			return nil, err
-		}
-
-		return nil, errors.Wrapf(errdefs.ErrNotFound, "blob %s expected at %s", desc.Digest, p)
-	}
 
-	fp, err := os.Open(p)
+	reader, err := OpenReader(p)
 	if err != nil {
-		if !os.IsNotExist(err) {
-			return nil, err
-		}
-
-		return nil, errors.Wrapf(errdefs.ErrNotFound, "blob %s expected at %s", desc.Digest, p)
+		return nil, errors.Wrapf(err, "blob %s expected at %s", desc.Digest, p)
 	}
 
-	return sizeReaderAt{size: fi.Size(), fp: fp}, nil
+	return reader, nil
 }
 
 // Delete removes a blob by its digest.
@@ -477,7 +465,6 @@ func (s *store) Writer(ctx context.Context, opts ...content.WriterOpt) (content.
 	}
 	var lockErr error
 	for count := uint64(0); count < 10; count++ {
-		time.Sleep(time.Millisecond * time.Duration(rand.Intn(1<<count)))
 		if err := tryLock(wOpts.Ref); err != nil {
 			if !errdefs.IsUnavailable(err) {
 				return nil, err
@@ -488,6 +475,7 @@ func (s *store) Writer(ctx context.Context, opts ...content.WriterOpt) (content.
 			lockErr = nil
 			break
 		}
+		time.Sleep(time.Millisecond * time.Duration(rand.Intn(1<<count)))
 	}
 
 	if lockErr != nil {

+ 8 - 1
vendor/github.com/containerd/containerd/content/proxy/content_writer.go

@@ -97,7 +97,14 @@ func (rw *remoteWriter) Write(p []byte) (n int, err error) {
 	return
 }
 
-func (rw *remoteWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
+func (rw *remoteWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) (err error) {
+	defer func() {
+		err1 := rw.Close()
+		if err == nil {
+			err = err1
+		}
+	}()
+
 	var base content.Info
 	for _, opt := range opts {
 		if err := opt(&base); err != nil {

+ 2 - 0
vendor/github.com/containerd/containerd/defaults/defaults_unix.go

@@ -34,4 +34,6 @@ const (
 	DefaultFIFODir = "/run/containerd/fifo"
 	// DefaultRuntime is the default linux runtime
 	DefaultRuntime = "io.containerd.runc.v2"
+	// DefaultConfigDir is the default location for config files.
+	DefaultConfigDir = "/etc/containerd"
 )

+ 3 - 0
vendor/github.com/containerd/containerd/defaults/defaults_windows.go

@@ -30,6 +30,9 @@ var (
 	// DefaultStateDir is the default location used by containerd to store
 	// transient data
 	DefaultStateDir = filepath.Join(os.Getenv("ProgramData"), "containerd", "state")
+
+	// DefaultConfigDir is the default location for config files.
+	DefaultConfigDir = filepath.Join(os.Getenv("programfiles"), "containerd")
 )
 
 const (

+ 4 - 0
vendor/github.com/containerd/containerd/diff/stream.go

@@ -168,6 +168,10 @@ func (c *compressedProcessor) Close() error {
 	return c.rc.Close()
 }
 
+// BinaryHandler creates a new stream processor handler which calls out to the given binary.
+// The id is used to identify the stream processor and allows the caller to send
+// payloads specific for that stream processor (i.e. decryption keys for decrypt stream processor).
+// The binary will be called for the provided mediaTypes and return the given media type.
 func BinaryHandler(id, returnsMediaType string, mediaTypes []string, path string, args, env []string) Handler {
 	set := make(map[string]struct{}, len(mediaTypes))
 	for _, m := range mediaTypes {

+ 42 - 37
vendor/github.com/containerd/containerd/go.mod

@@ -1,26 +1,24 @@
 module github.com/containerd/containerd
 
-go 1.15
+go 1.16
 
 require (
-	github.com/BurntSushi/toml v0.3.1
-	github.com/Microsoft/go-winio v0.4.16
-	github.com/Microsoft/hcsshim v0.8.14
-	github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da
-	github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4
-	github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e
-	github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102
-	github.com/containerd/console v1.0.1
-	github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7
-	github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c
-	github.com/containerd/go-cni v1.0.1
-	github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328
-	github.com/containerd/imgcrypt v1.0.1
-	github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164
+	github.com/Microsoft/go-winio v0.4.17
+	github.com/Microsoft/hcsshim v0.8.16
+	github.com/containerd/aufs v1.0.0
+	github.com/containerd/btrfs v1.0.0
+	github.com/containerd/cgroups v1.0.1
+	github.com/containerd/console v1.0.2
+	github.com/containerd/continuity v0.1.0
+	github.com/containerd/fifo v1.0.0
+	github.com/containerd/go-cni v1.0.2
+	github.com/containerd/go-runc v1.0.0
+	github.com/containerd/imgcrypt v1.1.1
+	github.com/containerd/nri v0.1.0
 	github.com/containerd/ttrpc v1.0.2
-	github.com/containerd/typeurl v1.0.1
-	github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2
-	github.com/containernetworking/plugins v0.8.6
+	github.com/containerd/typeurl v1.0.2
+	github.com/containerd/zfs v1.0.0
+	github.com/containernetworking/plugins v0.9.1
 	github.com/coreos/go-systemd/v22 v22.1.0
 	github.com/davecgh/go-spew v1.1.1
 	github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c
@@ -31,43 +29,50 @@ require (
 	github.com/gogo/googleapis v1.4.0
 	github.com/gogo/protobuf v1.3.2
 	github.com/golang/protobuf v1.4.3
-	github.com/google/go-cmp v0.5.2
-	github.com/google/uuid v1.1.2
+	github.com/google/go-cmp v0.5.4
+	github.com/google/uuid v1.2.0
 	github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
 	github.com/hashicorp/go-multierror v1.0.0
-	github.com/imdario/mergo v0.3.10
-	github.com/klauspost/compress v1.11.3
-	github.com/moby/sys/mountinfo v0.4.0
+	github.com/imdario/mergo v0.3.11
+	github.com/klauspost/compress v1.11.13
+	github.com/moby/locker v1.0.1
+	github.com/moby/sys/mountinfo v0.4.1
 	github.com/moby/sys/symlink v0.1.0
 	github.com/opencontainers/go-digest v1.0.0
 	github.com/opencontainers/image-spec v1.0.1
-	github.com/opencontainers/runc v1.0.0-rc92
-	github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6
+	github.com/opencontainers/runc v1.0.0-rc93
+	github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d
 	github.com/opencontainers/selinux v1.8.0
+	github.com/pelletier/go-toml v1.8.1
 	github.com/pkg/errors v0.9.1
 	github.com/prometheus/client_golang v1.7.1
+	github.com/prometheus/procfs v0.6.0 // indirect; temporarily force v0.6.0, which was previously defined in imgcrypt as explicit version
+	github.com/satori/go.uuid v1.2.0 // indirect
 	github.com/sirupsen/logrus v1.7.0
 	github.com/stretchr/testify v1.6.1
-	github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
 	github.com/tchap/go-patricia v2.2.6+incompatible
 	github.com/urfave/cli v1.22.2
 	go.etcd.io/bbolt v1.3.5
-	golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
-	golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
-	golang.org/x/sys v0.0.0-20201202213521-69691e467435
-	google.golang.org/grpc v1.30.0
-	gotest.tools/v3 v3.0.2
-	k8s.io/api v0.20.1
-	k8s.io/apimachinery v0.20.1
-	k8s.io/apiserver v0.20.1
-	k8s.io/client-go v0.20.1
-	k8s.io/component-base v0.20.1
-	k8s.io/cri-api v0.20.1
+	golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
+	golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
+	golang.org/x/sys v0.0.0-20210324051608-47abb6519492
+	google.golang.org/grpc v1.33.2
+	gotest.tools/v3 v3.0.3
+	k8s.io/api v0.20.6
+	k8s.io/apimachinery v0.20.6
+	k8s.io/apiserver v0.20.6
+	k8s.io/client-go v0.20.6
+	k8s.io/component-base v0.20.6
+	k8s.io/cri-api v0.20.6
 	k8s.io/klog/v2 v2.4.0
 	k8s.io/utils v0.0.0-20201110183641-67b214c5f920
 )
 
+// When updating replace rules, make sure to also update the rules in integration/client/go.mod
 replace (
+	// prevent transitional dependencies due to containerd having a circular
+	// dependency on itself through plugins. see .empty-mod/go.mod for details
+	github.com/containerd/containerd => ./.empty-mod/
 	github.com/gogo/googleapis => github.com/gogo/googleapis v1.3.2
 	github.com/golang/protobuf => github.com/golang/protobuf v1.3.5
 	// urfave/cli must be <= v1.22.1 due to a regression: https://github.com/urfave/cli/issues/1092

+ 4 - 3
vendor/github.com/containerd/containerd/images/diffid.go

@@ -17,10 +17,10 @@
 package images
 
 import (
-	"compress/gzip"
 	"context"
 	"io"
 
+	"github.com/containerd/containerd/archive/compression"
 	"github.com/containerd/containerd/content"
 	"github.com/containerd/containerd/labels"
 	"github.com/opencontainers/go-digest"
@@ -55,13 +55,14 @@ func GetDiffID(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (
 	}
 	defer ra.Close()
 	r := content.NewReader(ra)
-	gzR, err := gzip.NewReader(r)
+	uR, err := compression.DecompressStream(r)
 	if err != nil {
 		return "", err
 	}
+	defer uR.Close()
 	digester := digest.Canonical.Digester()
 	hashW := digester.Hash()
-	if _, err := io.Copy(hashW, gzR); err != nil {
+	if _, err := io.Copy(hashW, uR); err != nil {
 		return "", err
 	}
 	if err := ra.Close(); err != nil {

+ 3 - 0
vendor/github.com/containerd/containerd/images/mediatypes.go

@@ -49,6 +49,9 @@ const (
 	MediaTypeContainerd1CheckpointRuntimeOptions = "application/vnd.containerd.container.checkpoint.runtime.options+proto"
 	// Legacy Docker schema1 manifest
 	MediaTypeDockerSchema1Manifest = "application/vnd.docker.distribution.manifest.v1+prettyjws"
+	// Encypted media types
+	MediaTypeImageLayerEncrypted     = ocispec.MediaTypeImageLayer + "+encrypted"
+	MediaTypeImageLayerGzipEncrypted = ocispec.MediaTypeImageLayerGzip + "+encrypted"
 )
 
 // DiffCompression returns the compression as defined by the layer diff media

+ 88 - 0
vendor/github.com/containerd/containerd/metadata/boltutil/helpers.go

@@ -19,6 +19,8 @@ package boltutil
 import (
 	"time"
 
+	"github.com/gogo/protobuf/proto"
+	"github.com/gogo/protobuf/types"
 	"github.com/pkg/errors"
 	bolt "go.etcd.io/bbolt"
 )
@@ -28,6 +30,7 @@ var (
 	bucketKeyLabels      = []byte("labels")
 	bucketKeyCreatedAt   = []byte("createdat")
 	bucketKeyUpdatedAt   = []byte("updatedat")
+	bucketKeyExtensions  = []byte("extensions")
 )
 
 // ReadLabels reads the labels key from the bucket
@@ -145,3 +148,88 @@ func WriteTimestamps(bkt *bolt.Bucket, created, updated time.Time) error {
 
 	return nil
 }
+
+// WriteExtensions will write a KV map to the given bucket,
+// where `K` is a string key and `V` is a protobuf's Any type that represents a generic extension.
+func WriteExtensions(bkt *bolt.Bucket, extensions map[string]types.Any) error {
+	if len(extensions) == 0 {
+		return nil
+	}
+
+	ebkt, err := bkt.CreateBucketIfNotExists(bucketKeyExtensions)
+	if err != nil {
+		return err
+	}
+
+	for name, ext := range extensions {
+		p, err := proto.Marshal(&ext)
+		if err != nil {
+			return err
+		}
+
+		if err := ebkt.Put([]byte(name), p); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// ReadExtensions will read back a map of extensions from the given bucket, previously written by WriteExtensions
+func ReadExtensions(bkt *bolt.Bucket) (map[string]types.Any, error) {
+	var (
+		extensions = make(map[string]types.Any)
+		ebkt       = bkt.Bucket(bucketKeyExtensions)
+	)
+
+	if ebkt == nil {
+		return extensions, nil
+	}
+
+	if err := ebkt.ForEach(func(k, v []byte) error {
+		var t types.Any
+		if err := proto.Unmarshal(v, &t); err != nil {
+			return err
+		}
+
+		extensions[string(k)] = t
+		return nil
+	}); err != nil {
+		return nil, err
+	}
+
+	return extensions, nil
+}
+
+// WriteAny write a protobuf's Any type to the bucket
+func WriteAny(bkt *bolt.Bucket, name []byte, any *types.Any) error {
+	if any == nil {
+		return nil
+	}
+
+	data, err := proto.Marshal(any)
+	if err != nil {
+		return err
+	}
+
+	if err := bkt.Put(name, data); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// ReadAny reads back protobuf's Any type from the bucket
+func ReadAny(bkt *bolt.Bucket, name []byte) (*types.Any, error) {
+	bytes := bkt.Get(name)
+	if bytes == nil {
+		return nil, nil
+	}
+
+	out := types.Any{}
+	if err := proto.Unmarshal(bytes, &out); err != nil {
+		return nil, errors.Wrap(err, "failed to unmarshal any")
+	}
+
+	return &out, nil
+}

+ 11 - 58
vendor/github.com/containerd/containerd/metadata/containers.go

@@ -336,16 +336,11 @@ func readContainer(container *containers.Container, bkt *bolt.Bucket) error {
 				container.Runtime.Name = string(n)
 			}
 
-			obkt := rbkt.Get(bucketKeyOptions)
-			if obkt == nil {
-				return nil
-			}
-
-			var any types.Any
-			if err := proto.Unmarshal(obkt, &any); err != nil {
+			any, err := boltutil.ReadAny(rbkt, bucketKeyOptions)
+			if err != nil {
 				return err
 			}
-			container.Runtime.Options = &any
+			container.Runtime.Options = any
 		case string(bucketKeySpec):
 			var any types.Any
 			if err := proto.Unmarshal(v, &any); err != nil {
@@ -357,22 +352,8 @@ func readContainer(container *containers.Container, bkt *bolt.Bucket) error {
 		case string(bucketKeySnapshotter):
 			container.Snapshotter = string(v)
 		case string(bucketKeyExtensions):
-			ebkt := bkt.Bucket(bucketKeyExtensions)
-			if ebkt == nil {
-				return nil
-			}
-
-			extensions := make(map[string]types.Any)
-			if err := ebkt.ForEach(func(k, v []byte) error {
-				var a types.Any
-				if err := proto.Unmarshal(v, &a); err != nil {
-					return err
-				}
-
-				extensions[string(k)] = a
-				return nil
-			}); err != nil {
-
+			extensions, err := boltutil.ReadExtensions(bkt)
+			if err != nil {
 				return err
 			}
 
@@ -388,15 +369,8 @@ func writeContainer(bkt *bolt.Bucket, container *containers.Container) error {
 		return err
 	}
 
-	if container.Spec != nil {
-		spec, err := container.Spec.Marshal()
-		if err != nil {
-			return err
-		}
-
-		if err := bkt.Put(bucketKeySpec, spec); err != nil {
-			return err
-		}
+	if err := boltutil.WriteAny(bkt, bucketKeySpec, container.Spec); err != nil {
+		return err
 	}
 
 	for _, v := range [][2][]byte{
@@ -424,33 +398,12 @@ func writeContainer(bkt *bolt.Bucket, container *containers.Container) error {
 		return err
 	}
 
-	if len(container.Extensions) > 0 {
-		ebkt, err := bkt.CreateBucketIfNotExists(bucketKeyExtensions)
-		if err != nil {
-			return err
-		}
-
-		for name, ext := range container.Extensions {
-			p, err := proto.Marshal(&ext)
-			if err != nil {
-				return err
-			}
-
-			if err := ebkt.Put([]byte(name), p); err != nil {
-				return err
-			}
-		}
+	if err := boltutil.WriteExtensions(bkt, container.Extensions); err != nil {
+		return err
 	}
 
-	if container.Runtime.Options != nil {
-		data, err := proto.Marshal(container.Runtime.Options)
-		if err != nil {
-			return err
-		}
-
-		if err := rbkt.Put(bucketKeyOptions, data); err != nil {
-			return err
-		}
+	if err := boltutil.WriteAny(rbkt, bucketKeyOptions, container.Runtime.Options); err != nil {
+		return err
 	}
 
 	return boltutil.WriteLabels(bkt, container.Labels)

+ 30 - 19
vendor/github.com/containerd/containerd/metadata/namespaces.go

@@ -18,6 +18,7 @@ package metadata
 
 import (
 	"context"
+	"strings"
 
 	"github.com/containerd/containerd/errdefs"
 	"github.com/containerd/containerd/identifiers"
@@ -140,10 +141,17 @@ func (s *namespaceStore) Delete(ctx context.Context, namespace string, opts ...n
 		}
 	}
 	bkt := getBucket(s.tx, bucketKeyVersion)
-	if empty, err := s.namespaceEmpty(ctx, namespace); err != nil {
+	types, err := s.listNs(namespace)
+	if err != nil {
 		return err
-	} else if !empty {
-		return errors.Wrapf(errdefs.ErrFailedPrecondition, "namespace %q must be empty", namespace)
+	}
+
+	if len(types) > 0 {
+		return errors.Wrapf(
+			errdefs.ErrFailedPrecondition,
+			"namespace %q must be empty, but it still has %s",
+			namespace, strings.Join(types, ", "),
+		)
 	}
 
 	if err := bkt.DeleteBucket([]byte(namespace)); err != nil {
@@ -157,32 +165,35 @@ func (s *namespaceStore) Delete(ctx context.Context, namespace string, opts ...n
 	return nil
 }
 
-func (s *namespaceStore) namespaceEmpty(ctx context.Context, namespace string) (bool, error) {
-	// Get all data buckets
-	buckets := []*bolt.Bucket{
-		getImagesBucket(s.tx, namespace),
-		getBlobsBucket(s.tx, namespace),
-		getContainersBucket(s.tx, namespace),
+// listNs returns the types of the remaining objects inside the given namespace.
+// It doesn't return exact objects due to performance concerns.
+func (s *namespaceStore) listNs(namespace string) ([]string, error) {
+	var out []string
+
+	if !isBucketEmpty(getImagesBucket(s.tx, namespace)) {
+		out = append(out, "images")
+	}
+	if !isBucketEmpty(getBlobsBucket(s.tx, namespace)) {
+		out = append(out, "blobs")
 	}
+	if !isBucketEmpty(getContainersBucket(s.tx, namespace)) {
+		out = append(out, "containers")
+	}
+
 	if snbkt := getSnapshottersBucket(s.tx, namespace); snbkt != nil {
 		if err := snbkt.ForEach(func(k, v []byte) error {
 			if v == nil {
-				buckets = append(buckets, snbkt.Bucket(k))
+				if !isBucketEmpty(snbkt.Bucket(k)) {
+					out = append(out, "snapshot-"+string(k))
+				}
 			}
 			return nil
 		}); err != nil {
-			return false, err
-		}
-	}
-
-	// Ensure data buckets are empty
-	for _, bkt := range buckets {
-		if !isBucketEmpty(bkt) {
-			return false, nil
+			return nil, err
 		}
 	}
 
-	return true, nil
+	return out, nil
 }
 
 func isBucketEmpty(bkt *bolt.Bucket) bool {

+ 30 - 18
vendor/github.com/containerd/containerd/mount/losetup_linux.go

@@ -69,7 +69,10 @@ func getFreeLoopDev() (uint32, error) {
 	return uint32(num), nil
 }
 
-func setupLoopDev(backingFile, loopDev string, param LoopParams) error {
+// setupLoopDev attaches the backing file to the loop device and returns
+// the file handle for the loop device. The caller is responsible for
+// closing the file handle.
+func setupLoopDev(backingFile, loopDev string, param LoopParams) (_ *os.File, retErr error) {
 	// 1. Open backing file and loop device
 	flags := os.O_RDWR
 	if param.Readonly {
@@ -78,19 +81,23 @@ func setupLoopDev(backingFile, loopDev string, param LoopParams) error {
 
 	back, err := os.OpenFile(backingFile, flags, 0)
 	if err != nil {
-		return errors.Wrapf(err, "could not open backing file: %s", backingFile)
+		return nil, errors.Wrapf(err, "could not open backing file: %s", backingFile)
 	}
 	defer back.Close()
 
 	loop, err := os.OpenFile(loopDev, flags, 0)
 	if err != nil {
-		return errors.Wrapf(err, "could not open loop device: %s", loopDev)
+		return nil, errors.Wrapf(err, "could not open loop device: %s", loopDev)
 	}
-	defer loop.Close()
+	defer func() {
+		if retErr != nil {
+			loop.Close()
+		}
+	}()
 
 	// 2. Set FD
 	if _, _, err = ioctl(loop.Fd(), unix.LOOP_SET_FD, back.Fd()); err != nil {
-		return errors.Wrapf(err, "could not set loop fd for device: %s", loopDev)
+		return nil, errors.Wrapf(err, "could not set loop fd for device: %s", loopDev)
 	}
 
 	// 3. Set Info
@@ -110,7 +117,7 @@ func setupLoopDev(backingFile, loopDev string, param LoopParams) error {
 
 	_, _, err = ioctl(loop.Fd(), unix.LOOP_SET_STATUS64, uintptr(unsafe.Pointer(&info)))
 	if err == nil {
-		return nil
+		return loop, nil
 	}
 
 	if param.Direct {
@@ -119,13 +126,12 @@ func setupLoopDev(backingFile, loopDev string, param LoopParams) error {
 		info.Flags &= ^(uint32(unix.LO_FLAGS_DIRECT_IO))
 		_, _, err = ioctl(loop.Fd(), unix.LOOP_SET_STATUS64, uintptr(unsafe.Pointer(&info)))
 		if err == nil {
-			return nil
+			return loop, nil
 		}
 	}
 
-	// Cleanup loop fd and return error
 	_, _, _ = ioctl(loop.Fd(), unix.LOOP_CLR_FD, 0)
-	return errors.Errorf("failed to set loop device info: %v", err)
+	return nil, errors.Errorf("failed to set loop device info: %v", err)
 }
 
 // setupLoop looks for (and possibly creates) a free loop device, and
@@ -142,15 +148,16 @@ func setupLoopDev(backingFile, loopDev string, param LoopParams) error {
 // the loop device when done with it.
 //
 // Upon success, the file handle to the loop device is returned.
-func setupLoop(backingFile string, param LoopParams) (string, error) {
+func setupLoop(backingFile string, param LoopParams) (*os.File, error) {
 	for retry := 1; retry < 100; retry++ {
 		num, err := getFreeLoopDev()
 		if err != nil {
-			return "", err
+			return nil, err
 		}
 
 		loopDev := fmt.Sprintf(loopDevFormat, num)
-		if err := setupLoopDev(backingFile, loopDev, param); err != nil {
+		file, err := setupLoopDev(backingFile, loopDev, param)
+		if err != nil {
 			// Per util-linux/sys-utils/losetup.c:create_loop(),
 			// free loop device can race and we end up failing
 			// with EBUSY when trying to set it up.
@@ -159,13 +166,13 @@ func setupLoop(backingFile string, param LoopParams) (string, error) {
 				time.Sleep(time.Millisecond * time.Duration(rand.Intn(retry*10)))
 				continue
 			}
-			return "", err
+			return nil, err
 		}
 
-		return loopDev, nil
+		return file, nil
 	}
 
-	return "", errors.New("timeout creating new loopback device")
+	return nil, errors.New("timeout creating new loopback device")
 }
 
 func removeLoop(loopdev string) error {
@@ -179,12 +186,17 @@ func removeLoop(loopdev string) error {
 	return err
 }
 
-// Attach a specified backing file to a loop device
+// AttachLoopDevice attaches a specified backing file to a loop device
 func AttachLoopDevice(backingFile string) (string, error) {
-	return setupLoop(backingFile, LoopParams{})
+	file, err := setupLoop(backingFile, LoopParams{})
+	if err != nil {
+		return "", err
+	}
+	defer file.Close()
+	return file.Name(), nil
 }
 
-// Detach a loop device
+// DetachLoopDevice detaches the provided loop devices
 func DetachLoopDevice(devices ...string) error {
 	for _, dev := range devices {
 		if err := removeLoop(dev); err != nil {

+ 4 - 2
vendor/github.com/containerd/containerd/mount/mount_linux.go

@@ -79,14 +79,16 @@ func (m *Mount) Mount(target string) (err error) {
 		// or remount with changed data
 		source := m.Source
 		if losetup {
-			devFile, err := setupLoop(m.Source, LoopParams{
+			loFile, err := setupLoop(m.Source, LoopParams{
 				Readonly:  oflags&unix.MS_RDONLY == unix.MS_RDONLY,
 				Autoclear: true})
 			if err != nil {
 				return err
 			}
+			defer loFile.Close()
+
 			// Mount the loop device instead
-			source = devFile
+			source = loFile.Name()
 		}
 		if err := mountAt(chdir, source, target, m.Type, uintptr(oflags), data); err != nil {
 			return err

+ 31 - 44
vendor/github.com/containerd/containerd/oci/spec_opts.go

@@ -38,7 +38,6 @@ import (
 	"github.com/opencontainers/runc/libcontainer/user"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
 	"github.com/pkg/errors"
-	"github.com/syndtr/gocapability/capability"
 )
 
 // SpecOpts sets spec specific information to a newly generated OCI spec
@@ -274,6 +273,28 @@ func WithMounts(mounts []specs.Mount) SpecOpts {
 	}
 }
 
+// WithoutMounts removes mounts
+func WithoutMounts(dests ...string) SpecOpts {
+	return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
+		var (
+			mounts  []specs.Mount
+			current = s.Mounts
+		)
+	mLoop:
+		for _, m := range current {
+			mDestination := filepath.Clean(m.Destination)
+			for _, dest := range dests {
+				if mDestination == dest {
+					continue mLoop
+				}
+			}
+			mounts = append(mounts, m)
+		}
+		s.Mounts = mounts
+		return nil
+	}
+}
+
 // WithHostNamespace allows a task to run inside the host's linux namespace
 func WithHostNamespace(ns specs.LinuxNamespaceType) SpecOpts {
 	return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
@@ -295,10 +316,7 @@ func WithLinuxNamespace(ns specs.LinuxNamespace) SpecOpts {
 		setLinux(s)
 		for i, n := range s.Linux.Namespaces {
 			if n.Type == ns.Type {
-				before := s.Linux.Namespaces[:i]
-				after := s.Linux.Namespaces[i+1:]
-				s.Linux.Namespaces = append(before, ns)
-				s.Linux.Namespaces = append(s.Linux.Namespaces, after...)
+				s.Linux.Namespaces[i] = ns
 				return nil
 			}
 		}
@@ -776,29 +794,6 @@ func WithCapabilities(caps []string) SpecOpts {
 	}
 }
 
-// WithAllCapabilities sets all linux capabilities for the process
-var WithAllCapabilities = func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
-	return WithCapabilities(GetAllCapabilities())(ctx, client, c, s)
-}
-
-// GetAllCapabilities returns all caps up to CAP_LAST_CAP
-// or CAP_BLOCK_SUSPEND on RHEL6
-func GetAllCapabilities() []string {
-	last := capability.CAP_LAST_CAP
-	// hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
-	if last == capability.Cap(63) {
-		last = capability.CAP_BLOCK_SUSPEND
-	}
-	var caps []string
-	for _, cap := range capability.List() {
-		if cap > last {
-			continue
-		}
-		caps = append(caps, "CAP_"+strings.ToUpper(cap.String()))
-	}
-	return caps
-}
-
 func capsContain(caps []string, s string) bool {
 	for _, c := range caps {
 		if c == s {
@@ -954,16 +949,13 @@ func WithReadonlyPaths(paths []string) SpecOpts {
 
 // WithWriteableSysfs makes any sysfs mounts writeable
 func WithWriteableSysfs(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
-	for i, m := range s.Mounts {
+	for _, m := range s.Mounts {
 		if m.Type == "sysfs" {
-			var options []string
-			for _, o := range m.Options {
+			for i, o := range m.Options {
 				if o == "ro" {
-					o = "rw"
+					m.Options[i] = "rw"
 				}
-				options = append(options, o)
 			}
-			s.Mounts[i].Options = options
 		}
 	}
 	return nil
@@ -971,16 +963,13 @@ func WithWriteableSysfs(_ context.Context, _ Client, _ *containers.Container, s
 
 // WithWriteableCgroupfs makes any cgroup mounts writeable
 func WithWriteableCgroupfs(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
-	for i, m := range s.Mounts {
+	for _, m := range s.Mounts {
 		if m.Type == "cgroup" {
-			var options []string
-			for _, o := range m.Options {
+			for i, o := range m.Options {
 				if o == "ro" {
-					o = "rw"
+					m.Options[i] = "rw"
 				}
-				options = append(options, o)
 			}
-			s.Mounts[i].Options = options
 		}
 	}
 	return nil
@@ -1132,7 +1121,7 @@ func WithDefaultUnixDevices(_ context.Context, _ Client, _ *containers.Container
 
 // WithPrivileged sets up options for a privileged container
 var WithPrivileged = Compose(
-	WithAllCapabilities,
+	WithAllCurrentCapabilities,
 	WithMaskedPaths(nil),
 	WithReadonlyPaths(nil),
 	WithWriteableSysfs,
@@ -1205,15 +1194,13 @@ func WithLinuxDevices(devices []specs.LinuxDevice) SpecOpts {
 	}
 }
 
-var ErrNotADevice = errors.New("not a device node")
-
 // WithLinuxDevice adds the device specified by path to the spec
 func WithLinuxDevice(path, permissions string) SpecOpts {
 	return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
 		setLinux(s)
 		setResources(s)
 
-		dev, err := deviceFromPath(path, permissions)
+		dev, err := deviceFromPath(path)
 		if err != nil {
 			return err
 		}

+ 42 - 79
vendor/github.com/containerd/containerd/oci/spec_opts_linux.go

@@ -20,20 +20,17 @@ package oci
 
 import (
 	"context"
-	"io/ioutil"
-	"os"
-	"path/filepath"
 
 	"github.com/containerd/containerd/containers"
+	"github.com/containerd/containerd/pkg/cap"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
-	"golang.org/x/sys/unix"
 )
 
 // WithHostDevices adds all the hosts device nodes to the container's spec
 func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
 	setLinux(s)
 
-	devs, err := getDevices("/dev")
+	devs, err := HostDevices()
 	if err != nil {
 		return err
 	}
@@ -41,83 +38,28 @@ func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Sp
 	return nil
 }
 
-func getDevices(path string) ([]specs.LinuxDevice, error) {
-	files, err := ioutil.ReadDir(path)
-	if err != nil {
-		return nil, err
-	}
-	var out []specs.LinuxDevice
-	for _, f := range files {
-		switch {
-		case f.IsDir():
-			switch f.Name() {
-			// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
-			// ".udev" added to address https://github.com/opencontainers/runc/issues/2093
-			case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts", ".udev":
-				continue
-			default:
-				sub, err := getDevices(filepath.Join(path, f.Name()))
-				if err != nil {
-					return nil, err
-				}
-
-				out = append(out, sub...)
-				continue
-			}
-		case f.Name() == "console":
-			continue
-		}
-		device, err := deviceFromPath(filepath.Join(path, f.Name()), "rwm")
+// WithDevices recursively adds devices from the passed in path and associated cgroup rules for that device.
+// If devicePath is a dir it traverses the dir to add all devices in that dir.
+// If devicePath is not a dir, it attempts to add the single device.
+// If containerPath is not set then the device path is used for the container path.
+func WithDevices(devicePath, containerPath, permissions string) SpecOpts {
+	return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
+		devs, err := getDevices(devicePath, containerPath)
 		if err != nil {
-			if err == ErrNotADevice {
-				continue
-			}
-			if os.IsNotExist(err) {
-				continue
-			}
-			return nil, err
+			return err
 		}
-		out = append(out, *device)
-	}
-	return out, nil
-}
-
-func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
-	var stat unix.Stat_t
-	if err := unix.Lstat(path, &stat); err != nil {
-		return nil, err
-	}
-
-	var (
-		// The type is 32bit on mips.
-		devNumber = uint64(stat.Rdev) // nolint: unconvert
-		major     = unix.Major(devNumber)
-		minor     = unix.Minor(devNumber)
-	)
-	if major == 0 {
-		return nil, ErrNotADevice
-	}
-
-	var (
-		devType string
-		mode    = stat.Mode
-	)
-	switch {
-	case mode&unix.S_IFBLK == unix.S_IFBLK:
-		devType = "b"
-	case mode&unix.S_IFCHR == unix.S_IFCHR:
-		devType = "c"
+		for _, dev := range devs {
+			s.Linux.Devices = append(s.Linux.Devices, dev)
+			s.Linux.Resources.Devices = append(s.Linux.Resources.Devices, specs.LinuxDeviceCgroup{
+				Allow:  true,
+				Type:   dev.Type,
+				Major:  &dev.Major,
+				Minor:  &dev.Minor,
+				Access: permissions,
+			})
+		}
+		return nil
 	}
-	fm := os.FileMode(mode)
-	return &specs.LinuxDevice{
-		Type:     devType,
-		Path:     path,
-		Major:    int64(major),
-		Minor:    int64(minor),
-		FileMode: &fm,
-		UID:      &stat.Uid,
-		GID:      &stat.Gid,
-	}, nil
 }
 
 // WithMemorySwap sets the container's swap in bytes
@@ -180,3 +122,24 @@ func WithCPUCFS(quota int64, period uint64) SpecOpts {
 		return nil
 	}
 }
+
+// WithAllCurrentCapabilities propagates the effective capabilities of the caller process to the container process.
+// The capability set may differ from WithAllKnownCapabilities when running in a container.
+var WithAllCurrentCapabilities = func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
+	caps, err := cap.Current()
+	if err != nil {
+		return err
+	}
+	return WithCapabilities(caps)(ctx, client, c, s)
+}
+
+// WithAllKnownCapabilities sets all the the known linux capabilities for the container process
+var WithAllKnownCapabilities = func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
+	caps := cap.Known()
+	return WithCapabilities(caps)(ctx, client, c, s)
+}
+
+// WithoutRunMount removes the `/run` inside the spec
+func WithoutRunMount(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
+	return WithoutMounts("/run")(ctx, client, c, s)
+}

+ 38 - 0
vendor/github.com/containerd/containerd/oci/spec_opts_nonlinux.go

@@ -0,0 +1,38 @@
+// +build !linux
+
+/*
+   Copyright The containerd Authors.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package oci
+
+import (
+	"context"
+
+	"github.com/containerd/containerd/containers"
+)
+
+// WithAllCurrentCapabilities propagates the effective capabilities of the caller process to the container process.
+// The capability set may differ from WithAllKnownCapabilities when running in a container.
+//nolint: deadcode, unused
+var WithAllCurrentCapabilities = func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
+	return WithCapabilities(nil)(ctx, client, c, s)
+}
+
+// WithAllKnownCapabilities sets all the the known linux capabilities for the container process
+//nolint: deadcode, unused
+var WithAllKnownCapabilities = func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
+	return WithCapabilities(nil)(ctx, client, c, s)
+}

+ 10 - 79
vendor/github.com/containerd/containerd/oci/spec_opts_unix.go

@@ -20,20 +20,15 @@ package oci
 
 import (
 	"context"
-	"io/ioutil"
-	"os"
-	"path/filepath"
 
 	"github.com/containerd/containerd/containers"
-	specs "github.com/opencontainers/runtime-spec/specs-go"
-	"golang.org/x/sys/unix"
 )
 
 // WithHostDevices adds all the hosts device nodes to the container's spec
 func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
 	setLinux(s)
 
-	devs, err := getDevices("/dev")
+	devs, err := HostDevices()
 	if err != nil {
 		return err
 	}
@@ -41,82 +36,18 @@ func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Sp
 	return nil
 }
 
-func getDevices(path string) ([]specs.LinuxDevice, error) {
-	files, err := ioutil.ReadDir(path)
-	if err != nil {
-		return nil, err
-	}
-	var out []specs.LinuxDevice
-	for _, f := range files {
-		switch {
-		case f.IsDir():
-			switch f.Name() {
-			// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
-			// ".udev" added to address https://github.com/opencontainers/runc/issues/2093
-			case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts", ".udev":
-				continue
-			default:
-				sub, err := getDevices(filepath.Join(path, f.Name()))
-				if err != nil {
-					return nil, err
-				}
-
-				out = append(out, sub...)
-				continue
-			}
-		case f.Name() == "console":
-			continue
-		}
-		device, err := deviceFromPath(filepath.Join(path, f.Name()), "rwm")
+// WithDevices recursively adds devices from the passed in path and associated cgroup rules for that device.
+// If devicePath is a dir it traverses the dir to add all devices in that dir.
+// If devicePath is not a dir, it attempts to add the single device.
+func WithDevices(devicePath, containerPath, permissions string) SpecOpts {
+	return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
+		devs, err := getDevices(devicePath, containerPath)
 		if err != nil {
-			if err == ErrNotADevice {
-				continue
-			}
-			if os.IsNotExist(err) {
-				continue
-			}
-			return nil, err
+			return err
 		}
-		out = append(out, *device)
-	}
-	return out, nil
-}
-
-func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
-	var stat unix.Stat_t
-	if err := unix.Lstat(path, &stat); err != nil {
-		return nil, err
-	}
-
-	var (
-		devNumber = uint64(stat.Rdev)
-		major     = unix.Major(devNumber)
-		minor     = unix.Minor(devNumber)
-	)
-	if major == 0 {
-		return nil, ErrNotADevice
-	}
-
-	var (
-		devType string
-		mode    = stat.Mode
-	)
-	switch {
-	case mode&unix.S_IFBLK == unix.S_IFBLK:
-		devType = "b"
-	case mode&unix.S_IFCHR == unix.S_IFCHR:
-		devType = "c"
+		s.Linux.Devices = append(s.Linux.Devices, devs...)
+		return nil
 	}
-	fm := os.FileMode(mode)
-	return &specs.LinuxDevice{
-		Type:     devType,
-		Path:     path,
-		Major:    int64(major),
-		Minor:    int64(minor),
-		FileMode: &fm,
-		UID:      &stat.Uid,
-		GID:      &stat.Gid,
-	}, nil
 }
 
 // WithCPUCFS sets the container's Completely fair scheduling (CFS) quota and period

+ 1 - 1
vendor/github.com/containerd/containerd/oci/spec_opts_windows.go

@@ -74,6 +74,6 @@ func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Sp
 	return nil
 }
 
-func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
+func deviceFromPath(path string) (*specs.LinuxDevice, error) {
 	return nil, errors.New("device from path not supported on Windows")
 }

+ 137 - 0
vendor/github.com/containerd/containerd/oci/utils_unix.go

@@ -0,0 +1,137 @@
+// +build !windows
+
+/*
+   Copyright The containerd Authors.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package oci
+
+import (
+	"io/ioutil"
+	"os"
+	"path/filepath"
+
+	specs "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/pkg/errors"
+	"golang.org/x/sys/unix"
+)
+
+var errNotADevice = errors.New("not a device node")
+
+// HostDevices returns all devices that can be found under /dev directory.
+func HostDevices() ([]specs.LinuxDevice, error) {
+	return getDevices("/dev", "")
+}
+
+func getDevices(path, containerPath string) ([]specs.LinuxDevice, error) {
+	stat, err := os.Stat(path)
+	if err != nil {
+		return nil, errors.Wrap(err, "error stating device path")
+	}
+
+	if !stat.IsDir() {
+		dev, err := deviceFromPath(path)
+		if err != nil {
+			return nil, err
+		}
+		if containerPath != "" {
+			dev.Path = containerPath
+		}
+		return []specs.LinuxDevice{*dev}, nil
+	}
+
+	files, err := ioutil.ReadDir(path)
+	if err != nil {
+		return nil, err
+	}
+	var out []specs.LinuxDevice
+	for _, f := range files {
+		switch {
+		case f.IsDir():
+			switch f.Name() {
+			// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
+			// ".udev" added to address https://github.com/opencontainers/runc/issues/2093
+			case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts", ".udev":
+				continue
+			default:
+				var cp string
+				if containerPath != "" {
+					cp = filepath.Join(containerPath, filepath.Base(f.Name()))
+				}
+				sub, err := getDevices(filepath.Join(path, f.Name()), cp)
+				if err != nil {
+					return nil, err
+				}
+
+				out = append(out, sub...)
+				continue
+			}
+		case f.Name() == "console":
+			continue
+		}
+		device, err := deviceFromPath(filepath.Join(path, f.Name()))
+		if err != nil {
+			if err == errNotADevice {
+				continue
+			}
+			if os.IsNotExist(err) {
+				continue
+			}
+			return nil, err
+		}
+		if containerPath != "" {
+			device.Path = filepath.Join(containerPath, filepath.Base(f.Name()))
+		}
+		out = append(out, *device)
+	}
+	return out, nil
+}
+
+func deviceFromPath(path string) (*specs.LinuxDevice, error) {
+	var stat unix.Stat_t
+	if err := unix.Lstat(path, &stat); err != nil {
+		return nil, err
+	}
+
+	var (
+		devNumber = uint64(stat.Rdev) //nolint: unconvert // the type is 32bit on mips.
+		major     = unix.Major(devNumber)
+		minor     = unix.Minor(devNumber)
+	)
+	if major == 0 {
+		return nil, errNotADevice
+	}
+
+	var (
+		devType string
+		mode    = stat.Mode
+	)
+	switch {
+	case mode&unix.S_IFBLK == unix.S_IFBLK:
+		devType = "b"
+	case mode&unix.S_IFCHR == unix.S_IFCHR:
+		devType = "c"
+	}
+	fm := os.FileMode(mode &^ unix.S_IFMT)
+	return &specs.LinuxDevice{
+		Type:     devType,
+		Path:     path,
+		Major:    int64(major),
+		Minor:    int64(minor),
+		FileMode: &fm,
+		UID:      &stat.Uid,
+		GID:      &stat.Gid,
+	}, nil
+}

+ 6 - 27
vendor/github.com/containerd/containerd/pkg/apparmor/apparmor.go

@@ -1,5 +1,3 @@
-// +build linux
-
 /*
    Copyright The containerd Authors.
 
@@ -18,31 +16,12 @@
 
 package apparmor
 
-import (
-	"io/ioutil"
-	"os"
-	"sync"
-)
-
-var (
-	appArmorSupported bool
-	checkAppArmor     sync.Once
-)
-
-// HostSupports returns true if apparmor is enabled for the host, if
-// apparmor_parser is enabled, and if we are not running docker-in-docker.
+// HostSupports returns true if apparmor is enabled for the host, // On non-Linux returns false
+// On Linux returns true if apparmor_parser is enabled, and if we
+//  are not running docker-in-docker.
 //
-// It is a modified version of libcontainer/apparmor.IsEnabled(), which does not
-// check for apparmor_parser to be present, or if we're running docker-in-docker.
+//  It is a modified version of libcontainer/apparmor.IsEnabled(), which does not
+//  check for apparmor_parser to be present, or if we're running docker-in-docker.
 func HostSupports() bool {
-	checkAppArmor.Do(func() {
-		// see https://github.com/docker/docker/commit/de191e86321f7d3136ff42ff75826b8107399497
-		if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil && os.Getenv("container") == "" {
-			if _, err = os.Stat("/sbin/apparmor_parser"); err == nil {
-				buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled")
-				appArmorSupported = err == nil && len(buf) > 1 && buf[0] == 'Y'
-			}
-		}
-	})
-	return appArmorSupported
+	return hostSupports()
 }

+ 48 - 0
vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_linux.go

@@ -0,0 +1,48 @@
+// +build linux
+
+/*
+   Copyright The containerd Authors.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package apparmor
+
+import (
+	"io/ioutil"
+	"os"
+	"sync"
+)
+
+var (
+	appArmorSupported bool
+	checkAppArmor     sync.Once
+)
+
+// hostSupports returns true if apparmor is enabled for the host, if
+// apparmor_parser is enabled, and if we are not running docker-in-docker.
+//
+// It is a modified version of libcontainer/apparmor.IsEnabled(), which does not
+// check for apparmor_parser to be present, or if we're running docker-in-docker.
+func hostSupports() bool {
+	checkAppArmor.Do(func() {
+		// see https://github.com/docker/docker/commit/de191e86321f7d3136ff42ff75826b8107399497
+		if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil && os.Getenv("container") == "" {
+			if _, err = os.Stat("/sbin/apparmor_parser"); err == nil {
+				buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled")
+				appArmorSupported = err == nil && len(buf) > 1 && buf[0] == 'Y'
+			}
+		}
+	})
+	return appArmorSupported
+}

+ 1 - 2
vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_unsupported.go

@@ -18,7 +18,6 @@
 
 package apparmor
 
-//nolint: deadcode, unused
-func HostSupports() bool {
+func hostSupports() bool {
 	return false
 }

+ 192 - 0
vendor/github.com/containerd/containerd/pkg/cap/cap_linux.go

@@ -0,0 +1,192 @@
+/*
+   Copyright The containerd Authors.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+// Package cap provides Linux capability utility
+package cap
+
+import (
+	"bufio"
+	"io"
+	"os"
+	"strconv"
+	"strings"
+
+	"github.com/pkg/errors"
+)
+
+// FromNumber returns a cap string like "CAP_SYS_ADMIN"
+// that corresponds to the given number like 21.
+//
+// FromNumber returns an empty string for unknown cap number.
+func FromNumber(num int) string {
+	if num < 0 || num > len(capsLatest)-1 {
+		return ""
+	}
+	return capsLatest[num]
+}
+
+// FromBitmap parses an uint64 bitmap into string slice like
+// []{"CAP_SYS_ADMIN", ...}.
+//
+// Unknown cap numbers are returned as []int.
+func FromBitmap(v uint64) ([]string, []int) {
+	var (
+		res     []string
+		unknown []int
+	)
+	for i := 0; i <= 63; i++ {
+		if b := (v >> i) & 0x1; b == 0x1 {
+			if s := FromNumber(i); s != "" {
+				res = append(res, s)
+			} else {
+				unknown = append(unknown, i)
+			}
+		}
+	}
+	return res, unknown
+}
+
+// Type is the type of capability
+type Type int
+
+const (
+	// Effective is CapEff
+	Effective Type = 1 << iota
+	// Permitted is CapPrm
+	Permitted
+	// Inheritable is CapInh
+	Inheritable
+	// Bounding is CapBnd
+	Bounding
+	// Ambient is CapAmb
+	Ambient
+)
+
+// ParseProcPIDStatus returns uint64 bitmap value from /proc/<PID>/status file
+func ParseProcPIDStatus(r io.Reader) (map[Type]uint64, error) {
+	res := make(map[Type]uint64)
+	scanner := bufio.NewScanner(r)
+	for scanner.Scan() {
+		line := scanner.Text()
+		pair := strings.SplitN(line, ":", 2)
+		if len(pair) != 2 {
+			continue
+		}
+		k := strings.TrimSpace(pair[0])
+		v := strings.TrimSpace(pair[1])
+		switch k {
+		case "CapInh", "CapPrm", "CapEff", "CapBnd", "CapAmb":
+			ui64, err := strconv.ParseUint(v, 16, 64)
+			if err != nil {
+				return nil, errors.Errorf("failed to parse line %q", line)
+			}
+			switch k {
+			case "CapInh":
+				res[Inheritable] = ui64
+			case "CapPrm":
+				res[Permitted] = ui64
+			case "CapEff":
+				res[Effective] = ui64
+			case "CapBnd":
+				res[Bounding] = ui64
+			case "CapAmb":
+				res[Ambient] = ui64
+			}
+		}
+	}
+	if err := scanner.Err(); err != nil {
+		return nil, err
+	}
+	return res, nil
+}
+
+// Current returns the list of the effective and the known caps of
+// the current process.
+//
+// The result is like []string{"CAP_SYS_ADMIN", ...}.
+//
+// The result does not contain caps that are not recognized by
+// the "github.com/syndtr/gocapability" library.
+func Current() ([]string, error) {
+	f, err := os.Open("/proc/self/status")
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	caps, err := ParseProcPIDStatus(f)
+	if err != nil {
+		return nil, err
+	}
+	capEff := caps[Effective]
+	names, _ := FromBitmap(capEff)
+	return names, nil
+}
+
+var (
+	// caps35 is the caps of kernel 3.5 (37 entries)
+	caps35 = []string{
+		"CAP_CHOWN",            // 2.2
+		"CAP_DAC_OVERRIDE",     // 2.2
+		"CAP_DAC_READ_SEARCH",  // 2.2
+		"CAP_FOWNER",           // 2.2
+		"CAP_FSETID",           // 2.2
+		"CAP_KILL",             // 2.2
+		"CAP_SETGID",           // 2.2
+		"CAP_SETUID",           // 2.2
+		"CAP_SETPCAP",          // 2.2
+		"CAP_LINUX_IMMUTABLE",  // 2.2
+		"CAP_NET_BIND_SERVICE", // 2.2
+		"CAP_NET_BROADCAST",    // 2.2
+		"CAP_NET_ADMIN",        // 2.2
+		"CAP_NET_RAW",          // 2.2
+		"CAP_IPC_LOCK",         // 2.2
+		"CAP_IPC_OWNER",        // 2.2
+		"CAP_SYS_MODULE",       // 2.2
+		"CAP_SYS_RAWIO",        // 2.2
+		"CAP_SYS_CHROOT",       // 2.2
+		"CAP_SYS_PTRACE",       // 2.2
+		"CAP_SYS_PACCT",        // 2.2
+		"CAP_SYS_ADMIN",        // 2.2
+		"CAP_SYS_BOOT",         // 2.2
+		"CAP_SYS_NICE",         // 2.2
+		"CAP_SYS_RESOURCE",     // 2.2
+		"CAP_SYS_TIME",         // 2.2
+		"CAP_SYS_TTY_CONFIG",   // 2.2
+		"CAP_MKNOD",            // 2.4
+		"CAP_LEASE",            // 2.4
+		"CAP_AUDIT_WRITE",      // 2.6.11
+		"CAP_AUDIT_CONTROL",    // 2.6.11
+		"CAP_SETFCAP",          // 2.6.24
+		"CAP_MAC_OVERRIDE",     // 2.6.25
+		"CAP_MAC_ADMIN",        // 2.6.25
+		"CAP_SYSLOG",           // 2.6.37
+		"CAP_WAKE_ALARM",       // 3.0
+		"CAP_BLOCK_SUSPEND",    // 3.5
+	}
+	// caps316 is the caps of kernel 3.16 (38 entries)
+	caps316 = append(caps35, "CAP_AUDIT_READ")
+	// caps58 is the caps of kernel 5.8 (40 entries)
+	caps58 = append(caps316, []string{"CAP_PERFMON", "CAP_BPF"}...)
+	// caps59 is the caps of kernel 5.9 (41 entries)
+	caps59     = append(caps58, "CAP_CHECKPOINT_RESTORE")
+	capsLatest = caps59
+)
+
+// Known returns the known cap strings of the latest kernel.
+// The current latest kernel is 5.9.
+func Known() []string {
+	return capsLatest
+}

+ 6 - 2
vendor/github.com/containerd/containerd/pkg/process/init.go

@@ -193,11 +193,15 @@ func (p *Init) createCheckpointedState(r *CreateConfig, pidFile *pidFile) error
 			ParentPath: r.ParentCheckpoint,
 		},
 		PidFile:     pidFile.Path(),
-		IO:          p.io.IO(),
 		NoPivot:     p.NoPivotRoot,
 		Detach:      true,
 		NoSubreaper: true,
 	}
+
+	if p.io != nil {
+		opts.IO = p.io.IO()
+	}
+
 	p.initState = &createdCheckpointState{
 		p:    p,
 		opts: opts,
@@ -441,7 +445,7 @@ func (p *Init) checkpoint(ctx context.Context, r *CheckpointConfig) error {
 	}, actions...); err != nil {
 		dumpLog := filepath.Join(p.Bundle, "criu-dump.log")
 		if cerr := copyFile(dumpLog, filepath.Join(work, "dump.log")); cerr != nil {
-			log.G(ctx).Error(err)
+			log.G(ctx).WithError(cerr).Error("failed to copy dump.log to criu-dump.log")
 		}
 		return fmt.Errorf("%s path= %s", criuError(err), dumpLog)
 	}

+ 2 - 16
vendor/github.com/containerd/containerd/pkg/process/io.go

@@ -34,7 +34,6 @@ import (
 	"github.com/containerd/containerd/log"
 	"github.com/containerd/containerd/namespaces"
 	"github.com/containerd/containerd/pkg/stdio"
-	"github.com/containerd/containerd/sys"
 	"github.com/containerd/fifo"
 	runc "github.com/containerd/go-runc"
 	"github.com/hashicorp/go-multierror"
@@ -179,7 +178,7 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w
 			},
 		},
 	} {
-		ok, err := sys.IsFifo(i.name)
+		ok, err := fifo.IsFifo(i.name)
 		if err != nil {
 			return err
 		}
@@ -252,14 +251,6 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (_ runc.IO, err e
 		return nil, err
 	}
 
-	var args []string
-	for k, vs := range uri.Query() {
-		args = append(args, k)
-		if len(vs) > 0 {
-			args = append(args, vs[0])
-		}
-	}
-
 	var closers []func() error
 	defer func() {
 		if err == nil {
@@ -290,12 +281,7 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (_ runc.IO, err e
 	}
 	closers = append(closers, r.Close, w.Close)
 
-	cmd := exec.Command(uri.Path, args...)
-	cmd.Env = append(cmd.Env,
-		"CONTAINER_ID="+id,
-		"CONTAINER_NAMESPACE="+ns,
-	)
-
+	cmd := NewBinaryCmd(uri, id, ns)
 	cmd.ExtraFiles = append(cmd.ExtraFiles, out.r, serr.r, w)
 	// don't need to register this with the reaper or wait when
 	// running inside a shim

+ 1 - 1
vendor/github.com/containerd/containerd/runtime/io.go → vendor/github.com/containerd/containerd/pkg/process/io_util.go

@@ -14,7 +14,7 @@
    limitations under the License.
 */
 
-package runtime
+package process
 
 import (
 	"net/url"

+ 1 - 1
vendor/github.com/containerd/containerd/pkg/process/utils.go

@@ -172,7 +172,7 @@ func (p *pidFile) Read() (int, error) {
 func waitTimeout(ctx context.Context, wg *sync.WaitGroup, timeout time.Duration) error {
 	ctx, cancel := context.WithTimeout(ctx, timeout)
 	defer cancel()
-	done := make(chan struct{}, 1)
+	done := make(chan struct{})
 	go func() {
 		wg.Wait()
 		close(done)

+ 1 - 1
vendor/github.com/containerd/containerd/sys/userns_linux.go → vendor/github.com/containerd/containerd/pkg/userns/userns_linux.go

@@ -14,7 +14,7 @@
    limitations under the License.
 */
 
-package sys
+package userns
 
 import (
 	"bufio"

+ 1 - 1
vendor/github.com/containerd/containerd/sys/userns_unsupported.go → vendor/github.com/containerd/containerd/pkg/userns/userns_unsupported.go

@@ -16,7 +16,7 @@
    limitations under the License.
 */
 
-package sys
+package userns
 
 // RunningInUserNS is a stub for non-Linux systems
 // Always returns false

+ 53 - 5
vendor/github.com/containerd/containerd/platforms/defaults_windows.go

@@ -19,15 +19,63 @@
 package platforms
 
 import (
+	"fmt"
 	"runtime"
+	"strconv"
+	"strings"
 
+	imagespec "github.com/opencontainers/image-spec/specs-go/v1"
 	specs "github.com/opencontainers/image-spec/specs-go/v1"
+	"golang.org/x/sys/windows"
 )
 
-// Default returns the default matcher for the platform.
+type matchComparer struct {
+	defaults        Matcher
+	osVersionPrefix string
+}
+
+// Match matches platform with the same windows major, minor
+// and build version.
+func (m matchComparer) Match(p imagespec.Platform) bool {
+	if m.defaults.Match(p) {
+		// TODO(windows): Figure out whether OSVersion is deprecated.
+		return strings.HasPrefix(p.OSVersion, m.osVersionPrefix)
+	}
+	return false
+}
+
+// Less sorts matched platforms in front of other platforms.
+// For matched platforms, it puts platforms with larger revision
+// number in front.
+func (m matchComparer) Less(p1, p2 imagespec.Platform) bool {
+	m1, m2 := m.Match(p1), m.Match(p2)
+	if m1 && m2 {
+		r1, r2 := revision(p1.OSVersion), revision(p2.OSVersion)
+		return r1 > r2
+	}
+	return m1 && !m2
+}
+
+func revision(v string) int {
+	parts := strings.Split(v, ".")
+	if len(parts) < 4 {
+		return 0
+	}
+	r, err := strconv.Atoi(parts[3])
+	if err != nil {
+		return 0
+	}
+	return r
+}
+
+// Default returns the current platform's default platform specification.
 func Default() MatchComparer {
-	return Ordered(DefaultSpec(), specs.Platform{
-		OS:           "linux",
-		Architecture: runtime.GOARCH,
-	})
+	major, minor, build := windows.RtlGetNtVersionNumbers()
+	return matchComparer{
+		defaults: Ordered(DefaultSpec(), specs.Platform{
+			OS:           "linux",
+			Architecture: runtime.GOARCH,
+		}),
+		osVersionPrefix: fmt.Sprintf("%d.%d.%d", major, minor, build),
+	}
 }

+ 45 - 7
vendor/github.com/containerd/containerd/remotes/docker/pusher.go

@@ -44,17 +44,47 @@ type dockerPusher struct {
 	tracker StatusTracker
 }
 
+// Writer implements Ingester API of content store. This allows the client
+// to receive ErrUnavailable when there is already an on-going upload.
+// Note that the tracker MUST implement StatusTrackLocker interface to avoid
+// race condition on StatusTracker.
+func (p dockerPusher) Writer(ctx context.Context, opts ...content.WriterOpt) (content.Writer, error) {
+	var wOpts content.WriterOpts
+	for _, opt := range opts {
+		if err := opt(&wOpts); err != nil {
+			return nil, err
+		}
+	}
+	if wOpts.Ref == "" {
+		return nil, errors.Wrap(errdefs.ErrInvalidArgument, "ref must not be empty")
+	}
+	return p.push(ctx, wOpts.Desc, wOpts.Ref, true)
+}
+
 func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (content.Writer, error) {
+	return p.push(ctx, desc, remotes.MakeRefKey(ctx, desc), false)
+}
+
+func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref string, unavailableOnFail bool) (content.Writer, error) {
+	if l, ok := p.tracker.(StatusTrackLocker); ok {
+		l.Lock(ref)
+		defer l.Unlock(ref)
+	}
 	ctx, err := ContextWithRepositoryScope(ctx, p.refspec, true)
 	if err != nil {
 		return nil, err
 	}
-	ref := remotes.MakeRefKey(ctx, desc)
 	status, err := p.tracker.GetStatus(ref)
 	if err == nil {
-		if status.Offset == status.Total {
+		if status.Committed && status.Offset == status.Total {
 			return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "ref %v", ref)
 		}
+		if unavailableOnFail {
+			// Another push of this ref is happening elsewhere. The rest of function
+			// will continue only when `errdefs.IsNotFound(err) == true` (i.e. there
+			// is no actively-tracked ref already).
+			return nil, errors.Wrap(errdefs.ErrUnavailable, "push is on-going")
+		}
 		// TODO: Handle incomplete status
 	} else if !errdefs.IsNotFound(err) {
 		return nil, errors.Wrap(err, "failed to get status")
@@ -105,8 +135,11 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
 
 			if exists {
 				p.tracker.SetStatus(ref, Status{
+					Committed: true,
 					Status: content.Status{
-						Ref: ref,
+						Ref:    ref,
+						Total:  desc.Size,
+						Offset: desc.Size,
 						// TODO: Set updated time?
 					},
 				})
@@ -162,8 +195,11 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
 		case http.StatusOK, http.StatusAccepted, http.StatusNoContent:
 		case http.StatusCreated:
 			p.tracker.SetStatus(ref, Status{
+				Committed: true,
 				Status: content.Status{
-					Ref: ref,
+					Ref:    ref,
+					Total:  desc.Size,
+					Offset: desc.Size,
 				},
 			})
 			return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest)
@@ -341,8 +377,6 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
 	if err := pw.pipe.Close(); err != nil {
 		return err
 	}
-	// TODO: Update status to determine committing
-
 	// TODO: timeout waiting for response
 	resp := <-pw.responseC
 	if resp.err != nil {
@@ -354,7 +388,7 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
 	switch resp.StatusCode {
 	case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
 	default:
-		return errors.Errorf("unexpected status: %s", resp.Status)
+		return remoteserrors.NewUnexpectedStatusErr(resp.Response)
 	}
 
 	status, err := pw.tracker.GetStatus(pw.ref)
@@ -379,6 +413,10 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
 		return errors.Errorf("got digest %s, expected %s", actual, expected)
 	}
 
+	status.Committed = true
+	status.UpdatedAt = time.Now()
+	pw.tracker.SetStatus(pw.ref, status)
+
 	return nil
 }
 

+ 37 - 4
vendor/github.com/containerd/containerd/remotes/docker/registry.go

@@ -17,7 +17,10 @@
 package docker
 
 import (
+	"net"
 	"net/http"
+
+	"github.com/pkg/errors"
 )
 
 // HostCapabilities represent the capabilities of the registry
@@ -56,6 +59,7 @@ const (
 	// Reserved for future capabilities (i.e. search, catalog, remove)
 )
 
+// Has checks whether the capabilities list has the provide capability
 func (c HostCapabilities) Has(t HostCapabilities) bool {
 	return c&t == t
 }
@@ -201,12 +205,41 @@ func MatchAllHosts(string) (bool, error) {
 
 // MatchLocalhost is a host match function which returns true for
 // localhost.
+//
+// Note: this does not handle matching of ip addresses in octal,
+// decimal or hex form.
 func MatchLocalhost(host string) (bool, error) {
-	for _, s := range []string{"localhost", "127.0.0.1", "[::1]"} {
-		if len(host) >= len(s) && host[0:len(s)] == s && (len(host) == len(s) || host[len(s)] == ':') {
-			return true, nil
+	switch {
+	case host == "::1":
+		return true, nil
+	case host == "[::1]":
+		return true, nil
+	}
+	h, p, err := net.SplitHostPort(host)
+
+	// addrError helps distinguish between errors of form
+	// "no colon in address" and "too many colons in address".
+	// The former is fine as the host string need not have a
+	// port. Latter needs to be handled.
+	addrError := &net.AddrError{
+		Err:  "missing port in address",
+		Addr: host,
+	}
+	if err != nil {
+		if err.Error() != addrError.Error() {
+			return false, err
 		}
+		// host string without any port specified
+		h = host
+	} else if len(p) == 0 {
+		return false, errors.New("invalid host name format")
+	}
+
+	// use ipv4 dotted decimal for further checking
+	if h == "localhost" {
+		h = "127.0.0.1"
 	}
-	return host == "::1", nil
+	ip := net.ParseIP(h)
 
+	return ip.IsLoopback(), nil
 }

+ 2 - 0
vendor/github.com/containerd/containerd/remotes/docker/resolver.go

@@ -286,12 +286,14 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
 				if lastErr == nil {
 					lastErr = err
 				}
+				log.G(ctx).WithError(err).Info("trying next host")
 				continue // try another host
 			}
 			resp.Body.Close() // don't care about body contents.
 
 			if resp.StatusCode > 299 {
 				if resp.StatusCode == http.StatusNotFound {
+					log.G(ctx).Info("trying next host - response was http.StatusNotFound")
 					continue
 				}
 				return "", ocispec.Descriptor{}, errors.Errorf("unexpected status code %v: %v", u, resp.Status)

+ 21 - 1
vendor/github.com/containerd/containerd/remotes/docker/status.go

@@ -21,6 +21,7 @@ import (
 
 	"github.com/containerd/containerd/content"
 	"github.com/containerd/containerd/errdefs"
+	"github.com/moby/locker"
 	"github.com/pkg/errors"
 )
 
@@ -28,6 +29,8 @@ import (
 type Status struct {
 	content.Status
 
+	Committed bool
+
 	// UploadUUID is used by the Docker registry to reference blob uploads
 	UploadUUID string
 }
@@ -38,15 +41,24 @@ type StatusTracker interface {
 	SetStatus(string, Status)
 }
 
+// StatusTrackLocker to track status of operations with lock
+type StatusTrackLocker interface {
+	StatusTracker
+	Lock(string)
+	Unlock(string)
+}
+
 type memoryStatusTracker struct {
 	statuses map[string]Status
 	m        sync.Mutex
+	locker   *locker.Locker
 }
 
 // NewInMemoryTracker returns a StatusTracker that tracks content status in-memory
-func NewInMemoryTracker() StatusTracker {
+func NewInMemoryTracker() StatusTrackLocker {
 	return &memoryStatusTracker{
 		statuses: map[string]Status{},
+		locker:   locker.New(),
 	}
 }
 
@@ -65,3 +77,11 @@ func (t *memoryStatusTracker) SetStatus(ref string, status Status) {
 	t.statuses[ref] = status
 	t.m.Unlock()
 }
+
+func (t *memoryStatusTracker) Lock(ref string) {
+	t.locker.Lock(ref)
+}
+
+func (t *memoryStatusTracker) Unlock(ref string) {
+	t.locker.Unlock(ref)
+}

+ 14 - 4
vendor/github.com/containerd/containerd/remotes/errors/errors.go

@@ -27,9 +27,10 @@ var _ error = ErrUnexpectedStatus{}
 
 // ErrUnexpectedStatus is returned if a registry API request returned with unexpected HTTP status
 type ErrUnexpectedStatus struct {
-	Status     string
-	StatusCode int
-	Body       []byte
+	Status                    string
+	StatusCode                int
+	Body                      []byte
+	RequestURL, RequestMethod string
 }
 
 func (e ErrUnexpectedStatus) Error() string {
@@ -42,5 +43,14 @@ func NewUnexpectedStatusErr(resp *http.Response) error {
 	if resp.Body != nil {
 		b, _ = ioutil.ReadAll(io.LimitReader(resp.Body, 64000)) // 64KB
 	}
-	return ErrUnexpectedStatus{Status: resp.Status, StatusCode: resp.StatusCode, Body: b}
+	err := ErrUnexpectedStatus{
+		Body:          b,
+		Status:        resp.Status,
+		StatusCode:    resp.StatusCode,
+		RequestMethod: resp.Request.Method,
+	}
+	if resp.Request.URL != nil {
+		err.RequestURL = resp.Request.URL.String()
+	}
+	return err
 }

+ 32 - 9
vendor/github.com/containerd/containerd/remotes/handlers.go

@@ -31,6 +31,7 @@ import (
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
+	"golang.org/x/sync/semaphore"
 )
 
 type refKeyPrefix struct{}
@@ -55,25 +56,32 @@ func WithMediaTypeKeyPrefix(ctx context.Context, mediaType, prefix string) conte
 // used to lookup ongoing processes related to the descriptor. This function
 // may look to the context to namespace the reference appropriately.
 func MakeRefKey(ctx context.Context, desc ocispec.Descriptor) string {
+	key := desc.Digest.String()
+	if desc.Annotations != nil {
+		if name, ok := desc.Annotations[ocispec.AnnotationRefName]; ok {
+			key = fmt.Sprintf("%s@%s", name, desc.Digest.String())
+		}
+	}
+
 	if v := ctx.Value(refKeyPrefix{}); v != nil {
 		values := v.(map[string]string)
 		if prefix := values[desc.MediaType]; prefix != "" {
-			return prefix + "-" + desc.Digest.String()
+			return prefix + "-" + key
 		}
 	}
 
 	switch mt := desc.MediaType; {
 	case mt == images.MediaTypeDockerSchema2Manifest || mt == ocispec.MediaTypeImageManifest:
-		return "manifest-" + desc.Digest.String()
+		return "manifest-" + key
 	case mt == images.MediaTypeDockerSchema2ManifestList || mt == ocispec.MediaTypeImageIndex:
-		return "index-" + desc.Digest.String()
+		return "index-" + key
 	case images.IsLayerType(mt):
-		return "layer-" + desc.Digest.String()
+		return "layer-" + key
 	case images.IsKnownConfig(mt):
-		return "config-" + desc.Digest.String()
+		return "config-" + key
 	default:
 		log.G(ctx).Warnf("reference for unknown type: %s", mt)
-		return "unknown-" + desc.Digest.String()
+		return "unknown-" + key
 	}
 }
 
@@ -115,6 +123,12 @@ func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc
 		return err
 	}
 
+	if desc.Size == 0 {
+		// most likely a poorly configured registry/web front end which responded with no
+		// Content-Length header; unable (not to mention useless) to commit a 0-length entry
+		// into the content store. Error out here otherwise the error sent back is confusing
+		return errors.Wrapf(errdefs.ErrInvalidArgument, "unable to fetch descriptor (%s) which reports content size of zero", desc.Digest)
+	}
 	if ws.Offset == desc.Size {
 		// If writer is already complete, commit and return
 		err := cw.Commit(ctx, desc.Size, desc.Digest)
@@ -151,7 +165,15 @@ func PushHandler(pusher Pusher, provider content.Provider) images.HandlerFunc {
 func push(ctx context.Context, provider content.Provider, pusher Pusher, desc ocispec.Descriptor) error {
 	log.G(ctx).Debug("push")
 
-	cw, err := pusher.Push(ctx, desc)
+	var (
+		cw  content.Writer
+		err error
+	)
+	if cs, ok := pusher.(content.Ingester); ok {
+		cw, err = content.OpenWriter(ctx, cs, content.WithRef(MakeRefKey(ctx, desc)), content.WithDescriptor(desc))
+	} else {
+		cw, err = pusher.Push(ctx, desc)
+	}
 	if err != nil {
 		if !errdefs.IsAlreadyExists(err) {
 			return err
@@ -175,7 +197,8 @@ func push(ctx context.Context, provider content.Provider, pusher Pusher, desc oc
 //
 // Base handlers can be provided which will be called before any push specific
 // handlers.
-func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, store content.Store, platform platforms.MatchComparer, wrapper func(h images.Handler) images.Handler) error {
+func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, store content.Store, limiter *semaphore.Weighted, platform platforms.MatchComparer, wrapper func(h images.Handler) images.Handler) error {
+
 	var m sync.Mutex
 	manifestStack := []ocispec.Descriptor{}
 
@@ -207,7 +230,7 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, st
 		handler = wrapper(handler)
 	}
 
-	if err := images.Dispatch(ctx, handler, nil, desc); err != nil {
+	if err := images.Dispatch(ctx, handler, limiter, desc); err != nil {
 		return err
 	}
 

+ 2 - 0
vendor/github.com/containerd/containerd/remotes/resolver.go

@@ -45,6 +45,8 @@ type Resolver interface {
 	Fetcher(ctx context.Context, ref string) (Fetcher, error)
 
 	// Pusher returns a new pusher for the provided reference
+	// The returned Pusher should satisfy content.Ingester and concurrent attempts
+	// to push the same blob using the Ingester API should result in ErrUnavailable.
 	Pusher(ctx context.Context, ref string) (Pusher, error)
 }
 

+ 2 - 2
vendor/github.com/containerd/containerd/rootfs/init.go

@@ -67,7 +67,7 @@ func InitRootFS(ctx context.Context, name string, parent digest.Digest, readonly
 	return snapshotter.Prepare(ctx, name, parentS)
 }
 
-func createInitLayer(ctx context.Context, parent, initName string, initFn func(string) error, snapshotter snapshots.Snapshotter, mounter Mounter) (string, error) {
+func createInitLayer(ctx context.Context, parent, initName string, initFn func(string) error, snapshotter snapshots.Snapshotter, mounter Mounter) (_ string, retErr error) {
 	initS := fmt.Sprintf("%s %s", parent, initName)
 	if _, err := snapshotter.Stat(ctx, initS); err == nil {
 		return initS, nil
@@ -87,7 +87,7 @@ func createInitLayer(ctx context.Context, parent, initName string, initFn func(s
 	}
 
 	defer func() {
-		if err != nil {
+		if retErr != nil {
 			if rerr := snapshotter.Remove(ctx, td); rerr != nil {
 				log.G(ctx).Errorf("Failed to remove snapshot %s: %v", td, rerr)
 			}

+ 5 - 5
vendor/github.com/containerd/containerd/runtime/runtime.go

@@ -63,14 +63,14 @@ type PlatformRuntime interface {
 	// ID of the runtime
 	ID() string
 	// Create creates a task with the provided id and options.
-	Create(ctx context.Context, id string, opts CreateOpts) (Task, error)
+	Create(ctx context.Context, taskID string, opts CreateOpts) (Task, error)
 	// Get returns a task.
-	Get(context.Context, string) (Task, error)
+	Get(ctx context.Context, taskID string) (Task, error)
 	// Tasks returns all the current tasks for the runtime.
 	// Any container runs at most one task at a time.
-	Tasks(context.Context, bool) ([]Task, error)
+	Tasks(ctx context.Context, all bool) ([]Task, error)
 	// Add adds a task into runtime.
-	Add(context.Context, Task) error
+	Add(ctx context.Context, task Task) error
 	// Delete remove a task.
-	Delete(context.Context, string)
+	Delete(ctx context.Context, taskID string)
 }

+ 17 - 17
vendor/github.com/containerd/containerd/runtime/task.go

@@ -36,19 +36,19 @@ type Process interface {
 	// ID of the process
 	ID() string
 	// State returns the process state
-	State(context.Context) (State, error)
+	State(ctx context.Context) (State, error)
 	// Kill signals a container
-	Kill(context.Context, uint32, bool) error
-	// Pty resizes the processes pty/console
-	ResizePty(context.Context, ConsoleSize) error
-	// CloseStdin closes the processes stdin
-	CloseIO(context.Context) error
+	Kill(ctx context.Context, signal uint32, all bool) error
+	// ResizePty resizes the processes pty/console
+	ResizePty(ctx context.Context, size ConsoleSize) error
+	// CloseIO closes the processes IO
+	CloseIO(ctx context.Context) error
 	// Start the container's user defined process
-	Start(context.Context) error
+	Start(ctx context.Context) error
 	// Wait for the process to exit
-	Wait(context.Context) (*Exit, error)
+	Wait(ctx context.Context) (*Exit, error)
 	// Delete deletes the process
-	Delete(context.Context) (*Exit, error)
+	Delete(ctx context.Context) (*Exit, error)
 }
 
 // Task is the runtime object for an executing container
@@ -60,21 +60,21 @@ type Task interface {
 	// Namespace that the task exists in
 	Namespace() string
 	// Pause pauses the container process
-	Pause(context.Context) error
+	Pause(ctx context.Context) error
 	// Resume unpauses the container process
-	Resume(context.Context) error
+	Resume(ctx context.Context) error
 	// Exec adds a process into the container
-	Exec(context.Context, string, ExecOpts) (Process, error)
+	Exec(ctx context.Context, id string, opts ExecOpts) (Process, error)
 	// Pids returns all pids
-	Pids(context.Context) ([]ProcessInfo, error)
+	Pids(ctx context.Context) ([]ProcessInfo, error)
 	// Checkpoint checkpoints a container to an image with live system data
-	Checkpoint(context.Context, string, *types.Any) error
+	Checkpoint(ctx context.Context, path string, opts *types.Any) error
 	// Update sets the provided resources to a running task
-	Update(context.Context, *types.Any, map[string]string) error
+	Update(ctx context.Context, resources *types.Any, annotations map[string]string) error
 	// Process returns a process within the task for the provided id
-	Process(context.Context, string) (Process, error)
+	Process(ctx context.Context, id string) (Process, error)
 	// Stats returns runtime specific metrics for a task
-	Stats(context.Context) (*types.Any, error)
+	Stats(ctx context.Context) (*types.Any, error)
 }
 
 // ExecOpts provides additional options for additional processes running in a task

+ 1 - 1
vendor/github.com/containerd/containerd/runtime/v1/linux/runtime.go

@@ -219,7 +219,7 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts
 				namespaces.WithNamespace(context.TODO(), namespace), cleanupTimeout)
 			defer deferCancel()
 			if kerr := s.KillShim(deferCtx); kerr != nil {
-				log.G(ctx).WithError(err).Error("failed to kill shim")
+				log.G(ctx).WithError(kerr).Error("failed to kill shim")
 			}
 		}
 	}()

+ 1 - 4
vendor/github.com/containerd/containerd/runtime/v1/shim/client/client.go

@@ -182,10 +182,7 @@ func setupOOMScore(shimPid int) error {
 		return errors.Wrap(err, "get daemon OOM score")
 	}
 	shimScore := score + 1
-	if shimScore > sys.OOMScoreAdjMax {
-		shimScore = sys.OOMScoreAdjMax
-	}
-	if err := sys.SetOOMScore(shimPid, shimScore); err != nil {
+	if err := sys.AdjustOOMScore(shimPid, shimScore); err != nil {
 		return errors.Wrap(err, "set shim OOM score")
 	}
 	return nil

+ 3 - 0
vendor/github.com/containerd/containerd/runtime/v1/shim/service.go

@@ -397,6 +397,9 @@ func (s *Service) ListPids(ctx context.Context, r *shimapi.ListPidsRequest) (*sh
 		return nil, errdefs.ToGRPC(err)
 	}
 	var processes []*task.ProcessInfo
+
+	s.mu.Lock()
+	defer s.mu.Unlock()
 	for _, pid := range pids {
 		pInfo := task.ProcessInfo{
 			Pid: pid,

+ 3 - 3
vendor/github.com/containerd/containerd/runtime/v1/shim/service_linux.go

@@ -26,7 +26,7 @@ import (
 
 	"github.com/containerd/console"
 	"github.com/containerd/containerd/namespaces"
-	"github.com/containerd/containerd/runtime"
+	"github.com/containerd/containerd/pkg/process"
 	"github.com/containerd/fifo"
 	"github.com/pkg/errors"
 )
@@ -75,14 +75,14 @@ func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console
 			return nil, err
 		}
 
-		cmd := runtime.NewBinaryCmd(uri, id, ns)
+		cmd := process.NewBinaryCmd(uri, id, ns)
 
 		// In case of unexpected errors during logging binary start, close open pipes
 		var filesToClose []*os.File
 
 		defer func() {
 			if retErr != nil {
-				runtime.CloseFiles(filesToClose...)
+				process.CloseFiles(filesToClose...)
 			}
 		}()
 

+ 3 - 4
vendor/github.com/containerd/containerd/runtime/v1/shim/service_unix.go

@@ -28,7 +28,7 @@ import (
 
 	"github.com/containerd/console"
 	"github.com/containerd/containerd/namespaces"
-	"github.com/containerd/containerd/runtime"
+	"github.com/containerd/containerd/pkg/process"
 	"github.com/containerd/fifo"
 	"github.com/pkg/errors"
 )
@@ -63,15 +63,14 @@ func (p *unixPlatform) CopyConsole(ctx context.Context, console console.Console,
 		if err != nil {
 			return nil, err
 		}
-
-		cmd := runtime.NewBinaryCmd(uri, id, ns)
+		cmd := process.NewBinaryCmd(uri, id, ns)
 
 		// In case of unexpected errors during logging binary start, close open pipes
 		var filesToClose []*os.File
 
 		defer func() {
 			if retErr != nil {
-				runtime.CloseFiles(filesToClose...)
+				process.CloseFiles(filesToClose...)
 			}
 		}()
 

+ 2 - 0
vendor/github.com/containerd/containerd/services/introspection/introspection.go

@@ -25,6 +25,7 @@ import (
 	ptypes "github.com/gogo/protobuf/types"
 )
 
+// Service defines the instrospection service interface
 type Service interface {
 	Plugins(context.Context, []string) (*api.PluginsResponse, error)
 	Server(context.Context, *ptypes.Empty) (*api.ServerResponse, error)
@@ -36,6 +37,7 @@ type introspectionRemote struct {
 
 var _ = (Service)(&introspectionRemote{})
 
+// NewIntrospectionServiceFromClient creates a new introspection service from an API client
 func NewIntrospectionServiceFromClient(c api.IntrospectionClient) Service {
 	return &introspectionRemote{client: c}
 }

+ 4 - 0
vendor/github.com/containerd/containerd/services/introspection/local.go

@@ -54,6 +54,7 @@ func init() {
 	})
 }
 
+// Local is a local implementation of the introspection service
 type Local struct {
 	mu      sync.Mutex
 	plugins []api.Plugin
@@ -62,6 +63,7 @@ type Local struct {
 
 var _ = (api.IntrospectionClient)(&Local{})
 
+// UpdateLocal updates the local introspection service
 func (l *Local) UpdateLocal(root string, plugins []api.Plugin) {
 	l.mu.Lock()
 	defer l.mu.Unlock()
@@ -69,6 +71,7 @@ func (l *Local) UpdateLocal(root string, plugins []api.Plugin) {
 	l.plugins = plugins
 }
 
+// Plugins returns the locally defined plugins
 func (l *Local) Plugins(ctx context.Context, req *api.PluginsRequest, _ ...grpc.CallOption) (*api.PluginsResponse, error) {
 	filter, err := filters.ParseAll(req.Filters...)
 	if err != nil {
@@ -96,6 +99,7 @@ func (l *Local) getPlugins() []api.Plugin {
 	return l.plugins
 }
 
+// Server returns the local server information
 func (l *Local) Server(ctx context.Context, _ *ptypes.Empty, _ ...grpc.CallOption) (*api.ServerResponse, error) {
 	u, err := l.getUUID()
 	if err != nil {

+ 20 - 7
vendor/github.com/containerd/containerd/services/server/config/config.go

@@ -20,9 +20,10 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/BurntSushi/toml"
 	"github.com/imdario/mergo"
+	"github.com/pelletier/go-toml"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 
 	"github.com/containerd/containerd/errdefs"
 	"github.com/containerd/containerd/plugin"
@@ -55,7 +56,7 @@ type Config struct {
 	// required plugin doesn't exist or fails to be initialized or started.
 	RequiredPlugins []string `toml:"required_plugins"`
 	// Plugins provides plugin specific configuration for the initialization of a plugin
-	Plugins map[string]toml.Primitive `toml:"plugins"`
+	Plugins map[string]toml.Tree `toml:"plugins"`
 	// OOMScore adjust the containerd's oom score
 	OOMScore int `toml:"oom_score"`
 	// Cgroup specifies cgroup information for the containerd daemon process
@@ -94,7 +95,9 @@ func (c *Config) GetVersion() int {
 
 // ValidateV2 validates the config for a v2 file
 func (c *Config) ValidateV2() error {
-	if c.GetVersion() != 2 {
+	version := c.GetVersion()
+	if version < 2 {
+		logrus.Warnf("deprecated version : `%d`, please switch to version `2`", version)
 		return nil
 	}
 	for _, p := range c.DisabledPlugins {
@@ -209,7 +212,7 @@ func (c *Config) Decode(p *plugin.Registration) (interface{}, error) {
 	if !ok {
 		return p.Config, nil
 	}
-	if err := toml.PrimitiveDecode(data, p.Config); err != nil {
+	if err := data.Unmarshal(p.Config); err != nil {
 		return nil, err
 	}
 	return p.Config, nil
@@ -258,16 +261,26 @@ func LoadConfig(path string, out *Config) error {
 		out.Imports = append(out.Imports, path)
 	}
 
-	return out.ValidateV2()
+	err := out.ValidateV2()
+	if err != nil {
+		return errors.Wrapf(err, "failed to load TOML from %s", path)
+	}
+	return nil
 }
 
 // loadConfigFile decodes a TOML file at the given path
 func loadConfigFile(path string) (*Config, error) {
 	config := &Config{}
-	_, err := toml.DecodeFile(path, &config)
+
+	file, err := toml.LoadFile(path)
 	if err != nil {
-		return nil, err
+		return nil, errors.Wrapf(err, "failed to load TOML: %s", path)
+	}
+
+	if err := file.Unmarshal(config); err != nil {
+		return nil, errors.Wrap(err, "failed to unmarshal TOML")
 	}
+
 	return config, nil
 }
 

+ 2 - 1
vendor/github.com/containerd/containerd/snapshots/snapshotter.go

@@ -28,7 +28,8 @@ import (
 const (
 	// UnpackKeyPrefix is the beginning of the key format used for snapshots that will have
 	// image content unpacked into them.
-	UnpackKeyPrefix       = "extract"
+	UnpackKeyPrefix = "extract"
+	// UnpackKeyFormat is the format for the snapshotter keys used for extraction
 	UnpackKeyFormat       = UnpackKeyPrefix + "-%s %s"
 	inheritedLabelsPrefix = "containerd.io/snapshot/"
 	labelSnapshotRef      = "containerd.io/snapshot.ref"

+ 0 - 35
vendor/github.com/containerd/containerd/sys/filesys.go

@@ -1,35 +0,0 @@
-/*
-   Copyright The containerd Authors.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-*/
-
-package sys
-
-import "os"
-
-// IsFifo checks if a file is a (named pipe) fifo
-// if the file does not exist then it returns false
-func IsFifo(path string) (bool, error) {
-	stat, err := os.Stat(path)
-	if err != nil {
-		if os.IsNotExist(err) {
-			return false, nil
-		}
-		return false, err
-	}
-	if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
-		return true, nil
-	}
-	return false, nil
-}

+ 66 - 4
vendor/github.com/containerd/containerd/sys/filesys_windows.go

@@ -22,11 +22,14 @@ import (
 	"os"
 	"path/filepath"
 	"regexp"
+	"sort"
+	"strconv"
 	"strings"
 	"syscall"
 	"unsafe"
 
 	"github.com/Microsoft/hcsshim"
+	"github.com/pkg/errors"
 	"golang.org/x/sys/windows"
 )
 
@@ -257,12 +260,71 @@ func windowsOpenSequential(path string, mode int, _ uint32) (fd windows.Handle,
 	return h, e
 }
 
-// ForceRemoveAll is the same as os.RemoveAll, but uses hcsshim.DestroyLayer in order
-// to delete container layers.
+// ForceRemoveAll is the same as os.RemoveAll, but is aware of io.containerd.snapshotter.v1.windows
+// and uses hcsshim to unmount and delete container layers contained therein, in the correct order,
+// when passed a containerd root data directory (i.e. the `--root` directory for containerd).
 func ForceRemoveAll(path string) error {
+	// snapshots/windows/windows.go init()
+	const snapshotPlugin = "io.containerd.snapshotter.v1" + "." + "windows"
+	// snapshots/windows/windows.go NewSnapshotter()
+	snapshotDir := filepath.Join(path, snapshotPlugin, "snapshots")
+	if stat, err := os.Stat(snapshotDir); err == nil && stat.IsDir() {
+		if err := cleanupWCOWLayers(snapshotDir); err != nil {
+			return errors.Wrapf(err, "failed to cleanup WCOW layers in %s", snapshotDir)
+		}
+	}
+
+	return os.RemoveAll(path)
+}
+
+func cleanupWCOWLayers(root string) error {
+	// See snapshots/windows/windows.go getSnapshotDir()
+	var layerNums []int
+	if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
+		if path != root && info.IsDir() {
+			if layerNum, err := strconv.Atoi(filepath.Base(path)); err == nil {
+				layerNums = append(layerNums, layerNum)
+			} else {
+				return err
+			}
+			return filepath.SkipDir
+		}
+
+		return nil
+	}); err != nil {
+		return err
+	}
+
+	sort.Sort(sort.Reverse(sort.IntSlice(layerNums)))
+
+	for _, layerNum := range layerNums {
+		if err := cleanupWCOWLayer(filepath.Join(root, strconv.Itoa(layerNum))); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func cleanupWCOWLayer(layerPath string) error {
 	info := hcsshim.DriverInfo{
-		HomeDir: filepath.Dir(path),
+		HomeDir: filepath.Dir(layerPath),
 	}
 
-	return hcsshim.DestroyLayer(info, filepath.Base(path))
+	// ERROR_DEV_NOT_EXIST is returned if the layer is not currently prepared.
+	if err := hcsshim.UnprepareLayer(info, filepath.Base(layerPath)); err != nil {
+		if hcserror, ok := err.(*hcsshim.HcsError); !ok || hcserror.Err != windows.ERROR_DEV_NOT_EXIST {
+			return errors.Wrapf(err, "failed to unprepare %s", layerPath)
+		}
+	}
+
+	if err := hcsshim.DeactivateLayer(info, filepath.Base(layerPath)); err != nil {
+		return errors.Wrapf(err, "failed to deactivate %s", layerPath)
+	}
+
+	if err := hcsshim.DestroyLayer(info, filepath.Base(layerPath)); err != nil {
+		return errors.Wrapf(err, "failed to destroy %s", layerPath)
+	}
+
+	return nil
 }

+ 29 - 7
vendor/github.com/containerd/containerd/sys/oom_unix.go → vendor/github.com/containerd/containerd/sys/oom_linux.go

@@ -1,5 +1,3 @@
-// +build !windows
-
 /*
    Copyright The containerd Authors.
 
@@ -24,17 +22,34 @@ import (
 	"os"
 	"strconv"
 	"strings"
+
+	"github.com/containerd/containerd/pkg/userns"
+	"golang.org/x/sys/unix"
 )
 
 const (
-	// OOMScoreMaxKillable is the maximum score keeping the process killable by the oom killer
-	OOMScoreMaxKillable = -999
-	// OOMScoreAdjMax is from OOM_SCORE_ADJ_MAX https://github.com/torvalds/linux/blob/master/include/uapi/linux/oom.h
+	// OOMScoreAdjMin is from OOM_SCORE_ADJ_MIN https://github.com/torvalds/linux/blob/v5.10/include/uapi/linux/oom.h#L9
+	OOMScoreAdjMin = -1000
+	// OOMScoreAdjMax is from OOM_SCORE_ADJ_MAX https://github.com/torvalds/linux/blob/v5.10/include/uapi/linux/oom.h#L10
 	OOMScoreAdjMax = 1000
 )
 
+// AdjustOOMScore sets the oom score for the provided pid. If the provided score
+// is out of range (-1000 - 1000), it is clipped to the min/max value.
+func AdjustOOMScore(pid, score int) error {
+	if score > OOMScoreAdjMax {
+		score = OOMScoreAdjMax
+	} else if score < OOMScoreAdjMin {
+		score = OOMScoreAdjMin
+	}
+	return SetOOMScore(pid, score)
+}
+
 // SetOOMScore sets the oom score for the provided pid
 func SetOOMScore(pid, score int) error {
+	if score > OOMScoreAdjMax || score < OOMScoreAdjMin {
+		return fmt.Errorf("value out of range (%d): OOM score must be between %d and %d", score, OOMScoreAdjMin, OOMScoreAdjMax)
+	}
 	path := fmt.Sprintf("/proc/%d/oom_score_adj", pid)
 	f, err := os.OpenFile(path, os.O_WRONLY, 0)
 	if err != nil {
@@ -42,7 +57,7 @@ func SetOOMScore(pid, score int) error {
 	}
 	defer f.Close()
 	if _, err = f.WriteString(strconv.Itoa(score)); err != nil {
-		if os.IsPermission(err) && (RunningInUserNS() || RunningUnprivileged()) {
+		if os.IsPermission(err) && (!runningPrivileged() || userns.RunningInUserNS()) {
 			return nil
 		}
 		return err
@@ -50,7 +65,8 @@ func SetOOMScore(pid, score int) error {
 	return nil
 }
 
-// GetOOMScoreAdj gets the oom score for a process
+// GetOOMScoreAdj gets the oom score for a process. It returns 0 (zero) if either
+// no oom score is set, or a sore is set to 0.
 func GetOOMScoreAdj(pid int) (int, error) {
 	path := fmt.Sprintf("/proc/%d/oom_score_adj", pid)
 	data, err := ioutil.ReadFile(path)
@@ -59,3 +75,9 @@ func GetOOMScoreAdj(pid int) (int, error) {
 	}
 	return strconv.Atoi(strings.TrimSpace(string(data)))
 }
+
+// runningPrivileged returns true if the effective user ID of the
+// calling process is 0
+func runningPrivileged() bool {
+	return unix.Geteuid() == 0
+}

+ 13 - 1
vendor/github.com/containerd/containerd/sys/oom_windows.go → vendor/github.com/containerd/containerd/sys/oom_unsupported.go

@@ -1,3 +1,5 @@
+// +build !linux
+
 /*
    Copyright The containerd Authors.
 
@@ -17,10 +19,20 @@
 package sys
 
 const (
-	// OOMScoreAdjMax is not implemented on Windows
+	// OOMScoreMaxKillable is not implemented on non Linux
+	OOMScoreMaxKillable = 0
+	// OOMScoreAdjMax is not implemented on non Linux
 	OOMScoreAdjMax = 0
 )
 
+// AdjustOOMScore sets the oom score for the provided pid. If the provided score
+// is out of range (-1000 - 1000), it is clipped to the min/max value.
+//
+// Not implemented on Windows
+func AdjustOOMScore(pid, score int) error {
+	return nil
+}
+
 // SetOOMScore sets the oom score for the process
 //
 // Not implemented on Windows

+ 4 - 14
vendor/github.com/containerd/containerd/sys/env.go → vendor/github.com/containerd/containerd/sys/userns_deprecated.go

@@ -1,5 +1,3 @@
-// +build !windows
-
 /*
    Copyright The containerd Authors.
 
@@ -18,16 +16,8 @@
 
 package sys
 
-import "golang.org/x/sys/unix"
-
-// RunningPrivileged returns true if the effective user ID of the
-// calling process is 0
-func RunningPrivileged() bool {
-	return unix.Geteuid() == 0
-}
+import "github.com/containerd/containerd/pkg/userns"
 
-// RunningUnprivileged returns true if the effective user ID of the
-// calling process is not 0
-func RunningUnprivileged() bool {
-	return !RunningPrivileged()
-}
+// RunningInUserNS detects whether we are currently running in a user namespace.
+// Deprecated: use github.com/containerd/containerd/pkg/userns.RunningInUserNS instead.
+var RunningInUserNS = userns.RunningInUserNS

+ 12 - 3
vendor/github.com/containerd/containerd/task.go

@@ -451,11 +451,20 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Imag
 		}
 		request.Options = any
 	}
-	// make sure we pause it and resume after all other filesystem operations are completed
-	if err := t.Pause(ctx); err != nil {
+
+	status, err := t.Status(ctx)
+	if err != nil {
 		return nil, err
 	}
-	defer t.Resume(ctx)
+
+	if status.Status != Paused {
+		// make sure we pause it and resume after all other filesystem operations are completed
+		if err := t.Pause(ctx); err != nil {
+			return nil, err
+		}
+		defer t.Resume(ctx)
+	}
+
 	index := v1.Index{
 		Versioned: is.Versioned{
 			SchemaVersion: 2,

+ 1 - 1
vendor/github.com/containerd/containerd/version/version.go

@@ -23,7 +23,7 @@ var (
 	Package = "github.com/containerd/containerd"
 
 	// Version holds the complete version number. Filled in at linking time.
-	Version = "1.5.0-beta.0+unknown"
+	Version = "1.5.2+unknown"
 
 	// Revision is filled with the VCS (e.g. git) revision being used to build
 	// the program at linking time.