Browse Source

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>
Brian Goff 7 years ago
parent
commit
7c77df8acc

+ 12 - 8
daemon/graphdriver/plugin.go

@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"fmt"
 	"path/filepath"
 	"path/filepath"
 
 
+	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/plugin/v2"
 	"github.com/docker/docker/plugin/v2"
@@ -33,19 +34,22 @@ func newPluginDriver(name string, pl plugingetter.CompatPlugin, config Options)
 
 
 	var proxy *graphDriverProxy
 	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 {
 		if err != nil {
 			return nil, errors.Wrap(err, "error creating plugin client")
 			return nil, errors.Wrap(err, "error creating plugin client")
 		}
 		}
 		proxy = &graphDriverProxy{name, pl, Capabilities{}, 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)
 	return proxy, proxy.Init(filepath.Join(home, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
 }
 }

+ 5 - 1
daemon/logger/plugin.go

@@ -7,6 +7,7 @@ import (
 	"path/filepath"
 	"path/filepath"
 
 
 	"github.com/docker/docker/api/types/plugins/logdriver"
 	"github.com/docker/docker/api/types/plugins/logdriver"
+	"github.com/docker/docker/errdefs"
 	getter "github.com/docker/docker/pkg/plugingetter"
 	getter "github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/pkg/stringid"
 	"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) {
 func makePluginClient(p getter.CompatPlugin) (logPlugin, error) {
+	if pc, ok := p.(getter.PluginWithV1Client); ok {
+		return &logPluginProxy{pc.Client()}, nil
+	}
 	pa, ok := p.(getter.PluginAddr)
 	pa, ok := p.(getter.PluginAddr)
 	if !ok {
 	if !ok {
-		return &logPluginProxy{p.Client()}, nil
+		return nil, errdefs.System(errors.Errorf("got unknown plugin type %T", p))
 	}
 	}
 
 
 	if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {
 	if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {

+ 8 - 2
daemon/metrics.go

@@ -3,6 +3,7 @@ package daemon // import "github.com/docker/docker/daemon"
 import (
 import (
 	"sync"
 	"sync"
 
 
+	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/go-metrics"
 	"github.com/docker/go-metrics"
@@ -142,11 +143,16 @@ type metricsPlugin interface {
 	StopMetrics() error
 	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)
 	pa, ok := p.(plugingetter.PluginAddr)
 	if !ok {
 	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 {
 	if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {
 		return nil, errors.Errorf("plugin protocol not supported: %s", pa.Protocol())
 		return nil, errors.Errorf("plugin protocol not supported: %s", pa.Protocol())
 	}
 	}

+ 6 - 2
pkg/plugingetter/getter.go

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

+ 5 - 1
volume/drivers/extpoint.go

@@ -212,9 +212,13 @@ func (s *Store) GetAllDrivers() ([]volume.Driver, error) {
 }
 }
 
 
 func makePluginAdapter(p getter.CompatPlugin) (*volumeDriverAdapter, 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)
 	pa, ok := p.(getter.PluginAddr)
 	if !ok {
 	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 {
 	if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {