106 lines
3.4 KiB
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
|
|
}
|