Move shim restore to a separate file
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
This commit is contained in:
parent
a3d298193c
commit
b554b577b0
151
runtime/v2/shim_load.go
Normal file
151
runtime/v2/shim_load.go
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/events/exchange"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
)
|
||||
|
||||
func loadExistingTasks(ic *plugin.InitContext, list *runtime.TaskList, events *exchange.Exchange, containers containers.Store) error {
|
||||
var (
|
||||
ctx = ic.Context
|
||||
state = ic.State
|
||||
root = ic.Root
|
||||
containerdAddress = ic.Address
|
||||
containerdTTRPCAddress = ic.TTRPCAddress
|
||||
)
|
||||
|
||||
nsDirs, err := os.ReadDir(state)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, nsd := range nsDirs {
|
||||
if !nsd.IsDir() {
|
||||
continue
|
||||
}
|
||||
ns := nsd.Name()
|
||||
// skip hidden directories
|
||||
if len(ns) > 0 && ns[0] == '.' {
|
||||
continue
|
||||
}
|
||||
log.G(ctx).WithField("namespace", ns).Debug("loading tasks in namespace")
|
||||
if err := loadShims(namespaces.WithNamespace(ctx, ns), state, list, events, containers, containerdAddress, containerdTTRPCAddress); err != nil {
|
||||
log.G(ctx).WithField("namespace", ns).WithError(err).Error("loading tasks in namespace")
|
||||
continue
|
||||
}
|
||||
if err := cleanupWorkDirs(namespaces.WithNamespace(ctx, ns), root, list); err != nil {
|
||||
log.G(ctx).WithField("namespace", ns).WithError(err).Error("cleanup working directory in namespace")
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadShims(ctx context.Context, state string, list *runtime.TaskList, events *exchange.Exchange, containers containers.Store, containerdAddress string, containerdTTRPCAddress string) error {
|
||||
ns, err := namespaces.NamespaceRequired(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
shimDirs, err := os.ReadDir(filepath.Join(state, ns))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, sd := range shimDirs {
|
||||
if !sd.IsDir() {
|
||||
continue
|
||||
}
|
||||
id := sd.Name()
|
||||
// skip hidden directories
|
||||
if len(id) > 0 && id[0] == '.' {
|
||||
continue
|
||||
}
|
||||
bundle, err := LoadBundle(ctx, state, id)
|
||||
if err != nil {
|
||||
// fine to return error here, it is a programmer error if the context
|
||||
// does not have a namespace
|
||||
return err
|
||||
}
|
||||
// fast path
|
||||
bf, err := os.ReadDir(bundle.Path)
|
||||
if err != nil {
|
||||
bundle.Delete()
|
||||
log.G(ctx).WithError(err).Errorf("fast path read bundle path for %s", bundle.Path)
|
||||
continue
|
||||
}
|
||||
if len(bf) == 0 {
|
||||
bundle.Delete()
|
||||
continue
|
||||
}
|
||||
container, err := containers.Get(ctx, id)
|
||||
if err != nil {
|
||||
log.G(ctx).WithError(err).Errorf("loading container %s", id)
|
||||
if err := mount.UnmountAll(filepath.Join(bundle.Path, "rootfs"), 0); err != nil {
|
||||
log.G(ctx).WithError(err).Errorf("forceful unmount of rootfs %s", id)
|
||||
}
|
||||
bundle.Delete()
|
||||
continue
|
||||
}
|
||||
binaryCall := shimBinary(bundle, container.Runtime.Name, containerdAddress, containerdTTRPCAddress)
|
||||
shim, err := loadShim(ctx, bundle, func() {
|
||||
log.G(ctx).WithField("id", id).Info("shim disconnected")
|
||||
|
||||
cleanupAfterDeadShim(context.Background(), id, ns, list, events, binaryCall)
|
||||
// Remove self from the runtime task list.
|
||||
list.Delete(ctx, id)
|
||||
})
|
||||
if err != nil {
|
||||
cleanupAfterDeadShim(ctx, id, ns, list, events, binaryCall)
|
||||
continue
|
||||
}
|
||||
list.Add(ctx, shim)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func cleanupWorkDirs(ctx context.Context, root string, list *runtime.TaskList) error {
|
||||
ns, err := namespaces.NamespaceRequired(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dirs, err := os.ReadDir(filepath.Join(root, ns))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, d := range dirs {
|
||||
// if the task was not loaded, cleanup and empty working directory
|
||||
// this can happen on a reboot where /run for the bundle state is cleaned up
|
||||
// but that persistent working dir is left
|
||||
if _, err := list.Get(ctx, d.Name()); err != nil {
|
||||
path := filepath.Join(root, ns, d.Name())
|
||||
if err := os.RemoveAll(path); err != nil {
|
||||
log.G(ctx).WithError(err).Errorf("cleanup working dir %s", path)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user