Files
kata-containers/containerd-shim-v2/utils.go
fupan 709bc9aa12 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>
2018-11-28 14:32:25 +08:00

170 lines
3.9 KiB
Go

// Copyright (c) 2017 Intel Corporation
// Copyright (c) 2018 HyperHQ Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
package containerdshim
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) {
s.ec <- exit{
timestamp: exitat,
pid: s.pid,
status: status,
id: id,
execid: execid,
}
}
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 == "" {
return "", fmt.Errorf("Missing container ID")
}
// bundle path MUST be provided.
if bundlePath == "" {
return "", fmt.Errorf("Missing bundle path")
}
// bundle path MUST be valid.
fileInfo, err := os.Stat(bundlePath)
if err != nil {
return "", fmt.Errorf("Invalid bundle path '%s': %s", bundlePath, err)
}
if fileInfo.IsDir() == false {
return "", fmt.Errorf("Invalid bundle path '%s', it should be a directory", bundlePath)
}
resolved, err := katautils.ResolvePath(bundlePath)
if err != nil {
return "", err
}
return resolved, nil
}
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 = validBundle(id, bundlePath); err != nil {
return "", err
}
ociSpec, err := oci.ParseConfigJSON(bundlePath)
if err != nil {
return "", err
}
containerType, err := ociSpec.ContainerType()
if err != nil {
return "", err
}
if containerType == vc.PodContainer {
sandboxID, err := ociSpec.SandboxID()
if err != nil {
return "", err
}
address, err := cdshim.SocketAddress(ctx, sandboxID)
if err != nil {
return "", err
}
return address, nil
}
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
}
}
}