mirror of https://github.com/docker/docs.git
				
				
				
			plugins: vendor engine-api to import new plugin types
Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
		
							parent
							
								
									1704914d7c
								
							
						
					
					
						commit
						e5b7d36e99
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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{}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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{}
 | 
			
		||||
| 
						 | 
				
			
			@ -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{}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
		Loading…
	
		Reference in New Issue