Skip to content

Commit

Permalink
feature: support containerd shim v2
Browse files Browse the repository at this point in the history
Signed-off-by: zhuangqh <zhuangqhc@gmail.com>
  • Loading branch information
zhuangqh authored and fuweid committed May 13, 2019
1 parent 0ab3003 commit 1e283c0
Show file tree
Hide file tree
Showing 14 changed files with 1,514 additions and 45 deletions.
11 changes: 11 additions & 0 deletions apis/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2011,6 +2011,13 @@ definitions:
and SELinux.
type: "object"
properties:
type:
description: The runtime type used in containerd.
type: "string"
example: "io.containerd.runtime.v1.linux"
options:
description: Options are config options for specific runtime.
x-go-type: "interface{}"
path:
description: |
Name and, optional, path, of the OCI executable binary.
Expand All @@ -2022,6 +2029,7 @@ definitions:
runtimeArgs:
description: |
List of command-line arguments to pass to the runtime when invoked.
DEPRECATED: Use Options instead. Remove when shim v1 is deprecated.
type: "array"
x-nullable: true
items:
Expand Down Expand Up @@ -2452,6 +2460,9 @@ definitions:
Runtime:
type: "string"
description: "Runtime to use with this container."
RuntimeType:
type: "string"
description: "The runtime type used in containerd."
# Applicable to Windows
ConsoleSize:
type: "array"
Expand Down
11 changes: 11 additions & 0 deletions apis/types/host_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions apis/types/runtime.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 11 additions & 7 deletions ctrd/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,22 @@ import (
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/leases"
"github.com/containerd/containerd/oci"
"github.com/containerd/containerd/runtime/linux/runctypes"
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

var (
runtimeRoot = "/run"
// RuntimeRoot is the base directory path for each runtime.
RuntimeRoot = "/run"
// RuntimeTypeV1 is the runtime type name for containerd shim interface v1 version.
RuntimeTypeV1 = fmt.Sprintf("io.containerd.runtime.v1.%s", runtime.GOOS)
// RuntimeTypeV2runscV1 is the runtime type name for gVisor containerd shim implement the shim v2 api.
RuntimeTypeV2runscV1 = "io.containerd.runsc.v1"
// RuntimeTypeV2kataV2 is the runtime type name for kata-runtime containerd shim implement the shim v2 api.
RuntimeTypeV2kataV2 = "io.containerd.kata.v2"
// RuntimeTypeV2runcV1 is the runtime type name for runc containerd shim implement the shim v2 api.
RuntimeTypeV2runcV1 = "io.containerd.runc.v1"
)

type containerPack struct {
Expand Down Expand Up @@ -543,11 +551,7 @@ func (c *Client) createContainer(ctx context.Context, ref, id, checkpointDir str
options := []containerd.NewContainerOpts{
containerd.WithSnapshotter(CurrentSnapshotterName(ctx)),
containerd.WithContainerLabels(container.Labels),
containerd.WithRuntime(fmt.Sprintf("io.containerd.runtime.v1.%s", runtime.GOOS), &runctypes.RuncOptions{
Runtime: container.Runtime,
RuntimeRoot: runtimeRoot,
SystemdCgroup: container.UseSystemd,
}),
containerd.WithRuntime(container.RuntimeType, container.RuntimeOptions),
}

rootFSPath := "rootfs"
Expand Down
15 changes: 8 additions & 7 deletions ctrd/container_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import (
// then create container by specifying the snapshot;
// The other is create container by specify container rootfs, we use `RootFSProvided` flag to mark it,
type Container struct {
ID string
Image string
Runtime string
Labels map[string]string
IO *containerio.IO
Spec *specs.Spec
SnapshotID string
ID string
Image string
RuntimeType string
RuntimeOptions interface{}
Labels map[string]string
IO *containerio.IO
Spec *specs.Spec
SnapshotID string

// BaseFS is rootfs used by containerd container
BaseFS string
Expand Down
56 changes: 48 additions & 8 deletions daemon/daemon_utils.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package daemon

import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/alibaba/pouch/apis/types"
"github.com/alibaba/pouch/ctrd"

"github.com/containerd/containerd/runtime/linux/runctypes"
runcoptions "github.com/containerd/containerd/runtime/v2/runc/options"
)

var (
Expand All @@ -20,6 +25,7 @@ var (
// we will make a executable script as a path, or runtime.path is record as path.
// NOTE: containerd not support runtime args directly, so we make executable
// script include runtime path and args as a runtime execute binary.
// this solution would be deprecated after shim v1 is deprecated.
func initialRuntime(baseDir string, runtimes map[string]types.Runtime) error {
dir := filepath.Join(baseDir, runtimeDir)

Expand All @@ -35,20 +41,54 @@ func initialRuntime(baseDir string, runtimes map[string]types.Runtime) error {

// create script for runtime who has args
for name, r := range runtimes {
if len(r.RuntimeArgs) == 0 {
continue
}

script := filepath.Join(dir, name)
if r.Path == "" {
r.Path = name
}
data := fmt.Sprintf("#!/bin/sh\n%s %s $@\n", r.Path, strings.Join(r.RuntimeArgs, " "))

if err := ioutil.WriteFile(script, []byte(data), runtimeScriptPerm); err != nil {
return fmt.Errorf("failed to create runtime script %s: %s", script, err)
// setup a fake path
if len(r.RuntimeArgs) != 0 {
data := fmt.Sprintf("#!/bin/sh\n%s %s $@\n", r.Path, strings.Join(r.RuntimeArgs, " "))
r.Path = filepath.Join(dir, name)

if err := ioutil.WriteFile(r.Path, []byte(data), runtimeScriptPerm); err != nil {
return fmt.Errorf("failed to create runtime script %s: %s", r.Path, err)
}
}

if r.Type == "" {
r.Type = ctrd.RuntimeTypeV1
}

options := getRuntimeOptionsType(r.Type)
if options != nil {
// convert general json map to specific options type
b, err := json.Marshal(r.Options)
if err != nil {
return fmt.Errorf("failed to marshal options, runtime: %s: %v", name, err)
}
if err := json.Unmarshal(b, options); err != nil {
return fmt.Errorf("failed to unmarshal to type %+v: %v", options, err)
}
}

r.Options = options

runtimes[name] = r
}

return nil
}

func getRuntimeOptionsType(runtimeType string) interface{} {
switch runtimeType {
case
ctrd.RuntimeTypeV1,
ctrd.RuntimeTypeV2runscV1,
ctrd.RuntimeTypeV2kataV2:
return &runctypes.RuncOptions{}
case ctrd.RuntimeTypeV2runcV1:
return &runcoptions.Options{}
default:
return nil
}
}
24 changes: 18 additions & 6 deletions daemon/mgr/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,9 @@ func (mgr *ContainerManager) Create(ctx context.Context, name string, config *ty
config.HostConfig.Runtime = mgr.Config.DefaultRuntime
}

if _, exist := mgr.Config.Runtimes[config.HostConfig.Runtime]; !exist {
return nil, errors.Wrapf(errtypes.ErrInvalidParam, "unknown runtime %s", config.HostConfig.Runtime)
config.HostConfig.RuntimeType, err = mgr.getRuntimeType(config.HostConfig.Runtime)
if err != nil {
return nil, errors.Wrapf(errtypes.ErrInvalidParam, "unknown runtime %s: %v", config.HostConfig.Runtime, err)
}

snapID := id
Expand Down Expand Up @@ -794,7 +795,11 @@ func (mgr *ContainerManager) createContainerdContainer(ctx context.Context, c *C
// set container's LogPath
mgr.SetContainerLogPath(c)

runtime, err := mgr.getRuntime(c.HostConfig.Runtime)
if c.HostConfig.RuntimeType == "" {
c.HostConfig.RuntimeType = ctrd.RuntimeTypeV1
}

runtimeOptions, err := mgr.generateRuntimeOptions(c.HostConfig.Runtime)
if err != nil {
return err
}
Expand All @@ -803,7 +808,8 @@ func (mgr *ContainerManager) createContainerdContainer(ctx context.Context, c *C
ID: c.ID,
Image: c.Config.Image,
Labels: c.Config.Labels,
Runtime: runtime,
RuntimeType: c.HostConfig.RuntimeType,
RuntimeOptions: runtimeOptions,
Spec: sw.s,
IO: mgr.IOs.Get(c.ID),
RootFSProvided: c.RootFSProvided,
Expand Down Expand Up @@ -1932,8 +1938,14 @@ func (mgr *ContainerManager) setBaseFS(ctx context.Context, c *Container) {
return
}

// io.containerd.runtime.v1.linux as a const used by runc
c.BaseFS = filepath.Join(mgr.Config.HomeDir, "containerd/state", "io.containerd.runtime.v1.linux", mgr.Config.DefaultNamespace, c.ID, "rootfs")
var managerID string
if c.HostConfig.RuntimeType == ctrd.RuntimeTypeV1 {
managerID = ctrd.RuntimeTypeV1
} else {
managerID = "io.containerd.runtime.v2.task"
}

c.BaseFS = filepath.Join(mgr.Config.HomeDir, "containerd/state", managerID, mgr.Config.DefaultNamespace, c.ID, "rootfs")
}

// execProcessGC cleans unused exec processes config every 5 minutes.
Expand Down
Loading

0 comments on commit 1e283c0

Please sign in to comment.