Plugins: Add inititialization stage to plugin loader pipeline (#72667)

* first pass

* migrate tests

* simplify

* fix comments

* fix linter

* nil checks

* remove comment
This commit is contained in:
Will Browne 2023-08-02 18:29:12 +02:00 committed by GitHub
parent 77e7ae2a1b
commit ad2705fa0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 1809 additions and 1166 deletions

View File

@ -73,11 +73,12 @@ func TestCallResource(t *testing.T) {
discovery := pipeline.ProvideDiscoveryStage(pCfg, finder.NewLocalFinder(pCfg.DevMode), reg) discovery := pipeline.ProvideDiscoveryStage(pCfg, finder.NewLocalFinder(pCfg.DevMode), reg)
bootstrap := pipeline.ProvideBootstrapStage(pCfg, signature.ProvideService(pCfg, statickey.New()), assetpath.ProvideService(pluginscdn.ProvideService(pCfg))) bootstrap := pipeline.ProvideBootstrapStage(pCfg, signature.ProvideService(pCfg, statickey.New()), assetpath.ProvideService(pluginscdn.ProvideService(pCfg)))
initialize := pipeline.ProvideInitializationStage(pCfg, reg, fakes.NewFakeLicensingService(), provider.ProvideService(coreRegistry))
l := loader.ProvideService(pCfg, fakes.NewFakeLicensingService(), signature.NewUnsignedAuthorizer(pCfg), l := loader.ProvideService(pCfg, signature.NewUnsignedAuthorizer(pCfg),
reg, provider.ProvideService(coreRegistry), fakes.NewFakeRoleRegistry(), reg, fakes.NewFakeRoleRegistry(),
assetpath.ProvideService(pluginscdn.ProvideService(pCfg)), assetpath.ProvideService(pluginscdn.ProvideService(pCfg)),
angularInspector, &fakes.FakeOauthService{}, discovery, bootstrap) angularInspector, &fakes.FakeOauthService{}, discovery, bootstrap, initialize)
srcs := sources.ProvideService(cfg, pCfg) srcs := sources.ProvideService(cfg, pCfg)
ps, err := store.ProvideService(reg, srcs, l) ps, err := store.ProvideService(reg, srcs, l)
require.NoError(t, err) require.NoError(t, err)

View File

@ -463,3 +463,36 @@ func (pr *FakePluginStore) Plugins(_ context.Context, pluginTypes ...plugins.Typ
return result return result
} }
type FakeDiscoverer struct {
DiscoverFunc func(ctx context.Context, src plugins.PluginSource) ([]*plugins.FoundBundle, error)
}
func (f *FakeDiscoverer) Discover(ctx context.Context, src plugins.PluginSource) ([]*plugins.FoundBundle, error) {
if f.DiscoverFunc != nil {
return f.DiscoverFunc(ctx, src)
}
return []*plugins.FoundBundle{}, nil
}
type FakeBootstrapper struct {
BootstrapFunc func(ctx context.Context, src plugins.PluginSource, bundles []*plugins.FoundBundle) ([]*plugins.Plugin, error)
}
func (f *FakeBootstrapper) Bootstrap(ctx context.Context, src plugins.PluginSource, bundles []*plugins.FoundBundle) ([]*plugins.Plugin, error) {
if f.BootstrapFunc != nil {
return f.BootstrapFunc(ctx, src, bundles)
}
return []*plugins.Plugin{}, nil
}
type FakeInitializer struct {
IntializeFunc func(ctx context.Context, ps []*plugins.Plugin) ([]*plugins.Plugin, error)
}
func (f *FakeInitializer) Initialize(ctx context.Context, ps []*plugins.Plugin) ([]*plugins.Plugin, error) {
if f.IntializeFunc != nil {
return f.IntializeFunc(ctx, ps)
}
return []*plugins.Plugin{}, nil
}

View File

@ -1,43 +0,0 @@
package initializer
import (
"context"
"errors"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/envvars"
)
type Initializer struct {
envVarProvider envvars.Provider
backendProvider plugins.BackendFactoryProvider
}
func New(cfg *config.Cfg, backendProvider plugins.BackendFactoryProvider, license plugins.Licensing) Initializer {
return Initializer{
envVarProvider: envvars.NewProvider(cfg, license),
backendProvider: backendProvider,
}
}
func (i *Initializer) Initialize(ctx context.Context, p *plugins.Plugin) error {
if p.Backend {
backendFactory := i.backendProvider.BackendFactory(ctx, p)
if backendFactory == nil {
return errors.New("could not find backend factory for plugin")
}
env, err := i.envVarProvider.Get(ctx, p)
if err != nil {
return err
}
if backendClient, err := backendFactory(p.ID, p.Logger(), env); err != nil {
return err
} else {
p.RegisterClient(backendClient)
}
}
return nil
}

View File

@ -11,9 +11,9 @@ import (
"github.com/grafana/grafana/pkg/plugins/log" "github.com/grafana/grafana/pkg/plugins/log"
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector" "github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector"
"github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath" "github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath"
"github.com/grafana/grafana/pkg/plugins/manager/loader/initializer"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap" "github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery" "github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/initialization"
"github.com/grafana/grafana/pkg/plugins/manager/process" "github.com/grafana/grafana/pkg/plugins/manager/process"
"github.com/grafana/grafana/pkg/plugins/manager/registry" "github.com/grafana/grafana/pkg/plugins/manager/registry"
"github.com/grafana/grafana/pkg/plugins/manager/signature" "github.com/grafana/grafana/pkg/plugins/manager/signature"
@ -24,13 +24,13 @@ import (
var _ plugins.ErrorResolver = (*Loader)(nil) var _ plugins.ErrorResolver = (*Loader)(nil)
type Loader struct { type Loader struct {
discovery discovery.Discoverer discovery discovery.Discoverer
bootstrap bootstrap.Bootstrapper bootstrap bootstrap.Bootstrapper
initializer initialization.Initializer
processManager process.Service processManager process.Service
pluginRegistry registry.Service pluginRegistry registry.Service
roleRegistry plugins.RoleRegistry roleRegistry plugins.RoleRegistry
pluginInitializer initializer.Initializer
signatureValidator signature.Validator signatureValidator signature.Validator
externalServiceRegistry oauth.ExternalServiceRegistry externalServiceRegistry oauth.ExternalServiceRegistry
assetPath *assetpath.Service assetPath *assetpath.Service
@ -42,23 +42,20 @@ type Loader struct {
errs map[string]*plugins.SignatureError errs map[string]*plugins.SignatureError
} }
func ProvideService(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLoaderAuthorizer, func ProvideService(cfg *config.Cfg, authorizer plugins.PluginLoaderAuthorizer,
pluginRegistry registry.Service, backendProvider plugins.BackendFactoryProvider, pluginRegistry registry.Service, roleRegistry plugins.RoleRegistry, assetPath *assetpath.Service,
roleRegistry plugins.RoleRegistry, assetPath *assetpath.Service,
angularInspector angularinspector.Inspector, externalServiceRegistry oauth.ExternalServiceRegistry, angularInspector angularinspector.Inspector, externalServiceRegistry oauth.ExternalServiceRegistry,
discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper) *Loader { discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper, initializer initialization.Initializer) *Loader {
return New(cfg, license, authorizer, pluginRegistry, backendProvider, process.NewManager(pluginRegistry), return New(cfg, authorizer, pluginRegistry, process.NewManager(pluginRegistry), roleRegistry, assetPath,
roleRegistry, assetPath, angularInspector, externalServiceRegistry, discovery, bootstrap) angularInspector, externalServiceRegistry, discovery, bootstrap, initializer)
} }
func New(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLoaderAuthorizer, func New(cfg *config.Cfg, authorizer plugins.PluginLoaderAuthorizer, pluginRegistry registry.Service,
pluginRegistry registry.Service, backendProvider plugins.BackendFactoryProvider,
processManager process.Service, roleRegistry plugins.RoleRegistry, assetPath *assetpath.Service, processManager process.Service, roleRegistry plugins.RoleRegistry, assetPath *assetpath.Service,
angularInspector angularinspector.Inspector, externalServiceRegistry oauth.ExternalServiceRegistry, angularInspector angularinspector.Inspector, externalServiceRegistry oauth.ExternalServiceRegistry,
discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper) *Loader { discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper, initializer initialization.Initializer) *Loader {
return &Loader{ return &Loader{
pluginRegistry: pluginRegistry, pluginRegistry: pluginRegistry,
pluginInitializer: initializer.New(cfg, backendProvider, license),
signatureValidator: signature.NewValidator(authorizer), signatureValidator: signature.NewValidator(authorizer),
processManager: processManager, processManager: processManager,
errs: make(map[string]*plugins.SignatureError), errs: make(map[string]*plugins.SignatureError),
@ -70,6 +67,7 @@ func New(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLo
externalServiceRegistry: externalServiceRegistry, externalServiceRegistry: externalServiceRegistry,
discovery: discovery, discovery: discovery,
bootstrap: bootstrap, bootstrap: bootstrap,
initializer: initializer,
} }
} }
@ -144,24 +142,9 @@ func (l *Loader) Load(ctx context.Context, src plugins.PluginSource) ([]*plugins
// </VERIFICATION STAGE> // </VERIFICATION STAGE>
// <INITIALIZATION STAGE> // <INITIALIZATION STAGE>
initializedPlugins := make([]*plugins.Plugin, 0, len(verifiedPlugins)) initializedPlugins, err := l.initializer.Initialize(ctx, verifiedPlugins)
for _, p := range verifiedPlugins { if err != nil {
err = l.pluginInitializer.Initialize(ctx, p) return nil, err
if err != nil {
l.log.Error("Could not initialize plugin", "pluginId", p.ID, "err", err)
continue
}
if err = l.pluginRegistry.Add(ctx, p); err != nil {
l.log.Error("Could not start plugin", "pluginId", p.ID, "err", err)
continue
}
if !p.IsCorePlugin() {
l.log.Info("Plugin registered", "pluginID", p.ID)
}
initializedPlugins = append(initializedPlugins, p)
} }
// </INITIALIZATION STAGE> // </INITIALIZATION STAGE>

File diff suppressed because it is too large Load Diff

View File

@ -124,11 +124,11 @@ func TestIntegrationPluginManager(t *testing.T) {
discovery := pipeline.ProvideDiscoveryStage(pCfg, finder.NewLocalFinder(pCfg.DevMode), reg) discovery := pipeline.ProvideDiscoveryStage(pCfg, finder.NewLocalFinder(pCfg.DevMode), reg)
bootstrap := pipeline.ProvideBootstrapStage(pCfg, signature.ProvideService(pCfg, statickey.New()), assetpath.ProvideService(pluginscdn.ProvideService(pCfg))) bootstrap := pipeline.ProvideBootstrapStage(pCfg, signature.ProvideService(pCfg, statickey.New()), assetpath.ProvideService(pluginscdn.ProvideService(pCfg)))
initialize := pipeline.ProvideInitializationStage(pCfg, reg, lic, provider.ProvideService(coreRegistry))
l := loader.ProvideService(pCfg, lic, signature.NewUnsignedAuthorizer(pCfg), l := loader.ProvideService(pCfg, signature.NewUnsignedAuthorizer(pCfg),
reg, provider.ProvideService(coreRegistry), fakes.NewFakeRoleRegistry(), reg, fakes.NewFakeRoleRegistry(),
assetpath.ProvideService(pluginscdn.ProvideService(pCfg)), assetpath.ProvideService(pluginscdn.ProvideService(pCfg)),
angularInspector, &fakes.FakeOauthService{}, discovery, bootstrap) angularInspector, &fakes.FakeOauthService{}, discovery, bootstrap, initialize)
srcs := sources.ProvideService(cfg, pCfg) srcs := sources.ProvideService(cfg, pCfg)
ps, err := store.ProvideService(reg, srcs, l) ps, err := store.ProvideService(reg, srcs, l)
require.NoError(t, err) require.NoError(t, err)

View File

@ -47,7 +47,7 @@ func New(cfg *config.Cfg, opts Opts) *Bootstrap {
opts.ConstructFunc = DefaultConstructFunc(signature.DefaultCalculator(cfg), assetpath.DefaultService(cfg)) opts.ConstructFunc = DefaultConstructFunc(signature.DefaultCalculator(cfg), assetpath.DefaultService(cfg))
} }
if len(opts.DecorateFuncs) == 0 { if opts.DecorateFuncs == nil {
opts.DecorateFuncs = DefaultDecorateFuncs opts.DecorateFuncs = DefaultDecorateFuncs
} }

View File

@ -45,7 +45,7 @@ func New(cfg *config.Cfg, opts Opts) *Discovery {
opts.FindFunc = DefaultFindFunc(cfg) opts.FindFunc = DefaultFindFunc(cfg)
} }
if len(opts.FindFilterFuncs) == 0 { if opts.FindFilterFuncs == nil {
opts.FindFilterFuncs = []FindFilterFunc{} // no filters by default opts.FindFilterFuncs = []FindFilterFunc{} // no filters by default
} }

View File

@ -0,0 +1,6 @@
// Package initialization defines the fourth stage of the plugin loader pipeline.
//
// The Initialization stage must implement the Initializer interface.
// - Initialize(ctx context.Context, ps []*plugins.Plugin) ([]*plugins.Plugin, error)
package initialization

View File

@ -0,0 +1,67 @@
package initialization
import (
"context"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/log"
)
// Initializer is responsible for the Initialization stage of the plugin loader pipeline.
type Initializer interface {
Initialize(ctx context.Context, ps []*plugins.Plugin) ([]*plugins.Plugin, error)
}
// InitializeFunc is the function used for the Initialize step of the Initialization stage.
type InitializeFunc func(ctx context.Context, p *plugins.Plugin) (*plugins.Plugin, error)
type Initialize struct {
cfg *config.Cfg
initializeSteps []InitializeFunc
log log.Logger
}
type Opts struct {
InitializeFuncs []InitializeFunc
}
// New returns a new Initialization stage.
func New(cfg *config.Cfg, opts Opts) *Initialize {
if opts.InitializeFuncs == nil {
opts.InitializeFuncs = []InitializeFunc{}
}
return &Initialize{
cfg: cfg,
initializeSteps: opts.InitializeFuncs,
log: log.New("plugins.initialization"),
}
}
// Initialize will execute the Initialize steps of the Initialization stage.
func (i *Initialize) Initialize(ctx context.Context, ps []*plugins.Plugin) ([]*plugins.Plugin, error) {
if len(i.initializeSteps) == 0 {
return ps, nil
}
var err error
initializedPlugins := make([]*plugins.Plugin, 0, len(ps))
for _, p := range ps {
var ip *plugins.Plugin
stepFailed := false
for _, init := range i.initializeSteps {
ip, err = init(ctx, p)
if err != nil {
stepFailed = true
i.log.Error("Could not initialize plugin", "pluginId", p.ID, "err", err)
break
}
}
if !stepFailed {
initializedPlugins = append(initializedPlugins, ip)
}
}
return initializedPlugins, nil
}

View File

@ -0,0 +1,90 @@
package initialization
import (
"context"
"errors"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/envvars"
"github.com/grafana/grafana/pkg/plugins/log"
"github.com/grafana/grafana/pkg/plugins/manager/registry"
)
// BackendClientInit implements an InitializeFunc for initializing a backend plugin process.
//
// It uses the envvars.Provider to retrieve the environment variables required for the plugin and the plugins.BackendFactoryProvider
// to get fetch backend factory, which is used to form a connection to the backend plugin process.
//
// Note: This step does not start the backend plugin process.
type BackendClientInit struct {
envVarProvider envvars.Provider
backendProvider plugins.BackendFactoryProvider
log log.Logger
}
// NewBackendClientInitStep returns a new InitializeFunc for registering a backend plugin process.
func NewBackendClientInitStep(envVarProvider envvars.Provider,
backendProvider plugins.BackendFactoryProvider) InitializeFunc {
return newBackendProcessRegistration(envVarProvider, backendProvider).Initialize
}
func newBackendProcessRegistration(envVarProvider envvars.Provider,
backendProvider plugins.BackendFactoryProvider) *BackendClientInit {
return &BackendClientInit{
backendProvider: backendProvider,
envVarProvider: envVarProvider,
log: log.New("plugins.backend.registration"),
}
}
// Initialize will initialize a backend plugin client, if the plugin is a backend plugin.
func (b *BackendClientInit) Initialize(ctx context.Context, p *plugins.Plugin) (*plugins.Plugin, error) {
if p.Backend {
backendFactory := b.backendProvider.BackendFactory(ctx, p)
if backendFactory == nil {
return nil, errors.New("could not find backend factory for plugin")
}
env, err := b.envVarProvider.Get(ctx, p)
if err != nil {
return nil, err
}
if backendClient, err := backendFactory(p.ID, p.Logger(), env); err != nil {
return nil, err
} else {
p.RegisterClient(backendClient)
}
}
return p, nil
}
// PluginRegistration implements an InitializeFunc for registering a plugin with the plugin registry.
type PluginRegistration struct {
pluginRegistry registry.Service
log log.Logger
}
// NewPluginRegistrationStep returns a new InitializeFunc for registering a plugin with the plugin registry.
func NewPluginRegistrationStep(pluginRegistry registry.Service) InitializeFunc {
return newPluginRegistration(pluginRegistry).Initialize
}
func newPluginRegistration(pluginRegistry registry.Service) *PluginRegistration {
return &PluginRegistration{
pluginRegistry: pluginRegistry,
log: log.New("plugins.registration"),
}
}
// Initialize registers the plugin with the plugin registry.
func (r *PluginRegistration) Initialize(ctx context.Context, p *plugins.Plugin) (*plugins.Plugin, error) {
if err := r.pluginRegistry.Add(ctx, p); err != nil {
r.log.Error("Could not register plugin", "pluginID", p.ID, "err", err)
return nil, errors.New("could not register plugin")
}
if !p.IsCorePlugin() {
r.log.Info("Plugin registered", "pluginID", p.ID)
}
return p, nil
}

View File

@ -1,10 +1,10 @@
package initializer package initialization
import ( import (
"context" "context"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin" "github.com/grafana/grafana/pkg/plugins/backendplugin"
@ -28,19 +28,15 @@ func TestInitializer_Initialize(t *testing.T) {
Class: plugins.ClassCore, Class: plugins.ClassCore,
} }
i := &Initializer{ stepFunc := NewBackendClientInitStep(&fakeEnvVarsProvider{}, &fakeBackendProvider{plugin: p})
backendProvider: &fakeBackendProvider{
plugin: p,
},
envVarProvider: &fakeEnvVarsProvider{},
}
err := i.Initialize(context.Background(), p) var err error
assert.NoError(t, err) p, err = stepFunc(context.Background(), p)
require.NoError(t, err)
c, exists := p.Client() c, exists := p.Client()
assert.True(t, exists) require.True(t, exists)
assert.NotNil(t, c) require.NotNil(t, c)
}) })
t.Run("renderer", func(t *testing.T) { t.Run("renderer", func(t *testing.T) {
@ -56,19 +52,15 @@ func TestInitializer_Initialize(t *testing.T) {
Class: plugins.ClassExternal, Class: plugins.ClassExternal,
} }
i := &Initializer{ stepFunc := NewBackendClientInitStep(&fakeEnvVarsProvider{}, &fakeBackendProvider{plugin: p})
backendProvider: &fakeBackendProvider{
plugin: p,
},
envVarProvider: &fakeEnvVarsProvider{},
}
err := i.Initialize(context.Background(), p) var err error
assert.NoError(t, err) p, err = stepFunc(context.Background(), p)
require.NoError(t, err)
c, exists := p.Client() c, exists := p.Client()
assert.True(t, exists) require.True(t, exists)
assert.NotNil(t, c) require.NotNil(t, c)
}) })
t.Run("secretsmanager", func(t *testing.T) { t.Run("secretsmanager", func(t *testing.T) {
@ -84,19 +76,15 @@ func TestInitializer_Initialize(t *testing.T) {
Class: plugins.ClassExternal, Class: plugins.ClassExternal,
} }
i := &Initializer{ stepFunc := NewBackendClientInitStep(&fakeEnvVarsProvider{}, &fakeBackendProvider{plugin: p})
backendProvider: &fakeBackendProvider{
plugin: p,
},
envVarProvider: &fakeEnvVarsProvider{},
}
err := i.Initialize(context.Background(), p) var err error
assert.NoError(t, err) p, err = stepFunc(context.Background(), p)
require.NoError(t, err)
c, exists := p.Client() c, exists := p.Client()
assert.True(t, exists) require.True(t, exists)
assert.NotNil(t, c) require.NotNil(t, c)
}) })
t.Run("non backend plugin app", func(t *testing.T) { t.Run("non backend plugin app", func(t *testing.T) {
@ -106,19 +94,17 @@ func TestInitializer_Initialize(t *testing.T) {
}, },
} }
i := &Initializer{ i := NewBackendClientInitStep(&fakeEnvVarsProvider{}, &fakeBackendProvider{
backendProvider: &fakeBackendProvider{ plugin: p,
plugin: p, })
},
envVarProvider: &fakeEnvVarsProvider{},
}
err := i.Initialize(context.Background(), p) var err error
assert.NoError(t, err) p, err = i(context.Background(), p)
require.NoError(t, err)
c, exists := p.Client() c, exists := p.Client()
assert.False(t, exists) require.False(t, exists)
assert.Nil(t, c) require.Nil(t, c)
}) })
} }

