Преглед изворни кода

vendor: update containerd to acdcf13d5eaf0dfe0eaeabe7194a82535549bc2b

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Tonis Tiigi пре 5 година
родитељ
комит
f632e2d8d3
31 измењених фајлова са 1797 додато и 52 уклоњено
  1. 2 2
      vendor.conf
  2. 28 0
      vendor/github.com/containerd/containerd/README.md
  3. 1 1
      vendor/github.com/containerd/containerd/images/archive/exporter.go
  4. 1 1
      vendor/github.com/containerd/containerd/images/archive/reference.go
  5. 10 2
      vendor/github.com/containerd/containerd/lease.go
  6. 15 1
      vendor/github.com/containerd/containerd/oci/spec_opts.go
  7. 57 0
      vendor/github.com/containerd/containerd/oci/spec_opts_linux.go
  8. 57 0
      vendor/github.com/containerd/containerd/oci/spec_opts_unix.go
  9. 7 0
      vendor/github.com/containerd/containerd/oci/spec_opts_windows.go
  10. 4 0
      vendor/github.com/containerd/containerd/pkg/process/deleted_state.go
  11. 1 13
      vendor/github.com/containerd/containerd/pkg/process/exec.go
  12. 13 0
      vendor/github.com/containerd/containerd/pkg/process/exec_state.go
  13. 14 14
      vendor/github.com/containerd/containerd/pkg/process/init.go
  14. 28 0
      vendor/github.com/containerd/containerd/pkg/process/init_state.go
  15. 3 1
      vendor/github.com/containerd/containerd/pkg/process/io.go
  16. 15 0
      vendor/github.com/containerd/containerd/pkg/process/utils.go
  17. 797 0
      vendor/github.com/containerd/containerd/reference/docker/reference.go
  18. 283 0
      vendor/github.com/containerd/containerd/remotes/docker/errcode.go
  19. 154 0
      vendor/github.com/containerd/containerd/remotes/docker/errdesc.go
  20. 1 2
      vendor/github.com/containerd/containerd/remotes/docker/fetcher.go
  21. 9 3
      vendor/github.com/containerd/containerd/runtime/v1/linux/task.go
  22. 3 3
      vendor/github.com/containerd/containerd/runtime/v1/shim/service.go
  23. 2 2
      vendor/github.com/containerd/containerd/runtime/v1/shim/service_linux.go
  24. 4 4
      vendor/github.com/containerd/containerd/vendor.conf
  25. 5 0
      vendor/github.com/containerd/containerd/version/version.go
  26. 8 2
      vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go
  27. 1 0
      vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
  28. 93 0
      vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go
  29. 112 0
      vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go
  30. 68 0
      vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go
  31. 1 1
      vendor/github.com/opencontainers/runc/vendor.conf

+ 2 - 2
vendor.conf

@@ -80,7 +80,7 @@ google.golang.org/grpc                              6eaf6f47437a6b4e2153a190160e
 # the containerd project first, and update both after that is merged.
 # 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
 # This commit does not need to match RUNC_COMMIT as it is used for helper
 # packages but should be newer or equal.
 # packages but should be newer or equal.
-github.com/opencontainers/runc                      3e425f80a8c931f88e6d94a8c831b9d5aa481657 # v1.0.0-rc8-92-g84373aaa
+github.com/opencontainers/runc                      d736ef14f0288d6993a1845745d6756cfc9ddd5a # v1.0.0-rc9
 github.com/opencontainers/runtime-spec              29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
 github.com/opencontainers/runtime-spec              29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
 github.com/opencontainers/image-spec                d60099175f88c47cd379c4738d158884749ed235 # v1.0.1
 github.com/opencontainers/image-spec                d60099175f88c47cd379c4738d158884749ed235 # v1.0.1
 github.com/seccomp/libseccomp-golang                689e3c1541a84461afc49c1c87352a6cedf72e9c # v0.9.1
 github.com/seccomp/libseccomp-golang                689e3c1541a84461afc49c1c87352a6cedf72e9c # v0.9.1
@@ -117,7 +117,7 @@ github.com/googleapis/gax-go                        317e0006254c44a0ac427cc52a0e
 google.golang.org/genproto                          694d95ba50e67b2e363f3483057db5d4910c18f9
 google.golang.org/genproto                          694d95ba50e67b2e363f3483057db5d4910c18f9
 
 
 # containerd
 # containerd
-github.com/containerd/containerd                    36cf5b690dcc00ff0f34ff7799209050c3d0c59a # v1.3.0
+github.com/containerd/containerd                    acdcf13d5eaf0dfe0eaeabe7194a82535549bc2b
 github.com/containerd/fifo                          bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
 github.com/containerd/fifo                          bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
 github.com/containerd/continuity                    f2a389ac0a02ce21c09edd7344677a601970f41c
 github.com/containerd/continuity                    f2a389ac0a02ce21c09edd7344677a601970f41c
 github.com/containerd/cgroups                       5fbad35c2a7e855762d3c60f2e474ffcad0d470a
 github.com/containerd/cgroups                       5fbad35c2a7e855762d3c60f2e474ffcad0d470a

+ 28 - 0
vendor/github.com/containerd/containerd/README.md

@@ -210,6 +210,34 @@ See [PLUGINS.md](PLUGINS.md) for how to create plugins
 Please see [RELEASES.md](RELEASES.md) for details on versioning and stability
 Please see [RELEASES.md](RELEASES.md) for details on versioning and stability
 of containerd components.
 of containerd components.
 
 
