github.com/iaintshine/docker@v1.8.2/pkg/plugins/discovery.go (about)

     1  package plugins
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net/url"
     9  	"os"
    10  	"path/filepath"
    11  	"strings"
    12  )
    13  
    14  var (
    15  	ErrNotFound = errors.New("Plugin not found")
    16  	socketsPath = "/run/docker/plugins"
    17  	specsPaths  = []string{"/etc/docker/plugins", "/usr/lib/docker/plugins"}
    18  )
    19  
    20  type Registry interface {
    21  	Plugins() ([]*Plugin, error)
    22  	Plugin(name string) (*Plugin, error)
    23  }
    24  
    25  type LocalRegistry struct{}
    26  
    27  func newLocalRegistry() LocalRegistry {
    28  	return LocalRegistry{}
    29  }
    30  
    31  func (l *LocalRegistry) Plugin(name string) (*Plugin, error) {
    32  	socketpaths := pluginPaths(socketsPath, name, ".sock")
    33  
    34  	for _, p := range socketpaths {
    35  		if fi, err := os.Stat(p); err == nil && fi.Mode()&os.ModeSocket != 0 {
    36  			return newLocalPlugin(name, "unix://"+p), nil
    37  		}
    38  	}
    39  
    40  	var txtspecpaths []string
    41  	for _, p := range specsPaths {
    42  		txtspecpaths = append(txtspecpaths, pluginPaths(p, name, ".spec")...)
    43  		txtspecpaths = append(txtspecpaths, pluginPaths(p, name, ".json")...)
    44  	}
    45  
    46  	for _, p := range txtspecpaths {
    47  		if _, err := os.Stat(p); err == nil {
    48  			if strings.HasSuffix(p, ".json") {
    49  				return readPluginJSONInfo(name, p)
    50  			}
    51  			return readPluginInfo(name, p)
    52  		}
    53  	}
    54  	return nil, ErrNotFound
    55  }
    56  
    57  func readPluginInfo(name, path string) (*Plugin, error) {
    58  	content, err := ioutil.ReadFile(path)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	addr := strings.TrimSpace(string(content))
    63  
    64  	u, err := url.Parse(addr)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	if len(u.Scheme) == 0 {
    70  		return nil, fmt.Errorf("Unknown protocol")
    71  	}
    72  
    73  	return newLocalPlugin(name, addr), nil
    74  }
    75  
    76  func readPluginJSONInfo(name, path string) (*Plugin, error) {
    77  	f, err := os.Open(path)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	defer f.Close()
    82  
    83  	var p Plugin
    84  	if err := json.NewDecoder(f).Decode(&p); err != nil {
    85  		return nil, err
    86  	}
    87  	p.Name = name
    88  	if len(p.TLSConfig.CAFile) == 0 {
    89  		p.TLSConfig.InsecureSkipVerify = true
    90  	}
    91  
    92  	return &p, nil
    93  }
    94  
    95  func pluginPaths(base, name, ext string) []string {
    96  	return []string{
    97  		filepath.Join(base, name+ext),
    98  		filepath.Join(base, name, name+ext),
    99  	}
   100  }