Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package containerd for openSUSE:Factory 
checked in at 2023-05-23 14:53:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/containerd (Old)
 and      /work/SRC/openSUSE:Factory/.containerd.new.1533 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "containerd"

Tue May 23 14:53:10 2023 rev:57 rq:1088255 version:1.6.21

Changes:
--------
--- /work/SRC/openSUSE:Factory/containerd/containerd.changes    2023-04-22 
21:57:31.308162310 +0200
+++ /work/SRC/openSUSE:Factory/.containerd.new.1533/containerd.changes  
2023-05-23 14:53:11.598003852 +0200
@@ -1,0 +2,16 @@
+Sun May 21 11:16:18 UTC 2023 - Aleksa Sarai <asa...@suse.com>
+
+- Update to containerd v1.6.21 for Docker v23.0.6-ce. Upstream release notes:
+  <https://github.com/containerd/containerd/releases/tag/v1.6.21> bsc#1211578
+- Require a minimum Go version explicitly rather than using golang(API).
+  Fixes the change for bsc#1210298.
+
+-------------------------------------------------------------------
+Thu May  4 12:50:57 UTC 2023 - Marcus Meissner <meiss...@suse.com>
+
+[ This was only released in SLE. ]
+
+- unversion to golang requires to always use the current default go.
+  (bsc#1210298)
+
+-------------------------------------------------------------------

Old:
----
  containerd-1.6.20_2806fc105739.tar.xz

New:
----
  containerd-1.6.21_3dce8eb055cb.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ containerd.spec ++++++
--- /var/tmp/diff_new_pack.9sErbW/_old  2023-05-23 14:53:13.018012253 +0200
+++ /var/tmp/diff_new_pack.9sErbW/_new  2023-05-23 14:53:13.026012301 +0200
@@ -23,14 +23,14 @@
 %endif
 
 # MANUAL: Update the git_version.
-%define git_version 2806fc1057397dbaeefbea0e4e17bddfbd388f38
-%define git_short   2806fc105739
+%define git_version 3dce8eb055cbb6872793272b4f20ed16117344f8
+%define git_short   3dce8eb055cb
 
 %global provider_prefix github.com/containerd/containerd
 %global import_path %{provider_prefix}
 
 Name:           containerd
-Version:        1.6.20
+Version:        1.6.21
 Release:        0
 Summary:        Standalone OCI Container Daemon
 License:        Apache-2.0
@@ -41,12 +41,12 @@
 Source2:        %{name}.service
 BuildRequires:  fdupes
 BuildRequires:  glibc-devel-static
+BuildRequires:  go >= 1.18
 BuildRequires:  go-go-md2man
 BuildRequires:  golang-packaging
 BuildRequires:  libbtrfs-devel >= 3.8
 BuildRequires:  libseccomp-devel >= 2.2
 BuildRequires:  pkg-config
-BuildRequires:  golang(API) = 1.18
 # We provide a git revision so that Docker can require it properly.
 Provides:       %{name}-git = %{git_version}
 # Currently runc is the only supported runtime for containerd. We pin the same

++++++ _service ++++++
--- /var/tmp/diff_new_pack.9sErbW/_old  2023-05-23 14:53:13.062012513 +0200
+++ /var/tmp/diff_new_pack.9sErbW/_new  2023-05-23 14:53:13.066012537 +0200
@@ -3,8 +3,8 @@
     <param name="url">https://github.com/containerd/containerd.git</param>
     <param name="scm">git</param>
     <param name="filename">containerd</param>
-    <param name="versionformat">1.6.20_%h</param>
-    <param name="revision">v1.6.20</param>
+    <param name="versionformat">1.6.21_%h</param>
+    <param name="revision">v1.6.21</param>
     <param name="exclude">.git</param>
   </service>
   <service name="recompress" mode="disabled">

++++++ containerd-1.6.20_2806fc105739.tar.xz -> 
containerd-1.6.21_3dce8eb055cb.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/.github/workflows/build-test-images.yml 
new/containerd-1.6.21_3dce8eb055cb/.github/workflows/build-test-images.yml
--- old/containerd-1.6.20_2806fc105739/.github/workflows/build-test-images.yml  
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/.github/workflows/build-test-images.yml  
2023-05-05 17:13:28.000000000 +0200
@@ -41,7 +41,7 @@
     steps:
       - uses: actions/setup-go@v3
         with:
-          go-version: '1.19.7'
+          go-version: '1.19.9'
 
       - uses: actions/checkout@v3
         with:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/.github/workflows/ci.yml 
new/containerd-1.6.21_3dce8eb055cb/.github/workflows/ci.yml
--- old/containerd-1.6.20_2806fc105739/.github/workflows/ci.yml 2023-03-30 
22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/.github/workflows/ci.yml 2023-05-05 
17:13:28.000000000 +0200
@@ -12,7 +12,7 @@
 env:
   # Go version we currently use to build containerd across all CI.
   # Note: don't forget to update `Binaries` step, as it contains the matrix of 
all supported Go versions.
-  GO_VERSION: '1.19.7'
+  GO_VERSION: '1.19.9'
 
 permissions:  # added using https://github.com/step-security/secure-workflows
   contents: read
@@ -233,7 +233,7 @@
     strategy:
       matrix:
         os: [ubuntu-20.04, macos-12, windows-2019, windows-2022]
-        go-version: ["1.17.13", "1.19.7"]
+        go-version: ["1.17.13", "1.19.9"]
     steps:
       - name: Install dependencies
         if: matrix.os == 'ubuntu-20.04'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/.github/workflows/codeql.yml 
new/containerd-1.6.21_3dce8eb055cb/.github/workflows/codeql.yml
--- old/containerd-1.6.20_2806fc105739/.github/workflows/codeql.yml     
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/.github/workflows/codeql.yml     
2023-05-05 17:13:28.000000000 +0200
@@ -33,7 +33,7 @@
 
     - uses: actions/setup-go@v3
       with:
-        go-version: 1.19.7
+        go-version: 1.19.9
 
     # Initializes the CodeQL tools for scanning.
     - name: Initialize CodeQL
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/.github/workflows/images.yml 
new/containerd-1.6.21_3dce8eb055cb/.github/workflows/images.yml
--- old/containerd-1.6.20_2806fc105739/.github/workflows/images.yml     
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/.github/workflows/images.yml     
2023-05-05 17:13:28.000000000 +0200
@@ -26,7 +26,7 @@
     steps:
       - uses: actions/setup-go@v3
         with:
-          go-version: '1.19.7'
+          go-version: '1.19.9'
 
       - uses: actions/checkout@v3
         with:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/.github/workflows/nightly.yml 
new/containerd-1.6.21_3dce8eb055cb/.github/workflows/nightly.yml
--- old/containerd-1.6.20_2806fc105739/.github/workflows/nightly.yml    
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/.github/workflows/nightly.yml    
2023-05-05 17:13:28.000000000 +0200
@@ -7,7 +7,7 @@
       - '.github/workflows/nightly.yml'
 
 env:
-  GO_VERSION: '1.19.7'
+  GO_VERSION: '1.19.9'
 
 permissions:  # added using https://github.com/step-security/secure-workflows
   contents: read
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/.github/workflows/release.yml 
new/containerd-1.6.21_3dce8eb055cb/.github/workflows/release.yml
--- old/containerd-1.6.20_2806fc105739/.github/workflows/release.yml    
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/.github/workflows/release.yml    
2023-05-05 17:13:28.000000000 +0200
@@ -6,7 +6,7 @@
 name: Containerd Release
 
 env:
-  GO_VERSION: '1.19.7'
+  GO_VERSION: '1.19.9'
 
 permissions:  # added using https://github.com/step-security/secure-workflows
   contents: read
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/containerd-1.6.20_2806fc105739/Vagrantfile 
new/containerd-1.6.21_3dce8eb055cb/Vagrantfile
--- old/containerd-1.6.20_2806fc105739/Vagrantfile      2023-03-30 
22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/Vagrantfile      2023-05-05 
17:13:28.000000000 +0200
@@ -93,7 +93,7 @@
   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.7",
+        'GO_VERSION': ENV['GO_VERSION'] || "1.19.9",
     }
     sh.inline = <<~SHELL
         #!/usr/bin/env bash
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/containerd-1.6.20_2806fc105739/container.go 
new/containerd-1.6.21_3dce8eb055cb/container.go
--- old/containerd-1.6.20_2806fc105739/container.go     2023-03-30 
22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/container.go     2023-05-05 
17:13:28.000000000 +0200
@@ -279,6 +279,7 @@
                        })
                }
        }
