Files
Olares/daemon/pkg/containerd/config.go

106 lines
3.4 KiB
Go

package containerd
import (
"errors"
"fmt"
"os"
"github.com/beclab/Olares/daemon/pkg/utils"
criconfig "github.com/containerd/containerd/pkg/cri/config"
"github.com/containerd/containerd/plugin"
serverconfig "github.com/containerd/containerd/services/server/config"
"github.com/pelletier/go-toml"
"k8s.io/klog/v2"
)
const (
DefaultContainerdConfigPath = "/etc/containerd/config.toml"
DefaultContainerdRootPath = "/var/lib/containerd"
)
func getConfig() (*serverconfig.Config, error) {
config := &serverconfig.Config{}
err := serverconfig.LoadConfig(DefaultContainerdConfigPath, config)
if err != nil {
return nil, err
}
if config.Plugins == nil {
config.Plugins = make(map[string]toml.Tree)
}
return config, nil
}
// newDefaultCRIPlugin returns an instance of CRI plugin with the default configuration.
// It's not actually used, and just for convenient plugin identification like plugin.URI and config decode
func newDefaultCRIPlugin() *plugin.Registration {
criDefaultPluginConfig := criconfig.DefaultConfig()
return &plugin.Registration{
Type: plugin.GRPCPlugin,
ID: "cri",
Config: &criDefaultPluginConfig,
}
}
func getCRIPluginConfig(config *serverconfig.Config) (*criconfig.PluginConfig, error) {
if config == nil {
return nil, errors.New("nil containerd config")
}
criPlugin := newDefaultCRIPlugin()
criPluginConfigInterface, err := config.Decode(criPlugin)
if err != nil {
return nil, fmt.Errorf("failed to load cri plugin config from containerd config: %v", err)
}
criPluginConfig, ok := criPluginConfigInterface.(*criconfig.PluginConfig)
if !ok {
return nil, errors.New("failed to decode cri plugin config: type mismatch")
}
if criPluginConfig.Registry.Mirrors == nil {
criPluginConfig.Registry.Mirrors = make(map[string]criconfig.Mirror)
}
return criPluginConfig, nil
}
func updateCRIPluginConfig(config *serverconfig.Config, criPluginConfig *criconfig.PluginConfig) error {
backupPath := DefaultContainerdConfigPath + ".bak"
if err := utils.CopyFile(DefaultContainerdConfigPath, backupPath); err != nil {
klog.Errorf("failed to backup containerd config: %v", err)
return err
}
defer os.Remove(backupPath)
if criPluginConfig.Registry.ConfigPath != "" {
// reset config path as it will mask the other options
// we do not set mirrors in the config path
// because image-service expects an explicit inline config in the Mirrors field
// as of now
criPluginConfig.Registry.ConfigPath = ""
}
criPlugin := newDefaultCRIPlugin()
criPluginConfigBytes, err := toml.Marshal(criPluginConfig)
if err != nil {
return fmt.Errorf("failed to marshal cri plugin config: %v", err)
}
criPluginConfigTree, err := toml.LoadBytes(criPluginConfigBytes)
if err != nil {
return fmt.Errorf("failed to load cri plugin config to toml tree: %v", err)
}
config.Plugins[criPlugin.URI()] = *criPluginConfigTree
configFile, err := os.OpenFile(DefaultContainerdConfigPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return fmt.Errorf("failed to open containerd config file for writing: %v", err)
}
defer configFile.Close()
if err := toml.NewEncoder(configFile).Encode(config); err != nil {
rollbackErr := utils.CopyFile(backupPath, DefaultContainerdConfigPath)
if rollbackErr != nil {
klog.Errorf("failed to rollback containerd config: %v", rollbackErr)
}
return fmt.Errorf("failed to encode new containerd config: %v", err)
}
return nil
}