-
Notifications
You must be signed in to change notification settings - Fork 564
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/plugins_api' of https://github.com/airking05/go…
- Loading branch information
Showing
2 changed files
with
719 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,399 @@ | ||
// Copyright 2013 go-dockerclient authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package docker | ||
|
||
import ( | ||
"encoding/json" | ||
ioutil "io/ioutil" | ||
"net/http" | ||
"net/url" | ||
|
||
"golang.org/x/net/context" | ||
) | ||
|
||
// PluginPrivilege represents a privilege for a plugin. | ||
type PluginPrivilege struct { | ||
Name string `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"` | ||
Description string `json:"Description,omitempty" yaml:"Description,omitempty" toml:"Description,omitempty"` | ||
Value []string `json:"Value,omitempty" yaml:"Value,omitempty" toml:"Value,omitempty"` | ||
} | ||
|
||
// InstallPluginOptions specify parameters to the InstallPlugins function. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type InstallPluginOptions struct { | ||
Remote string | ||
Name string | ||
Plugins []PluginPrivilege `qs:"-"` | ||
|
||
Auth AuthConfiguration | ||
|
||
Context context.Context | ||
} | ||
|
||
// InstallPlugins installs a plugin or returns an error in case of failure. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
func (c *Client) InstallPlugins(opts InstallPluginOptions) error { | ||
params := make(url.Values) | ||
params.Set("remote", opts.Remote) | ||
if opts.Name != "" { | ||
params.Set("name", opts.Name) | ||
} | ||
path := "/plugins/pull?" + queryString(params) | ||
resp, err := c.do("POST", path, doOptions{ | ||
data: opts.Plugins, | ||
context: opts.Context, | ||
}) | ||
defer resp.Body.Close() | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
// PluginSettings stores plugin settings. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type PluginSettings struct { | ||
Env []string `json:"Env,omitempty" yaml:"Env,omitempty" toml:"Env,omitempty"` | ||
Args []string `json:"Args,omitempty" yaml:"Args,omitempty" toml:"Args,omitempty"` | ||
Devices []string `json:"Devices,omitempty" yaml:"Devices,omitempty" toml:"Devices,omitempty"` | ||
} | ||
|
||
// PluginInterface stores plugin interface. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type PluginInterface struct { | ||
Types []string `json:"Types,omitempty" yaml:"Types,omitempty" toml:"Types,omitempty"` | ||
Socket string `json:"Socket,omitempty" yaml:"Socket,omitempty" toml:"Socket,omitempty"` | ||
} | ||
|
||
// PluginNetwork stores plugin network type. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type PluginNetwork struct { | ||
Type string `json:"Type,omitempty" yaml:"Type,omitempty" toml:"Type,omitempty"` | ||
} | ||
|
||
// PluginLinux stores plugin linux setting. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type PluginLinux struct { | ||
Capabilities []string `json:"Capabilities,omitempty" yaml:"Capabilities,omitempty" toml:"Capabilities,omitempty"` | ||
AllowAllDevices bool `json:"AllowAllDevices,omitempty" yaml:"AllowAllDevices,omitempty" toml:"AllowAllDevices,omitempty"` | ||
Devices []PluginLinuxDevices `json:"Devices,omitempty" yaml:"Devices,omitempty" toml:"Devices,omitempty"` | ||
} | ||
|
||
// PluginLinuxDevices stores plugin linux device setting. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type PluginLinuxDevices struct { | ||
Name string `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"` | ||
Description string `json:"Documentation,omitempty" yaml:"Documentation,omitempty" toml:"Documentation,omitempty"` | ||
Settable []string `json:"Settable,omitempty" yaml:"Settable,omitempty" toml:"Settable,omitempty"` | ||
Path string `json:"Path,omitempty" yaml:"Path,omitempty" toml:"Path,omitempty"` | ||
} | ||
|
||
// PluginEnv stores plugin environment. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type PluginEnv struct { | ||
Name string `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"` | ||
Description string `json:"Description,omitempty" yaml:"Description,omitempty" toml:"Description,omitempty"` | ||
Settable []string `json:"Settable,omitempty" yaml:"Settable,omitempty" toml:"Settable,omitempty"` | ||
Value string `json:"Value,omitempty" yaml:"Value,omitempty" toml:"Value,omitempty"` | ||
} | ||
|
||
// PluginArgs stores plugin arguments. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type PluginArgs struct { | ||
Name string `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"` | ||
Description string `json:"Description,omitempty" yaml:"Description,omitempty" toml:"Description,omitempty"` | ||
Settable []string `json:"Settable,omitempty" yaml:"Settable,omitempty" toml:"Settable,omitempty"` | ||
Value []string `json:"Value,omitempty" yaml:"Value,omitempty" toml:"Value,omitempty"` | ||
} | ||
|
||
// PluginUser stores plugin user. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type PluginUser struct { | ||
UID int32 `json:"UID,omitempty" yaml:"UID,omitempty" toml:"UID,omitempty"` | ||
GID int32 `json:"GID,omitempty" yaml:"GID,omitempty" toml:"GID,omitempty"` | ||
} | ||
|
||
// PluginConfig stores plugin config. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type PluginConfig struct { | ||
Description string `json:"Description,omitempty" yaml:"Description,omitempty" toml:"Description,omitempty"` | ||
Documentation string | ||
Interface PluginInterface `json:"Interface,omitempty" yaml:"Interface,omitempty" toml:"Interface,omitempty"` | ||
Entrypoint []string `json:"Entrypoint,omitempty" yaml:"Entrypoint,omitempty" toml:"Entrypoint,omitempty"` | ||
WorkDir string `json:"WorkDir,omitempty" yaml:"WorkDir,omitempty" toml:"WorkDir,omitempty"` | ||
User PluginUser `json:"User,omitempty" yaml:"User,omitempty" toml:"User,omitempty"` | ||
Network PluginNetwork `json:"Network,omitempty" yaml:"Network,omitempty" toml:"Network,omitempty"` | ||
Linux PluginLinux `json:"Linux,omitempty" yaml:"Linux,omitempty" toml:"Linux,omitempty"` | ||
PropagatedMount string `json:"PropagatedMount,omitempty" yaml:"PropagatedMount,omitempty" toml:"PropagatedMount,omitempty"` | ||
Mounts []Mount `json:"Mounts,omitempty" yaml:"Mounts,omitempty" toml:"Mounts,omitempty"` | ||
Env []PluginEnv `json:"Env,omitempty" yaml:"Env,omitempty" toml:"Env,omitempty"` | ||
Args PluginArgs `json:"Args,omitempty" yaml:"Args,omitempty" toml:"Args,omitempty"` | ||
} | ||
|
||
// PluginDetail specify results from the ListPlugins function. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type PluginDetail struct { | ||
ID string `json:"Id,omitempty" yaml:"Id,omitempty" toml:"Id,omitempty"` | ||
Name string `json:"Name,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty"` | ||
Tag string `json:"Tag,omitempty" yaml:"Tag,omitempty" toml:"Tag,omitempty"` | ||
Active bool `json:"Active,omitempty" yaml:"Active,omitempty" toml:"Active,omitempty"` | ||
Settings PluginSettings `json:"Settings,omitempty" yaml:"Settings,omitempty" toml:"Settings,omitempty"` | ||
Config PluginConfig `json:"Config,omitempty" yaml:"Config,omitempty" toml:"Config,omitempty"` | ||
} | ||
|
||
// ListPlugins returns pluginDetails or an error. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
func (c *Client) ListPlugins(ctx context.Context) ([]PluginDetail, error) { | ||
resp, err := c.do("GET", "/plugins", doOptions{ | ||
context:ctx, | ||
|
||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
pluginDetails := make([]PluginDetail, 0) | ||
if err := json.NewDecoder(resp.Body).Decode(&pluginDetails); err != nil { | ||
return nil, err | ||
} | ||
return pluginDetails, nil | ||
} | ||
|
||
// GetPluginPrivileges returns pulginPrivileges or an error. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
func (c *Client) GetPluginPrivileges(name string,ctx context.Context) ([]PluginPrivilege, error) { | ||
resp, err := c.do("GET", "/plugins/privileges?remote="+name, doOptions{ | ||
context:ctx, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
var pluginPrivileges []PluginPrivilege | ||
if err := json.NewDecoder(resp.Body).Decode(&pluginPrivileges); err != nil { | ||
return nil, err | ||
} | ||
return pluginPrivileges, nil | ||
} | ||
|
||
// InspectPlugins returns a pluginDetail or an error. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
func (c *Client) InspectPlugins(name string, ctx context.Context) (*PluginDetail, error) { | ||
resp, err := c.do("GET", "/plugins/"+name+"/json", doOptions{ | ||
context:ctx, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
if err != nil { | ||
if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { | ||
return nil, &NoSuchPlugin{ID: name} | ||
} | ||
return nil, err | ||
} | ||
resp.Body.Close() | ||
var pluginDetail PluginDetail | ||
if err := json.NewDecoder(resp.Body).Decode(&pluginDetail); err != nil { | ||
return nil, err | ||
} | ||
return &pluginDetail, nil | ||
} | ||
|
||
// RemovePluginOptions specify parameters to the RemovePlugin function. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type RemovePluginOptions struct { | ||
// The Name of the plugin. | ||
Name string `qs:"-"` | ||
|
||
Force bool `qs:"force"` | ||
Context context.Context | ||
} | ||
|
||
// RemovePlugin returns a PluginDetail or an error. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
func (c *Client) RemovePlugin(opts RemovePluginOptions) (*PluginDetail, error) { | ||
path := "/plugins/" + opts.Name + "?" + queryString(opts) | ||
resp, err := c.do("DELETE", path, doOptions{context: opts.Context}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
if err != nil { | ||
if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { | ||
return nil, &NoSuchPlugin{ID: opts.Name} | ||
} | ||
return nil, err | ||
} | ||
resp.Body.Close() | ||
var pluginDetail PluginDetail | ||
if err := json.NewDecoder(resp.Body).Decode(&pluginDetail); err != nil { | ||
return nil, err | ||
} | ||
return &pluginDetail, nil | ||
} | ||
|
||
// EnablePluginOptions specify parameters to the EnablePlugin function. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type EnablePluginOptions struct { | ||
// The Name of the plugin. | ||
Name string `qs:"-"` | ||
Timeout int64 `qs:"timeout"` | ||
|
||
Context context.Context | ||
} | ||
|
||
// EnablePlugin enables plugin that opts point or returns an error. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
func (c *Client) EnablePlugin(opts EnablePluginOptions) error { | ||
path := "/plugins/" + opts.Name + "/enable?" + queryString(opts) | ||
resp, err := c.do("POST", path, doOptions{context: opts.Context}) | ||
defer resp.Body.Close() | ||
if err != nil { | ||
return err | ||
} | ||
resp.Body.Close() | ||
return nil | ||
} | ||
|
||
// DisablePluginOptions specify parameters to the DisablePlugin function. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type DisablePluginOptions struct { | ||
// The Name of the plugin. | ||
Name string `qs:"-"` | ||
|
||
Context context.Context | ||
} | ||
|
||
// DisablePlugin disables plugin that opts point or returns an error. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
func (c *Client) DisablePlugin(opts DisablePluginOptions) error { | ||
path := "/plugins/" + opts.Name + "/disable" | ||
resp, err := c.do("POST", path, doOptions{context: opts.Context}) | ||
defer resp.Body.Close() | ||
if err != nil { | ||
return err | ||
} | ||
resp.Body.Close() | ||
return nil | ||
} | ||
|
||
// CreatePluginOptions specify parameters to the CreatePlugin function. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type CreatePluginOptions struct { | ||
// The Name of the plugin. | ||
Name string `qs:"name"` | ||
// Path to tar containing plugin | ||
Path string `qs:"-"` | ||
|
||
Context context.Context | ||
} | ||
|
||
// CreatePlugin creates plugin that opts point or returns an error. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
func (c *Client) CreatePlugin(opts CreatePluginOptions) (string, error) { | ||
path := "/plugins/create?" + queryString(opts) | ||
resp, err := c.do("POST", path, doOptions{ | ||
data: opts.Path, | ||
context: opts.Context}) | ||
defer resp.Body.Close() | ||
if err != nil { | ||
return "", err | ||
} | ||
containerNameBytes, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return "", err | ||
} | ||
return string(containerNameBytes), nil | ||
} | ||
|
||
// PushPluginOptions specify parameters to PushPlugin function. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type PushPluginOptions struct { | ||
// The Name of the plugin. | ||
Name string | ||
|
||
Context context.Context | ||
} | ||
|
||
// PushPlugin pushes plugin that opts point or returns an error. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
func (c *Client) PushPlugin(opts PushPluginOptions) error { | ||
path := "/plugins/" + opts.Name + "/push" | ||
resp, err := c.do("POST", path, doOptions{context: opts.Context}) | ||
defer resp.Body.Close() | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
// ConfigurePluginOptions specify parameters to the ConfigurePlugin | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
type ConfigurePluginOptions struct { | ||
// The Name of the plugin. | ||
Name string `qs:"name"` | ||
Envs []string | ||
|
||
Context context.Context | ||
} | ||
|
||
// ConfigurePlugin configures plugin that opts point or returns an error. | ||
// | ||
// See https://goo.gl/C4t7Tz for more details. | ||
func (c *Client) ConfigurePlugin(opts ConfigurePluginOptions) error { | ||
path := "/plugins/" + opts.Name + "/set" | ||
resp, err := c.do("POST", path, doOptions{ | ||
data: opts.Envs, | ||
context: opts.Context, | ||
}) | ||
defer resp.Body.Close() | ||
if err != nil { | ||
if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { | ||
return &NoSuchPlugin{ID: opts.Name} | ||
} | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
// NoSuchPlugin is the error returned when a given plugin does not exist. | ||
type NoSuchPlugin struct { | ||
ID string | ||
Err error | ||
} | ||
|
||
func (err *NoSuchPlugin) Error() string { | ||
if err.Err != nil { | ||
return err.Err.Error() | ||
} | ||
return "No such plugin: " + err.ID | ||
} |
Oops, something went wrong.