Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: plugin multiplexing: handle plugin client cleanup #13896

Merged
merged 16 commits into from
Feb 10, 2022

Conversation

fairclothjm
Copy link
Contributor

@fairclothjm fairclothjm commented Feb 4, 2022

Description

This is a follow up to the PR #13734 which added multiplexing support for DB plugins.

This PR makes the following changes

  • Ensure plugin processes are cleaned up for v5 and multiplexed plugins
    • this is handled by a cleanup function that is stored on the PluginClient instance
  • Move the context ID injection logic from the SDK to Core

To test multiplexing

  • build a v5 db plugin from main branch
  • build v6 multiplexed plugin from the feat-mux branch
  • build a vault binary from the multiplexing branch feat-mux
  • start vault and register the plugins
  • write the database configs and perform credential operations as normal

@fairclothjm fairclothjm requested review from a team and removed request for a team February 4, 2022 00:09
vault/plugin_catalog.go Outdated Show resolved Hide resolved
@vercel vercel bot temporarily deployed to Preview – vault February 4, 2022 15:10 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 4, 2022 15:10 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 4, 2022 17:23 Inactive
@vercel vercel bot temporarily deployed to Preview – vault February 4, 2022 17:23 Inactive
vault/plugin_catalog.go Outdated Show resolved Hide resolved
vault/plugin_catalog.go Outdated Show resolved Hide resolved
@fairclothjm fairclothjm changed the title feat: plugin multiplexing: use closure for plugin client cleanup feat: plugin multiplexing: handle plugin client cleanup Feb 4, 2022
@vercel vercel bot temporarily deployed to Preview – vault February 7, 2022 18:06 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 7, 2022 18:06 Inactive
@vercel vercel bot temporarily deployed to Preview – vault February 7, 2022 21:10 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 7, 2022 21:10 Inactive
vault/plugin_catalog.go Outdated Show resolved Hide resolved
vault/plugin_catalog.go Outdated Show resolved Hide resolved
@vercel vercel bot temporarily deployed to Preview – vault February 9, 2022 01:47 Inactive
@vercel vercel bot temporarily deployed to Preview – vault February 9, 2022 01:48 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 9, 2022 01:48 Inactive
vault/plugin_catalog.go Outdated Show resolved Hide resolved
vault/plugin_catalog.go Outdated Show resolved Hide resolved
vault/plugin_catalog.go Outdated Show resolved Hide resolved
vault/plugin_catalog.go Outdated Show resolved Hide resolved
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 9, 2022 20:02 Inactive
@vercel vercel bot temporarily deployed to Preview – vault February 9, 2022 20:02 Inactive
@@ -98,6 +99,8 @@ func CtxCancelIfCanceled(f context.CancelFunc, ctxCanceler context.Context) chan
return quitCh
}

