mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 23:52:19 +08:00
122 lines
3.6 KiB
Go
122 lines
3.6 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/grafana/grafana/pkg/plugins"
|
|
"github.com/grafana/grafana/pkg/plugins/config"
|
|
"github.com/grafana/grafana/pkg/plugins/log"
|
|
"github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath"
|
|
"github.com/grafana/grafana/pkg/plugins/pluginassets"
|
|
)
|
|
|
|
type pluginFactoryFunc func(p *plugins.FoundBundle, pluginClass plugins.Class, sig plugins.Signature) (*plugins.Plugin, error)
|
|
|
|
// DefaultPluginFactory is the default plugin factory used by the Construct step of the Bootstrap stage.
|
|
//
|
|
// It creates the plugin using plugin information found during the Discovery stage and makes use of the assetPath
|
|
// service to set the plugin's BaseURL, Module, Logos and Screenshots fields.
|
|
type DefaultPluginFactory struct {
|
|
assetPath *assetpath.Service
|
|
features *config.Features
|
|
}
|
|
|
|
// NewDefaultPluginFactory returns a new DefaultPluginFactory.
|
|
func NewDefaultPluginFactory(features *config.Features, assetPath *assetpath.Service) *DefaultPluginFactory {
|
|
return &DefaultPluginFactory{assetPath: assetPath, features: features}
|
|
}
|
|
|
|
func (f *DefaultPluginFactory) createPlugin(bundle *plugins.FoundBundle, class plugins.Class,
|
|
sig plugins.Signature) (*plugins.Plugin, error) {
|
|
parentInfo := pluginassets.NewPluginInfo(bundle.Primary.JSONData, class, bundle.Primary.FS, nil)
|
|
plugin, err := f.newPlugin(bundle.Primary, class, sig, parentInfo)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(bundle.Children) == 0 {
|
|
return plugin, nil
|
|
}
|
|
|
|
plugin.Children = make([]*plugins.Plugin, 0, len(bundle.Children))
|
|
for _, child := range bundle.Children {
|
|
childInfo := pluginassets.NewPluginInfo(child.JSONData, class, child.FS, &parentInfo)
|
|
cp, err := f.newPlugin(*child, class, sig, childInfo)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cp.Parent = plugin
|
|
plugin.Children = append(plugin.Children, cp)
|
|
}
|
|
|
|
return plugin, nil
|
|
}
|
|
|
|
func (f *DefaultPluginFactory) newPlugin(p plugins.FoundPlugin, class plugins.Class, sig plugins.Signature,
|
|
info pluginassets.PluginInfo) (*plugins.Plugin, error) {
|
|
baseURL, err := f.assetPath.Base(info)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("base url: %w", err)
|
|
}
|
|
moduleURL, err := f.assetPath.Module(info)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("module url: %w", err)
|
|
}
|
|
plugin := &plugins.Plugin{
|
|
JSONData: p.JSONData,
|
|
Class: class,
|
|
FS: p.FS,
|
|
BaseURL: baseURL,
|
|
Module: moduleURL,
|
|
Signature: sig.Status,
|
|
SignatureType: sig.Type,
|
|
SignatureOrg: sig.SigningOrg,
|
|
}
|
|
|
|
plugin.SetLogger(log.New(fmt.Sprintf("plugin.%s", plugin.ID)))
|
|
if err = setImages(plugin, f.assetPath, info); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if f.features.LocalizationForPlugins {
|
|
if err := setTranslations(plugin, f.assetPath, info); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return plugin, nil
|
|
}
|
|
|
|
func setImages(p *plugins.Plugin, assetPath *assetpath.Service, info pluginassets.PluginInfo) error {
|
|
var err error
|
|
for _, dst := range []*string{&p.Info.Logos.Small, &p.Info.Logos.Large} {
|
|
if len(*dst) == 0 {
|
|
*dst = assetPath.DefaultLogoPath(p.Type)
|
|
continue
|
|
}
|
|
|
|
*dst, err = assetPath.RelativeURL(info, *dst)
|
|
if err != nil {
|
|
return fmt.Errorf("logo: %w", err)
|
|
}
|
|
}
|
|
for i := 0; i < len(p.Info.Screenshots); i++ {
|
|
screenshot := &p.Info.Screenshots[i]
|
|
screenshot.Path, err = assetPath.RelativeURL(info, screenshot.Path)
|
|
if err != nil {
|
|
return fmt.Errorf("screenshot %d relative url: %w", i, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func setTranslations(p *plugins.Plugin, assetPath *assetpath.Service, info pluginassets.PluginInfo) error {
|
|
translations, err := assetPath.GetTranslations(info)
|
|
if err != nil {
|
|
return fmt.Errorf("set translations: %w", err)
|
|
}
|
|
|
|
p.Translations = translations
|
|
return nil
|
|
}
|