Move config version to version package

Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
Derek McGowan 2024-02-14 16:36:35 -08:00
parent 81965c0a57
commit a086125ae3
No known key found for this signature in database
GPG Key ID: F58C5D0A4405ACDB
10 changed files with 40 additions and 31 deletions

View File

@ -26,6 +26,7 @@ import (
"github.com/containerd/containerd/v2/core/images" "github.com/containerd/containerd/v2/core/images"
"github.com/containerd/containerd/v2/defaults" "github.com/containerd/containerd/v2/defaults"
"github.com/containerd/containerd/v2/pkg/timeout" "github.com/containerd/containerd/v2/pkg/timeout"
"github.com/containerd/containerd/v2/version"
"github.com/containerd/plugin/registry" "github.com/containerd/plugin/registry"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pelletier/go-toml/v2" "github.com/pelletier/go-toml/v2"
@ -69,7 +70,7 @@ func outputConfig(ctx gocontext.Context, config *srvconfig.Config) error {
// when a config without a version is loaded from disk and has no version // when a config without a version is loaded from disk and has no version
// set, we assume it's a v1 config. But when generating new configs via // set, we assume it's a v1 config. But when generating new configs via
// this command, generate the max configuration version // this command, generate the max configuration version
config.Version = srvconfig.CurrentConfigVersion config.Version = version.ConfigVersion
return toml.NewEncoder(os.Stdout).SetIndentTables(true).Encode(config) return toml.NewEncoder(os.Stdout).SetIndentTables(true).Encode(config)
} }
@ -112,7 +113,7 @@ var configCommand = cli.Command{
return err return err
} }
if config.Version < srvconfig.CurrentConfigVersion { if config.Version < version.ConfigVersion {
plugins := registry.Graph(srvconfig.V2DisabledFilter(config.DisabledPlugins)) plugins := registry.Graph(srvconfig.V2DisabledFilter(config.DisabledPlugins))
for _, p := range plugins { for _, p := range plugins {
if p.ConfigMigration != nil { if p.ConfigMigration != nil {
@ -145,7 +146,7 @@ var configCommand = cli.Command{
} }
} }
config.Version = srvconfig.CurrentConfigVersion config.Version = version.ConfigVersion
return toml.NewEncoder(os.Stdout).SetIndentTables(true).Encode(config) return toml.NewEncoder(os.Stdout).SetIndentTables(true).Encode(config)
}, },
@ -155,7 +156,7 @@ var configCommand = cli.Command{
func platformAgnosticDefaultConfig() *srvconfig.Config { func platformAgnosticDefaultConfig() *srvconfig.Config {
return &srvconfig.Config{ return &srvconfig.Config{
Version: srvconfig.CurrentConfigVersion, Version: version.ConfigVersion,
Root: defaults.DefaultRootDir, Root: defaults.DefaultRootDir,
State: defaults.DefaultStateDir, State: defaults.DefaultStateDir,
GRPC: srvconfig.GRPCConfig{ GRPC: srvconfig.GRPCConfig{

View File

@ -36,14 +36,12 @@ import (
"dario.cat/mergo" "dario.cat/mergo"
"github.com/pelletier/go-toml/v2" "github.com/pelletier/go-toml/v2"
"github.com/containerd/containerd/v2/version"
"github.com/containerd/errdefs" "github.com/containerd/errdefs"
"github.com/containerd/log" "github.com/containerd/log"
"github.com/containerd/plugin" "github.com/containerd/plugin"
) )
// CurrentConfigVersion is the max config version which is supported
const CurrentConfigVersion = 3
// migrations hold the migration functions for every prior containerd config version // migrations hold the migration functions for every prior containerd config version
var migrations = []func(context.Context, *Config) error{ var migrations = []func(context.Context, *Config) error{
nil, // Version 0 is not defined, treated at version 1 nil, // Version 0 is not defined, treated at version 1
@ -115,8 +113,8 @@ type StreamProcessor struct {
// ValidateVersion validates the config for a v2 file // ValidateVersion validates the config for a v2 file
func (c *Config) ValidateVersion() error { func (c *Config) ValidateVersion() error {
if c.Version > CurrentConfigVersion { if c.Version > version.ConfigVersion {
return fmt.Errorf("expected containerd config version equal to or less than `%d`, got `%d`", CurrentConfigVersion, c.Version) return fmt.Errorf("expected containerd config version equal to or less than `%d`, got `%d`", version.ConfigVersion, c.Version)
} }
for _, p := range c.DisabledPlugins { for _, p := range c.DisabledPlugins {
@ -135,7 +133,7 @@ func (c *Config) ValidateVersion() error {
// MigrateConfig will convert the config to the latest version before using // MigrateConfig will convert the config to the latest version before using
func (c *Config) MigrateConfig(ctx context.Context) error { func (c *Config) MigrateConfig(ctx context.Context) error {
for c.Version < CurrentConfigVersion { for c.Version < version.ConfigVersion {
if m := migrations[c.Version]; m != nil { if m := migrations[c.Version]; m != nil {
if err := m(ctx, c); err != nil { if err := m(ctx, c); err != nil {
return err return err

View File

@ -25,12 +25,13 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/containerd/containerd/v2/version"
"github.com/containerd/log/logtest" "github.com/containerd/log/logtest"
) )
func TestMigrations(t *testing.T) { func TestMigrations(t *testing.T) {
if len(migrations) != CurrentConfigVersion { if len(migrations) != version.ConfigVersion {
t.Fatalf("Migration missing, expected %d migrations, only %d defined", CurrentConfigVersion, len(migrations)) t.Fatalf("Migration missing, expected %d migrations, only %d defined", version.ConfigVersion, len(migrations))
} }
} }

View File

@ -64,6 +64,7 @@ import (
"github.com/containerd/containerd/v2/plugins" "github.com/containerd/containerd/v2/plugins"
"github.com/containerd/containerd/v2/plugins/content/local" "github.com/containerd/containerd/v2/plugins/content/local"
"github.com/containerd/containerd/v2/plugins/services/warning" "github.com/containerd/containerd/v2/plugins/services/warning"
"github.com/containerd/containerd/v2/version"
"github.com/containerd/platforms" "github.com/containerd/platforms"
"github.com/containerd/plugin" "github.com/containerd/plugin"
"github.com/containerd/plugin/dynamic" "github.com/containerd/plugin/dynamic"
@ -112,10 +113,10 @@ func CreateTopLevelDirectories(config *srvconfig.Config) error {
// New creates and initializes a new containerd server // New creates and initializes a new containerd server
func New(ctx context.Context, config *srvconfig.Config) (*Server, error) { func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
var ( var (
version = config.Version currentVersion = config.Version
migrationT time.Duration migrationT time.Duration
) )
if version < srvconfig.CurrentConfigVersion { if currentVersion < version.ConfigVersion {
// Migrate config to latest version // Migrate config to latest version
t1 := time.Now() t1 := time.Now()
err := config.MigrateConfig(ctx) err := config.MigrateConfig(ctx)
@ -224,12 +225,12 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
required[r] = struct{}{} required[r] = struct{}{}
} }
if version < srvconfig.CurrentConfigVersion { if currentVersion < version.ConfigVersion {
t1 := time.Now() t1 := time.Now()
// Run migration for each configuration version // Run migration for each configuration version
// Run each plugin migration for each version to ensure that migration logic is simple and // Run each plugin migration for each version to ensure that migration logic is simple and
// focused on upgrading from one version at a time. // focused on upgrading from one version at a time.
for v := version; v < srvconfig.CurrentConfigVersion; v++ { for v := currentVersion; v < version.ConfigVersion; v++ {
for _, p := range loaded { for _, p := range loaded {
if p.ConfigMigration != nil { if p.ConfigMigration != nil {
if err := p.ConfigMigration(ctx, v, config.Plugins); err != nil { if err := p.ConfigMigration(ctx, v, config.Plugins); err != nil {
@ -241,7 +242,7 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
migrationT = migrationT + time.Since(t1) migrationT = migrationT + time.Since(t1)
} }
if migrationT > 0 { if migrationT > 0 {
log.G(ctx).WithField("t", migrationT).Warnf("Configuration migrated from version %d, use `containerd config migrate` to avoid migration", version) log.G(ctx).WithField("t", migrationT).Warnf("Configuration migrated from version %d, use `containerd config migrate` to avoid migration", currentVersion)
} }
for _, p := range loaded { for _, p := range loaded {

View File

@ -21,6 +21,7 @@ import (
"testing" "testing"
srvconfig "github.com/containerd/containerd/v2/cmd/containerd/server/config" srvconfig "github.com/containerd/containerd/v2/cmd/containerd/server/config"
"github.com/containerd/containerd/v2/version"
"github.com/containerd/plugin" "github.com/containerd/plugin"
"github.com/containerd/plugin/registry" "github.com/containerd/plugin/registry"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -61,7 +62,7 @@ func TestMigration(t *testing.T) {
registry.Reset() registry.Reset()
defer registry.Reset() defer registry.Reset()
version := srvconfig.CurrentConfigVersion - 1 configVersion := version.ConfigVersion - 1
type testConfig struct { type testConfig struct {
Migrated string `toml:"migrated"` Migrated string `toml:"migrated"`
@ -109,7 +110,7 @@ func TestMigration(t *testing.T) {
return nil, nil return nil, nil
}, },
ConfigMigration: func(ctx context.Context, v int, plugins map[string]interface{}) error { ConfigMigration: func(ctx context.Context, v int, plugins map[string]interface{}) error {
if v != version { if v != configVersion {
t.Errorf("unxpected version: %d", v) t.Errorf("unxpected version: %d", v)
} }
t1, ok := plugins["io.containerd.test.t1"] t1, ok := plugins["io.containerd.test.t1"]
@ -133,7 +134,7 @@ func TestMigration(t *testing.T) {
}) })
config := &srvconfig.Config{} config := &srvconfig.Config{}
config.Version = version config.Version = configVersion
config.Plugins = map[string]interface{}{ config.Plugins = map[string]interface{}{
"io.containerd.test.t1": map[string]interface{}{ "io.containerd.test.t1": map[string]interface{}{
"migrated": "migrate me", "migrated": "migrate me",

View File

@ -27,6 +27,7 @@ import (
"github.com/containerd/containerd/v2/cmd/containerd/server/config" "github.com/containerd/containerd/v2/cmd/containerd/server/config"
"github.com/containerd/containerd/v2/defaults" "github.com/containerd/containerd/v2/defaults"
"github.com/containerd/containerd/v2/pkg/sys" "github.com/containerd/containerd/v2/pkg/sys"
"github.com/containerd/containerd/v2/version"
"github.com/containerd/log" "github.com/containerd/log"
) )
@ -51,7 +52,7 @@ func startDaemon() {
defer close(errC) defer close(errC)
srvconfig := &config.Config{ srvconfig := &config.Config{
Version: config.CurrentConfigVersion, Version: version.ConfigVersion,
Root: defaultRoot, Root: defaultRoot,
State: defaultState, State: defaultState,
Debug: config.Debug{ Debug: config.Debug{

View File

@ -26,7 +26,6 @@ import (
"github.com/containerd/plugin/registry" "github.com/containerd/plugin/registry"
containerd "github.com/containerd/containerd/v2/client" containerd "github.com/containerd/containerd/v2/client"
srvconfig "github.com/containerd/containerd/v2/cmd/containerd/server/config"
"github.com/containerd/containerd/v2/core/sandbox" "github.com/containerd/containerd/v2/core/sandbox"
criconfig "github.com/containerd/containerd/v2/internal/cri/config" criconfig "github.com/containerd/containerd/v2/internal/cri/config"
"github.com/containerd/containerd/v2/internal/cri/constants" "github.com/containerd/containerd/v2/internal/cri/constants"
@ -36,6 +35,7 @@ import (
nriservice "github.com/containerd/containerd/v2/pkg/nri" nriservice "github.com/containerd/containerd/v2/pkg/nri"
"github.com/containerd/containerd/v2/plugins" "github.com/containerd/containerd/v2/plugins"
"github.com/containerd/containerd/v2/plugins/services/warning" "github.com/containerd/containerd/v2/plugins/services/warning"
"github.com/containerd/containerd/v2/version"
"github.com/containerd/platforms" "github.com/containerd/platforms"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -61,8 +61,8 @@ func init() {
plugins.WarningPlugin, plugins.WarningPlugin,
}, },
Config: &defaultConfig, Config: &defaultConfig,
ConfigMigration: func(ctx context.Context, version int, pluginConfigs map[string]interface{}) error { ConfigMigration: func(ctx context.Context, configVersion int, pluginConfigs map[string]interface{}) error {
if version >= srvconfig.CurrentConfigVersion { if configVersion >= version.ConfigVersion {
return nil return nil
} }
const pluginName = string(plugins.GRPCPlugin) + ".cri" const pluginName = string(plugins.GRPCPlugin) + ".cri"

View File

@ -22,7 +22,6 @@ import (
"path/filepath" "path/filepath"
containerd "github.com/containerd/containerd/v2/client" containerd "github.com/containerd/containerd/v2/client"
srvconfig "github.com/containerd/containerd/v2/cmd/containerd/server/config"
"github.com/containerd/containerd/v2/core/metadata" "github.com/containerd/containerd/v2/core/metadata"
"github.com/containerd/containerd/v2/core/snapshots" "github.com/containerd/containerd/v2/core/snapshots"
criconfig "github.com/containerd/containerd/v2/internal/cri/config" criconfig "github.com/containerd/containerd/v2/internal/cri/config"
@ -30,6 +29,7 @@ import (
"github.com/containerd/containerd/v2/internal/cri/server/images" "github.com/containerd/containerd/v2/internal/cri/server/images"
"github.com/containerd/containerd/v2/plugins" "github.com/containerd/containerd/v2/plugins"
"github.com/containerd/containerd/v2/plugins/services/warning" "github.com/containerd/containerd/v2/plugins/services/warning"
"github.com/containerd/containerd/v2/version"
"github.com/containerd/log" "github.com/containerd/log"
"github.com/containerd/platforms" "github.com/containerd/platforms"
"github.com/containerd/plugin" "github.com/containerd/plugin"
@ -154,8 +154,8 @@ func init() {
}) })
} }
func configMigration(ctx context.Context, version int, pluginConfigs map[string]interface{}) error { func configMigration(ctx context.Context, configVersion int, pluginConfigs map[string]interface{}) error {
if version >= srvconfig.CurrentConfigVersion { if configVersion >= version.ConfigVersion {
return nil return nil
} }
original, ok := pluginConfigs[string(plugins.GRPCPlugin)+".cri"] original, ok := pluginConfigs[string(plugins.GRPCPlugin)+".cri"]

View File

@ -30,12 +30,12 @@ import (
imagespec "github.com/opencontainers/image-spec/specs-go/v1" imagespec "github.com/opencontainers/image-spec/specs-go/v1"
"k8s.io/klog/v2" "k8s.io/klog/v2"
srvconfig "github.com/containerd/containerd/v2/cmd/containerd/server/config"
criconfig "github.com/containerd/containerd/v2/internal/cri/config" criconfig "github.com/containerd/containerd/v2/internal/cri/config"
"github.com/containerd/containerd/v2/internal/cri/constants" "github.com/containerd/containerd/v2/internal/cri/constants"
"github.com/containerd/containerd/v2/pkg/oci" "github.com/containerd/containerd/v2/pkg/oci"
"github.com/containerd/containerd/v2/plugins" "github.com/containerd/containerd/v2/plugins"
"github.com/containerd/containerd/v2/plugins/services/warning" "github.com/containerd/containerd/v2/plugins/services/warning"
"github.com/containerd/containerd/v2/version"
"github.com/containerd/errdefs" "github.com/containerd/errdefs"
"github.com/containerd/platforms" "github.com/containerd/platforms"
) )
@ -51,8 +51,8 @@ func init() {
Requires: []plugin.Type{ Requires: []plugin.Type{
plugins.WarningPlugin, plugins.WarningPlugin,
}, },
ConfigMigration: func(ctx context.Context, version int, pluginConfigs map[string]interface{}) error { ConfigMigration: func(ctx context.Context, configVersion int, pluginConfigs map[string]interface{}) error {
if version >= srvconfig.CurrentConfigVersion { if configVersion >= version.ConfigVersion {
return nil return nil
} }
c, ok := pluginConfigs[string(plugins.GRPCPlugin)+".cri"] c, ok := pluginConfigs[string(plugins.GRPCPlugin)+".cri"]

View File

@ -32,3 +32,9 @@ var (
// GoVersion is Go tree's version. // GoVersion is Go tree's version.
GoVersion = runtime.Version() GoVersion = runtime.Version()
) )
// ConfigVersion is the current highest supported configuration version.
// This version is used by the main configuration as well as all plugins.
// Any configuration less than this version which has structural changes
// should migrate the configuration structures used by this version.
const ConfigVersion = 3