@@ -20,7 +20,6 @@ import (
2020 "context"
2121 "errors"
2222 "fmt"
23- "sync"
2423)
2524
2625var (
3433 // this allows the plugin loader differentiate between a plugin which is configured
3534 // not to load and one that fails to load.
3635 ErrSkipPlugin = errors .New ("skip plugin" )
36+ // ErrPluginInitialized is used when a plugin is already initialized
37+ ErrPluginInitialized = errors .New ("plugin: already initialized" )
38+ // ErrPluginNotFound is used when a plugin is looked up but not found
39+ ErrPluginNotFound = errors .New ("plugin: not found" )
3740
3841 // ErrInvalidRequires will be thrown if the requirements for a plugin are
3942 // defined in an invalid manner.
@@ -65,8 +68,6 @@ type Registration struct {
6568 // context are passed in. The init function may modify the registration to
6669 // add exports, capabilities and platform support declarations.
6770 InitFn func (* InitContext ) (interface {}, error )
68- // Disable the plugin from loading
69- Disable bool
7071
7172 // ConfigMigration allows a plugin to migrate configurations from an older
7273 // version to handle plugin renames or moving of features from one plugin
@@ -79,12 +80,12 @@ type Registration struct {
7980}
8081
8182// Init the registered plugin
82- func (r * Registration ) Init (ic * InitContext ) * Plugin {
83+ func (r Registration ) Init (ic * InitContext ) * Plugin {
8384 p , err := r .InitFn (ic )
8485 return & Plugin {
8586 Registration : r ,
8687 Config : ic .Config ,
87- Meta : ic .Meta ,
88+ Meta : * ic .Meta ,
8889 instance : p ,
8990 err : err ,
9091 }
@@ -95,11 +96,6 @@ func (r *Registration) URI() string {
9596 return r .Type .String () + "." + r .ID
9697}
9798
98- var register = struct {
99- sync.RWMutex
100- r []* Registration
101- }{}
102-
10399// Load loads all plugins at the provided path into containerd.
104100//
105101// Load is currently only implemented on non-static, non-gccgo builds for amd64
@@ -118,87 +114,81 @@ func Load(path string) (err error) {
118114 return loadPlugins (path )
119115}
120116
121- // Register allows plugins to register
122- func Register (r * Registration ) {
123- register .Lock ()
124- defer register .Unlock ()
125-
126- if r .Type == "" {
127- panic (ErrNoType )
128- }
129- if r .ID == "" {
130- panic (ErrNoPluginID )
131- }
132- if err := checkUnique (r ); err != nil {
133- panic (err )
134- }
135-
136- for _ , requires := range r .Requires {
137- if requires == "*" && len (r .Requires ) != 1 {
138- panic (ErrInvalidRequires )
139- }
140- }
141-
142- register .r = append (register .r , r )
143- }
144-
145- // Reset removes all global registrations
146- func Reset () {
147- register .Lock ()
148- defer register .Unlock ()
149- register .r = nil
150- }
151-
152- func checkUnique (r * Registration ) error {
153- for _ , registered := range register .r {
154- if r .URI () == registered .URI () {
155- return fmt .Errorf ("%s: %w" , r .URI (), ErrIDRegistered )
156- }
157- }
158- return nil
159- }
160-
161117// DisableFilter filters out disabled plugins
162118type DisableFilter func (r * Registration ) bool
163119
164- // Graph returns an ordered list of registered plugins for initialization.
165- // Plugins in disableList specified by id will be disabled.
166- func Graph (filter DisableFilter ) (ordered []* Registration ) {
167- register .RLock ()
168- defer register .RUnlock ()
169-
170- for _ , r := range register .r {
120+ // Registry is list of registrations which can be registered to and
121+ // produce a filtered and ordered output.
122+ // The Registry itself is immutable and the list will be copied
123+ // and appeneded to a new registry when new items are registered.
124+ type Registry []* Registration
125+
126+ // Graph computes the ordered list of registrations based on their dependencies,
127+ // filtering out any plugins which match the provided filter.
128+ func (registry Registry ) Graph (filter DisableFilter ) []Registration {
129+ disabled := map [* Registration ]bool {}
130+ for _ , r := range registry {
171131 if filter (r ) {
172- r . Disable = true
132+ disabled [ r ] = true
173133 }
174134 }
175135
136+ ordered := make ([]Registration , 0 , len (registry )- len (disabled ))
176137 added := map [* Registration ]bool {}
177- for _ , r := range register . r {
178- if r . Disable {
138+ for _ , r := range registry {
139+ if disabled [ r ] {
179140 continue
180141 }
181- children (r , added , & ordered )
142+ children (r , registry , added , disabled , & ordered )
182143 if ! added [r ] {
183- ordered = append (ordered , r )
144+ ordered = append (ordered , * r )
184145 added [r ] = true
185146 }
186147 }
187148 return ordered
188149}
189150
190- func children (reg * Registration , added map [* Registration ]bool , ordered * []* Registration ) {
151+ func children (reg * Registration , registry [] * Registration , added , disabled map [* Registration ]bool , ordered * []Registration ) {
191152 for _ , t := range reg .Requires {
192- for _ , r := range register .r {
193- if ! r .Disable &&
194- r .URI () != reg .URI () &&
195- (t == "*" || r .Type == t ) {
196- children (r , added , ordered )
153+ for _ , r := range registry {
154+ if ! disabled [r ] && r .URI () != reg .URI () && (t == "*" || r .Type == t ) {
155+ children (r , registry , added , disabled , ordered )
197156 if ! added [r ] {
198- * ordered = append (* ordered , r )
157+ * ordered = append (* ordered , * r )
199158 added [r ] = true
200159 }
201160 }
202161 }
203162 }
204163}
164+
165+ // Register adds the registration to a Registry and returns the
166+ // updated Registry, panicking if registration could not succeed.
167+ func (registry Registry ) Register (r * Registration ) Registry {
168+ if r .Type == "" {
169+ panic (ErrNoType )
170+ }
171+ if r .ID == "" {
172+ panic (ErrNoPluginID )
173+ }
174+ if err := checkUnique (registry , r ); err != nil {
175+ panic (err )
176+ }
177+
178+ for _ , requires := range r .Requires {
179+ if requires == "*" && len (r .Requires ) != 1 {
180+ panic (ErrInvalidRequires )
181+ }
182+ }
183+
184+ return append (registry , r )
185+ }
186+
187+ func checkUnique (registry Registry , r * Registration ) error {
188+ for _ , registered := range registry {
189+ if r .URI () == registered .URI () {
190+ return fmt .Errorf ("%s: %w" , r .URI (), ErrIDRegistered )
191+ }
192+ }
193+ return nil
194+ }
0 commit comments