+       request.RuntimePath = info.RuntimePath
        if info.Options != nil {
                any, err := typeurl.MarshalAny(info.Options)
                if err != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/contrib/Dockerfile.test 
new/containerd-1.6.21_3dce8eb055cb/contrib/Dockerfile.test
--- old/containerd-1.6.20_2806fc105739/contrib/Dockerfile.test  2023-03-30 
22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/contrib/Dockerfile.test  2023-05-05 
17:13:28.000000000 +0200
@@ -10,7 +10,7 @@
 #
 # docker build -t containerd-test --build-arg RUNC_VERSION=v1.0.0-rc94 -f 
Dockerfile.test ../
 
-ARG GOLANG_VERSION=1.19.7
+ARG GOLANG_VERSION=1.19.9
 ARG GOLANG_IMAGE=golang
 
 FROM ${GOLANG_IMAGE}:${GOLANG_VERSION} AS golang
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/images/archive/exporter.go 
new/containerd-1.6.21_3dce8eb055cb/images/archive/exporter.go
--- old/containerd-1.6.20_2806fc105739/images/archive/exporter.go       
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/images/archive/exporter.go       
2023-05-05 17:13:28.000000000 +0200
@@ -176,7 +176,7 @@
                        }
 
                        name := desc.Annotations[images.AnnotationImageName]
-                       if name != "" && !eo.skipDockerManifest {
+                       if name != "" {
                                mt.names = append(mt.names, name)
                        }
                case images.MediaTypeDockerSchema2ManifestList, 
ocispec.MediaTypeImageIndex:
@@ -215,26 +215,24 @@
                                        records = append(records, r...)
                                }
 
