Browse Source

Merge pull request #44964 from laurazard/c8d-docker-diff

containerd integration: `docker diff`
Sebastiaan van Stijn 2 years ago
parent
commit
f7b6aefe0e
42 changed files with 462 additions and 72 deletions
  1. 2 1
      .github/workflows/buildkit.yml
  2. 1 1
      api/server/router/container/backend.go
  3. 1 1
      api/server/router/container/container_routes.go
  4. 4 11
      daemon/changes.go
  5. 69 0
      daemon/containerd/image_changes.go
  6. 2 0
      daemon/image_service.go
  7. 19 0
      daemon/images/image_changes.go
  8. 2 2
      vendor.mod
  9. 4 4
      vendor.sum
  10. 35 7
      vendor/github.com/containerd/containerd/.golangci.yml
  11. 1 1
      vendor/github.com/containerd/containerd/Vagrantfile
  12. 1 1
      vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go
  13. 1 1
      vendor/github.com/containerd/containerd/api/services/containers/v1/containers.proto
  14. 1 1
      vendor/github.com/containerd/containerd/api/services/content/v1/content.proto
  15. 1 1
      vendor/github.com/containerd/containerd/api/services/images/v1/images.pb.go
  16. 1 1
      vendor/github.com/containerd/containerd/api/services/images/v1/images.proto
  17. 1 1
      vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.pb.go
  18. 1 1
      vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.proto
  19. 1 1
      vendor/github.com/containerd/containerd/api/services/snapshots/v1/snapshots.pb.go
  20. 1 1
      vendor/github.com/containerd/containerd/api/services/snapshots/v1/snapshots.proto
  21. 3 1
      vendor/github.com/containerd/containerd/archive/tar.go
  22. 1 2
      vendor/github.com/containerd/containerd/archive/tar_unix.go
  23. 82 0
      vendor/github.com/containerd/containerd/archive/tarheader/tarheader.go
  24. 59 0
      vendor/github.com/containerd/containerd/archive/tarheader/tarheader_unix.go
  25. 1 0
      vendor/github.com/containerd/containerd/containerstore.go
  26. 2 1
      vendor/github.com/containerd/containerd/content/local/store.go
  27. 1 1
      vendor/github.com/containerd/containerd/diff/walking/differ.go
  28. 1 0
      vendor/github.com/containerd/containerd/image_store.go
  29. 1 1
      vendor/github.com/containerd/containerd/images/converter/default.go
  30. 1 0
      vendor/github.com/containerd/containerd/metadata/boltutil/helpers.go
  31. 47 0
      vendor/github.com/containerd/containerd/mount/mount.go
  32. 7 0
      vendor/github.com/containerd/containerd/mount/temp.go
  33. 69 7
      vendor/github.com/containerd/containerd/oci/spec_opts.go
  34. 5 1
      vendor/github.com/containerd/containerd/oci/spec_opts_linux.go
  35. 1 7
      vendor/github.com/containerd/containerd/oci/spec_opts_nonlinux.go
  36. 4 0
      vendor/github.com/containerd/containerd/oci/spec_opts_unix.go
  37. 11 0
      vendor/github.com/containerd/containerd/oci/spec_opts_windows.go
  38. 2 2
      vendor/github.com/containerd/containerd/oci/utils_unix.go
  39. 1 1
      vendor/github.com/containerd/containerd/pkg/runtimeoptions/v1/doc.go
  40. 1 1
      vendor/github.com/containerd/containerd/reference/docker/reference.go
  41. 10 8
      vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go
  42. 3 2
      vendor/modules.txt

+ 2 - 1
.github/workflows/buildkit.yml

@@ -119,5 +119,6 @@ jobs:
           TEST_DOCKERD: "1"
           TEST_DOCKERD_BINARY: "./build/moby/dockerd"
           TESTPKGS: "./${{ matrix.pkg }}"
-          TESTFLAGS: "-v --parallel=1 --timeout=30m --run=//worker=${{ matrix.worker }}$"
+          # Skip buildkit tests checking the digest (see https://github.com/moby/buildkit/pull/3736)
+          TESTFLAGS: "-v --parallel=1 --timeout=30m --run=/^Test([^R]|.[^e]|..[^p]|...[^r]|....[^o]|.....[^S])/worker=${{ matrix.worker }}$"
         working-directory: buildkit

+ 1 - 1
api/server/router/container/backend.go

