Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
containerd-shim-kata-v2: add the create service support
Browse files Browse the repository at this point in the history
Add the "Create" api support for creating a pod
or container.

Signed-off-by: fupan <[email protected]>
  • Loading branch information
lifupan committed Nov 28, 2018
1 parent d6c4ca5 commit 72fd6e0
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 3 deletions.
32 changes: 32 additions & 0 deletions containerd-shim-v2/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import (
"time"

"github.com/containerd/containerd/api/types/task"
"github.com/containerd/containerd/errdefs"
taskAPI "github.com/containerd/containerd/runtime/v2/task"

vc "github.com/kata-containers/runtime/virtcontainers"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
)
Expand All @@ -33,3 +36,32 @@ type container struct {
status task.Status
terminal bool
}

func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.ContainerType, spec *oci.CompatOCISpec) (*container, error) {
if r == nil {
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, " CreateTaskRequest points to nil")
}

// in order to avoid deferencing a nil pointer in test
if spec == nil {
spec = &oci.CompatOCISpec{}
}

c := &container{
s: s,
spec: spec,
id: r.ID,
bundle: r.Bundle,
stdin: r.Stdin,
stdout: r.Stdout,
stderr: r.Stderr,
terminal: r.Terminal,
cType: containerType,
execs: make(map[string]*exec),
status: task.StatusCreated,
exitIOch: make(chan struct{}),
exitCh: make(chan uint32, 1),
time: time.Now(),
}
return c, nil
}
102 changes: 102 additions & 0 deletions containerd-shim-v2/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (c) 2014,2015,2016 Docker, Inc.
// Copyright (c) 2017 Intel Corporation
// Copyright (c) 2018 HyperHQ Inc.
//
// SPDX-License-Identifier: Apache-2.0
//

package containerdshim

import (
"context"
"fmt"

vc "github.com/kata-containers/runtime/virtcontainers"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"

taskAPI "github.com/containerd/containerd/runtime/v2/task"

"github.com/kata-containers/runtime/pkg/katautils"
"github.com/opencontainers/runtime-spec/specs-go"
)

func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest, netns string,
runtimeConfig *oci.RuntimeConfig) (*container, error) {

detach := !r.Terminal

// Checks the MUST and MUST NOT from OCI runtime specification
bundlePath, err := validBundle(r.ID, r.Bundle)
if err != nil {
return nil, err
}

ociSpec, err := oci.ParseConfigJSON(bundlePath)
if err != nil {
return nil, err
}

containerType, err := ociSpec.ContainerType()
if err != nil {
return nil, err
}

// Todo:
// Since there is a bug in kata for sharedPidNs, here to
// remove the pidns to disable the sharePidNs temporarily,
// once kata fixed this issue, we can remove this line.
// For the bug, please see:
// https://github.com/kata-containers/runtime/issues/930
removeNamespace(&ociSpec, specs.PIDNamespace)

//set the network namespace path
//this set will be applied to sandbox's
//network config and has nothing to
//do with containers in the sandbox since
//networkNamespace has been ignored by
//kata-agent in sandbox.

for _, n := range ociSpec.Linux.Namespaces {
if n.Type != specs.NetworkNamespace {
continue
}

if n.Path == "" {
n.Path = netns
}
}

katautils.HandleFactory(ctx, vci, runtimeConfig)

disableOutput := noNeedForOutput(detach, ociSpec.Process.Terminal)

switch containerType {
case vc.PodSandbox:
if s.sandbox != nil {
return nil, fmt.Errorf("cannot create another sandbox in sandbox: %s", s.sandbox.ID())
}

sandbox, _, err := katautils.CreateSandbox(ctx, vci, ociSpec, *runtimeConfig, r.ID, bundlePath, "", disableOutput, false, true)
if err != nil {
return nil, err
}
s.sandbox = sandbox

case vc.PodContainer:
if s.sandbox == nil {
return nil, fmt.Errorf("BUG: Cannot start the container, since the sandbox hasn't been created")
}

_, err = katautils.CreateContainer(ctx, vci, s.sandbox, ociSpec, r.ID, bundlePath, "", disableOutput, true)
if err != nil {
return nil, err
}
}

container, err := newContainer(s, r, containerType, &ociSpec)
if err != nil {
return nil, err
}

return container, nil
}
45 changes: 44 additions & 1 deletion containerd-shim-v2/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (
"context"
"os"
sysexec "os/exec"
"path/filepath"
"sync"
"syscall"
"time"

eventstypes "github.com/containerd/containerd/api/events"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/namespaces"
cdruntime "github.com/containerd/containerd/runtime"
cdshim "github.com/containerd/containerd/runtime/v2/shim"
Expand All @@ -23,7 +25,9 @@ import (
vc "github.com/kata-containers/runtime/virtcontainers"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"

"github.com/containerd/containerd/api/types/task"
ptypes "github.com/gogo/protobuf/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -235,7 +239,46 @@ func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error)

// Create a new sandbox or container with the underlying OCI runtime
func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (_ *taskAPI.CreateTaskResponse, err error) {
return nil, errdefs.ErrNotImplemented
s.Lock()
defer s.Unlock()

//the network namespace created by cni plugin
netns, err := namespaces.NamespaceRequired(ctx)
if err != nil {
return nil, errors.Wrap(err, "create namespace")
}

rootfs := filepath.Join(r.Bundle, "rootfs")
defer func() {
if err != nil {
if err2 := mount.UnmountAll(rootfs, 0); err2 != nil {
logrus.WithError(err2).Warn("failed to cleanup rootfs mount")
}
}
}()
for _, rm := range r.Rootfs {
m := &mount.Mount{
Type: rm.Type,
Source: rm.Source,
Options: rm.Options,
}
if err := m.Mount(rootfs); err != nil {
return nil, errors.Wrapf(err, "failed to mount rootfs component %v", m)
}
}

container, err := create(ctx, s, r, netns, s.config)
if err != nil {
return nil, err
}

container.status = task.StatusCreated

s.containers[r.ID] = container

return &taskAPI.CreateTaskResponse{
Pid: s.pid,
}, nil
}

// Start a process
Expand Down
26 changes: 24 additions & 2 deletions containerd-shim-v2/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import (
"github.com/kata-containers/runtime/pkg/katautils"
vc "github.com/kata-containers/runtime/virtcontainers"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
"github.com/opencontainers/runtime-spec/specs-go"
)

func validCreateParams(containerID, bundlePath string) (string, error) {
func validBundle(containerID, bundlePath string) (string, error) {
// container ID MUST be provided.
if containerID == "" {
return "", fmt.Errorf("Missing container ID")
Expand Down Expand Up @@ -49,7 +50,7 @@ func getAddress(ctx context.Context, bundlePath, id string) (string, error) {
var err error

// Checks the MUST and MUST NOT from OCI runtime specification
if bundlePath, err = validCreateParams(id, bundlePath); err != nil {
if bundlePath, err = validBundle(id, bundlePath); err != nil {
return "", err
}

Expand Down Expand Up @@ -77,3 +78,24 @@ func getAddress(ctx context.Context, bundlePath, id string) (string, error) {

return "", nil
}

func noNeedForOutput(detach bool, tty bool) bool {
if !detach {
return false
}

if !tty {
return false
}

return true
}

func removeNamespace(s *oci.CompatOCISpec, nsType specs.LinuxNamespaceType) {
for i, n := range s.Linux.Namespaces {
if n.Type == nsType {
s.Linux.Namespaces = append(s.Linux.Namespaces[:i], s.Linux.Namespaces[i+1:]...)
return
}
}
}

0 comments on commit 72fd6e0

Please sign in to comment.