summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/types/types.go10
-rw-r--r--daemon/config/config.go29
-rw-r--r--daemon/daemon.go8
-rw-r--r--daemon/daemon_unix.go74
-rw-r--r--daemon/info.go5
-rw-r--r--daemon/runtime_unix.go134
-rw-r--r--daemon/start.go6
-rw-r--r--daemon/start_unix.go65
-rw-r--r--daemon/start_windows.go12
-rw-r--r--daemon/util_test.go2
-rw-r--r--libcontainerd/libcontainerd_linux.go4
-rw-r--r--libcontainerd/libcontainerd_windows.go4
-rw-r--r--libcontainerd/local/local_windows.go2
-rw-r--r--libcontainerd/remote/client.go36
-rw-r--r--libcontainerd/remote/client_linux.go5
-rw-r--r--libcontainerd/types/types.go2
-rw-r--r--plugin/executor/containerd/containerd.go16
17 files changed, 237 insertions, 177 deletions
diff --git a/api/types/types.go b/api/types/types.go
index a6ed75de3e..dd5f2aff8a 100644
--- a/api/types/types.go
+++ b/api/types/types.go
@@ -511,6 +511,16 @@ type Checkpoint struct {
type Runtime struct {
Path string `json:"path"`
Args []string `json:"runtimeArgs,omitempty"`
+
+ // This is exposed here only for internal use
+ // It is not currently supported to specify custom shim configs
+ Shim *ShimConfig `json:"-"`
+}
+
+// ShimConfig is used by runtime to configure containerd shims
+type ShimConfig struct {
+ Binary string
+ Opts interface{}
}
// DiskUsage contains response of Engine API:
diff --git a/daemon/config/config.go b/daemon/config/config.go
index 26614d37c4..bcecd36356 100644
--- a/daemon/config/config.go
+++ b/daemon/config/config.go
@@ -36,9 +36,6 @@ const (
// maximum number of attempts that
// may take place at a time for each pull when the connection is lost.
DefaultDownloadAttempts = 5
- // StockRuntimeName is the reserved name/alias used to represent the
- // OCI runtime being shipped with the docker daemon package.
- StockRuntimeName = "runc"
// DefaultShmSize is the default value for container's shm size
DefaultShmSize = int64(67108864)
// DefaultNetworkMtu is the default value for network MTU
@@ -47,8 +44,24 @@ const (
DisableNetworkBridge = "none"
// DefaultInitBinary is the name of the default init binary
DefaultInitBinary = "docker-init"
+
+ // StockRuntimeName is the reserved name/alias used to represent the
+ // OCI runtime being shipped with the docker daemon package.
+ StockRuntimeName = "runc"
+ // LinuxV1RuntimeName is the runtime used to specify the containerd v1 shim with the runc binary
+ // Note this is different than io.containerd.runc.v1 which would be the v1 shim using the v2 shim API.
+ // This is specifically for the v1 shim using the v1 shim API.
+ LinuxV1RuntimeName = "io.containerd.runtime.v1.linux"
+ // LinuxV2RuntimeName is the runtime used to specify the containerd v2 runc shim
+ LinuxV2RuntimeName = "io.containerd.runc.v2"
)
+var builtinRuntimes = map[string]bool{
+ StockRuntimeName: true,
+ LinuxV1RuntimeName: true,
+ LinuxV2RuntimeName: true,
+}
+
// flatOptions contains configuration keys
// that MUST NOT be parsed as deep structures.
// Use this to differentiate these options
@@ -571,10 +584,12 @@ func Validate(config *Config) error {
return err
}
- if defaultRuntime := config.GetDefaultRuntimeName(); defaultRuntime != "" && defaultRuntime != StockRuntimeName {
- runtimes := config.GetAllRuntimes()
- if _, ok := runtimes[defaultRuntime]; !ok {
- return fmt.Errorf("specified default runtime '%s' does not exist", defaultRuntime)
+ if defaultRuntime := config.GetDefaultRuntimeName(); defaultRuntime != "" {
+ if !builtinRuntimes[defaultRuntime] {
+ runtimes := config.GetAllRuntimes()
+ if _, ok := runtimes[defaultRuntime]; !ok {
+ return fmt.Errorf("specified default runtime '%s' does not exist", defaultRuntime)
+ }
}
}
diff --git a/daemon/daemon.go b/daemon/daemon.go
index 3ea3069888..98c852b425 100644
--- a/daemon/daemon.go
+++ b/daemon/daemon.go
@@ -932,7 +932,11 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
}
}
- return pluginexec.New(ctx, getPluginExecRoot(config.Root), pluginCli, config.ContainerdPluginNamespace, m, d.useShimV2())
+ var rt types.Runtime
+ if runtime := config.GetRuntime(config.GetDefaultRuntimeName()); runtime != nil {
+ rt = *runtime
+ }
+ return pluginexec.New(ctx, getPluginExecRoot(config.Root), pluginCli, config.ContainerdPluginNamespace, m, rt)
}
// Plugin system initialization should happen before restore. Do not change order.
@@ -1081,7 +1085,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
go d.execCommandGC()
- d.containerd, err = libcontainerd.NewClient(ctx, d.containerdCli, filepath.Join(config.ExecRoot, "containerd"), config.ContainerdNamespace, d, d.useShimV2())
+ d.containerd, err = libcontainerd.NewClient(ctx, d.containerdCli, filepath.Join(config.ExecRoot, "containerd"), config.ContainerdNamespace, d)
if err != nil {
return nil, err
}
diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go
index 1a577276ef..e3cf60e7fd 100644
--- a/daemon/daemon_unix.go
+++ b/daemon/daemon_unix.go
@@ -30,7 +30,6 @@ import (
"github.com/docker/docker/opts"
"github.com/docker/docker/pkg/containerfs"
"github.com/docker/docker/pkg/idtools"
- "github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/docker/pkg/sysinfo"
@@ -78,10 +77,6 @@ const (
cgroupFsDriver = "cgroupfs"
cgroupSystemdDriver = "systemd"
cgroupNoneDriver = "none"
-
- // DefaultRuntimeName is the default runtime to be used by
- // containerd if none is specified
- DefaultRuntimeName = "runc"
)
type containerGetter interface {
@@ -729,55 +724,11 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
}
}
- return warnings, nil
-}
-
-func (daemon *Daemon) loadRuntimes() error {
- return daemon.initRuntimes(daemon.configStore.Runtimes)
-}
-
-func (daemon *Daemon) initRuntimes(runtimes map[string]types.Runtime) (err error) {
- runtimeDir := filepath.Join(daemon.configStore.Root, "runtimes")
- // Remove old temp directory if any
- os.RemoveAll(runtimeDir + "-old")
- tmpDir, err := ioutils.TempDir(daemon.configStore.Root, "gen-runtimes")
- if err != nil {
- return errors.Wrap(err, "failed to get temp dir to generate runtime scripts")
+ if hostConfig.Runtime == config.LinuxV1RuntimeName || (hostConfig.Runtime == "" && daemon.configStore.DefaultRuntime == config.LinuxV1RuntimeName) {
+ warnings = append(warnings, fmt.Sprintf("Configured runtime %q is deprecated and will be removed in the next release.", config.LinuxV1RuntimeName))
}
- defer func() {
- if err != nil {
- if err1 := os.RemoveAll(tmpDir); err1 != nil {
- logrus.WithError(err1).WithField("dir", tmpDir).
- Warn("failed to remove tmp dir")
- }
- return
- }
-
- if err = os.Rename(runtimeDir, runtimeDir+"-old"); err != nil {
- return
- }
- if err = os.Rename(tmpDir, runtimeDir); err != nil {
- err = errors.Wrap(err, "failed to setup runtimes dir, new containers may not start")
- return
- }
- if err = os.RemoveAll(runtimeDir + "-old"); err != nil {
- logrus.WithError(err).WithField("dir", tmpDir).
- Warn("failed to remove old runtimes dir")
- }
- }()
- for name, rt := range runtimes {
- if len(rt.Args) == 0 {
- continue
- }
-
- script := filepath.Join(tmpDir, name)
- content := fmt.Sprintf("#!/bin/sh\n%s %s $@\n", rt.Path, strings.Join(rt.Args, " "))
- if err := ioutil.WriteFile(script, []byte(content), 0700); err != nil {
- return err
- }
- }
- return nil
+ return warnings, nil
}
// verifyDaemonSettings performs validation of daemon config struct
@@ -808,14 +759,15 @@ func verifyDaemonSettings(conf *config.Config) error {
return fmt.Errorf("exec-opt native.cgroupdriver=systemd requires cgroup v2 for rootless mode")
}
- if conf.DefaultRuntime == "" {
- conf.DefaultRuntime = config.StockRuntimeName
- }
- if conf.Runtimes == nil {
- conf.Runtimes = make(map[string]types.Runtime)
+ configureRuntimes(conf)
+ if rtName := conf.GetDefaultRuntimeName(); rtName != "" {
+ if conf.GetRuntime(rtName) == nil {
+ return fmt.Errorf("specified default runtime '%s' does not exist", rtName)
+ }
+ if rtName == config.LinuxV1RuntimeName {
+ logrus.Warnf("Configured default runtime %q is deprecated and will be removed in the next release.", config.LinuxV1RuntimeName)
+ }
}
- conf.Runtimes[config.StockRuntimeName] = types.Runtime{Path: DefaultRuntimeName}
-
return nil
}
@@ -1756,10 +1708,6 @@ func (daemon *Daemon) setupSeccompProfile() error {
return nil
}
-func (daemon *Daemon) useShimV2() bool {
- return cgroups.IsCgroup2UnifiedMode()
-}
-
// RawSysInfo returns *sysinfo.SysInfo .
func (daemon *Daemon) RawSysInfo(quiet bool) *sysinfo.SysInfo {
var opts []sysinfo.Opt
diff --git a/daemon/info.go b/daemon/info.go
index 72f30cdd00..cbae94ec47 100644
--- a/daemon/info.go
+++ b/daemon/info.go
@@ -11,6 +11,7 @@ import (
"github.com/docker/docker/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/cli/debug"
+ "github.com/docker/docker/daemon/config"
"github.com/docker/docker/daemon/logger"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/pkg/fileutils"
@@ -78,6 +79,10 @@ func (daemon *Daemon) SystemInfo() *types.Info {
daemon.fillSecurityOptions(v, sysInfo)
daemon.fillLicense(v)
+ if v.DefaultRuntime == config.LinuxV1RuntimeName {
+ v.Warnings = append(v.Warnings, fmt.Sprintf("Configured default runtime %q is deprecated and will be removed in the next release.", config.LinuxV1RuntimeName))
+ }
+
return v
}
diff --git a/daemon/runtime_unix.go b/daemon/runtime_unix.go
new file mode 100644
index 0000000000..17e2b15d49
--- /dev/null
+++ b/daemon/runtime_unix.go
@@ -0,0 +1,134 @@
+// +build !windows
+
+package daemon
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+
+ "github.com/containerd/containerd/runtime/linux/runctypes"
+ v2runcoptions "github.com/containerd/containerd/runtime/v2/runc/options"
+ "github.com/docker/docker/api/types"
+ "github.com/docker/docker/daemon/config"
+ "github.com/docker/docker/pkg/ioutils"
+ "github.com/opencontainers/runc/libcontainer/cgroups"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+const (
+ defaultRuntimeName = "runc"
+
+ linuxShimV1 = "io.containerd.runtime.v1.linux"
+ linuxShimV2 = "io.containerd.runc.v2"
+)
+
+func configureRuntimes(conf *config.Config) {
+ if conf.DefaultRuntime == "" {
+ conf.DefaultRuntime = config.StockRuntimeName
+ }
+ if conf.Runtimes == nil {
+ conf.Runtimes = make(map[string]types.Runtime)
+ }
+ conf.Runtimes[config.StockRuntimeName] = types.Runtime{Path: defaultRuntimeName, Shim: getShimConfig(conf, defaultRuntimeName)}
+ conf.Runtimes[config.LinuxV1RuntimeName] = types.Runtime{Path: defaultRuntimeName, Shim: defaultV1ShimConfig(conf, defaultRuntimeName)}
+ conf.Runtimes[config.LinuxV2RuntimeName] = types.Runtime{Path: defaultRuntimeName, Shim: defaultV2ShimConfig(conf, defaultRuntimeName)}
+}
+
+func getShimConfig(conf *config.Config, runtimePath string) *types.ShimConfig {
+ if cgroups.IsCgroup2UnifiedMode() {
+ return defaultV2ShimConfig(conf, runtimePath)
+ }
+ return defaultV1ShimConfig(conf, runtimePath)
+}
+
+func defaultV2ShimConfig(conf *config.Config, runtimePath string) *types.ShimConfig {
+ return &types.ShimConfig{
+ Binary: linuxShimV2,
+ Opts: &v2runcoptions.Options{
+ BinaryName: runtimePath,
+ Root: filepath.Join(conf.ExecRoot, "runtime-"+defaultRuntimeName),
+ SystemdCgroup: UsingSystemd(conf),
+ NoPivotRoot: os.Getenv("DOCKER_RAMDISK") != "",
+ },
+ }
+}
+
+func defaultV1ShimConfig(conf *config.Config, runtimePath string) *types.ShimConfig {
+ return &types.ShimConfig{
+ Binary: linuxShimV1,
+ Opts: &runctypes.RuncOptions{
+ Runtime: runtimePath,
+ RuntimeRoot: filepath.Join(conf.ExecRoot, "runtime-"+defaultRuntimeName),
+ SystemdCgroup: UsingSystemd(conf),
+ },
+ }
+}
+
+func (daemon *Daemon) loadRuntimes() error {
+ return daemon.initRuntimes(daemon.configStore.Runtimes)
+}
+
+func (daemon *Daemon) initRuntimes(runtimes map[string]types.Runtime) (err error) {
+ runtimeDir := filepath.Join(daemon.configStore.Root, "runtimes")
+ // Remove old temp directory if any
+ os.RemoveAll(runtimeDir + "-old")
+ tmpDir, err := ioutils.TempDir(daemon.configStore.Root, "gen-runtimes")
+ if err != nil {
+ return errors.Wrap(err, "failed to get temp dir to generate runtime scripts")
+ }
+ defer func() {
+ if err != nil {
+ if err1 := os.RemoveAll(tmpDir); err1 != nil {
+ logrus.WithError(err1).WithField("dir", tmpDir).
+ Warn("failed to remove tmp dir")
+ }
+ return
+ }
+
+ if err = os.Rename(runtimeDir, runtimeDir+"-old"); err != nil {
+ return
+ }
+ if err = os.Rename(tmpDir, runtimeDir); err != nil {
+ err = errors.Wrap(err, "failed to setup runtimes dir, new containers may not start")
+ return
+ }
+ if err = os.RemoveAll(runtimeDir + "-old"); err != nil {
+ logrus.WithError(err).WithField("dir", tmpDir).
+ Warn("failed to remove old runtimes dir")
+ }
+ }()
+
+ for name, rt := range runtimes {
+ if len(rt.Args) == 0 {
+ continue
+ }
+
+ script := filepath.Join(tmpDir, name)
+ content := fmt.Sprintf("#!/bin/sh\n%s %s $@\n", rt.Path, strings.Join(rt.Args, " "))
+ if err := ioutil.WriteFile(script, []byte(content), 0700); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// rewriteRuntimePath is used for runtimes which have custom arguments supplied.
+// This is needed because the containerd API only calls the OCI runtime binary, there is no options for extra arguments.
+// To support this case, the daemon wraps the specified runtime in a script that passes through those arguments.
+func (daemon *Daemon) rewriteRuntimePath(name, p string, args []string) (string, error) {
+ if len(args) == 0 {
+ return p, nil
+ }
+
+ // Check that the runtime path actually exists here so that we can return a well known error.
+ if _, err := exec.LookPath(p); err != nil {
+ return "", errors.Wrap(err, "error while looking up the specified runtime path")
+ }
+
+ return filepath.Join(daemon.configStore.Root, "runtimes", name), nil
+}
diff --git a/daemon/start.go b/daemon/start.go
index 857b5fb80b..6126efacbf 100644
--- a/daemon/start.go
+++ b/daemon/start.go
@@ -175,7 +175,7 @@ func (daemon *Daemon) containerStart(container *container.Container, checkpoint
}
}
- createOptions, err := daemon.getLibcontainerdCreateOptions(container)
+ shim, createOptions, err := daemon.getLibcontainerdCreateOptions(container)
if err != nil {
return err
}
@@ -187,7 +187,7 @@ func (daemon *Daemon) containerStart(container *container.Container, checkpoint
return err
}
- err = daemon.containerd.Create(ctx, container.ID, spec, createOptions, withImageName(imageRef.String()))
+ err = daemon.containerd.Create(ctx, container.ID, spec, shim, createOptions, withImageName(imageRef.String()))
if err != nil {
if errdefs.IsConflict(err) {
logrus.WithError(err).WithField("container", container.ID).Error("Container not cleaned up from containerd from previous run")
@@ -196,7 +196,7 @@ func (daemon *Daemon) containerStart(container *container.Container, checkpoint
if err := daemon.containerd.Delete(ctx, container.ID); err != nil && !errdefs.IsNotFound(err) {
logrus.WithError(err).WithField("container", container.ID).Error("Error cleaning up stale containerd container object")
}
- err = daemon.containerd.Create(ctx, container.ID, spec, createOptions, withImageName(imageRef.String()))
+ err = daemon.containerd.Create(ctx, container.ID, spec, shim, createOptions, withImageName(imageRef.String()))
}
if err != nil {
return translateContainerdStartErr(container.Path, container.SetExitCode, err)
diff --git a/daemon/start_unix.go b/daemon/start_unix.go
index 73963b9cf6..4373a97d83 100644
--- a/daemon/start_unix.go
+++ b/daemon/start_unix.go
@@ -3,70 +3,35 @@
package daemon // import "github.com/docker/docker/daemon"
import (
- "fmt"
- "os/exec"
- "path/filepath"
-
- "github.com/containerd/containerd/runtime/linux/runctypes"
- v2runcoptions "github.com/containerd/containerd/runtime/v2/runc/options"
"github.com/docker/docker/container"
"github.com/docker/docker/errdefs"
+ "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
-func (daemon *Daemon) getRuntimeScript(container *container.Container) (string, error) {
- name := container.HostConfig.Runtime
- rt := daemon.configStore.GetRuntime(name)
- if rt == nil {
- return "", errdefs.InvalidParameter(errors.Errorf("no such runtime '%s'", name))
- }
-
- if len(rt.Args) > 0 {
- // First check that the target exist, as using it in a script won't
- // give us the right error
- if _, err := exec.LookPath(rt.Path); err != nil {
- return "", translateContainerdStartErr(container.Path, container.SetExitCode, err)
- }
- return filepath.Join(daemon.configStore.Root, "runtimes", name), nil
- }
- return rt.Path, nil
-}
-
// getLibcontainerdCreateOptions callers must hold a lock on the container
-func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Container) (interface{}, error) {
+func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Container) (string, interface{}, error) {
// Ensure a runtime has been assigned to this container
if container.HostConfig.Runtime == "" {
container.HostConfig.Runtime = daemon.configStore.GetDefaultRuntimeName()
container.CheckpointTo(daemon.containersReplica)
}
- path, err := daemon.getRuntimeScript(container)
- if err != nil {
- return nil, err
- }
- if daemon.useShimV2() {
- opts := &v2runcoptions.Options{
- BinaryName: path,
- Root: filepath.Join(daemon.configStore.ExecRoot,
- fmt.Sprintf("runtime-%s", container.HostConfig.Runtime)),
+ rt := daemon.configStore.GetRuntime(container.HostConfig.Runtime)
+ if rt.Shim == nil {
+ p, err := daemon.rewriteRuntimePath(container.HostConfig.Runtime, rt.Path, rt.Args)
+ if err != nil {
+ return "", nil, translateContainerdStartErr(container.Path, container.SetExitCode, err)
}
-
- if UsingSystemd(daemon.configStore) {
- opts.SystemdCgroup = true
- }
-
- return opts, nil
-
+ rt.Shim = getShimConfig(daemon.configStore, p)
}
- opts := &runctypes.RuncOptions{
- Runtime: path,
- RuntimeRoot: filepath.Join(daemon.configStore.ExecRoot,
- fmt.Sprintf("runtime-%s", container.HostConfig.Runtime)),
- }
-
- if UsingSystemd(daemon.configStore) {
- opts.SystemdCgroup = true
+ if rt.Shim.Binary == linuxShimV1 {
+ if cgroups.IsCgroup2UnifiedMode() {
+ return "", nil, errdefs.InvalidParameter(errors.Errorf("runtime %q is not supported while cgroups v2 (unified hierarchy) is being used", container.HostConfig.Runtime))
+ }
+ logrus.Warnf("Configured runtime %q is deprecated and will be removed in the next release", container.HostConfig.Runtime)
}
- return opts, nil
+ return rt.Shim.Binary, rt.Shim.Opts, nil
}
diff --git a/daemon/start_windows.go b/daemon/start_windows.go
index fc34375e7e..d21fec5d70 100644
--- a/daemon/start_windows.go
+++ b/daemon/start_windows.go
@@ -7,12 +7,12 @@ import (
"github.com/docker/docker/pkg/system"
)
-func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Container) (interface{}, error) {
+func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Container) (string, interface{}, error) {
// Set the runtime options to debug regardless of current logging level.
if system.ContainerdRuntimeSupported() {
opts := &options.Options{Debug: true}
- return opts, nil
+ return "", opts, nil
}
// TODO (containerd) - Probably need to revisit LCOW options here
@@ -22,7 +22,7 @@ func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Contain
if container.OS == "linux" {
config := &client.Config{}
if err := config.GenerateDefault(daemon.configStore.GraphOptions); err != nil {
- return nil, err
+ return "", nil, err
}
// Override from user-supplied options.
for k, v := range container.HostConfig.StorageOpt {
@@ -34,11 +34,11 @@ func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Contain
}
}
if err := config.Validate(); err != nil {
- return nil, err
+ return "", nil, err
}
- return config, nil
+ return "", config, nil
}
- return nil, nil
+ return "", nil, nil
}
diff --git a/daemon/util_test.go b/daemon/util_test.go
index 6ef9ba682b..05cf1dd344 100644
--- a/daemon/util_test.go
+++ b/daemon/util_test.go
@@ -28,7 +28,7 @@ func (c *MockContainerdClient) Version(ctx context.Context) (containerd.Version,
func (c *MockContainerdClient) Restore(ctx context.Context, containerID string, attachStdio libcontainerdtypes.StdioCallback) (alive bool, pid int, p libcontainerdtypes.Process, err error) {
return false, 0, &mockProcess{}, nil
}
-func (c *MockContainerdClient) Create(ctx context.Context, containerID string, spec *specs.Spec, runtimeOptions interface{}, opts ...containerd.NewContainerOpts) error {
+func (c *MockContainerdClient) Create(ctx context.Context, containerID string, spec *specs.Spec, shim string, runtimeOptions interface{}, opts ...containerd.NewContainerOpts) error {
return nil
}
func (c *MockContainerdClient) Start(ctx context.Context, containerID, checkpointDir string, withStdin bool, attachStdio libcontainerdtypes.StdioCallback) (pid int, err error) {
diff --git a/libcontainerd/libcontainerd_linux.go b/libcontainerd/libcontainerd_linux.go
index 3b008fe256..ec195a7905 100644
--- a/libcontainerd/libcontainerd_linux.go
+++ b/libcontainerd/libcontainerd_linux.go
@@ -9,6 +9,6 @@ import (
)
// NewClient creates a new libcontainerd client from a containerd client
-func NewClient(ctx context.Context, cli *containerd.Client, stateDir, ns string, b libcontainerdtypes.Backend, useShimV2 bool) (libcontainerdtypes.Client, error) {
- return remote.NewClient(ctx, cli, stateDir, ns, b, useShimV2)
+func NewClient(ctx context.Context, cli *containerd.Client, stateDir, ns string, b libcontainerdtypes.Backend) (libcontainerdtypes.Client, error) {
+ return remote.NewClient(ctx, cli, stateDir, ns, b)
}
diff --git a/libcontainerd/libcontainerd_windows.go b/libcontainerd/libcontainerd_windows.go
index 5a64180be4..e7f0bc9d30 100644
--- a/libcontainerd/libcontainerd_windows.go
+++ b/libcontainerd/libcontainerd_windows.go
@@ -11,10 +11,10 @@ import (
)
// NewClient creates a new libcontainerd client from a containerd client
-func NewClient(ctx context.Context, cli *containerd.Client, stateDir, ns string, b libcontainerdtypes.Backend, useShimV2 bool) (libcontainerdtypes.Client, error) {
+func NewClient(ctx context.Context, cli *containerd.Client, stateDir, ns string, b libcontainerdtypes.Backend) (libcontainerdtypes.Client, error) {
if !system.ContainerdRuntimeSupported() {
// useShimV2 is ignored for windows
return local.NewClient(ctx, cli, stateDir, ns, b)
}
- return remote.NewClient(ctx, cli, stateDir, ns, b, useShimV2)
+ return remote.NewClient(ctx, cli, stateDir, ns, b)
}
diff --git a/libcontainerd/local/local_windows.go b/libcontainerd/local/local_windows.go
index 67592e54e8..85e1d8c772 100644
--- a/libcontainerd/local/local_windows.go
+++ b/libcontainerd/local/local_windows.go
@@ -153,7 +153,7 @@ func (c *client) Version(ctx context.Context) (containerd.Version, error) {
// "ImagePath": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c\\\\UtilityVM"
// },
// }
-func (c *client) Create(_ context.Context, id string, spec *specs.Spec, runtimeOptions interface{}, opts ...containerd.NewContainerOpts) error {
+func (c *client) Create(_ context.Context, id string, spec *specs.Spec, shim string, runtimeOptions interface{}, opts ...containerd.NewContainerOpts) error {
if ctr := c.getContainer(id); ctr != nil {
return errors.WithStack(errdefs.Conflict(errors.New("id already in use")))
}
diff --git a/libcontainerd/remote/client.go b/libcontainerd/remote/client.go
index 9bc4ffde02..11a5990a7b 100644
--- a/libcontainerd/remote/client.go
+++ b/libcontainerd/remote/client.go
@@ -50,14 +50,13 @@ type client struct {
eventQ queue.Queue
oomMu sync.Mutex
oom map[string]bool
- useShimV2 bool
v2runcoptionsMu sync.Mutex
// v2runcoptions is used for copying options specified on Create() to Start()
v2runcoptions map[string]v2runcoptions.Options
}
// NewClient creates a new libcontainerd client from a containerd client
-func NewClient(ctx context.Context, cli *containerd.Client, stateDir, ns string, b libcontainerdtypes.Backend, useShimV2 bool) (libcontainerdtypes.Client, error) {
+func NewClient(ctx context.Context, cli *containerd.Client, stateDir, ns string, b libcontainerdtypes.Backend) (libcontainerdtypes.Client, error) {
c := &client{
client: cli,
stateDir: stateDir,
@@ -65,7 +64,6 @@ func NewClient(ctx context.Context, cli *containerd.Client, stateDir, ns string,
ns: ns,
backend: b,
oom: make(map[string]bool),
- useShimV2: useShimV2,
v2runcoptions: make(map[string]v2runcoptions.Options),
}
@@ -129,17 +127,13 @@ func (c *client) Restore(ctx context.Context, id string, attachStdio libcontaine
}, nil
}
-func (c *client) Create(ctx context.Context, id string, ociSpec *specs.Spec, runtimeOptions interface{}, opts ...containerd.NewContainerOpts) error {
+func (c *client) Create(ctx context.Context, id string, ociSpec *specs.Spec, shim string, runtimeOptions interface{}, opts ...containerd.NewContainerOpts) error {
bdir := c.bundleDir(id)
c.logger.WithField("bundle", bdir).WithField("root", ociSpec.Root.Path).Debug("bundle dir created")
- rt := runtimeName
- if c.useShimV2 {
- rt = shimV2RuntimeName
- }
newOpts := []containerd.NewContainerOpts{
containerd.WithSpec(ociSpec),
- containerd.WithRuntime(rt, runtimeOptions),
+ containerd.WithRuntime(shim, runtimeOptions),
WithBundle(bdir, ociSpec),
}
opts = append(opts, newOpts...)
@@ -151,12 +145,10 @@ func (c *client) Create(ctx context.Context, id string, ociSpec *specs.Spec, run
}
return wrapError(err)
}
- if c.useShimV2 {
- if x, ok := runtimeOptions.(*v2runcoptions.Options); ok {
- c.v2runcoptionsMu.Lock()
- c.v2runcoptions[id] = *x
- c.v2runcoptionsMu.Unlock()
- }
+ if x, ok := runtimeOptions.(*v2runcoptions.Options); ok {
+ c.v2runcoptionsMu.Lock()
+ c.v2runcoptions[id] = *x
+ c.v2runcoptionsMu.Unlock()
}
return nil
}
@@ -218,17 +210,12 @@ func (c *client) Start(ctx context.Context, id, checkpointDir string, withStdin
if runtime.GOOS != "windows" {
taskOpts = append(taskOpts, func(_ context.Context, _ *containerd.Client, info *containerd.TaskInfo) error {
- if c.useShimV2 {
- // For v2, we need to inherit options specified on Create
- c.v2runcoptionsMu.Lock()
- opts, ok := c.v2runcoptions[id]
- c.v2runcoptionsMu.Unlock()
- if !ok {
- opts = v2runcoptions.Options{}
- }
+ c.v2runcoptionsMu.Lock()
+ opts, ok := c.v2runcoptions[id]
+ c.v2runcoptionsMu.Unlock()
+ if ok {
opts.IoUid = uint32(uid)
opts.IoGid = uint32(gid)
- opts.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != ""
info.Options = &opts
} else {
info.Options = &runctypes.CreateOptions{
@@ -237,7 +224,6 @@ func (c *client) Start(ctx context.Context, id, checkpointDir string, withStdin
NoPivotRoot: os.Getenv("DOCKER_RAMDISK") != "",
}
}
-
return nil
})
} else {
diff --git a/libcontainerd/remote/client_linux.go b/libcontainerd/remote/client_linux.go
index 637ac94d82..e45d140b2f 100644
--- a/libcontainerd/remote/client_linux.go
+++ b/libcontainerd/remote/client_linux.go
@@ -16,11 +16,6 @@ import (
"github.com/sirupsen/logrus"
)
-const (
- runtimeName = "io.containerd.runtime.v1.linux"
- shimV2RuntimeName = "io.containerd.runc.v2"
-)
-
func summaryFromInterface(i interface{}) (*libcontainerdtypes.Summary, error) {
return &libcontainerdtypes.Summary{}, nil
}
diff --git a/libcontainerd/types/types.go b/libcontainerd/types/types.go
index ba88e4db6f..1d1a420e79 100644
--- a/libcontainerd/types/types.go
+++ b/libcontainerd/types/types.go
@@ -52,7 +52,7 @@ type Client interface {
Restore(ctx context.Context, containerID string, attachStdio StdioCallback) (alive bool, pid int, p Process, err error)
- Create(ctx context.Context, containerID string, spec *specs.Spec, runtimeOptions interface{}, opts ...containerd.NewContainerOpts) error
+ Create(ctx context.Context, containerID string, spec *specs.Spec, shim string, runtimeOptions interface{}, opts ...containerd.NewContainerOpts) error
Start(ctx context.Context, containerID, checkpointDir string, withStdin bool, attachStdio StdioCallback) (pid int, err error)
SignalProcess(ctx context.Context, containerID, processID string, signal int) error
Exec(ctx context.Context, containerID, processID string, spec *specs.Process, withStdin bool, attachStdio StdioCallback) (int, error)
diff --git a/plugin/executor/containerd/containerd.go b/plugin/executor/containerd/containerd.go
index aeeb2184ec..8354745990 100644
--- a/plugin/executor/containerd/containerd.go
+++ b/plugin/executor/containerd/containerd.go
@@ -3,12 +3,11 @@ package containerd // import "github.com/docker/docker/plugin/executor/container
import (
"context"
"io"
- "path/filepath"
"sync"
"github.com/containerd/containerd"
"github.com/containerd/containerd/cio"
- "github.com/containerd/containerd/runtime/linux/runctypes"
+ "github.com/docker/docker/api/types"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/libcontainerd"
libcontainerdtypes "github.com/docker/docker/libcontainerd/types"
@@ -26,13 +25,14 @@ type ExitHandler interface {
}
// New creates a new containerd plugin executor
-func New(ctx context.Context, rootDir string, cli *containerd.Client, ns string, exitHandler ExitHandler, useShimV2 bool) (*Executor, error) {
+func New(ctx context.Context, rootDir string, cli *containerd.Client, ns string, exitHandler ExitHandler, runtime types.Runtime) (*Executor, error) {
e := &Executor{
rootDir: rootDir,
exitHandler: exitHandler,
+ runtime: runtime,
}
- client, err := libcontainerd.NewClient(ctx, cli, rootDir, ns, e, useShimV2)
+ client, err := libcontainerd.NewClient(ctx, cli, rootDir, ns, e)
if err != nil {
return nil, errors.Wrap(err, "error creating containerd exec client")
}
@@ -45,6 +45,7 @@ type Executor struct {
rootDir string
client libcontainerdtypes.Client
exitHandler ExitHandler
+ runtime types.Runtime
}
// deleteTaskAndContainer deletes plugin task and then plugin container from containerd
@@ -66,11 +67,8 @@ func deleteTaskAndContainer(ctx context.Context, cli libcontainerdtypes.Client,
// Create creates a new container
func (e *Executor) Create(id string, spec specs.Spec, stdout, stderr io.WriteCloser) error {
- opts := runctypes.RuncOptions{
- RuntimeRoot: filepath.Join(e.rootDir, "runtime-root"),
- }
ctx := context.Background()
- err := e.client.Create(ctx, id, &spec, &opts)
+ err := e.client.Create(ctx, id, &spec, e.runtime.Shim.Binary, e.runtime.Shim.Opts)
if err != nil {
status, err2 := e.client.Status(ctx, id)
if err2 != nil {
@@ -82,7 +80,7 @@ func (e *Executor) Create(id string, spec specs.Spec, stdout, stderr io.WriteClo
if err2 := e.client.Delete(ctx, id); err2 != nil && !errdefs.IsNotFound(err2) {
logrus.WithError(err2).WithField("plugin", id).Error("Error cleaning up containerd container")
}
- err = e.client.Create(ctx, id, &spec, &opts)
+ err = e.client.Create(ctx, id, &spec, e.runtime.Shim.Binary, e.runtime.Shim.Opts)
}
}