containerd-shim-kata-v2: add the service Cleanup support

Add the Cleanup api support to cleanup the pod and
containers running in it when the pod's corresponding
shim died.

Signed-off-by: fupan <lifupan@gmail.com>
This commit is contained in:
fupan 2018-11-19 11:27:54 +08:00
parent a0e6456455
commit 709bc9aa12
2 changed files with 105 additions and 1 deletions

View File

@ -29,6 +29,7 @@ import (
ptypes "github.com/gogo/protobuf/types" ptypes "github.com/gogo/protobuf/types"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
) )
const ( const (
@ -235,7 +236,53 @@ func getTopic(ctx context.Context, e interface{}) string {
} }
func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error) { func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error) {
return nil, errdefs.ErrNotImplemented //Since the binary cleanup will return the DeleteResponse from stdout to
//containerd, thus we must make sure there is no any outputs in stdout except
//the returned response, thus here redirect the log to stderr in case there's
//any log output to stdout.
logrus.SetOutput(os.Stderr)
if s.id == "" {
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "the container id is empty, please specify the container id")
}
path, err := os.Getwd()
if err != nil {
return nil, err
}
ociSpec, err := oci.ParseConfigJSON(path)
if err != nil {
return nil, err
}
containerType, err := ociSpec.ContainerType()
if err != nil {
return nil, err
}
switch containerType {
case vc.PodSandbox:
err = cleanupContainer(ctx, s.id, s.id, path)
if err != nil {
return nil, err
}
case vc.PodContainer:
sandboxID, err := ociSpec.SandboxID()
if err != nil {
return nil, err
}
err = cleanupContainer(ctx, sandboxID, s.id, path)
if err != nil {
return nil, err
}
}
return &taskAPI.DeleteResponse{
ExitedAt: time.Now(),
ExitStatus: 128 + uint32(unix.SIGKILL),
}, nil
} }
// Create a new sandbox or container with the underlying OCI runtime // Create a new sandbox or container with the underlying OCI runtime

View File

@ -10,13 +10,17 @@ import (
"context" "context"
"fmt" "fmt"
"os" "os"
"path/filepath"
"syscall"
"time" "time"
"github.com/containerd/containerd/mount"
cdshim "github.com/containerd/containerd/runtime/v2/shim" cdshim "github.com/containerd/containerd/runtime/v2/shim"
"github.com/kata-containers/runtime/pkg/katautils" "github.com/kata-containers/runtime/pkg/katautils"
vc "github.com/kata-containers/runtime/virtcontainers" vc "github.com/kata-containers/runtime/virtcontainers"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci" "github.com/kata-containers/runtime/virtcontainers/pkg/oci"
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
) )
func cReap(s *service, status int, id, execid string, exitat time.Time) { func cReap(s *service, status int, id, execid string, exitat time.Time) {
@ -29,6 +33,59 @@ func cReap(s *service, status int, id, execid string, exitat time.Time) {
} }
} }
func cleanupContainer(ctx context.Context, sid, cid, bundlePath string) error {
logrus.WithField("Service", "Cleanup").WithField("container", cid).Info("Cleanup container")
rootfs := filepath.Join(bundlePath, "rootfs")
sandbox, err := vci.FetchSandbox(ctx, sid)
if err != nil {
return err
}
status, err := sandbox.StatusContainer(cid)
if err != nil {
logrus.WithError(err).WithField("container", cid).Warn("failed to get container status")
return err
}
if oci.StateToOCIState(status.State) != oci.StateStopped {
err := sandbox.KillContainer(cid, syscall.SIGKILL, true)
if err != nil {
logrus.WithError(err).WithField("container", cid).Warn("failed to kill container")
return err
}
}
if _, err = sandbox.StopContainer(cid); err != nil {
logrus.WithError(err).WithField("container", cid).Warn("failed to stop container")
return err
}
if _, err := sandbox.DeleteContainer(cid); err != nil {
logrus.WithError(err).WithField("container", cid).Warn("failed to remove container")
}
if err := mount.UnmountAll(rootfs, 0); err != nil {
logrus.WithError(err).WithField("container", cid).Warn("failed to cleanup container rootfs")
}
if len(sandbox.GetAllContainers()) == 0 {
err = sandbox.Stop()
if err != nil {
logrus.WithError(err).WithField("sandbox", sid).Warn("failed to stop sandbox")
return err
}
err = sandbox.Delete()
if err != nil {
logrus.WithError(err).WithField("sandbox", sid).Warnf("failed to delete sandbox")
return err
}
}
return nil
}
func validBundle(containerID, bundlePath string) (string, error) { func validBundle(containerID, bundlePath string) (string, error) {
// container ID MUST be provided. // container ID MUST be provided.
if containerID == "" { if containerID == "" {