package initialization import ( "context" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/trace" "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/tracing" "github.com/grafana/grafana/pkg/semconv" ) // 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.PluginManagementCfg initializeSteps []InitializeFunc log log.Logger tracer trace.Tracer } type Opts struct { InitializeFuncs []InitializeFunc } // New returns a new Initialization stage. func New(cfg *config.PluginManagementCfg, opts Opts) *Initialize { if opts.InitializeFuncs == nil { opts.InitializeFuncs = []InitializeFunc{} } return &Initialize{ cfg: cfg, initializeSteps: opts.InitializeFuncs, log: log.New("plugins.initialization"), tracer: otel.Tracer("github.com/grafana/grafana/pkg/plugins/manager/pipeline/initialization"), } } // Initialize will execute the Initialize steps of the Initialization stage. func (i *Initialize) Initialize(ctx context.Context, ps *plugins.Plugin) (*plugins.Plugin, error) { ctx, span := i.tracer.Start(ctx, "initialization.Initialize", trace.WithAttributes( semconv.GrafanaPluginId(ps.ID), )) defer span.End() if len(i.initializeSteps) == 0 { return ps, nil } var err error var ip *plugins.Plugin for _, init := range i.initializeSteps { ip, err = init(ctx, ps) if err != nil { i.log.Error("Could not initialize plugin", "pluginId", ps.ID, "error", err) return nil, tracing.Error(span, err) } } return ip, nil }