MM-57018: support reattaching plugins (#26421)
* ProfileImageBytes for EnsureBotOptions * leverage plugintest.NewAPI * fix linting * add UpdateUserRoles to plugin api * MM-57018: support reattaching plugins Expose a local-only API for reattaching plugins: instead of the server starting and managing the process itself, allow the plugin to be launched externally (eg within a unit test) and reattach to an existing server instance to provide the unit test with a fully functional RPC API, sidestepping the need for mocking the plugin API in most cases. In the future, this may become the basis for running plugins in a sidecar container. Fixes: https://mattermost.atlassian.net/browse/MM-57018 * drop unused supervisor.pid * factor out checkMinServerVersion * factor out startPluginServer * restore missing setPluginState on successful reattach * avoid passing around a stale registeredPlugin * inline initializePluginImplementation * have IsValid return an error * explicitly close rpcClient In the case of reattached plugins, the Unix socket won't necessarily disappear leaving the muxBrokers blocked indefinitely. And `Kill()` doesn't do anything if there's no process being managed. * explicitly detachPlugin * emphasize gRPC not being supported --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
f5ea554c96
Коммит
2230fb6f5f
@@ -4,6 +4,8 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
)
|
||||
|
||||
@@ -12,10 +14,51 @@ const (
|
||||
BotUserKey = InternalKeyPrefix + "botid"
|
||||
)
|
||||
|
||||
// Starts the serving of a Mattermost plugin over net/rpc. gRPC is not yet supported.
|
||||
// WithTestContext provides a context typically used to terminate a plugin from a unit test.
|
||||
func WithTestContext(ctx context.Context) func(*plugin.ServeConfig) error {
|
||||
return func(config *plugin.ServeConfig) error {
|
||||
if config.Test == nil {
|
||||
config.Test = &plugin.ServeTestConfig{}
|
||||
}
|
||||
|
||||
config.Test.Context = ctx
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithTestReattachConfigCh configures the channel to receive the ReattachConfig used to reattach
|
||||
// an externally launched plugin instance with the Mattermost server.
|
||||
func WithTestReattachConfigCh(reattachConfigCh chan<- *plugin.ReattachConfig) func(*plugin.ServeConfig) error {
|
||||
return func(config *plugin.ServeConfig) error {
|
||||
if config.Test == nil {
|
||||
config.Test = &plugin.ServeTestConfig{}
|
||||
}
|
||||
|
||||
config.Test.ReattachConfigCh = reattachConfigCh
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithTestCloseCh provides a channel that signals when the plugin exits.
|
||||
func WithTestCloseCh(closeCh chan<- struct{}) func(*plugin.ServeConfig) error {
|
||||
return func(config *plugin.ServeConfig) error {
|
||||
if config.Test == nil {
|
||||
config.Test = &plugin.ServeTestConfig{}
|
||||
}
|
||||
|
||||
config.Test.CloseCh = closeCh
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Starts the serving of a Mattermost plugin over net/rpc. gRPC is not supported.
|
||||
//
|
||||
// Call this when your plugin is ready to start.
|
||||
func ClientMain(pluginImplementation any) {
|
||||
// Call this when your plugin is ready to start. Options allow configuring plugins for testing
|
||||
// scenarios.
|
||||
func ClientMain(pluginImplementation any, opts ...func(config *plugin.ServeConfig) error) {
|
||||
impl, ok := pluginImplementation.(interface {
|
||||
SetAPI(api API)
|
||||
SetDriver(driver Driver)
|
||||
@@ -30,10 +73,19 @@ func ClientMain(pluginImplementation any) {
|
||||
"hooks": &hooksPlugin{hooks: pluginImplementation},
|
||||
}
|
||||
|
||||
plugin.Serve(&plugin.ServeConfig{
|
||||
serveConfig := &plugin.ServeConfig{
|
||||
HandshakeConfig: handshake,
|
||||
Plugins: pluginMap,
|
||||
})
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
err := opt(serveConfig)
|
||||
if err != nil {
|
||||
panic("failed to start serving plugin: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
plugin.Serve(serveConfig)
|
||||
}
|
||||
|
||||
type MattermostPlugin struct {
|
||||
|
||||
Ссылка в новой задаче
Block a user