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