diff --git a/agent/csi/plugin/manager.go b/agent/csi/plugin/manager.go index 26c74f79f5..4fc089c0cd 100644 --- a/agent/csi/plugin/manager.go +++ b/agent/csi/plugin/manager.go @@ -5,9 +5,8 @@ import ( "fmt" "sync" - "github.com/docker/docker/pkg/plugingetter" - "github.com/moby/swarmkit/v2/api" + "github.com/moby/swarmkit/v2/node/plugin" ) const ( @@ -35,15 +34,15 @@ type pluginManager struct { // newNodePluginFunc usually points to NewNodePlugin. However, for testing, // NewNodePlugin can be swapped out with a function that creates fake node // plugins - newNodePluginFunc func(string, plugingetter.CompatPlugin, plugingetter.PluginAddr, SecretGetter) NodePlugin + newNodePluginFunc func(string, plugin.PluginAddr, SecretGetter) NodePlugin // secrets is a SecretGetter for use by node plugins. secrets SecretGetter - pg plugingetter.PluginGetter + pg plugin.Getter } -func NewManager(pg plugingetter.PluginGetter, secrets SecretGetter) Manager { +func NewManager(pg plugin.Getter, secrets SecretGetter) Manager { return &pluginManager{ plugins: map[string]NodePlugin{}, newNodePluginFunc: NewNodePlugin, @@ -104,17 +103,17 @@ func (pm *pluginManager) getPlugin(name string) (NodePlugin, error) { return p, nil } - pc, err := pm.pg.Get(name, DockerCSIPluginCap, plugingetter.Lookup) + pc, err := pm.pg.Get(name, DockerCSIPluginCap) if err != nil { return nil, err } - pa, ok := pc.(plugingetter.PluginAddr) + pa, ok := pc.(plugin.PluginAddr) if !ok { return nil, fmt.Errorf("plugin does not implement PluginAddr interface") } - p := pm.newNodePluginFunc(name, pc, pa, pm.secrets) + p := pm.newNodePluginFunc(name, pa, pm.secrets) pm.plugins[name] = p return p, nil } diff --git a/agent/csi/plugin/manager_test.go b/agent/csi/plugin/manager_test.go index 092efa43f4..f597c68831 100644 --- a/agent/csi/plugin/manager_test.go +++ b/agent/csi/plugin/manager_test.go @@ -18,7 +18,7 @@ var _ = Describe("Manager", func() { BeforeEach(func() { pg = &testutils.FakePluginGetter{ - Plugins: map[string]*testutils.FakeCompatPlugin{}, + Plugins: map[string]*testutils.FakePlugin{}, } pm = &pluginManager{ @@ -27,21 +27,21 @@ var _ = Describe("Manager", func() { pg: pg, } - pg.Plugins["plug1"] = &testutils.FakeCompatPlugin{ + pg.Plugins["plug1"] = &testutils.FakePlugin{ PluginName: "plug1", PluginAddr: &net.UnixAddr{ Net: "unix", Name: "", }, } - pg.Plugins["plug2"] = &testutils.FakeCompatPlugin{ + pg.Plugins["plug2"] = &testutils.FakePlugin{ PluginName: "plug2", PluginAddr: &net.UnixAddr{ Net: "unix", Name: "fail", }, } - pg.Plugins["plug3"] = &testutils.FakeCompatPlugin{ + pg.Plugins["plug3"] = &testutils.FakePlugin{ PluginName: "plug3", PluginAddr: &net.UnixAddr{ Net: "unix", diff --git a/agent/csi/plugin/plugin.go b/agent/csi/plugin/plugin.go index 560474d025..436b0d9f33 100644 --- a/agent/csi/plugin/plugin.go +++ b/agent/csi/plugin/plugin.go @@ -11,10 +11,10 @@ import ( "google.golang.org/grpc/status" "github.com/container-storage-interface/spec/lib/go/csi" - "github.com/docker/docker/pkg/plugingetter" "github.com/moby/swarmkit/v2/api" "github.com/moby/swarmkit/v2/internal/csi/capability" "github.com/moby/swarmkit/v2/log" + "github.com/moby/swarmkit/v2/node/plugin" ) // SecretGetter is a reimplementation of the exec.SecretGetter interface in the @@ -88,17 +88,17 @@ const ( TargetPublishPath string = "/data/published" ) -func NewNodePlugin(name string, pc plugingetter.CompatPlugin, pa plugingetter.PluginAddr, secrets SecretGetter) NodePlugin { - return newNodePlugin(name, pc, pa, secrets) +func NewNodePlugin(name string, p plugin.PluginAddr, secrets SecretGetter) NodePlugin { + return newNodePlugin(name, p, secrets) } // newNodePlugin returns a raw nodePlugin object, not behind an interface. this // is useful for testing. -func newNodePlugin(name string, pc plugingetter.CompatPlugin, pa plugingetter.PluginAddr, secrets SecretGetter) *nodePlugin { +func newNodePlugin(name string, p plugin.PluginAddr, secrets SecretGetter) *nodePlugin { return &nodePlugin{ name: name, - socket: fmt.Sprintf("%s://%s", pa.Addr().Network(), pa.Addr().String()), - scopePath: pc.ScopedPath, + socket: fmt.Sprintf("%s://%s", p.Addr().Network(), p.Addr().String()), + scopePath: p.ScopedPath, secrets: secrets, volumeMap: map[string]*volumePublishStatus{}, } diff --git a/agent/csi/plugin/plugin_fake_test.go b/agent/csi/plugin/plugin_fake_test.go index f1fdc60c5c..c8b1a0cb09 100644 --- a/agent/csi/plugin/plugin_fake_test.go +++ b/agent/csi/plugin/plugin_fake_test.go @@ -4,9 +4,8 @@ import ( "context" "fmt" - "github.com/docker/docker/pkg/plugingetter" - "github.com/moby/swarmkit/v2/api" + mobyplugin "github.com/moby/swarmkit/v2/node/plugin" ) // plugin_fake_test.go contains code for faking node plugins in the context of @@ -20,7 +19,7 @@ type fakeNodePlugin struct { // newFakeNodePlugin has the same signature as NewNodePlugin, allowing it to be // substituted in testing. -func newFakeNodePlugin(name string, pc plugingetter.CompatPlugin, pa plugingetter.PluginAddr, secrets SecretGetter) NodePlugin { +func newFakeNodePlugin(name string, pa mobyplugin.PluginAddr, secrets SecretGetter) NodePlugin { return &fakeNodePlugin{ name: name, socket: pa.Addr().String(), diff --git a/agent/csi/plugin/plugin_test.go b/agent/csi/plugin/plugin_test.go index 5427a45fbb..0e312c5080 100644 --- a/agent/csi/plugin/plugin_test.go +++ b/agent/csi/plugin/plugin_test.go @@ -15,11 +15,11 @@ import ( ) func newVolumeClient(name string, nodeID string) *nodePlugin { - p := &testutils.FakeCompatPlugin{ + p := &testutils.FakePlugin{ PluginName: name, PluginAddr: &net.UnixAddr{}, } - n := newNodePlugin(name, p, p, nil) + n := newNodePlugin(name, p, nil) n.staging = true fakeNodeClient := newFakeNodeClient(true, nodeID) diff --git a/agent/csi/volumes.go b/agent/csi/volumes.go index ae276d5d29..97539286df 100644 --- a/agent/csi/volumes.go +++ b/agent/csi/volumes.go @@ -6,12 +6,11 @@ import ( "sync" "time" - "github.com/docker/docker/pkg/plugingetter" - "github.com/moby/swarmkit/v2/agent/csi/plugin" "github.com/moby/swarmkit/v2/agent/exec" "github.com/moby/swarmkit/v2/api" "github.com/moby/swarmkit/v2/log" + mobyplugin "github.com/moby/swarmkit/v2/node/plugin" "github.com/moby/swarmkit/v2/volumequeue" ) @@ -46,7 +45,7 @@ type volumes struct { } // NewManager returns a place to store volumes. -func NewManager(pg plugingetter.PluginGetter, secrets exec.SecretGetter) exec.VolumesManager { +func NewManager(pg mobyplugin.Getter, secrets exec.SecretGetter) exec.VolumesManager { r := &volumes{ volumes: map[string]volumeState{}, plugins: plugin.NewManager(pg, secrets), diff --git a/agent/dependency.go b/agent/dependency.go index d123e30a1b..16aacf8d72 100644 --- a/agent/dependency.go +++ b/agent/dependency.go @@ -1,13 +1,12 @@ package agent import ( - "github.com/docker/docker/pkg/plugingetter" - "github.com/moby/swarmkit/v2/agent/configs" "github.com/moby/swarmkit/v2/agent/csi" "github.com/moby/swarmkit/v2/agent/exec" "github.com/moby/swarmkit/v2/agent/secrets" "github.com/moby/swarmkit/v2/api" + "github.com/moby/swarmkit/v2/node/plugin" ) type dependencyManager struct { @@ -18,7 +17,7 @@ type dependencyManager struct { // NewDependencyManager creates a dependency manager object that wraps // objects which provide access to various dependency types. -func NewDependencyManager(pg plugingetter.PluginGetter) exec.DependencyManager { +func NewDependencyManager(pg plugin.Getter) exec.DependencyManager { d := &dependencyManager{ secrets: secrets.NewManager(), configs: configs.NewManager(), diff --git a/agent/worker_test.go b/agent/worker_test.go index 03cf3b2712..40de4adc75 100644 --- a/agent/worker_test.go +++ b/agent/worker_test.go @@ -42,7 +42,7 @@ func TestWorkerAssign(t *testing.T) { defer cleanup() pg := &testutils.FakePluginGetter{ - Plugins: map[string]*testutils.FakeCompatPlugin{ + Plugins: map[string]*testutils.FakePlugin{ "plugin-1": { PluginName: "plugin-1", PluginAddr: &net.UnixAddr{}, @@ -268,7 +268,7 @@ func TestWorkerWait(t *testing.T) { ctx := context.Background() pg := &testutils.FakePluginGetter{ - Plugins: map[string]*testutils.FakeCompatPlugin{ + Plugins: map[string]*testutils.FakePlugin{ "plugin-1": { PluginName: "plugin-1", PluginAddr: &net.UnixAddr{}, @@ -416,7 +416,7 @@ func TestWorkerUpdate(t *testing.T) { ctx := context.Background() pg := &testutils.FakePluginGetter{ - Plugins: map[string]*testutils.FakeCompatPlugin{ + Plugins: map[string]*testutils.FakePlugin{ "plugin-1": { PluginName: "plugin-1", PluginAddr: &net.UnixAddr{}, diff --git a/manager/csi/fakes_test.go b/manager/csi/fakes_test.go index 254c8ba0c4..3c8f025afb 100644 --- a/manager/csi/fakes_test.go +++ b/manager/csi/fakes_test.go @@ -10,8 +10,8 @@ import ( "github.com/golang/protobuf/ptypes/wrappers" "google.golang.org/grpc" - "github.com/docker/docker/pkg/plugingetter" "github.com/moby/swarmkit/v2/api" + mobyplugin "github.com/moby/swarmkit/v2/node/plugin" ) const ( @@ -203,11 +203,11 @@ type fakePluginMaker struct { plugins map[string]*fakePlugin } -func (fpm *fakePluginMaker) newFakePlugin(pc plugingetter.CompatPlugin, pa plugingetter.PluginAddr, provider SecretProvider) Plugin { +func (fpm *fakePluginMaker) newFakePlugin(pa mobyplugin.PluginAddr, provider SecretProvider) Plugin { fpm.Lock() defer fpm.Unlock() p := &fakePlugin{ - name: pc.Name(), + name: pa.Name(), socket: pa.Addr().String(), swarmToCSI: map[string]string{}, volumesCreated: map[string]*api.Volume{}, @@ -216,7 +216,7 @@ func (fpm *fakePluginMaker) newFakePlugin(pc plugingetter.CompatPlugin, pa plugi volumesUnpublished: map[string][]string{}, removedIDs: map[string]struct{}{}, } - fpm.plugins[pc.Name()] = p + fpm.plugins[pa.Name()] = p return p } diff --git a/manager/csi/manager.go b/manager/csi/manager.go index adb2bf2611..7f958a1441 100644 --- a/manager/csi/manager.go +++ b/manager/csi/manager.go @@ -7,12 +7,12 @@ import ( "sync" "time" - "github.com/docker/docker/pkg/plugingetter" "github.com/docker/go-events" "github.com/moby/swarmkit/v2/api" "github.com/moby/swarmkit/v2/log" "github.com/moby/swarmkit/v2/manager/state/store" + mobyplugin "github.com/moby/swarmkit/v2/node/plugin" "github.com/moby/swarmkit/v2/volumequeue" ) @@ -36,12 +36,12 @@ type Manager struct { // pg is the plugingetter, which allows us to access the Docker Engine's // plugin store. - pg plugingetter.PluginGetter + pg mobyplugin.Getter // newPlugin is a function which returns an object implementing the Plugin // interface. It allows us to swap out the implementation of plugins while // unit-testing the Manager - newPlugin func(pc plugingetter.CompatPlugin, pa plugingetter.PluginAddr, provider SecretProvider) Plugin + newPlugin func(p mobyplugin.PluginAddr, provider SecretProvider) Plugin // synchronization for starting and stopping the Manager startOnce sync.Once @@ -55,7 +55,7 @@ type Manager struct { pendingVolumes *volumequeue.VolumeQueue } -func NewManager(s *store.MemoryStore, pg plugingetter.PluginGetter) *Manager { +func NewManager(s *store.MemoryStore, pg mobyplugin.Getter) *Manager { return &Manager{ store: s, stopChan: make(chan struct{}), @@ -469,7 +469,7 @@ func (vm *Manager) getPlugin(name string) (Plugin, error) { } // otherwise, we need to load the plugin. - pc, err := vm.pg.Get(name, DockerCSIPluginCap, plugingetter.Lookup) + pc, err := vm.pg.Get(name, DockerCSIPluginCap) if err != nil { return nil, err } @@ -478,12 +478,12 @@ func (vm *Manager) getPlugin(name string) (Plugin, error) { return nil, errors.New("driver \"" + name + "\" not found") } - pa, ok := pc.(plugingetter.PluginAddr) + pa, ok := pc.(mobyplugin.PluginAddr) if !ok { return nil, errors.New("plugin for driver \"" + name + "\" does not implement PluginAddr") } - p := vm.newPlugin(pc, pa, vm.provider) + p := vm.newPlugin(pa, vm.provider) vm.plugins[name] = p return p, nil diff --git a/manager/csi/manager_test.go b/manager/csi/manager_test.go index 229d6ad63a..6cd2b73e3e 100644 --- a/manager/csi/manager_test.go +++ b/manager/csi/manager_test.go @@ -63,7 +63,7 @@ var _ = Describe("Manager", func() { plugins: map[string]*fakePlugin{}, } pluginGetter = &testutils.FakePluginGetter{ - Plugins: map[string]*testutils.FakeCompatPlugin{}, + Plugins: map[string]*testutils.FakePlugin{}, } s = store.NewMemoryStore(nil) @@ -108,14 +108,14 @@ var _ = Describe("Manager", func() { When("starting up", func() { BeforeEach(func() { - pluginGetter.Plugins["newPlugin"] = &testutils.FakeCompatPlugin{ + pluginGetter.Plugins["newPlugin"] = &testutils.FakePlugin{ PluginName: "newPlugin", PluginAddr: &net.UnixAddr{ Net: "unix", Name: "unix:///whatever.sock", }, } - pluginGetter.Plugins["differentPlugin"] = &testutils.FakeCompatPlugin{ + pluginGetter.Plugins["differentPlugin"] = &testutils.FakePlugin{ PluginName: "differentPlugin", PluginAddr: &net.UnixAddr{ Net: "unix", @@ -233,14 +233,14 @@ var _ = Describe("Manager", func() { When("a volume is created", func() { BeforeEach(func() { - pluginGetter.Plugins["somePlugin"] = &testutils.FakeCompatPlugin{ + pluginGetter.Plugins["somePlugin"] = &testutils.FakePlugin{ PluginName: "somePlugin", PluginAddr: &net.UnixAddr{ Net: "unix", Name: "unix:///whatever.sock", }, } - pluginGetter.Plugins["someOtherPlugin"] = &testutils.FakeCompatPlugin{ + pluginGetter.Plugins["someOtherPlugin"] = &testutils.FakePlugin{ PluginName: "someOtherPlugin", PluginAddr: &net.UnixAddr{ Net: "unix", @@ -297,14 +297,14 @@ var _ = Describe("Manager", func() { Describe("managing node inventory", func() { BeforeEach(func() { - pluginGetter.Plugins["newPlugin"] = &testutils.FakeCompatPlugin{ + pluginGetter.Plugins["newPlugin"] = &testutils.FakePlugin{ PluginName: "newPlugin", PluginAddr: &net.UnixAddr{ Net: "unix", Name: "unix:///whatever.sock", }, } - pluginGetter.Plugins["differentPlugin"] = &testutils.FakeCompatPlugin{ + pluginGetter.Plugins["differentPlugin"] = &testutils.FakePlugin{ PluginName: "differentPlugin", PluginAddr: &net.UnixAddr{ Net: "unix", @@ -469,7 +469,7 @@ var _ = Describe("Manager", func() { v1 *api.Volume ) BeforeEach(func() { - pluginGetter.Plugins["plug1"] = &testutils.FakeCompatPlugin{ + pluginGetter.Plugins["plug1"] = &testutils.FakePlugin{ PluginName: "plug1", PluginAddr: &net.UnixAddr{ Net: "unix", @@ -666,7 +666,7 @@ var _ = Describe("Manager", func() { Describe("removing a Volume", func() { BeforeEach(func() { - pluginGetter.Plugins["plug"] = &testutils.FakeCompatPlugin{ + pluginGetter.Plugins["plug"] = &testutils.FakePlugin{ PluginName: "plug", PluginAddr: &net.UnixAddr{ Net: "unix", diff --git a/manager/csi/plugin.go b/manager/csi/plugin.go index 6a1cd70a2e..2f5dc30b7f 100644 --- a/manager/csi/plugin.go +++ b/manager/csi/plugin.go @@ -10,10 +10,10 @@ import ( "google.golang.org/grpc/status" "github.com/container-storage-interface/spec/lib/go/csi" - "github.com/docker/docker/pkg/plugingetter" "github.com/moby/swarmkit/v2/api" "github.com/moby/swarmkit/v2/internal/csi/capability" "github.com/moby/swarmkit/v2/log" + mobyplugin "github.com/moby/swarmkit/v2/node/plugin" ) // Plugin is the interface for a CSI controller plugin. @@ -74,12 +74,12 @@ type plugin struct { // the same object. By taking both parts here, we can push off the work of // assuring that the given plugin implements the PluginAddr interface without // having to typecast in this constructor. -func NewPlugin(pc plugingetter.CompatPlugin, pa plugingetter.PluginAddr, provider SecretProvider) Plugin { +func NewPlugin(p mobyplugin.PluginAddr, provider SecretProvider) Plugin { return &plugin{ - name: pc.Name(), + name: p.Name(), // TODO(dperny): verify that we do not need to include the Network() // portion of the Addr. - socket: fmt.Sprintf("%s://%s", pa.Addr().Network(), pa.Addr().String()), + socket: fmt.Sprintf("%s://%s", p.Addr().Network(), p.Addr().String()), provider: provider, swarmToCSI: map[string]string{}, csiToSwarm: map[string]string{}, diff --git a/manager/dispatcher/dispatcher_test.go b/manager/dispatcher/dispatcher_test.go index 2d5e7e5d84..b5e4311e07 100644 --- a/manager/dispatcher/dispatcher_test.go +++ b/manager/dispatcher/dispatcher_test.go @@ -6,10 +6,7 @@ import ( "encoding/json" "errors" "fmt" - "io" "net" - "net/http" - "net/http/httptest" "sync" "testing" "time" @@ -18,8 +15,6 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" - "github.com/docker/docker/pkg/plugingetter" - "github.com/docker/docker/pkg/plugins" "github.com/docker/go-events" "github.com/moby/swarmkit/v2/api" "github.com/moby/swarmkit/v2/ca" @@ -27,6 +22,7 @@ import ( "github.com/moby/swarmkit/v2/identity" "github.com/moby/swarmkit/v2/manager/drivers" "github.com/moby/swarmkit/v2/manager/state/store" + "github.com/moby/swarmkit/v2/node/plugin" "github.com/moby/swarmkit/v2/testutils" digest "github.com/opencontainers/go-digest" "github.com/stretchr/testify/assert" @@ -52,7 +48,6 @@ func (gd *grpcDispatcher) Close() { } gd.dispatcherServer.Stop() gd.grpcServer.Stop() - gd.PluginGetter.Close() gd.testCA.Stop() } @@ -423,12 +418,9 @@ func TestAssignmentsSecretDriver(t *testing.T) { errSecretName: {Err: "Error from driver"}, } - mux := http.NewServeMux() - mux.HandleFunc(drivers.SecretsProviderAPI, func(w http.ResponseWriter, r *http.Request) { - defer r.Body.Close() - body, err := io.ReadAll(r.Body) + var mux MockPluginClient + mux.HandleFunc(drivers.SecretsProviderAPI, func(body []byte) (interface{}, error) { var request drivers.SecretsProviderRequest - assert.NoError(t, err) assert.NoError(t, json.Unmarshal(body, &request)) response := responses[request.SecretName] assert.Equal(t, serviceName, request.ServiceName) @@ -438,14 +430,12 @@ func TestAssignmentsSecretDriver(t *testing.T) { assert.EqualValues(t, portConfig, request.ServiceEndpointSpec.Ports[0]) assert.EqualValues(t, serviceLabels, request.ServiceLabels) assert.NotNil(t, response) - resp, err := json.Marshal(response) - assert.NoError(t, err) - w.Write(resp) + return response, nil }) gd := startDispatcher(t, DefaultConfig()) defer gd.Close() - assert.NoError(t, gd.PluginGetter.SetupPlugin(secretDriver, mux)) + assert.NoError(t, gd.PluginGetter.SetupPlugin(secretDriver, &mux)) expectedSessionID, nodeID := getSessionAndNodeID(t, gd.Clients[0]) @@ -2333,59 +2323,41 @@ func TestClusterUpdatesSendMessages(t *testing.T) { // mockPluginGetter enables mocking the server plugin getter with customized plugins type mockPluginGetter struct { - addr string - server *httptest.Server name string - plugin plugingetter.CompatPlugin + plugin plugin.Plugin } +var _ plugin.Getter = &mockPluginGetter{} + // SetupPlugin setup a new plugin - the same plugin wil always return in all calls -func (m *mockPluginGetter) SetupPlugin(name string, handler http.Handler) error { - m.server = httptest.NewServer(handler) - client, err := plugins.NewClient(m.server.URL, nil) - if err != nil { - return err - } +func (m *mockPluginGetter) SetupPlugin(name string, client plugin.Client) error { m.plugin = NewMockPlugin(m.name, client) m.name = name return nil } -// Close closes the mock plugin getter -func (m *mockPluginGetter) Close() { - if m.server == nil { - return - } - m.server.Close() -} - -func (m *mockPluginGetter) Get(name, capability string, mode int) (plugingetter.CompatPlugin, error) { +func (m *mockPluginGetter) Get(name, capability string) (plugin.Plugin, error) { if name != m.name { return nil, fmt.Errorf("plugin with name %s not defined", name) } return m.plugin, nil } -func (m *mockPluginGetter) GetAllByCap(capability string) ([]plugingetter.CompatPlugin, error) { - return nil, nil -} -func (m *mockPluginGetter) GetAllManagedPluginsByCap(capability string) []plugingetter.CompatPlugin { +func (m *mockPluginGetter) GetAllManagedPluginsByCap(capability string) []plugin.Plugin { return nil } -func (m *mockPluginGetter) Handle(capability string, callback func(string, *plugins.Client)) { -} // MockPlugin mocks a v2 docker plugin type MockPlugin struct { - client *plugins.Client + client plugin.Client name string } // NewMockPlugin creates a new v2 plugin fake (returns the specified client and name for all calls) -func NewMockPlugin(name string, client *plugins.Client) *MockPlugin { +func NewMockPlugin(name string, client plugin.Client) *MockPlugin { return &MockPlugin{name: name, client: client} } -func (m *MockPlugin) Client() *plugins.Client { +func (m *MockPlugin) Client() plugin.Client { return m.client } func (m *MockPlugin) Name() string { @@ -2394,10 +2366,39 @@ func (m *MockPlugin) Name() string { func (m *MockPlugin) ScopedPath(_ string) string { return "" } -func (m *MockPlugin) BasePath() string { - return "" +type MockPluginHandlerFn func(argsJSON []byte) (interface{}, error) + +type MockPluginClient struct { + handlers map[string]MockPluginHandlerFn } -func (m *MockPlugin) IsV1() bool { - return false + +func (mc *MockPluginClient) HandleFunc(method string, fn MockPluginHandlerFn) { + if mc.handlers == nil { + mc.handlers = make(map[string]MockPluginHandlerFn) + } + if _, ok := mc.handlers[method]; ok { + panic(fmt.Sprintf("handler for %s already exists", method)) + } + mc.handlers[method] = fn +} + +func (mc *MockPluginClient) Call(method string, args, ret interface{}) error { + fn, ok := mc.handlers[method] + if !ok { + return fmt.Errorf("no handler for %s", method) + } + jsonArgs, err := json.Marshal(args) + if err != nil { + return err + } + res, err := fn(jsonArgs) + if err != nil { + return err + } + jsonRes, err := json.Marshal(res) + if err != nil { + return fmt.Errorf("error marshalling response: %v", err) + } + return json.Unmarshal(jsonRes, ret) } diff --git a/manager/drivers/provider.go b/manager/drivers/provider.go index 899c54e1a7..1dd3fa620b 100644 --- a/manager/drivers/provider.go +++ b/manager/drivers/provider.go @@ -3,17 +3,17 @@ package drivers import ( "fmt" - "github.com/docker/docker/pkg/plugingetter" "github.com/moby/swarmkit/v2/api" + "github.com/moby/swarmkit/v2/node/plugin" ) // DriverProvider provides external drivers type DriverProvider struct { - pluginGetter plugingetter.PluginGetter + pluginGetter plugin.Getter } // New returns a new driver provider -func New(pluginGetter plugingetter.PluginGetter) *DriverProvider { +func New(pluginGetter plugin.Getter) *DriverProvider { return &DriverProvider{pluginGetter: pluginGetter} } @@ -26,7 +26,7 @@ func (m *DriverProvider) NewSecretDriver(driver *api.Driver) (*SecretDriver, err return nil, fmt.Errorf("driver specification is nil") } // Search for the specified plugin - plugin, err := m.pluginGetter.Get(driver.Name, SecretsProviderCapability, plugingetter.Lookup) + plugin, err := m.pluginGetter.Get(driver.Name, SecretsProviderCapability) if err != nil { return nil, err } diff --git a/manager/drivers/secrets.go b/manager/drivers/secrets.go index ec221a4cb6..63d6e47c23 100644 --- a/manager/drivers/secrets.go +++ b/manager/drivers/secrets.go @@ -3,9 +3,9 @@ package drivers import ( "fmt" - "github.com/docker/docker/pkg/plugingetter" "github.com/moby/swarmkit/v2/api" "github.com/moby/swarmkit/v2/api/naming" + "github.com/moby/swarmkit/v2/node/plugin" ) const ( @@ -18,11 +18,11 @@ const ( // SecretDriver provides secrets from different stores type SecretDriver struct { - plugin plugingetter.CompatPlugin + plugin plugin.Plugin } // NewSecretDriver creates a new driver that provides third party secrets -func NewSecretDriver(plugin plugingetter.CompatPlugin) *SecretDriver { +func NewSecretDriver(plugin plugin.Plugin) *SecretDriver { return &SecretDriver{plugin: plugin} } diff --git a/manager/manager.go b/manager/manager.go index 06e1971c21..8e00c57477 100644 --- a/manager/manager.go +++ b/manager/manager.go @@ -13,7 +13,6 @@ import ( "syscall" "time" - "github.com/docker/docker/pkg/plugingetter" "github.com/docker/go-events" gmetrics "github.com/docker/go-metrics" gogotypes "github.com/gogo/protobuf/types" @@ -45,6 +44,7 @@ import ( "github.com/moby/swarmkit/v2/manager/state/raft/transport" "github.com/moby/swarmkit/v2/manager/state/store" "github.com/moby/swarmkit/v2/manager/watchapi" + "github.com/moby/swarmkit/v2/node/plugin" "github.com/moby/swarmkit/v2/remotes" "github.com/moby/swarmkit/v2/xnet" "github.com/pkg/errors" @@ -123,7 +123,7 @@ type Config struct { Availability api.NodeSpec_Availability // PluginGetter provides access to docker's plugin inventory. - PluginGetter plugingetter.PluginGetter + PluginGetter plugin.Getter // FIPS is a boolean stating whether the node is FIPS enabled - if this is the // first node in the cluster, this setting is used to set the cluster-wide mandatory diff --git a/node/node.go b/node/node.go index b6b6ec3711..eda5266a73 100644 --- a/node/node.go +++ b/node/node.go @@ -15,7 +15,6 @@ import ( "sync" "time" - "github.com/docker/docker/pkg/plugingetter" "github.com/docker/go-metrics" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/moby/swarmkit/v2/agent" @@ -30,6 +29,7 @@ import ( "github.com/moby/swarmkit/v2/manager" "github.com/moby/swarmkit/v2/manager/allocator/networkallocator" "github.com/moby/swarmkit/v2/manager/encryption" + "github.com/moby/swarmkit/v2/node/plugin" "github.com/moby/swarmkit/v2/remotes" "github.com/moby/swarmkit/v2/xnet" "github.com/pkg/errors" @@ -134,7 +134,7 @@ type Config struct { Availability api.NodeSpec_Availability // PluginGetter provides access to docker's plugin inventory. - PluginGetter plugingetter.PluginGetter + PluginGetter plugin.Getter // FIPS is a boolean stating whether the node is FIPS enabled FIPS bool diff --git a/node/plugin/pluginapi.go b/node/plugin/pluginapi.go new file mode 100644 index 0000000000..9dd2151c85 --- /dev/null +++ b/node/plugin/pluginapi.go @@ -0,0 +1,23 @@ +package plugin + +import "net" + +type Plugin interface { + Name() string + ScopedPath(string) string + Client() Client +} + +type PluginAddr interface { + Plugin + Addr() net.Addr +} + +type Client interface { + Call(method string, args, ret interface{}) error +} + +type Getter interface { + Get(name, capability string) (Plugin, error) + GetAllManagedPluginsByCap(capability string) []Plugin +} diff --git a/testutils/fake_plugingetter.go b/testutils/fake_plugingetter.go index f134b3b3ab..376324bfea 100644 --- a/testutils/fake_plugingetter.go +++ b/testutils/fake_plugingetter.go @@ -3,20 +3,20 @@ package testutils import ( "fmt" "net" - "time" - "github.com/docker/docker/pkg/plugingetter" - "github.com/docker/docker/pkg/plugins" + "github.com/moby/swarmkit/v2/node/plugin" ) const DockerCSIPluginNodeCap = "csinode" const DockerCSIPluginControllerCap = "csicontroller" type FakePluginGetter struct { - Plugins map[string]*FakeCompatPlugin + Plugins map[string]*FakePlugin } -func (f *FakePluginGetter) Get(name, capability string, _ int) (plugingetter.CompatPlugin, error) { +var _ plugin.Getter = &FakePluginGetter{} + +func (f *FakePluginGetter) Get(name, capability string) (plugin.Plugin, error) { if capability != DockerCSIPluginNodeCap && capability != DockerCSIPluginControllerCap { return nil, fmt.Errorf( "requested plugin with %s cap, but should only ever request %s or %s", @@ -30,63 +30,43 @@ func (f *FakePluginGetter) Get(name, capability string, _ int) (plugingetter.Com return nil, fmt.Errorf("plugin %s not found", name) } -// GetAllByCap is not needed in the fake and is unimplemented -func (f *FakePluginGetter) GetAllByCap(_ string) ([]plugingetter.CompatPlugin, error) { - return nil, nil -} - // GetAllManagedPluginsByCap returns all of the fake's plugins. If capability // is anything other than DockerCSIPluginCap, it returns nothing. -func (f *FakePluginGetter) GetAllManagedPluginsByCap(capability string) []plugingetter.CompatPlugin { +func (f *FakePluginGetter) GetAllManagedPluginsByCap(capability string) []plugin.Plugin { if capability != DockerCSIPluginNodeCap && capability != DockerCSIPluginControllerCap { return nil } - allPlugins := make([]plugingetter.CompatPlugin, 0, len(f.Plugins)) + allPlugins := make([]plugin.Plugin, 0, len(f.Plugins)) for _, plug := range f.Plugins { allPlugins = append(allPlugins, plug) } return allPlugins } -// Handle is not needed in the fake, so is unimplemented. -func (f *FakePluginGetter) Handle(_ string, _ func(string, *plugins.Client)) {} - -// fakeCompatPlugin is a fake implementing the plugingetter.CompatPlugin and -// plugingetter.PluginAddr interfaces -type FakeCompatPlugin struct { +type FakePlugin struct { PluginName string PluginAddr net.Addr Scope string } -func (f *FakeCompatPlugin) Name() string { +var _ plugin.PluginAddr = &FakePlugin{} + +func (f *FakePlugin) Name() string { return f.PluginName } -func (f *FakeCompatPlugin) ScopedPath(path string) string { +func (f *FakePlugin) ScopedPath(path string) string { if f.Scope != "" { return fmt.Sprintf("%s/%s", f.Scope, path) } return path } -func (f *FakeCompatPlugin) IsV1() bool { - return false -} - -func (f *FakeCompatPlugin) Client() *plugins.Client { +func (f *FakePlugin) Client() plugin.Client { return nil } -func (f *FakeCompatPlugin) Addr() net.Addr { +func (f *FakePlugin) Addr() net.Addr { return f.PluginAddr } - -func (f *FakeCompatPlugin) Timeout() time.Duration { - return time.Second -} - -func (f *FakeCompatPlugin) Protocol() string { - return "" -}