Skip to content

Commit 7aea04c

Browse files
committed
Merge branch 'feature/plugins_api' of https://github.com/airking05/go-dockerclient
2 parents 13ebb77 + 0d072dc commit 7aea04c

File tree

2 files changed

+719
-0
lines changed

2 files changed

+719
-0
lines changed

plugin.go

Lines changed: 399 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,399 @@
1+
// Copyright 2013 go-dockerclient authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package docker
6+
7+
import (
8+
"encoding/json"
9+
ioutil "io/ioutil"
10+
"net/http"
11+
"net/url"
12+
13+
"golang.org/x/net/context"
14+
)
15+
16+
// PluginPrivilege represents a privilege for a plugin.
17+
type PluginPrivilege struct {
18+
Name string `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"`
19+
Description string `json:"Description,omitempty" yaml:"Description,omitempty" toml:"Description,omitempty"`
20+
Value []string `json:"Value,omitempty" yaml:"Value,omitempty" toml:"Value,omitempty"`
21+
}
22+
23+
// InstallPluginOptions specify parameters to the InstallPlugins function.
24+
//
25+
// See https://goo.gl/C4t7Tz for more details.
26+
type InstallPluginOptions struct {
27+
Remote string
28+
Name string
29+
Plugins []PluginPrivilege `qs:"-"`
30+
31+
Auth AuthConfiguration
32+
33+
Context context.Context
34+
}
35+
36+
// InstallPlugins installs a plugin or returns an error in case of failure.
37+
//
38+
// See https://goo.gl/C4t7Tz for more details.
39+
func (c *Client) InstallPlugins(opts InstallPluginOptions) error {
40+
params := make(url.Values)
41+
params.Set("remote", opts.Remote)
42+
if opts.Name != "" {
43+
params.Set("name", opts.Name)
44+
}
45+
path := "/plugins/pull?" + queryString(params)
46+
resp, err := c.do("POST", path, doOptions{
47+
data: opts.Plugins,
48+
context: opts.Context,
49+
})
50+
defer resp.Body.Close()
51+
if err != nil {
52+
return err
53+
}
54+
return nil
55+
}
56+
57+
// PluginSettings stores plugin settings.
58+
//
59+
// See https://goo.gl/C4t7Tz for more details.
60+
type PluginSettings struct {
61+
Env []string `json:"Env,omitempty" yaml:"Env,omitempty" toml:"Env,omitempty"`
62+
Args []string `json:"Args,omitempty" yaml:"Args,omitempty" toml:"Args,omitempty"`
63+
Devices []string `json:"Devices,omitempty" yaml:"Devices,omitempty" toml:"Devices,omitempty"`
64+
}
65+
66+
// PluginInterface stores plugin interface.
67+
//
68+
// See https://goo.gl/C4t7Tz for more details.
69+
type PluginInterface struct {
70+
Types []string `json:"Types,omitempty" yaml:"Types,omitempty" toml:"Types,omitempty"`
71+
Socket string `json:"Socket,omitempty" yaml:"Socket,omitempty" toml:"Socket,omitempty"`
72+
}
73+
74+
// PluginNetwork stores plugin network type.
75+
//
76+
// See https://goo.gl/C4t7Tz for more details.
77+
type PluginNetwork struct {
78+
Type string `json:"Type,omitempty" yaml:"Type,omitempty" toml:"Type,omitempty"`
79+
}
80+
81+
// PluginLinux stores plugin linux setting.
82+
//
83+
// See https://goo.gl/C4t7Tz for more details.
84+
type PluginLinux struct {
85+
Capabilities []string `json:"Capabilities,omitempty" yaml:"Capabilities,omitempty" toml:"Capabilities,omitempty"`
86+
AllowAllDevices bool `json:"AllowAllDevices,omitempty" yaml:"AllowAllDevices,omitempty" toml:"AllowAllDevices,omitempty"`
87+
Devices []PluginLinuxDevices `json:"Devices,omitempty" yaml:"Devices,omitempty" toml:"Devices,omitempty"`
88+
}
89+
90+
// PluginLinuxDevices stores plugin linux device setting.
91+
//
92+
// See https://goo.gl/C4t7Tz for more details.
93+
type PluginLinuxDevices struct {
94+
Name string `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"`
95+
Description string `json:"Documentation,omitempty" yaml:"Documentation,omitempty" toml:"Documentation,omitempty"`
96+
Settable []string `json:"Settable,omitempty" yaml:"Settable,omitempty" toml:"Settable,omitempty"`
97+
Path string `json:"Path,omitempty" yaml:"Path,omitempty" toml:"Path,omitempty"`
98+
}
99+
100+
// PluginEnv stores plugin environment.
101+
//
102+
// See https://goo.gl/C4t7Tz for more details.
103+
type PluginEnv struct {
104+
Name string `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"`
105+
Description string `json:"Description,omitempty" yaml:"Description,omitempty" toml:"Description,omitempty"`
106+
Settable []string `json:"Settable,omitempty" yaml:"Settable,omitempty" toml:"Settable,omitempty"`
107+
Value string `json:"Value,omitempty" yaml:"Value,omitempty" toml:"Value,omitempty"`
108+
}
109+
110+
// PluginArgs stores plugin arguments.
111+
//
112+
// See https://goo.gl/C4t7Tz for more details.
113+
type PluginArgs struct {
114+
Name string `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"`
115+
Description string `json:"Description,omitempty" yaml:"Description,omitempty" toml:"Description,omitempty"`
116+
Settable []string `json:"Settable,omitempty" yaml:"Settable,omitempty" toml:"Settable,omitempty"`
117+
Value []string `json:"Value,omitempty" yaml:"Value,omitempty" toml:"Value,omitempty"`
118+
}
119+
120+
// PluginUser stores plugin user.
121+
//
122+
// See https://goo.gl/C4t7Tz for more details.
123+
type PluginUser struct {
124+
UID int32 `json:"UID,omitempty" yaml:"UID,omitempty" toml:"UID,omitempty"`
125+
GID int32 `json:"GID,omitempty" yaml:"GID,omitempty" toml:"GID,omitempty"`
126+
}
127+
128+
// PluginConfig stores plugin config.
129+
//
130+
// See https://goo.gl/C4t7Tz for more details.
131+
type PluginConfig struct {
132+
Description string `json:"Description,omitempty" yaml:"Description,omitempty" toml:"Description,omitempty"`
133+
Documentation string
134+
Interface PluginInterface `json:"Interface,omitempty" yaml:"Interface,omitempty" toml:"Interface,omitempty"`
135+
Entrypoint []string `json:"Entrypoint,omitempty" yaml:"Entrypoint,omitempty" toml:"Entrypoint,omitempty"`
136+
WorkDir string `json:"WorkDir,omitempty" yaml:"WorkDir,omitempty" toml:"WorkDir,omitempty"`
137+
User PluginUser `json:"User,omitempty" yaml:"User,omitempty" toml:"User,omitempty"`
138+
Network PluginNetwork `json:"Network,omitempty" yaml:"Network,omitempty" toml:"Network,omitempty"`
139+
Linux PluginLinux `json:"Linux,omitempty" yaml:"Linux,omitempty" toml:"Linux,omitempty"`
140+
PropagatedMount string `json:"PropagatedMount,omitempty" yaml:"PropagatedMount,omitempty" toml:"PropagatedMount,omitempty"`
141+
Mounts []Mount `json:"Mounts,omitempty" yaml:"Mounts,omitempty" toml:"Mounts,omitempty"`
142+
Env []PluginEnv `json:"Env,omitempty" yaml:"Env,omitempty" toml:"Env,omitempty"`
143+
Args PluginArgs `json:"Args,omitempty" yaml:"Args,omitempty" toml:"Args,omitempty"`
144+
}
145+
146+
// PluginDetail specify results from the ListPlugins function.
147+
//
148+
// See https://goo.gl/C4t7Tz for more details.
149+
type PluginDetail struct {
150+
ID string `json:"Id,omitempty" yaml:"Id,omitempty" toml:"Id,omitempty"`
151+
Name string `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"`
152+
Tag string `json:"Tag,omitempty" yaml:"Tag,omitempty" toml:"Tag,omitempty"`
153+
Active bool `json:"Active,omitempty" yaml:"Active,omitempty" toml:"Active,omitempty"`
154+
Settings PluginSettings `json:"Settings,omitempty" yaml:"Settings,omitempty" toml:"Settings,omitempty"`
155+
Config PluginConfig `json:"Config,omitempty" yaml:"Config,omitempty" toml:"Config,omitempty"`
156+
}
157+
158+
// ListPlugins returns pluginDetails or an error.
159+
//
160+
// See https://goo.gl/C4t7Tz for more details.
161+
func (c *Client) ListPlugins(ctx context.Context) ([]PluginDetail, error) {
162+
resp, err := c.do("GET", "/plugins", doOptions{
163+
context:ctx,
164+
165+
})
166+
if err != nil {
167+
return nil, err
168+
}
169+
defer resp.Body.Close()
170+
pluginDetails := make([]PluginDetail, 0)
171+
if err := json.NewDecoder(resp.Body).Decode(&pluginDetails); err != nil {
172+
return nil, err
173+
}
174+
return pluginDetails, nil
175+
}
176+
177+
// GetPluginPrivileges returns pulginPrivileges or an error.
178+
//
179+
// See https://goo.gl/C4t7Tz for more details.
180+
func (c *Client) GetPluginPrivileges(name string,ctx context.Context) ([]PluginPrivilege, error) {
181+
resp, err := c.do("GET", "/plugins/privileges?remote="+name, doOptions{
182+
context:ctx,
183+
})
184+
if err != nil {
185+
return nil, err
186+
}
187+
defer resp.Body.Close()
188+
var pluginPrivileges []PluginPrivilege
189+
if err := json.NewDecoder(resp.Body).Decode(&pluginPrivileges); err != nil {
190+
return nil, err
191+
}
192+
return pluginPrivileges, nil
193+
}
194+
195+
// InspectPlugins returns a pluginDetail or an error.
196+
//
197+
// See https://goo.gl/C4t7Tz for more details.
198+
func (c *Client) InspectPlugins(name string, ctx context.Context) (*PluginDetail, error) {
199+
resp, err := c.do("GET", "/plugins/"+name+"/json", doOptions{
200+
context:ctx,
201+
})
202+
if err != nil {
203+
return nil, err
204+
}
205+
defer resp.Body.Close()
206+
if err != nil {
207+
if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
208+
return nil, &NoSuchPlugin{ID: name}
209+
}
210+
return nil, err
211+
}
212+
resp.Body.Close()
213+
var pluginDetail PluginDetail
214+
if err := json.NewDecoder(resp.Body).Decode(&pluginDetail); err != nil {
215+
return nil, err
216+
}
217+
return &pluginDetail, nil
218+
}
219+
220+
// RemovePluginOptions specify parameters to the RemovePlugin function.
221+
//
222+
// See https://goo.gl/C4t7Tz for more details.
223+
type RemovePluginOptions struct {
224+
// The Name of the plugin.
225+
Name string `qs:"-"`
226+
227+
Force bool `qs:"force"`
228+
Context context.Context
229+
}
230+
231+
// RemovePlugin returns a PluginDetail or an error.
232+
//
233+
// See https://goo.gl/C4t7Tz for more details.
234+
func (c *Client) RemovePlugin(opts RemovePluginOptions) (*PluginDetail, error) {
235+
path := "/plugins/" + opts.Name + "?" + queryString(opts)
236+
resp, err := c.do("DELETE", path, doOptions{context: opts.Context})
237+
if err != nil {
238+
return nil, err
239+
}
240+
defer resp.Body.Close()
241+
if err != nil {
242+
if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
243+
return nil, &NoSuchPlugin{ID: opts.Name}
244+
}
245+
return nil, err
246+
}
247+
resp.Body.Close()
248+
var pluginDetail PluginDetail
249+
if err := json.NewDecoder(resp.Body).Decode(&pluginDetail); err != nil {
250+
return nil, err
251+
}
252+
return &pluginDetail, nil
253+
}
254+
255+
// EnablePluginOptions specify parameters to the EnablePlugin function.
256+
//
257+
// See https://goo.gl/C4t7Tz for more details.
258+
type EnablePluginOptions struct {
259+
// The Name of the plugin.
260+
Name string `qs:"-"`
261+
Timeout int64 `qs:"timeout"`
262+
263+
Context context.Context
264+
}
265+
266+
// EnablePlugin enables plugin that opts point or returns an error.
267+
//
268+
// See https://goo.gl/C4t7Tz for more details.
269+
func (c *Client) EnablePlugin(opts EnablePluginOptions) error {
270+
path := "/plugins/" + opts.Name + "/enable?" + queryString(opts)
271+
resp, err := c.do("POST", path, doOptions{context: opts.Context})
272+
defer resp.Body.Close()
273+
if err != nil {
274+
return err
275+
}
276+
resp.Body.Close()
277+
return nil
278+
}
279+
280+
// DisablePluginOptions specify parameters to the DisablePlugin function.
281+
//
282+
// See https://goo.gl/C4t7Tz for more details.
283+
type DisablePluginOptions struct {
284+
// The Name of the plugin.
285+
Name string `qs:"-"`
286+
287+
Context context.Context
288+
}
289+
290+
// DisablePlugin disables plugin that opts point or returns an error.
291+
//
292+
// See https://goo.gl/C4t7Tz for more details.
293+
func (c *Client) DisablePlugin(opts DisablePluginOptions) error {
294+
path := "/plugins/" + opts.Name + "/disable"
295+
resp, err := c.do("POST", path, doOptions{context: opts.Context})
296+
defer resp.Body.Close()
297+
if err != nil {
298+
return err
299+
}
300+
resp.Body.Close()
301+
return nil
302+
}
303+
304+
// CreatePluginOptions specify parameters to the CreatePlugin function.
305+
//
306+
// See https://goo.gl/C4t7Tz for more details.
307+
type CreatePluginOptions struct {
308+
// The Name of the plugin.
309+
Name string `qs:"name"`
310+
// Path to tar containing plugin
311+
Path string `qs:"-"`
312+
313+
Context context.Context
314+
}
315+
316+
// CreatePlugin creates plugin that opts point or returns an error.
317+
//
318+
// See https://goo.gl/C4t7Tz for more details.
319+
func (c *Client) CreatePlugin(opts CreatePluginOptions) (string, error) {
320+
path := "/plugins/create?" + queryString(opts)
321+
resp, err := c.do("POST", path, doOptions{
322+
data: opts.Path,
323+
context: opts.Context})
324+
defer resp.Body.Close()
325+
if err != nil {
326+
return "", err
327+
}
328+
containerNameBytes, err := ioutil.ReadAll(resp.Body)
329+
if err != nil {
330+
return "", err
331+
}
332+
return string(containerNameBytes), nil
333+
}
334+
335+
// PushPluginOptions specify parameters to PushPlugin function.
336+
//
337+
// See https://goo.gl/C4t7Tz for more details.
338+
type PushPluginOptions struct {
339+
// The Name of the plugin.
340+
Name string
341+
342+
Context context.Context
343+
}
344+
345+
// PushPlugin pushes plugin that opts point or returns an error.
346+
//
347+
// See https://goo.gl/C4t7Tz for more details.
348+
func (c *Client) PushPlugin(opts PushPluginOptions) error {
349+
path := "/plugins/" + opts.Name + "/push"
350+
resp, err := c.do("POST", path, doOptions{context: opts.Context})
351+
defer resp.Body.Close()
352+
if err != nil {
353+
return err
354+
}
355+
return nil
356+
}
357+
358+
// ConfigurePluginOptions specify parameters to the ConfigurePlugin
359+
//
360+
// See https://goo.gl/C4t7Tz for more details.
361+
type ConfigurePluginOptions struct {
362+
// The Name of the plugin.
363+
Name string `qs:"name"`
364+
Envs []string
365+
366+
Context context.Context
367+
}
368+
369+
// ConfigurePlugin configures plugin that opts point or returns an error.
370+
//
371+
// See https://goo.gl/C4t7Tz for more details.
372+
func (c *Client) ConfigurePlugin(opts ConfigurePluginOptions) error {
373+
path := "/plugins/" + opts.Name + "/set"
374+
resp, err := c.do("POST", path, doOptions{
375+
data: opts.Envs,
376+
context: opts.Context,
377+
})
378+
defer resp.Body.Close()
379+
if err != nil {
380+
if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
381+
return &NoSuchPlugin{ID: opts.Name}
382+
}
383+
return err
384+
}
385+
return nil
386+
}
387+
388+
// NoSuchPlugin is the error returned when a given plugin does not exist.
389+
type NoSuchPlugin struct {
390+
ID string
391+
Err error
392+
}
393+
394+
func (err *NoSuchPlugin) Error() string {
395+
if err.Err != nil {
396+
return err.Err.Error()
397+
}
398+
return "No such plugin: " + err.ID
399+
}

0 commit comments

Comments
 (0)