From c4763e02d12815ebcbde6db7f5a231feecd844d5 Mon Sep 17 00:00:00 2001
From: Sebastiaan van Stijn <github@gone.nl>
Date: Tue, 12 Feb 2019 14:16:54 +0100
Subject: [PATCH] Update containerd to 1.2.3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
---
 hack/dockerfile/install/containerd.installer  |  2 +-
 vendor.conf                                   |  6 +-
 .../containerd/containerd/archive/tar.go      |  4 +-
 .../containerd/archive/tar_windows.go         |  8 +-
 .../containerd/containerd/client.go           | 38 ++++++--
 .../containerd/content/local/locks.go         |  4 +-
 .../containerd/contrib/seccomp/seccomp.go     |  4 +-
 .../containerd/containerd/filters/scanner.go  |  1 -
 .../containerd/containerd/import.go           |  3 +-
 .../containerd/containerd/metadata/content.go |  2 +-
 .../containerd/containerd/metadata/db.go      |  8 +-
 .../containerd/containerd/metadata/gc.go      |  4 -
 .../containerd/metadata/snapshot.go           |  2 +-
 .../containerd/mount/mountinfo_linux.go       |  8 +-
 .../containerd/containerd/plugin/plugin.go    |  5 +-
 .../containerd/containerd/process.go          |  8 +-
 .../containerd/remotes/docker/auth.go         |  4 +-
 .../containerd/remotes/docker/converter.go    | 88 +++++++++++++++++++
 .../containerd/containerd/runtime/runtime.go  |  4 +
 .../runtime/v1/linux/proc/deleted_state.go    |  4 -
 .../containerd/runtime/v1/linux/proc/exec.go  | 29 +++---
 .../runtime/v1/linux/proc/exec_state.go       | 17 ----
 .../containerd/runtime/v1/linux/proc/init.go  |  8 +-
 .../runtime/v1/linux/proc/init_state.go       |  2 +-
 .../containerd/runtime/v1/linux/proc/io.go    |  2 +-
 .../containerd/runtime/v1/linux/proc/utils.go | 13 +++
 .../containerd/runtime/v1/linux/runtime.go    | 10 +++
 .../github.com/containerd/containerd/task.go  |  6 +-
 .../containerd/containerd/vendor.conf         |  4 +-
 .../containerd/cri/pkg/util/strings.go        |  4 +-
 vendor/github.com/containerd/cri/vendor.conf  |  4 +-
 .../runc/libcontainer/cgroups/utils.go        |  2 +-
 32 files changed, 207 insertions(+), 101 deletions(-)
 create mode 100644 vendor/github.com/containerd/containerd/remotes/docker/converter.go

diff --git a/hack/dockerfile/install/containerd.installer b/hack/dockerfile/install/containerd.installer
index 5d78c8471d..0a3bc552a7 100755
--- a/hack/dockerfile/install/containerd.installer
+++ b/hack/dockerfile/install/containerd.installer
@@ -4,7 +4,7 @@
 # containerd is also pinned in vendor.conf. When updating the binary
 # version you may also need to update the vendor version to pick up bug
 # fixes or new APIs.
