mattermost/server/public/model/plugin_reattach.go
Jesse Hallam 2230fb6f5f
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>
2024-04-11 11:10:25 -04:00

59 lines
1.6 KiB
Go

package model
import (
"net"
"net/http"
"github.com/hashicorp/go-plugin"
)
// PluginReattachConfig is a serializable version of go-plugin's ReattachConfig.
type PluginReattachConfig struct {
Protocol string
ProtocolVersion int
Addr net.UnixAddr
Pid int
Test bool
}
func NewPluginReattachConfig(pluginReattachmentConfig *plugin.ReattachConfig) *PluginReattachConfig {
return &PluginReattachConfig{
Protocol: string(pluginReattachmentConfig.Protocol),
ProtocolVersion: pluginReattachmentConfig.ProtocolVersion,
Addr: net.UnixAddr{
Name: pluginReattachmentConfig.Addr.String(),
Net: pluginReattachmentConfig.Addr.Network(),
},
Pid: pluginReattachmentConfig.Pid,
Test: pluginReattachmentConfig.Test,
}
}
func (prc *PluginReattachConfig) ToHashicorpPluginReattachmentConfig() *plugin.ReattachConfig {
addr := prc.Addr
return &plugin.ReattachConfig{
Protocol: plugin.Protocol(prc.Protocol),
ProtocolVersion: prc.ProtocolVersion,
Addr: &addr,
Pid: prc.Pid,
ReattachFunc: nil,
Test: prc.Test,
}
}
type PluginReattachRequest struct {
Manifest *Manifest
PluginReattachConfig *PluginReattachConfig
}
func (prr *PluginReattachRequest) IsValid() *AppError {
if prr.Manifest == nil {
return NewAppError("PluginReattachRequest.IsValid", "plugin_reattach_request.is_valid.manifest.app_error", nil, "", http.StatusBadRequest)
}
if prr.PluginReattachConfig == nil {
return NewAppError("PluginReattachRequest.IsValid", "plugin_reattach_request.is_valid.plugin_reattach_config.app_error", nil, "", http.StatusBadRequest)
}
return nil
}