mirror of
https://github.com/linuxkit/linuxkit.git
synced 2026-01-17 04:22:29 +00:00
- The tools directory ideally should not contain source code - Removes double vendoring of packagages - Makes it easer to hook the build into the top-level Makefile Eventually, the plugin should be moved to the infrakit repo. Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
107 lines
2.3 KiB
Go
107 lines
2.3 KiB
Go
package discovery
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
|
|
log "github.com/Sirupsen/logrus"
|
|
"github.com/docker/infrakit/pkg/plugin"
|
|
)
|
|
|
|
type errNotUnixSocket string
|
|
|
|
func (e errNotUnixSocket) Error() string {
|
|
return string(e)
|
|
}
|
|
|
|
// IsErrNotUnixSocket returns true if the error is due to the file not being a valid unix socket.
|
|
func IsErrNotUnixSocket(e error) bool {
|
|
_, is := e.(errNotUnixSocket)
|
|
return is
|
|
}
|
|
|
|
type dirPluginDiscovery struct {
|
|
dir string
|
|
lock sync.Mutex
|
|
}
|
|
|
|
// Find returns a plugin by name
|
|
func (r *dirPluginDiscovery) Find(name plugin.Name) (*plugin.Endpoint, error) {
|
|
lookup, _ := name.GetLookupAndType()
|
|
plugins, err := r.List()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
p, exists := plugins[lookup]
|
|
if !exists {
|
|
return nil, fmt.Errorf("Plugin not found: %s (looked up using %s)", name, lookup)
|
|
}
|
|
|
|
return p, nil
|
|
}
|
|
|
|
// newDirPluginDiscovery creates a registry instance with the given file directory path.
|
|
func newDirPluginDiscovery(dir string) (*dirPluginDiscovery, error) {
|
|
d := &dirPluginDiscovery{dir: dir}
|
|
|
|
// Perform a dummy read to catch obvious issues early (such as the directory not existing).
|
|
_, err := d.List()
|
|
return d, err
|
|
}
|
|
|
|
func (r *dirPluginDiscovery) dirLookup(entry os.FileInfo) (*plugin.Endpoint, error) {
|
|
if entry.Mode()&os.ModeSocket != 0 {
|
|
socketPath := filepath.Join(r.dir, entry.Name())
|
|
return &plugin.Endpoint{
|
|
Protocol: "unix",
|
|
Address: socketPath,
|
|
Name: entry.Name(),
|
|
}, nil
|
|
}
|
|
|
|
return nil, errNotUnixSocket(fmt.Sprintf("File is not a socket: %s", entry))
|
|
}
|
|
|
|
// List returns a list of plugins known, keyed by the name
|
|
func (r *dirPluginDiscovery) List() (map[string]*plugin.Endpoint, error) {
|
|
|
|
r.lock.Lock()
|
|
defer r.lock.Unlock()
|
|
|
|
log.Debugln("Opening:", r.dir)
|
|
entries, err := ioutil.ReadDir(r.dir)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
plugins := map[string]*plugin.Endpoint{}
|
|
|
|
for _, entry := range entries {
|
|
if !entry.IsDir() {
|
|
|
|
instance, err := r.dirLookup(entry)
|
|
|
|
if err != nil {
|
|
if !IsErrNotUnixSocket(err) {
|
|
log.Warningln("Loading plugin err=", err)
|
|
}
|
|
continue
|
|
}
|
|
|
|
if instance == nil {
|
|
log.Warningln("Plugin in nil=")
|
|
continue
|
|
}
|
|
|
|
log.Debugln("Discovered plugin at", instance.Address)
|
|
plugins[instance.Name] = instance
|
|
}
|
|
}
|
|
|
|
return plugins, nil
|
|
}
|