runtimeclass-debugger/pkg/cri/containerd.go

70 lines
2 KiB
Go

// Package cri inspects the container runtime configuration on the node.
package cri
import (
"errors"
"fmt"
"os"
"sort"
"github.com/pelletier/go-toml/v2"
)
// ErrConfigNotFound is returned when the containerd config file does not
// exist.
var ErrConfigNotFound = errors.New("containerd config not found")
// Containerd holds the CRI runtime handlers configured in containerd.
type Containerd struct {
path string
handlers map[string]struct{}
}
// Load parses the containerd config at the given path and collects the CRI
// runtime handler names from
// [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.<name>] (and the
// legacy [plugins.cri.containerd.runtimes.<name>] spelling).
func Load(path string) (*Containerd, error) {
data, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("%w: %s", ErrConfigNotFound, path)
}
return nil, err
}
var tree map[string]interface{}
if err := toml.Unmarshal(data, &tree); err != nil {
return nil, fmt.Errorf("parse %s: %w", path, err)
}
c := &Containerd{path: path, handlers: map[string]struct{}{}}
c.collectHandlers(tree)
return c, nil
}
func (c *Containerd) collectHandlers(tree map[string]interface{}) {
plugins, _ := tree["plugins"].(map[string]interface{})
for _, criName := range []string{"io.containerd.grpc.v1.cri", "cri"} {
criSection, _ := plugins[criName].(map[string]interface{})
containerdSection, _ := criSection["containerd"].(map[string]interface{})
runtimes, _ := containerdSection["runtimes"].(map[string]interface{})
for handler := range runtimes {
c.handlers[handler] = struct{}{}
}
}
}
// HandlerNames returns the configured runtime handler names, sorted.
func (c *Containerd) HandlerNames() []string {
names := make([]string, 0, len(c.handlers))
for h := range c.handlers {
names = append(names, h)
}
sort.Strings(names)
return names
}
// HasHandler reports whether the named runtime handler is configured.
func (c *Containerd) HasHandler(name string) bool {
_, ok := c.handlers[name]
return ok
}