View File

@ -0,0 +1,47 @@
package loader
import (
"context"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
pluginsLoader "github.com/grafana/grafana/pkg/plugins/manager/loader"
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector"
"github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/initialization"
"github.com/grafana/grafana/pkg/plugins/manager/process"
"github.com/grafana/grafana/pkg/plugins/manager/registry"
"github.com/grafana/grafana/pkg/plugins/oauth"
)
var _ plugins.ErrorResolver = (*Loader)(nil)
var _ pluginsLoader.Service = (*Loader)(nil)
type Loader struct {
loader *pluginsLoader.Loader
}
func ProvideService(cfg *config.Cfg, authorizer plugins.PluginLoaderAuthorizer, processManager process.Service,
pluginRegistry registry.Service, roleRegistry plugins.RoleRegistry, assetPath *assetpath.Service,
angularInspector angularinspector.Inspector, externalServiceRegistry oauth.ExternalServiceRegistry,
discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper, initializer initialization.Initializer,
) *Loader {
return &Loader{
loader: pluginsLoader.New(cfg, authorizer, pluginRegistry, processManager, roleRegistry, assetPath,
angularInspector, externalServiceRegistry, discovery, bootstrap, initializer),
}
}
func (l *Loader) Load(ctx context.Context, src plugins.PluginSource) ([]*plugins.Plugin, error) {
return l.loader.Load(ctx, src)
}
func (l *Loader) Unload(ctx context.Context, pluginID string) error {
return l.loader.Unload(ctx, pluginID)
}
func (l *Loader) PluginErrors() []*plugins.Error {
return l.loader.PluginErrors()
}

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +0,0 @@
package pipeline
import (
"context"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath"
"github.com/grafana/grafana/pkg/plugins/manager/loader/finder"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery"
"github.com/grafana/grafana/pkg/plugins/manager/registry"
)
func ProvideDiscoveryStage(cfg *config.Cfg, pluginFinder finder.Finder, pluginRegistry registry.Service) *discovery.Discovery {
return discovery.New(cfg, discovery.Opts{
FindFunc: func(ctx context.Context, src plugins.PluginSource) ([]*plugins.FoundBundle, error) {
return pluginFinder.Find(ctx, src)
},
FindFilterFuncs: []discovery.FindFilterFunc{
func(ctx context.Context, _ plugins.Class, bundles []*plugins.FoundBundle) ([]*plugins.FoundBundle, error) {
return discovery.NewDuplicatePluginFilterStep(pluginRegistry).Filter(ctx, bundles)
},
},
})
}
func ProvideBootstrapStage(cfg *config.Cfg, signatureCalculator plugins.SignatureCalculator, assetPath *assetpath.Service) *bootstrap.Bootstrap {
return bootstrap.New(cfg, bootstrap.Opts{
ConstructFunc: bootstrap.DefaultConstructFunc(signatureCalculator, assetPath),
DecorateFuncs: bootstrap.DefaultDecorateFuncs,
})
}

