Plugins: Make Installer responsible for removing plugins from file system (#73323)

* installer is responsible for removing from file system

* take plugin as arg

* remove resolve step

* return plugin in test
This commit is contained in:
Will Browne
2023-08-16 15:44:20 +02:00
committed by GitHub
parent 243b757168
commit 3c50db328d
13 changed files with 64 additions and 106 deletions
@@ -9,39 +9,6 @@ import (
"github.com/grafana/grafana/pkg/plugins/manager/registry"
)
// TerminablePluginResolver implements a ResolveFunc for resolving a plugin that can be terminated.
type TerminablePluginResolver struct {
pluginRegistry registry.Service
log log.Logger
}
// TerminablePluginResolverStep returns a new ResolveFunc for resolving a plugin that can be terminated.
func TerminablePluginResolverStep(pluginRegistry registry.Service) ResolveFunc {
return newTerminablePluginResolver(pluginRegistry).Resolve
}
func newTerminablePluginResolver(pluginRegistry registry.Service) *TerminablePluginResolver {
return &TerminablePluginResolver{
pluginRegistry: pluginRegistry,
log: log.New("plugins.resolver"),
}
}
// Resolve returns a plugin that can be terminated.
func (r *TerminablePluginResolver) Resolve(ctx context.Context, pluginID string) (*plugins.Plugin, error) {
p, exists := r.pluginRegistry.Plugin(ctx, pluginID)
if !exists {
return nil, plugins.ErrPluginNotInstalled
}
// core plugins and bundled plugins cannot be terminated
if p.IsCorePlugin() || p.IsBundledPlugin() {
return nil, plugins.ErrUninstallCorePlugin
}
return p, nil
}
// BackendProcessTerminator implements a TerminateFunc for stopping a backend plugin process.
//
// It uses the process.Manager to stop the backend plugin process.
@@ -93,13 +60,3 @@ func (d *Deregister) Deregister(ctx context.Context, p *plugins.Plugin) error {
d.log.Debug("Plugin unregistered", "pluginId", p.ID)
return nil
}
// FSRemoval implements a TerminateFunc for removing plugin files from the filesystem.
func FSRemoval(_ context.Context, p *plugins.Plugin) error {
if remover, ok := p.FS.(plugins.FSRemover); ok {
if err := remover.Remove(); err != nil {
return err
}
}
return nil
}
@@ -2,7 +2,6 @@ package termination
import (
"context"
"errors"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
@@ -11,57 +10,41 @@ import (
// Terminator is responsible for the Termination stage of the plugin loader pipeline.
type Terminator interface {
Terminate(ctx context.Context, pluginID string) error
Terminate(ctx context.Context, p *plugins.Plugin) (*plugins.Plugin, error)
}
// ResolveFunc is the function used for the Resolve step of the Termination stage.
type ResolveFunc func(ctx context.Context, pluginID string) (*plugins.Plugin, error)
// TerminateFunc is the function used for the Terminate step of the Termination stage.
type TerminateFunc func(ctx context.Context, p *plugins.Plugin) error
type Terminate struct {
cfg *config.Cfg
resolveStep ResolveFunc
terminateSteps []TerminateFunc
log log.Logger
}
type Opts struct {
ResolveFunc ResolveFunc
TerminateFuncs []TerminateFunc
}
// New returns a new Termination stage.
func New(cfg *config.Cfg, opts Opts) (*Terminate, error) {
// without a resolve function, we can't do anything so return an error
if opts.ResolveFunc == nil && opts.TerminateFuncs != nil {
return nil, errors.New("resolve function is required")
}
if opts.TerminateFuncs == nil {
opts.TerminateFuncs = []TerminateFunc{}
}
return &Terminate{
cfg: cfg,
resolveStep: opts.ResolveFunc,
terminateSteps: opts.TerminateFuncs,
log: log.New("plugins.termination"),
}, nil
}
// Terminate will execute the Terminate steps of the Termination stage.
func (t *Terminate) Terminate(ctx context.Context, pluginID string) error {
p, err := t.resolveStep(ctx, pluginID)
if err != nil {
return err
}
func (t *Terminate) Terminate(ctx context.Context, p *plugins.Plugin) (*plugins.Plugin, error) {
for _, terminate := range t.terminateSteps {
if err = terminate(ctx, p); err != nil {
return err
if err := terminate(ctx, p); err != nil {
return nil, err
}
}
return nil
return p, nil
}