Move plugin client to separate interface

This makes it a bit simpler to remove this interface for v2 plugins
and not break external projects (libnetwork and swarmkit).

Note that before we remove the `Client()` interface from `CompatPlugin`
libnetwork and swarmkit must be updated to explicitly check for the v1
client interface as is done int his PR.

This is just a minor tweak that I realized is needed after trying to
implement the needed changes on libnetwork.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff 2018-05-30 15:00:42 -04:00
parent b85799b63f
commit 7c77df8acc
5 changed files with 36 additions and 14 deletions

View file

@ -4,6 +4,7 @@ import (
"fmt"
"path/filepath"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/plugingetter"
"github.com/docker/docker/pkg/plugins"
"github.com/docker/docker/plugin/v2"
@ -33,19 +34,22 @@ func newPluginDriver(name string, pl plugingetter.CompatPlugin, config Options)
var proxy *graphDriverProxy
pa, ok := pl.(plugingetter.PluginAddr)
if !ok {
proxy = &graphDriverProxy{name, pl, Capabilities{}, pl.Client()}
} else {
if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {
return nil, errors.Errorf("plugin protocol not supported: %s", pa.Protocol())
switch pt := pl.(type) {
case plugingetter.PluginWithV1Client:
proxy = &graphDriverProxy{name, pl, Capabilities{}, pt.Client()}
case plugingetter.PluginAddr:
if pt.Protocol() != plugins.ProtocolSchemeHTTPV1 {
return nil, errors.Errorf("plugin protocol not supported: %s", pt.Protocol())
}
addr := pa.Addr()
client, err := plugins.NewClientWithTimeout(addr.Network()+"://"+addr.String(), nil, pa.Timeout())
addr := pt.Addr()
client, err := plugins.NewClientWithTimeout(addr.Network()+"://"+addr.String(), nil, pt.Timeout())
if err != nil {
return nil, errors.Wrap(err, "error creating plugin client")
}
proxy = &graphDriverProxy{name, pl, Capabilities{}, client}
default:
return nil, errdefs.System(errors.Errorf("got unknown plugin type %T", pt))
}
return proxy, proxy.Init(filepath.Join(home, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
}

View file

@ -7,6 +7,7 @@ import (
"path/filepath"
"github.com/docker/docker/api/types/plugins/logdriver"
"github.com/docker/docker/errdefs"
getter "github.com/docker/docker/pkg/plugingetter"
"github.com/docker/docker/pkg/plugins"
"github.com/docker/docker/pkg/stringid"
@ -46,9 +47,12 @@ func getPlugin(name string, mode int) (Creator, error) {
}
func makePluginClient(p getter.CompatPlugin) (logPlugin, error) {
if pc, ok := p.(getter.PluginWithV1Client); ok {
return &logPluginProxy{pc.Client()}, nil
}
pa, ok := p.(getter.PluginAddr)
if !ok {
return &logPluginProxy{p.Client()}, nil
return nil, errdefs.System(errors.Errorf("got unknown plugin type %T", p))
}
if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {

View file

@ -3,6 +3,7 @@ package daemon // import "github.com/docker/docker/daemon"
import (
"sync"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/plugingetter"
"github.com/docker/docker/pkg/plugins"
"github.com/docker/go-metrics"
@ -142,11 +143,16 @@ type metricsPlugin interface {
StopMetrics() error
}
func makePluginAdapter(p plugingetter.CompatPlugin) (metricsPlugin, error) {
func makePluginAdapter(p plugingetter.CompatPlugin) (metricsPlugin, error) { // nolint: interfacer
if pc, ok := p.(plugingetter.PluginWithV1Client); ok {
return &metricsPluginAdapter{pc.Client(), p.Name()}, nil
}
pa, ok := p.(plugingetter.PluginAddr)
if !ok {
return &metricsPluginAdapter{p.Client(), p.Name()}, nil
return nil, errdefs.System(errors.Errorf("got unknown plugin type %T", p))
}
if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {
return nil, errors.Errorf("plugin protocol not supported: %s", pa.Protocol())
}

View file

@ -18,15 +18,19 @@ const (
// CompatPlugin is an abstraction to handle both v2(new) and v1(legacy) plugins.
type CompatPlugin interface {
Client() *plugins.Client
Name() string
ScopedPath(string) string
IsV1() bool
PluginWithV1Client
}
// PluginWithV1Client is a plugin that directly utilizes the v1/http plugin client
type PluginWithV1Client interface {
Client() *plugins.Client
}
// PluginAddr is a plugin that exposes the socket address for creating custom clients rather than the built-in `*plugins.Client`
type PluginAddr interface {
CompatPlugin
Addr() net.Addr
Timeout() time.Duration
Protocol() string

View file

@ -212,9 +212,13 @@ func (s *Store) GetAllDrivers() ([]volume.Driver, error) {
}
func makePluginAdapter(p getter.CompatPlugin) (*volumeDriverAdapter, error) {
if pc, ok := p.(getter.PluginWithV1Client); ok {
return &volumeDriverAdapter{name: p.Name(), scopePath: p.ScopedPath, proxy: &volumeDriverProxy{pc.Client()}}, nil
}
pa, ok := p.(getter.PluginAddr)
if !ok {
return &volumeDriverAdapter{name: p.Name(), scopePath: p.ScopedPath, proxy: &volumeDriverProxy{p.Client()}}, nil
return nil, errdefs.System(errors.Errorf("got unknown plugin instance %T", p))
}
if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {