Generalize the plugin package

Remove containerd specific parts of the plugin package to prepare its
move out of the main repository. Separate the plugin registration
singleton into a separate package.

Separating out the plugin package and registration makes it easier to
implement external plugins without creating a dependency loop.

Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
Derek McGowan 2023-10-12 15:36:02 -07:00
parent a80606bc2d
commit 7b2a918213
No known key found for this signature in database
GPG Key ID: F58C5D0A4405ACDB
65 changed files with 363 additions and 299 deletions

View File

@ -24,7 +24,7 @@ import (
"github.com/containerd/containerd/defaults"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/pkg/timeout"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/services/server"
srvconfig "github.com/containerd/containerd/services/server/config"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@ -46,7 +46,7 @@ func outputConfig(ctx gocontext.Context, config *srvconfig.Config) error {
continue
}
pc, err := config.Decode(ctx, p)
pc, err := config.Decode(ctx, p.URI(), p.Config)
if err != nil {
return err
}
@ -113,7 +113,7 @@ var configCommand = cli.Command{
}
if config.Version < srvconfig.CurrentConfigVersion {
plugins := plugin.Graph(srvconfig.V2DisabledFilter(config.DisabledPlugins))
plugins := registry.Graph(srvconfig.V2DisabledFilter(config.DisabledPlugins))
for _, p := range plugins {
if p.ConfigMigration != nil {
if err := p.ConfigMigration(ctx, config.Version, config.Plugins); err != nil {

View File

@ -36,6 +36,7 @@ import (
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/log"
digest "github.com/opencontainers/go-digest"
@ -48,7 +49,7 @@ const (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.DiffPlugin,
ID: "windows-lcow",
Requires: []plugin.Type{

View File

@ -23,11 +23,12 @@ import (
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.DiffPlugin,
ID: "walking",
Requires: []plugin.Type{

View File

@ -39,6 +39,7 @@ import (
"github.com/containerd/containerd/pkg/epoch"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/log"
"github.com/opencontainers/go-digest"
@ -46,7 +47,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.DiffPlugin,
ID: "windows",
Requires: []plugin.Type{

View File

@ -19,11 +19,12 @@ package plugin
import (
"github.com/containerd/containerd/events/exchange"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.EventPlugin,
ID: "exchange",
InitFn: func(ic *plugin.InitContext) (interface{}, error) {

View File

@ -25,6 +25,7 @@ import (
"github.com/containerd/containerd/gc"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/log"
)
@ -97,7 +98,7 @@ func (d duration) MarshalText() (text []byte, err error) {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GCPlugin,
ID: "scheduler",
Requires: []plugin.Type{

View File

@ -26,6 +26,7 @@ import (
"github.com/containerd/containerd/pkg/cri/constants"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugins"
ctrdsrv "github.com/containerd/containerd/services/server"
srvconfig "github.com/containerd/containerd/services/server/config"
"github.com/containerd/log/logtest"
@ -54,7 +55,7 @@ import (
var (
loadPluginOnce sync.Once
loadedPlugins []*plugin.Registration
loadedPlugins []plugin.Registration
loadedPluginsErr error
)
@ -88,15 +89,16 @@ func buildLocalContainerdClient(t *testing.T, tmpDir string) *containerd.Client
for _, p := range loadedPlugins {
initContext := plugin.NewContext(
ctx,
p,
initialized,
config.Root,
config.State,
map[string]string{
plugins.PropertyRootDir: filepath.Join(config.Root, p.URI()),
plugins.PropertyStateDir: filepath.Join(config.State, p.URI()),
},
)
// load the plugin specific configuration if it is provided
if p.Config != nil {
pc, err := config.Decode(ctx, p)
pc, err := config.Decode(ctx, p.URI(), p.Config)
assert.NoError(t, err)
initContext.Config = pc

View File

@ -28,6 +28,7 @@ import (
"github.com/containerd/containerd/pkg/failpoint"
"github.com/containerd/containerd/pkg/shutdown"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/runtime/v2/runc/task"
"github.com/containerd/containerd/runtime/v2/shim"
@ -39,7 +40,7 @@ const (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.TTRPCPlugin,
ID: "task",
Requires: []plugin.Type{

View File

@ -23,11 +23,12 @@ import (
"github.com/containerd/containerd/leases"
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.LeasePlugin,
ID: "manager",
Requires: []plugin.Type{

View File

@ -28,6 +28,7 @@ import (
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/pkg/timeout"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/snapshots"
"github.com/containerd/log"
@ -82,7 +83,7 @@ func (bc *BoltConfig) Validate() error {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.MetadataPlugin,
ID: "bolt",
Requires: []plugin.Type{
@ -94,7 +95,8 @@ func init() {
ContentSharingPolicy: SharingPolicyShared,
},
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
if err := os.MkdirAll(ic.Root, 0711); err != nil {
root := ic.Properties[plugins.PropertyRootDir]
if err := os.MkdirAll(root, 0711); err != nil {
return nil, err
}
cs, err := ic.Get(plugins.ContentPlugin)
@ -141,7 +143,7 @@ func init() {
}
}
path := filepath.Join(ic.Root, "meta.db")
path := filepath.Join(root, "meta.db")
ic.Meta.Exports["path"] = path
options := *bolt.DefaultOptions

View File

@ -25,6 +25,7 @@ import (
v2 "github.com/containerd/containerd/metrics/cgroups/v2"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/runtime"
metrics "github.com/docker/go-metrics"
@ -36,7 +37,7 @@ type Config struct {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.TaskMonitorPlugin,
ID: "cgroups",
InitFn: New,

View File

@ -27,6 +27,7 @@ import (
nriservice "github.com/containerd/containerd/pkg/nri"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/log"
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
@ -39,7 +40,7 @@ import (
// Register CRI service plugin
func init() {
config := criconfig.DefaultConfig()
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "cri",
Config: &config,
@ -63,10 +64,10 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
c := criconfig.Config{
PluginConfig: *pluginConfig,
ContainerdRootDir: filepath.Dir(ic.Root),
ContainerdEndpoint: ic.Address,
RootDir: ic.Root,
StateDir: ic.State,
ContainerdRootDir: filepath.Dir(ic.Properties[plugins.PropertyRootDir]),
ContainerdEndpoint: ic.Properties[plugins.PropertyGRPCAddress],
RootDir: ic.Properties[plugins.PropertyRootDir],
StateDir: ic.Properties[plugins.PropertyStateDir],
}
log.G(ctx).Infof("Start cri plugin with config %+v", c)

View File

@ -19,11 +19,12 @@ package plugin
import (
"github.com/containerd/containerd/pkg/nri"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.NRIApiPlugin,
ID: "nri",
Config: nri.DefaultConfig(),

View File

@ -19,20 +19,15 @@ package plugin
import (
"context"
"fmt"
"path/filepath"
"github.com/containerd/containerd/errdefs"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
)
// InitContext is used for plugin initialization
type InitContext struct {
Context context.Context
Root string
State string
Properties map[string]string
Config interface{}
Address string
TTRPCAddress string
RegisterReadiness func() func()
// Meta is metadata plugins can fill in at init
@ -42,11 +37,13 @@ type InitContext struct {
}
// NewContext returns a new plugin InitContext
func NewContext(ctx context.Context, r *Registration, plugins *Set, root, state string) *InitContext {
func NewContext(ctx context.Context, plugins *Set, properties map[string]string) *InitContext {
if properties == nil {
properties = map[string]string{}
}
return &InitContext{
Context: ctx,
Root: filepath.Join(root, r.URI()),
State: filepath.Join(state, r.URI()),
Properties: properties,
Meta: &Meta{
Exports: map[string]string{},
},
@ -62,16 +59,16 @@ func (i *InitContext) Get(t Type) (interface{}, error) {
// Meta contains information gathered from the registration and initialization
// process.
type Meta struct {
Platforms []ocispec.Platform // platforms supported by plugin
Platforms []imagespec.Platform // platforms supported by plugin
Exports map[string]string // values exported by plugin
Capabilities []string // feature switches for plugin
}
// Plugin represents an initialized plugin, used with an init context.
type Plugin struct {
Registration *Registration // registration, as initialized
Registration Registration // registration, as initialized
Config interface{} // config, as initialized
Meta *Meta
Meta Meta
instance interface{}
err error // will be set if there was an error initializing the plugin
@ -115,7 +112,7 @@ func (ps *Set) Add(p *Plugin) error {
} else if _, idok := byID[p.Registration.ID]; !idok {
byID[p.Registration.ID] = p
} else {
return fmt.Errorf("plugin %v already initialized: %w", p.Registration.URI(), errdefs.ErrAlreadyExists)
return fmt.Errorf("plugin add failed for %s: %w", p.Registration.URI(), ErrPluginInitialized)
}
ps.ordered = append(ps.ordered, p)
@ -127,7 +124,7 @@ func (ps *Set) Get(t Type) (interface{}, error) {
for _, v := range ps.byTypeAndID[t] {
return v.Instance()
}
return nil, fmt.Errorf("no plugins registered for %s: %w", t, errdefs.ErrNotFound)
return nil, fmt.Errorf("no plugins registered for %s: %w", t, ErrPluginNotFound)
}
// GetAll returns all initialized plugins
@ -153,7 +150,7 @@ func (i *InitContext) GetByID(t Type, id string) (interface{}, error) {
}
p, ok := ps[id]
if !ok {
return nil, fmt.Errorf("no %s plugins with id %s: %w", t, id, errdefs.ErrNotFound)
return nil, fmt.Errorf("no %s plugins with id %s: %w", t, id, ErrPluginNotFound)
}
return p.Instance()
}
@ -162,7 +159,7 @@ func (i *InitContext) GetByID(t Type, id string) (interface{}, error) {
func (i *InitContext) GetByType(t Type) (map[string]*Plugin, error) {
p, ok := i.plugins.byTypeAndID[t]
if !ok {
return nil, fmt.Errorf("no plugins registered for %s: %w", t, errdefs.ErrNotFound)
return nil, fmt.Errorf("no plugins registered for %s: %w", t, ErrPluginNotFound)
}
return p, nil

View File

@ -20,7 +20,6 @@ import (
"context"
"errors"
"fmt"
"sync"
)
var (
@ -34,6 +33,10 @@ var (
// this allows the plugin loader differentiate between a plugin which is configured
// not to load and one that fails to load.
ErrSkipPlugin = errors.New("skip plugin")
// ErrPluginInitialized is used when a plugin is already initialized
ErrPluginInitialized = errors.New("plugin: already initialized")
// ErrPluginNotFound is used when a plugin is looked up but not found
ErrPluginNotFound = errors.New("plugin: not found")
// ErrInvalidRequires will be thrown if the requirements for a plugin are
// defined in an invalid manner.
@ -65,8 +68,6 @@ type Registration struct {
// context are passed in. The init function may modify the registration to
// add exports, capabilities and platform support declarations.
InitFn func(*InitContext) (interface{}, error)
// Disable the plugin from loading
Disable bool
// ConfigMigration allows a plugin to migrate configurations from an older
// version to handle plugin renames or moving of features from one plugin
@ -79,12 +80,12 @@ type Registration struct {
}
// Init the registered plugin
func (r *Registration) Init(ic *InitContext) *Plugin {
func (r Registration) Init(ic *InitContext) *Plugin {
p, err := r.InitFn(ic)
return &Plugin{
Registration: r,
Config: ic.Config,
Meta: ic.Meta,
Meta: *ic.Meta,
instance: p,
err: err,
}
@ -95,11 +96,6 @@ func (r *Registration) URI() string {
return r.Type.String() + "." + r.ID
}
var register = struct {
sync.RWMutex
r []*Registration
}{}
// Load loads all plugins at the provided path into containerd.
//
// Load is currently only implemented on non-static, non-gccgo builds for amd64
@ -118,18 +114,64 @@ func Load(path string) (err error) {
return loadPlugins(path)
}
// Register allows plugins to register
func Register(r *Registration) {
register.Lock()
defer register.Unlock()
// DisableFilter filters out disabled plugins
type DisableFilter func(r *Registration) bool
// Registry is list of registrations which can be registered to and
// produce a filtered and ordered output.
// The Registry itself is immutable and the list will be copied
// and appeneded to a new registry when new items are registered.
type Registry []*Registration
// Graph computes the ordered list of registrations based on their dependencies,
// filtering out any plugins which match the provided filter.
func (registry Registry) Graph(filter DisableFilter) []Registration {
disabled := map[*Registration]bool{}
for _, r := range registry {
if filter(r) {
disabled[r] = true
}
}
ordered := make([]Registration, 0, len(registry)-len(disabled))
added := map[*Registration]bool{}
for _, r := range registry {
if disabled[r] {
continue
}
children(r, registry, added, disabled, &ordered)
if !added[r] {
ordered = append(ordered, *r)
added[r] = true
}
}
return ordered
}
func children(reg *Registration, registry []*Registration, added, disabled map[*Registration]bool, ordered *[]Registration) {
for _, t := range reg.Requires {
for _, r := range registry {
if !disabled[r] && r.URI() != reg.URI() && (t == "*" || r.Type == t) {
children(r, registry, added, disabled, ordered)
if !added[r] {
*ordered = append(*ordered, *r)
added[r] = true
}
}
}
}
}
// Register adds the registration to a Registry and returns the
// updated Registry, panicking if registration could not succeed.
func (registry Registry) Register(r *Registration) Registry {
if r.Type == "" {
panic(ErrNoType)
}
if r.ID == "" {
panic(ErrNoPluginID)
}
if err := checkUnique(r); err != nil {
if err := checkUnique(registry, r); err != nil {
panic(err)
}
@ -139,66 +181,14 @@ func Register(r *Registration) {
}
}
register.r = append(register.r, r)
return append(registry, r)
}
// Reset removes all global registrations
func Reset() {
register.Lock()
defer register.Unlock()
register.r = nil
}
func checkUnique(r *Registration) error {
for _, registered := range register.r {
func checkUnique(registry Registry, r *Registration) error {
for _, registered := range registry {
if r.URI() == registered.URI() {
return fmt.Errorf("%s: %w", r.URI(), ErrIDRegistered)
}
}
return nil
}
// DisableFilter filters out disabled plugins
type DisableFilter func(r *Registration) bool
// Graph returns an ordered list of registered plugins for initialization.
// Plugins in disableList specified by id will be disabled.
func Graph(filter DisableFilter) (ordered []*Registration) {
register.RLock()
defer register.RUnlock()
for _, r := range register.r {
if filter(r) {
r.Disable = true
}
}
added := map[*Registration]bool{}
for _, r := range register.r {
if r.Disable {
continue
}
children(r, added, &ordered)
if !added[r] {
ordered = append(ordered, r)
added[r] = true
}
}
return ordered
}
func children(reg *Registration, added map[*Registration]bool, ordered *[]*Registration) {
for _, t := range reg.Requires {
for _, r := range register.r {
if !r.Disable &&
r.URI() != reg.URI() &&
(t == "*" || r.Type == t) {
children(r, added, ordered)
if !added[r] {
*ordered = append(*ordered, r)
added[r] = true
}
}
}
}
}

View File

@ -22,19 +22,12 @@ import (
"github.com/containerd/containerd/services"
)
func registerClear() {
register.Lock()
defer register.Unlock()
register.r = nil
}
func mockPluginFilter(*Registration) bool {
return false
}
// TestContainerdPlugin tests the logic of Graph, use the containerd's plugin
func TestContainerdPlugin(t *testing.T) {
registerClear()
// Plugin types commonly used by containerd
const (
InternalPlugin Type = "io.containerd.internal.v1"
@ -52,11 +45,11 @@ func TestContainerdPlugin(t *testing.T) {
TracingProcessorPlugin Type = "io.containerd.tracing.processor.v1"
)
Register(&Registration{
var register Registry
register = register.Register(&Registration{
Type: TaskMonitorPlugin,
ID: "cgroups",
})
Register(&Registration{
}).Register(&Registration{
Type: ServicePlugin,
ID: services.TasksService,
Requires: []Type{
@ -65,199 +58,165 @@ func TestContainerdPlugin(t *testing.T) {
MetadataPlugin,
TaskMonitorPlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: ServicePlugin,
ID: services.IntrospectionService,
})
Register(&Registration{
}).Register(&Registration{
Type: ServicePlugin,
ID: services.NamespacesService,
Requires: []Type{
MetadataPlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "namespaces",
Requires: []Type{
ServicePlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "content",
Requires: []Type{
ServicePlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "containers",
Requires: []Type{
ServicePlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: ServicePlugin,
ID: services.ContainersService,
Requires: []Type{
MetadataPlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "events",
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "leases",
Requires: []Type{
LeasePlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: LeasePlugin,
ID: "manager",
Requires: []Type{
MetadataPlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "diff",
Requires: []Type{
ServicePlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: ServicePlugin,
ID: services.DiffService,
Requires: []Type{
DiffPlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: ServicePlugin,
ID: services.SnapshotsService,
Requires: []Type{
MetadataPlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "snapshots",
Requires: []Type{
ServicePlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "version",
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "images",
Requires: []Type{
ServicePlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: GCPlugin,
ID: "scheduler",
Requires: []Type{
MetadataPlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: RuntimePluginV2,
ID: "task",
Requires: []Type{
MetadataPlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "tasks",
Requires: []Type{
ServicePlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "introspection",
Requires: []Type{"*"},
})
Register(&Registration{
}).Register(&Registration{
Type: ServicePlugin,
ID: services.ContentService,
Requires: []Type{
MetadataPlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "healthcheck",
})
Register(&Registration{
}).Register(&Registration{
Type: InternalPlugin,
ID: "opt",
})
Register(&Registration{
}).Register(&Registration{
Type: GRPCPlugin,
ID: "cri",
Requires: []Type{
ServicePlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: RuntimePlugin,
ID: "linux",
Requires: []Type{
MetadataPlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: InternalPlugin,
Requires: []Type{
ServicePlugin,
},
ID: "restart",
})
Register(&Registration{
}).Register(&Registration{
Type: DiffPlugin,
ID: "walking",
Requires: []Type{
MetadataPlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: SnapshotPlugin,
ID: "native",
})
Register(&Registration{
}).Register(&Registration{
Type: SnapshotPlugin,
ID: "overlayfs",
})
Register(&Registration{
}).Register(&Registration{
Type: ContentPlugin,
ID: "content",
})
Register(&Registration{
}).Register(&Registration{
Type: MetadataPlugin,
ID: "bolt",
Requires: []Type{
ContentPlugin,
SnapshotPlugin,
},
})
Register(&Registration{
}).Register(&Registration{
Type: TracingProcessorPlugin,
ID: "otlp",
})
Register(&Registration{
}).Register(&Registration{
Type: InternalPlugin,
ID: "tracing",
Requires: []Type{
@ -265,7 +224,7 @@ func TestContainerdPlugin(t *testing.T) {
},
})
ordered := Graph(mockPluginFilter)
ordered := register.Graph(mockPluginFilter)
expectedURI := []string{
"io.containerd.monitor.v1.cgroups",
"io.containerd.content.v1.content",
@ -305,7 +264,7 @@ func TestContainerdPlugin(t *testing.T) {
cmpOrdered(t, ordered, expectedURI)
}
func cmpOrdered(t *testing.T, ordered []*Registration, expectedURI []string) {
func cmpOrdered(t *testing.T, ordered []Registration, expectedURI []string) {
if len(ordered) != len(expectedURI) {
t.Fatalf("ordered compare failed, %d != %d", len(ordered), len(expectedURI))
}
@ -321,6 +280,7 @@ func TestPluginGraph(t *testing.T) {
for _, testcase := range []struct {
input []*Registration
expectedURI []string
filter DisableFilter
}{
// test requires *
{
@ -397,19 +357,25 @@ func TestPluginGraph(t *testing.T) {
{
Type: "disable",
ID: "disable",
Disable: true,
},
},
expectedURI: []string{
"content.content",
},
filter: func(r *Registration) bool {
return r.Type == "disable"
},
},
} {
registerClear()
var register Registry
for _, in := range testcase.input {
Register(in)
register = register.Register(in)
}
ordered := Graph(mockPluginFilter)
var filter DisableFilter = mockPluginFilter
if testcase.filter != nil {
filter = testcase.filter
}
ordered := register.Graph(filter)
cmpOrdered(t, ordered, testcase.expectedURI)
}
}

View File

@ -0,0 +1,50 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package registry
import (
"sync"
"github.com/containerd/containerd/plugin"
)
var register = struct {
sync.RWMutex
r plugin.Registry
}{}
// Register allows plugins to register
func Register(r *plugin.Registration) {
register.Lock()
defer register.Unlock()
register.r = register.r.Register(r)
}
// Reset removes all global registrations
func Reset() {
register.Lock()
defer register.Unlock()
register.r = nil
}
// Graph returns an ordered list of registered plugins for initialization.
// Plugins in disableList specified by id will be disabled.
func Graph(filter plugin.DisableFilter) []plugin.Registration {
register.RLock()
defer register.RUnlock()
return register.r.Graph(filter)
}

View File

@ -22,12 +22,13 @@ import (
"github.com/containerd/containerd/pkg/imageverifier/bindir"
"github.com/containerd/containerd/pkg/tomlext"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
)
// Register default image verifier service plugin
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.ImageVerifierPlugin,
ID: "bindir",
Config: defaultConfig(),

View File

@ -29,6 +29,7 @@ import (
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/runtime"
v2 "github.com/containerd/containerd/runtime/v2"
@ -39,7 +40,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.SandboxControllerPlugin,
ID: "local",
Requires: []plugin.Type{

View File

@ -19,11 +19,12 @@ package sandbox
import (
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.SandboxStorePlugin,
ID: "local",
Requires: []plugin.Type{

View File

@ -28,11 +28,12 @@ import (
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/pkg/streaming"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.StreamingPlugin,
ID: "manager",
Requires: []plugin.Type{

View File

@ -29,6 +29,7 @@ import (
"github.com/containerd/containerd/pkg/unpack"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/log"
@ -40,7 +41,7 @@ import (
// Register local transfer service plugin
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.TransferPlugin,
ID: "local",
Requires: []plugin.Type{

View File

@ -26,6 +26,7 @@ import (
"github.com/containerd/containerd"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/runtime/restart"
"github.com/containerd/log"
@ -52,7 +53,7 @@ type Config struct {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.InternalPlugin,
Requires: []plugin.Type{
plugins.EventPlugin,

View File

@ -24,6 +24,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/pkg/shutdown"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/containerd/runtime/v2/shim"
@ -31,7 +32,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.TTRPCPlugin,
ID: "task",
Requires: []plugin.Type{

View File

@ -34,6 +34,7 @@ import (
"github.com/containerd/containerd/pkg/timeout"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/runtime"
@ -51,7 +52,7 @@ type Config struct {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.RuntimePluginV2,
ID: "task",
Requires: []plugin.Type{
@ -83,10 +84,10 @@ func init() {
events := ep.(*exchange.Exchange)
shimManager, err := NewShimManager(ic.Context, &ManagerConfig{
Root: ic.Root,
State: ic.State,
Address: ic.Address,
TTRPCAddress: ic.TTRPCAddress,
Root: ic.Properties[plugins.PropertyRootDir],
State: ic.Properties[plugins.PropertyStateDir],
Address: ic.Properties[plugins.PropertyGRPCAddress],
TTRPCAddress: ic.Properties[plugins.PropertyTTRPCAddress],
Events: events,
Store: cs,
SchedCore: config.SchedCore,
@ -104,7 +105,7 @@ func init() {
// However, due to time limits and to avoid migration steps in 1.6 release,
// use the following workaround.
// This expected to be removed in 1.7.
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.RuntimePluginV2,
ID: "shim",
InitFn: func(ic *plugin.InitContext) (interface{}, error) {

View File

@ -24,6 +24,7 @@ import (
"github.com/containerd/containerd/api/types"
"github.com/containerd/containerd/pkg/shutdown"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/runtime/v2/shim"
"github.com/containerd/log"
@ -34,7 +35,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.TTRPCPlugin,
ID: "pause",
Requires: []plugin.Type{

View File

@ -19,13 +19,14 @@ package plugin
import (
"github.com/containerd/containerd/pkg/shutdown"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/runtime/v2/runc/task"
"github.com/containerd/containerd/runtime/v2/shim"
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.TTRPCPlugin,
ID: "task",
Requires: []plugin.Type{

View File

@ -34,6 +34,7 @@ import (
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/pkg/shutdown"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/protobuf/proto"
@ -284,7 +285,7 @@ func run(ctx context.Context, manager Manager, name string, config Config) error
}
}
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.InternalPlugin,
ID: "shutdown",
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
@ -293,7 +294,7 @@ func run(ctx context.Context, manager Manager, name string, config Config) error
})
// Register event plugin
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.EventPlugin,
ID: "publisher",
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
@ -307,24 +308,24 @@ func run(ctx context.Context, manager Manager, name string, config Config) error
ttrpcUnaryInterceptors = []ttrpc.UnaryServerInterceptor{}
)
plugins := plugin.Graph(func(*plugin.Registration) bool { return false })
for _, p := range plugins {
for _, p := range registry.Graph(func(*plugin.Registration) bool { return false }) {
id := p.URI()
log.G(ctx).WithField("type", p.Type).Infof("loading plugin %q...", id)
initContext := plugin.NewContext(
ctx,
p,
initialized,
map[string]string{
// NOTE: Root is empty since the shim does not support persistent storage,
// shim plugins should make use state directory for writing files to disk.
// The state directory will be destroyed when the shim if cleaned up or
// on reboot
"",
bundlePath,
plugins.PropertyStateDir: filepath.Join(bundlePath, p.URI()),
plugins.PropertyGRPCAddress: addressFlag,
plugins.PropertyTTRPCAddress: ttrpcAddress,
},
)
initContext.Address = addressFlag
initContext.TTRPCAddress = ttrpcAddress
// load the plugin specific configuration if it is provided
// TODO: Read configuration passed into shim, or from state directory?

View File

@ -27,6 +27,7 @@ import (
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/containerd/services"
@ -38,7 +39,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.ServicePlugin,
ID: services.ContainersService,
Requires: []plugin.Type{

View File

@ -23,6 +23,7 @@ import (
api "github.com/containerd/containerd/api/services/containers/v1"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/containerd/services"
@ -30,7 +31,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "containers",
Requires: []plugin.Type{

View File

@ -21,13 +21,14 @@ import (
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/services"
"github.com/containerd/containerd/services/content/contentserver"
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "content",
Requires: []plugin.Type{

View File

@ -24,6 +24,7 @@ import (
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/services"
digest "github.com/opencontainers/go-digest"
@ -36,7 +37,7 @@ type store struct {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.ServicePlugin,
ID: services.ContentService,
Requires: []plugin.Type{

View File

@ -26,6 +26,7 @@ import (
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/oci"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/services"
"github.com/containerd/typeurl/v2"
@ -49,7 +50,7 @@ type differ interface {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.ServicePlugin,
ID: services.DiffService,
Requires: []plugin.Type{

View File

@ -22,13 +22,14 @@ import (
diffapi "github.com/containerd/containerd/api/services/diff/v1"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/services"
"google.golang.org/grpc"
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "diff",
Requires: []plugin.Type{

View File

@ -26,6 +26,7 @@ import (
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/events/exchange"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/protobuf"
ptypes "github.com/containerd/containerd/protobuf/types"
@ -34,7 +35,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "events",
Requires: []plugin.Type{

View File

@ -18,6 +18,7 @@ package healthcheck
import (
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"google.golang.org/grpc"
@ -30,7 +31,7 @@ type service struct {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "healthcheck",
InitFn: func(*plugin.InitContext) (interface{}, error) {

View File

@ -28,6 +28,7 @@ import (
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/pkg/epoch"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/containerd/services"
@ -38,7 +39,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.ServicePlugin,
ID: services.ImagesService,
Requires: []plugin.Type{

View File

@ -22,6 +22,7 @@ import (
imagesapi "github.com/containerd/containerd/api/services/images/v1"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/containerd/services"
@ -29,7 +30,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "images",
Requires: []plugin.Type{

View File

@ -28,6 +28,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/filters"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/containerd/services"
@ -39,7 +40,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.ServicePlugin,
ID: services.IntrospectionService,
Requires: []plugin.Type{},
@ -47,7 +48,7 @@ func init() {
// this service fetches all plugins through the plugin set of the plugin context
return &Local{
plugins: ic.Plugins(),
root: ic.Root,
root: ic.Properties[plugins.PropertyRootDir],
}, nil
},
})

View File

@ -22,6 +22,7 @@ import (
api "github.com/containerd/containerd/api/services/introspection/v1"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/containerd/services"
@ -29,7 +30,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "introspection",
Requires: []plugin.Type{plugins.ServicePlugin},
@ -52,7 +53,7 @@ func init() {
if !ok {
return nil, errors.New("could not create a local client for introspection service")
}
localClient.UpdateLocal(ic.Root)
localClient.UpdateLocal(ic.Properties[plugins.PropertyRootDir])
return &server{
local: localClient,

View File

@ -23,6 +23,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/leases"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/protobuf"
ptypes "github.com/containerd/containerd/protobuf/types"
@ -30,7 +31,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "leases",
Requires: []plugin.Type{

View File

@ -27,6 +27,7 @@ import (
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/containerd/services"
@ -37,7 +38,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.ServicePlugin,
ID: services.NamespacesService,
Requires: []plugin.Type{

View File

@ -22,6 +22,7 @@ import (
api "github.com/containerd/containerd/api/services/namespaces/v1"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/containerd/services"
@ -29,7 +30,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "namespaces",
Requires: []plugin.Type{

View File

@ -22,6 +22,7 @@ import (
"path/filepath"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
)
@ -32,7 +33,7 @@ type Config struct {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.InternalPlugin,
ID: "opt",
Config: &Config{

View File

@ -27,6 +27,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/sandbox"
@ -34,7 +35,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "sandbox-controllers",
Requires: []plugin.Type{

View File

@ -25,13 +25,14 @@ import (
"github.com/containerd/containerd/api/types"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/sandbox"
"github.com/containerd/log"
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "sandboxes",
Requires: []plugin.Type{

View File

@ -239,11 +239,10 @@ type ProxyPlugin struct {
}
// Decode unmarshals a plugin specific configuration by plugin id
func (c *Config) Decode(ctx context.Context, p *plugin.Registration) (interface{}, error) {
id := p.URI()
func (c *Config) Decode(ctx context.Context, id string, config interface{}) (interface{}, error) {
data, ok := c.Plugins[id]
if !ok {
return p.Config, nil
return config, nil
}
b, err := toml.Marshal(data)
@ -251,7 +250,7 @@ func (c *Config) Decode(ctx context.Context, p *plugin.Registration) (interface{
return nil, err
}
if err := toml.NewDecoder(bytes.NewReader(b)).DisallowUnknownFields().Decode(p.Config); err != nil {
if err := toml.NewDecoder(bytes.NewReader(b)).DisallowUnknownFields().Decode(config); err != nil {
var serr *toml.StrictMissingError
if errors.As(err, &serr) {
for _, derr := range serr.Errors {
@ -260,7 +259,7 @@ func (c *Config) Decode(ctx context.Context, p *plugin.Registration) (interface{
"key": strings.Join(derr.Key(), " "),
}).WithError(err).Warn("Ignoring unknown key in TOML for plugin")
}
err = toml.Unmarshal(b, p.Config)
err = toml.Unmarshal(b, config)
}
if err != nil {
return nil, err
@ -268,7 +267,7 @@ func (c *Config) Decode(ctx context.Context, p *plugin.Registration) (interface{
}
return p.Config, nil
return config, nil
}
// LoadConfig loads the containerd server config from the provided path

View File

@ -25,7 +25,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/containerd/containerd/plugin"
"github.com/containerd/log/logtest"
)
@ -201,7 +200,7 @@ func TestDecodePlugin(t *testing.T) {
ctx := logtest.WithT(context.Background(), t)
data := `
version = 2
[plugins."io.containerd.runtime.v1.linux"]
[plugins."io.containerd.runtime.v2.task"]
shim_debug = true
`
@ -216,7 +215,7 @@ version = 2
assert.NoError(t, err)
pluginConfig := map[string]interface{}{}
_, err = out.Decode(ctx, &plugin.Registration{Type: "io.containerd.runtime.v1", ID: "linux", Config: &pluginConfig})
_, err = out.Decode(ctx, "io.containerd.runtime.v2.task", &pluginConfig)
assert.NoError(t, err)
assert.Equal(t, true, pluginConfig["shim_debug"])
}
@ -226,7 +225,7 @@ version = 2
func TestDecodePluginInV1Config(t *testing.T) {
ctx := logtest.WithT(context.Background(), t)
data := `
[plugins.linux]
[plugins.task]
shim_debug = true
`
@ -244,7 +243,7 @@ func TestDecodePluginInV1Config(t *testing.T) {
assert.Equal(t, 3, out.Version)
pluginConfig := map[string]interface{}{}
_, err = out.Decode(ctx, &plugin.Registration{Type: "io.containerd.runtime.v1", ID: "linux", Config: &pluginConfig})
_, err = out.Decode(ctx, "io.containerd.runtime.v2.task", &pluginConfig)
assert.NoError(t, err)
assert.Equal(t, true, pluginConfig["shim_debug"])
}

View File

@ -46,6 +46,7 @@ import (
"github.com/containerd/containerd/pkg/timeout"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
srvconfig "github.com/containerd/containerd/services/server/config"
ssproxy "github.com/containerd/containerd/snapshots/proxy"
@ -245,13 +246,14 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
initContext := plugin.NewContext(
ctx,
p,
initialized,
config.Root,
config.State,
map[string]string{
plugins.PropertyRootDir: filepath.Join(config.Root, id),
plugins.PropertyStateDir: filepath.Join(config.State, id),
plugins.PropertyGRPCAddress: config.GRPC.Address,
plugins.PropertyTTRPCAddress: config.TTRPC.Address,
},
)
initContext.Address = config.GRPC.Address
initContext.TTRPCAddress = config.TTRPC.Address
initContext.RegisterReadiness = func() func() {
atomic.StoreInt32(&mustSucceed, 1)
return s.RegisterReadiness()
@ -259,7 +261,7 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
// load the plugin specific configuration if it is provided
if p.Config != nil {
pc, err := config.Decode(ctx, p)
pc, err := config.Decode(ctx, id, p.Config)
if err != nil {
return nil, err
}
@ -426,7 +428,7 @@ func (s *Server) Wait() {
// LoadPlugins loads all plugins into containerd and generates an ordered graph
// of all plugins.
func LoadPlugins(ctx context.Context, config *srvconfig.Config) ([]*plugin.Registration, error) {
func LoadPlugins(ctx context.Context, config *srvconfig.Config) ([]plugin.Registration, error) {
// load all plugins into containerd
path := config.PluginDir
if path == "" {
@ -436,12 +438,13 @@ func LoadPlugins(ctx context.Context, config *srvconfig.Config) ([]*plugin.Regis
return nil, err
}
// load additional plugins that don't automatically register themselves
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.ContentPlugin,
ID: "content",
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
ic.Meta.Exports["root"] = ic.Root
return local.NewStore(ic.Root)
root := ic.Properties[plugins.PropertyRootDir]
ic.Meta.Exports["root"] = root
return local.NewStore(root)
},
})
@ -486,7 +489,7 @@ func LoadPlugins(ctx context.Context, config *srvconfig.Config) ([]*plugin.Regis
p = platforms.DefaultSpec()
}
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: t,
ID: name,
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
@ -504,7 +507,7 @@ func LoadPlugins(ctx context.Context, config *srvconfig.Config) ([]*plugin.Regis
filter := srvconfig.V2DisabledFilter
// return the ordered graph for plugins
return plugin.Graph(filter(config.DisabledPlugins)), nil
return registry.Graph(filter(config.DisabledPlugins)), nil
}
type proxyClients struct {

View File

@ -21,6 +21,7 @@ import (
"testing"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
srvconfig "github.com/containerd/containerd/services/server/config"
"github.com/stretchr/testify/assert"
)
@ -57,8 +58,8 @@ func TestCreateTopLevelDirectoriesWithEmptyRootPath(t *testing.T) {
}
func TestMigration(t *testing.T) {
plugin.Reset()
defer plugin.Reset()
registry.Reset()
defer registry.Reset()
version := srvconfig.CurrentConfigVersion - 1
@ -67,7 +68,7 @@ func TestMigration(t *testing.T) {
NotMigrated string `toml:"notmigrated"`
}
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: "io.containerd.test",
ID: "t1",
Config: &testConfig{},
@ -86,7 +87,7 @@ func TestMigration(t *testing.T) {
return nil, nil
},
})
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: "io.containerd.new",
Requires: []plugin.Type{
"io.containerd.test", // Ensure this test runs second

View File

@ -24,6 +24,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/containerd/services"
@ -33,7 +34,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "snapshots",
Requires: []plugin.Type{

View File

@ -19,12 +19,13 @@ package snapshots
import (
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/services"
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.ServicePlugin,
ID: services.SnapshotsService,
Requires: []plugin.Type{

View File

@ -24,6 +24,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/pkg/streaming"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/protobuf"
ptypes "github.com/containerd/containerd/protobuf/types"
@ -42,7 +43,7 @@ func init() {
panic(err)
}
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "streaming",
Requires: []plugin.Type{

View File

@ -19,6 +19,7 @@ package tasks
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"os"
@ -41,6 +42,7 @@ import (
"github.com/containerd/containerd/pkg/rdt"
"github.com/containerd/containerd/pkg/timeout"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/protobuf/proto"
@ -75,7 +77,7 @@ type Config struct {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.ServicePlugin,
ID: services.TasksService,
Requires: tasksServiceRequires,
@ -106,7 +108,7 @@ func initFunc(ic *plugin.InitContext) (interface{}, error) {
monitor, err := ic.Get(plugins.TaskMonitorPlugin)
if err != nil {
if !errdefs.IsNotFound(err) {
if !errors.Is(err, plugin.ErrPluginNotFound) {
return nil, err
}
monitor = runtime.NewNoopMonitor()

View File

@ -22,6 +22,7 @@ import (
api "github.com/containerd/containerd/api/services/tasks/v1"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/containerd/services"
@ -33,7 +34,7 @@ var (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "tasks",
Requires: []plugin.Type{

View File

@ -26,6 +26,7 @@ import (
"github.com/containerd/containerd/pkg/transfer"
tplugins "github.com/containerd/containerd/pkg/transfer/plugins"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/log"
@ -37,7 +38,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "transfer",
Requires: []plugin.Type{

View File

@ -21,6 +21,7 @@ import (
api "github.com/containerd/containerd/api/services/version/v1"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
ptypes "github.com/containerd/containerd/protobuf/types"
ctrdversion "github.com/containerd/containerd/version"
@ -30,7 +31,7 @@ import (
var _ api.VersionServer = &service{}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.GRPCPlugin,
ID: "version",
InitFn: initFunc,

View File

@ -21,6 +21,7 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/snapshots/blockfile"
)
@ -45,7 +46,7 @@ type Config struct {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.SnapshotPlugin,
ID: "blockfile",
Config: &Config{},
@ -58,7 +59,7 @@ func init() {
}
var opts []blockfile.Opt
root := ic.Root
root := ic.Properties[plugins.PropertyRootDir]
if len(config.RootPath) != 0 {
root = config.RootPath
}

View File

@ -25,6 +25,7 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/snapshots/btrfs"
)
@ -36,7 +37,7 @@ type Config struct {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
ID: "btrfs",
Type: plugins.SnapshotPlugin,
Config: &Config{},
@ -48,7 +49,7 @@ func init() {
return nil, errors.New("invalid btrfs configuration")
}
root := ic.Root
root := ic.Properties[plugins.PropertyRootDir]
if len(config.RootPath) != 0 {
root = config.RootPath
}

View File

@ -24,12 +24,13 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/snapshots/devmapper"
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.SnapshotPlugin,
ID: "devmapper",
Config: &devmapper.Config{},
@ -46,7 +47,7 @@ func init() {
}
if config.RootPath == "" {
config.RootPath = ic.Root
config.RootPath = ic.Properties[plugins.PropertyRootDir]
}
return devmapper.NewSnapshotter(ic.Context, config)

View File

@ -37,6 +37,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/snapshots"
"github.com/containerd/containerd/snapshots/storage"
@ -46,7 +47,7 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.SnapshotPlugin,
ID: "windows-lcow",
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
@ -54,7 +55,7 @@ func init() {
OS: "linux",
Architecture: runtime.GOARCH,
})
return NewSnapshotter(ic.Root)
return NewSnapshotter(ic.Properties[plugins.PropertyRootDir])
},
})
}

View File

@ -21,6 +21,7 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/snapshots/native"
)
@ -32,7 +33,7 @@ type Config struct {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.SnapshotPlugin,
ID: "native",
Config: &Config{},
@ -44,7 +45,7 @@ func init() {
return nil, errors.New("invalid native configuration")
}
root := ic.Root
root := ic.Properties[plugins.PropertyRootDir]
if len(config.RootPath) != 0 {
root = config.RootPath
}

View File

@ -23,6 +23,7 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/snapshots/overlay"
"github.com/containerd/containerd/snapshots/overlay/overlayutils"
@ -50,7 +51,7 @@ type Config struct {
}
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.SnapshotPlugin,
ID: "overlayfs",
Config: &Config{},
@ -62,7 +63,7 @@ func init() {
return nil, errors.New("invalid overlay configuration")
}
root := ic.Root
root := ic.Properties[plugins.PropertyRootDir]
if config.RootPath != "" {
root = config.RootPath
}

View File

@ -38,6 +38,7 @@ import (
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/snapshots"
"github.com/containerd/containerd/snapshots/storage"
@ -47,12 +48,12 @@ import (
)
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
Type: plugins.SnapshotPlugin,
ID: "windows",
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
ic.Meta.Platforms = []ocispec.Platform{platforms.DefaultSpec()}
return NewSnapshotter(ic.Root)
return NewSnapshotter(ic.Properties[plugins.PropertyRootDir])
},
})
}

View File

@ -25,6 +25,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/plugin/registry"
"github.com/containerd/containerd/plugins"
"github.com/containerd/containerd/tracing"
"github.com/containerd/log"
@ -42,7 +43,7 @@ import (
const exporterPlugin = "otlp"
func init() {
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
ID: exporterPlugin,
Type: plugins.TracingProcessorPlugin,
Config: &OTLPConfig{},
@ -55,7 +56,7 @@ func init() {
return trace.NewBatchSpanProcessor(exp), nil
},
})
plugin.Register(&plugin.Registration{
registry.Register(&plugin.Registration{
ID: "tracing",
Type: plugins.InternalPlugin,
Requires: []plugin.Type{