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  }