-CONTAINERD_COMMIT=9754871865f7fe2f4e74d43e2fc7ccd237edcbce # v1.2.2
+CONTAINERD_COMMIT=7f5f1176dd9fb3cc8d3ce5de91759ed3dc969fa2 # v1.2.3
 
 install_containerd() {
 	echo "Install containerd version $CONTAINERD_COMMIT"
diff --git a/vendor.conf b/vendor.conf
index b5d310e0ea..7cd6d6cb64 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -78,7 +78,7 @@ google.golang.org/grpc v1.12.0
 # the containerd project first, and update both after that is merged.
 # This commit does not need to match RUNC_COMMIT as it is used for helper
 # packages but should be newer or equal.
-github.com/opencontainers/runc 96ec2177ae841256168fcf76954f7177af9446eb
+github.com/opencontainers/runc 12f6a991201fdb8f82579582d5e00e28fba06d0a
 github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
 github.com/opencontainers/image-spec v1.0.1
 github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
@@ -117,12 +117,12 @@ github.com/googleapis/gax-go v2.0.0
 google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
 
 # containerd
-github.com/containerd/containerd 9754871865f7fe2f4e74d43e2fc7ccd237edcbce # v1.2.2
+github.com/containerd/containerd 7f5f1176dd9fb3cc8d3ce5de91759ed3dc969fa2 # v1.2.3
 github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
 github.com/containerd/continuity 004b46473808b3e7a4a3049c20e4376c91eb966d
 github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2
 github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
-github.com/containerd/cri 0d5cabd006cb5319dc965046067b8432d9fa5ef8 # release/1.2 branch
+github.com/containerd/cri c3cf754321fc38c6af5dfd2552fdde0ad192b31d # release/1.2 branch
 github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3
 github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
 github.com/containerd/ttrpc 2a805f71863501300ae1976d29f0454ae003e85a
diff --git a/vendor/github.com/containerd/containerd/archive/tar.go b/vendor/github.com/containerd/containerd/archive/tar.go
index ac04e3e023..0d9e0e7501 100644
--- a/vendor/github.com/containerd/containerd/archive/tar.go
+++ b/vendor/github.com/containerd/containerd/archive/tar.go
@@ -100,7 +100,7 @@ const (
 	// readdir calls to this directory do not follow to lower layers.
 	whiteoutOpaqueDir = whiteoutMetaPrefix + ".opq"
 
-	paxSchilyXattr = "SCHILY.xattrs."
+	paxSchilyXattr = "SCHILY.xattr."
 )
 
 // Apply applies a tar stream of an OCI style diff tar.
@@ -295,7 +295,7 @@ func applyNaive(ctx context.Context, root string, tr *tar.Reader, options ApplyO
 			linkBasename := filepath.Base(hdr.Linkname)
 			srcHdr = aufsHardlinks[linkBasename]
 			if srcHdr == nil {
-				return 0, fmt.Errorf("Invalid aufs hardlink")
+				return 0, fmt.Errorf("invalid aufs hardlink")
 			}
 			p, err := fs.RootPath(aufsTempdir, linkBasename)
 			if err != nil {
diff --git a/vendor/github.com/containerd/containerd/archive/tar_windows.go b/vendor/github.com/containerd/containerd/archive/tar_windows.go
index a3f585ac81..b97631fcc5 100644
--- a/vendor/github.com/containerd/containerd/archive/tar_windows.go
+++ b/vendor/github.com/containerd/containerd/archive/tar_windows.go
@@ -74,7 +74,7 @@ func tarName(p string) (string, error) {
 	// in file names, it is mostly safe to replace however we must
 	// check just in case
 	if strings.Contains(p, "/") {
-		return "", fmt.Errorf("Windows path contains forward slash: %s", p)
+		return "", fmt.Errorf("windows path contains forward slash: %s", p)
 	}
 
 	return strings.Replace(p, string(os.PathSeparator), "/", -1), nil
@@ -130,11 +130,7 @@ func skipFile(hdr *tar.Header) bool {
 	// specific or Linux-specific, this warning should be changed to an error
 	// to cater for the situation where someone does manage to upload a Linux
 	// image but have it tagged as Windows inadvertently.
-	if strings.Contains(hdr.Name, ":") {
-		return true
-	}
-
-	return false
+	return strings.Contains(hdr.Name, ":")
 }
 
 // handleTarTypeBlockCharFifo is an OS-specific helper function used by
diff --git a/vendor/github.com/containerd/containerd/client.go b/vendor/github.com/containerd/containerd/client.go
index fd20c3dd0e..f909bae1a7 100644
--- a/vendor/github.com/containerd/containerd/client.go
+++ b/vendor/github.com/containerd/containerd/client.go
@@ -401,12 +401,22 @@ func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, lim
 	}
 
 	var (
-		schema1Converter *schema1.Converter
-		handler          images.Handler
+		handler images.Handler
+
+		isConvertible bool
+		converterFunc func(context.Context, ocispec.Descriptor) (ocispec.Descriptor, error)
 	)
+
 	if desc.MediaType == images.MediaTypeDockerSchema1Manifest && rCtx.ConvertSchema1 {
-		schema1Converter = schema1.NewConverter(store, fetcher)
+		schema1Converter := schema1.NewConverter(store, fetcher)
+
 		handler = images.Handlers(append(rCtx.BaseHandlers, schema1Converter)...)
+
+		isConvertible = true
+
+		converterFunc = func(ctx context.Context, _ ocispec.Descriptor) (ocispec.Descriptor, error) {
+			return schema1Converter.Convert(ctx)
+		}
 	} else {
 		// Get all the children for a descriptor
 		childrenHandler := images.ChildrenHandler(store)
@@ -419,18 +429,34 @@ func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, lim
 			childrenHandler = images.LimitManifests(childrenHandler, rCtx.PlatformMatcher, limit)
 		}
 
+		// set isConvertible to true if there is application/octet-stream media type
+		convertibleHandler := images.HandlerFunc(
+			func(_ context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
+				if desc.MediaType == docker.LegacyConfigMediaType {
+					isConvertible = true
+				}
+
+				return []ocispec.Descriptor{}, nil
+			},
+		)
+
 		handler = images.Handlers(append(rCtx.BaseHandlers,
 			remotes.FetchHandler(store, fetcher),
+			convertibleHandler,
 			childrenHandler,
 		)...)
+
+		converterFunc = func(ctx context.Context, desc ocispec.Descriptor) (ocispec.Descriptor, error) {
+			return docker.ConvertManifest(ctx, store, desc)
+		}
 	}
 
 	if err := images.Dispatch(ctx, handler, desc); err != nil {
 		return images.Image{}, err
 	}
-	if schema1Converter != nil {
-		desc, err = schema1Converter.Convert(ctx)
-		if err != nil {
+
+	if isConvertible {
+		if desc, err = converterFunc(ctx, desc); err != nil {
 			return images.Image{}, err
 		}
 	}
diff --git a/vendor/github.com/containerd/containerd/content/local/locks.go b/vendor/github.com/containerd/containerd/content/local/locks.go
index 411c29a9d9..bc3bd18e09 100644
--- a/vendor/github.com/containerd/containerd/content/local/locks.go
+++ b/vendor/github.com/containerd/containerd/content/local/locks.go
@@ -47,7 +47,5 @@ func unlock(ref string) {
 	locksMu.Lock()
 	defer locksMu.Unlock()
 
-	if _, ok := locks[ref]; ok {
-		delete(locks, ref)
-	}
+	delete(locks, ref)
 }
diff --git a/vendor/github.com/containerd/containerd/contrib/seccomp/seccomp.go b/vendor/github.com/containerd/containerd/contrib/seccomp/seccomp.go
index 4619681f45..275a4c3e6c 100644
--- a/vendor/github.com/containerd/containerd/contrib/seccomp/seccomp.go
+++ b/vendor/github.com/containerd/containerd/contrib/seccomp/seccomp.go
@@ -37,10 +37,10 @@ func WithProfile(profile string) oci.SpecOpts {
 		s.Linux.Seccomp = &specs.LinuxSeccomp{}
 		f, err := ioutil.ReadFile(profile)
 		if err != nil {
-			return fmt.Errorf("Cannot load seccomp profile %q: %v", profile, err)
+			return fmt.Errorf("cannot load seccomp profile %q: %v", profile, err)
 		}
 		if err := json.Unmarshal(f, s.Linux.Seccomp); err != nil {
-			return fmt.Errorf("Decoding seccomp profile failed %q: %v", profile, err)
+			return fmt.Errorf("decoding seccomp profile failed %q: %v", profile, err)
 		}
 		return nil
 	}
diff --git a/vendor/github.com/containerd/containerd/filters/scanner.go b/vendor/github.com/containerd/containerd/filters/scanner.go
index c3961962cc..45c52606da 100644
--- a/vendor/github.com/containerd/containerd/filters/scanner.go
+++ b/vendor/github.com/containerd/containerd/filters/scanner.go
@@ -185,7 +185,6 @@ func (s *scanner) scanQuoted(quote rune) {
 			ch = s.next()
 		}
 	}
-	return
 }
 
 func (s *scanner) scanEscape(quote rune) rune {
diff --git a/vendor/github.com/containerd/containerd/import.go b/vendor/github.com/containerd/containerd/import.go
index 3650568240..e00f502a0d 100644
--- a/vendor/github.com/containerd/containerd/import.go
+++ b/vendor/github.com/containerd/containerd/import.go
@@ -99,8 +99,7 @@ func (c *Client) Import(ctx context.Context, reader io.Reader, opts ...ImportOpt
 		})
 	}
 
-	var handler images.HandlerFunc
-	handler = func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
+	var handler images.HandlerFunc = func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
 		// Only save images at top level
 		if desc.Digest != index.Digest {
 			return images.Children(ctx, cs, desc)
diff --git a/vendor/github.com/containerd/containerd/metadata/content.go b/vendor/github.com/containerd/containerd/metadata/content.go
index 8ee0f2e201..36737ee47b 100644
--- a/vendor/github.com/containerd/containerd/metadata/content.go
+++ b/vendor/github.com/containerd/containerd/metadata/content.go
@@ -762,7 +762,7 @@ func (cs *contentStore) garbageCollect(ctx context.Context) (d time.Duration, er
 	t1 := time.Now()
 	defer func() {
 		if err == nil {
-			d = time.Now().Sub(t1)
+			d = time.Since(t1)
 		}
 		cs.l.Unlock()
 	}()
diff --git a/vendor/github.com/containerd/containerd/metadata/db.go b/vendor/github.com/containerd/containerd/metadata/db.go
index 507d6d22d0..97509bd9ea 100644
--- a/vendor/github.com/containerd/containerd/metadata/db.go
+++ b/vendor/github.com/containerd/containerd/metadata/db.go
@@ -154,7 +154,7 @@ func (m *DB) Init(ctx context.Context) error {
 				if err := m.migrate(tx); err != nil {
 					return errors.Wrapf(err, "failed to migrate to %s.%d", m.schema, m.version)
 				}
-				log.G(ctx).WithField("d", time.Now().Sub(t0)).Debugf("finished database migration to %s.%d", m.schema, m.version)
+				log.G(ctx).WithField("d", time.Since(t0)).Debugf("finished database migration to %s.%d", m.schema, m.version)
 			}
 		}
 
@@ -306,7 +306,7 @@ func (m *DB) GarbageCollect(ctx context.Context) (gc.Stats, error) {
 				m.cleanupSnapshotter(snapshotterName)
 
 				sl.Lock()
-				stats.SnapshotD[snapshotterName] = time.Now().Sub(st1)
+				stats.SnapshotD[snapshotterName] = time.Since(st1)
 				sl.Unlock()
 
 				wg.Done()
@@ -321,7 +321,7 @@ func (m *DB) GarbageCollect(ctx context.Context) (gc.Stats, error) {
 		go func() {
 			ct1 := time.Now()
 			m.cleanupContent()
-			stats.ContentD = time.Now().Sub(ct1)
+			stats.ContentD = time.Since(ct1)
 			wg.Done()
 		}()
 		m.dirtyCS = false
@@ -329,7 +329,7 @@ func (m *DB) GarbageCollect(ctx context.Context) (gc.Stats, error) {
 
 	m.dirtyL.Unlock()
 
-	stats.MetaD = time.Now().Sub(t1)
+	stats.MetaD = time.Since(t1)
 	m.wlock.Unlock()
 
 	wg.Wait()
diff --git a/vendor/github.com/containerd/containerd/metadata/gc.go b/vendor/github.com/containerd/containerd/metadata/gc.go
index a670ce1a3e..99503fad7d 100644
--- a/vendor/github.com/containerd/containerd/metadata/gc.go
+++ b/vendor/github.com/containerd/containerd/metadata/gc.go
@@ -296,10 +296,6 @@ func references(ctx context.Context, tx *bolt.Tx, node gc.Node, fn func(gc.Node)
 
 		bkt := getBucket(tx, bucketKeyVersion, []byte(node.Namespace), bucketKeyObjectSnapshots, []byte(ss), []byte(name))
 		if bkt == nil {
-			getBucket(tx, bucketKeyVersion, []byte(node.Namespace), bucketKeyObjectSnapshots).ForEach(func(k, v []byte) error {
-				return nil
-			})
-
 			// Node may be created from dead edge
 			return nil
 		}
diff --git a/vendor/github.com/containerd/containerd/metadata/snapshot.go b/vendor/github.com/containerd/containerd/metadata/snapshot.go
index 75b80b0bc5..b1665c0191 100644
--- a/vendor/github.com/containerd/containerd/metadata/snapshot.go
+++ b/vendor/github.com/containerd/containerd/metadata/snapshot.go
@@ -628,7 +628,7 @@ func (s *snapshotter) garbageCollect(ctx context.Context) (d time.Duration, err
 			}
 		}
 		if err == nil {
-			d = time.Now().Sub(t1)
+			d = time.Since(t1)
 		}
 	}()
 
diff --git a/vendor/github.com/containerd/containerd/mount/mountinfo_linux.go b/vendor/github.com/containerd/containerd/mount/mountinfo_linux.go
index a986f8f4ea..369d045d7d 100644
--- a/vendor/github.com/containerd/containerd/mount/mountinfo_linux.go
+++ b/vendor/github.com/containerd/containerd/mount/mountinfo_linux.go
@@ -68,7 +68,7 @@ func parseInfoFile(r io.Reader) ([]Info, error) {
 		numFields := len(fields)
 		if numFields < 10 {
 			// should be at least 10 fields
-			return nil, fmt.Errorf("Parsing '%s' failed: not enough fields (%d)", text, numFields)
+			return nil, fmt.Errorf("parsing '%s' failed: not enough fields (%d)", text, numFields)
 		}
 		p := Info{}
 		// ignore any numbers parsing errors, as there should not be any
@@ -76,7 +76,7 @@ func parseInfoFile(r io.Reader) ([]Info, error) {
 		p.Parent, _ = strconv.Atoi(fields[1])
 		mm := strings.Split(fields[2], ":")
 		if len(mm) != 2 {
-			return nil, fmt.Errorf("Parsing '%s' failed: unexpected minor:major pair %s", text, mm)
+			return nil, fmt.Errorf("parsing '%s' failed: unexpected minor:major pair %s", text, mm)
 		}
 		p.Major, _ = strconv.Atoi(mm[0])
 		p.Minor, _ = strconv.Atoi(mm[1])
@@ -101,11 +101,11 @@ func parseInfoFile(r io.Reader) ([]Info, error) {
 			}
 		}
 		if i == numFields {
-			return nil, fmt.Errorf("Parsing '%s' failed: missing separator ('-')", text)
+			return nil, fmt.Errorf("parsing '%s' failed: missing separator ('-')", text)
 		}
 		// There should be 3 fields after the separator...
 		if i+4 > numFields {
-			return nil, fmt.Errorf("Parsing '%s' failed: not enough fields after a separator", text)
+			return nil, fmt.Errorf("parsing '%s' failed: not enough fields after a separator", text)
 		}
 		// ... but in Linux <= 3.9 mounting a cifs with spaces in a share name
 		// (like "//serv/My Documents") _may_ end up having a space in the last field
diff --git a/vendor/github.com/containerd/containerd/plugin/plugin.go b/vendor/github.com/containerd/containerd/plugin/plugin.go
index 0847ae7f28..4d2d486d09 100644
--- a/vendor/github.com/containerd/containerd/plugin/plugin.go
+++ b/vendor/github.com/containerd/containerd/plugin/plugin.go
@@ -42,10 +42,7 @@ var (
 
 // IsSkipPlugin returns true if the error is skipping the plugin
 func IsSkipPlugin(err error) bool {
-	if errors.Cause(err) == ErrSkipPlugin {
-		return true
-	}
-	return false
+	return errors.Cause(err) == ErrSkipPlugin
 }
 
 // Type is the type of the plugin
diff --git a/vendor/github.com/containerd/containerd/process.go b/vendor/github.com/containerd/containerd/process.go
index ff7d838cde..42f3b84a9b 100644
--- a/vendor/github.com/containerd/containerd/process.go
+++ b/vendor/github.com/containerd/containerd/process.go
@@ -111,9 +111,11 @@ func (p *process) Start(ctx context.Context) error {
 		ExecID:      p.id,
 	})
 	if err != nil {
-		p.io.Cancel()
-		p.io.Wait()
-		p.io.Close()
+		if p.io != nil {
+			p.io.Cancel()
+			p.io.Wait()
+			p.io.Close()
+		}
 		return errdefs.FromGRPC(err)
 	}
 	p.pid = r.Pid
diff --git a/vendor/github.com/containerd/containerd/remotes/docker/auth.go b/vendor/github.com/containerd/containerd/remotes/docker/auth.go
index 80bcb9dcf7..70cfdea4f3 100644
--- a/vendor/github.com/containerd/containerd/remotes/docker/auth.go
+++ b/vendor/github.com/containerd/containerd/remotes/docker/auth.go
@@ -79,8 +79,8 @@ func init() {
 		var t octetType
 		isCtl := c <= 31 || c == 127
 		isChar := 0 <= c && c <= 127
-		isSeparator := strings.IndexRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) >= 0
-		if strings.IndexRune(" \t\r\n", rune(c)) >= 0 {
+		isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c))
+		if strings.ContainsRune(" \t\r\n", rune(c)) {
 			t |= isSpace
 		}
 		if isChar && !isCtl && !isSeparator {
diff --git a/vendor/github.com/containerd/containerd/remotes/docker/converter.go b/vendor/github.com/containerd/containerd/remotes/docker/converter.go
new file mode 100644
index 0000000000..43e6b372c1
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/remotes/docker/converter.go
@@ -0,0 +1,88 @@
+/*
+   Copyright The containerd Authors.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package docker
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"fmt"
+
+	"github.com/containerd/containerd/content"
+	"github.com/containerd/containerd/images"
+	"github.com/containerd/containerd/log"
+	"github.com/containerd/containerd/remotes"
+	digest "github.com/opencontainers/go-digest"
+	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
+	"github.com/pkg/errors"
+)
+
+// LegacyConfigMediaType should be replaced by OCI image spec.
+//
+// More detail: docker/distribution#1622
+const LegacyConfigMediaType = "application/octet-stream"
+
+// ConvertManifest changes application/octet-stream to schema2 config media type if need.
+//
+// NOTE:
+// 1. original manifest will be deleted by next gc round.
+// 2. don't cover manifest list.
+func ConvertManifest(ctx context.Context, store content.Store, desc ocispec.Descriptor) (ocispec.Descriptor, error) {
+	if !(desc.MediaType == images.MediaTypeDockerSchema2Manifest ||
+		desc.MediaType == ocispec.MediaTypeImageManifest) {
+
+		log.G(ctx).Warnf("do nothing for media type: %s", desc.MediaType)
+		return desc, nil
+	}
+
+	// read manifest data
+	mb, err := content.ReadBlob(ctx, store, desc)
+	if err != nil {
+		return ocispec.Descriptor{}, errors.Wrap(err, "failed to read index data")
+	}
+
+	var manifest ocispec.Manifest
+	if err := json.Unmarshal(mb, &manifest); err != nil {
+		return ocispec.Descriptor{}, errors.Wrap(err, "failed to unmarshal data into manifest")
+	}
+
+	// check config media type
+	if manifest.Config.MediaType != LegacyConfigMediaType {
+		return desc, nil
+	}
+
+	manifest.Config.MediaType = images.MediaTypeDockerSchema2Config
+	data, err := json.MarshalIndent(manifest, "", "   ")
+	if err != nil {
+		return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal manifest")
+	}
+
+	// update manifest with gc labels
+	desc.Digest = digest.Canonical.FromBytes(data)
+	desc.Size = int64(len(data))
+
+	labels := map[string]string{}
+	for i, c := range append([]ocispec.Descriptor{manifest.Config}, manifest.Layers...) {
+		labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = c.Digest.String()
+	}
+
+	ref := remotes.MakeRefKey(ctx, desc)
+	if err := content.WriteBlob(ctx, store, ref, bytes.NewReader(data), desc, content.WithLabels(labels)); err != nil {
+		return ocispec.Descriptor{}, errors.Wrap(err, "failed to update content")
+	}
+	return desc, nil
+}
diff --git a/vendor/github.com/containerd/containerd/runtime/runtime.go b/vendor/github.com/containerd/containerd/runtime/runtime.go
index 1b3f87c152..5a3f654bd3 100644
--- a/vendor/github.com/containerd/containerd/runtime/runtime.go
+++ b/vendor/github.com/containerd/containerd/runtime/runtime.go
@@ -69,4 +69,8 @@ type PlatformRuntime interface {
 	// Tasks returns all the current tasks for the runtime.
 	// Any container runs at most one task at a time.
 	Tasks(context.Context, bool) ([]Task, error)
+	// Add adds a task into runtime.
+	Add(context.Context, Task) error
+	// Delete remove a task.
+	Delete(context.Context, string)
 }
diff --git a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/deleted_state.go b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/deleted_state.go
index bc9aefb7fb..ab89c3ecba 100644
--- a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/deleted_state.go
+++ b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/deleted_state.go
@@ -69,7 +69,3 @@ func (s *deletedState) SetExited(status int) {
 func (s *deletedState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
 	return nil, errors.Errorf("cannot exec in a deleted state")
 }
-
-func (s *deletedState) Pid() int {
-	return -1
-}
diff --git a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec.go b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec.go
index cefce6cc3c..5dbfbaf620 100644
--- a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec.go
+++ b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec.go
@@ -49,7 +49,7 @@ type execProcess struct {
 	io      runc.IO
 	status  int
 	exited  time.Time
-	pid     int
+	pid     *safePid
 	closers []io.Closer
 	stdin   io.Closer
 	stdio   proc.Stdio
@@ -69,11 +69,7 @@ func (e *execProcess) ID() string {
 }
 
 func (e *execProcess) Pid() int {
-	return e.execState.Pid()
-}
-
-func (e *execProcess) pidv() int {
-	return e.pid
+	return e.pid.get()
 }
 
 func (e *execProcess) ExitStatus() int {
@@ -145,7 +141,7 @@ func (e *execProcess) Kill(ctx context.Context, sig uint32, _ bool) error {
 }
 
 func (e *execProcess) kill(ctx context.Context, sig uint32, _ bool) error {
-	pid := e.pid
+	pid := e.pid.get()
 	if pid != 0 {
 		if err := unix.Kill(pid, syscall.Signal(sig)); err != nil {
 			return errors.Wrapf(checkKillError(err), "exec kill error")
@@ -170,6 +166,12 @@ func (e *execProcess) Start(ctx context.Context) error {
 }
 
 func (e *execProcess) start(ctx context.Context) (err error) {
+	// The reaper may receive exit signal right after
+	// the container is started, before the e.pid is updated.
+	// In that case, we want to block the signal handler to
+	// access e.pid until it is updated.
+	e.pid.Lock()
+	defer e.pid.Unlock()
 	var (
 		socket  *runc.Socket
 		pidfile = filepath.Join(e.path, fmt.Sprintf("%s.pid", e.id))
@@ -201,7 +203,7 @@ func (e *execProcess) start(ctx context.Context) (err error) {
 		return e.parent.runtimeError(err, "OCI runtime exec failed")
 	}
 	if e.stdio.Stdin != "" {
-		sc, err := fifo.OpenFifo(ctx, e.stdio.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
+		sc, err := fifo.OpenFifo(context.Background(), e.stdio.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
 		if err != nil {
 			return errors.Wrapf(err, "failed to open stdin fifo %s", e.stdio.Stdin)
 		}
@@ -210,29 +212,26 @@ func (e *execProcess) start(ctx context.Context) (err error) {
 	}
 	var copyWaitGroup sync.WaitGroup
 	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
+	defer cancel()
 	if socket != nil {
 		console, err := socket.ReceiveMaster()
 		if err != nil {
-			cancel()
 			return errors.Wrap(err, "failed to retrieve console master")
 		}
 		if e.console, err = e.parent.Platform.CopyConsole(ctx, console, e.stdio.Stdin, e.stdio.Stdout, e.stdio.Stderr, &e.wg, &copyWaitGroup); err != nil {
-			cancel()
 			return errors.Wrap(err, "failed to start console copy")
 		}
 	} else if !e.stdio.IsNull() {
 		if err := copyPipes(ctx, e.io, e.stdio.Stdin, e.stdio.Stdout, e.stdio.Stderr, &e.wg, &copyWaitGroup); err != nil {
-			cancel()
 			return errors.Wrap(err, "failed to start io pipe copy")
 		}
 	}
 	copyWaitGroup.Wait()
 	pid, err := runc.ReadPidFile(opts.PidFile)
 	if err != nil {
-		cancel()
 		return errors.Wrap(err, "failed to retrieve OCI runtime exec pid")
 	}
-	e.pid = pid
+	e.pid.pid = pid
 	return nil
 }
 
@@ -250,11 +249,11 @@ func (e *execProcess) Status(ctx context.Context) (string, error) {
 	e.mu.Lock()
 	defer e.mu.Unlock()
 	// if we don't have a pid then the exec process has just been created
-	if e.pid == 0 {
+	if e.pid.get() == 0 {
 		return "created", nil
 	}
 	// if we have a pid and it can be signaled, the process is running
-	if err := unix.Kill(e.pid, 0); err == nil {
+	if err := unix.Kill(e.pid.get(), 0); err == nil {
 		return "running", nil
 	}
 	// else if we have a pid but it can nolonger be signaled, it has stopped
diff --git a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec_state.go b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec_state.go
index 0e0bc3fcf2..12489501ba 100644
--- a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec_state.go
+++ b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec_state.go
@@ -31,7 +31,6 @@ type execState interface {
 	Delete(context.Context) error
 	Kill(context.Context, uint32, bool) error
 	SetExited(int)
-	Pid() int
 }
 
 type execCreatedState struct {
@@ -83,12 +82,6 @@ func (s *execCreatedState) SetExited(status int) {
 	}
 }
 
-func (s *execCreatedState) Pid() int {
-	s.p.mu.Lock()
-	defer s.p.mu.Unlock()
-	return s.p.pidv()
-}
-
 type execRunningState struct {
 	p *execProcess
 }
@@ -127,12 +120,6 @@ func (s *execRunningState) SetExited(status int) {
 	}
 }
 
-func (s *execRunningState) Pid() int {
-	s.p.mu.Lock()
-	defer s.p.mu.Unlock()
-	return s.p.pidv()
-}
-
 type execStoppedState struct {
 	p *execProcess
 }
@@ -170,7 +157,3 @@ func (s *execStoppedState) Kill(ctx context.Context, sig uint32, all bool) error
 func (s *execStoppedState) SetExited(status int) {
 	// no op
 }
-
-func (s *execStoppedState) Pid() int {
-	return s.p.pidv()
-}
diff --git a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init.go b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init.go
index c76bcfe43d..b72f03bd18 100644
--- a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init.go
+++ b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init.go
@@ -160,7 +160,7 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
 		return p.runtimeError(err, "OCI runtime create failed")
 	}
 	if r.Stdin != "" {
-		sc, err := fifo.OpenFifo(ctx, r.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
+		sc, err := fifo.OpenFifo(context.Background(), r.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
 		if err != nil {
 			return errors.Wrapf(err, "failed to open stdin fifo %s", r.Stdin)
 		}
@@ -169,21 +169,19 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
 	}
 	var copyWaitGroup sync.WaitGroup
 	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
+	defer cancel()
 	if socket != nil {
 		console, err := socket.ReceiveMaster()
 		if err != nil {
-			cancel()
 			return errors.Wrap(err, "failed to retrieve console master")
 		}
 		console, err = p.Platform.CopyConsole(ctx, console, r.Stdin, r.Stdout, r.Stderr, &p.wg, &copyWaitGroup)
 		if err != nil {
-			cancel()
 			return errors.Wrap(err, "failed to start console copy")
 		}
 		p.console = console
 	} else if !hasNoIO(r) {
 		if err := copyPipes(ctx, p.io, r.Stdin, r.Stdout, r.Stderr, &p.wg, &copyWaitGroup); err != nil {
-			cancel()
 			return errors.Wrap(err, "failed to start io pipe copy")
 		}
 	}
@@ -191,7 +189,6 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
 	copyWaitGroup.Wait()
 	pid, err := runc.ReadPidFile(pidFile)
 	if err != nil {
-		cancel()
 		return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
 	}
 	p.pid = pid
@@ -409,6 +406,7 @@ func (p *Init) exec(ctx context.Context, path string, r *ExecConfig) (proc.Proce
 			Terminal: r.Terminal,
 		},
 		waitBlock: make(chan struct{}),
+		pid:       &safePid{},
 	}
 	e.execState = &execCreatedState{p: e}
 	return e, nil
diff --git a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init_state.go b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init_state.go
index 37798de201..62cbe38cd9 100644
--- a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init_state.go
+++ b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init_state.go
@@ -172,7 +172,7 @@ func (s *createdCheckpointState) Start(ctx context.Context) error {
 		return p.runtimeError(err, "OCI runtime restore failed")
 	}
 	if sio.Stdin != "" {
-		sc, err := fifo.OpenFifo(ctx, sio.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
+		sc, err := fifo.OpenFifo(context.Background(), sio.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
 		if err != nil {
 			return errors.Wrapf(err, "failed to open stdin fifo %s", sio.Stdin)
 		}
diff --git a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/io.go b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/io.go
index 71f6ee1bb3..aed349a860 100644
--- a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/io.go
+++ b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/io.go
@@ -111,7 +111,7 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w
 	if stdin == "" {
 		return nil
 	}
-	f, err := fifo.OpenFifo(ctx, stdin, syscall.O_RDONLY|syscall.O_NONBLOCK, 0)
+	f, err := fifo.OpenFifo(context.Background(), stdin, syscall.O_RDONLY|syscall.O_NONBLOCK, 0)
 	if err != nil {
 		return fmt.Errorf("containerd-shim: opening %s failed: %s", stdin, err)
 	}
diff --git a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/utils.go b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/utils.go
index 04baae0f75..075ef26177 100644
--- a/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/utils.go
+++ b/vendor/github.com/containerd/containerd/runtime/v1/linux/proc/utils.go
@@ -23,6 +23,7 @@ import (
 	"io"
 	"os"
 	"strings"
+	"sync"
 	"time"
 
 	"github.com/containerd/containerd/errdefs"
@@ -31,6 +32,18 @@ import (
 	"golang.org/x/sys/unix"
 )
 
+// safePid is a thread safe wrapper for pid.
+type safePid struct {
+	sync.Mutex
+	pid int
+}
+
+func (s *safePid) get() int {
+	s.Lock()
+	defer s.Unlock()
+	return s.pid
+}
+
 // TODO(mlaventure): move to runc package?
 func getLastRuntimeError(r *runc.Runc) (string, error) {
 	if r.Log == "" {
diff --git a/vendor/github.com/containerd/containerd/runtime/v1/linux/runtime.go b/vendor/github.com/containerd/containerd/runtime/v1/linux/runtime.go
index d19b8e5168..d2edccbbec 100644
--- a/vendor/github.com/containerd/containerd/runtime/v1/linux/runtime.go
+++ b/vendor/github.com/containerd/containerd/runtime/v1/linux/runtime.go
@@ -303,6 +303,16 @@ func (r *Runtime) Get(ctx context.Context, id string) (runtime.Task, error) {
 	return r.tasks.Get(ctx, id)
 }
 
+// Add a runtime task
+func (r *Runtime) Add(ctx context.Context, task runtime.Task) error {
+	return r.tasks.Add(ctx, task)
+}
+
+// Delete a runtime task
+func (r *Runtime) Delete(ctx context.Context, id string) {
+	r.tasks.Delete(ctx, id)
+}
+
 func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
 	dir, err := ioutil.ReadDir(filepath.Join(r.state, ns))
 	if err != nil {
diff --git a/vendor/github.com/containerd/containerd/task.go b/vendor/github.com/containerd/containerd/task.go
index 6806e11620..1fbd1cc164 100644
--- a/vendor/github.com/containerd/containerd/task.go
+++ b/vendor/github.com/containerd/containerd/task.go
@@ -185,8 +185,10 @@ func (t *task) Start(ctx context.Context) error {
 		ContainerID: t.id,
 	})
 	if err != nil {
-		t.io.Cancel()
-		t.io.Close()
+		if t.io != nil {
+			t.io.Cancel()
+			t.io.Close()
+		}
 		return errdefs.FromGRPC(err)
 	}
 	t.pid = r.Pid
diff --git a/vendor/github.com/containerd/containerd/vendor.conf b/vendor/github.com/containerd/containerd/vendor.conf
index 25b1a01bd7..2488ca7730 100644
--- a/vendor/github.com/containerd/containerd/vendor.conf
+++ b/vendor/github.com/containerd/containerd/vendor.conf
@@ -20,7 +20,7 @@ github.com/gogo/protobuf v1.0.0
 github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef
 github.com/golang/protobuf v1.1.0
 github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353 # v1.0.1-45-geba862d
-github.com/opencontainers/runc 96ec2177ae841256168fcf76954f7177af9446eb
+github.com/opencontainers/runc 12f6a991201fdb8f82579582d5e00e28fba06d0a
 github.com/sirupsen/logrus v1.0.0
 github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
 golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
@@ -43,7 +43,7 @@ github.com/google/go-cmp v0.1.0
 go.etcd.io/bbolt v1.3.1-etcd.8
 
 # cri dependencies
-github.com/containerd/cri 0d5cabd006cb5319dc965046067b8432d9fa5ef8 # release/1.2 branch
+github.com/containerd/cri c3cf754321fc38c6af5dfd2552fdde0ad192b31d # release/1.2 branch
 github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90
 github.com/blang/semver v3.1.0
 github.com/containernetworking/cni v0.6.0
diff --git a/vendor/github.com/containerd/cri/pkg/util/strings.go b/vendor/github.com/containerd/cri/pkg/util/strings.go
index d5cbc2e8ef..4d06ecbf07 100644
--- a/vendor/github.com/containerd/cri/pkg/util/strings.go
+++ b/vendor/github.com/containerd/cri/pkg/util/strings.go
@@ -22,7 +22,7 @@ import "strings"
 // Comparison is case insensitive.
 func InStringSlice(ss []string, str string) bool {
 	for _, s := range ss {
-		if strings.ToLower(s) == strings.ToLower(str) {
+		if strings.EqualFold(s, str) {
 			return true
 		}
 	}
@@ -34,7 +34,7 @@ func InStringSlice(ss []string, str string) bool {
 func SubtractStringSlice(ss []string, str string) []string {
 	var res []string
 	for _, s := range ss {
-		if strings.ToLower(s) == strings.ToLower(str) {
+		if strings.EqualFold(s, str) {
 			continue
 		}
 		res = append(res, s)
diff --git a/vendor/github.com/containerd/cri/vendor.conf b/vendor/github.com/containerd/cri/vendor.conf
index 208a079b6a..26c3d89418 100644
--- a/vendor/github.com/containerd/cri/vendor.conf
+++ b/vendor/github.com/containerd/cri/vendor.conf
@@ -3,7 +3,7 @@ github.com/blang/semver v3.1.0
 github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
 github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2
 github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
-github.com/containerd/containerd 4b284fa3ab61832b022ba428055f793a75ffc251
+github.com/containerd/containerd 0137339c8c1d55de5545ffdd723199dfba27cb24
 github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4
 github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
 github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90
@@ -39,7 +39,7 @@ github.com/modern-go/concurrent 1.0.3
 github.com/modern-go/reflect2 1.0.1
 github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
 github.com/opencontainers/image-spec v1.0.1
-github.com/opencontainers/runc v1.0.0-rc6
+github.com/opencontainers/runc 12f6a991201fdb8f82579582d5e00e28fba06d0a
 github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353
 github.com/opencontainers/runtime-tools v0.6.0
 github.com/opencontainers/selinux b6fa367ed7f534f9ba25391cc2d467085dbb445a
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go
index 316d963d62..ea571ad937 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go
@@ -463,7 +463,7 @@ func WriteCgroupProc(dir string, pid int) error {
 		return fmt.Errorf("no such directory for %s", CgroupProcesses)
 	}
 
-	// Dont attach any pid to the cgroup if -1 is specified as a pid
+	// Don't attach any pid to the cgroup if -1 is specified as a pid
 	if pid != -1 {
 		if err := ioutil.WriteFile(filepath.Join(dir, CgroupProcesses), []byte(strconv.Itoa(pid)), 0700); err != nil {
 			return fmt.Errorf("failed to write %v to %v: %v", pid, CgroupProcesses, err)