github.com/wulonghui/docker@v1.8.0-rc2/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 }