github.com/endophage/docker@v1.4.2-0.20161027011718-242853499895/plugin/backend.go (about) 1 package plugin 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "os" 10 "path/filepath" 11 12 "github.com/Sirupsen/logrus" 13 "github.com/docker/docker/api/types" 14 "github.com/docker/docker/pkg/archive" 15 "github.com/docker/docker/pkg/stringid" 16 "github.com/docker/docker/plugin/distribution" 17 "github.com/docker/docker/plugin/v2" 18 ) 19 20 // Disable deactivates a plugin, which implies that they cannot be used by containers. 21 func (pm *Manager) Disable(name string) error { 22 p, err := pm.pluginStore.GetByName(name) 23 if err != nil { 24 return err 25 } 26 if err := pm.disable(p); err != nil { 27 return err 28 } 29 pm.pluginEventLogger(p.GetID(), name, "disable") 30 return nil 31 } 32 33 // Enable activates a plugin, which implies that they are ready to be used by containers. 34 func (pm *Manager) Enable(name string) error { 35 p, err := pm.pluginStore.GetByName(name) 36 if err != nil { 37 return err 38 } 39 if err := pm.enable(p, false); err != nil { 40 return err 41 } 42 pm.pluginEventLogger(p.GetID(), name, "enable") 43 return nil 44 } 45 46 // Inspect examines a plugin manifest 47 func (pm *Manager) Inspect(name string) (tp types.Plugin, err error) { 48 p, err := pm.pluginStore.GetByName(name) 49 if err != nil { 50 return tp, err 51 } 52 return p.PluginObj, nil 53 } 54 55 // Pull pulls a plugin and computes the privileges required to install it. 56 func (pm *Manager) Pull(name string, metaHeader http.Header, authConfig *types.AuthConfig) (types.PluginPrivileges, error) { 57 ref, err := distribution.GetRef(name) 58 if err != nil { 59 logrus.Debugf("error in distribution.GetRef: %v", err) 60 return nil, err 61 } 62 name = ref.String() 63 64 if p, _ := pm.pluginStore.GetByName(name); p != nil { 65 logrus.Debugf("plugin already exists") 66 return nil, fmt.Errorf("%s exists", name) 67 } 68 69 pluginID := stringid.GenerateNonCryptoID() 70 71 if err := os.MkdirAll(filepath.Join(pm.libRoot, pluginID), 0755); err != nil { 72 logrus.Debugf("error in MkdirAll: %v", err) 73 return nil, err 74 } 75 76 pd, err := distribution.Pull(ref, pm.registryService, metaHeader, authConfig) 77 if err != nil { 78 logrus.Debugf("error in distribution.Pull(): %v", err) 79 return nil, err 80 } 81 82 if err := distribution.WritePullData(pd, filepath.Join(pm.libRoot, pluginID), true); err != nil { 83 logrus.Debugf("error in distribution.WritePullData(): %v", err) 84 return nil, err 85 } 86 87 tag := distribution.GetTag(ref) 88 p := v2.NewPlugin(ref.Name(), pluginID, pm.runRoot, tag) 89 if err := p.InitPlugin(pm.libRoot); err != nil { 90 return nil, err 91 } 92 pm.pluginStore.Add(p) 93 94 pm.pluginEventLogger(pluginID, name, "pull") 95 return p.ComputePrivileges(), nil 96 } 97 98 // List displays the list of plugins and associated metadata. 99 func (pm *Manager) List() ([]types.Plugin, error) { 100 plugins := pm.pluginStore.GetAll() 101 out := make([]types.Plugin, 0, len(plugins)) 102 for _, p := range plugins { 103 out = append(out, p.PluginObj) 104 } 105 return out, nil 106 } 107 108 // Push pushes a plugin to the store. 109 func (pm *Manager) Push(name string, metaHeader http.Header, authConfig *types.AuthConfig) error { 110 p, err := pm.pluginStore.GetByName(name) 111 if err != nil { 112 return err 113 } 114 dest := filepath.Join(pm.libRoot, p.GetID()) 115 config, err := ioutil.ReadFile(filepath.Join(dest, "manifest.json")) 116 if err != nil { 117 return err 118 } 119 120 var dummy types.Plugin 121 err = json.Unmarshal(config, &dummy) 122 if err != nil { 123 return err 124 } 125 126 rootfs, err := archive.Tar(filepath.Join(dest, "rootfs"), archive.Gzip) 127 if err != nil { 128 return err 129 } 130 defer rootfs.Close() 131 132 _, err = distribution.Push(name, pm.registryService, metaHeader, authConfig, ioutil.NopCloser(bytes.NewReader(config)), rootfs) 133 // XXX: Ignore returning digest for now. 134 // Since digest needs to be written to the ProgressWriter. 135 return err 136 } 137 138 // Remove deletes plugin's root directory. 139 func (pm *Manager) Remove(name string, config *types.PluginRmConfig) error { 140 p, err := pm.pluginStore.GetByName(name) 141 if err != nil { 142 return err 143 } 144 145 if !config.ForceRemove { 146 p.RLock() 147 if p.RefCount > 0 { 148 p.RUnlock() 149 return fmt.Errorf("plugin %s is in use", p.Name()) 150 } 151 p.RUnlock() 152 153 if p.IsEnabled() { 154 return fmt.Errorf("plugin %s is enabled", p.Name()) 155 } 156 } 157 158 if p.IsEnabled() { 159 if err := pm.disable(p); err != nil { 160 logrus.Errorf("failed to disable plugin '%s': %s", p.Name(), err) 161 } 162 } 163 164 pm.pluginStore.Remove(p) 165 pm.pluginEventLogger(p.GetID(), name, "remove") 166 return nil 167 } 168 169 // Set sets plugin args 170 func (pm *Manager) Set(name string, args []string) error { 171 p, err := pm.pluginStore.GetByName(name) 172 if err != nil { 173 return err 174 } 175 return p.Set(args) 176 }