diff --git a/cmd/containerd/builtins/cri.go b/cmd/containerd/builtins/cri.go index 3673889d3..5c88cb9e4 100644 --- a/cmd/containerd/builtins/cri.go +++ b/cmd/containerd/builtins/cri.go @@ -21,4 +21,5 @@ package builtins import ( _ "github.com/containerd/containerd/v2/pkg/cri" _ "github.com/containerd/containerd/v2/plugins/cri/images" + _ "github.com/containerd/containerd/v2/plugins/cri/runtime" ) diff --git a/contrib/fuzz/builtins.go b/contrib/fuzz/builtins.go index 2b7c7fe12..6c4888748 100644 --- a/contrib/fuzz/builtins.go +++ b/contrib/fuzz/builtins.go @@ -23,6 +23,7 @@ import ( _ "github.com/containerd/containerd/v2/pkg/events/plugin" _ "github.com/containerd/containerd/v2/pkg/nri/plugin" _ "github.com/containerd/containerd/v2/plugins/cri/images" + _ "github.com/containerd/containerd/v2/plugins/cri/runtime" _ "github.com/containerd/containerd/v2/plugins/diff/walking/plugin" _ "github.com/containerd/containerd/v2/plugins/gc" _ "github.com/containerd/containerd/v2/plugins/imageverifier" diff --git a/contrib/fuzz/cri_server_fuzzer.go b/contrib/fuzz/cri_server_fuzzer.go index adb9a388b..08cf4a645 100644 --- a/contrib/fuzz/cri_server_fuzzer.go +++ b/contrib/fuzz/cri_server_fuzzer.go @@ -29,6 +29,7 @@ import ( "github.com/containerd/containerd/v2/pkg/cri/server" "github.com/containerd/containerd/v2/pkg/cri/server/images" "github.com/containerd/containerd/v2/pkg/oci" + "github.com/containerd/errdefs" ) func FuzzCRIServer(data []byte) int { @@ -42,7 +43,6 @@ func FuzzCRIServer(data []byte) int { } defer client.Close() - config := criconfig.Config{} imageConfig := criconfig.ImageConfig{} imageService, err := images.NewService(imageConfig, &images.CRIImageServiceOptions{ @@ -52,10 +52,10 @@ func FuzzCRIServer(data []byte) int { panic(err) } - c, rs, err := server.NewCRIService(config, &server.CRIServiceOptions{ - ImageService: imageService, - Client: client, - BaseOCISpecs: map[string]*oci.Spec{}, + c, rs, err := server.NewCRIService(&server.CRIServiceOptions{ + RuntimeService: &fakeRuntimeService{}, + ImageService: imageService, + Client: client, }) if err != nil { panic(err) @@ -68,6 +68,16 @@ func FuzzCRIServer(data []byte) int { }) } +type fakeRuntimeService struct{} + +func (fakeRuntimeService) Config() criconfig.Config { + return criconfig.Config{} +} + +func (fakeRuntimeService) LoadOCISpec(string) (*oci.Spec, error) { + return nil, errdefs.ErrNotFound +} + type service struct { server.CRIService runtime.RuntimeServiceServer diff --git a/integration/build_local_containerd_helper_test.go b/integration/build_local_containerd_helper_test.go index f9577485e..0a4471df6 100644 --- a/integration/build_local_containerd_helper_test.go +++ b/integration/build_local_containerd_helper_test.go @@ -38,6 +38,7 @@ import ( _ "github.com/containerd/containerd/v2/core/runtime/v2/runc/options" _ "github.com/containerd/containerd/v2/pkg/events/plugin" _ "github.com/containerd/containerd/v2/plugins/cri/images" + _ "github.com/containerd/containerd/v2/plugins/cri/runtime" _ "github.com/containerd/containerd/v2/plugins/diff/walking/plugin" _ "github.com/containerd/containerd/v2/plugins/gc" _ "github.com/containerd/containerd/v2/plugins/leases" diff --git a/pkg/cri/config/config.go b/pkg/cri/config/config.go index 1ae4f1341..15617b1f0 100644 --- a/pkg/cri/config/config.go +++ b/pkg/cri/config/config.go @@ -319,8 +319,6 @@ type PluginConfig struct { ContainerdConfig `toml:"containerd" json:"containerd"` // CniConfig contains config related to cni CniConfig `toml:"cni" json:"cni"` - // DisableTCPService disables serving CRI on the TCP server. - DisableTCPService bool `toml:"disable_tcp_service" json:"disableTCPService"` // StreamServerAddress is the ip address streaming server is listening on. StreamServerAddress string `toml:"stream_server_address" json:"streamServerAddress"` // StreamServerPort is the port streaming server is listening on. @@ -433,6 +431,12 @@ type Config struct { StateDir string `json:"stateDir"` } +// ServiceConfig contains all the configuration for the CRI API server. +type ServiceConfig struct { + // DisableTCPService disables serving CRI on the TCP server. + DisableTCPService bool `toml:"disable_tcp_service" json:"disableTCPService"` +} + const ( // RuntimeUntrusted is the implicit runtime defined for ContainerdConfig.UntrustedWorkloadRuntime RuntimeUntrusted = "untrusted" diff --git a/pkg/cri/config/config_unix.go b/pkg/cri/config/config_unix.go index 7a0405566..c04651ecc 100644 --- a/pkg/cri/config/config_unix.go +++ b/pkg/cri/config/config_unix.go @@ -89,7 +89,6 @@ func DefaultConfig() PluginConfig { }, }, }, - DisableTCPService: true, StreamServerAddress: "127.0.0.1", StreamServerPort: "0", StreamIdleTimeout: streaming.DefaultConfig.StreamIdleTimeout.String(), // 4 hour diff --git a/pkg/cri/config/config_windows.go b/pkg/cri/config/config_windows.go index 9c2eeac15..db499a074 100644 --- a/pkg/cri/config/config_windows.go +++ b/pkg/cri/config/config_windows.go @@ -78,7 +78,6 @@ func DefaultConfig() PluginConfig { }, }, }, - DisableTCPService: true, StreamServerAddress: "127.0.0.1", StreamServerPort: "0", StreamIdleTimeout: streaming.DefaultConfig.StreamIdleTimeout.String(), // 4 hour diff --git a/pkg/cri/cri.go b/pkg/cri/cri.go index 3488b9915..a9071e40a 100644 --- a/pkg/cri/cri.go +++ b/pkg/cri/cri.go @@ -17,6 +17,7 @@ package cri import ( + "context" "fmt" "io" @@ -25,13 +26,13 @@ import ( "github.com/containerd/plugin/registry" containerd "github.com/containerd/containerd/v2/client" + srvconfig "github.com/containerd/containerd/v2/cmd/containerd/server/config" "github.com/containerd/containerd/v2/core/sandbox" criconfig "github.com/containerd/containerd/v2/pkg/cri/config" "github.com/containerd/containerd/v2/pkg/cri/constants" "github.com/containerd/containerd/v2/pkg/cri/instrument" "github.com/containerd/containerd/v2/pkg/cri/nri" "github.com/containerd/containerd/v2/pkg/cri/server" - "github.com/containerd/containerd/v2/pkg/cri/server/base" nriservice "github.com/containerd/containerd/v2/pkg/nri" "github.com/containerd/containerd/v2/plugins" "github.com/containerd/platforms" @@ -43,13 +44,11 @@ import ( // Register CRI service plugin func init() { - registry.Register(&plugin.Registration{ Type: plugins.GRPCPlugin, ID: "cri", Requires: []plugin.Type{ - plugins.CRIImagePlugin, - plugins.InternalPlugin, + plugins.CRIServicePlugin, plugins.SandboxControllerPlugin, plugins.NRIApiPlugin, plugins.EventPlugin, @@ -58,23 +57,46 @@ func init() { plugins.SandboxStorePlugin, plugins.TransferPlugin, }, + Config: &criconfig.ServiceConfig{ + DisableTCPService: true, + }, + ConfigMigration: func(ctx context.Context, version int, pluginConfigs map[string]interface{}) error { + if version >= srvconfig.CurrentConfigVersion { + return nil + } + const pluginName = string(plugins.GRPCPlugin) + ".cri" + original, ok := pluginConfigs[pluginName] + if !ok { + return nil + } + src := original.(map[string]interface{}) + + // Currently only a single key migrated + if val, ok := src["disable_tcp_service"]; ok { + pluginConfigs[pluginName] = map[string]interface{}{ + "disable_tcp_service": val, + } + } else { + delete(pluginConfigs, pluginName) + } + return nil + }, InitFn: initCRIService, }) } func initCRIService(ic *plugin.InitContext) (interface{}, error) { ctx := ic.Context + config := ic.Config.(*criconfig.ServiceConfig) - // Get base CRI dependencies. - criBasePlugin, err := ic.GetByID(plugins.InternalPlugin, "cri") + // Get runtime service. + criRuntimePlugin, err := ic.GetByID(plugins.CRIServicePlugin, "runtime") if err != nil { - return nil, fmt.Errorf("unable to load CRI service base dependencies: %w", err) + return nil, fmt.Errorf("unable to load CRI runtime service plugin dependency: %w", err) } - criBase := criBasePlugin.(*base.CRIBase) - c := criBase.Config // Get image service. - criImagePlugin, err := ic.GetSingle(plugins.CRIImagePlugin) + criImagePlugin, err := ic.GetByID(plugins.CRIServicePlugin, "images") if err != nil { return nil, fmt.Errorf("unable to load CRI image service plugin dependency: %w", err) } @@ -98,15 +120,16 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) { } options := &server.CRIServiceOptions{ + RuntimeService: criRuntimePlugin.(server.RuntimeService), ImageService: criImagePlugin.(server.ImageService), NRI: getNRIAPI(ic), Client: client, SandboxControllers: sbControllers, - BaseOCISpecs: criBase.BaseOCISpecs, } is := criImagePlugin.(imageService).GRPCService() - s, rs, err := server.NewCRIService(criBase.Config, options) + // TODO: More options specifically for grpc service? + s, rs, err := server.NewCRIService(options) if err != nil { return nil, fmt.Errorf("failed to create CRI service: %w", err) } @@ -127,7 +150,7 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) { initializer: s, } - if c.DisableTCPService { + if config.DisableTCPService { return service, nil } diff --git a/pkg/cri/server/container_create.go b/pkg/cri/server/container_create.go index 272096aaf..b922bc976 100644 --- a/pkg/cri/server/container_create.go +++ b/pkg/cri/server/container_create.go @@ -394,9 +394,9 @@ func (c *criService) runtimeSpec(id string, platform platforms.Platform, baseSpe container := &containers.Container{ID: id} if baseSpecFile != "" { - baseSpec, ok := c.baseOCISpecs[baseSpecFile] - if !ok { - return nil, fmt.Errorf("can't find base OCI spec %q", baseSpecFile) + baseSpec, err := c.LoadOCISpec(baseSpecFile) + if err != nil { + return nil, fmt.Errorf("can't load base OCI spec %q: %w", baseSpecFile, err) } spec := oci.Spec{} diff --git a/pkg/cri/server/container_create_linux_test.go b/pkg/cri/server/container_create_linux_test.go index f106d327c..e46b00df1 100644 --- a/pkg/cri/server/container_create_linux_test.go +++ b/pkg/cri/server/container_create_linux_test.go @@ -1680,23 +1680,24 @@ func TestPrivilegedDevices(t *testing.T) { } func TestBaseOCISpec(t *testing.T) { - c := newTestCRIService() baseLimit := int64(100) - c.baseOCISpecs = map[string]*oci.Spec{ - "/etc/containerd/cri-base.json": { - Process: &runtimespec.Process{ - User: runtimespec.User{AdditionalGids: []uint32{9999}}, - Capabilities: &runtimespec.LinuxCapabilities{ - Permitted: []string{"CAP_SETUID"}, + c := newTestCRIService(withRuntimeService(&fakeRuntimeService{ + ocispecs: map[string]*oci.Spec{ + "/etc/containerd/cri-base.json": { + Process: &runtimespec.Process{ + User: runtimespec.User{AdditionalGids: []uint32{9999}}, + Capabilities: &runtimespec.LinuxCapabilities{ + Permitted: []string{"CAP_SETUID"}, + }, }, - }, - Linux: &runtimespec.Linux{ - Resources: &runtimespec.LinuxResources{ - Memory: &runtimespec.LinuxMemory{Limit: &baseLimit}, // Will be overwritten by `getCreateContainerTestData` + Linux: &runtimespec.Linux{ + Resources: &runtimespec.LinuxResources{ + Memory: &runtimespec.LinuxMemory{Limit: &baseLimit}, // Will be overwritten by `getCreateContainerTestData` + }, }, }, }, - } + })) ociRuntime := config.Runtime{} ociRuntime.BaseRuntimeSpec = "/etc/containerd/cri-base.json" diff --git a/pkg/cri/server/container_create_test.go b/pkg/cri/server/container_create_test.go index f0f93fcbb..fa5f6bbf7 100644 --- a/pkg/cri/server/container_create_test.go +++ b/pkg/cri/server/container_create_test.go @@ -524,13 +524,14 @@ func TestContainerAnnotationPassthroughContainerSpec(t *testing.T) { } func TestBaseRuntimeSpec(t *testing.T) { - c := newTestCRIService() - c.baseOCISpecs = map[string]*oci.Spec{ - "/etc/containerd/cri-base.json": { - Version: "1.0.2", - Hostname: "old", + c := newTestCRIService(withRuntimeService(&fakeRuntimeService{ + ocispecs: map[string]*oci.Spec{ + "/etc/containerd/cri-base.json": { + Version: "1.0.2", + Hostname: "old", + }, }, - } + })) out, err := c.runtimeSpec( "id1", @@ -546,8 +547,10 @@ func TestBaseRuntimeSpec(t *testing.T) { assert.Equal(t, "new-domain", out.Domainname) // Make sure original base spec not changed - assert.NotEqual(t, out, c.baseOCISpecs["/etc/containerd/cri-base.json"]) - assert.Equal(t, c.baseOCISpecs["/etc/containerd/cri-base.json"].Hostname, "old") + spec, err := c.LoadOCISpec("/etc/containerd/cri-base.json") + assert.NoError(t, err) + assert.NotEqual(t, out, spec) + assert.Equal(t, spec.Hostname, "old") assert.Equal(t, filepath.Join("/", constants.K8sContainerdNamespace, "id1"), out.Linux.CgroupsPath) } diff --git a/pkg/cri/server/podsandbox/controller.go b/pkg/cri/server/podsandbox/controller.go index 6ab044112..604b5168d 100644 --- a/pkg/cri/server/podsandbox/controller.go +++ b/pkg/cri/server/podsandbox/controller.go @@ -31,7 +31,6 @@ import ( "github.com/containerd/containerd/v2/core/sandbox" criconfig "github.com/containerd/containerd/v2/pkg/cri/config" "github.com/containerd/containerd/v2/pkg/cri/constants" - "github.com/containerd/containerd/v2/pkg/cri/server/base" "github.com/containerd/containerd/v2/pkg/cri/server/podsandbox/types" imagestore "github.com/containerd/containerd/v2/pkg/cri/store/image" ctrdutil "github.com/containerd/containerd/v2/pkg/cri/util" @@ -51,8 +50,7 @@ func init() { plugins.EventPlugin, plugins.LeasePlugin, plugins.SandboxStorePlugin, - plugins.InternalPlugin, - plugins.CRIImagePlugin, + plugins.CRIServicePlugin, plugins.ServicePlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { @@ -66,26 +64,26 @@ func init() { return nil, fmt.Errorf("unable to init client for podsandbox: %w", err) } - // Get base CRI dependencies. - criBasePlugin, err := ic.GetByID(plugins.InternalPlugin, "cri") + // Get runtime service. + criRuntimePlugin, err := ic.GetByID(plugins.CRIServicePlugin, "runtime") if err != nil { - return nil, fmt.Errorf("unable to load CRI service base dependencies: %w", err) + return nil, fmt.Errorf("unable to load CRI runtime service plugin dependency: %w", err) } - criBase := criBasePlugin.(*base.CRIBase) + runtimeService := criRuntimePlugin.(RuntimeService) // Get image service. - criImagePlugin, err := ic.GetSingle(plugins.CRIImagePlugin) + criImagePlugin, err := ic.GetByID(plugins.CRIServicePlugin, "images") if err != nil { return nil, fmt.Errorf("unable to load CRI image service plugin dependency: %w", err) } c := Controller{ - client: client, - config: criBase.Config, - os: osinterface.RealOS{}, - baseOCISpecs: criBase.BaseOCISpecs, - imageService: criImagePlugin.(ImageService), - store: NewStore(), + client: client, + config: runtimeService.Config(), + os: osinterface.RealOS{}, + runtimeService: runtimeService, + imageService: criImagePlugin.(ImageService), + store: NewStore(), } return &c, nil }, @@ -99,6 +97,12 @@ type CRIService interface { BackOffEvent(id string, event interface{}) } +// RuntimeService specifies dependencies to CRI runtime service. +type RuntimeService interface { + Config() criconfig.Config + LoadOCISpec(string) (*oci.Spec, error) +} + // ImageService specifies dependencies to CRI image service. type ImageService interface { LocalResolve(refOrID string) (imagestore.Image, error) @@ -113,14 +117,14 @@ type Controller struct { config criconfig.Config // client is an instance of the containerd client client *containerd.Client + // runtimeService is a dependency to CRI runtime service. + runtimeService RuntimeService // imageService is a dependency to CRI image service. imageService ImageService // os is an interface for all required os operations. os osinterface.OS // cri is CRI service that provides missing gaps needed by controller. cri CRIService - // baseOCISpecs contains cached OCI specs loaded via `Runtime.BaseRuntimeSpec` - baseOCISpecs map[string]*oci.Spec store *Store } diff --git a/pkg/cri/server/podsandbox/helpers.go b/pkg/cri/server/podsandbox/helpers.go index 3fa231181..67b380d3a 100644 --- a/pkg/cri/server/podsandbox/helpers.go +++ b/pkg/cri/server/podsandbox/helpers.go @@ -159,9 +159,9 @@ func (c *Controller) runtimeSpec(id string, baseSpecFile string, opts ...oci.Spe container := &containers.Container{ID: id} if baseSpecFile != "" { - baseSpec, ok := c.baseOCISpecs[baseSpecFile] - if !ok { - return nil, fmt.Errorf("can't find base OCI spec %q", baseSpecFile) + baseSpec, err := c.runtimeService.LoadOCISpec(baseSpecFile) + if err != nil { + return nil, fmt.Errorf("can't load base OCI spec %q: %w", baseSpecFile, err) } spec := oci.Spec{} diff --git a/pkg/cri/server/service.go b/pkg/cri/server/service.go index 708088b92..dc1bbc23a 100644 --- a/pkg/cri/server/service.go +++ b/pkg/cri/server/service.go @@ -65,6 +65,15 @@ type sandboxService interface { SandboxController(config *runtime.PodSandboxConfig, runtimeHandler string) (sandbox.Controller, error) } +// RuntimeService specifies dependencies to runtime service which provides +// the runtime configuration and OCI spec loading. +type RuntimeService interface { + Config() criconfig.Config + + // LoadCISpec loads cached OCI specs via `Runtime.BaseRuntimeSpec` + LoadOCISpec(string) (*oci.Spec, error) +} + // ImageService specifies dependencies to image service. type ImageService interface { RuntimeSnapshotter(ctx context.Context, ociRuntime criconfig.Runtime) string @@ -84,6 +93,7 @@ type ImageService interface { // criService implements CRIService. type criService struct { + RuntimeService ImageService // config contains all configurations. config criconfig.Config @@ -115,8 +125,6 @@ type criService struct { // cniNetConfMonitor is used to reload cni network conf if there is // any valid fs change events from cni network conf dir. cniNetConfMonitor map[string]*cniNetConfSyncer - // baseOCISpecs contains cached OCI specs loaded via `Runtime.BaseRuntimeSpec` - baseOCISpecs map[string]*oci.Spec // allCaps is the list of the capabilities. // When nil, parsed from CapEff of /proc/self/status. allCaps []string //nolint:nolintlint,unused // Ignore on non-Linux @@ -130,6 +138,8 @@ type criService struct { } type CRIServiceOptions struct { + RuntimeService RuntimeService + ImageService ImageService NRI *nri.API @@ -137,9 +147,6 @@ type CRIServiceOptions struct { // SandboxControllers is a map of all the loaded sandbox controllers SandboxControllers map[string]sandbox.Controller - // BaseOCISpecs contains cached OCI specs loaded via `Runtime.BaseRuntimeSpec` - BaseOCISpecs map[string]*oci.Spec - // Client is the base containerd client used for accessing services, // // TODO: Replace this gradually with directly configured instances @@ -147,18 +154,18 @@ type CRIServiceOptions struct { } // NewCRIService returns a new instance of CRIService -// TODO: Add criBase.BaseOCISpecs to options -func NewCRIService(config criconfig.Config, options *CRIServiceOptions) (CRIService, runtime.RuntimeServiceServer, error) { +func NewCRIService(options *CRIServiceOptions) (CRIService, runtime.RuntimeServiceServer, error) { var err error labels := label.NewStore() + config := options.RuntimeService.Config() c := &criService{ + RuntimeService: options.RuntimeService, ImageService: options.ImageService, config: config, client: options.Client, imageFSPaths: options.ImageService.ImageFSPaths(), os: osinterface.RealOS{}, - baseOCISpecs: options.BaseOCISpecs, sandboxStore: sandboxstore.NewStore(labels), containerStore: containerstore.NewStore(labels), sandboxNameIndex: registrar.NewRegistrar(), diff --git a/pkg/cri/server/service_test.go b/pkg/cri/server/service_test.go index 4d8cc047b..f6d2c1d5f 100644 --- a/pkg/cri/server/service_test.go +++ b/pkg/cri/server/service_test.go @@ -25,10 +25,12 @@ import ( "github.com/containerd/containerd/v2/api/types" "github.com/containerd/containerd/v2/core/sandbox" "github.com/containerd/containerd/v2/internal/registrar" + criconfig "github.com/containerd/containerd/v2/pkg/cri/config" containerstore "github.com/containerd/containerd/v2/pkg/cri/store/container" "github.com/containerd/containerd/v2/pkg/cri/store/label" sandboxstore "github.com/containerd/containerd/v2/pkg/cri/store/sandbox" servertesting "github.com/containerd/containerd/v2/pkg/cri/testing" + "github.com/containerd/containerd/v2/pkg/oci" ostesting "github.com/containerd/containerd/v2/pkg/os/testing" "github.com/containerd/errdefs" "github.com/containerd/platforms" @@ -74,11 +76,34 @@ func (f fakeSandboxController) Metrics(ctx context.Context, sandboxID string) (* return &types.Metric{}, errdefs.ErrNotImplemented } +type fakeRuntimeService struct { + ocispecs map[string]*oci.Spec +} + +func (f fakeRuntimeService) Config() criconfig.Config { + return testConfig +} + +func (f fakeRuntimeService) LoadOCISpec(filename string) (*oci.Spec, error) { + spec, ok := f.ocispecs[filename] + if !ok { + return nil, errdefs.ErrNotFound + } + return spec, nil +} + +type testOpt func(*criService) + +func withRuntimeService(rs RuntimeService) testOpt { + return func(service *criService) { + service.RuntimeService = rs + } +} + // newTestCRIService creates a fake criService for test. -func newTestCRIService() *criService { +func newTestCRIService(opts ...testOpt) *criService { labels := label.NewStore() - return &criService{ - ImageService: &fakeImageService{}, + service := &criService{ config: testConfig, os: ostesting.NewFakeOS(), sandboxStore: sandboxstore.NewStore(labels), @@ -90,4 +115,15 @@ func newTestCRIService() *criService { }, sandboxService: &fakeSandboxService{}, } + for _, opt := range opts { + opt(service) + } + if service.RuntimeService == nil { + service.RuntimeService = &fakeRuntimeService{} + } + if service.ImageService == nil { + service.ImageService = &fakeImageService{} + } + + return service } diff --git a/pkg/cri/server/base/sandbox_info.go b/pkg/cri/types/sandbox_info.go similarity index 100% rename from pkg/cri/server/base/sandbox_info.go rename to pkg/cri/types/sandbox_info.go diff --git a/plugins/cri/images/plugin.go b/plugins/cri/images/plugin.go index c297a28a5..963ef3b50 100644 --- a/plugins/cri/images/plugin.go +++ b/plugins/cri/images/plugin.go @@ -40,15 +40,14 @@ func init() { config := criconfig.DefaultImageConfig() registry.Register(&plugin.Registration{ - Type: plugins.CRIImagePlugin, - ID: "local", + Type: plugins.CRIServicePlugin, + ID: "images", Config: &config, Requires: []plugin.Type{ plugins.LeasePlugin, plugins.EventPlugin, plugins.MetadataPlugin, plugins.SandboxStorePlugin, - plugins.InternalPlugin, // For config migration ordering plugins.ServicePlugin, // For client plugins.SnapshotPlugin, // For root directory properties }, @@ -152,12 +151,12 @@ func configMigration(ctx context.Context, version int, pluginConfigs map[string] if version >= srvconfig.CurrentConfigVersion { return nil } - original, ok := pluginConfigs[string(plugins.InternalPlugin)+".cri"] + original, ok := pluginConfigs[string(plugins.GRPCPlugin)+".cri"] if !ok { return nil } src := original.(map[string]interface{}) - updated, ok := pluginConfigs[string(plugins.CRIImagePlugin)+".local"] + updated, ok := pluginConfigs[string(plugins.CRIServicePlugin)+".images"] var dst map[string]interface{} if ok { dst = updated.(map[string]interface{}) @@ -166,7 +165,7 @@ func configMigration(ctx context.Context, version int, pluginConfigs map[string] } migrateConfig(dst, src) - pluginConfigs[string(plugins.CRIImagePlugin)+".local"] = dst + pluginConfigs[string(plugins.CRIServicePlugin)+".images"] = dst return nil } func migrateConfig(dst, src map[string]interface{}) { diff --git a/pkg/cri/server/base/cri_base_test.go b/plugins/cri/runtime/load_test.go similarity index 98% rename from pkg/cri/server/base/cri_base_test.go rename to plugins/cri/runtime/load_test.go index 07e796640..2abd21580 100644 --- a/pkg/cri/server/base/cri_base_test.go +++ b/plugins/cri/runtime/load_test.go @@ -14,7 +14,7 @@ limitations under the License. */ -package base +package runtime import ( "encoding/json" diff --git a/pkg/cri/server/base/cri_base.go b/plugins/cri/runtime/plugin.go similarity index 85% rename from pkg/cri/server/base/cri_base.go rename to plugins/cri/runtime/plugin.go index a28070700..7e8181a88 100644 --- a/pkg/cri/server/base/cri_base.go +++ b/plugins/cri/runtime/plugin.go @@ -14,7 +14,7 @@ limitations under the License. */ -package base +package runtime import ( "context" @@ -36,47 +36,39 @@ import ( "github.com/containerd/containerd/v2/pkg/oci" "github.com/containerd/containerd/v2/plugins" "github.com/containerd/containerd/v2/plugins/services/warning" + "github.com/containerd/errdefs" "github.com/containerd/platforms" ) -// CRIBase contains common dependencies for CRI's runtime, image, and podsandbox services. -type CRIBase struct { - // Config contains all configurations. - Config criconfig.Config - // BaseOCISpecs contains cached OCI specs loaded via `Runtime.BaseRuntimeSpec` - BaseOCISpecs map[string]*oci.Spec -} - func init() { config := criconfig.DefaultConfig() // Base plugin that other CRI services depend on. registry.Register(&plugin.Registration{ - Type: plugins.InternalPlugin, - ID: "cri", + Type: plugins.CRIServicePlugin, + ID: "runtime", Config: &config, Requires: []plugin.Type{ plugins.WarningPlugin, }, - ConfigMigration: func(ctx context.Context, version int, plugins map[string]interface{}) error { + ConfigMigration: func(ctx context.Context, version int, pluginConfigs map[string]interface{}) error { if version >= srvconfig.CurrentConfigVersion { return nil } - c, ok := plugins["io.containerd.grpc.v1.cri"] + c, ok := pluginConfigs[string(plugins.GRPCPlugin)+".cri"] if !ok { return nil } conf := c.(map[string]interface{}) migrateConfig(conf) - plugins["io.containerd.internal.v1.cri"] = conf - delete(plugins, "io.containerd.grpc.v1.cri") + pluginConfigs[string(plugins.CRIServicePlugin)+".runtime"] = conf return nil }, - InitFn: initCRIBase, + InitFn: initCRIRuntime, }) } -func initCRIBase(ic *plugin.InitContext) (interface{}, error) { +func initCRIRuntime(ic *plugin.InitContext) (interface{}, error) { ic.Meta.Platforms = []imagespec.Platform{platforms.DefaultSpec()} ic.Meta.Exports = map[string]string{"CRIVersion": constants.CRIVersion} ctx := ic.Context @@ -118,12 +110,33 @@ func initCRIBase(ic *plugin.InitContext) (interface{}, error) { return nil, fmt.Errorf("failed to create load basic oci spec: %w", err) } - return &CRIBase{ - Config: c, - BaseOCISpecs: ociSpec, + return &runtime{ + config: c, + baseOCISpecs: ociSpec, }, nil } +// runtime contains common dependencies for CRI's runtime, image, and podsandbox services. +type runtime struct { + // Config contains all configurations. + config criconfig.Config + // BaseOCISpecs contains cached OCI specs loaded via `Runtime.BaseRuntimeSpec` + baseOCISpecs map[string]*oci.Spec +} + +func (r *runtime) Config() criconfig.Config { + return r.config +} + +func (r *runtime) LoadOCISpec(filename string) (*oci.Spec, error) { + spec, ok := r.baseOCISpecs[filename] + if !ok { + // TODO: Load here or only allow preloading... + return nil, errdefs.ErrNotFound + } + return spec, nil +} + func loadBaseOCISpecs(config *criconfig.Config) (map[string]*oci.Spec, error) { specs := map[string]*oci.Spec{} for _, cfg := range config.Runtimes { diff --git a/plugins/types.go b/plugins/types.go index 740e2d253..c09734443 100644 --- a/plugins/types.go +++ b/plugins/types.go @@ -67,8 +67,8 @@ const ( ImageVerifierPlugin plugin.Type = "io.containerd.image-verifier.v1" // WarningPlugin implements a warning service WarningPlugin plugin.Type = "io.containerd.warning.v1" - // CRIImagePlugin implements a cri image service - CRIImagePlugin plugin.Type = "io.containerd.cri.image.v1" + // CRIServicePlugin implements a cri service + CRIServicePlugin plugin.Type = "io.containerd.cri.v1" ) const (