From e5b7d36e9954ffd8c199c0fcfaa0b9f4bfdeb196 Mon Sep 17 00:00:00 2001 From: Tibor Vass Date: Mon, 13 Jun 2016 22:01:08 -0700 Subject: [PATCH] plugins: vendor engine-api to import new plugin types Signed-off-by: Tibor Vass --- hack/vendor.sh | 2 +- .../docker/engine-api/client/errors.go | 15 ++ .../docker/engine-api/client/interface.go | 10 +- .../client/interface_experimental.go | 26 +++ .../engine-api/client/interface_stable.go | 11 ++ .../engine-api/client/plugin_disable.go | 14 ++ .../docker/engine-api/client/plugin_enable.go | 14 ++ .../engine-api/client/plugin_inspect.go | 22 +++ .../engine-api/client/plugin_install.go | 54 ++++++ .../docker/engine-api/client/plugin_list.go | 23 +++ .../docker/engine-api/client/plugin_push.go | 15 ++ .../docker/engine-api/client/plugin_remove.go | 14 ++ .../docker/engine-api/client/plugin_set.go | 14 ++ .../docker/engine-api/types/plugin.go | 160 ++++++++++++++++++ 14 files changed, 386 insertions(+), 8 deletions(-) create mode 100644 vendor/src/github.com/docker/engine-api/client/interface_experimental.go create mode 100644 vendor/src/github.com/docker/engine-api/client/interface_stable.go create mode 100644 vendor/src/github.com/docker/engine-api/client/plugin_disable.go create mode 100644 vendor/src/github.com/docker/engine-api/client/plugin_enable.go create mode 100644 vendor/src/github.com/docker/engine-api/client/plugin_inspect.go create mode 100644 vendor/src/github.com/docker/engine-api/client/plugin_install.go create mode 100644 vendor/src/github.com/docker/engine-api/client/plugin_list.go create mode 100644 vendor/src/github.com/docker/engine-api/client/plugin_push.go create mode 100644 vendor/src/github.com/docker/engine-api/client/plugin_remove.go create mode 100644 vendor/src/github.com/docker/engine-api/client/plugin_set.go create mode 100644 vendor/src/github.com/docker/engine-api/types/plugin.go diff --git a/hack/vendor.sh b/hack/vendor.sh index e2ee7a08f8..5301e16289 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -60,7 +60,7 @@ clone git golang.org/x/net 2beffdc2e92c8a3027590f898fe88f69af48a3f8 https://gith clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://github.com/golang/sys.git clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3 clone git github.com/docker/go-connections fa2850ff103453a9ad190da0df0af134f0314b3d -clone git github.com/docker/engine-api 6b2f24f16a7f1598635b6a99dbe38ec8a5eccaf8 +clone git github.com/docker/engine-api f3b5ad20d4576de14c96603db522dec530d03f62 clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837 clone git github.com/imdario/mergo 0.2.1 diff --git a/vendor/src/github.com/docker/engine-api/client/errors.go b/vendor/src/github.com/docker/engine-api/client/errors.go index be9f595ef8..6f6a78f97d 100644 --- a/vendor/src/github.com/docker/engine-api/client/errors.go +++ b/vendor/src/github.com/docker/engine-api/client/errors.go @@ -171,3 +171,18 @@ func IsErrTaskNotFound(err error) bool { _, ok := err.(taskNotFoundError) return ok } + +type pluginPermissionDenied struct { + name string +} + +func (e pluginPermissionDenied) Error() string { + return "Permission denied while installing plugin " + e.name +} + +// IsErrPluginPermissionDenied returns true if the error is caused +// when a user denies a plugin's permissions +func IsErrPluginPermissionDenied(err error) bool { + _, ok := err.(pluginPermissionDenied) + return ok +} diff --git a/vendor/src/github.com/docker/engine-api/client/interface.go b/vendor/src/github.com/docker/engine-api/client/interface.go index d64619899e..95d775561f 100644 --- a/vendor/src/github.com/docker/engine-api/client/interface.go +++ b/vendor/src/github.com/docker/engine-api/client/interface.go @@ -4,18 +4,17 @@ import ( "io" "time" - "golang.org/x/net/context" - "github.com/docker/engine-api/types" "github.com/docker/engine-api/types/container" "github.com/docker/engine-api/types/filters" "github.com/docker/engine-api/types/network" "github.com/docker/engine-api/types/registry" "github.com/docker/engine-api/types/swarm" + "golang.org/x/net/context" ) -// APIClient is an interface that clients that talk with a docker server must implement. -type APIClient interface { +// CommonAPIClient is the common methods between stable and experimental versions of APIClient. +type CommonAPIClient interface { ClientVersion() string CheckpointCreate(ctx context.Context, container string, options types.CheckpointCreateOptions) error CheckpointDelete(ctx context.Context, container string, checkpointID string) error @@ -97,6 +96,3 @@ type APIClient interface { VolumeList(ctx context.Context, filter filters.Args) (types.VolumesListResponse, error) VolumeRemove(ctx context.Context, volumeID string) error } - -// Ensure that Client always implements APIClient. -var _ APIClient = &Client{} diff --git a/vendor/src/github.com/docker/engine-api/client/interface_experimental.go b/vendor/src/github.com/docker/engine-api/client/interface_experimental.go new file mode 100644 index 0000000000..c968e530bf --- /dev/null +++ b/vendor/src/github.com/docker/engine-api/client/interface_experimental.go @@ -0,0 +1,26 @@ +// +build experimental + +package client + +import ( + "io" + + "github.com/docker/engine-api/types" + "golang.org/x/net/context" +) + +// APIClient is an interface that clients that talk with a docker server must implement. +type APIClient interface { + CommonAPIClient + PluginList(ctx context.Context) (types.PluginsListResponse, error) + PluginRemove(ctx context.Context, name string) error + PluginEnable(ctx context.Context, name string) error + PluginDisable(ctx context.Context, name string) error + PluginInstall(ctx context.Context, name, registryAuth string, acceptAllPermissions, noEnable bool, in io.ReadCloser, out io.Writer) error + PluginPush(ctx context.Context, name string, registryAuth string) error + PluginSet(ctx context.Context, name string, args []string) error + PluginInspect(ctx context.Context, name string) (*types.Plugin, error) +} + +// Ensure that Client always implements APIClient. +var _ APIClient = &Client{} diff --git a/vendor/src/github.com/docker/engine-api/client/interface_stable.go b/vendor/src/github.com/docker/engine-api/client/interface_stable.go new file mode 100644 index 0000000000..496f522d51 --- /dev/null +++ b/vendor/src/github.com/docker/engine-api/client/interface_stable.go @@ -0,0 +1,11 @@ +// +build !experimental + +package client + +// APIClient is an interface that clients that talk with a docker server must implement. +type APIClient interface { + CommonAPIClient +} + +// Ensure that Client always implements APIClient. +var _ APIClient = &Client{} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_disable.go b/vendor/src/github.com/docker/engine-api/client/plugin_disable.go new file mode 100644 index 0000000000..893fc6e823 --- /dev/null +++ b/vendor/src/github.com/docker/engine-api/client/plugin_disable.go @@ -0,0 +1,14 @@ +// +build experimental + +package client + +import ( + "golang.org/x/net/context" +) + +// PluginDisable disables a plugin +func (cli *Client) PluginDisable(ctx context.Context, name string) error { + resp, err := cli.post(ctx, "/plugins/"+name+"/disable", nil, nil, nil) + ensureReaderClosed(resp) + return err +} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_enable.go b/vendor/src/github.com/docker/engine-api/client/plugin_enable.go new file mode 100644 index 0000000000..84422abc79 --- /dev/null +++ b/vendor/src/github.com/docker/engine-api/client/plugin_enable.go @@ -0,0 +1,14 @@ +// +build experimental + +package client + +import ( + "golang.org/x/net/context" +) + +// PluginEnable enables a plugin +func (cli *Client) PluginEnable(ctx context.Context, name string) error { + resp, err := cli.post(ctx, "/plugins/"+name+"/enable", nil, nil, nil) + ensureReaderClosed(resp) + return err +} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_inspect.go b/vendor/src/github.com/docker/engine-api/client/plugin_inspect.go new file mode 100644 index 0000000000..b4bcc20069 --- /dev/null +++ b/vendor/src/github.com/docker/engine-api/client/plugin_inspect.go @@ -0,0 +1,22 @@ +// +build experimental + +package client + +import ( + "encoding/json" + + "github.com/docker/engine-api/types" + "golang.org/x/net/context" +) + +// PluginInspect inspects an existing plugin +func (cli *Client) PluginInspect(ctx context.Context, name string) (*types.Plugin, error) { + var p types.Plugin + resp, err := cli.get(ctx, "/plugins/"+name, nil, nil) + if err != nil { + return nil, err + } + err = json.NewDecoder(resp.body).Decode(&p) + ensureReaderClosed(resp) + return &p, err +} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_install.go b/vendor/src/github.com/docker/engine-api/client/plugin_install.go new file mode 100644 index 0000000000..9005e81a56 --- /dev/null +++ b/vendor/src/github.com/docker/engine-api/client/plugin_install.go @@ -0,0 +1,54 @@ +// +build experimental + +package client + +import ( + "bufio" + "encoding/json" + "fmt" + "io" + "net/url" + "strings" + + "github.com/docker/engine-api/types" + "golang.org/x/net/context" +) + +// PluginInstall installs a plugin +func (cli *Client) PluginInstall(ctx context.Context, name, registryAuth string, acceptAllPermissions, noEnable bool, in io.ReadCloser, out io.Writer) error { + headers := map[string][]string{"X-Registry-Auth": {registryAuth}} + resp, err := cli.post(ctx, "/plugins/pull", url.Values{"name": []string{name}}, nil, headers) + if err != nil { + ensureReaderClosed(resp) + return err + } + var privileges types.PluginPrivileges + if err := json.NewDecoder(resp.body).Decode(&privileges); err != nil { + return err + } + ensureReaderClosed(resp) + + if !acceptAllPermissions && len(privileges) > 0 { + + fmt.Fprintf(out, "Plugin %q requested the following privileges:\n", name) + for _, privilege := range privileges { + fmt.Fprintf(out, " - %s: %v\n", privilege.Name, privilege.Value) + } + + fmt.Fprint(out, "Do you grant the above permissions? [y/N] ") + reader := bufio.NewReader(in) + line, _, err := reader.ReadLine() + if err != nil { + return err + } + if strings.ToLower(string(line)) != "y" { + resp, _ := cli.delete(ctx, "/plugins/"+name, nil, nil) + ensureReaderClosed(resp) + return pluginPermissionDenied{name} + } + } + if noEnable { + return nil + } + return cli.PluginEnable(ctx, name) +} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_list.go b/vendor/src/github.com/docker/engine-api/client/plugin_list.go new file mode 100644 index 0000000000..7f2e2f21f3 --- /dev/null +++ b/vendor/src/github.com/docker/engine-api/client/plugin_list.go @@ -0,0 +1,23 @@ +// +build experimental + +package client + +import ( + "encoding/json" + + "github.com/docker/engine-api/types" + "golang.org/x/net/context" +) + +// PluginList returns the installed plugins +func (cli *Client) PluginList(ctx context.Context) (types.PluginsListResponse, error) { + var plugins types.PluginsListResponse + resp, err := cli.get(ctx, "/plugins", nil, nil) + if err != nil { + return plugins, err + } + + err = json.NewDecoder(resp.body).Decode(&plugins) + ensureReaderClosed(resp) + return plugins, err +} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_push.go b/vendor/src/github.com/docker/engine-api/client/plugin_push.go new file mode 100644 index 0000000000..3afea5ed79 --- /dev/null +++ b/vendor/src/github.com/docker/engine-api/client/plugin_push.go @@ -0,0 +1,15 @@ +// +build experimental + +package client + +import ( + "golang.org/x/net/context" +) + +// PluginPush pushes a plugin to a registry +func (cli *Client) PluginPush(ctx context.Context, name string, registryAuth string) error { + headers := map[string][]string{"X-Registry-Auth": {registryAuth}} + resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, headers) + ensureReaderClosed(resp) + return err +} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_remove.go b/vendor/src/github.com/docker/engine-api/client/plugin_remove.go new file mode 100644 index 0000000000..baf666556b --- /dev/null +++ b/vendor/src/github.com/docker/engine-api/client/plugin_remove.go @@ -0,0 +1,14 @@ +// +build experimental + +package client + +import ( + "golang.org/x/net/context" +) + +// PluginRemove removes a plugin +func (cli *Client) PluginRemove(ctx context.Context, name string) error { + resp, err := cli.delete(ctx, "/plugins/"+name, nil, nil) + ensureReaderClosed(resp) + return err +} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_set.go b/vendor/src/github.com/docker/engine-api/client/plugin_set.go new file mode 100644 index 0000000000..fb40f38b22 --- /dev/null +++ b/vendor/src/github.com/docker/engine-api/client/plugin_set.go @@ -0,0 +1,14 @@ +// +build experimental + +package client + +import ( + "golang.org/x/net/context" +) + +// PluginSet modifies settings for an existing plugin +func (cli *Client) PluginSet(ctx context.Context, name string, args []string) error { + resp, err := cli.post(ctx, "/plugins/"+name+"/set", nil, args, nil) + ensureReaderClosed(resp) + return err +} diff --git a/vendor/src/github.com/docker/engine-api/types/plugin.go b/vendor/src/github.com/docker/engine-api/types/plugin.go new file mode 100644 index 0000000000..f9df9efe05 --- /dev/null +++ b/vendor/src/github.com/docker/engine-api/types/plugin.go @@ -0,0 +1,160 @@ +// +build experimental + +package types + +import ( + "encoding/json" + "fmt" +) + +// PluginConfig represents the values of settings potentially modifiable by a user +type PluginConfig struct { + Mounts []PluginMount + Env []string + Args []string + Devices []PluginDevice +} + +// Plugin represents a Docker plugin for the remote API +type Plugin struct { + ID string `json:"Id,omitempty"` + Name string + Tag string + Active bool + Config PluginConfig + Manifest PluginManifest +} + +// PluginsListResponse contains the response for the remote API +type PluginsListResponse []*Plugin + +const ( + authzDriver = "AuthzDriver" + graphDriver = "GraphDriver" + ipamDriver = "IpamDriver" + networkDriver = "NetworkDriver" + volumeDriver = "VolumeDriver" +) + +// PluginInterfaceType represents a type that a plugin implements. +type PluginInterfaceType struct { + Prefix string // This is always "docker" + Capability string // Capability should be validated against the above list. + Version string // Plugin API version. Depends on the capability +} + +// UnmarshalJSON implements json.Unmarshaler for PluginInterfaceType +func (t *PluginInterfaceType) UnmarshalJSON(p []byte) error { + versionIndex := len(p) + prefixIndex := 0 + if len(p) < 2 || p[0] != '"' || p[len(p)-1] != '"' { + return fmt.Errorf("%q is not a plugin interface type", p) + } + p = p[1 : len(p)-1] +loop: + for i, b := range p { + switch b { + case '.': + prefixIndex = i + case '/': + versionIndex = i + break loop + } + } + t.Prefix = string(p[:prefixIndex]) + t.Capability = string(p[prefixIndex+1 : versionIndex]) + if versionIndex < len(p) { + t.Version = string(p[versionIndex+1:]) + } + return nil +} + +// MarshalJSON implements json.Marshaler for PluginInterfaceType +func (t *PluginInterfaceType) MarshalJSON() ([]byte, error) { + return json.Marshal(t.String()) +} + +// String implements fmt.Stringer for PluginInterfaceType +func (t PluginInterfaceType) String() string { + return fmt.Sprintf("%s.%s/%s", t.Prefix, t.Capability, t.Version) +} + +// PluginInterface describes the interface between Docker and plugin +type PluginInterface struct { + Types []PluginInterfaceType + Socket string +} + +// PluginSetting is to be embedded in other structs, if they are supposed to be +// modifiable by the user. +type PluginSetting struct { + Name string + Description string + Settable []string +} + +// PluginNetwork represents the network configuration for a plugin +type PluginNetwork struct { + Type string +} + +// PluginMount represents the mount configuration for a plugin +type PluginMount struct { + PluginSetting + Source *string + Destination string + Type string + Options []string +} + +// PluginEnv represents an environment variable for a plugin +type PluginEnv struct { + PluginSetting + Value *string +} + +// PluginArgs represents the command line arguments for a plugin +type PluginArgs struct { + PluginSetting + Value []string +} + +// PluginDevice represents a device for a plugin +type PluginDevice struct { + PluginSetting + Path *string +} + +// PluginUser represents the user for the plugin's process +type PluginUser struct { + UID uint32 `json:"Uid,omitempty"` + GID uint32 `json:"Gid,omitempty"` +} + +// PluginManifest represents the manifest of a plugin +type PluginManifest struct { + ManifestVersion string + Description string + Documentation string + Interface PluginInterface + Entrypoint []string + Workdir string + User PluginUser `json:",omitempty"` + Network PluginNetwork + Capabilities []string + Mounts []PluginMount + Devices []PluginDevice + Env []PluginEnv + Args PluginArgs +} + +// PluginPrivilege describes a permission the user has to accept +// upon installing a plugin. +type PluginPrivilege struct { + Name string + Description string + Value []string +} + +// PluginPrivileges is a list of PluginPrivilege +type PluginPrivileges []PluginPrivilege