mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-04 02:56:18 +00:00
containerd-shim-kata-v2: add the create service support
Add the "Create" api support for creating a pod or container. Signed-off-by: fupan <lifupan@gmail.com>
This commit is contained in:
parent
d6c4ca5fe5
commit
72fd6e0c7d
@ -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"
|
||||
)
|
||||
@ -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
containerd-shim-v2/create.go
Normal file
102
containerd-shim-v2/create.go
Normal file
@ -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
|
||||
}
|
@ -8,6 +8,7 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
sysexec "os/exec"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
@ -15,6 +16,7 @@ import (
|
||||
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"
|
||||
@ -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"
|
||||
)
|
||||
|
||||
@ -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
|
||||
|
@ -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")
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user