@@ -48,7 +48,7 @@ type stateBackend interface {
 
 // monitorBackend includes functions to implement to provide containers monitoring functionality.
 type monitorBackend interface {
-	ContainerChanges(name string) ([]archive.Change, error)
+	ContainerChanges(ctx context.Context, name string) ([]archive.Change, error)
 	ContainerInspect(ctx context.Context, name string, size bool, version string) (interface{}, error)
 	ContainerLogs(ctx context.Context, name string, config *types.ContainerLogsOptions) (msgs <-chan *backend.LogMessage, tty bool, err error)
 	ContainerStats(ctx context.Context, name string, config *backend.ContainerStatsConfig) error

+ 1 - 1
api/server/router/container/container_routes.go

@@ -401,7 +401,7 @@ func (s *containerRouter) postContainersWait(ctx context.Context, w http.Respons
 }
 
 func (s *containerRouter) getContainersChanges(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
-	changes, err := s.backend.ContainerChanges(vars["name"])
+	changes, err := s.backend.ContainerChanges(ctx, vars["name"])
 	if err != nil {
 		return err
 	}

+ 4 - 11
daemon/changes.go

@@ -1,16 +1,17 @@
 package daemon // import "github.com/docker/docker/daemon"
 
 import (
+	"context"
 	"errors"
 	"time"
 
-	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/pkg/archive"
 )
 
 // ContainerChanges returns a list of container fs changes
-func (daemon *Daemon) ContainerChanges(name string) ([]archive.Change, error) {
+func (daemon *Daemon) ContainerChanges(ctx context.Context, name string) ([]archive.Change, error) {
 	start := time.Now()
+
 	container, err := daemon.GetContainer(name)
 	if err != nil {
 		return nil, err
@@ -20,15 +21,7 @@ func (daemon *Daemon) ContainerChanges(name string) ([]archive.Change, error) {
 		return nil, errors.New("Windows does not support diff of a running container")
 	}
 
-	if daemon.UsesSnapshotter() {
-		return nil, errdefs.NotImplemented(errors.New("not implemented"))
-	}
-	container.Lock()
-	defer container.Unlock()
-	if container.RWLayer == nil {
-		return nil, errors.New("RWLayer of container " + name + " is unexpectedly nil")
-	}
-	c, err := container.RWLayer.Changes()
+	c, err := daemon.imageService.Changes(ctx, container)
 	if err != nil {
 		return nil, err
 	}

+ 69 - 0
daemon/containerd/image_changes.go

@@ -0,0 +1,69 @@
+package containerd
+
+import (
+	"context"
+	"encoding/json"
+
+	"github.com/containerd/containerd/content"
+	"github.com/containerd/containerd/mount"
+	"github.com/docker/docker/container"
+	"github.com/docker/docker/pkg/archive"
+	"github.com/google/uuid"
+	"github.com/opencontainers/image-spec/identity"
+	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
+	"github.com/sirupsen/logrus"
+)
+
+func (i *ImageService) Changes(ctx context.Context, container *container.Container) ([]archive.Change, error) {
+	cs := i.client.ContentStore()
+
+	imageManifestBytes, err := content.ReadBlob(ctx, cs, *container.ImageManifest)
+	if err != nil {
+		return nil, err
+	}
+	var manifest ocispec.Manifest
+	if err := json.Unmarshal(imageManifestBytes, &manifest); err != nil {
+		return nil, err
+	}
+
+	imageConfigBytes, err := content.ReadBlob(ctx, cs, manifest.Config)
+	if err != nil {
+		return nil, err
+	}
+	var image ocispec.Image
+	if err := json.Unmarshal(imageConfigBytes, &image); err != nil {
+		return nil, err
+	}
+
+	rnd, err := uuid.NewRandom()
+	if err != nil {
+		return nil, err
+	}
+
+	snapshotter := i.client.SnapshotService(i.snapshotter)
+
+	diffIDs := image.RootFS.DiffIDs
+	parent, err := snapshotter.View(ctx, rnd.String(), identity.ChainID(diffIDs).String())
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		if err := snapshotter.Remove(ctx, rnd.String()); err != nil {
+			logrus.WithError(err).WithField("key", rnd.String()).Warn("remove temporary snapshot")
+		}
+	}()
+
+	mounts, err := snapshotter.Mounts(ctx, container.ID)
+	if err != nil {
+		return nil, err
+	}
+
+	var changes []archive.Change
+	err = mount.WithReadonlyTempMount(ctx, mounts, func(fs string) error {
+		return mount.WithTempMount(ctx, parent, func(root string) error {
+			changes, err = archive.ChangesDirs(fs, root)
+			return err
+		})
+	})
+	return changes, err
+}

+ 2 - 0
daemon/image_service.go

@@ -16,6 +16,7 @@ import (
 	"github.com/docker/docker/daemon/images"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
+	"github.com/docker/docker/pkg/archive"
 	v1 "github.com/opencontainers/image-spec/specs-go/v1"
 )
 
@@ -60,6 +61,7 @@ type ImageService interface {
 	GetContainerLayerSize(ctx context.Context, containerID string) (int64, int64, error)
 	Mount(ctx context.Context, container *container.Container) error
 	Unmount(ctx context.Context, container *container.Container) error
+	Changes(ctx context.Context, container *container.Container) ([]archive.Change, error)
 
 	// Windows specific
 

+ 19 - 0
daemon/images/image_changes.go

@@ -0,0 +1,19 @@
+package images
+
+import (
+	"context"
+	"errors"
+
+	"github.com/docker/docker/container"
+	"github.com/docker/docker/pkg/archive"
+)
+
+func (i *ImageService) Changes(ctx context.Context, container *container.Container) ([]archive.Change, error) {
+	container.Lock()
+	defer container.Unlock()
+
+	if container.RWLayer == nil {
+		return nil, errors.New("RWLayer of container " + container.Name + " is unexpectedly nil")
+	}
+	return container.RWLayer.Changes()
+}

+ 2 - 2
vendor.mod

@@ -14,7 +14,7 @@ require (
 	github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1
 	github.com/Graylog2/go-gelf v0.0.0-20191017102106-1550ee647df0
 	github.com/Microsoft/go-winio v0.5.2
-	github.com/Microsoft/hcsshim v0.9.7
+	github.com/Microsoft/hcsshim v0.9.8
 	github.com/RackSec/srslog v0.0.0-20180709174129-a4725f04ec91
 	github.com/aws/aws-sdk-go-v2 v1.16.13
 	github.com/aws/aws-sdk-go-v2/config v1.17.4
@@ -25,7 +25,7 @@ require (
 	github.com/bsphere/le_go v0.0.0-20200109081728-fc06dab2caa8
 	github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5
 	github.com/containerd/cgroups/v3 v3.0.1
-	github.com/containerd/containerd v1.6.19
+	github.com/containerd/containerd v1.6.20-0.20230322235238-de33abf0547c
 	github.com/containerd/continuity v0.3.0
 	github.com/containerd/fifo v1.1.0
 	github.com/containerd/typeurl/v2 v2.1.0

+ 4 - 4
vendor.sum

@@ -164,8 +164,8 @@ github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2
 github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
 github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
 github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
-github.com/Microsoft/hcsshim v0.9.7 h1:mKNHW/Xvv1aFH87Jb6ERDzXTJTLPlmzfZ28VBFD/bfg=
-github.com/Microsoft/hcsshim v0.9.7/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
+github.com/Microsoft/hcsshim v0.9.8 h1:lf7xxK2+Ikbj9sVf2QZsouGjRjEp2STj1yDHgoVtU5k=
+github.com/Microsoft/hcsshim v0.9.8/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
 github.com/Microsoft/hcsshim/test v0.0.0-20200826032352-301c83a30e7c/go.mod h1:30A5igQ91GEmhYJF8TaRP79pMBOYynRsyOByfVV0dU4=
 github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
 github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
@@ -372,8 +372,8 @@ github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09Zvgq
 github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
 github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
 github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
-github.com/containerd/containerd v1.6.19 h1:F0qgQPrG0P2JPgwpxWxYavrVeXAG0ezUIB9Z/4FTUAU=
-github.com/containerd/containerd v1.6.19/go.mod h1:HZCDMn4v/Xl2579/MvtOC2M206i+JJ6VxFWU/NetrGY=
+github.com/containerd/containerd v1.6.20-0.20230322235238-de33abf0547c h1:N1iR6/12eEH/ysnTXGJSCvxIM0zYVfM2d4F6HAd59wA=
+github.com/containerd/containerd v1.6.20-0.20230322235238-de33abf0547c/go.mod h1:VTE2dTyaPd3Zsyd6pXBeJsJQfrJV+tmVLTN1bvntKkA=
 github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
 github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
 github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=

+ 35 - 7
vendor/github.com/containerd/containerd/.golangci.yml

@@ -1,27 +1,55 @@
 linters:
   enable:
-    - structcheck
-    - varcheck
-    - staticcheck
-    - unconvert
+    - exportloopref # Checks for pointers to enclosing loop variables
     - gofmt
     - goimports
-    - revive
+    - gosec
     - ineffassign
-    - vet
-    - unused
     - misspell
+    - nolintlint
+    - revive
+    - staticcheck
+    - tenv # Detects using os.Setenv instead of t.Setenv since Go 1.17
+    - unconvert
+    - unused
+    - vet
+    - dupword # Checks for duplicate words in the source code
   disable:
     - errcheck
 
 issues:
   include:
     - EXC0002
+  max-issues-per-linter: 0
+  max-same-issues: 0
+
+  # Only using / doesn't work due to https://github.com/golangci/golangci-lint/issues/1398.
+  exclude-rules:
+    - path: 'archive[\\/]tarheader[\\/]'
+      # conversion is necessary on Linux, unnecessary on macOS
+      text: "unnecessary conversion"
+
+linters-settings:
+  gosec:
+    # The following issues surfaced when `gosec` linter
+    # was enabled. They are temporarily excluded to unblock
+    # the existing workflow, but still to be addressed by
+    # future works.
+    excludes:
+      - G204
+      - G305
+      - G306
+      - G402
+      - G404
 
 run:
   timeout: 8m
   skip-dirs:
     - api
+    - cluster
     - design
     - docs
     - docs/man
+    - releases
+    - reports
+    - test # e2e scripts

+ 1 - 1
vendor/github.com/containerd/containerd/Vagrantfile

@@ -93,7 +93,7 @@ EOF
   config.vm.provision "install-golang", type: "shell", run: "once" do |sh|
     sh.upload_path = "/tmp/vagrant-install-golang"
     sh.env = {
-        'GO_VERSION': ENV['GO_VERSION'] || "1.19.6",
+        'GO_VERSION': ENV['GO_VERSION'] || "1.19.7",
     }
     sh.inline = <<~SHELL
         #!/usr/bin/env bash

+ 1 - 1
vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go

@@ -246,7 +246,7 @@ type ListContainersRequest struct {
 	// filters. Expanded, containers that match the following will be
 	// returned:
 	//
-	//   filters[0] or filters[1] or ... or filters[n-1] or filters[n]
+	//	filters[0] or filters[1] or ... or filters[n-1] or filters[n]
 	//
 	// If filters is zero-length or nil, all items will be returned.
 	Filters              []string `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"`

+ 1 - 1
vendor/github.com/containerd/containerd/api/services/containers/v1/containers.proto

@@ -132,7 +132,7 @@ message ListContainersRequest {
 	// filters. Expanded, containers that match the following will be
 	// returned:
 	//
-	//   filters[0] or filters[1] or ... or filters[n-1] or filters[n]
+	//	filters[0] or filters[1] or ... or filters[n-1] or filters[n]
 	//
 	// If filters is zero-length or nil, all items will be returned.
 	repeated string filters = 1;

+ 1 - 1
vendor/github.com/containerd/containerd/api/services/content/v1/content.proto

@@ -141,7 +141,7 @@ message ListContentRequest {
 	// filters. Expanded, containers that match the following will be
 	// returned:
 	//
-	//   filters[0] or filters[1] or ... or filters[n-1] or filters[n]
+	//	filters[0] or filters[1] or ... or filters[n-1] or filters[n]
 	//
 	// If filters is zero-length or nil, all items will be returned.
 	repeated string filters = 1;

+ 1 - 1
vendor/github.com/containerd/containerd/api/services/images/v1/images.pb.go

@@ -336,7 +336,7 @@ type ListImagesRequest struct {
 	// filters. Expanded, images that match the following will be
 	// returned:
 	//
-	//   filters[0] or filters[1] or ... or filters[n-1] or filters[n]
+	//	filters[0] or filters[1] or ... or filters[n-1] or filters[n]
 	//
 	// If filters is zero-length or nil, all items will be returned.
 	Filters              []string `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"`

+ 1 - 1
vendor/github.com/containerd/containerd/api/services/images/v1/images.proto

@@ -119,7 +119,7 @@ message ListImagesRequest {
 	// filters. Expanded, images that match the following will be
 	// returned:
 	//
-	//   filters[0] or filters[1] or ... or filters[n-1] or filters[n]
+	//	filters[0] or filters[1] or ... or filters[n-1] or filters[n]
 	//
 	// If filters is zero-length or nil, all items will be returned.
 	repeated string filters = 1;

+ 1 - 1
vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.pb.go

@@ -115,7 +115,7 @@ type PluginsRequest struct {
 	// filters. Expanded, plugins that match the following will be
 	// returned:
 	//
-	//   filters[0] or filters[1] or ... or filters[n-1] or filters[n]
+	//	filters[0] or filters[1] or ... or filters[n-1] or filters[n]
 	//
 	// If filters is zero-length or nil, all items will be returned.
 	Filters              []string `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"`

+ 1 - 1
vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.proto

@@ -89,7 +89,7 @@ message PluginsRequest {
 	// filters. Expanded, plugins that match the following will be
 	// returned:
 	//
-	//   filters[0] or filters[1] or ... or filters[n-1] or filters[n]
+	//	filters[0] or filters[1] or ... or filters[n-1] or filters[n]
 	//
 	// If filters is zero-length or nil, all items will be returned.
 	repeated string filters = 1;

+ 1 - 1
vendor/github.com/containerd/containerd/api/services/snapshots/v1/snapshots.pb.go

@@ -620,7 +620,7 @@ type ListSnapshotsRequest struct {
 	// filters. Expanded, images that match the following will be
 	// returned:
 	//
-	//   filters[0] or filters[1] or ... or filters[n-1] or filters[n]
+	//	filters[0] or filters[1] or ... or filters[n-1] or filters[n]
 	//
 	// If filters is zero-length or nil, all items will be returned.
 	Filters              []string `protobuf:"bytes,2,rep,name=filters,proto3" json:"filters,omitempty"`

+ 1 - 1
vendor/github.com/containerd/containerd/api/services/snapshots/v1/snapshots.proto

@@ -158,7 +158,7 @@ message ListSnapshotsRequest{
 	// filters. Expanded, images that match the following will be
 	// returned:
 	//
-	//   filters[0] or filters[1] or ... or filters[n-1] or filters[n]
+	//	filters[0] or filters[1] or ... or filters[n-1] or filters[n]
 	//
 	// If filters is zero-length or nil, all items will be returned.
 	repeated string filters = 2;

+ 3 - 1
vendor/github.com/containerd/containerd/archive/tar.go

@@ -30,6 +30,7 @@ import (
 	"syscall"
 	"time"
 
+	"github.com/containerd/containerd/archive/tarheader"
 	"github.com/containerd/containerd/log"
 	"github.com/containerd/containerd/pkg/userns"
 	"github.com/containerd/continuity/fs"
@@ -554,7 +555,8 @@ func (cw *ChangeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, e
 			}
 		}
 
-		hdr, err := tar.FileInfoHeader(f, link)
+		// Use FileInfoHeaderNoLookups to avoid propagating user names and group names from the host
+		hdr, err := tarheader.FileInfoHeaderNoLookups(f, link)
 		if err != nil {
 			return err
 		}

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

@@ -62,8 +62,7 @@ func setHeaderForSpecialDevice(hdr *tar.Header, name string, fi os.FileInfo) err
 		return errors.New("unsupported stat type")
 	}
 
-	// Rdev is int32 on darwin/bsd, int64 on linux/solaris
-	rdev := uint64(s.Rdev) //nolint:unconvert
+	rdev := uint64(s.Rdev) //nolint:nolintlint,unconvert // rdev is int32 on darwin/bsd, int64 on linux/solaris
 
 	// Currently go does not fill in the major/minors
 	if s.Mode&syscall.S_IFBLK != 0 ||

+ 82 - 0
vendor/github.com/containerd/containerd/archive/tarheader/tarheader.go

@@ -0,0 +1,82 @@
+/*
+   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.
+*/
+
+/*
+   Portions from https://github.com/moby/moby/blob/v23.0.1/pkg/archive/archive.go#L419-L464
+   Copyright (C) Docker/Moby authors.
+   Licensed under the Apache License, Version 2.0
+   NOTICE: https://github.com/moby/moby/blob/v23.0.1/NOTICE
+*/
+
+package tarheader
+
+import (
+	"archive/tar"
+	"os"
+)
+
+// nosysFileInfo hides the system-dependent info of the wrapped FileInfo to
+// prevent tar.FileInfoHeader from introspecting it and potentially calling into
+// glibc.
+//
+// From https://github.com/moby/moby/blob/v23.0.1/pkg/archive/archive.go#L419-L434 .
+type nosysFileInfo struct {
+	os.FileInfo
+}
+
+func (fi nosysFileInfo) Sys() interface{} {
+	// A Sys value of type *tar.Header is safe as it is system-independent.
+	// The tar.FileInfoHeader function copies the fields into the returned
+	// header without performing any OS lookups.
+	if sys, ok := fi.FileInfo.Sys().(*tar.Header); ok {
+		return sys
+	}
+	return nil
+}
+
+// sysStat, if non-nil, populates hdr from system-dependent fields of fi.
+//
+// From https://github.com/moby/moby/blob/v23.0.1/pkg/archive/archive.go#L436-L437 .
+var sysStat func(fi os.FileInfo, hdr *tar.Header) error
+
+// FileInfoHeaderNoLookups creates a partially-populated tar.Header from fi.
+//
+// Compared to the archive/tar.FileInfoHeader function, this function is safe to
+// call from a chrooted process as it does not populate fields which would
+// require operating system lookups. It behaves identically to
+// tar.FileInfoHeader when fi is a FileInfo value returned from
+// tar.Header.FileInfo().
+//
+// When fi is a FileInfo for a native file, such as returned from os.Stat() and
+// os.Lstat(), the returned Header value differs from one returned from
+// tar.FileInfoHeader in the following ways. The Uname and Gname fields are not
+// set as OS lookups would be required to populate them. The AccessTime and
+// ChangeTime fields are not currently set (not yet implemented) although that
+// is subject to change. Callers which require the AccessTime or ChangeTime
+// fields to be zeroed should explicitly zero them out in the returned Header
+// value to avoid any compatibility issues in the future.
+//
+// From https://github.com/moby/moby/blob/v23.0.1/pkg/archive/archive.go#L439-L464 .
+func FileInfoHeaderNoLookups(fi os.FileInfo, link string) (*tar.Header, error) {
+	hdr, err := tar.FileInfoHeader(nosysFileInfo{fi}, link)
+	if err != nil {
+		return nil, err
+	}
+	if sysStat != nil {
+		return hdr, sysStat(fi, hdr)
+	}
+	return hdr, nil
+}

+ 59 - 0
vendor/github.com/containerd/containerd/archive/tarheader/tarheader_unix.go

@@ -0,0 +1,59 @@
+//go: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.
+*/
+
+/*
+   Portions from https://github.com/moby/moby/blob/v23.0.1/pkg/archive/archive_unix.go#L52-L70
+   Copyright (C) Docker/Moby authors.
+   Licensed under the Apache License, Version 2.0
+   NOTICE: https://github.com/moby/moby/blob/v23.0.1/NOTICE
+*/
+
+package tarheader
+
+import (
+	"archive/tar"
+	"os"
+	"syscall"
+
+	"golang.org/x/sys/unix"
+)
+
+func init() {
+	sysStat = statUnix
+}
+
+// statUnix populates hdr from system-dependent fields of fi without performing
+// any OS lookups.
+// From https://github.com/moby/moby/blob/v23.0.1/pkg/archive/archive_unix.go#L52-L70
+func statUnix(fi os.FileInfo, hdr *tar.Header) error {
+	s, ok := fi.Sys().(*syscall.Stat_t)
+	if !ok {
+		return nil
+	}
+
+	hdr.Uid = int(s.Uid)
+	hdr.Gid = int(s.Gid)
+
+	if s.Mode&unix.S_IFBLK != 0 ||
+		s.Mode&unix.S_IFCHR != 0 {
+		hdr.Devmajor = int64(unix.Major(uint64(s.Rdev)))
+		hdr.Devminor = int64(unix.Minor(uint64(s.Rdev)))
+	}
+
+	return nil
+}

+ 1 - 0
vendor/github.com/containerd/containerd/containerstore.go

@@ -189,6 +189,7 @@ func containersFromProto(containerspb []containersapi.Container) []containers.Co
 	var containers []containers.Container
 
 	for _, container := range containerspb {
+		container := container
 		containers = append(containers, containerFromProto(&container))
 	}
 

+ 2 - 1
vendor/github.com/containerd/containerd/content/local/store.go

@@ -34,7 +34,7 @@ import (
 	"github.com/containerd/containerd/log"
 	"github.com/sirupsen/logrus"
 
-	digest "github.com/opencontainers/go-digest"
+	"github.com/opencontainers/go-digest"
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 )
 
@@ -505,6 +505,7 @@ func (s *store) resumeStatus(ref string, total int64, digester digest.Digester)
 		return status, fmt.Errorf("provided total differs from status: %v != %v", total, status.Total)
 	}
 
+	//nolint:dupword
 	// TODO(stevvooe): slow slow slow!!, send to goroutine or use resumable hashes
 	fp, err := os.Open(data)
 	if err != nil {

+ 1 - 1
vendor/github.com/containerd/containerd/diff/walking/differ.go

@@ -87,7 +87,7 @@ func (s *walkingDiff) Compare(ctx context.Context, lower, upper []mount.Mount, o
 
 	var ocidesc ocispec.Descriptor
 	if err := mount.WithTempMount(ctx, lower, func(lowerRoot string) error {
-		return mount.WithTempMount(ctx, upper, func(upperRoot string) error {
+		return mount.WithReadonlyTempMount(ctx, upper, func(upperRoot string) error {
 			var newReference bool
 			if config.Reference == "" {
 				newReference = true

+ 1 - 0
vendor/github.com/containerd/containerd/image_store.go

@@ -129,6 +129,7 @@ func imagesFromProto(imagespb []imagesapi.Image) []images.Image {
 	var images []images.Image
 
 	for _, image := range imagespb {
+		image := image
 		images = append(images, imageFromProto(&image))
 	}
 

+ 1 - 1
vendor/github.com/containerd/containerd/images/converter/default.go

@@ -132,7 +132,7 @@ func copyDesc(desc ocispec.Descriptor) *ocispec.Descriptor {
 	return &descCopy
 }
 
-// convertLayer converts image image layers if c.layerConvertFunc is set.
+// convertLayer converts image layers if c.layerConvertFunc is set.
 //
 // c.layerConvertFunc can be nil, e.g., for converting Docker media types to OCI ones.
 func (c *defaultConverter) convertLayer(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (*ocispec.Descriptor, error) {

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

@@ -162,6 +162,7 @@ func WriteExtensions(bkt *bolt.Bucket, extensions map[string]types.Any) error {
 	}
 
 	for name, ext := range extensions {
+		ext := ext
 		p, err := proto.Marshal(&ext)
 		if err != nil {
 			return err

+ 47 - 0
vendor/github.com/containerd/containerd/mount/mount.go

@@ -16,6 +16,10 @@
 
 package mount
 
+import (
+	"strings"
+)
+
 // Mount is the lingua franca of containerd. A mount represents a
 // serialized mount syscall. Components either emit or consume mounts.
 type Mount struct {
@@ -38,3 +42,46 @@ func All(mounts []Mount, target string) error {
 	}
 	return nil
 }
+
+// readonlyMounts modifies the received mount options
+// to make them readonly
+func readonlyMounts(mounts []Mount) []Mount {
+	for i, m := range mounts {
+		if m.Type == "overlay" {
+			mounts[i].Options = readonlyOverlay(m.Options)
+			continue
+		}
+		opts := make([]string, 0, len(m.Options))
+		for _, opt := range m.Options {
+			if opt != "rw" && opt != "ro" { // skip `ro` too so we don't append it twice
+				opts = append(opts, opt)
+			}
+		}
+		opts = append(opts, "ro")
+		mounts[i].Options = opts
+	}
+	return mounts
+}
+
+// readonlyOverlay takes mount options for overlay mounts and makes them readonly by
+// removing workdir and upperdir (and appending the upperdir layer to lowerdir) - see:
+// https://www.kernel.org/doc/html/latest/filesystems/overlayfs.html#multiple-lower-layers
+func readonlyOverlay(opt []string) []string {
+	out := make([]string, 0, len(opt))
+	upper := ""
+	for _, o := range opt {
+		if strings.HasPrefix(o, "upperdir=") {
+			upper = strings.TrimPrefix(o, "upperdir=")
+		} else if !strings.HasPrefix(o, "workdir=") {
+			out = append(out, o)
+		}
+	}
+	if upper != "" {
+		for i, o := range out {
+			if strings.HasPrefix(o, "lowerdir=") {
+				out[i] = "lowerdir=" + upper + ":" + strings.TrimPrefix(o, "lowerdir=")
+			}
+		}
+	}
+	return out
+}

+ 7 - 0
vendor/github.com/containerd/containerd/mount/temp.go

@@ -67,6 +67,13 @@ func WithTempMount(ctx context.Context, mounts []Mount, f func(root string) erro
 	return nil
 }
 
+// WithReadonlyTempMount mounts the provided mounts to a temp dir as readonly,
+// and pass the temp dir to f. The mounts are valid during the call to the f.
+// Finally we will unmount and remove the temp dir regardless of the result of f.
+func WithReadonlyTempMount(ctx context.Context, mounts []Mount, f func(root string) error) (err error) {
+	return WithTempMount(ctx, readonlyMounts(mounts), f)
+}
+
 func getTempDir() string {
 	if xdg := os.Getenv("XDG_RUNTIME_DIR"); xdg != "" {
 		return xdg

+ 69 - 7
vendor/github.com/containerd/containerd/oci/spec_opts.go

@@ -76,7 +76,6 @@ func setLinux(s *Spec) {
 	}
 }
 
-// nolint
 func setResources(s *Spec) {
 	if s.Linux != nil {
 		if s.Linux.Resources == nil {
@@ -90,7 +89,7 @@ func setResources(s *Spec) {
 	}
 }
 
-// nolint
+//nolint:nolintlint,unused // not used on all platforms
 func setCPU(s *Spec) {
 	setResources(s)
 	if s.Linux != nil {
@@ -229,6 +228,7 @@ func WithProcessArgs(args ...string) SpecOpts {
 	return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
 		setProcess(s)
 		s.Process.Args = args
+		s.Process.CommandLine = ""
 		return nil
 	}
 }
@@ -358,17 +358,19 @@ func WithImageConfigArgs(image Image, args []string) SpecOpts {
 			return err
 		}
 		var (
-			ociimage v1.Image
-			config   v1.ImageConfig
+			imageConfigBytes []byte
+			ociimage         v1.Image
+			config           v1.ImageConfig
 		)
 		switch ic.MediaType {
 		case v1.MediaTypeImageConfig, images.MediaTypeDockerSchema2Config:
-			p, err := content.ReadBlob(ctx, image.ContentStore(), ic)
+			var err error
+			imageConfigBytes, err = content.ReadBlob(ctx, image.ContentStore(), ic)
 			if err != nil {
 				return err
 			}
 
-			if err := json.Unmarshal(p, &ociimage); err != nil {
+			if err := json.Unmarshal(imageConfigBytes, &ociimage); err != nil {
 				return err
 			}
 			config = ociimage.Config
@@ -404,12 +406,72 @@ func WithImageConfigArgs(image Image, args []string) SpecOpts {
 			// even if there is no specified user in the image config
 			return WithAdditionalGIDs("root")(ctx, client, c, s)
 		} else if s.Windows != nil {
+			// imageExtended is a superset of the oci Image struct that changes
+			// the Config type to be imageConfigExtended in order to add the
+			// ability to deserialize `ArgsEscaped` which is not an OCI field,
+			// but is supported by Docker built images.
+			type imageExtended struct {
+				Config struct {
+					ArgsEscaped bool `json:"ArgsEscaped,omitempty"`
+				}
+			}
+			// Deserialize the extended image format for Windows.
+			var ociImageExtended imageExtended
+			if err := json.Unmarshal(imageConfigBytes, &ociImageExtended); err != nil {
+				return err
+			}
+			argsEscaped := ociImageExtended.Config.ArgsEscaped
+
 			s.Process.Env = replaceOrAppendEnvValues(config.Env, s.Process.Env)
+
+			// To support Docker ArgsEscaped on Windows we need to combine the
+			// image Entrypoint & (Cmd Or User Args) while taking into account
+			// if Docker has already escaped them in the image config. When
+			// Docker sets `ArgsEscaped==true` in the config it has pre-escaped
+			// either Entrypoint or Cmd or both. Cmd should always be treated as
+			// arguments appended to Entrypoint unless:
+			//
+			// 1. Entrypoint does not exist, in which case Cmd[0] is the
+			// executable.
+			//
+			// 2. The user overrides the Cmd with User Args when activating the
+			// container in which case those args should be appended to the
+			// Entrypoint if it exists.
+			//
+			// To effectively do this we need to know if the arguments came from
+			// the user or if the arguments came from the image config when
+			// ArgsEscaped==true. In this case we only want to escape the
+			// additional user args when forming the complete CommandLine. This
+			// is safe in both cases of Entrypoint or Cmd being set because
+			// Docker will always escape them to an array of length one. Thus in
+			// both cases it is the "executable" portion of the command.
+			//
+			// In the case ArgsEscaped==false, Entrypoint or Cmd will contain
+			// any number of entries that are all unescaped and can simply be
+			// combined (potentially overwriting Cmd with User Args if present)
+			// and forwarded the container start as an Args array.
 			cmd := config.Cmd
+			cmdFromImage := true
 			if len(args) > 0 {
 				cmd = args
+				cmdFromImage = false
+			}
+
+			cmd = append(config.Entrypoint, cmd...)
+			if len(cmd) == 0 {
+				return errors.New("no arguments specified")
+			}
+
+			if argsEscaped && (len(config.Entrypoint) > 0 || cmdFromImage) {
+				s.Process.Args = nil
+				s.Process.CommandLine = cmd[0]
+				if len(cmd) > 1 {
+					s.Process.CommandLine += " " + escapeAndCombineArgs(cmd[1:])
+				}
+			} else {
+				s.Process.Args = cmd
+				s.Process.CommandLine = ""
 			}
-			s.Process.Args = append(config.Entrypoint, cmd...)
 
 			s.Process.Cwd = config.WorkingDir
 			s.Process.User = specs.User{

+ 5 - 1
vendor/github.com/containerd/containerd/oci/spec_opts_linux.go

@@ -131,7 +131,7 @@ var WithAllCurrentCapabilities = func(ctx context.Context, client Client, c *con
 	return WithCapabilities(caps)(ctx, client, c, s)
 }
 
-// WithAllKnownCapabilities sets all the the known linux capabilities for the container process
+// WithAllKnownCapabilities sets all 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)
@@ -153,3 +153,7 @@ func WithRdt(closID, l3CacheSchema, memBwSchema string) SpecOpts {
 		return nil
 	}
 }
+
+func escapeAndCombineArgs(args []string) string {
+	panic("not supported")
+}

+ 1 - 7
vendor/github.com/containerd/containerd/oci/spec_opts_nonlinux.go

@@ -28,22 +28,16 @@ import (
 
 // 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
+// WithAllKnownCapabilities sets all the known linux capabilities for the container process
 var WithAllKnownCapabilities = func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
 	return WithCapabilities(nil)(ctx, client, c, s)
 }
 
 // WithCPUShares sets the container's cpu shares
-//
-//nolint:deadcode,unused
 func WithCPUShares(shares uint64) SpecOpts {
 	return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
 		return nil

+ 4 - 0
vendor/github.com/containerd/containerd/oci/spec_opts_unix.go

@@ -57,3 +57,7 @@ func WithCPUCFS(quota int64, period uint64) SpecOpts {
 		return nil
 	}
 }
+
+func escapeAndCombineArgs(args []string) string {
+	panic("not supported")
+}

+ 11 - 0
vendor/github.com/containerd/containerd/oci/spec_opts_windows.go

@@ -19,9 +19,12 @@ package oci
 import (
 	"context"
 	"errors"
+	"strings"
 
 	"github.com/containerd/containerd/containers"
+
 	specs "github.com/opencontainers/runtime-spec/specs-go"
+	"golang.org/x/sys/windows"
 )
 
 // WithWindowsCPUCount sets the `Windows.Resources.CPU.Count` section to the
@@ -89,3 +92,11 @@ func WithWindowsNetworkNamespace(ns string) SpecOpts {
 		return nil
 	}
 }
+
+func escapeAndCombineArgs(args []string) string {
+	escaped := make([]string, len(args))
+	for i, a := range args {
+		escaped[i] = windows.EscapeArg(a)
+	}
+	return strings.Join(escaped, " ")
+}

+ 2 - 2
vendor/github.com/containerd/containerd/oci/utils_unix.go

@@ -127,7 +127,7 @@ func getDevices(path, containerPath string) ([]specs.LinuxDevice, error) {
 
 // TODO consider adding these consts to the OCI runtime-spec.
 const (
-	wildcardDevice = "a" //nolint // currently unused, but should be included when upstreaming to OCI runtime-spec.
+	wildcardDevice = "a" //nolint:nolintlint,unused,varcheck // currently unused, but should be included when upstreaming to OCI runtime-spec.
 	blockDevice    = "b"
 	charDevice     = "c" // or "u"
 	fifoDevice     = "p"
@@ -148,7 +148,7 @@ func DeviceFromPath(path string) (*specs.LinuxDevice, error) {
 	}
 
 	var (
-		devNumber = uint64(stat.Rdev) //nolint: unconvert // the type is 32bit on mips.
+		devNumber = uint64(stat.Rdev) //nolint:nolintlint,unconvert // the type is 32bit on mips.
 		major     = unix.Major(devNumber)
 		minor     = unix.Minor(devNumber)
 	)

+ 1 - 1
vendor/github.com/containerd/containerd/pkg/runtimeoptions/v1/doc.go

@@ -14,4 +14,4 @@
    limitations under the License.
 */
 
-package runtimeoptions_v1 //nolint
+package runtimeoptions_v1 //nolint:revive // Ignore var-naming: don't use an underscore in package name (revive)

+ 1 - 1
vendor/github.com/containerd/containerd/reference/docker/reference.go

@@ -683,7 +683,7 @@ func splitDockerDomain(name string) (domain, remainder string) {
 }
 
 // familiarizeName returns a shortened version of the name familiar
-// to to the Docker UI. Familiar names have the default domain
+// to the Docker UI. Familiar names have the default domain
 // "docker.io" and "library/" repository prefix removed.
 // For example, "docker.io/library/redis" will have the familiar
 // name "redis" and "docker.io/dmcgowan/myapp" will be "dmcgowan/myapp".

+ 10 - 8
vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go

@@ -52,6 +52,7 @@ type StartOpts struct {
 	ContainerdBinary string
 	Address          string
 	TTRPCAddress     string
+	Debug            bool
 }
 
 type StopStatus struct {
@@ -175,7 +176,7 @@ func setLogger(ctx context.Context, id string) (context.Context, error) {
 		l.Logger.SetLevel(logrus.DebugLevel)
 	}
 	f, err := openLog(ctx, id)
-	if err != nil { //nolint:staticcheck // Ignore SA4023 as some platforms always return error
+	if err != nil { //nolint:nolintlint,staticcheck // Ignore SA4023 as some platforms always return error
 		return ctx, err
 	}
 	l.Logger.SetOutput(f)
@@ -261,12 +262,12 @@ func run(ctx context.Context, manager Manager, initFunc Init, name string, confi
 	setRuntime()
 
 	signals, err := setupSignals(config)
-	if err != nil { //nolint:staticcheck // Ignore SA4023 as some platforms always return error
+	if err != nil { //nolint:nolintlint,staticcheck // Ignore SA4023 as some platforms always return error
 		return err
 	}
 
 	if !config.NoSubreaper {
-		if err := subreaper(); err != nil { //nolint:staticcheck // Ignore SA4023 as some platforms always return error
+		if err := subreaper(); err != nil { //nolint:nolintlint,staticcheck // Ignore SA4023 as some platforms always return error
 			return err
 		}
 	}
@@ -333,6 +334,7 @@ func run(ctx context.Context, manager Manager, initFunc Init, name string, confi
 			ContainerdBinary: containerdBinaryFlag,
 			Address:          addressFlag,
 			TTRPCAddress:     ttrpcAddress,
+			Debug:            debugFlag,
 		}
 
 		address, err := manager.Start(ctx, id, opts)
@@ -395,14 +397,14 @@ func run(ctx context.Context, manager Manager, initFunc Init, name string, confi
 		initContext.TTRPCAddress = ttrpcAddress
 
 		// load the plugin specific configuration if it is provided
-		//TODO: Read configuration passed into shim, or from state directory?
-		//if p.Config != nil {
+		// TODO: Read configuration passed into shim, or from state directory?
+		// if p.Config != nil {
 		//	pc, err := config.Decode(p)
 		//	if err != nil {
 		//		return nil, err
 		//	}
 		//	initContext.Config = pc
-		//}
+		// }
 
 		result := p.Init(initContext)
 		if err := initialized.Add(result); err != nil {
@@ -445,7 +447,7 @@ func run(ctx context.Context, manager Manager, initFunc Init, name string, confi
 		}
 	}
 
-	if err := serve(ctx, server, signals, sd.Shutdown); err != nil { //nolint:staticcheck // Ignore SA4023 as some platforms always return error
+	if err := serve(ctx, server, signals, sd.Shutdown); err != nil { //nolint:nolintlint,staticcheck // Ignore SA4023 as some platforms always return error
 		if err != shutdown.ErrShutdown {
 			return err
 		}
@@ -477,7 +479,7 @@ func serve(ctx context.Context, server *ttrpc.Server, signals chan os.Signal, sh
 	}
 
 	l, err := serveListener(socketFlag)
-	if err != nil { //nolint:staticcheck // Ignore SA4023 as some platforms always return error
+	if err != nil { //nolint:nolintlint,staticcheck // Ignore SA4023 as some platforms always return error
 		return err
 	}
 	go func() {

+ 3 - 2
vendor/modules.txt

@@ -33,7 +33,7 @@ github.com/Microsoft/go-winio/pkg/fs
 github.com/Microsoft/go-winio/pkg/guid
 github.com/Microsoft/go-winio/pkg/security
 github.com/Microsoft/go-winio/vhd
-# github.com/Microsoft/hcsshim v0.9.7
+# github.com/Microsoft/hcsshim v0.9.8
 ## explicit; go 1.13
 github.com/Microsoft/hcsshim
 github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options
@@ -216,7 +216,7 @@ github.com/containerd/cgroups/v3/cgroup2/stats
 # github.com/containerd/console v1.0.3
 ## explicit; go 1.13
 github.com/containerd/console
-# github.com/containerd/containerd v1.6.19
+# github.com/containerd/containerd v1.6.20-0.20230322235238-de33abf0547c
 ## explicit; go 1.17
 github.com/containerd/containerd
 github.com/containerd/containerd/api/events
@@ -236,6 +236,7 @@ github.com/containerd/containerd/api/types
 github.com/containerd/containerd/api/types/task
 github.com/containerd/containerd/archive
 github.com/containerd/containerd/archive/compression
+github.com/containerd/containerd/archive/tarheader
 github.com/containerd/containerd/cio
 github.com/containerd/containerd/containers
 github.com/containerd/containerd/content