Plugins: Make renderer service load renderer plugin (#77854)

* rendering service loads renderer plugin

* update naming

* tidy

* apply PR feedback

* fix missing feature manager

* fix step

* set plugin
This commit is contained in:
Will Browne
2023-12-14 17:33:29 +01:00
committed by GitHub
parent a7a51bf2d8
commit ce8fd14f1f
15 changed files with 220 additions and 71 deletions

View File

@@ -7,14 +7,13 @@ import (
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/setting"
)
type dummyPluginManager struct{}
func (d *dummyPluginManager) Renderer(_ context.Context) *plugins.Plugin {
return nil
func (d *dummyPluginManager) Renderer(_ context.Context) (Plugin, bool) {
return nil, false
}
var dummyRendererUrl = "http://dummyurl.com"

View File

@@ -8,10 +8,6 @@ import (
"github.com/grafana/grafana/pkg/plugins/backendplugin/pluginextensionv2"
)
func (rs *RenderingService) startPlugin(ctx context.Context) error {
return rs.pluginInfo.Start(ctx)
}
func (rs *RenderingService) renderViaPlugin(ctx context.Context, renderKey string, opts Opts) (*RenderResult, error) {
// gives plugin some additional time to timeout and return possible errors.
ctx, cancel := context.WithTimeout(ctx, getRequestTimeout(opts.TimeoutOpts))
@@ -45,7 +41,11 @@ func (rs *RenderingService) renderViaPlugin(ctx context.Context, renderKey strin
}
rs.log.Debug("Calling renderer plugin", "req", req)
rsp, err := rs.pluginInfo.Renderer.Render(ctx, req)
rc, err := rs.plugin.Client()
if err != nil {
return nil, err
}
rsp, err := rc.Render(ctx, req)
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
rs.log.Info("Rendering timed out")
return nil, ErrTimeout
@@ -89,7 +89,12 @@ func (rs *RenderingService) renderCSVViaPlugin(ctx context.Context, renderKey st
}
rs.log.Debug("Calling renderer plugin", "req", req)
rsp, err := rs.pluginInfo.Renderer.RenderCSV(ctx, req)
rc, err := rs.plugin.Client()
if err != nil {
return nil, err
}
rsp, err := rc.RenderCSV(ctx, req)
if err != nil {
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
rs.log.Info("Rendering timed out")

View File

@@ -18,7 +18,7 @@ import (
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/infra/remotecache"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin/pluginextensionv2"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
@@ -28,7 +28,7 @@ var _ Service = (*RenderingService)(nil)
type RenderingService struct {
log log.Logger
pluginInfo *plugins.Plugin
plugin Plugin
renderAction renderFunc
renderCSVAction renderCSVFunc
sanitizeSVGAction sanitizeFunc
@@ -43,10 +43,20 @@ type RenderingService struct {
Cfg *setting.Cfg
features *featuremgmt.FeatureManager
RemoteCacheService *remotecache.RemoteCache
RendererPluginManager plugins.RendererManager
RendererPluginManager PluginManager
}
func ProvideService(cfg *setting.Cfg, features *featuremgmt.FeatureManager, remoteCache *remotecache.RemoteCache, rm plugins.RendererManager) (*RenderingService, error) {
type PluginManager interface {
Renderer(ctx context.Context) (Plugin, bool)
}
type Plugin interface {
Client() (pluginextensionv2.RendererPlugin, error)
Start(ctx context.Context) error
Version() string
}
func ProvideService(cfg *setting.Cfg, features *featuremgmt.FeatureManager, remoteCache *remotecache.RemoteCache, rm PluginManager) (*RenderingService, error) {
// ensure ImagesDir exists
err := os.MkdirAll(cfg.ImagesDir, 0700)
if err != nil {
@@ -167,15 +177,13 @@ func (rs *RenderingService) Run(ctx context.Context) error {
}
}
if rs.pluginAvailable(ctx) {
if rp, exists := rs.RendererPluginManager.Renderer(ctx); exists {
rs.log = rs.log.New("renderer", "plugin")
rs.pluginInfo = rs.RendererPluginManager.Renderer(ctx)
if err := rs.startPlugin(ctx); err != nil {
rs.plugin = rp
if err := rs.plugin.Start(ctx); err != nil {
return err
}
rs.version = rs.pluginInfo.Info.Version
rs.version = rp.Version()
rs.renderAction = rs.renderViaPlugin
rs.renderCSVAction = rs.renderCSVViaPlugin
rs.sanitizeSVGAction = rs.sanitizeSVGViaPlugin
@@ -193,7 +201,8 @@ func (rs *RenderingService) Run(ctx context.Context) error {
}
func (rs *RenderingService) pluginAvailable(ctx context.Context) bool {
return rs.RendererPluginManager.Renderer(ctx) != nil
_, exists := rs.RendererPluginManager.Renderer(ctx)
return exists
}
func (rs *RenderingService) remoteAvailable() bool {

View File

@@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/setting"
)
@@ -104,15 +103,11 @@ func TestRenderErrorImage(t *testing.T) {
})
}
type unavailableRendererManager struct{}
func (m unavailableRendererManager) Renderer(_ context.Context) *plugins.Plugin { return nil }
func TestRenderUnavailableError(t *testing.T) {
rs := RenderingService{
Cfg: &setting.Cfg{},
log: log.New("test"),
RendererPluginManager: unavailableRendererManager{},
RendererPluginManager: &dummyPluginManager{},
}
opts := Opts{ErrorOpts: ErrorOpts{ErrorRenderUnavailable: true}}
result, err := rs.Render(context.Background(), opts, nil)

View File

@@ -160,7 +160,11 @@ func (rs *RenderingService) sanitizeSVGViaPlugin(ctx context.Context, req *Sanit
}
rs.log.Debug("Sanitizer - plugin: calling", "filename", req.Filename, "contentLength", len(req.Content))
rsp, err := rs.pluginInfo.Renderer.Sanitize(ctx, grpcReq)
rc, err := rs.plugin.Client()
if err != nil {
return nil, err
}
rsp, err := rc.Sanitize(ctx, grpcReq)
if err != nil {
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
rs.log.Info("Sanitizer - plugin: time out")