mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 22:57:16 +08:00
Plugins: Use grafana-plugin-sdk-go v0.5.0 (#21116)
* fix dispense * plugin loading refactor Moves common functionality of registering, starting, stopping and restarting backend plugins to backendplugin package. * simplify plugin descriptors * target sdk v0.5.0 Co-authored-by: Kyle Brandt <kyle@kbrandt.com>
This commit is contained in:

committed by
Kyle Brandt

parent
5321e7536f
commit
baba1634b8
@ -1,12 +1,10 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||
|
||||
@ -14,13 +12,12 @@ import (
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
|
||||
datasourceV1 "github.com/grafana/grafana-plugin-model/go/datasource"
|
||||
sdk "github.com/grafana/grafana-plugin-sdk-go/datasource"
|
||||
sdk "github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins/datasource/wrapper"
|
||||
"github.com/grafana/grafana/pkg/tsdb"
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// DataSourcePlugin contains all metadata about a datasource plugin
|
||||
@ -41,9 +38,6 @@ type DataSourcePlugin struct {
|
||||
Backend bool `json:"backend,omitempty"`
|
||||
Executable string `json:"executable,omitempty"`
|
||||
SDK bool `json:"sdk,omitempty"`
|
||||
|
||||
log log.Logger
|
||||
client *plugin.Client
|
||||
}
|
||||
|
||||
func (p *DataSourcePlugin) Load(decoder *json.Decoder, pluginDir string) error {
|
||||
@ -59,23 +53,16 @@ func (p *DataSourcePlugin) Load(decoder *json.Decoder, pluginDir string) error {
|
||||
return errutil.Wrapf(err, "Failed to register plugin")
|
||||
}
|
||||
|
||||
DataSources[p.Id] = p
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *DataSourcePlugin) startBackendPlugin(ctx context.Context, log log.Logger) error {
|
||||
p.log = log.New("plugin-id", p.Id)
|
||||
|
||||
if err := p.spawnSubProcess(); err != nil {
|
||||
return err
|
||||
if p.Backend {
|
||||
cmd := ComposePluginStartCommmand(p.Executable)
|
||||
fullpath := path.Join(p.PluginDir, cmd)
|
||||
descriptor := backendplugin.NewBackendPluginDescriptor(p.Id, fullpath)
|
||||
if err := backendplugin.Register(descriptor, p.onPluginStart); err != nil {
|
||||
return errutil.Wrapf(err, "Failed to register backend plugin")
|
||||
}
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := p.restartKilledProcess(ctx); err != nil {
|
||||
p.log.Error("Attempting to restart killed process failed", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
DataSources[p.Id] = p
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -83,71 +70,37 @@ func (p *DataSourcePlugin) isVersionOne() bool {
|
||||
return !p.SDK
|
||||
}
|
||||
|
||||
func (p *DataSourcePlugin) spawnSubProcess() error {
|
||||
cmd := ComposePluginStartCommmand(p.Executable)
|
||||
fullpath := path.Join(p.PluginDir, cmd)
|
||||
|
||||
p.client = backendplugin.NewDatasourceClient(p.Id, fullpath, p.log)
|
||||
|
||||
rpcClient, err := p.client.Client()
|
||||
func (p *DataSourcePlugin) onPluginStart(pluginID string, client *plugin.Client, logger log.Logger) error {
|
||||
rpcClient, err := client.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
raw, err := rpcClient.Dispense(p.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if p.client.NegotiatedVersion() == 1 {
|
||||
if client.NegotiatedVersion() == 1 {
|
||||
raw, err := rpcClient.Dispense(pluginID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
plugin := raw.(datasourceV1.DatasourcePlugin)
|
||||
|
||||
tsdb.RegisterTsdbQueryEndpoint(p.Id, func(dsInfo *models.DataSource) (tsdb.TsdbQueryEndpoint, error) {
|
||||
return wrapper.NewDatasourcePluginWrapper(p.log, plugin), nil
|
||||
tsdb.RegisterTsdbQueryEndpoint(pluginID, func(dsInfo *models.DataSource) (tsdb.TsdbQueryEndpoint, error) {
|
||||
return wrapper.NewDatasourcePluginWrapper(logger, plugin), nil
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
plugin, ok := raw.(sdk.DatasourcePlugin)
|
||||
raw, err := rpcClient.Dispense("backend")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
plugin, ok := raw.(sdk.BackendPlugin)
|
||||
if !ok {
|
||||
return fmt.Errorf("unxpected type %T, expeced sdk.DatasourcePlugin", raw)
|
||||
return fmt.Errorf("unexpected type %T, expected sdk.Plugin", raw)
|
||||
}
|
||||
|
||||
tsdb.RegisterTsdbQueryEndpoint(p.Id, func(dsInfo *models.DataSource) (tsdb.TsdbQueryEndpoint, error) {
|
||||
return wrapper.NewDatasourcePluginWrapperV2(p.log, plugin), nil
|
||||
tsdb.RegisterTsdbQueryEndpoint(pluginID, func(dsInfo *models.DataSource) (tsdb.TsdbQueryEndpoint, error) {
|
||||
return wrapper.NewDatasourcePluginWrapperV2(logger, plugin), nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *DataSourcePlugin) restartKilledProcess(ctx context.Context) error {
|
||||
ticker := time.NewTicker(time.Second * 1)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
if err := ctx.Err(); err != nil && !xerrors.Is(err, context.Canceled) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case <-ticker.C:
|
||||
if !p.client.Exited() {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := p.spawnSubProcess(); err != nil {
|
||||
p.log.Error("Failed to restart plugin", "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
p.log.Debug("Plugin process restarted")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *DataSourcePlugin) Kill() {
|
||||
if p.client != nil {
|
||||
p.log.Debug("Killing subprocess ", "name", p.Name)
|
||||
p.client.Kill()
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user