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  }