Plugins: Add termination stage to plugin loader pipeline (#72822)

* add termination stage

* uid -> pluginID (for now)

* also fix fakes

* add simple test

* Fix logger name

Co-authored-by: Giuseppe Guerra <giuseppe.guerra@grafana.com>

* inline stop func call

Co-authored-by: Giuseppe Guerra <giuseppe.guerra@grafana.com>

---------

Co-authored-by: Giuseppe Guerra <giuseppe.guerra@grafana.com>
This commit is contained in:
Will Browne
2023-08-04 11:57:49 +02:00
committed by GitHub
parent 7bc6d32eb9
commit 60b4a0b2a4
19 changed files with 305 additions and 62 deletions

View File

@ -14,6 +14,7 @@ import (
"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/pipeline/termination"
"github.com/grafana/grafana/pkg/plugins/manager/process"
"github.com/grafana/grafana/pkg/plugins/manager/registry"
"github.com/grafana/grafana/pkg/plugins/manager/signature"
@ -27,6 +28,7 @@ type Loader struct {
discovery discovery.Discoverer
bootstrap bootstrap.Bootstrapper
initializer initialization.Initializer
termination termination.Terminator
processManager process.Service
pluginRegistry registry.Service
@ -45,15 +47,17 @@ type Loader struct {
func ProvideService(cfg *config.Cfg, authorizer plugins.PluginLoaderAuthorizer,
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 {
discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper, initializer initialization.Initializer,
termination termination.Terminator) *Loader {
return New(cfg, authorizer, pluginRegistry, process.NewManager(pluginRegistry), roleRegistry, assetPath,
angularInspector, externalServiceRegistry, discovery, bootstrap, initializer)
angularInspector, externalServiceRegistry, discovery, bootstrap, initializer, termination)
}
func New(cfg *config.Cfg, authorizer plugins.PluginLoaderAuthorizer, pluginRegistry registry.Service,
processManager process.Service, roleRegistry plugins.RoleRegistry, assetPath *assetpath.Service,
angularInspector angularinspector.Inspector, externalServiceRegistry oauth.ExternalServiceRegistry,
discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper, initializer initialization.Initializer) *Loader {
discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper, initializer initialization.Initializer,
termination termination.Terminator) *Loader {
return &Loader{
pluginRegistry: pluginRegistry,
signatureValidator: signature.NewValidator(authorizer),
@ -68,6 +72,7 @@ func New(cfg *config.Cfg, authorizer plugins.PluginLoaderAuthorizer, pluginRegis
discovery: discovery,
bootstrap: bootstrap,
initializer: initializer,
termination: termination,
}
}
@ -178,40 +183,7 @@ func (l *Loader) Load(ctx context.Context, src plugins.PluginSource) ([]*plugins
}
func (l *Loader) Unload(ctx context.Context, pluginID string) error {
plugin, exists := l.pluginRegistry.Plugin(ctx, pluginID)
if !exists {
return plugins.ErrPluginNotInstalled
}
if plugin.IsCorePlugin() || plugin.IsBundledPlugin() {
return plugins.ErrUninstallCorePlugin
}
if err := l.unload(ctx, plugin); err != nil {
return err
}
return nil
}
func (l *Loader) unload(ctx context.Context, p *plugins.Plugin) error {
l.log.Debug("Stopping plugin process", "pluginId", p.ID)
if err := l.processManager.Stop(ctx, p.ID); err != nil {
return err
}
if err := l.pluginRegistry.Remove(ctx, p.ID); err != nil {
return err
}
l.log.Debug("Plugin unregistered", "pluginId", p.ID)
if remover, ok := p.FS.(plugins.FSRemover); ok {
if err := remover.Remove(); err != nil {
return err
}
}
return nil
return l.termination.Terminate(ctx, pluginID)
}
func (l *Loader) PluginErrors() []*plugins.Error {