// MultiplexingSupport returns true if a plugin supports multiplexing.
// Currently this is hardcoded for database plugins.
func MultiplexingSupport(version int) bool {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will likely need a Plugin Type arg in the future but I think it is ok to leave out for now.

vault/plugin_catalog.go Outdated Show resolved Hide resolved
NewPluginClient(ctx context.Context, pluginRunner *pluginutil.PluginRunner, config pluginutil.PluginClientConfig) (pluginutil.Multiplexer, error)
// NewPluginClient returns a client for managing the lifecycle of plugin
// processes
NewPluginClient(ctx context.Context, config pluginutil.PluginClientConfig) (pluginutil.PluginInstance, error)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me think whether we should be embedding pluginutil.RunnerUtil instead of duplicating the method signatures...

Copy link
Member

@calvn calvn Feb 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be more appropriate to name this NewPluginClientInstance now that the interface is renamed?

@vercel vercel bot temporarily deployed to Preview – vault February 9, 2022 20:48 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 9, 2022 20:48 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook February 9, 2022 20:57 Inactive
@vercel vercel bot temporarily deployed to Preview – vault February 9, 2022 20:57 Inactive
@fairclothjm fairclothjm merged commit 269df8e into feat-mux Feb 10, 2022
@fairclothjm fairclothjm deleted the feat-mux-plugin-cleanup branch February 10, 2022 18:11
fairclothjm added a commit that referenced this pull request Feb 14, 2022
* use closure for plugin client cleanup

* log and return errors; add comments

* move rpcClient wrapping to core for ID injection

* refactor core plugin client and sdk

* remove unused ID method

* refactor and only wrap clientConn on multiplexed plugins

* rename structs and do not export types

* Slight refactor of system view interface

* Revert "Slight refactor of system view interface"

This reverts commit 73d420e.

* Revert "Revert "Slight refactor of system view interface""

This reverts commit f755270.

* only provide pluginRunner arg to the internal newPluginClient method

* embed ClientProtocol in pluginClient and name logger

* Add back MLock support

* remove enableMlock arg from setupPluginCatalog

* rename plugin util interface to PluginClient

Co-authored-by: Brian Kassouf <bkassouf@hashicorp.com>
fairclothjm added a commit that referenced this pull request Feb 17, 2022
* feat: DB plugin multiplexing (#13734)

* WIP: start from main and get a plugin runner from core

* move MultiplexedClient map to plugin catalog
- call sys.NewPluginClient from PluginFactory
- updates to getPluginClient
- thread through isMetadataMode

* use go-plugin ClientProtocol interface
- call sys.NewPluginClient from dbplugin.NewPluginClient

* move PluginSets to dbplugin package
- export dbplugin HandshakeConfig
- small refactor of PluginCatalog.getPluginClient

* add removeMultiplexedClient; clean up on Close()
- call client.Kill from plugin catalog
- set rpcClient when muxed client exists

* add ID to dbplugin.DatabasePluginClient struct

* only create one plugin process per plugin type

* update NewPluginClient to return connection ID to sdk
- wrap grpc.ClientConn so we can inject the ID into context
- get ID from context on grpc server

* add v6 multiplexing  protocol version

* WIP: backwards compat for db plugins

* Ensure locking on plugin catalog access

- Create public GetPluginClient method for plugin catalog
- rename postgres db plugin

* use the New constructor for db plugins

* grpc server: use write lock for Close and rlock for CRUD

* cleanup MultiplexedClients on Close

* remove TODO

* fix multiplexing regression with grpc server connection

* cleanup grpc server instances on close

* embed ClientProtocol in Multiplexer interface

* use PluginClientConfig arg to make NewPluginClient plugin type agnostic

* create a new plugin process for non-muxed plugins

* feat: plugin multiplexing: handle plugin client cleanup (#13896)

* use closure for plugin client cleanup

* log and return errors; add comments

* move rpcClient wrapping to core for ID injection

* refactor core plugin client and sdk

* remove unused ID method

* refactor and only wrap clientConn on multiplexed plugins

* rename structs and do not export types

* Slight refactor of system view interface

* Revert "Slight refactor of system view interface"

This reverts commit 73d420e.

* Revert "Revert "Slight refactor of system view interface""

This reverts commit f755270.

* only provide pluginRunner arg to the internal newPluginClient method

* embed ClientProtocol in pluginClient and name logger

* Add back MLock support

* remove enableMlock arg from setupPluginCatalog

* rename plugin util interface to PluginClient

Co-authored-by: Brian Kassouf <bkassouf@hashicorp.com>

* feature: multiplexing: fix unit tests (#14007)

* fix grpc_server tests and add coverage

* update run_config tests

* add happy path test case for grpc_server ID from context

* update test helpers

* feat: multiplexing: handle v5 plugin compiled with new sdk

* add mux supported flag and increase test coverage

* set multiplexingSupport field in plugin server

* remove multiplexingSupport field in sdk

* revert postgres to non-multiplexed

* add comments on grpc server fields

* use pointer receiver on grpc server methods

* add changelog

* use pointer for grpcserver instance

* Use a gRPC server to determine if a plugin should be multiplexed

* Apply suggestions from code review

Co-authored-by: Brian Kassouf <briankassouf@users.noreply.github.com>

* add lock to removePluginClient

* add multiplexingSupport field to externalPlugin struct

* do not send nil to grpc MultiplexingSupport

* check err before logging

* handle locking scenario for cleanupFunc

* allow ServeConfigMultiplex to dispense v5 plugin

* reposition structs, add err check and comments

* add comment on locking for cleanupExternalPlugin

Co-authored-by: Brian Kassouf <bkassouf@hashicorp.com>
Co-authored-by: Brian Kassouf <briankassouf@users.noreply.github.com>
fairclothjm added a commit that referenced this pull request Feb 17, 2022
* feat: DB plugin multiplexing (#13734)

* WIP: start from main and get a plugin runner from core

* move MultiplexedClient map to plugin catalog
- call sys.NewPluginClient from PluginFactory
- updates to getPluginClient
- thread through isMetadataMode

* use go-plugin ClientProtocol interface
- call sys.NewPluginClient from dbplugin.NewPluginClient

* move PluginSets to dbplugin package
- export dbplugin HandshakeConfig
- small refactor of PluginCatalog.getPluginClient

* add removeMultiplexedClient; clean up on Close()
- call client.Kill from plugin catalog
- set rpcClient when muxed client exists

* add ID to dbplugin.DatabasePluginClient struct

* only create one plugin process per plugin type

* update NewPluginClient to return connection ID to sdk
- wrap grpc.ClientConn so we can inject the ID into context
- get ID from context on grpc server

* add v6 multiplexing  protocol version

* WIP: backwards compat for db plugins

* Ensure locking on plugin catalog access

- Create public GetPluginClient method for plugin catalog
- rename postgres db plugin

* use the New constructor for db plugins

* grpc server: use write lock for Close and rlock for CRUD

* cleanup MultiplexedClients on Close

* remove TODO

* fix multiplexing regression with grpc server connection

* cleanup grpc server instances on close

* embed ClientProtocol in Multiplexer interface

* use PluginClientConfig arg to make NewPluginClient plugin type agnostic

* create a new plugin process for non-muxed plugins

* feat: plugin multiplexing: handle plugin client cleanup (#13896)

* use closure for plugin client cleanup

* log and return errors; add comments

* move rpcClient wrapping to core for ID injection

* refactor core plugin client and sdk

* remove unused ID method

* refactor and only wrap clientConn on multiplexed plugins

* rename structs and do not export types

* Slight refactor of system view interface

* Revert "Slight refactor of system view interface"

This reverts commit 73d420e.

* Revert "Revert "Slight refactor of system view interface""

This reverts commit f755270.

* only provide pluginRunner arg to the internal newPluginClient method

* embed ClientProtocol in pluginClient and name logger

* Add back MLock support

* remove enableMlock arg from setupPluginCatalog

* rename plugin util interface to PluginClient

Co-authored-by: Brian Kassouf <bkassouf@hashicorp.com>

* feature: multiplexing: fix unit tests (#14007)

* fix grpc_server tests and add coverage

* update run_config tests

* add happy path test case for grpc_server ID from context

* update test helpers

* feat: multiplexing: handle v5 plugin compiled with new sdk

* add mux supported flag and increase test coverage

* set multiplexingSupport field in plugin server

* remove multiplexingSupport field in sdk

* revert postgres to non-multiplexed

* add comments on grpc server fields

* use pointer receiver on grpc server methods

* add changelog

* use pointer for grpcserver instance

* Use a gRPC server to determine if a plugin should be multiplexed

* Apply suggestions from code review

Co-authored-by: Brian Kassouf <briankassouf@users.noreply.github.com>

* add lock to removePluginClient

* add multiplexingSupport field to externalPlugin struct

* do not send nil to grpc MultiplexingSupport

* check err before logging

* handle locking scenario for cleanupFunc

* allow ServeConfigMultiplex to dispense v5 plugin

* reposition structs, add err check and comments

* add comment on locking for cleanupExternalPlugin

* feature: multiplexing: handle error plugin shutdown

Co-authored-by: Brian Kassouf <bkassouf@hashicorp.com>
Co-authored-by: Brian Kassouf <briankassouf@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants