containerd/plugin/plugin.go
Michael Crosby 94e7f8e943 Setup plugin ids and dependencies
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
2017-06-14 16:17:20 -07:00

101 lines
1.9 KiB
Go

package plugin
import (
"errors"
"fmt"
"sync"
"google.golang.org/grpc"
)
var (
ErrNoPluginType = errors.New("plugin: no type")
ErrNoPluginID = errors.New("plugin: no id")
)
type PluginType string
const (
RuntimePlugin PluginType = "io.containerd.runtime.v1"
GRPCPlugin PluginType = "io.containerd.grpc.v1"
SnapshotPlugin PluginType = "io.containerd.snapshotter.v1"
TaskMonitorPlugin PluginType = "io.containerd.monitor.v1"
DiffPlugin PluginType = "io.containerd.differ.v1"
MetadataPlugin PluginType = "io.containerd.metadata.v1"
ContentPlugin PluginType = "io.containerd.content.v1"
)
type Registration struct {
Type PluginType
ID string
Config interface{}
Requires []PluginType
Init func(*InitContext) (interface{}, error)
added bool
}
func (r *Registration) URI() string {
return fmt.Sprintf("%s.%s", r.Type, r.ID)
}
type Service interface {
Register(*grpc.Server) error
}
var register = struct {
sync.Mutex
r []*Registration
}{}
// Load loads all plugins at the provided path into containerd
func Load(path string) (err error) {
defer func() {
if v := recover(); v != nil {
rerr, ok := v.(error)
if !ok {
rerr = fmt.Errorf("%s", v)
}
err = rerr
}
}()
return loadPlugins(path)
}
func Register(r *Registration) {
register.Lock()
defer register.Unlock()
if r.Type == "" {
panic(ErrNoPluginType)
}
if r.ID == "" {
panic(ErrNoPluginID)
}
register.r = append(register.r, r)
}
func Graph() (ordered []*Registration) {
for _, r := range register.r {
children(r.Requires, &ordered)
if !r.added {
ordered = append(ordered, r)
r.added = true
}
}
return ordered
}
func children(types []PluginType, ordered *[]*Registration) {
for _, t := range types {
for _, r := range register.r {
if r.Type == t {
children(r.Requires, ordered)
if !r.added {
*ordered = append(*ordered, r)
r.added = true
}
}
}
}
}