View File

@ -0,0 +1,44 @@
package pipeline
import (
"context"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/envvars"
"github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath"
"github.com/grafana/grafana/pkg/plugins/manager/loader/finder"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/initialization"
"github.com/grafana/grafana/pkg/plugins/manager/registry"
)
func ProvideDiscoveryStage(cfg *config.Cfg, pf finder.Finder, pr registry.Service) *discovery.Discovery {
return discovery.New(cfg, discovery.Opts{
FindFunc: func(ctx context.Context, src plugins.PluginSource) ([]*plugins.FoundBundle, error) {
return pf.Find(ctx, src)
},
FindFilterFuncs: []discovery.FindFilterFunc{
func(ctx context.Context, _ plugins.Class, b []*plugins.FoundBundle) ([]*plugins.FoundBundle, error) {
return discovery.NewDuplicatePluginFilterStep(pr).Filter(ctx, b)
},
},
})
}
func ProvideBootstrapStage(cfg *config.Cfg, sc plugins.SignatureCalculator, a *assetpath.Service) *bootstrap.Bootstrap {
return bootstrap.New(cfg, bootstrap.Opts{
ConstructFunc: bootstrap.DefaultConstructFunc(sc, a),
DecorateFuncs: bootstrap.DefaultDecorateFuncs,
})
}
func ProvideInitializationStage(cfg *config.Cfg, pr registry.Service, l plugins.Licensing, bp plugins.BackendFactoryProvider) *initialization.Initialize {
return initialization.New(cfg, initialization.Opts{
InitializeFuncs: []initialization.InitializeFunc{
initialization.NewBackendClientInitStep(envvars.NewProvider(cfg, l), bp),
initialization.NewPluginRegistrationStep(pr),
},
})
}

