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 service Cleanup support
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
lifupan committed Nov 28, 2018
1 parent a0e6456 commit 709bc9a
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 1 deletion.
49 changes: 48 additions & 1 deletion containerd-shim-v2/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
ptypes "github.com/gogo/protobuf/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)

const (
Expand Down Expand Up @@ -235,7 +236,53 @@ func getTopic(ctx context.Context, e interface{}) string {
}

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
Expand Down
57 changes: 57 additions & 0 deletions containerd-shim-v2/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ import (
"context"
"fmt"
"os"
"path/filepath"
"syscall"
"time"

"github.com/containerd/containerd/mount"
cdshim "github.com/containerd/containerd/runtime/v2/shim"
"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"
"github.com/sirupsen/logrus"
)

func cReap(s *service, status int, id, execid string, exitat time.Time) {
Expand All @@ -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) {
// container ID MUST be provided.
if containerID == "" {
Expand Down

0 comments on commit 709bc9a

Please sign in to comment.