mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-26 18:44:47 +01:00
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>
170 lines
3.9 KiB
Go
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
|
|
}
|
|
}
|
|
}
|