2017-03-07 01:23:00 +00:00
|
|
|
package plugin
|
2017-02-16 22:45:13 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
|
2017-04-03 20:14:15 +00:00
|
|
|
"github.com/containerd/containerd"
|
|
|
|
"github.com/containerd/containerd/content"
|
|
|
|
"github.com/containerd/containerd/snapshot"
|
2017-02-16 22:45:13 +00:00
|
|
|
|
|
|
|
"golang.org/x/net/context"
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
)
|
|
|
|
|
|
|
|
type PluginType int
|
|
|
|
|
|
|
|
const (
|
|
|
|
RuntimePlugin PluginType = iota + 1
|
|
|
|
GRPCPlugin
|
2017-03-07 22:55:36 +00:00
|
|
|
SnapshotPlugin
|
2017-03-21 18:39:44 +00:00
|
|
|
ContainerMonitorPlugin
|
2017-02-16 22:45:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Registration struct {
|
|
|
|
Type PluginType
|
|
|
|
Config interface{}
|
|
|
|
Init func(*InitContext) (interface{}, error)
|
|
|
|
}
|
|
|
|
|
2017-03-21 18:39:44 +00:00
|
|
|
// TODO(@crosbymichael): how to we keep this struct from growing but support dependency injection for loaded plugins?
|
2017-02-16 22:45:13 +00:00
|
|
|
type InitContext struct {
|
2017-03-07 22:55:36 +00:00
|
|
|
Root string
|
|
|
|
State string
|
|
|
|
Runtimes map[string]containerd.Runtime
|
|
|
|
Store *content.Store
|
|
|
|
Snapshotter snapshot.Snapshotter
|
|
|
|
Config interface{}
|
|
|
|
Context context.Context
|
2017-03-21 18:39:44 +00:00
|
|
|
Monitor ContainerMonitor
|
2017-02-16 22:45:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Service interface {
|
|
|
|
Register(*grpc.Server) error
|
|
|
|
}
|
|
|
|
|
|
|
|
var register = struct {
|
|
|
|
sync.Mutex
|
|
|
|
r map[string]*Registration
|
|
|
|
}{
|
|
|
|
r: make(map[string]*Registration),
|
|
|
|
}
|
|
|
|
|
2017-02-22 00:35:42 +00:00
|
|
|
// Load loads all plugins at the provided path into containerd
|
2017-02-16 22:45:13 +00:00
|
|
|
func Load(path string) (err error) {
|
|
|
|
defer func() {
|
|
|
|
if v := recover(); v != nil {
|
|
|
|
rerr, ok := v.(error)
|
|
|
|
if !ok {
|
2017-02-22 00:35:42 +00:00
|
|
|
rerr = fmt.Errorf("%s", v)
|
2017-02-16 22:45:13 +00:00
|
|
|
}
|
|
|
|
err = rerr
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
return loadPlugins(path)
|
|
|
|
}
|
|
|
|
|
|
|
|
func Register(name string, r *Registration) error {
|
|
|
|
register.Lock()
|
|
|
|
defer register.Unlock()
|
|
|
|
if _, ok := register.r[name]; ok {
|
|
|
|
return fmt.Errorf("plugin already registered as %q", name)
|
|
|
|
}
|
|
|
|
register.r[name] = r
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func Registrations() map[string]*Registration {
|
|
|
|
return register.r
|
|
|
|
}
|