github.com/codemac/docker@v1.2.1-0.20150518222241-6a18412d5b9c/pkg/plugins/plugins.go (about) 1 package plugins 2 3 import ( 4 "errors" 5 "sync" 6 7 "github.com/Sirupsen/logrus" 8 ) 9 10 var ( 11 ErrNotImplements = errors.New("Plugin does not implement the requested driver") 12 ) 13 14 type plugins struct { 15 sync.Mutex 16 plugins map[string]*Plugin 17 } 18 19 var ( 20 storage = plugins{plugins: make(map[string]*Plugin)} 21 extpointHandlers = make(map[string]func(string, *Client)) 22 ) 23 24 type Manifest struct { 25 Implements []string 26 } 27 28 type Plugin struct { 29 Name string 30 Addr string 31 Client *Client 32 Manifest *Manifest 33 } 34 35 func (p *Plugin) activate() error { 36 m := new(Manifest) 37 p.Client = NewClient(p.Addr) 38 err := p.Client.Call("Plugin.Activate", nil, m) 39 if err != nil { 40 return err 41 } 42 43 logrus.Debugf("%s's manifest: %v", p.Name, m) 44 p.Manifest = m 45 for _, iface := range m.Implements { 46 handler, handled := extpointHandlers[iface] 47 if !handled { 48 continue 49 } 50 handler(p.Name, p.Client) 51 } 52 return nil 53 } 54 55 func load(name string) (*Plugin, error) { 56 registry := newLocalRegistry("") 57 pl, err := registry.Plugin(name) 58 if err != nil { 59 return nil, err 60 } 61 if err := pl.activate(); err != nil { 62 return nil, err 63 } 64 return pl, nil 65 } 66 67 func get(name string) (*Plugin, error) { 68 storage.Lock() 69 defer storage.Unlock() 70 pl, ok := storage.plugins[name] 71 if ok { 72 return pl, nil 73 } 74 pl, err := load(name) 75 if err != nil { 76 return nil, err 77 } 78 79 logrus.Debugf("Plugin: %v", pl) 80 storage.plugins[name] = pl 81 return pl, nil 82 } 83 84 func Get(name, imp string) (*Plugin, error) { 85 pl, err := get(name) 86 if err != nil { 87 return nil, err 88 } 89 for _, driver := range pl.Manifest.Implements { 90 logrus.Debugf("%s implements: %s", name, driver) 91 if driver == imp { 92 return pl, nil 93 } 94 } 95 return nil, ErrNotImplements 96 } 97 98 func Handle(iface string, fn func(string, *Client)) { 99 extpointHandlers[iface] = fn 100 }