View File

@ -11,12 +11,13 @@ import (
"github.com/grafana/grafana/pkg/plugins/manager" "github.com/grafana/grafana/pkg/plugins/manager"
"github.com/grafana/grafana/pkg/plugins/manager/client" "github.com/grafana/grafana/pkg/plugins/manager/client"
"github.com/grafana/grafana/pkg/plugins/manager/filestore" "github.com/grafana/grafana/pkg/plugins/manager/filestore"
"github.com/grafana/grafana/pkg/plugins/manager/loader" pluginLoader "github.com/grafana/grafana/pkg/plugins/manager/loader"
pAngularInspector "github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector" pAngularInspector "github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector"
"github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath" "github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath"
"github.com/grafana/grafana/pkg/plugins/manager/loader/finder" "github.com/grafana/grafana/pkg/plugins/manager/loader/finder"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap" "github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery" "github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery"
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/initialization"
"github.com/grafana/grafana/pkg/plugins/manager/process" "github.com/grafana/grafana/pkg/plugins/manager/process"
"github.com/grafana/grafana/pkg/plugins/manager/registry" "github.com/grafana/grafana/pkg/plugins/manager/registry"
"github.com/grafana/grafana/pkg/plugins/manager/signature" "github.com/grafana/grafana/pkg/plugins/manager/signature"
@ -37,6 +38,7 @@ import (
"github.com/grafana/grafana/pkg/services/pluginsintegration/keyretriever/dynamic" "github.com/grafana/grafana/pkg/services/pluginsintegration/keyretriever/dynamic"
"github.com/grafana/grafana/pkg/services/pluginsintegration/keystore" "github.com/grafana/grafana/pkg/services/pluginsintegration/keystore"
"github.com/grafana/grafana/pkg/services/pluginsintegration/licensing" "github.com/grafana/grafana/pkg/services/pluginsintegration/licensing"
"github.com/grafana/grafana/pkg/services/pluginsintegration/loader"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pipeline" "github.com/grafana/grafana/pkg/services/pluginsintegration/pipeline"
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
@ -65,6 +67,8 @@ var WireSet = wire.NewSet(
wire.Bind(new(discovery.Discoverer), new(*discovery.Discovery)), wire.Bind(new(discovery.Discoverer), new(*discovery.Discovery)),
pipeline.ProvideBootstrapStage, pipeline.ProvideBootstrapStage,
wire.Bind(new(bootstrap.Bootstrapper), new(*bootstrap.Bootstrap)), wire.Bind(new(bootstrap.Bootstrapper), new(*bootstrap.Bootstrap)),
pipeline.ProvideInitializationStage,
wire.Bind(new(initialization.Initializer), new(*initialization.Initialize)),
angularpatternsstore.ProvideService, angularpatternsstore.ProvideService,
angulardetectorsprovider.ProvideDynamic, angulardetectorsprovider.ProvideDynamic,
@ -72,7 +76,7 @@ var WireSet = wire.NewSet(
wire.Bind(new(pAngularInspector.Inspector), new(*angularinspector.Service)), wire.Bind(new(pAngularInspector.Inspector), new(*angularinspector.Service)),
loader.ProvideService, loader.ProvideService,
wire.Bind(new(loader.Service), new(*loader.Loader)), wire.Bind(new(pluginLoader.Service), new(*loader.Loader)),
wire.Bind(new(plugins.ErrorResolver), new(*loader.Loader)), wire.Bind(new(plugins.ErrorResolver), new(*loader.Loader)),
manager.ProvideInstaller, manager.ProvideInstaller,
wire.Bind(new(plugins.Installer), new(*manager.PluginInstaller)), wire.Bind(new(plugins.Installer), new(*manager.PluginInstaller)),