-                               if !eo.skipDockerManifest {
-                                       if len(manifests) >= 1 {
-                                               if len(manifests) > 1 {
-                                                       
sort.SliceStable(manifests, func(i, j int) bool {
-                                                               if 
manifests[i].Platform == nil {
-                                                                       return 
false
-                                                               }
-                                                               if 
manifests[j].Platform == nil {
-                                                                       return 
true
-                                                               }
-                                                               return 
eo.platform.Less(*manifests[i].Platform, *manifests[j].Platform)
-                                                       })
-                                               }
-                                               d = manifests[0].Digest
-                                               dManifests[d] = &exportManifest{
-                                                       manifest: manifests[0],
-                                               }
-                                       } else if eo.platform != nil {
-                                               return fmt.Errorf("no manifest 
found for platform: %w", errdefs.ErrNotFound)
+                               if len(manifests) >= 1 {
+                                       if len(manifests) > 1 {
+                                               sort.SliceStable(manifests, 
func(i, j int) bool {
+                                                       if 
manifests[i].Platform == nil {
+                                                               return false
+                                                       }
+                                                       if 
manifests[j].Platform == nil {
+                                                               return true
+                                                       }
+                                                       return 
eo.platform.Less(*manifests[i].Platform, *manifests[j].Platform)
+                                               })
+                                       }
+                                       d = manifests[0].Digest
+                                       dManifests[d] = &exportManifest{
+                                               manifest: manifests[0],
                                        }
+                               } else if eo.platform != nil {
+                                       return fmt.Errorf("no manifest found 
for platform: %w", errdefs.ErrNotFound)
                                }
                                resolvedIndex[desc.Digest] = d
                        }
@@ -250,7 +248,7 @@
                }
        }
 
-       if len(dManifests) > 0 {
+       if !eo.skipDockerManifest && len(dManifests) > 0 {
                tr, err := manifestsRecord(ctx, store, dManifests)
                if err != nil {
                        return fmt.Errorf("unable to create manifests file: 
%w", err)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/integration/client/container_test.go 
new/containerd-1.6.21_3dce8eb055cb/integration/client/container_test.go
--- old/containerd-1.6.20_2806fc105739/integration/client/container_test.go     
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/integration/client/container_test.go     
2023-05-05 17:13:28.000000000 +0200
@@ -23,6 +23,7 @@
        "io"
        "os"
        "path"
+       "path/filepath"
        "runtime"
        "strings"
        "syscall"
@@ -42,6 +43,7 @@
        "github.com/containerd/containerd/plugin"
        _ "github.com/containerd/containerd/runtime"
        "github.com/containerd/containerd/runtime/v2/runc/options"
+       "github.com/containerd/continuity/fs"
        "github.com/containerd/go-runc"
        "github.com/containerd/typeurl"
        gogotypes "github.com/gogo/protobuf/types"
@@ -140,6 +142,134 @@
 
        statusC, err := task.Wait(ctx)
        if err != nil {
+               t.Fatal(err)
+       }
+
+       if runtime.GOOS != "windows" {
+               // task.Pid not implemented on Windows
+               if pid := task.Pid(); pid < 1 {
+                       t.Errorf("invalid task pid %d", pid)
+               }
+       }
+
+       if err := task.Start(ctx); err != nil {
+               t.Error(err)
+               task.Delete(ctx)
+               return
+       }
+       status := <-statusC
+       code, _, err := status.Result()
+       if err != nil {
+               t.Fatal(err)
+       }
+       if code != 7 {
+               t.Errorf("expected status 7 from wait but received %d", code)
+       }
+
+       deleteStatus, err := task.Delete(ctx)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if ec := deleteStatus.ExitCode(); ec != 7 {
+               t.Errorf("expected status 7 from delete but received %d", ec)
+       }
+}
+
+func readShimPath(taskID string) (string, error) {
+       runtime := fmt.Sprintf("%s.%s", plugin.RuntimePluginV2, "task")
+       shimBinaryNamePath := filepath.Join(defaultState, runtime, 
testNamespace, taskID, "shim-binary-path")
+
+       shimPath, err := os.ReadFile(shimBinaryNamePath)
+       if err != nil {
+               return "", err
+       }
+       return string(shimPath), nil
+}
+
+func copyShim(shimPath string) (string, error) {
+       tempPath := filepath.Join(os.TempDir(), filepath.Base(shimPath))
+       if err := fs.CopyFile(tempPath, shimPath); err != nil {
+               return "", err
+       }
+
+       fi, err := os.Stat(shimPath)
+       if err != nil {
+               return "", err
+       }
+       if err := os.Chmod(tempPath, fi.Mode().Perm()); err != nil {
+               return "", err
+       }
+
+       return tempPath, nil
+}
+
+func TestContainerStartWithAbsRuntimePath(t *testing.T) {
+       t.Parallel()
+
+       client, err := newClient(t, address)
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer client.Close()
+
+       if client.Runtime() == plugin.RuntimeLinuxV1 {
+               t.Skip("test relies on runtime v2")
+       }
+
+       var (
+               image       Image
+               ctx, cancel = testContext(t)
+               id          = t.Name()
+       )
+       defer cancel()
+
+       image, err = client.GetImage(ctx, testImage)
+       if err != nil {
+               t.Fatal(err)
+       }
+       container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, 
image), WithNewSpec(oci.WithImageConfig(image), withExitStatus(7)))
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer container.Delete(ctx, WithSnapshotCleanup)
+
+       // create a temp task to read the default shim path
+       task, err := container.NewTask(ctx, empty())
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       defaultShimPath, err := readShimPath(task.ID())
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // remove the temp task
+       if _, err := task.Delete(ctx, WithProcessKill); err != nil {
+               t.Fatal(err)
+       }
+
+       tempShimPath, err := copyShim(defaultShimPath)
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer os.Remove(tempShimPath)
+
+       task, err = container.NewTask(ctx, empty(), 
WithRuntimePath(tempShimPath))
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       shimPath, err := readShimPath(task.ID())
+       if err != nil {
+               t.Fatal(err)
+       }
+       if shimPath != tempShimPath {
+               t.Fatalf("The task's shim path is %s, does not used the 
specified runtime path: %s", shimPath, tempShimPath)
+       }
+
+       statusC, err := task.Wait(ctx)
+       if err != nil {
                t.Fatal(err)
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/integration/client/export_test.go 
new/containerd-1.6.21_3dce8eb055cb/integration/client/export_test.go
--- old/containerd-1.6.20_2806fc105739/integration/client/export_test.go        
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/integration/client/export_test.go        
2023-05-05 17:13:28.000000000 +0200
@@ -19,12 +19,18 @@
 import (
        "archive/tar"
        "bytes"
+       "context"
+       "encoding/json"
        "io"
+       "os"
        "testing"
 
        . "github.com/containerd/containerd"
+       "github.com/containerd/containerd/content"
+       "github.com/containerd/containerd/images"
        "github.com/containerd/containerd/images/archive"
        "github.com/containerd/containerd/platforms"
+       ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 )
 
 // TestExport exports testImage as a tar stream
@@ -50,14 +56,103 @@
        if err != nil {
                t.Fatal(err)
        }
-       assertOCITar(t, bytes.NewReader(wb.Bytes()))
+       assertOCITar(t, bytes.NewReader(wb.Bytes()), true)
 }
 
-func assertOCITar(t *testing.T, r io.Reader) {
+// TestExportDockerManifest exports testImage as a tar stream, using the
+// WithSkipDockerManifest option
+func TestExportDockerManifest(t *testing.T) {
+       if testing.Short() {
+               t.Skip()
+       }
+       ctx, cancel := testContext(t)
+       defer cancel()
+
+       client, err := New(address)
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer client.Close()
+
+       _, err = client.Fetch(ctx, testImage)
+       if err != nil {
+               t.Fatal(err)
+       }
+       dstFile, err := os.CreateTemp("", "export-import-test")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer func() {
+               dstFile.Close()
+               os.Remove(dstFile.Name())
+       }()
+
+       img, err := client.ImageService().Get(ctx, testImage)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // test multi-platform export
+       err = client.Export(ctx, dstFile, archive.WithManifest(img.Target), 
archive.WithSkipDockerManifest())
+       if err != nil {
+               t.Fatal(err)
+       }
+       dstFile.Seek(0, 0)
+       assertOCITar(t, dstFile, false)
+
+       // reset to beginning
+       dstFile.Seek(0, 0)
+
+       // test single-platform export
+       var result ocispec.Descriptor
+       err = images.Walk(ctx, images.HandlerFunc(func(ctx context.Context, 
desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
+               switch desc.MediaType {
+               case images.MediaTypeDockerSchema2Manifest, 
ocispec.MediaTypeImageManifest:
+                       p, err := content.ReadBlob(ctx, client.ContentStore(), 
desc)
+                       if err != nil {
+                               return nil, err
+                       }
+
+                       var manifest ocispec.Manifest
+                       if err := json.Unmarshal(p, &manifest); err != nil {
+                               return nil, err
+                       }
+
+                       if desc.Platform == nil || 
platforms.Default().Match(platforms.Normalize(*desc.Platform)) {
+                               result = desc
+                       }
+                       return nil, nil
+               case images.MediaTypeDockerSchema2ManifestList, 
ocispec.MediaTypeImageIndex:
+                       p, err := content.ReadBlob(ctx, client.ContentStore(), 
desc)
+                       if err != nil {
+                               return nil, err
+                       }
+
+                       var idx ocispec.Index
+                       if err := json.Unmarshal(p, &idx); err != nil {
+                               return nil, err
+                       }
+                       return idx.Manifests, nil
+               }
+               return nil, nil
+       }), img.Target)
+       if err != nil {
+               t.Fatal(err)
+       }
+       err = client.Export(ctx, dstFile, archive.WithManifest(result), 
archive.WithSkipDockerManifest())
+       if err != nil {
+               t.Fatal(err)
+       }
+       dstFile.Seek(0, 0)
+       assertOCITar(t, dstFile, false)
+}
+
+func assertOCITar(t *testing.T, r io.Reader, docker bool) {
        // TODO: add more assertion
        tr := tar.NewReader(r)
        foundOCILayout := false
        foundIndexJSON := false
+       foundManifestJSON := false
        for {
                h, err := tr.Next()
                if err == io.EOF {
@@ -73,6 +168,9 @@
                if h.Name == "index.json" {
                        foundIndexJSON = true
                }
+               if h.Name == "manifest.json" {
+                       foundManifestJSON = true
+               }
        }
        if !foundOCILayout {
                t.Error("oci-layout not found")
@@ -80,4 +178,9 @@
        if !foundIndexJSON {
                t.Error("index.json not found")
        }
+       if docker && !foundManifestJSON {
+               t.Error("manifest.json not found")
+       } else if !docker && foundManifestJSON {
+               t.Error("manifest.json found")
+       }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/integration/client/go.mod 
new/containerd-1.6.21_3dce8eb055cb/integration/client/go.mod
--- old/containerd-1.6.20_2806fc105739/integration/client/go.mod        
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/integration/client/go.mod        
2023-05-05 17:13:28.000000000 +0200
@@ -8,6 +8,7 @@
        github.com/containerd/cgroups v1.0.4
        // the actual version of containerd is replaced with the code at the 
root of this repository
        github.com/containerd/containerd v1.6.1
+       github.com/containerd/continuity v0.3.0
        github.com/containerd/go-runc v1.0.0
        github.com/containerd/ttrpc v1.1.1
        github.com/containerd/typeurl v1.0.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/containerd-1.6.20_2806fc105739/integration/common.go 
new/containerd-1.6.21_3dce8eb055cb/integration/common.go
--- old/containerd-1.6.20_2806fc105739/integration/common.go    2023-03-30 
22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/integration/common.go    2023-05-05 
17:13:28.000000000 +0200
@@ -36,6 +36,7 @@
        ResourceConsumer string
        VolumeCopyUp     string
        VolumeOwnership  string
+       ArgsEscaped      string
 }
 
 var (
@@ -53,6 +54,7 @@
                ResourceConsumer: 
"registry.k8s.io/e2e-test-images/resource-consumer:1.10",
                VolumeCopyUp:     "ghcr.io/containerd/volume-copy-up:2.1",
                VolumeOwnership:  "ghcr.io/containerd/volume-ownership:2.1",
+               ArgsEscaped:      
"cplatpublic.azurecr.io/args-escaped-test-image-ns:1.0",
        }
 
        if imageListFile != "" {
@@ -88,6 +90,8 @@
        VolumeCopyUp
        // VolumeOwnership image
        VolumeOwnership
+       // Test image for ArgsEscaped windows bug
+       ArgsEscaped
 )
 
 func initImageMap(imageList ImageList) map[int]string {
@@ -98,6 +102,7 @@
        images[ResourceConsumer] = imageList.ResourceConsumer
        images[VolumeCopyUp] = imageList.VolumeCopyUp
        images[VolumeOwnership] = imageList.VolumeOwnership
+       images[ArgsEscaped] = imageList.ArgsEscaped
        return images
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/integration/image_list.sample.toml 
new/containerd-1.6.21_3dce8eb055cb/integration/image_list.sample.toml
--- old/containerd-1.6.20_2806fc105739/integration/image_list.sample.toml       
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/integration/image_list.sample.toml       
2023-05-05 17:13:28.000000000 +0200
@@ -3,3 +3,4 @@
 pause = "registry.k8s.io/pause:3.6"
 VolumeCopyUp = "ghcr.io/containerd/volume-copy-up:2.1"
 VolumeOwnership = "ghcr.io/containerd/volume-ownership:2.1"
+ArgsEscaped = "cplatpublic.azurecr.io/args-escaped-test-image-ns:1.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/integration/windows_hostprocess_test.go 
new/containerd-1.6.21_3dce8eb055cb/integration/windows_hostprocess_test.go
--- old/containerd-1.6.20_2806fc105739/integration/windows_hostprocess_test.go  
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/integration/windows_hostprocess_test.go  
2023-05-05 17:13:28.000000000 +0200
@@ -22,11 +22,14 @@
 import (
        "fmt"
        "os"
+       "strconv"
        "testing"
        "time"
 
+       "github.com/Microsoft/hcsshim/osversion"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/require"
+       "golang.org/x/sys/windows/registry"
        runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
        v1 "k8s.io/cri-api/pkg/apis/runtime/v1"
 )
@@ -122,3 +125,67 @@
 
        action(t, cn, containerConfig)
 }
+
+func runAndRemoveContainer(t *testing.T, sb string, sbConfig 
*runtime.PodSandboxConfig, cnConfig *runtime.ContainerConfig) {
+       t.Log("Create the container")
+       cn, err := runtimeService.CreateContainer(sb, cnConfig, sbConfig)
+       require.NoError(t, err)
+       t.Log("Start the container")
+       require.NoError(t, runtimeService.StartContainer(cn))
+       // Wait few seconds for the container to be completely initialized
+       time.Sleep(5 * time.Second)
+
+       t.Log("Stop the container")
+       require.NoError(t, runtimeService.StopContainer(cn, 0))
+       t.Log("Remove the container")
+       require.NoError(t, runtimeService.RemoveContainer(cn))
+}
+
+func TestArgsEscapedImagesOnWindows(t *testing.T) {
+       // the ArgsEscaped test image is based on nanoserver:ltsc2022, so 
ensure we run on the correct OS version
+       k, err := registry.OpenKey(registry.LOCAL_MACHINE, 
`SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
+       if err != nil {
+               t.Skip("Error in getting OS version")
+       }
+       defer k.Close()
+
+       b, _, _ := k.GetStringValue("CurrentBuild")
+       buildNum, _ := strconv.Atoi(b)
+       if buildNum < osversion.V21H2Server {
+               t.Skip()
+       }
+
+       containerName := "test-container"
+       testImage := GetImage(ArgsEscaped)
+       sbConfig := &runtime.PodSandboxConfig{
+               Metadata: &runtime.PodSandboxMetadata{
+                       Name:      "sandbox",
+                       Namespace: testImage,
+               },
+               Windows: &runtime.WindowsPodSandboxConfig{},
+       }
+       sb, err := runtimeService.RunPodSandbox(sbConfig, *runtimeHandler)
+       require.NoError(t, err)
+       t.Cleanup(func() {
+               assert.NoError(t, runtimeService.StopPodSandbox(sb))
+               assert.NoError(t, runtimeService.RemovePodSandbox(sb))
+       })
+
+       EnsureImageExists(t, testImage)
+
+       cnConfigWithCtrCmd := ContainerConfig(
+               containerName,
+               testImage,
+               WithCommand("ping", "-t", "127.0.0.1"),
+               localSystemUsername,
+       )
+
+       cnConfigNoCtrCmd := ContainerConfig(
+               containerName,
+               testImage,
+               localSystemUsername,
+       )
+
+       runAndRemoveContainer(t, sb, sbConfig, cnConfigWithCtrCmd)
+       runAndRemoveContainer(t, sb, sbConfig, cnConfigNoCtrCmd)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/containerd-1.6.20_2806fc105739/oci/spec_opts.go 
new/containerd-1.6.21_3dce8eb055cb/oci/spec_opts.go
--- old/containerd-1.6.20_2806fc105739/oci/spec_opts.go 2023-03-30 
22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/oci/spec_opts.go 2023-05-05 
17:13:28.000000000 +0200
@@ -663,8 +663,11 @@
                                return err
                        }
 
-                       mounts = tryReadonlyMounts(mounts)
-                       return mount.WithTempMount(ctx, mounts, f)
+                       // Use a read-only mount when trying to get user/group 
information
+                       // from the container's rootfs. Since the option does 
read operation
+                       // only, we append ReadOnly mount option to prevent the 
Linux kernel
+                       // from syncing whole filesystem in umount syscall.
+                       return mount.WithReadonlyTempMount(ctx, mounts, f)
                default:
                        return fmt.Errorf("invalid USER value %s", userstr)
                }
@@ -724,8 +727,11 @@
                        return err
                }
 
-               mounts = tryReadonlyMounts(mounts)
-               return mount.WithTempMount(ctx, mounts, setUser)
+               // Use a read-only mount when trying to get user/group 
information
+               // from the container's rootfs. Since the option does read 
operation
+               // only, we append ReadOnly mount option to prevent the Linux 
kernel
+               // from syncing whole filesystem in umount syscall.
+               return mount.WithReadonlyTempMount(ctx, mounts, setUser)
        }
 }
 
@@ -769,8 +775,11 @@
                                return err
                        }
 
-                       mounts = tryReadonlyMounts(mounts)
-                       return mount.WithTempMount(ctx, mounts, setUser)
+                       // Use a read-only mount when trying to get user/group 
information
+                       // from the container's rootfs. Since the option does 
read operation
+                       // only, we append ReadOnly mount option to prevent the 
Linux kernel
+                       // from syncing whole filesystem in umount syscall.
+                       return mount.WithReadonlyTempMount(ctx, mounts, setUser)
                } else if s.Windows != nil {
                        s.Process.User.Username = username
                } else {
@@ -848,8 +857,11 @@
                        return err
                }
 
-               mounts = tryReadonlyMounts(mounts)
-               return mount.WithTempMount(ctx, mounts, setAdditionalGids)
+               // Use a read-only mount when trying to get user/group 
information
+               // from the container's rootfs. Since the option does read 
operation
+               // only, we append ReadOnly mount option to prevent the Linux 
kernel
+               // from syncing whole filesystem in umount syscall.
+               return mount.WithReadonlyTempMount(ctx, mounts, 
setAdditionalGids)
        }
 }
 
@@ -910,8 +922,11 @@
                        return err
                }
 
-               mounts = tryReadonlyMounts(mounts)
-               return mount.WithTempMount(ctx, mounts, setAdditionalGids)
+               // Use a read-only mount when trying to get user/group 
information
+               // from the container's rootfs. Since the option does read 
operation
+               // only, we append ReadOnly mount option to prevent the Linux 
kernel
+               // from syncing whole filesystem in umount syscall.
+               return mount.WithReadonlyTempMount(ctx, mounts, 
setAdditionalGids)
        }
 }
 
@@ -1389,21 +1404,3 @@
                return ErrNoShmMount
        }
 }
-
-// tryReadonlyMounts is used by the options which are trying to get user/group
-// information from container's rootfs. Since the option does read operation
-// only, this helper will append ReadOnly mount option to prevent linux kernel
-// from syncing whole filesystem in umount syscall.
-//
-// TODO(fuweid):
-//
-// Currently, it only works for overlayfs. I think we can apply it to other
-// kinds of filesystem. Maybe we can return `ro` option by `snapshotter.Mount`
-// API, when the caller passes that experimental annotation
-// `containerd.io/snapshot/readonly.mount` something like that.
-func tryReadonlyMounts(mounts []mount.Mount) []mount.Mount {
-       if len(mounts) == 1 && mounts[0].Type == "overlay" {
-               mounts[0].Options = append(mounts[0].Options, "ro")
-       }
-       return mounts
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/oci/spec_opts_windows.go 
new/containerd-1.6.21_3dce8eb055cb/oci/spec_opts_windows.go
--- old/containerd-1.6.20_2806fc105739/oci/spec_opts_windows.go 2023-03-30 
22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/oci/spec_opts_windows.go 2023-05-05 
17:13:28.000000000 +0200
@@ -68,6 +68,16 @@
        }
 }
 
+// WithProcessCommandLine replaces the command line on the generated spec
+func WithProcessCommandLine(cmdLine string) SpecOpts {
+       return func(_ context.Context, _ Client, _ *containers.Container, s 
*Spec) error {
+               setProcess(s)
+               s.Process.Args = nil
+               s.Process.CommandLine = cmdLine
+               return nil
+       }
+}
+
 // WithHostDevices adds all the hosts device nodes to the container's spec
 //
 // Not supported on windows
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/pkg/cri/opts/spec_windows.go 
new/containerd-1.6.21_3dce8eb055cb/pkg/cri/opts/spec_windows.go
--- old/containerd-1.6.20_2806fc105739/pkg/cri/opts/spec_windows.go     
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/pkg/cri/opts/spec_windows.go     
2023-05-05 17:13:28.000000000 +0200
@@ -18,6 +18,7 @@
 
 import (
        "context"
+       "errors"
        "fmt"
        "os"
        "path/filepath"
@@ -26,7 +27,9 @@
 
        "github.com/containerd/containerd/containers"
        "github.com/containerd/containerd/oci"
+       imagespec "github.com/opencontainers/image-spec/specs-go/v1"
        runtimespec "github.com/opencontainers/runtime-spec/specs-go"
+       "golang.org/x/sys/windows"
        runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
 
        osinterface "github.com/containerd/containerd/pkg/os"
@@ -243,3 +246,92 @@
                return nil
        }
 }
+
+func escapeAndCombineArgsWindows(args []string) string {
+       escaped := make([]string, len(args))
+       for i, a := range args {
+               escaped[i] = windows.EscapeArg(a)
+       }
+       return strings.Join(escaped, " ")
+}
+
+// WithProcessCommandLineOrArgsForWindows sets the process command line or 
process args on the spec based on the image
+// and runtime config
+// If image.ArgsEscaped field is set, this function sets the process command 
line and if not, it sets the
+// process args field
+func WithProcessCommandLineOrArgsForWindows(config *runtime.ContainerConfig, 
image *imagespec.ImageConfig) oci.SpecOpts {
+       if image.ArgsEscaped {
+               return func(ctx context.Context, client oci.Client, c 
*containers.Container, s *runtimespec.Spec) (err error) {
+                       // firstArgFromImg is a flag that is returned to 
indicate that the first arg in the slice comes from either the
+                       // image Entrypoint or Cmd. If the first arg instead 
comes from the container config (e.g. overriding the image values),
+                       // it should be false. This is done to support the 
non-OCI ArgsEscaped field that Docker used to determine how the image
+                       // entrypoint and cmd should be interpreted.
+                       //
+                       args, firstArgFromImg, err := getArgs(image.Entrypoint, 
image.Cmd, config.GetCommand(), config.GetArgs())
+                       if err != nil {
+                               return err
+                       }
+
+                       var cmdLine string
+                       if image.ArgsEscaped && firstArgFromImg {
+                               cmdLine = args[0]
+                               if len(args) > 1 {
+                                       cmdLine += " " + 
escapeAndCombineArgsWindows(args[1:])
+                               }
+                       } else {
+                               cmdLine = escapeAndCombineArgsWindows(args)
+                       }
+
+                       return oci.WithProcessCommandLine(cmdLine)(ctx, client, 
c, s)
+               }
+       }
+       // if ArgsEscaped is not set
+       return func(ctx context.Context, client oci.Client, c 
*containers.Container, s *runtimespec.Spec) (err error) {
+               args, _, err := getArgs(image.Entrypoint, image.Cmd, 
config.GetCommand(), config.GetArgs())
+               if err != nil {
+                       return err
+               }
+               return oci.WithProcessArgs(args...)(ctx, client, c, s)
+       }
+}
+
+// getArgs is used to evaluate the overall args for the container by taking 
into account the image command and entrypoints
+// along with the container command and entrypoints specified through the 
podspec if any
+func getArgs(imgEntrypoint []string, imgCmd []string, ctrEntrypoint []string, 
ctrCmd []string) ([]string, bool, error) {
+       //nolint:dupword
+       // firstArgFromImg is a flag that is returned to indicate that the 
first arg in the slice comes from either the image
+       // Entrypoint or Cmd. If the first arg instead comes from the container 
config (e.g. overriding the image values),
+       // it should be false.
+       // Essentially this means firstArgFromImg should be true iff:
+       // Ctr entrypoint       ctr cmd         image entrypoint        image 
cmd       firstArgFromImg
+       // 
--------------------------------------------------------------------------------
+       //      nil                              nil                    exists  
                 nil              true
+       //  nil                          nil                nil                 
         exists           true
+
+       // This is needed to support the non-OCI ArgsEscaped field used by 
Docker. ArgsEscaped is used for
+       // Windows images to indicate that the command has already been escaped 
and should be
+       // used directly as the command line.
+       var firstArgFromImg bool
+       entrypoint, cmd := ctrEntrypoint, ctrCmd
+       // The following logic is migrated from 
https://github.com/moby/moby/blob/master/daemon/commit.go
+       // TODO(random-liu): Clearly define the commands overwrite behavior.
+       if len(entrypoint) == 0 {
+               // Copy array to avoid data race.
+               if len(cmd) == 0 {
+                       cmd = append([]string{}, imgCmd...)
+                       if len(imgCmd) > 0 {
+                               firstArgFromImg = true
+                       }
+               }
+               if entrypoint == nil {
+                       entrypoint = append([]string{}, imgEntrypoint...)
+                       if len(imgEntrypoint) > 0 || len(ctrCmd) == 0 {
+                               firstArgFromImg = true
+                       }
+               }
+       }
+       if len(entrypoint) == 0 && len(cmd) == 0 {
+               return nil, false, errors.New("no command specified")
+       }
+       return append(entrypoint, cmd...), firstArgFromImg, nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/pkg/cri/server/container_create_windows.go 
new/containerd-1.6.21_3dce8eb055cb/pkg/cri/server/container_create_windows.go
--- 
old/containerd-1.6.20_2806fc105739/pkg/cri/server/container_create_windows.go   
    2023-03-30 22:30:13.000000000 +0200
+++ 
new/containerd-1.6.21_3dce8eb055cb/pkg/cri/server/container_create_windows.go   
    2023-05-05 17:13:28.000000000 +0200
@@ -48,9 +48,8 @@
        extraMounts []*runtime.Mount,
        ociRuntime config.Runtime,
 ) (*runtimespec.Spec, error) {
-       specOpts := []oci.SpecOpts{
-               customopts.WithProcessArgs(config, imageConfig),
-       }
+       var specOpts []oci.SpecOpts
+       specOpts = append(specOpts, 
customopts.WithProcessCommandLineOrArgsForWindows(config, imageConfig))
 
        // All containers in a pod need to have HostProcess set if it was set 
on the pod,
        // and vice versa no containers in the pod can be HostProcess if the 
pods spec
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/pkg/cri/server/container_create_windows_test.go
 
new/containerd-1.6.21_3dce8eb055cb/pkg/cri/server/container_create_windows_test.go
--- 
old/containerd-1.6.20_2806fc105739/pkg/cri/server/container_create_windows_test.go
  2023-03-30 22:30:13.000000000 +0200
+++ 
new/containerd-1.6.21_3dce8eb055cb/pkg/cri/server/container_create_windows_test.go
  2023-05-05 17:13:28.000000000 +0200
@@ -22,12 +22,27 @@
        imagespec "github.com/opencontainers/image-spec/specs-go/v1"
        runtimespec "github.com/opencontainers/runtime-spec/specs-go"
        "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
        runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
 
        "github.com/containerd/containerd/pkg/cri/annotations"
        "github.com/containerd/containerd/pkg/cri/config"
 )
 
+func getSandboxConfig() *runtime.PodSandboxConfig {
+       return &runtime.PodSandboxConfig{
+               Metadata: &runtime.PodSandboxMetadata{
+                       Name:      "test-sandbox-name",
+                       Uid:       "test-sandbox-uid",
+                       Namespace: "test-sandbox-ns",
+                       Attempt:   2,
+               },
+               Windows:     &runtime.WindowsPodSandboxConfig{},
+               Hostname:    "test-hostname",
+               Annotations: map[string]string{"c": "d"},
+       }
+}
+
 func getCreateContainerTestData() (*runtime.ContainerConfig, 
*runtime.PodSandboxConfig,
        *imagespec.ImageConfig, func(*testing.T, string, string, uint32, 
*runtimespec.Spec)) {
        config := &runtime.ContainerConfig{
@@ -76,17 +91,7 @@
                        },
                },
        }
-       sandboxConfig := &runtime.PodSandboxConfig{
-               Metadata: &runtime.PodSandboxMetadata{
-                       Name:      "test-sandbox-name",
-                       Uid:       "test-sandbox-uid",
-                       Namespace: "test-sandbox-ns",
-                       Attempt:   2,
-               },
-               Windows:     &runtime.WindowsPodSandboxConfig{},
-               Hostname:    "test-hostname",
-               Annotations: map[string]string{"c": "d"},
-       }
+       sandboxConfig := getSandboxConfig()
        imageConfig := &imagespec.ImageConfig{
                Env:        []string{"ik1=iv1", "ik2=iv2", "ik3=iv3=iv3bis", 
"ik4=iv4=iv4bis=boop"},
                Entrypoint: []string{"/entrypoint"},
@@ -248,3 +253,104 @@
                })
        }
 }
+
+func TestEntrypointAndCmdForArgsEscaped(t *testing.T) {
+       testID := "test-id"
+       testSandboxID := "sandbox-id"
+       testContainerName := "container-name"
+       testPid := uint32(1234)
+       nsPath := "test-ns"
+       c := newTestCRIService()
+
+       for name, test := range map[string]struct {
+               imgEntrypoint       []string
+               imgCmd              []string
+               command             []string
+               args                []string
+               expectedArgs        []string
+               expectedCommandLine string
+               ArgsEscaped         bool
+       }{
+               // override image entrypoint and cmd in shell form with 
container args and verify expected runtime spec
+               "TestShellFormImgEntrypointCmdWithCtrArgs": {
+                       imgEntrypoint:       []string{`"C:\My 
Folder\MyProcess.exe" -arg1 "test value"`},
+                       imgCmd:              []string{`cmd -args "hello 
world"`},
+                       command:             nil,
+                       args:                []string{`cmd -args "additional 
args"`},
+                       expectedArgs:        nil,
+                       expectedCommandLine: `"C:\My Folder\MyProcess.exe" 
-arg1 "test value" "cmd -args \"additional args\""`,
+                       ArgsEscaped:         true,
+               },
+               // check image entrypoint and cmd in shell form without 
overriding with container command and args and verify expected runtime spec
+               "TestShellFormImgEntrypointCmdWithoutCtrArgs": {
+                       imgEntrypoint:       []string{`"C:\My 
Folder\MyProcess.exe" -arg1 "test value"`},
+                       imgCmd:              []string{`cmd -args "hello 
world"`},
+                       command:             nil,
+                       args:                nil,
+                       expectedArgs:        nil,
+                       expectedCommandLine: `"C:\My Folder\MyProcess.exe" 
-arg1 "test value" "cmd -args \"hello world\""`,
+                       ArgsEscaped:         true,
+               },
+               // override image entrypoint and cmd by container command and 
args in shell form and verify expected runtime spec
+               "TestShellFormImgEntrypointCmdWithCtrEntrypointAndArgs": {
+                       imgEntrypoint:       []string{`"C:\My 
Folder\MyProcess.exe" -arg1 "test value"`},
+                       imgCmd:              []string{`cmd -args "hello 
world"`},
+                       command:             []string{`C:\My 
Folder\MyProcess.exe`, "-arg1", "additional test value"},
+                       args:                []string{"cmd", "-args", 
"additional args"},
+                       expectedArgs:        nil,
+                       expectedCommandLine: `"C:\My Folder\MyProcess.exe" 
-arg1 "additional test value" cmd -args "additional args"`,
+                       ArgsEscaped:         true,
+               },
+               // override image cmd by container args in exec form and verify 
expected runtime spec
+               "TestExecFormImgEntrypointCmdWithCtrArgs": {
+                       imgEntrypoint:       []string{`C:\My 
Folder\MyProcess.exe`, "-arg1", "test value"},
+                       imgCmd:              []string{"cmd", "-args", "hello 
world"},
+                       command:             nil,
+                       args:                []string{"additional", "args"},
+                       expectedArgs:        []string{`C:\My 
Folder\MyProcess.exe`, "-arg1", "test value", "additional", "args"},
+                       expectedCommandLine: "",
+                       ArgsEscaped:         false,
+               },
+               // check image entrypoint and cmd in exec form without 
overriding with container command and args and verify expected runtime spec
+               "TestExecFormImgEntrypointCmdWithoutCtrArgs": {
+                       imgEntrypoint:       []string{`C:\My 
Folder\MyProcess.exe`, "-arg1", "test value"},
+                       imgCmd:              []string{"cmd", "-args", "hello 
world"},
+                       command:             nil,
+                       args:                nil,
+                       expectedArgs:        []string{`C:\My 
Folder\MyProcess.exe`, "-arg1", "test value", "cmd", "-args", "hello world"},
+                       expectedCommandLine: "",
+                       ArgsEscaped:         false,
+               },
+       } {
+               t.Run(name, func(t *testing.T) {
+                       imageConfig := &imagespec.ImageConfig{
+                               Entrypoint:  test.imgEntrypoint,
+                               Cmd:         test.imgCmd,
+                               ArgsEscaped: test.ArgsEscaped,
+                       }
+                       sandboxConfig := getSandboxConfig()
+                       containerConfig := &runtime.ContainerConfig{
+                               Metadata: &runtime.ContainerMetadata{
+                                       Name:    "test-name",
+                                       Attempt: 1,
+                               },
+                               Image: &runtime.ImageSpec{
+                                       Image: testImageName,
+                               },
+                               Command: test.command,
+                               Args:    test.args,
+                               Windows: &runtime.WindowsContainerConfig{},
+                       }
+                       runtimeSpec, err := c.containerSpec(testID, 
testSandboxID, testPid, nsPath, testContainerName, testImageName, 
containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{})
+                       assert.NoError(t, err)
+                       assert.NotNil(t, runtimeSpec)
+
+                       // check the runtime spec for expected commandline and 
args
+                       actualCommandLine := runtimeSpec.Process.CommandLine
+                       actualArgs := runtimeSpec.Process.Args
+
+                       require.Equal(t, actualArgs, test.expectedArgs)
+                       require.Equal(t, actualCommandLine, 
test.expectedCommandLine)
+               })
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/pkg/cri/server/container_execsync.go 
new/containerd-1.6.21_3dce8eb055cb/pkg/cri/server/container_execsync.go
--- old/containerd-1.6.20_2806fc105739/pkg/cri/server/container_execsync.go     
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/pkg/cri/server/container_execsync.go     
2023-05-05 17:13:28.000000000 +0200
@@ -136,6 +136,8 @@
        }
 
        pspec.Args = opts.cmd
+       // CommandLine may already be set on the container's spec, but we want 
to only use Args here.
+       pspec.CommandLine = ""
 
        if opts.stdout == nil {
                opts.stdout = cio.NewDiscardLogger()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/pkg/cri/server/container_remove.go 
new/containerd-1.6.21_3dce8eb055cb/pkg/cri/server/container_remove.go
--- old/containerd-1.6.20_2806fc105739/pkg/cri/server/container_remove.go       
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/pkg/cri/server/container_remove.go       
2023-05-05 17:13:28.000000000 +0200
@@ -33,19 +33,29 @@
 // RemoveContainer removes the container.
 func (c *criService) RemoveContainer(ctx context.Context, r 
*runtime.RemoveContainerRequest) (_ *runtime.RemoveContainerResponse, retErr 
error) {
        start := time.Now()
-       container, err := c.containerStore.Get(r.GetContainerId())
+       ctrID := r.GetContainerId()
+       container, err := c.containerStore.Get(ctrID)
        if err != nil {
                if !errdefs.IsNotFound(err) {
-                       return nil, fmt.Errorf("an error occurred when try to 
find container %q: %w", r.GetContainerId(), err)
+                       return nil, fmt.Errorf("an error occurred when try to 
find container %q: %w", ctrID, err)
                }
                // Do not return error if container metadata doesn't exist.
-               log.G(ctx).Tracef("RemoveContainer called for container %q that 
does not exist", r.GetContainerId())
+               log.G(ctx).Tracef("RemoveContainer called for container %q that 
does not exist", ctrID)
                return &runtime.RemoveContainerResponse{}, nil
        }
        id := container.ID
        i, err := container.Container.Info(ctx)
        if err != nil {
-               return nil, fmt.Errorf("get container info: %w", err)
+               if !errdefs.IsNotFound(err) {
+                       return nil, fmt.Errorf("get container info: %w", err)
+               }
+               // Since containerd doesn't see the container and criservice's 
content store does,
+               // we should try to recover from this state by removing entry 
for this container
+               // from the container store as well and return successfully.
+               log.G(ctx).WithError(err).Warn("get container info failed")
+               c.containerStore.Delete(ctrID)
+               c.containerNameIndex.ReleaseByKey(ctrID)
+               return &runtime.RemoveContainerResponse{}, nil
        }
 
        // Forcibly stop the containers if they are in running or unknown state
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/containerd-1.6.20_2806fc105739/releases/v1.6.21.toml 
new/containerd-1.6.21_3dce8eb055cb/releases/v1.6.21.toml
--- old/containerd-1.6.20_2806fc105739/releases/v1.6.21.toml    1970-01-01 
01:00:00.000000000 +0100
+++ new/containerd-1.6.21_3dce8eb055cb/releases/v1.6.21.toml    2023-05-05 
17:13:28.000000000 +0200
@@ -0,0 +1,36 @@
+# commit to be tagged for new release
+commit = "HEAD"
+
+# project_name is used to refer to the project in the notes
+project_name = "containerd"
+
+# github_repo is the github project, only github is currently supported
+github_repo = "containerd/containerd"
+
+# match_deps is a pattern to determine which dependencies should be included
+# as part of this release. The changelog will also include changes for these
+# dependencies based on the change in the dependency's version.
+match_deps = "^github.com/(containerd/[a-zA-Z0-9-]+)$"
+
+# previous release of this project for determining changes
+previous = "v1.6.20"
+
+# pre_release is whether to include a disclaimer about being a pre-release
+pre_release = false
+
+# preface is the description of the release which precedes the author list
+# and changelog. This description could include highlights as well as any
+# description of changes. Use markdown formatting.
+preface = """\
+The twenty-first patch release for containerd 1.6 contains various fixes and 
updates.
+
+### Notable Updates
+
+* **update runc binary to v1.1.7 
([#8450](https://github.com/containerd/containerd/pull/8450))
+* **Remove entry for container from container store on error 
([#8456](https://github.com/containerd/containerd/pull/8456))
+* **oci: partially restore comment on read-only mounts for uid/gid uses 
([#8403](https://github.com/containerd/containerd/pull/8403))
+* **windows: Add ArgsEscaped support for CRI 
([#8247](https://github.com/containerd/containerd/pull/8247))
+* **oci: Use WithReadonlyTempMount when adding users/groups 
([#8357](https://github.com/containerd/containerd/pull/8357))
+* **archive: consistently respect value of WithSkipDockerManifest 
([#8345](https://github.com/containerd/containerd/pull/8345))
+
+See the changelog for complete list of changes"""
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/script/setup/prepare_env_windows.ps1 
new/containerd-1.6.21_3dce8eb055cb/script/setup/prepare_env_windows.ps1
--- old/containerd-1.6.20_2806fc105739/script/setup/prepare_env_windows.ps1     
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/script/setup/prepare_env_windows.ps1     
2023-05-05 17:13:28.000000000 +0200
@@ -5,7 +5,7 @@
 # lived test environment.
 Set-MpPreference -DisableRealtimeMonitoring:$true
 
-$PACKAGES= @{ mingw = "10.2.0"; git = ""; golang = "1.19.7"; make = ""; nssm = 
"" }
+$PACKAGES= @{ mingw = "10.2.0"; git = ""; golang = "1.19.9"; make = ""; nssm = 
"" }
 
 Write-Host "Downloading chocolatey package"
 curl.exe -L "https://packages.chocolatey.org/chocolatey.0.10.15.nupkg"; -o 
'c:\choco.zip'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/containerd-1.6.20_2806fc105739/script/setup/runc-version 
new/containerd-1.6.21_3dce8eb055cb/script/setup/runc-version
--- old/containerd-1.6.20_2806fc105739/script/setup/runc-version        
2023-03-30 22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/script/setup/runc-version        
2023-05-05 17:13:28.000000000 +0200
@@ -1 +1 @@
-v1.1.5
+v1.1.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/containerd-1.6.20_2806fc105739/task.go 
new/containerd-1.6.21_3dce8eb055cb/task.go
--- old/containerd-1.6.20_2806fc105739/task.go  2023-03-30 22:30:13.000000000 
+0200
+++ new/containerd-1.6.21_3dce8eb055cb/task.go  2023-05-05 17:13:28.000000000 
+0200
@@ -139,6 +139,11 @@
        RootFS []mount.Mount
        // Options hold runtime specific settings for task creation
        Options interface{}
+       // RuntimePath is an absolute path that can be used to overwrite path
+       // to a shim runtime binary.
+       RuntimePath string
+
+       // runtime is the runtime name for the container, and cannot be changed.
        runtime string
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/containerd-1.6.20_2806fc105739/task_opts.go 
new/containerd-1.6.21_3dce8eb055cb/task_opts.go
--- old/containerd-1.6.20_2806fc105739/task_opts.go     2023-03-30 
22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/task_opts.go     2023-05-05 
17:13:28.000000000 +0200
@@ -49,7 +49,7 @@
 // instead of resolving it from runtime name.
 func WithRuntimePath(absRuntimePath string) NewTaskOpts {
        return func(ctx context.Context, client *Client, info *TaskInfo) error {
-               info.runtime = absRuntimePath
+               info.RuntimePath = absRuntimePath
                return nil
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/containerd-1.6.20_2806fc105739/version/version.go 
new/containerd-1.6.21_3dce8eb055cb/version/version.go
--- old/containerd-1.6.20_2806fc105739/version/version.go       2023-03-30 
22:30:13.000000000 +0200
+++ new/containerd-1.6.21_3dce8eb055cb/version/version.go       2023-05-05 
17:13:28.000000000 +0200
@@ -23,7 +23,7 @@
        Package = "github.com/containerd/containerd"
 
        // Version holds the complete version number. Filled in at linking time.
-       Version = "1.6.20+unknown"
+       Version = "1.6.21+unknown"
 
        // Revision is filled with the VCS (e.g. git) revision being used to 
build
        // the program at linking time.

Reply via email to