Skip to content

Commit f51a96c

Browse files
committed
Move plugin client creation to the extension point
Signed-off-by: Brian Goff <[email protected]>
1 parent 9c2c887 commit f51a96c

14 files changed

Lines changed: 229 additions & 47 deletions

File tree

api/swagger.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,13 @@ definitions:
18591859
type: "string"
18601860
x-nullable: false
18611861
example: "plugins.sock"
1862+
ProtocolScheme:
1863+
type: "string"
1864+
example: "some.protocol/v1.0"
1865+
description: "Protocol to use for clients connecting to the plugin."
1866+
enum:
1867+
- ""
1868+
- "moby.plugins.http/v1"
18621869
Entrypoint:
18631870
type: "array"
18641871
items:

api/types/plugin.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ type PluginConfigArgs struct {
121121
// swagger:model PluginConfigInterface
122122
type PluginConfigInterface struct {
123123

124+
// Protocol to use for clients connecting to the plugin.
125+
ProtocolScheme string `json:"ProtocolScheme,omitempty"`
126+
124127
// socket
125128
// Required: true
126129
Socket string `json:"Socket"`

daemon/graphdriver/plugin.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"path/filepath"
66

77
"github.com/docker/docker/pkg/plugingetter"
8+
"github.com/docker/docker/pkg/plugins"
89
"github.com/docker/docker/plugin/v2"
10+
"github.com/pkg/errors"
911
)
1012

1113
func lookupPlugin(name string, pg plugingetter.PluginGetter, config Options) (Driver, error) {
@@ -28,6 +30,22 @@ func newPluginDriver(name string, pl plugingetter.CompatPlugin, config Options)
2830
}
2931
}
3032
}
31-
proxy := &graphDriverProxy{name, pl, Capabilities{}}
33+
34+
var proxy *graphDriverProxy
35+
36+
pa, ok := pl.(plugingetter.PluginAddr)
37+
if !ok {
38+
proxy = &graphDriverProxy{name, pl, Capabilities{}, pl.Client()}
39+
} else {
40+
if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {
41+
return nil, errors.Errorf("plugin protocol not supported: %s", pa.Protocol())
42+
}
43+
addr := pa.Addr()
44+
client, err := plugins.NewClientWithTimeout(addr.Network()+"://"+addr.String(), nil, pa.Timeout())
45+
if err != nil {
46+
return nil, errors.Wrap(err, "error creating plugin client")
47+
}
48+
proxy = &graphDriverProxy{name, pl, Capabilities{}, client}
49+
}
3250
return proxy, proxy.Init(filepath.Join(home, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
3351
}

daemon/graphdriver/proxy.go

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ import (
1313
)
1414

1515
type graphDriverProxy struct {
16-
name string
17-
p plugingetter.CompatPlugin
18-
caps Capabilities
16+
name string
17+
p plugingetter.CompatPlugin
18+
caps Capabilities
19+
client *plugins.Client
1920
}
2021

2122
type graphDriverRequest struct {
@@ -57,7 +58,7 @@ func (d *graphDriverProxy) Init(home string, opts []string, uidMaps, gidMaps []i
5758
GIDMaps: gidMaps,
5859
}
5960
var ret graphDriverResponse
60-
if err := d.p.Client().Call("GraphDriver.Init", args, &ret); err != nil {
61+
if err := d.client.Call("GraphDriver.Init", args, &ret); err != nil {
6162
return err
6263
}
6364
if ret.Err != "" {
@@ -74,7 +75,7 @@ func (d *graphDriverProxy) Init(home string, opts []string, uidMaps, gidMaps []i
7475
func (d *graphDriverProxy) fetchCaps() (Capabilities, error) {
7576
args := &graphDriverRequest{}
7677
var ret graphDriverResponse
77-
if err := d.p.Client().Call("GraphDriver.Capabilities", args, &ret); err != nil {
78+
if err := d.client.Call("GraphDriver.Capabilities", args, &ret); err != nil {
7879
if !plugins.IsNotFound(err) {
7980
return Capabilities{}, err
8081
}
@@ -108,7 +109,7 @@ func (d *graphDriverProxy) create(method, id, parent string, opts *CreateOpts) e
108109
args.StorageOpt = opts.StorageOpt
109110
}
110111
var ret graphDriverResponse
111-
if err := d.p.Client().Call(method, args, &ret); err != nil {
112+
if err := d.client.Call(method, args, &ret); err != nil {
112113
return err
113114
}
114115
if ret.Err != "" {
@@ -120,7 +121,7 @@ func (d *graphDriverProxy) create(method, id, parent string, opts *CreateOpts) e
120121
func (d *graphDriverProxy) Remove(id string) error {
121122
args := &graphDriverRequest{ID: id}
122123
var ret graphDriverResponse
123-
if err := d.p.Client().Call("GraphDriver.Remove", args, &ret); err != nil {
124+
if err := d.client.Call("GraphDriver.Remove", args, &ret); err != nil {
124125
return err
125126
}
126127
if ret.Err != "" {
@@ -135,7 +136,7 @@ func (d *graphDriverProxy) Get(id, mountLabel string) (containerfs.ContainerFS,
135136
MountLabel: mountLabel,
136137
}
137138
var ret graphDriverResponse
138-
if err := d.p.Client().Call("GraphDriver.Get", args, &ret); err != nil {
139+
if err := d.client.Call("GraphDriver.Get", args, &ret); err != nil {
139140
return nil, err
140141
}
141142
var err error
@@ -148,7 +149,7 @@ func (d *graphDriverProxy) Get(id, mountLabel string) (containerfs.ContainerFS,
148149
func (d *graphDriverProxy) Put(id string) error {
149150
args := &graphDriverRequest{ID: id}
150151
var ret graphDriverResponse
151-
if err := d.p.Client().Call("GraphDriver.Put", args, &ret); err != nil {
152+
if err := d.client.Call("GraphDriver.Put", args, &ret); err != nil {
152153
return err
153154
}
154155
if ret.Err != "" {
@@ -160,7 +161,7 @@ func (d *graphDriverProxy) Put(id string) error {
160161
func (d *graphDriverProxy) Exists(id string) bool {
161162
args := &graphDriverRequest{ID: id}
162163
var ret graphDriverResponse
163-
if err := d.p.Client().Call("GraphDriver.Exists", args, &ret); err != nil {
164+
if err := d.client.Call("GraphDriver.Exists", args, &ret); err != nil {
164165
return false
165166
}
166167
return ret.Exists
@@ -169,7 +170,7 @@ func (d *graphDriverProxy) Exists(id string) bool {
169170
func (d *graphDriverProxy) Status() [][2]string {
170171
args := &graphDriverRequest{}
171172
var ret graphDriverResponse
172-
if err := d.p.Client().Call("GraphDriver.Status", args, &ret); err != nil {
173+
if err := d.client.Call("GraphDriver.Status", args, &ret); err != nil {
173174
return nil
174175
}
175176
return ret.Status
@@ -180,7 +181,7 @@ func (d *graphDriverProxy) GetMetadata(id string) (map[string]string, error) {
180181
ID: id,
181182
}
182183
var ret graphDriverResponse
183-
if err := d.p.Client().Call("GraphDriver.GetMetadata", args, &ret); err != nil {
184+
if err := d.client.Call("GraphDriver.GetMetadata", args, &ret); err != nil {
184185
return nil, err
185186
}
186187
if ret.Err != "" {
@@ -199,7 +200,7 @@ func (d *graphDriverProxy) Cleanup() error {
199200

200201
args := &graphDriverRequest{}
201202
var ret graphDriverResponse
202-
if err := d.p.Client().Call("GraphDriver.Cleanup", args, &ret); err != nil {
203+
if err := d.client.Call("GraphDriver.Cleanup", args, &ret); err != nil {
203204
return nil
204205
}
205206
if ret.Err != "" {
@@ -213,7 +214,7 @@ func (d *graphDriverProxy) Diff(id, parent string) (io.ReadCloser, error) {
213214
ID: id,
214215
Parent: parent,
215216
}
216-
body, err := d.p.Client().Stream("GraphDriver.Diff", args)
217+
body, err := d.client.Stream("GraphDriver.Diff", args)
217218
if err != nil {
218219
return nil, err
219220
}
@@ -226,7 +227,7 @@ func (d *graphDriverProxy) Changes(id, parent string) ([]archive.Change, error)
226227
Parent: parent,
227228
}
228229
var ret graphDriverResponse
229-
if err := d.p.Client().Call("GraphDriver.Changes", args, &ret); err != nil {
230+
if err := d.client.Call("GraphDriver.Changes", args, &ret); err != nil {
230231
return nil, err
231232
}
232233
if ret.Err != "" {
@@ -238,7 +239,7 @@ func (d *graphDriverProxy) Changes(id, parent string) ([]archive.Change, error)
238239

239240
func (d *graphDriverProxy) ApplyDiff(id, parent string, diff io.Reader) (int64, error) {
240241
var ret graphDriverResponse
241-
if err := d.p.Client().SendFile(fmt.Sprintf("GraphDriver.ApplyDiff?id=%s&parent=%s", id, parent), diff, &ret); err != nil {
242+
if err := d.client.SendFile(fmt.Sprintf("GraphDriver.ApplyDiff?id=%s&parent=%s", id, parent), diff, &ret); err != nil {
242243
return -1, err
243244
}
244245
if ret.Err != "" {
@@ -253,7 +254,7 @@ func (d *graphDriverProxy) DiffSize(id, parent string) (int64, error) {
253254
Parent: parent,
254255
}
255256
var ret graphDriverResponse
256-
if err := d.p.Client().Call("GraphDriver.DiffSize", args, &ret); err != nil {
257+
if err := d.client.Call("GraphDriver.DiffSize", args, &ret); err != nil {
257258
return -1, err
258259
}
259260
if ret.Err != "" {

daemon/logger/plugin.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/docker/docker/api/types/plugins/logdriver"
1010
getter "github.com/docker/docker/pkg/plugingetter"
11+
"github.com/docker/docker/pkg/plugins"
1112
"github.com/docker/docker/pkg/stringid"
1213
"github.com/pkg/errors"
1314
)
@@ -37,11 +38,32 @@ func getPlugin(name string, mode int) (Creator, error) {
3738
return nil, fmt.Errorf("error looking up logging plugin %s: %v", name, err)
3839
}
3940

40-
d := &logPluginProxy{p.Client()}
41-
return makePluginCreator(name, d, p.ScopedPath), nil
41+
client, err := makePluginClient(p)
42+
if err != nil {
43+
return nil, err
44+
}
45+
return makePluginCreator(name, client, p.ScopedPath), nil
46+
}
47+
48+
func makePluginClient(p getter.CompatPlugin) (logPlugin, error) {
49+
pa, ok := p.(getter.PluginAddr)
50+
if !ok {
51+
return &logPluginProxy{p.Client()}, nil
52+
}
53+
54+
if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {
55+
return nil, errors.Errorf("plugin protocol not supported: %s", p)
56+
}
57+
58+
addr := pa.Addr()
59+
c, err := plugins.NewClientWithTimeout(addr.Network()+"://"+addr.String(), nil, pa.Timeout())
60+
if err != nil {
61+
return nil, errors.Wrap(err, "error making plugin client")
62+
}
63+
return &logPluginProxy{c}, nil
4264
}
4365

44-
func makePluginCreator(name string, l *logPluginProxy, scopePath func(s string) string) Creator {
66+
func makePluginCreator(name string, l logPlugin, scopePath func(s string) string) Creator {
4567
return func(logCtx Info) (logger Logger, err error) {
4668
defer func() {
4769
if err != nil {

daemon/metrics.go

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"sync"
55

66
"github.com/docker/docker/pkg/plugingetter"
7+
"github.com/docker/docker/pkg/plugins"
78
"github.com/docker/go-metrics"
89
"github.com/pkg/errors"
910
"github.com/prometheus/client_golang/prometheus"
@@ -118,7 +119,15 @@ func (d *Daemon) cleanupMetricsPlugins() {
118119
p := plugin
119120
go func() {
120121
defer wg.Done()
121-
pluginStopMetricsCollection(p)
122+
123+
adapter, err := makePluginAdapter(p)
124+
if err != nil {
125+
logrus.WithError(err).WithField("plugin", p.Name()).Error("Error creating metrics plugin adapater")
126+
return
127+
}
128+
if err := adapter.StopMetrics(); err != nil {
129+
logrus.WithError(err).WithField("plugin", p.Name()).Error("Error stopping plugin metrics collection")
130+
}
122131
}()
123132
}
124133
wg.Wait()
@@ -128,12 +137,39 @@ func (d *Daemon) cleanupMetricsPlugins() {
128137
}
129138
}
130139

131-
func pluginStartMetricsCollection(p plugingetter.CompatPlugin) error {
140+
type metricsPlugin interface {
141+
StartMetrics() error
142+
StopMetrics() error
143+
}
144+
145+
func makePluginAdapter(p plugingetter.CompatPlugin) (metricsPlugin, error) {
146+
pa, ok := p.(plugingetter.PluginAddr)
147+
if !ok {
148+
return &metricsPluginAdapter{p.Client(), p.Name()}, nil
149+
}
150+
if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {
151+
return nil, errors.Errorf("plugin protocol not supported: %s", pa.Protocol())
152+
}
153+
154+
addr := pa.Addr()
155+
client, err := plugins.NewClientWithTimeout(addr.Network()+"://"+addr.String(), nil, pa.Timeout())
156+
if err != nil {
157+
return nil, errors.Wrap(err, "error creating metrics plugin client")
158+
}
159+
return &metricsPluginAdapter{client, p.Name()}, nil
160+
}
161+
162+
type metricsPluginAdapter struct {
163+
c *plugins.Client
164+
name string
165+
}
166+
167+
func (a *metricsPluginAdapter) StartMetrics() error {
132168
type metricsPluginResponse struct {
133169
Err string
134170
}
135171
var res metricsPluginResponse
136-
if err := p.Client().Call(metricsPluginType+".StartMetrics", nil, &res); err != nil {
172+
if err := a.c.Call(metricsPluginType+".StartMetrics", nil, &res); err != nil {
137173
return errors.Wrap(err, "could not start metrics plugin")
138174
}
139175
if res.Err != "" {
@@ -142,8 +178,9 @@ func pluginStartMetricsCollection(p plugingetter.CompatPlugin) error {
142178
return nil
143179
}
144180

145-
func pluginStopMetricsCollection(p plugingetter.CompatPlugin) {
146-
if err := p.Client().Call(metricsPluginType+".StopMetrics", nil, nil); err != nil {
147-
logrus.WithError(err).WithField("name", p.Name()).Error("error stopping metrics collector")
181+
func (a *metricsPluginAdapter) StopMetrics() error {
182+
if err := a.c.Call(metricsPluginType+".StopMetrics", nil, nil); err != nil {
183+
return errors.Wrap(err, "error stopping metrics collector")
148184
}
185+
return nil
149186
}

daemon/metrics_unix.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,12 @@ func registerMetricsPluginCallback(store *plugin.Store, sockPath string) {
4949
return
5050
}
5151

52-
if err := pluginStartMetricsCollection(p); err != nil {
53-
logrus.WithError(err).WithField("name", name).Error("error while initializing metrics plugin")
52+
adapter, err := makePluginAdapter(p)
53+
if err != nil {
54+
logrus.WithError(err).WithField("plugin", p.Name()).Error("Error creating plugin adapater")
55+
}
56+
if err := adapter.StartMetrics(); err != nil {
57+
logrus.WithError(err).WithField("plugin", p.Name()).Error("Error starting metrics collector plugin")
5458
}
5559
})
5660
}

pkg/plugingetter/getter.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package plugingetter // import "github.com/docker/docker/pkg/plugingetter"
22

33
import (
4+
"net"
5+
"time"
6+
47
"github.com/docker/docker/pkg/plugins"
58
)
69

@@ -21,6 +24,14 @@ type CompatPlugin interface {
2124
IsV1() bool
2225
}
2326

27+
// PluginAddr is a plugin that exposes the socket address for creating custom clients rather than the built-in `*plugins.Client`
28+
type PluginAddr interface {
29+
CompatPlugin
30+
Addr() net.Addr
31+
Timeout() time.Duration
32+
Protocol() string
33+
}
34+
2435
// CountedPlugin is a plugin which is reference counted.
2536
type CountedPlugin interface {
2637
Acquire()

pkg/plugins/plugins.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ import (
3131
"github.com/sirupsen/logrus"
3232
)
3333

34+
// ProtocolSchemeHTTPV1 is the name of the protocol used for interacting with plugins using this package.
35+
const ProtocolSchemeHTTPV1 = "moby.plugins.http/v1"
36+
3437
var (
3538
// ErrNotImplements is returned if the plugin does not implement the requested driver.
3639
ErrNotImplements = errors.New("Plugin does not implement the requested driver")
@@ -88,6 +91,11 @@ func (p *Plugin) Client() *Client {
8891
return p.client
8992
}
9093

94+
// Protocol returns the protocol name/version used for plugins in this package.
95+
func (p *Plugin) Protocol() string {
96+
return ProtocolSchemeHTTPV1
97+
}
98+
9199
// IsV1 returns true for V1 plugins and false otherwise.
92100
func (p *Plugin) IsV1() bool {
93101
return true

0 commit comments

Comments
 (0)