+Downloadable 64-bit Intel/AMD binaries of all official releases are available on
+our [releases page](https://github.com/containerd/containerd/releases), as well as
+auto-published to the [cri-containerd-release storage bucket](https://console.cloud.google.com/storage/browser/cri-containerd-release?pli=1).
+
+For other architectures and distribution support, you will find that many
+Linux distributions package their own containerd and provide it across several
+architectures, such as [Canonical's Ubuntu packaging](https://launchpad.net/ubuntu/bionic/+package/containerd).
+
+#### Enabling command auto-completion
+
+Starting with containerd 1.4, the urfave client feature for auto-creation of bash
+autocompletion data is enabled. To use the autocomplete feature in your shell, source
+the autocomplete/bash_autocomplete file in your .bashrc file while setting the `PROG`
+variable to `ctr`:
+
+```
+$ PROG=ctr source vendor/github.com/urfave/cli/autocomplete/bash_autocomplete
+```
+
+#### Distribution of `ctr` autocomplete for bash
+
+Copy `vendor/github.com/urfave/cli/autocomplete/bash_autocomplete` into
+`/etc/bash_completion.d/` and rename it to `ctr`.
+
+Provide documentation to users to `source` this file into their shell if
+you don't place the autocomplete file in a location where it is automatically
+loaded for user's bash shell environment.
+
 ### Communication
 ### Communication
 
 
 For async communication and long running discussions please use issues and pull requests on the github repo.
 For async communication and long running discussions please use issues and pull requests on the github repo.

+ 1 - 1
vendor/github.com/containerd/containerd/images/archive/exporter.go

@@ -263,7 +263,7 @@ func getRecords(ctx context.Context, store content.Provider, desc ocispec.Descri
 		images.HandlerFunc(exportHandler),
 		images.HandlerFunc(exportHandler),
 	)
 	)
 
 
-	// Walk sequentially since the number of fetchs is likely one and doing in
+	// Walk sequentially since the number of fetches is likely one and doing in
 	// parallel requires locking the export handler
 	// parallel requires locking the export handler
 	if err := images.Walk(ctx, handlers, desc); err != nil {
 	if err := images.Walk(ctx, handlers, desc); err != nil {
 		return nil, err
 		return nil, err

+ 1 - 1
vendor/github.com/containerd/containerd/images/archive/reference.go

@@ -20,7 +20,7 @@ import (
 	"strings"
 	"strings"
 
 
 	"github.com/containerd/containerd/reference"
 	"github.com/containerd/containerd/reference"
-	distref "github.com/docker/distribution/reference"
+	distref "github.com/containerd/containerd/reference/docker"
 	"github.com/opencontainers/go-digest"
 	"github.com/opencontainers/go-digest"
 	"github.com/pkg/errors"
 	"github.com/pkg/errors"
 )
 )

+ 10 - 2
vendor/github.com/containerd/containerd/lease.go

@@ -24,7 +24,7 @@ import (
 )
 )
 
 
 // WithLease attaches a lease on the context
 // WithLease attaches a lease on the context
-func (c *Client) WithLease(ctx context.Context) (context.Context, func(context.Context) error, error) {
+func (c *Client) WithLease(ctx context.Context, opts ...leases.Opt) (context.Context, func(context.Context) error, error) {
 	_, ok := leases.FromContext(ctx)
 	_, ok := leases.FromContext(ctx)
 	if ok {
 	if ok {
 		return ctx, func(context.Context) error {
 		return ctx, func(context.Context) error {
@@ -34,7 +34,15 @@ func (c *Client) WithLease(ctx context.Context) (context.Context, func(context.C
 
 
 	ls := c.LeasesService()
 	ls := c.LeasesService()
 
 
-	l, err := ls.Create(ctx, leases.WithRandomID(), leases.WithExpiration(24*time.Hour))
+	if len(opts) == 0 {
+		// Use default lease configuration if no options provided
+		opts = []leases.Opt{
+			leases.WithRandomID(),
+			leases.WithExpiration(24 * time.Hour),
+		}
+	}
+
+	l, err := ls.Create(ctx, opts...)
 	if err != nil {
 	if err != nil {
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}

+ 15 - 1
vendor/github.com/containerd/containerd/oci/spec_opts.go

@@ -1006,6 +1006,21 @@ func WithParentCgroupDevices(_ context.Context, _ Client, _ *containers.Containe
 	return nil
 	return nil
 }
 }
 
 
+// WithAllDevicesAllowed permits READ WRITE MKNOD on all devices nodes for the container
+func WithAllDevicesAllowed(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
+	setLinux(s)
+	if s.Linux.Resources == nil {
+		s.Linux.Resources = &specs.LinuxResources{}
+	}
+	s.Linux.Resources.Devices = []specs.LinuxDeviceCgroup{
+		{
+			Allow:  true,
+			Access: rwm,
+		},
+	}
+	return nil
+}
+
 // WithDefaultUnixDevices adds the default devices for unix such as /dev/null, /dev/random to
 // WithDefaultUnixDevices adds the default devices for unix such as /dev/null, /dev/random to
 // the container's resource cgroup spec
 // the container's resource cgroup spec
 func WithDefaultUnixDevices(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
 func WithDefaultUnixDevices(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
@@ -1100,7 +1115,6 @@ func WithDefaultUnixDevices(_ context.Context, _ Client, _ *containers.Container
 }
 }
 
 
 // WithPrivileged sets up options for a privileged container
 // WithPrivileged sets up options for a privileged container
-// TODO(justincormack) device handling
 var WithPrivileged = Compose(
 var WithPrivileged = Compose(
 	WithAllCapabilities,
 	WithAllCapabilities,
 	WithMaskedPaths(nil),
 	WithMaskedPaths(nil),

+ 57 - 0
vendor/github.com/containerd/containerd/oci/spec_opts_linux.go

@@ -19,12 +19,69 @@
 package oci
 package oci
 
 
 import (
 import (
+	"context"
+	"io/ioutil"
 	"os"
 	"os"
+	"path/filepath"
 
 
+	"github.com/containerd/containerd/containers"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
 	"golang.org/x/sys/unix"
 	"golang.org/x/sys/unix"
 )
 )
 
 
+// WithHostDevices adds all the hosts device nodes to the container's spec
+func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
+	setLinux(s)
+
+	devs, err := getDevices("/dev")
+	if err != nil {
+		return err
+	}
+	s.Linux.Devices = append(s.Linux.Devices, devs...)
+	return nil
+}
+
+func getDevices(path string) ([]specs.LinuxDevice, error) {
+	files, err := ioutil.ReadDir(path)
+	if err != nil {
+		return nil, err
+	}
+	var out []specs.LinuxDevice
+	for _, f := range files {
+		switch {
+		case f.IsDir():
+			switch f.Name() {
+			// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
+			// ".udev" added to address https://github.com/opencontainers/runc/issues/2093
+			case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts", ".udev":
+				continue
+			default:
+				sub, err := getDevices(filepath.Join(path, f.Name()))
+				if err != nil {
+					return nil, err
+				}
+
+				out = append(out, sub...)
+				continue
+			}
+		case f.Name() == "console":
+			continue
+		}
+		device, err := deviceFromPath(filepath.Join(path, f.Name()), "rwm")
+		if err != nil {
+			if err == ErrNotADevice {
+				continue
+			}
+			if os.IsNotExist(err) {
+				continue
+			}
+			return nil, err
+		}
+		out = append(out, *device)
+	}
+	return out, nil
+}
+
 func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
 func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
 	var stat unix.Stat_t
 	var stat unix.Stat_t
 	if err := unix.Lstat(path, &stat); err != nil {
 	if err := unix.Lstat(path, &stat); err != nil {

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

@@ -19,12 +19,69 @@
 package oci
 package oci
 
 
 import (
 import (
+	"context"
+	"io/ioutil"
 	"os"
 	"os"
+	"path/filepath"
 
 
+	"github.com/containerd/containerd/containers"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
 	"golang.org/x/sys/unix"
 	"golang.org/x/sys/unix"
 )
 )
 
 
+// WithHostDevices adds all the hosts device nodes to the container's spec
+func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
+	setLinux(s)
+
+	devs, err := getDevices("/dev")
+	if err != nil {
+		return err
+	}
+	s.Linux.Devices = append(s.Linux.Devices, devs...)
+	return nil
+}
+
+func getDevices(path string) ([]specs.LinuxDevice, error) {
+	files, err := ioutil.ReadDir(path)
+	if err != nil {
+		return nil, err
+	}
+	var out []specs.LinuxDevice
+	for _, f := range files {
+		switch {
+		case f.IsDir():
+			switch f.Name() {
+			// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
+			// ".udev" added to address https://github.com/opencontainers/runc/issues/2093
+			case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts", ".udev":
+				continue
+			default:
+				sub, err := getDevices(filepath.Join(path, f.Name()))
+				if err != nil {
+					return nil, err
+				}
+
+				out = append(out, sub...)
+				continue
+			}
+		case f.Name() == "console":
+			continue
+		}
+		device, err := deviceFromPath(filepath.Join(path, f.Name()), "rwm")
+		if err != nil {
+			if err == ErrNotADevice {
+				continue
+			}
+			if os.IsNotExist(err) {
+				continue
+			}
+			return nil, err
+		}
+		out = append(out, *device)
+	}
+	return out, nil
+}
+
 func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
 func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
 	var stat unix.Stat_t
 	var stat unix.Stat_t
 	if err := unix.Lstat(path, &stat); err != nil {
 	if err := unix.Lstat(path, &stat); err != nil {

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

@@ -67,6 +67,13 @@ func WithWindowNetworksAllowUnqualifiedDNSQuery() SpecOpts {
 	}
 	}
 }
 }
 
 
+// WithHostDevices adds all the hosts device nodes to the container's spec
+//
+// Not supported on windows
+func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
+	return nil
+}
+
 func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
 func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
 	return nil, errors.New("device from path not supported on Windows")
 	return nil, errors.New("device from path not supported on Windows")
 }
 }

+ 4 - 0
vendor/github.com/containerd/containerd/pkg/process/deleted_state.go

@@ -69,3 +69,7 @@ func (s *deletedState) SetExited(status int) {
 func (s *deletedState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) {
 func (s *deletedState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) {
 	return nil, errors.Errorf("cannot exec in a deleted state")
 	return nil, errors.Errorf("cannot exec in a deleted state")
 }
 }
+
+func (s *deletedState) Status(ctx context.Context) (string, error) {
+	return "stopped", nil
+}

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

@@ -261,17 +261,5 @@ func (e *execProcess) Status(ctx context.Context) (string, error) {
 	}
 	}
 	e.mu.Lock()
 	e.mu.Lock()
 	defer e.mu.Unlock()
 	defer e.mu.Unlock()
-	// if we don't have a pid(pid=0) then the exec process has just been created
-	if e.pid.get() == 0 {
-		return "created", nil
-	}
-	if e.pid.get() == StoppedPID {
-		return "stopped", nil
-	}
-	// if we have a pid and it can be signaled, the process is running
-	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
-	return "stopped", nil
+	return e.execState.Status(ctx)
 }
 }

+ 13 - 0
vendor/github.com/containerd/containerd/pkg/process/exec_state.go

@@ -31,6 +31,7 @@ type execState interface {
 	Delete(context.Context) error
 	Delete(context.Context) error
 	Kill(context.Context, uint32, bool) error
 	Kill(context.Context, uint32, bool) error
 	SetExited(int)
 	SetExited(int)
+	Status(context.Context) (string, error)
 }
 }
 
 
 type execCreatedState struct {
 type execCreatedState struct {
@@ -82,6 +83,10 @@ func (s *execCreatedState) SetExited(status int) {
 	}
 	}
 }
 }
 
 
+func (s *execCreatedState) Status(ctx context.Context) (string, error) {
+	return "created", nil
+}
+
 type execRunningState struct {
 type execRunningState struct {
 	p *execProcess
 	p *execProcess
 }
 }
@@ -120,6 +125,10 @@ func (s *execRunningState) SetExited(status int) {
 	}
 	}
 }
 }
 
 
+func (s *execRunningState) Status(ctx context.Context) (string, error) {
+	return "running", nil
+}
+
 type execStoppedState struct {
 type execStoppedState struct {
 	p *execProcess
 	p *execProcess
 }
 }
@@ -157,3 +166,7 @@ func (s *execStoppedState) Kill(ctx context.Context, sig uint32, all bool) error
 func (s *execStoppedState) SetExited(status int) {
 func (s *execStoppedState) SetExited(status int) {
 	// no op
 	// no op
 }
 }
+
+func (s *execStoppedState) Status(ctx context.Context) (string, error) {
+	return "stopped", nil
+}

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

@@ -56,12 +56,14 @@ type Init struct {
 
 
 	WorkDir string
 	WorkDir string
 
 
-	id           string
-	Bundle       string
-	console      console.Console
-	Platform     stdio.Platform
-	io           *processIO
-	runtime      *runc.Runc
+	id       string
+	Bundle   string
+	console  console.Console
+	Platform stdio.Platform
+	io       *processIO
+	runtime  *runc.Runc
+	// pausing preserves the pausing state.
+	pausing      *atomicBool
 	status       int
 	status       int
 	exited       time.Time
 	exited       time.Time
 	pid          safePid
 	pid          safePid
@@ -97,6 +99,7 @@ func New(id string, runtime *runc.Runc, stdio stdio.Stdio) *Init {
 	p := &Init{
 	p := &Init{
 		id:        id,
 		id:        id,
 		runtime:   runtime,
 		runtime:   runtime,
+		pausing:   new(atomicBool),
 		stdio:     stdio,
 		stdio:     stdio,
 		status:    0,
 		status:    0,
 		waitBlock: make(chan struct{}),
 		waitBlock: make(chan struct{}),
@@ -237,17 +240,14 @@ func (p *Init) ExitedAt() time.Time {
 
 
 // Status of the process
 // Status of the process
 func (p *Init) Status(ctx context.Context) (string, error) {
 func (p *Init) Status(ctx context.Context) (string, error) {
+	if p.pausing.get() {
+		return "pausing", nil
+	}
+
 	p.mu.Lock()
 	p.mu.Lock()
 	defer p.mu.Unlock()
 	defer p.mu.Unlock()
 
 
-	c, err := p.runtime.State(ctx, p.id)
-	if err != nil {
-		if strings.Contains(err.Error(), "does not exist") {
-			return "stopped", nil
-		}
-		return "", p.runtimeError(err, "OCI runtime state failed")
-	}
-	return c.Status, nil
+	return p.initState.Status(ctx)
 }
 }
 
 
 // Start the init process
 // Start the init process

+ 28 - 0
vendor/github.com/containerd/containerd/pkg/process/init_state.go

@@ -37,6 +37,7 @@ type initState interface {
 	Exec(context.Context, string, *ExecConfig) (Process, error)
 	Exec(context.Context, string, *ExecConfig) (Process, error)
 	Kill(context.Context, uint32, bool) error
 	Kill(context.Context, uint32, bool) error
 	SetExited(int)
 	SetExited(int)
+	Status(context.Context) (string, error)
 }
 }
 
 
 type createdState struct {
 type createdState struct {
@@ -103,6 +104,10 @@ func (s *createdState) Exec(ctx context.Context, path string, r *ExecConfig) (Pr
 	return s.p.exec(ctx, path, r)
 	return s.p.exec(ctx, path, r)
 }
 }
 
 
+func (s *createdState) Status(ctx context.Context) (string, error) {
+	return "created", nil
+}
+
 type createdCheckpointState struct {
 type createdCheckpointState struct {
 	p    *Init
 	p    *Init
 	opts *runc.RestoreOpts
 	opts *runc.RestoreOpts
@@ -211,6 +216,10 @@ func (s *createdCheckpointState) Exec(ctx context.Context, path string, r *ExecC
 	return nil, errors.Errorf("cannot exec in a created state")
 	return nil, errors.Errorf("cannot exec in a created state")
 }
 }
 
 
+func (s *createdCheckpointState) Status(ctx context.Context) (string, error) {
+	return "created", nil
+}
+
 type runningState struct {
 type runningState struct {
 	p *Init
 	p *Init
 }
 }
@@ -228,6 +237,13 @@ func (s *runningState) transition(name string) error {
 }
 }
 
 
 func (s *runningState) Pause(ctx context.Context) error {
 func (s *runningState) Pause(ctx context.Context) error {
+	s.p.pausing.set(true)
+	// NOTE "pausing" will be returned in the short window
+	// after `transition("paused")`, before `pausing` is reset
+	// to false. That doesn't break the state machine, just
+	// delays the "paused" state a little bit.
+	defer s.p.pausing.set(false)
+
 	if err := s.p.runtime.Pause(ctx, s.p.id); err != nil {
 	if err := s.p.runtime.Pause(ctx, s.p.id); err != nil {
 		return s.p.runtimeError(err, "OCI runtime pause failed")
 		return s.p.runtimeError(err, "OCI runtime pause failed")
 	}
 	}
@@ -271,6 +287,10 @@ func (s *runningState) Exec(ctx context.Context, path string, r *ExecConfig) (Pr
 	return s.p.exec(ctx, path, r)
 	return s.p.exec(ctx, path, r)
 }
 }
 
 
+func (s *runningState) Status(ctx context.Context) (string, error) {
+	return "running", nil
+}
+
 type pausedState struct {
 type pausedState struct {
 	p *Init
 	p *Init
 }
 }
@@ -335,6 +355,10 @@ func (s *pausedState) Exec(ctx context.Context, path string, r *ExecConfig) (Pro
 	return nil, errors.Errorf("cannot exec in a paused state")
 	return nil, errors.Errorf("cannot exec in a paused state")
 }
 }
 
 
+func (s *pausedState) Status(ctx context.Context) (string, error) {
+	return "paused", nil
+}
+
 type stoppedState struct {
 type stoppedState struct {
 	p *Init
 	p *Init
 }
 }
@@ -387,3 +411,7 @@ func (s *stoppedState) SetExited(status int) {
 func (s *stoppedState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) {
 func (s *stoppedState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) {
 	return nil, errors.Errorf("cannot exec in a stopped state")
 	return nil, errors.Errorf("cannot exec in a stopped state")
 }
 }
+
+func (s *stoppedState) Status(ctx context.Context) (string, error) {
+	return "stopped", nil
+}

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

@@ -40,7 +40,9 @@ import (
 
 
 var bufPool = sync.Pool{
 var bufPool = sync.Pool{
 	New: func() interface{} {
 	New: func() interface{} {
-		buffer := make([]byte, 32<<10)
+		// setting to 4096 to align with PIPE_BUF
+		// http://man7.org/linux/man-pages/man7/pipe.7.html
+		buffer := make([]byte, 4096)
 		return &buffer
 		return &buffer
 	},
 	},
 }
 }

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

@@ -27,6 +27,7 @@ import (
 	"path/filepath"
 	"path/filepath"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
+	"sync/atomic"
 	"time"
 	"time"
 
 
 	"github.com/containerd/containerd/errdefs"
 	"github.com/containerd/containerd/errdefs"
@@ -62,6 +63,20 @@ func (s *safePid) set(pid int) {
 	s.Unlock()
 	s.Unlock()
 }
 }
 
 
+type atomicBool int32
+
+func (ab *atomicBool) set(b bool) {
+	if b {
+		atomic.StoreInt32((*int32)(ab), 1)
+	} else {
+		atomic.StoreInt32((*int32)(ab), 0)
+	}
+}
+
+func (ab *atomicBool) get() bool {
+	return atomic.LoadInt32((*int32)(ab)) == 1
+}
+
 // TODO(mlaventure): move to runc package?
 // TODO(mlaventure): move to runc package?
 func getLastRuntimeError(r *runc.Runc) (string, error) {
 func getLastRuntimeError(r *runc.Runc) (string, error) {
 	if r.Log == "" {
 	if r.Log == "" {

+ 797 - 0
vendor/github.com/containerd/containerd/reference/docker/reference.go

@@ -0,0 +1,797 @@
+/*
+   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 provides a general type to represent any way of referencing images within the registry.
+// Its main purpose is to abstract tags and digests (content-addressable hash).
+//
+// Grammar
+//
+// 	reference                       := name [ ":" tag ] [ "@" digest ]
+//	name                            := [domain '/'] path-component ['/' path-component]*
+//	domain                          := domain-component ['.' domain-component]* [':' port-number]
+//	domain-component                := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
+//	port-number                     := /[0-9]+/
+//	path-component                  := alpha-numeric [separator alpha-numeric]*
+// 	alpha-numeric                   := /[a-z0-9]+/
+//	separator                       := /[_.]|__|[-]*/
+//
+//	tag                             := /[\w][\w.-]{0,127}/
+//
+//	digest                          := digest-algorithm ":" digest-hex
+//	digest-algorithm                := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]*
+//	digest-algorithm-separator      := /[+.-_]/
+//	digest-algorithm-component      := /[A-Za-z][A-Za-z0-9]*/
+//	digest-hex                      := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
+//
+//	identifier                      := /[a-f0-9]{64}/
+//	short-identifier                := /[a-f0-9]{6,64}/
+package docker
+
+import (
+	"errors"
+	"fmt"
+	"path"
+	"regexp"
+	"strings"
+
+	"github.com/opencontainers/go-digest"
+)
+
+const (
+	// NameTotalLengthMax is the maximum total number of characters in a repository name.
+	NameTotalLengthMax = 255
+)
+
+var (
+	// ErrReferenceInvalidFormat represents an error while trying to parse a string as a reference.
+	ErrReferenceInvalidFormat = errors.New("invalid reference format")
+
+	// ErrTagInvalidFormat represents an error while trying to parse a string as a tag.
+	ErrTagInvalidFormat = errors.New("invalid tag format")
+
+	// ErrDigestInvalidFormat represents an error while trying to parse a string as a tag.
+	ErrDigestInvalidFormat = errors.New("invalid digest format")
+
+	// ErrNameContainsUppercase is returned for invalid repository names that contain uppercase characters.
+	ErrNameContainsUppercase = errors.New("repository name must be lowercase")
+
+	// ErrNameEmpty is returned for empty, invalid repository names.
+	ErrNameEmpty = errors.New("repository name must have at least one component")
+
+	// ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax.
+	ErrNameTooLong = fmt.Errorf("repository name must not be more than %v characters", NameTotalLengthMax)
+
+	// ErrNameNotCanonical is returned when a name is not canonical.
+	ErrNameNotCanonical = errors.New("repository name must be canonical")
+)
+
+// Reference is an opaque object reference identifier that may include
+// modifiers such as a hostname, name, tag, and digest.
+type Reference interface {
+	// String returns the full reference
+	String() string
+}
+
+// Field provides a wrapper type for resolving correct reference types when
+// working with encoding.
+type Field struct {
+	reference Reference
+}
+
+// AsField wraps a reference in a Field for encoding.
+func AsField(reference Reference) Field {
+	return Field{reference}
+}
+
+// Reference unwraps the reference type from the field to
+// return the Reference object. This object should be
+// of the appropriate type to further check for different
+// reference types.
+func (f Field) Reference() Reference {
+	return f.reference
+}
+
+// MarshalText serializes the field to byte text which
+// is the string of the reference.
+func (f Field) MarshalText() (p []byte, err error) {
+	return []byte(f.reference.String()), nil
+}
+
+// UnmarshalText parses text bytes by invoking the
+// reference parser to ensure the appropriately
+// typed reference object is wrapped by field.
+func (f *Field) UnmarshalText(p []byte) error {
+	r, err := Parse(string(p))
+	if err != nil {
+		return err
+	}
+
+	f.reference = r
+	return nil
+}
+
+// Named is an object with a full name
+type Named interface {
+	Reference
+	Name() string
+}
+
+// Tagged is an object which has a tag
+type Tagged interface {
+	Reference
+	Tag() string
+}
+
+// NamedTagged is an object including a name and tag.
+type NamedTagged interface {
+	Named
+	Tag() string
+}
+
+// Digested is an object which has a digest
+// in which it can be referenced by
+type Digested interface {
+	Reference
+	Digest() digest.Digest
+}
+
+// Canonical reference is an object with a fully unique
+// name including a name with domain and digest
+type Canonical interface {
+	Named
+	Digest() digest.Digest
+}
+
+// namedRepository is a reference to a repository with a name.
+// A namedRepository has both domain and path components.
+type namedRepository interface {
+	Named
+	Domain() string
+	Path() string
+}
+
+// Domain returns the domain part of the Named reference
+func Domain(named Named) string {
+	if r, ok := named.(namedRepository); ok {
+		return r.Domain()
+	}
+	domain, _ := splitDomain(named.Name())
+	return domain
+}
+
+// Path returns the name without the domain part of the Named reference
+func Path(named Named) (name string) {
+	if r, ok := named.(namedRepository); ok {
+		return r.Path()
+	}
+	_, path := splitDomain(named.Name())
+	return path
+}
+
+func splitDomain(name string) (string, string) {
+	match := anchoredNameRegexp.FindStringSubmatch(name)
+	if len(match) != 3 {
+		return "", name
+	}
+	return match[1], match[2]
+}
+
+// SplitHostname splits a named reference into a
+// hostname and name string. If no valid hostname is
+// found, the hostname is empty and the full value
+// is returned as name
+// DEPRECATED: Use Domain or Path
+func SplitHostname(named Named) (string, string) {
+	if r, ok := named.(namedRepository); ok {
+		return r.Domain(), r.Path()
+	}
+	return splitDomain(named.Name())
+}
+
+// Parse parses s and returns a syntactically valid Reference.
+// If an error was encountered it is returned, along with a nil Reference.
+// NOTE: Parse will not handle short digests.
+func Parse(s string) (Reference, error) {
+	matches := ReferenceRegexp.FindStringSubmatch(s)
+	if matches == nil {
+		if s == "" {
+			return nil, ErrNameEmpty
+		}
+		if ReferenceRegexp.FindStringSubmatch(strings.ToLower(s)) != nil {
+			return nil, ErrNameContainsUppercase
+		}
+		return nil, ErrReferenceInvalidFormat
+	}
+
+	if len(matches[1]) > NameTotalLengthMax {
+		return nil, ErrNameTooLong
+	}
+
+	var repo repository
+
+	nameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1])
+	if len(nameMatch) == 3 {
+		repo.domain = nameMatch[1]
+		repo.path = nameMatch[2]
+	} else {
+		repo.domain = ""
+		repo.path = matches[1]
+	}
+
+	ref := reference{
+		namedRepository: repo,
+		tag:             matches[2],
+	}
+	if matches[3] != "" {
+		var err error
+		ref.digest, err = digest.Parse(matches[3])
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	r := getBestReferenceType(ref)
+	if r == nil {
+		return nil, ErrNameEmpty
+	}
+
+	return r, nil
+}
+
+// ParseNamed parses s and returns a syntactically valid reference implementing
+// the Named interface. The reference must have a name and be in the canonical
+// form, otherwise an error is returned.
+// If an error was encountered it is returned, along with a nil Reference.
+// NOTE: ParseNamed will not handle short digests.
+func ParseNamed(s string) (Named, error) {
+	named, err := ParseNormalizedNamed(s)
+	if err != nil {
+		return nil, err
+	}
+	if named.String() != s {
+		return nil, ErrNameNotCanonical
+	}
+	return named, nil
+}
+
+// WithName returns a named object representing the given string. If the input
+// is invalid ErrReferenceInvalidFormat will be returned.
+func WithName(name string) (Named, error) {
+	if len(name) > NameTotalLengthMax {
+		return nil, ErrNameTooLong
+	}
+
+	match := anchoredNameRegexp.FindStringSubmatch(name)
+	if match == nil || len(match) != 3 {
+		return nil, ErrReferenceInvalidFormat
+	}
+	return repository{
+		domain: match[1],
+		path:   match[2],
+	}, nil
+}
+
+// WithTag combines the name from "name" and the tag from "tag" to form a
+// reference incorporating both the name and the tag.
+func WithTag(name Named, tag string) (NamedTagged, error) {
+	if !anchoredTagRegexp.MatchString(tag) {
+		return nil, ErrTagInvalidFormat
+	}
+	var repo repository
+	if r, ok := name.(namedRepository); ok {
+		repo.domain = r.Domain()
+		repo.path = r.Path()
+	} else {
+		repo.path = name.Name()
+	}
+	if canonical, ok := name.(Canonical); ok {
+		return reference{
+			namedRepository: repo,
+			tag:             tag,
+			digest:          canonical.Digest(),
+		}, nil
+	}
+	return taggedReference{
+		namedRepository: repo,
+		tag:             tag,
+	}, nil
+}
+
+// WithDigest combines the name from "name" and the digest from "digest" to form
+// a reference incorporating both the name and the digest.
+func WithDigest(name Named, digest digest.Digest) (Canonical, error) {
+	if !anchoredDigestRegexp.MatchString(digest.String()) {
+		return nil, ErrDigestInvalidFormat
+	}
+	var repo repository
+	if r, ok := name.(namedRepository); ok {
+		repo.domain = r.Domain()
+		repo.path = r.Path()
+	} else {
+		repo.path = name.Name()
+	}
+	if tagged, ok := name.(Tagged); ok {
+		return reference{
+			namedRepository: repo,
+			tag:             tagged.Tag(),
+			digest:          digest,
+		}, nil
+	}
+	return canonicalReference{
+		namedRepository: repo,
+		digest:          digest,
+	}, nil
+}
+
+// TrimNamed removes any tag or digest from the named reference.
+func TrimNamed(ref Named) Named {
+	domain, path := SplitHostname(ref)
+	return repository{
+		domain: domain,
+		path:   path,
+	}
+}
+
+func getBestReferenceType(ref reference) Reference {
+	if ref.Name() == "" {
+		// Allow digest only references
+		if ref.digest != "" {
+			return digestReference(ref.digest)
+		}
+		return nil
+	}
+	if ref.tag == "" {
+		if ref.digest != "" {
+			return canonicalReference{
+				namedRepository: ref.namedRepository,
+				digest:          ref.digest,
+			}
+		}
+		return ref.namedRepository
+	}
+	if ref.digest == "" {
+		return taggedReference{
+			namedRepository: ref.namedRepository,
+			tag:             ref.tag,
+		}
+	}
+
+	return ref
+}
+
+type reference struct {
+	namedRepository
+	tag    string
+	digest digest.Digest
+}
+
+func (r reference) String() string {
+	return r.Name() + ":" + r.tag + "@" + r.digest.String()
+}
+
+func (r reference) Tag() string {
+	return r.tag
+}
+
+func (r reference) Digest() digest.Digest {
+	return r.digest
+}
+
+type repository struct {
+	domain string
+	path   string
+}
+
+func (r repository) String() string {
+	return r.Name()
+}
+
+func (r repository) Name() string {
+	if r.domain == "" {
+		return r.path
+	}
+	return r.domain + "/" + r.path
+}
+
+func (r repository) Domain() string {
+	return r.domain
+}
+
+func (r repository) Path() string {
+	return r.path
+}
+
+type digestReference digest.Digest
+
+func (d digestReference) String() string {
+	return digest.Digest(d).String()
+}
+
+func (d digestReference) Digest() digest.Digest {
+	return digest.Digest(d)
+}
+
+type taggedReference struct {
+	namedRepository
+	tag string
+}
+
+func (t taggedReference) String() string {
+	return t.Name() + ":" + t.tag
+}
+
+func (t taggedReference) Tag() string {
+	return t.tag
+}
+
+type canonicalReference struct {
+	namedRepository
+	digest digest.Digest
+}
+
+func (c canonicalReference) String() string {
+	return c.Name() + "@" + c.digest.String()
+}
+
+func (c canonicalReference) Digest() digest.Digest {
+	return c.digest
+}
+
+var (
+	// alphaNumericRegexp defines the alpha numeric atom, typically a
+	// component of names. This only allows lower case characters and digits.
+	alphaNumericRegexp = match(`[a-z0-9]+`)
+
+	// separatorRegexp defines the separators allowed to be embedded in name
+	// components. This allow one period, one or two underscore and multiple
+	// dashes.
+	separatorRegexp = match(`(?:[._]|__|[-]*)`)
+
+	// nameComponentRegexp restricts registry path component names to start
+	// with at least one letter or number, with following parts able to be
+	// separated by one period, one or two underscore and multiple dashes.
+	nameComponentRegexp = expression(
+		alphaNumericRegexp,
+		optional(repeated(separatorRegexp, alphaNumericRegexp)))
+
+	// domainComponentRegexp restricts the registry domain component of a
+	// repository name to start with a component as defined by DomainRegexp
+	// and followed by an optional port.
+	domainComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`)
+
+	// DomainRegexp defines the structure of potential domain components
+	// that may be part of image names. This is purposely a subset of what is
+	// allowed by DNS to ensure backwards compatibility with Docker image
+	// names.
+	DomainRegexp = expression(
+		domainComponentRegexp,
+		optional(repeated(literal(`.`), domainComponentRegexp)),
+		optional(literal(`:`), match(`[0-9]+`)))
+
+	// TagRegexp matches valid tag names. From docker/docker:graph/tags.go.
+	TagRegexp = match(`[\w][\w.-]{0,127}`)
+
+	// anchoredTagRegexp matches valid tag names, anchored at the start and
+	// end of the matched string.
+	anchoredTagRegexp = anchored(TagRegexp)
+
+	// DigestRegexp matches valid digests.
+	DigestRegexp = match(`[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}`)
+
+	// anchoredDigestRegexp matches valid digests, anchored at the start and
+	// end of the matched string.
+	anchoredDigestRegexp = anchored(DigestRegexp)
+
+	// NameRegexp is the format for the name component of references. The
+	// regexp has capturing groups for the domain and name part omitting
+	// the separating forward slash from either.
+	NameRegexp = expression(
+		optional(DomainRegexp, literal(`/`)),
+		nameComponentRegexp,
+		optional(repeated(literal(`/`), nameComponentRegexp)))
+
+	// anchoredNameRegexp is used to parse a name value, capturing the
+	// domain and trailing components.
+	anchoredNameRegexp = anchored(
+		optional(capture(DomainRegexp), literal(`/`)),
+		capture(nameComponentRegexp,
+			optional(repeated(literal(`/`), nameComponentRegexp))))
+
+	// ReferenceRegexp is the full supported format of a reference. The regexp
+	// is anchored and has capturing groups for name, tag, and digest
+	// components.
+	ReferenceRegexp = anchored(capture(NameRegexp),
+		optional(literal(":"), capture(TagRegexp)),
+		optional(literal("@"), capture(DigestRegexp)))
+
+	// IdentifierRegexp is the format for string identifier used as a
+	// content addressable identifier using sha256. These identifiers
+	// are like digests without the algorithm, since sha256 is used.
+	IdentifierRegexp = match(`([a-f0-9]{64})`)
+
+	// ShortIdentifierRegexp is the format used to represent a prefix
+	// of an identifier. A prefix may be used to match a sha256 identifier
+	// within a list of trusted identifiers.
+	ShortIdentifierRegexp = match(`([a-f0-9]{6,64})`)
+
+	// anchoredIdentifierRegexp is used to check or match an
+	// identifier value, anchored at start and end of string.
+	anchoredIdentifierRegexp = anchored(IdentifierRegexp)
+)
+
+// match compiles the string to a regular expression.
+var match = regexp.MustCompile
+
+// literal compiles s into a literal regular expression, escaping any regexp
+// reserved characters.
+func literal(s string) *regexp.Regexp {
+	re := match(regexp.QuoteMeta(s))
+
+	if _, complete := re.LiteralPrefix(); !complete {
+		panic("must be a literal")
+	}
+
+	return re
+}
+
+// expression defines a full expression, where each regular expression must
+// follow the previous.
+func expression(res ...*regexp.Regexp) *regexp.Regexp {
+	var s string
+	for _, re := range res {
+		s += re.String()
+	}
+
+	return match(s)
+}
+
+// optional wraps the expression in a non-capturing group and makes the
+// production optional.
+func optional(res ...*regexp.Regexp) *regexp.Regexp {
+	return match(group(expression(res...)).String() + `?`)
+}
+
+// repeated wraps the regexp in a non-capturing group to get one or more
+// matches.
+func repeated(res ...*regexp.Regexp) *regexp.Regexp {
+	return match(group(expression(res...)).String() + `+`)
+}
+
+// group wraps the regexp in a non-capturing group.
+func group(res ...*regexp.Regexp) *regexp.Regexp {
+	return match(`(?:` + expression(res...).String() + `)`)
+}
+
+// capture wraps the expression in a capturing group.
+func capture(res ...*regexp.Regexp) *regexp.Regexp {
+	return match(`(` + expression(res...).String() + `)`)
+}
+
+// anchored anchors the regular expression by adding start and end delimiters.
+func anchored(res ...*regexp.Regexp) *regexp.Regexp {
+	return match(`^` + expression(res...).String() + `$`)
+}
+
+var (
+	legacyDefaultDomain = "index.docker.io"
+	defaultDomain       = "docker.io"
+	officialRepoName    = "library"
+	defaultTag          = "latest"
+)
+
+// normalizedNamed represents a name which has been
+// normalized and has a familiar form. A familiar name
+// is what is used in Docker UI. An example normalized
+// name is "docker.io/library/ubuntu" and corresponding
+// familiar name of "ubuntu".
+type normalizedNamed interface {
+	Named
+	Familiar() Named
+}
+
+// ParseNormalizedNamed parses a string into a named reference
+// transforming a familiar name from Docker UI to a fully
+// qualified reference. If the value may be an identifier
+// use ParseAnyReference.
+func ParseNormalizedNamed(s string) (Named, error) {
+	if ok := anchoredIdentifierRegexp.MatchString(s); ok {
+		return nil, fmt.Errorf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings", s)
+	}
+	domain, remainder := splitDockerDomain(s)
+	var remoteName string
+	if tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 {
+		remoteName = remainder[:tagSep]
+	} else {
+		remoteName = remainder
+	}
+	if strings.ToLower(remoteName) != remoteName {
+		return nil, errors.New("invalid reference format: repository name must be lowercase")
+	}
+
+	ref, err := Parse(domain + "/" + remainder)
+	if err != nil {
+		return nil, err
+	}
+	named, isNamed := ref.(Named)
+	if !isNamed {
+		return nil, fmt.Errorf("reference %s has no name", ref.String())
+	}
+	return named, nil
+}
+
+// ParseDockerRef normalizes the image reference following the docker convention. This is added
+// mainly for backward compatibility.
+// The reference returned can only be either tagged or digested. For reference contains both tag
+// and digest, the function returns digested reference, e.g. docker.io/library/busybox:latest@
+// sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa will be returned as
+// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa.
+func ParseDockerRef(ref string) (Named, error) {
+	named, err := ParseNormalizedNamed(ref)
+	if err != nil {
+		return nil, err
+	}
+	if _, ok := named.(NamedTagged); ok {
+		if canonical, ok := named.(Canonical); ok {
+			// The reference is both tagged and digested, only
+			// return digested.
+			newNamed, err := WithName(canonical.Name())
+			if err != nil {
+				return nil, err
+			}
+			newCanonical, err := WithDigest(newNamed, canonical.Digest())
+			if err != nil {
+				return nil, err
+			}
+			return newCanonical, nil
+		}
+	}
+	return TagNameOnly(named), nil
+}
+
+// splitDockerDomain splits a repository name to domain and remotename string.
+// If no valid domain is found, the default domain is used. Repository name
+// needs to be already validated before.
+func splitDockerDomain(name string) (domain, remainder string) {
+	i := strings.IndexRune(name, '/')
+	if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
+		domain, remainder = defaultDomain, name
+	} else {
+		domain, remainder = name[:i], name[i+1:]
+	}
+	if domain == legacyDefaultDomain {
+		domain = defaultDomain
+	}
+	if domain == defaultDomain && !strings.ContainsRune(remainder, '/') {
+		remainder = officialRepoName + "/" + remainder
+	}
+	return
+}
+
+// familiarizeName returns a shortened version of the name familiar
+// to to the Docker UI. Familiar names have the default domain
+// "docker.io" and "library/" repository prefix removed.
+// For example, "docker.io/library/redis" will have the familiar
+// name "redis" and "docker.io/dmcgowan/myapp" will be "dmcgowan/myapp".
+// Returns a familiarized named only reference.
+func familiarizeName(named namedRepository) repository {
+	repo := repository{
+		domain: named.Domain(),
+		path:   named.Path(),
+	}
+
+	if repo.domain == defaultDomain {
+		repo.domain = ""
+		// Handle official repositories which have the pattern "library/<official repo name>"
+		if split := strings.Split(repo.path, "/"); len(split) == 2 && split[0] == officialRepoName {
+			repo.path = split[1]
+		}
+	}
+	return repo
+}
+
+func (r reference) Familiar() Named {
+	return reference{
+		namedRepository: familiarizeName(r.namedRepository),
+		tag:             r.tag,
+		digest:          r.digest,
+	}
+}
+
+func (r repository) Familiar() Named {
+	return familiarizeName(r)
+}
+
+func (t taggedReference) Familiar() Named {
+	return taggedReference{
+		namedRepository: familiarizeName(t.namedRepository),
+		tag:             t.tag,
+	}
+}
+
+func (c canonicalReference) Familiar() Named {
+	return canonicalReference{
+		namedRepository: familiarizeName(c.namedRepository),
+		digest:          c.digest,
+	}
+}
+
+// TagNameOnly adds the default tag "latest" to a reference if it only has
+// a repo name.
+func TagNameOnly(ref Named) Named {
+	if IsNameOnly(ref) {
+		namedTagged, err := WithTag(ref, defaultTag)
+		if err != nil {
+			// Default tag must be valid, to create a NamedTagged
+			// type with non-validated input the WithTag function
+			// should be used instead
+			panic(err)
+		}
+		return namedTagged
+	}
+	return ref
+}
+
+// ParseAnyReference parses a reference string as a possible identifier,
+// full digest, or familiar name.
+func ParseAnyReference(ref string) (Reference, error) {
+	if ok := anchoredIdentifierRegexp.MatchString(ref); ok {
+		return digestReference("sha256:" + ref), nil
+	}
+	if dgst, err := digest.Parse(ref); err == nil {
+		return digestReference(dgst), nil
+	}
+
+	return ParseNormalizedNamed(ref)
+}
+
+// IsNameOnly returns true if reference only contains a repo name.
+func IsNameOnly(ref Named) bool {
+	if _, ok := ref.(NamedTagged); ok {
+		return false
+	}
+	if _, ok := ref.(Canonical); ok {
+		return false
+	}
+	return true
+}
+
+// FamiliarName returns the familiar name string
+// for the given named, familiarizing if needed.
+func FamiliarName(ref Named) string {
+	if nn, ok := ref.(normalizedNamed); ok {
+		return nn.Familiar().Name()
+	}
+	return ref.Name()
+}
+
+// FamiliarString returns the familiar string representation
+// for the given reference, familiarizing if needed.
+func FamiliarString(ref Reference) string {
+	if nn, ok := ref.(normalizedNamed); ok {
+		return nn.Familiar().String()
+	}
+	return ref.String()
+}
+
+// FamiliarMatch reports whether ref matches the specified pattern.
+// See https://godoc.org/path#Match for supported patterns.
+func FamiliarMatch(pattern string, ref Reference) (bool, error) {
+	matched, err := path.Match(pattern, FamiliarString(ref))
+	if namedRef, isNamed := ref.(Named); isNamed && !matched {
+		matched, _ = path.Match(pattern, FamiliarName(namedRef))
+	}
+	return matched, err
+}

+ 283 - 0
vendor/github.com/containerd/containerd/remotes/docker/errcode.go

@@ -0,0 +1,283 @@
+/*
+   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 (
+	"encoding/json"
+	"fmt"
+	"strings"
+)
+
+// ErrorCoder is the base interface for ErrorCode and Error allowing
+// users of each to just call ErrorCode to get the real ID of each
+type ErrorCoder interface {
+	ErrorCode() ErrorCode
+}
+
+// ErrorCode represents the error type. The errors are serialized via strings
+// and the integer format may change and should *never* be exported.
+type ErrorCode int
+
+var _ error = ErrorCode(0)
+
+// ErrorCode just returns itself
+func (ec ErrorCode) ErrorCode() ErrorCode {
+	return ec
+}
+
+// Error returns the ID/Value
+func (ec ErrorCode) Error() string {
+	// NOTE(stevvooe): Cannot use message here since it may have unpopulated args.
+	return strings.ToLower(strings.Replace(ec.String(), "_", " ", -1))
+}
+
+// Descriptor returns the descriptor for the error code.
+func (ec ErrorCode) Descriptor() ErrorDescriptor {
+	d, ok := errorCodeToDescriptors[ec]
+
+	if !ok {
+		return ErrorCodeUnknown.Descriptor()
+	}
+
+	return d
+}
+
+// String returns the canonical identifier for this error code.
+func (ec ErrorCode) String() string {
+	return ec.Descriptor().Value
+}
+
+// Message returned the human-readable error message for this error code.
+func (ec ErrorCode) Message() string {
+	return ec.Descriptor().Message
+}
+
+// MarshalText encodes the receiver into UTF-8-encoded text and returns the
+// result.
+func (ec ErrorCode) MarshalText() (text []byte, err error) {
+	return []byte(ec.String()), nil
+}
+
+// UnmarshalText decodes the form generated by MarshalText.
+func (ec *ErrorCode) UnmarshalText(text []byte) error {
+	desc, ok := idToDescriptors[string(text)]
+
+	if !ok {
+		desc = ErrorCodeUnknown.Descriptor()
+	}
+
+	*ec = desc.Code
+
+	return nil
+}
+
+// WithMessage creates a new Error struct based on the passed-in info and
+// overrides the Message property.
+func (ec ErrorCode) WithMessage(message string) Error {
+	return Error{
+		Code:    ec,
+		Message: message,
+	}
+}
+
+// WithDetail creates a new Error struct based on the passed-in info and
+// set the Detail property appropriately
+func (ec ErrorCode) WithDetail(detail interface{}) Error {
+	return Error{
+		Code:    ec,
+		Message: ec.Message(),
+	}.WithDetail(detail)
+}
+
+// WithArgs creates a new Error struct and sets the Args slice
+func (ec ErrorCode) WithArgs(args ...interface{}) Error {
+	return Error{
+		Code:    ec,
+		Message: ec.Message(),
+	}.WithArgs(args...)
+}
+
+// Error provides a wrapper around ErrorCode with extra Details provided.
+type Error struct {
+	Code    ErrorCode   `json:"code"`
+	Message string      `json:"message"`
+	Detail  interface{} `json:"detail,omitempty"`
+
+	// TODO(duglin): See if we need an "args" property so we can do the
+	// variable substitution right before showing the message to the user
+}
+
+var _ error = Error{}
+
+// ErrorCode returns the ID/Value of this Error
+func (e Error) ErrorCode() ErrorCode {
+	return e.Code
+}
+
+// Error returns a human readable representation of the error.
+func (e Error) Error() string {
+	return fmt.Sprintf("%s: %s", e.Code.Error(), e.Message)
+}
+
+// WithDetail will return a new Error, based on the current one, but with
+// some Detail info added
+func (e Error) WithDetail(detail interface{}) Error {
+	return Error{
+		Code:    e.Code,
+		Message: e.Message,
+		Detail:  detail,
+	}
+}
+
+// WithArgs uses the passed-in list of interface{} as the substitution
+// variables in the Error's Message string, but returns a new Error
+func (e Error) WithArgs(args ...interface{}) Error {
+	return Error{
+		Code:    e.Code,
+		Message: fmt.Sprintf(e.Code.Message(), args...),
+		Detail:  e.Detail,
+	}
+}
+
+// ErrorDescriptor provides relevant information about a given error code.
+type ErrorDescriptor struct {
+	// Code is the error code that this descriptor describes.
+	Code ErrorCode
+
+	// Value provides a unique, string key, often captilized with
+	// underscores, to identify the error code. This value is used as the
+	// keyed value when serializing api errors.
+	Value string
+
+	// Message is a short, human readable decription of the error condition
+	// included in API responses.
+	Message string
+
+	// Description provides a complete account of the errors purpose, suitable
+	// for use in documentation.
+	Description string
+
+	// HTTPStatusCode provides the http status code that is associated with
+	// this error condition.
+	HTTPStatusCode int
+}
+
+// ParseErrorCode returns the value by the string error code.
+// `ErrorCodeUnknown` will be returned if the error is not known.
+func ParseErrorCode(value string) ErrorCode {
+	ed, ok := idToDescriptors[value]
+	if ok {
+		return ed.Code
+	}
+
+	return ErrorCodeUnknown
+}
+
+// Errors provides the envelope for multiple errors and a few sugar methods
+// for use within the application.
+type Errors []error
+
+var _ error = Errors{}
+
+func (errs Errors) Error() string {
+	switch len(errs) {
+	case 0:
+		return "<nil>"
+	case 1:
+		return errs[0].Error()
+	default:
+		msg := "errors:\n"
+		for _, err := range errs {
+			msg += err.Error() + "\n"
+		}
+		return msg
+	}
+}
+
+// Len returns the current number of errors.
+func (errs Errors) Len() int {
+	return len(errs)
+}
+
+// MarshalJSON converts slice of error, ErrorCode or Error into a
+// slice of Error - then serializes
+func (errs Errors) MarshalJSON() ([]byte, error) {
+	var tmpErrs struct {
+		Errors []Error `json:"errors,omitempty"`
+	}
+
+	for _, daErr := range errs {
+		var err Error
+
+		switch daErr := daErr.(type) {
+		case ErrorCode:
+			err = daErr.WithDetail(nil)
+		case Error:
+			err = daErr
+		default:
+			err = ErrorCodeUnknown.WithDetail(daErr)
+
+		}
+
+		// If the Error struct was setup and they forgot to set the
+		// Message field (meaning its "") then grab it from the ErrCode
+		msg := err.Message
+		if msg == "" {
+			msg = err.Code.Message()
+		}
+
+		tmpErrs.Errors = append(tmpErrs.Errors, Error{
+			Code:    err.Code,
+			Message: msg,
+			Detail:  err.Detail,
+		})
+	}
+
+	return json.Marshal(tmpErrs)
+}
+
+// UnmarshalJSON deserializes []Error and then converts it into slice of
+// Error or ErrorCode
+func (errs *Errors) UnmarshalJSON(data []byte) error {
+	var tmpErrs struct {
+		Errors []Error
+	}
+
+	if err := json.Unmarshal(data, &tmpErrs); err != nil {
+		return err
+	}
+
+	var newErrs Errors
+	for _, daErr := range tmpErrs.Errors {
+		// If Message is empty or exactly matches the Code's message string
+		// then just use the Code, no need for a full Error struct
+		if daErr.Detail == nil && (daErr.Message == "" || daErr.Message == daErr.Code.Message()) {
+			// Error's w/o details get converted to ErrorCode
+			newErrs = append(newErrs, daErr.Code)
+		} else {
+			// Error's w/ details are untouched
+			newErrs = append(newErrs, Error{
+				Code:    daErr.Code,
+				Message: daErr.Message,
+				Detail:  daErr.Detail,
+			})
+		}
+	}
+
+	*errs = newErrs
+	return nil
+}

+ 154 - 0
vendor/github.com/containerd/containerd/remotes/docker/errdesc.go

@@ -0,0 +1,154 @@
+/*
+   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 (
+	"fmt"
+	"net/http"
+	"sort"
+	"sync"
+)
+
+var (
+	errorCodeToDescriptors = map[ErrorCode]ErrorDescriptor{}
+	idToDescriptors        = map[string]ErrorDescriptor{}
+	groupToDescriptors     = map[string][]ErrorDescriptor{}
+)
+
+var (
+	// ErrorCodeUnknown is a generic error that can be used as a last
+	// resort if there is no situation-specific error message that can be used
+	ErrorCodeUnknown = Register("errcode", ErrorDescriptor{
+		Value:   "UNKNOWN",
+		Message: "unknown error",
+		Description: `Generic error returned when the error does not have an
+			                                            API classification.`,
+		HTTPStatusCode: http.StatusInternalServerError,
+	})
+
+	// ErrorCodeUnsupported is returned when an operation is not supported.
+	ErrorCodeUnsupported = Register("errcode", ErrorDescriptor{
+		Value:   "UNSUPPORTED",
+		Message: "The operation is unsupported.",
+		Description: `The operation was unsupported due to a missing
+		implementation or invalid set of parameters.`,
+		HTTPStatusCode: http.StatusMethodNotAllowed,
+	})
+
+	// ErrorCodeUnauthorized is returned if a request requires
+	// authentication.
+	ErrorCodeUnauthorized = Register("errcode", ErrorDescriptor{
+		Value:   "UNAUTHORIZED",
+		Message: "authentication required",
+		Description: `The access controller was unable to authenticate
+		the client. Often this will be accompanied by a
+		Www-Authenticate HTTP response header indicating how to
+		authenticate.`,
+		HTTPStatusCode: http.StatusUnauthorized,
+	})
+
+	// ErrorCodeDenied is returned if a client does not have sufficient
+	// permission to perform an action.
+	ErrorCodeDenied = Register("errcode", ErrorDescriptor{
+		Value:   "DENIED",
+		Message: "requested access to the resource is denied",
+		Description: `The access controller denied access for the
+		operation on a resource.`,
+		HTTPStatusCode: http.StatusForbidden,
+	})
+
+	// ErrorCodeUnavailable provides a common error to report unavailability
+	// of a service or endpoint.
+	ErrorCodeUnavailable = Register("errcode", ErrorDescriptor{
+		Value:          "UNAVAILABLE",
+		Message:        "service unavailable",
+		Description:    "Returned when a service is not available",
+		HTTPStatusCode: http.StatusServiceUnavailable,
+	})
+
+	// ErrorCodeTooManyRequests is returned if a client attempts too many
+	// times to contact a service endpoint.
+	ErrorCodeTooManyRequests = Register("errcode", ErrorDescriptor{
+		Value:   "TOOMANYREQUESTS",
+		Message: "too many requests",
+		Description: `Returned when a client attempts to contact a
+		service too many times`,
+		HTTPStatusCode: http.StatusTooManyRequests,
+	})
+)
+
+var nextCode = 1000
+var registerLock sync.Mutex
+
+// Register will make the passed-in error known to the environment and
+// return a new ErrorCode
+func Register(group string, descriptor ErrorDescriptor) ErrorCode {
+	registerLock.Lock()
+	defer registerLock.Unlock()
+
+	descriptor.Code = ErrorCode(nextCode)
+
+	if _, ok := idToDescriptors[descriptor.Value]; ok {
+		panic(fmt.Sprintf("ErrorValue %q is already registered", descriptor.Value))
+	}
+	if _, ok := errorCodeToDescriptors[descriptor.Code]; ok {
+		panic(fmt.Sprintf("ErrorCode %v is already registered", descriptor.Code))
+	}
+
+	groupToDescriptors[group] = append(groupToDescriptors[group], descriptor)
+	errorCodeToDescriptors[descriptor.Code] = descriptor
+	idToDescriptors[descriptor.Value] = descriptor
+
+	nextCode++
+	return descriptor.Code
+}
+
+type byValue []ErrorDescriptor
+
+func (a byValue) Len() int           { return len(a) }
+func (a byValue) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a byValue) Less(i, j int) bool { return a[i].Value < a[j].Value }
+
+// GetGroupNames returns the list of Error group names that are registered
+func GetGroupNames() []string {
+	keys := []string{}
+
+	for k := range groupToDescriptors {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	return keys
+}
+
+// GetErrorCodeGroup returns the named group of error descriptors
+func GetErrorCodeGroup(name string) []ErrorDescriptor {
+	desc := groupToDescriptors[name]
+	sort.Sort(byValue(desc))
+	return desc
+}
+
+// GetErrorAllDescriptors returns a slice of all ErrorDescriptors that are
+// registered, irrespective of what group they're in
+func GetErrorAllDescriptors() []ErrorDescriptor {
+	result := []ErrorDescriptor{}
+
+	for _, group := range GetGroupNames() {
+		result = append(result, GetErrorCodeGroup(group)...)
+	}
+	sort.Sort(byValue(result))
+	return result
+}

+ 1 - 2
vendor/github.com/containerd/containerd/remotes/docker/fetcher.go

@@ -29,7 +29,6 @@ import (
 	"github.com/containerd/containerd/errdefs"
 	"github.com/containerd/containerd/errdefs"
 	"github.com/containerd/containerd/images"
 	"github.com/containerd/containerd/images"
 	"github.com/containerd/containerd/log"
 	"github.com/containerd/containerd/log"
-	"github.com/docker/distribution/registry/api/errcode"
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 	"github.com/pkg/errors"
 	"github.com/pkg/errors"
 )
 )
@@ -160,7 +159,7 @@ func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string,
 		if resp.StatusCode == http.StatusNotFound {
 		if resp.StatusCode == http.StatusNotFound {
 			return nil, errors.Wrapf(errdefs.ErrNotFound, "content at %v not found", req.String())
 			return nil, errors.Wrapf(errdefs.ErrNotFound, "content at %v not found", req.String())
 		}
 		}
-		var registryErr errcode.Errors
+		var registryErr Errors
 		if err := json.NewDecoder(resp.Body).Decode(&registryErr); err != nil || registryErr.Len() < 1 {
 		if err := json.NewDecoder(resp.Body).Decode(&registryErr); err != nil || registryErr.Len() < 1 {
 			return nil, errors.Errorf("unexpected status code %v: %v", req.String(), resp.Status)
 			return nil, errors.Errorf("unexpected status code %v: %v", req.String(), resp.Status)
 		}
 		}

+ 9 - 3
vendor/github.com/containerd/containerd/runtime/v1/linux/task.go

@@ -91,9 +91,12 @@ func (t *Task) PID() uint32 {
 
 
 // Delete the task and return the exit status
 // Delete the task and return the exit status
 func (t *Task) Delete(ctx context.Context) (*runtime.Exit, error) {
 func (t *Task) Delete(ctx context.Context) (*runtime.Exit, error) {
-	rsp, err := t.shim.Delete(ctx, empty)
-	if err != nil && !errdefs.IsNotFound(err) {
-		return nil, errdefs.FromGRPC(err)
+	rsp, shimErr := t.shim.Delete(ctx, empty)
+	if shimErr != nil {
+		shimErr = errdefs.FromGRPC(shimErr)
+		if !errdefs.IsNotFound(shimErr) {
+			return nil, shimErr
+		}
 	}
 	}
 	t.tasks.Delete(ctx, t.id)
 	t.tasks.Delete(ctx, t.id)
 	if err := t.shim.KillShim(ctx); err != nil {
 	if err := t.shim.KillShim(ctx); err != nil {
@@ -102,6 +105,9 @@ func (t *Task) Delete(ctx context.Context) (*runtime.Exit, error) {
 	if err := t.bundle.Delete(); err != nil {
 	if err := t.bundle.Delete(); err != nil {
 		log.G(ctx).WithError(err).Error("failed to delete bundle")
 		log.G(ctx).WithError(err).Error("failed to delete bundle")
 	}
 	}
+	if shimErr != nil {
+		return nil, shimErr
+	}
 	t.events.Publish(ctx, runtime.TaskDeleteEventTopic, &eventstypes.TaskDelete{
 	t.events.Publish(ctx, runtime.TaskDeleteEventTopic, &eventstypes.TaskDelete{
 		ContainerID: t.id,
 		ContainerID: t.id,
 		ExitStatus:  rsp.ExitStatus,
 		ExitStatus:  rsp.ExitStatus,

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

@@ -55,7 +55,7 @@ var (
 	empty   = &ptypes.Empty{}
 	empty   = &ptypes.Empty{}
 	bufPool = sync.Pool{
 	bufPool = sync.Pool{
 		New: func() interface{} {
 		New: func() interface{} {
-			buffer := make([]byte, 32<<10)
+			buffer := make([]byte, 4096)
 			return &buffer
 			return &buffer
 		},
 		},
 	}
 	}
@@ -217,7 +217,7 @@ func (s *Service) Delete(ctx context.Context, r *ptypes.Empty) (*shimapi.DeleteR
 		return nil, err
 		return nil, err
 	}
 	}
 	if err := p.Delete(ctx); err != nil {
 	if err := p.Delete(ctx); err != nil {
-		return nil, err
+		return nil, errdefs.ToGRPC(err)
 	}
 	}
 	s.mu.Lock()
 	s.mu.Lock()
 	delete(s.processes, s.id)
 	delete(s.processes, s.id)
@@ -240,7 +240,7 @@ func (s *Service) DeleteProcess(ctx context.Context, r *shimapi.DeleteProcessReq
 		return nil, err
 		return nil, err
 	}
 	}
 	if err := p.Delete(ctx); err != nil {
 	if err := p.Delete(ctx); err != nil {
-		return nil, err
+		return nil, errdefs.ToGRPC(err)
 	}
 	}
 	s.mu.Lock()
 	s.mu.Lock()
 	delete(s.processes, r.ID)
 	delete(s.processes, r.ID)

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

@@ -55,6 +55,7 @@ func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console
 			io.CopyBuffer(epollConsole, in, *bp)
 			io.CopyBuffer(epollConsole, in, *bp)
 			// we need to shutdown epollConsole when pipe broken
 			// we need to shutdown epollConsole when pipe broken
 			epollConsole.Shutdown(p.epoller.CloseConsole)
 			epollConsole.Shutdown(p.epoller.CloseConsole)
+			epollConsole.Close()
 		}()
 		}()
 	}
 	}
 
 
@@ -73,9 +74,8 @@ func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console
 		p := bufPool.Get().(*[]byte)
 		p := bufPool.Get().(*[]byte)
 		defer bufPool.Put(p)
 		defer bufPool.Put(p)
 		io.CopyBuffer(outw, epollConsole, *p)
 		io.CopyBuffer(outw, epollConsole, *p)
-		epollConsole.Close()
-		outr.Close()
 		outw.Close()
 		outw.Close()
+		outr.Close()
 		wg.Done()
 		wg.Done()
 	}()
 	}()
 	cwg.Wait()
 	cwg.Wait()

+ 4 - 4
vendor/github.com/containerd/containerd/vendor.conf

@@ -1,6 +1,6 @@
 github.com/containerd/go-runc e029b79d8cda8374981c64eba71f28ec38e5526f
 github.com/containerd/go-runc e029b79d8cda8374981c64eba71f28ec38e5526f
 github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
 github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
-github.com/containerd/cgroups c4b9ac5c7601384c965b9646fc515884e091ebb9
+github.com/containerd/cgroups abd0b19954a6b05e0963f48427062d1481b7faad
 github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
 github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
 github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
 github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
 github.com/containerd/btrfs af5082808c833de0e79c1e72eea9fea239364877
 github.com/containerd/btrfs af5082808c833de0e79c1e72eea9fea239364877
@@ -20,7 +20,7 @@ github.com/gogo/protobuf v1.2.1
 github.com/gogo/googleapis v1.2.0
 github.com/gogo/googleapis v1.2.0
 github.com/golang/protobuf v1.2.0
 github.com/golang/protobuf v1.2.0
 github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
 github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
-github.com/opencontainers/runc 3e425f80a8c931f88e6d94a8c831b9d5aa481657 # v1.0.0-rc8+ CVE-2019-16884
+github.com/opencontainers/runc d736ef14f0288d6993a1845745d6756cfc9ddd5a # v1.0.0-rc9
 github.com/konsorten/go-windows-terminal-sequences v1.0.1
 github.com/konsorten/go-windows-terminal-sequences v1.0.1
 github.com/sirupsen/logrus v1.4.1
 github.com/sirupsen/logrus v1.4.1
 github.com/urfave/cli v1.22.0
 github.com/urfave/cli v1.22.0
@@ -51,8 +51,8 @@ github.com/cpuguy83/go-md2man v1.0.10
 github.com/russross/blackfriday v1.5.2
 github.com/russross/blackfriday v1.5.2
 
 
 # cri dependencies
 # cri dependencies
-github.com/containerd/cri 5d49e7e51b43e36a6b9c4386257c7d08c602237f # release/1.3
-github.com/containerd/go-cni 49fbd9b210f3c8ee3b7fd3cd797aabaf364627c1
+github.com/containerd/cri 0ebf032aac5f6029f95a94e42161e9db7a7e84df # release/1.3+
+github.com/containerd/go-cni 0d360c50b10b350b6bb23863fd4dfb1c232b01c9
 github.com/containernetworking/cni v0.7.1
 github.com/containernetworking/cni v0.7.1
 github.com/containernetworking/plugins v0.7.6
 github.com/containernetworking/plugins v0.7.6
 github.com/davecgh/go-spew v1.1.1
 github.com/davecgh/go-spew v1.1.1

+ 5 - 0
vendor/github.com/containerd/containerd/version/version.go

@@ -16,6 +16,8 @@
 
 
 package version
 package version
 
 
+import "runtime"
+
 var (
 var (
 	// Package is filled at linking time
 	// Package is filled at linking time
 	Package = "github.com/containerd/containerd"
 	Package = "github.com/containerd/containerd"
@@ -26,4 +28,7 @@ var (
 	// Revision is filled with the VCS (e.g. git) revision being used to build
 	// Revision is filled with the VCS (e.g. git) revision being used to build
 	// the program at linking time.
 	// the program at linking time.
 	Revision = ""
 	Revision = ""
+
+	// GoVersion is Go tree's version.
+	GoVersion = runtime.Version()
 )
 )

+ 8 - 2
vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go

@@ -6,6 +6,8 @@ import (
 	"fmt"
 	"fmt"
 	"io/ioutil"
 	"io/ioutil"
 	"os"
 	"os"
+
+	"github.com/opencontainers/runc/libcontainer/utils"
 )
 )
 
 
 // IsEnabled returns true if apparmor is enabled for the host.
 // IsEnabled returns true if apparmor is enabled for the host.
@@ -19,7 +21,7 @@ func IsEnabled() bool {
 	return false
 	return false
 }
 }
 
 
-func setprocattr(attr, value string) error {
+func setProcAttr(attr, value string) error {
 	// Under AppArmor you can only change your own attr, so use /proc/self/
 	// Under AppArmor you can only change your own attr, so use /proc/self/
 	// instead of /proc/<tid>/ like libapparmor does
 	// instead of /proc/<tid>/ like libapparmor does
 	path := fmt.Sprintf("/proc/self/attr/%s", attr)
 	path := fmt.Sprintf("/proc/self/attr/%s", attr)
@@ -30,6 +32,10 @@ func setprocattr(attr, value string) error {
 	}
 	}
 	defer f.Close()
 	defer f.Close()
 
 
+	if err := utils.EnsureProcHandle(f); err != nil {
+		return err
+	}
+
 	_, err = fmt.Fprintf(f, "%s", value)
 	_, err = fmt.Fprintf(f, "%s", value)
 	return err
 	return err
 }
 }
@@ -37,7 +43,7 @@ func setprocattr(attr, value string) error {
 // changeOnExec reimplements aa_change_onexec from libapparmor in Go
 // changeOnExec reimplements aa_change_onexec from libapparmor in Go
 func changeOnExec(name string) error {
 func changeOnExec(name string) error {
 	value := "exec " + name
 	value := "exec " + name
-	if err := setprocattr("exec", value); err != nil {
+	if err := setProcAttr("exec", value); err != nil {
 		return fmt.Errorf("apparmor failed to apply profile: %s", err)
 		return fmt.Errorf("apparmor failed to apply profile: %s", err)
 	}
 	}
 	return nil
 	return nil

+ 1 - 0
vendor/github.com/opencontainers/runc/libcontainer/configs/config.go

@@ -44,6 +44,7 @@ const (
 	Trap
 	Trap
 	Allow
 	Allow
 	Trace
 	Trace
+	Log
 )
 )
 
 
 // Operator is a comparison operator to be used when matching syscall arguments in Seccomp
 // Operator is a comparison operator to be used when matching syscall arguments in Seccomp

+ 93 - 0
vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go

@@ -0,0 +1,93 @@
+// +build linux
+
+package utils
+
+/*
+ * Copyright 2016, 2017 SUSE LLC
+ *
+ * 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.
+ */
+
+import (
+	"fmt"
+	"os"
+
+	"golang.org/x/sys/unix"
+)
+
+// MaxSendfdLen is the maximum length of the name of a file descriptor being
+// sent using SendFd. The name of the file handle returned by RecvFd will never
+// be larger than this value.
+const MaxNameLen = 4096
+
+// oobSpace is the size of the oob slice required to store a single FD. Note
+// that unix.UnixRights appears to make the assumption that fd is always int32,
+// so sizeof(fd) = 4.
+var oobSpace = unix.CmsgSpace(4)
+
+// RecvFd waits for a file descriptor to be sent over the given AF_UNIX
+// socket. The file name of the remote file descriptor will be recreated
+// locally (it is sent as non-auxiliary data in the same payload).
+func RecvFd(socket *os.File) (*os.File, error) {
+	// For some reason, unix.Recvmsg uses the length rather than the capacity
+	// when passing the msg_controllen and other attributes to recvmsg.  So we
+	// have to actually set the length.
+	name := make([]byte, MaxNameLen)
+	oob := make([]byte, oobSpace)
+
+	sockfd := socket.Fd()
+	n, oobn, _, _, err := unix.Recvmsg(int(sockfd), name, oob, 0)
+	if err != nil {
+		return nil, err
+	}
+
+	if n >= MaxNameLen || oobn != oobSpace {
+		return nil, fmt.Errorf("recvfd: incorrect number of bytes read (n=%d oobn=%d)", n, oobn)
+	}
+
+	// Truncate.
+	name = name[:n]
+	oob = oob[:oobn]
+
+	scms, err := unix.ParseSocketControlMessage(oob)
+	if err != nil {
+		return nil, err
+	}
+	if len(scms) != 1 {
+		return nil, fmt.Errorf("recvfd: number of SCMs is not 1: %d", len(scms))
+	}
+	scm := scms[0]
+
+	fds, err := unix.ParseUnixRights(&scm)
+	if err != nil {
+		return nil, err
+	}
+	if len(fds) != 1 {
+		return nil, fmt.Errorf("recvfd: number of fds is not 1: %d", len(fds))
+	}
+	fd := uintptr(fds[0])
+
+	return os.NewFile(fd, string(name)), nil
+}
+
+// SendFd sends a file descriptor over the given AF_UNIX socket. In
+// addition, the file.Name() of the given file will also be sent as
+// non-auxiliary data in the same payload (allowing to send contextual
+// information for a file descriptor).
+func SendFd(socket *os.File, name string, fd uintptr) error {
+	if len(name) >= MaxNameLen {
+		return fmt.Errorf("sendfd: filename too long: %s", name)
+	}
+	oob := unix.UnixRights(int(fd))
+	return unix.Sendmsg(int(socket.Fd()), []byte(name), oob, nil, 0)
+}

+ 112 - 0
vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go

@@ -0,0 +1,112 @@
+package utils
+
+import (
+	"encoding/json"
+	"io"
+	"os"
+	"path/filepath"
+	"strings"
+	"unsafe"
+
+	"golang.org/x/sys/unix"
+)
+
+const (
+	exitSignalOffset = 128
+)
+
+// ResolveRootfs ensures that the current working directory is
+// not a symlink and returns the absolute path to the rootfs
+func ResolveRootfs(uncleanRootfs string) (string, error) {
+	rootfs, err := filepath.Abs(uncleanRootfs)
+	if err != nil {
+		return "", err
+	}
+	return filepath.EvalSymlinks(rootfs)
+}
+
+// ExitStatus returns the correct exit status for a process based on if it
+// was signaled or exited cleanly
+func ExitStatus(status unix.WaitStatus) int {
+	if status.Signaled() {
+		return exitSignalOffset + int(status.Signal())
+	}
+	return status.ExitStatus()
+}
+
+// WriteJSON writes the provided struct v to w using standard json marshaling
+func WriteJSON(w io.Writer, v interface{}) error {
+	data, err := json.Marshal(v)
+	if err != nil {
+		return err
+	}
+	_, err = w.Write(data)
+	return err
+}
+
+// CleanPath makes a path safe for use with filepath.Join. This is done by not
+// only cleaning the path, but also (if the path is relative) adding a leading
+// '/' and cleaning it (then removing the leading '/'). This ensures that a
+// path resulting from prepending another path will always resolve to lexically
+// be a subdirectory of the prefixed path. This is all done lexically, so paths
+// that include symlinks won't be safe as a result of using CleanPath.
+func CleanPath(path string) string {
+	// Deal with empty strings nicely.
+	if path == "" {
+		return ""
+	}
+
+	// Ensure that all paths are cleaned (especially problematic ones like
+	// "/../../../../../" which can cause lots of issues).
+	path = filepath.Clean(path)
+
+	// If the path isn't absolute, we need to do more processing to fix paths
+	// such as "../../../../<etc>/some/path". We also shouldn't convert absolute
+	// paths to relative ones.
+	if !filepath.IsAbs(path) {
+		path = filepath.Clean(string(os.PathSeparator) + path)
+		// This can't fail, as (by definition) all paths are relative to root.
+		path, _ = filepath.Rel(string(os.PathSeparator), path)
+	}
+
+	// Clean the path again for good measure.
+	return filepath.Clean(path)
+}
+
+// SearchLabels searches a list of key-value pairs for the provided key and
+// returns the corresponding value. The pairs must be separated with '='.
+func SearchLabels(labels []string, query string) string {
+	for _, l := range labels {
+		parts := strings.SplitN(l, "=", 2)
+		if len(parts) < 2 {
+			continue
+		}
+		if parts[0] == query {
+			return parts[1]
+		}
+	}
+	return ""
+}
+
+// Annotations returns the bundle path and user defined annotations from the
+// libcontainer state.  We need to remove the bundle because that is a label
+// added by libcontainer.
+func Annotations(labels []string) (bundle string, userAnnotations map[string]string) {
+	userAnnotations = make(map[string]string)
+	for _, l := range labels {
+		parts := strings.SplitN(l, "=", 2)
+		if len(parts) < 2 {
+			continue
+		}
+		if parts[0] == "bundle" {
+			bundle = parts[1]
+		} else {
+			userAnnotations[parts[0]] = parts[1]
+		}
+	}
+	return
+}
+
+func GetIntSize() int {
+	return int(unsafe.Sizeof(1))
+}

+ 68 - 0
vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go

@@ -0,0 +1,68 @@
+// +build !windows
+
+package utils
+
+import (
+	"fmt"
+	"os"
+	"strconv"
+
+	"golang.org/x/sys/unix"
+)
+
+// EnsureProcHandle returns whether or not the given file handle is on procfs.
+func EnsureProcHandle(fh *os.File) error {
+	var buf unix.Statfs_t
+	if err := unix.Fstatfs(int(fh.Fd()), &buf); err != nil {
+		return fmt.Errorf("ensure %s is on procfs: %v", fh.Name(), err)
+	}
+	if buf.Type != unix.PROC_SUPER_MAGIC {
+		return fmt.Errorf("%s is not on procfs", fh.Name())
+	}
+	return nil
+}
+
+// CloseExecFrom applies O_CLOEXEC to all file descriptors currently open for
+// the process (except for those below the given fd value).
+func CloseExecFrom(minFd int) error {
+	fdDir, err := os.Open("/proc/self/fd")
+	if err != nil {
+		return err
+	}
+	defer fdDir.Close()
+
+	if err := EnsureProcHandle(fdDir); err != nil {
+		return err
+	}
+
+	fdList, err := fdDir.Readdirnames(-1)
+	if err != nil {
+		return err
+	}
+	for _, fdStr := range fdList {
+		fd, err := strconv.Atoi(fdStr)
+		// Ignore non-numeric file names.
+		if err != nil {
+			continue
+		}
+		// Ignore descriptors lower than our specified minimum.
+		if fd < minFd {
+			continue
+		}
+		// Intentionally ignore errors from unix.CloseOnExec -- the cases where
+		// this might fail are basically file descriptors that have already
+		// been closed (including and especially the one that was created when
+		// ioutil.ReadDir did the "opendir" syscall).
+		unix.CloseOnExec(fd)
+	}
+	return nil
+}
+
+// NewSockPair returns a new unix socket pair
+func NewSockPair(name string) (parent *os.File, child *os.File, err error) {
+	fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
+	if err != nil {
+		return nil, nil, err
+	}
+	return os.NewFile(uintptr(fds[1]), name+"-p"), os.NewFile(uintptr(fds[0]), name+"-c"), nil
+}

+ 1 - 1
vendor/github.com/opencontainers/runc/vendor.conf

@@ -6,7 +6,7 @@ github.com/opencontainers/runtime-spec  29686dbc5559d93fb1ef402eeda3e35c38d75af4
 # Core libcontainer functionality.
 # Core libcontainer functionality.
 github.com/checkpoint-restore/go-criu   17b0214f6c48980c45dc47ecb0cfd6d9e02df723 # v3.11
 github.com/checkpoint-restore/go-criu   17b0214f6c48980c45dc47ecb0cfd6d9e02df723 # v3.11
 github.com/mrunalp/fileutils            7d4729fb36185a7c1719923406c9d40e54fb93c7
 github.com/mrunalp/fileutils            7d4729fb36185a7c1719923406c9d40e54fb93c7
-github.com/opencontainers/selinux       3a1f366feb7aecbf7a0e71ac4cea88b31597de9e # v1.2.2
+github.com/opencontainers/selinux       5215b1806f52b1fcc2070a8826c542c9d33cd3cf # v1.3.0 (+ CVE-2019-16884)
 github.com/seccomp/libseccomp-golang    689e3c1541a84461afc49c1c87352a6cedf72e9c # v0.9.1
 github.com/seccomp/libseccomp-golang    689e3c1541a84461afc49c1c87352a6cedf72e9c # v0.9.1
 github.com/sirupsen/logrus              8bdbc7bcc01dcbb8ec23dc8a28e332258d25251f # v1.4.1
 github.com/sirupsen/logrus              8bdbc7bcc01dcbb8ec23dc8a28e332258d25251f # v1.4.1
 github.com/syndtr/gocapability          d98352740cb2c55f81556b63d4a1ec64c5a319c2
 github.com/syndtr/gocapability          d98352740cb2c55f81556b63d4a1ec64c5a319c2