diff --git a/pkg/api/plugins.go b/pkg/api/plugins.go index b5161f80a13..639d0804ddf 100644 --- a/pkg/api/plugins.go +++ b/pkg/api/plugins.go @@ -409,7 +409,7 @@ func (hs *HTTPServer) InstallPlugin(c *models.ReqContext) response.Response { } pluginID := web.Params(c.Req)[":pluginId"] - err := hs.pluginStore.Add(c.Req.Context(), pluginID, dto.Version, plugins.AddOpts{}) + err := hs.pluginStore.Add(c.Req.Context(), pluginID, dto.Version) if err != nil { var dupeErr plugins.DuplicateError if errors.As(err, &dupeErr) { diff --git a/pkg/plugins/backend_utils.go b/pkg/plugins/backend_utils.go index 075635e9ef4..edb905045d7 100644 --- a/pkg/plugins/backend_utils.go +++ b/pkg/plugins/backend_utils.go @@ -2,8 +2,11 @@ package plugins import ( "fmt" + "path/filepath" "runtime" "strings" + + "github.com/grafana/grafana/pkg/setting" ) func ComposePluginStartCommand(executable string) string { @@ -29,3 +32,14 @@ func ComposeRendererStartCommand() string { return fmt.Sprintf("%s_%s_%s%s", "plugin_start", os, strings.ToLower(arch), extension) } + +func CoreDataSourcePathResolver(cfg *setting.Cfg, pluginRootDirName string) PluginPathResolver { + return func() (string, error) { + // override mismatch cloud monitoring plugin + if pluginRootDirName == "stackdriver" { + pluginRootDirName = "cloud-monitoring" + } + + return filepath.Join(cfg.StaticRootPath, "app/plugins/datasource", pluginRootDirName), nil + } +} diff --git a/pkg/plugins/ifaces.go b/pkg/plugins/ifaces.go index c267d1a5666..8716b64ba21 100644 --- a/pkg/plugins/ifaces.go +++ b/pkg/plugins/ifaces.go @@ -18,11 +18,15 @@ type Store interface { Plugins(ctx context.Context, pluginTypes ...Type) []PluginDTO // Add adds a plugin to the store. - Add(ctx context.Context, pluginID, version string, opts AddOpts) error + Add(ctx context.Context, pluginID, version string) error + // AddWithFactory adds a plugin to the store. + AddWithFactory(ctx context.Context, pluginID string, factory backendplugin.PluginFactoryFunc, resolver PluginPathResolver) error // Remove removes a plugin from the store. Remove(ctx context.Context, pluginID string) error } +type PluginPathResolver func() (string, error) + type AddOpts struct { PluginInstallDir, PluginZipURL, PluginRepoURL string } @@ -66,11 +70,6 @@ type RendererManager interface { Renderer() *Plugin } -type CoreBackendRegistrar interface { - // LoadAndRegister loads and registers a Core backend plugin - LoadAndRegister(pluginID string, factory backendplugin.PluginFactoryFunc) error -} - type StaticRouteResolver interface { Routes() []*StaticRoute } diff --git a/pkg/plugins/manager/manager.go b/pkg/plugins/manager/manager.go index 22687c0323d..b07d97f4a61 100644 --- a/pkg/plugins/manager/manager.go +++ b/pkg/plugins/manager/manager.go @@ -32,7 +32,6 @@ var _ plugins.Client = (*PluginManager)(nil) var _ plugins.Store = (*PluginManager)(nil) var _ plugins.PluginDashboardManager = (*PluginManager)(nil) var _ plugins.StaticRouteResolver = (*PluginManager)(nil) -var _ plugins.CoreBackendRegistrar = (*PluginManager)(nil) var _ plugins.RendererManager = (*PluginManager)(nil) type PluginManager struct { @@ -358,31 +357,6 @@ func (m *PluginManager) isRegistered(pluginID string) bool { return !p.IsDecommissioned() } -func (m *PluginManager) LoadAndRegister(pluginID string, factory backendplugin.PluginFactoryFunc) error { - if m.isRegistered(pluginID) { - return fmt.Errorf("backend plugin %s already registered", pluginID) - } - - pluginRootDir := pluginID - if pluginID == "stackdriver" { - pluginRootDir = "cloud-monitoring" - } - - path := filepath.Join(m.cfg.StaticRootPath, "app/plugins/datasource", pluginRootDir) - - p, err := m.pluginLoader.LoadWithFactory(path, factory) - if err != nil { - return err - } - - err = m.register(p) - if err != nil { - return err - } - - return nil -} - func (m *PluginManager) Routes() []*plugins.StaticRoute { staticRoutes := make([]*plugins.StaticRoute, 0) diff --git a/pkg/plugins/manager/manager_test.go b/pkg/plugins/manager/manager_test.go index 51a9c9d35ee..26409d397b6 100644 --- a/pkg/plugins/manager/manager_test.go +++ b/pkg/plugins/manager/manager_test.go @@ -173,7 +173,7 @@ func TestPluginManager_Installer(t *testing.T) { pm.pluginLoader = l }) - err := pm.Add(context.Background(), testPluginID, "1.0.0", plugins.AddOpts{}) + err := pm.Add(context.Background(), testPluginID, "1.0.0") require.NoError(t, err) assert.Equal(t, 1, i.installCount) @@ -196,7 +196,7 @@ func TestPluginManager_Installer(t *testing.T) { assert.Len(t, pm.Plugins(context.Background()), 1) t.Run("Won't install if already installed", func(t *testing.T) { - err := pm.Add(context.Background(), testPluginID, "1.0.0", plugins.AddOpts{}) + err := pm.Add(context.Background(), testPluginID, "1.0.0") assert.Equal(t, plugins.DuplicateError{ PluginID: p.ID, ExistingPluginDir: p.PluginDir, @@ -211,7 +211,7 @@ func TestPluginManager_Installer(t *testing.T) { } pm.pluginLoader = l - err = pm.Add(context.Background(), testPluginID, "1.2.0", plugins.AddOpts{}) + err = pm.Add(context.Background(), testPluginID, "1.2.0") assert.NoError(t, err) assert.Equal(t, 2, i.installCount) @@ -272,7 +272,7 @@ func TestPluginManager_Installer(t *testing.T) { verifyNoPluginErrors(t, pm) - err = pm.Add(context.Background(), testPluginID, "", plugins.AddOpts{}) + err = pm.Add(context.Background(), testPluginID, "") assert.Equal(t, plugins.ErrInstallCorePlugin, err) t.Run("Can't uninstall core plugin", func(t *testing.T) { @@ -306,7 +306,7 @@ func TestPluginManager_Installer(t *testing.T) { verifyNoPluginErrors(t, pm) - err = pm.Add(context.Background(), testPluginID, "", plugins.AddOpts{}) + err = pm.Add(context.Background(), testPluginID, "") assert.Equal(t, plugins.ErrInstallCorePlugin, err) t.Run("Can't uninstall bundled plugin", func(t *testing.T) { diff --git a/pkg/plugins/manager/store.go b/pkg/plugins/manager/store.go index db60e9f21f4..931b93e5df4 100644 --- a/pkg/plugins/manager/store.go +++ b/pkg/plugins/manager/store.go @@ -2,10 +2,12 @@ package manager import ( "context" + "fmt" "path/filepath" "strings" "github.com/grafana/grafana/pkg/plugins" + "github.com/grafana/grafana/pkg/plugins/backendplugin" ) func (m *PluginManager) Plugin(_ context.Context, pluginID string) (plugins.PluginDTO, bool) { @@ -38,13 +40,9 @@ func (m *PluginManager) Plugins(_ context.Context, pluginTypes ...plugins.Type) return pluginsList } -func (m *PluginManager) Add(ctx context.Context, pluginID, version string, opts plugins.AddOpts) error { +func (m *PluginManager) Add(ctx context.Context, pluginID, version string) error { var pluginZipURL string - if opts.PluginRepoURL == "" { - opts.PluginRepoURL = grafanaComURL - } - if plugin, exists := m.plugin(pluginID); exists { if !plugin.IsExternalPlugin() { return plugins.ErrInstallCorePlugin @@ -58,7 +56,7 @@ func (m *PluginManager) Add(ctx context.Context, pluginID, version string, opts } // get plugin update information to confirm if upgrading is possible - updateInfo, err := m.pluginInstaller.GetUpdateInfo(ctx, pluginID, version, opts.PluginRepoURL) + updateInfo, err := m.pluginInstaller.GetUpdateInfo(ctx, pluginID, version, grafanaComURL) if err != nil { return err } @@ -72,20 +70,12 @@ func (m *PluginManager) Add(ctx context.Context, pluginID, version string, opts } } - if opts.PluginInstallDir == "" { - opts.PluginInstallDir = m.cfg.PluginsPath - } - - if opts.PluginZipURL == "" { - opts.PluginZipURL = pluginZipURL - } - - err := m.pluginInstaller.Install(ctx, pluginID, version, opts.PluginInstallDir, opts.PluginZipURL, opts.PluginRepoURL) + err := m.pluginInstaller.Install(ctx, pluginID, version, m.cfg.PluginsPath, pluginZipURL, grafanaComURL) if err != nil { return err } - err = m.loadPlugins(opts.PluginInstallDir) + err = m.loadPlugins(m.cfg.PluginsPath) if err != nil { return err } @@ -93,6 +83,28 @@ func (m *PluginManager) Add(ctx context.Context, pluginID, version string, opts return nil } +func (m *PluginManager) AddWithFactory(_ context.Context, pluginID string, factory backendplugin.PluginFactoryFunc, + pathResolver plugins.PluginPathResolver) error { + if m.isRegistered(pluginID) { + return fmt.Errorf("plugin %s is already registered", pluginID) + } + + path, err := pathResolver() + if err != nil { + return err + } + + p, err := m.pluginLoader.LoadWithFactory(path, factory) + if err != nil { + return err + } + err = m.register(p) + if err != nil { + return err + } + return nil +} + func (m *PluginManager) Remove(ctx context.Context, pluginID string) error { plugin, exists := m.plugin(pluginID) if !exists { diff --git a/pkg/server/wire.go b/pkg/server/wire.go index 3ff8974cec9..3590de89fe5 100644 --- a/pkg/server/wire.go +++ b/pkg/server/wire.go @@ -102,7 +102,6 @@ var wireBasicSet = wire.NewSet( manager.ProvideService, wire.Bind(new(plugins.Client), new(*manager.PluginManager)), wire.Bind(new(plugins.Store), new(*manager.PluginManager)), - wire.Bind(new(plugins.CoreBackendRegistrar), new(*manager.PluginManager)), wire.Bind(new(plugins.StaticRouteResolver), new(*manager.PluginManager)), wire.Bind(new(plugins.PluginDashboardManager), new(*manager.PluginManager)), wire.Bind(new(plugins.RendererManager), new(*manager.PluginManager)), diff --git a/pkg/tsdb/azuremonitor/azuremonitor.go b/pkg/tsdb/azuremonitor/azuremonitor.go index 978afffd0c7..9c60374a5bd 100644 --- a/pkg/tsdb/azuremonitor/azuremonitor.go +++ b/pkg/tsdb/azuremonitor/azuremonitor.go @@ -22,7 +22,7 @@ import ( const ( timeSeries = "time_series" - dsName = "grafana-azure-monitor-datasource" + pluginID = "grafana-azure-monitor-datasource" ) var ( @@ -30,7 +30,7 @@ var ( legendKeyFormat = regexp.MustCompile(`\{\{\s*(.+?)\s*\}\}`) ) -func ProvideService(cfg *setting.Cfg, httpClientProvider *httpclient.Provider, registrar plugins.CoreBackendRegistrar) *Service { +func ProvideService(cfg *setting.Cfg, httpClientProvider *httpclient.Provider, pluginStore plugins.Store) *Service { proxy := &httpServiceProxy{} executors := map[string]azDatasourceExecutor{ azureMonitor: &AzureMonitorDatasource{proxy: proxy}, @@ -55,7 +55,8 @@ func ProvideService(cfg *setting.Cfg, httpClientProvider *httpclient.Provider, r CallResourceHandler: httpadapter.New(resourceMux), }) - if err := registrar.LoadAndRegister(dsName, factory); err != nil { + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { azlog.Error("Failed to register plugin", "error", err) } diff --git a/pkg/tsdb/cloudmonitoring/cloudmonitoring.go b/pkg/tsdb/cloudmonitoring/cloudmonitoring.go index bd4f0d12571..2f730c2fe43 100644 --- a/pkg/tsdb/cloudmonitoring/cloudmonitoring.go +++ b/pkg/tsdb/cloudmonitoring/cloudmonitoring.go @@ -71,7 +71,7 @@ const ( perSeriesAlignerDefault string = "ALIGN_MEAN" ) -func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, registrar plugins.CoreBackendRegistrar, +func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store, dsService *datasources.Service) *Service { s := &Service{ httpClientProvider: httpClientProvider, @@ -88,7 +88,8 @@ func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, re CheckHealthHandler: s, }) - if err := registrar.LoadAndRegister(pluginID, factory); err != nil { + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { slog.Error("Failed to register plugin", "error", err) } return s diff --git a/pkg/tsdb/cloudwatch/cloudwatch.go b/pkg/tsdb/cloudwatch/cloudwatch.go index 3b0c91a13aa..8ef02c05fcd 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch.go +++ b/pkg/tsdb/cloudwatch/cloudwatch.go @@ -52,10 +52,12 @@ const defaultRegion = "default" const logIdentifierInternal = "__log__grafana_internal__" const logStreamIdentifierInternal = "__logstream__grafana_internal__" +const pluginID = "cloudwatch" + var plog = log.New("tsdb.cloudwatch") var aliasFormat = regexp.MustCompile(`\{\{\s*(.+?)\s*\}\}`) -func ProvideService(cfg *setting.Cfg, logsService *LogsService, registrar plugins.CoreBackendRegistrar) (*CloudWatchService, error) { +func ProvideService(cfg *setting.Cfg, logsService *LogsService, pluginStore plugins.Store) (*CloudWatchService, error) { plog.Debug("initing") executor := newExecutor(logsService, datasource.NewInstanceManager(NewInstanceSettings()), cfg, awsds.NewSessionCache()) @@ -63,7 +65,8 @@ func ProvideService(cfg *setting.Cfg, logsService *LogsService, registrar plugin QueryDataHandler: executor, }) - if err := registrar.LoadAndRegister("cloudwatch", factory); err != nil { + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { plog.Error("Failed to register plugin", "error", err) return nil, err } diff --git a/pkg/tsdb/elasticsearch/elasticsearch.go b/pkg/tsdb/elasticsearch/elasticsearch.go index cda99ee6d3d..558466d57aa 100644 --- a/pkg/tsdb/elasticsearch/elasticsearch.go +++ b/pkg/tsdb/elasticsearch/elasticsearch.go @@ -14,19 +14,22 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" + "github.com/grafana/grafana/pkg/setting" es "github.com/grafana/grafana/pkg/tsdb/elasticsearch/client" "github.com/grafana/grafana/pkg/tsdb/intervalv2" ) var eslog = log.New("tsdb.elasticsearch") +const pluginID = "elasticsearch" + type Service struct { HTTPClientProvider httpclient.Provider intervalCalculator intervalv2.Calculator im instancemgmt.InstanceManager } -func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.CoreBackendRegistrar) (*Service, error) { +func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store) (*Service, error) { eslog.Debug("initializing") im := datasource.NewInstanceManager(newInstanceSettings()) @@ -36,7 +39,8 @@ func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.Co QueryDataHandler: newService(im, s.HTTPClientProvider), }) - if err := registrar.LoadAndRegister("elasticsearch", factory); err != nil { + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, + plugins.CoreDataSourcePathResolver(cfg, pluginID)); err != nil { eslog.Error("Failed to register plugin", "error", err) return nil, err } diff --git a/pkg/tsdb/grafanads/grafana.go b/pkg/tsdb/grafanads/grafana.go index da6da2007f9..d3cd80b77c5 100644 --- a/pkg/tsdb/grafanads/grafana.go +++ b/pkg/tsdb/grafanads/grafana.go @@ -32,6 +32,8 @@ const DatasourceID = -1 // Grafana DS command. const DatasourceUID = "grafana" +const pluginID = "grafana" + // Make sure Service implements required interfaces. // This is important to do since otherwise we will only get a // not implemented error response from plugin at runtime. @@ -41,13 +43,13 @@ var ( logger = log.New("tsdb.grafana") ) -func ProvideService(cfg *setting.Cfg, registrar plugins.CoreBackendRegistrar) *Service { - return newService(cfg.StaticRootPath, registrar) +func ProvideService(cfg *setting.Cfg, pluginStore plugins.Store) *Service { + return newService(cfg, pluginStore) } -func newService(staticRootPath string, registrar plugins.CoreBackendRegistrar) *Service { +func newService(cfg *setting.Cfg, pluginStore plugins.Store) *Service { s := &Service{ - staticRootPath: staticRootPath, + staticRootPath: cfg.StaticRootPath, roots: []string{ "testdata", "img/icons", @@ -57,10 +59,11 @@ func newService(staticRootPath string, registrar plugins.CoreBackendRegistrar) * }, } - if err := registrar.LoadAndRegister("grafana", coreplugin.New(backend.ServeOpts{ + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, coreplugin.New(backend.ServeOpts{ CheckHealthHandler: s, QueryDataHandler: s, - })); err != nil { + }), resolver); err != nil { logger.Error("Failed to register plugin", "error", err) return nil } diff --git a/pkg/tsdb/grafanads/grafana_test.go b/pkg/tsdb/grafanads/grafana_test.go index 55beb54f084..07dec0e3325 100644 --- a/pkg/tsdb/grafanads/grafana_test.go +++ b/pkg/tsdb/grafanads/grafana_test.go @@ -1,12 +1,14 @@ package grafanads import ( + "context" "encoding/json" "path" "testing" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins/backendplugin" + "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/experimental" @@ -19,7 +21,7 @@ func asJSON(v interface{}) json.RawMessage { } func TestReadFolderListing(t *testing.T) { - ds := newService("../../../public", &fakeBackendPM{}) + ds := newService(&setting.Cfg{StaticRootPath: "../../../public"}, &fakePluginStore{}) dr := ds.doListQuery(backend.DataQuery{ QueryType: "x", JSON: asJSON(listQueryModel{ @@ -31,7 +33,7 @@ func TestReadFolderListing(t *testing.T) { } func TestReadCSVFile(t *testing.T) { - ds := newService("../../../public", &fakeBackendPM{}) + ds := newService(&setting.Cfg{StaticRootPath: "../../../public"}, &fakePluginStore{}) dr := ds.doReadQuery(backend.DataQuery{ QueryType: "x", JSON: asJSON(readQueryModel{ @@ -42,10 +44,10 @@ func TestReadCSVFile(t *testing.T) { require.NoError(t, err) } -type fakeBackendPM struct { - plugins.CoreBackendRegistrar +type fakePluginStore struct { + plugins.Store } -func (pm *fakeBackendPM) LoadAndRegister(pluginID string, factory backendplugin.PluginFactoryFunc) error { +func (ps *fakePluginStore) AddWithFactory(_ context.Context, _ string, _ backendplugin.PluginFactoryFunc, _ plugins.PluginPathResolver) error { return nil } diff --git a/pkg/tsdb/graphite/graphite.go b/pkg/tsdb/graphite/graphite.go index 422a1a446fa..5d75c487f98 100644 --- a/pkg/tsdb/graphite/graphite.go +++ b/pkg/tsdb/graphite/graphite.go @@ -37,11 +37,12 @@ type Service struct { } const ( + pluginID = "graphite" TargetFullModelField = "targetFull" TargetModelField = "target" ) -func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.CoreBackendRegistrar) (*Service, error) { +func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store) (*Service, error) { s := &Service{ logger: log.New("tsdb.graphite"), im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)), @@ -51,7 +52,8 @@ func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.Co QueryDataHandler: s, }) - if err := registrar.LoadAndRegister("graphite", factory); err != nil { + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { s.logger.Error("Failed to register plugin", "error", err) return nil, err } diff --git a/pkg/tsdb/influxdb/influxdb.go b/pkg/tsdb/influxdb/influxdb.go index 112902d4d31..fec2e42c304 100644 --- a/pkg/tsdb/influxdb/influxdb.go +++ b/pkg/tsdb/influxdb/influxdb.go @@ -22,6 +22,8 @@ import ( "github.com/grafana/grafana/pkg/tsdb/influxdb/models" ) +const pluginID = "influxdb" + type Service struct { QueryParser *InfluxdbQueryParser ResponseParser *ResponseParser @@ -32,7 +34,7 @@ type Service struct { var ErrInvalidHttpMode = errors.New("'httpMode' should be either 'GET' or 'POST'") -func ProvideService(httpClient httpclient.Provider, registrar plugins.CoreBackendRegistrar) (*Service, error) { +func ProvideService(cfg *setting.Cfg, httpClient httpclient.Provider, pluginStore plugins.Store) (*Service, error) { im := datasource.NewInstanceManager(newInstanceSettings(httpClient)) s := &Service{ QueryParser: &InfluxdbQueryParser{}, @@ -45,7 +47,8 @@ func ProvideService(httpClient httpclient.Provider, registrar plugins.CoreBacken QueryDataHandler: s, }) - if err := registrar.LoadAndRegister("influxdb", factory); err != nil { + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { s.glog.Error("Failed to register plugin", "error", err) return nil, err } diff --git a/pkg/tsdb/loki/loki.go b/pkg/tsdb/loki/loki.go index 171f2bb1769..1a74118b0e9 100644 --- a/pkg/tsdb/loki/loki.go +++ b/pkg/tsdb/loki/loki.go @@ -18,6 +18,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" + "github.com/grafana/grafana/pkg/setting" "github.com/grafana/loki/pkg/logcli/client" "github.com/grafana/loki/pkg/loghttp" "github.com/grafana/loki/pkg/logproto" @@ -27,12 +28,14 @@ import ( "github.com/prometheus/common/model" ) +const pluginID = "loki" + type Service struct { im instancemgmt.InstanceManager plog log.Logger } -func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.CoreBackendRegistrar) (*Service, error) { +func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store) (*Service, error) { im := datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)) s := &Service{ im: im, @@ -43,7 +46,8 @@ func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.Co QueryDataHandler: s, }) - if err := registrar.LoadAndRegister("loki", factory); err != nil { + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { s.plog.Error("Failed to register plugin", "error", err) return nil, err } diff --git a/pkg/tsdb/mssql/mssql.go b/pkg/tsdb/mssql/mssql.go index 654daf14559..792c45a72d5 100644 --- a/pkg/tsdb/mssql/mssql.go +++ b/pkg/tsdb/mssql/mssql.go @@ -26,11 +26,13 @@ import ( var logger = log.New("tsdb.mssql") +const pluginID = "mssql" + type Service struct { im instancemgmt.InstanceManager } -func ProvideService(cfg *setting.Cfg, registrar plugins.CoreBackendRegistrar) (*Service, error) { +func ProvideService(cfg *setting.Cfg, pluginStore plugins.Store) (*Service, error) { s := &Service{ im: datasource.NewInstanceManager(newInstanceSettings(cfg)), } @@ -38,7 +40,8 @@ func ProvideService(cfg *setting.Cfg, registrar plugins.CoreBackendRegistrar) (* QueryDataHandler: s, }) - if err := registrar.LoadAndRegister("mssql", factory); err != nil { + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { logger.Error("Failed to register plugin", "error", err) } return s, nil diff --git a/pkg/tsdb/mysql/mysql.go b/pkg/tsdb/mysql/mysql.go index be7cf885489..19dcf99fbd3 100644 --- a/pkg/tsdb/mysql/mysql.go +++ b/pkg/tsdb/mysql/mysql.go @@ -27,6 +27,7 @@ import ( ) const ( + pluginID = "mysql" dateFormat = "2006-01-02" dateTimeFormat1 = "2006-01-02 15:04:05" dateTimeFormat2 = "2006-01-02T15:04:05Z" @@ -43,7 +44,7 @@ func characterEscape(s string, escapeChar string) string { return strings.ReplaceAll(s, escapeChar, url.QueryEscape(escapeChar)) } -func ProvideService(cfg *setting.Cfg, registrar plugins.CoreBackendRegistrar, httpClientProvider httpclient.Provider) (*Service, error) { +func ProvideService(cfg *setting.Cfg, pluginStore plugins.Store, httpClientProvider httpclient.Provider) (*Service, error) { s := &Service{ im: datasource.NewInstanceManager(newInstanceSettings(cfg, httpClientProvider)), } @@ -51,7 +52,8 @@ func ProvideService(cfg *setting.Cfg, registrar plugins.CoreBackendRegistrar, ht QueryDataHandler: s, }) - if err := registrar.LoadAndRegister("mysql", factory); err != nil { + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { logger.Error("Failed to register plugin", "error", err) } return s, nil diff --git a/pkg/tsdb/opentsdb/opentsdb.go b/pkg/tsdb/opentsdb/opentsdb.go index 6fd12b41c76..ef42bf1bdbf 100644 --- a/pkg/tsdb/opentsdb/opentsdb.go +++ b/pkg/tsdb/opentsdb/opentsdb.go @@ -25,12 +25,14 @@ import ( "golang.org/x/net/context/ctxhttp" ) +const pluginID = "opentsdb" + type Service struct { logger log.Logger im instancemgmt.InstanceManager } -func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.CoreBackendRegistrar) (*Service, error) { +func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store) (*Service, error) { im := datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)) s := &Service{ logger: log.New("tsdb.opentsdb"), @@ -40,7 +42,8 @@ func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.Co factory := coreplugin.New(backend.ServeOpts{ QueryDataHandler: s, }) - if err := registrar.LoadAndRegister("opentsdb", factory); err != nil { + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { return nil, err } diff --git a/pkg/tsdb/postgres/postgres.go b/pkg/tsdb/postgres/postgres.go index a1053f4ca25..112c9bc9678 100644 --- a/pkg/tsdb/postgres/postgres.go +++ b/pkg/tsdb/postgres/postgres.go @@ -23,7 +23,9 @@ import ( var logger = log.New("tsdb.postgres") -func ProvideService(cfg *setting.Cfg, registrar plugins.CoreBackendRegistrar) (*Service, error) { +const pluginID = "postgres" + +func ProvideService(cfg *setting.Cfg, pluginStore plugins.Store) (*Service, error) { s := &Service{ tlsManager: newTLSManager(logger, cfg.DataPath), } @@ -32,7 +34,8 @@ func ProvideService(cfg *setting.Cfg, registrar plugins.CoreBackendRegistrar) (* QueryDataHandler: s, }) - if err := registrar.LoadAndRegister("postgres", factory); err != nil { + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { logger.Error("Failed to register plugin", "error", err) } return s, nil diff --git a/pkg/tsdb/prometheus/prometheus.go b/pkg/tsdb/prometheus/prometheus.go index bd0bd34ded7..62e77849b02 100644 --- a/pkg/tsdb/prometheus/prometheus.go +++ b/pkg/tsdb/prometheus/prometheus.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" + "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tsdb/intervalv2" "github.com/prometheus/client_golang/api" apiv1 "github.com/prometheus/client_golang/api/prometheus/v1" @@ -26,12 +27,14 @@ var ( safeRes = 11000 ) +const pluginID = "prometheus" + type Service struct { intervalCalculator intervalv2.Calculator im instancemgmt.InstanceManager } -func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.CoreBackendRegistrar) (*Service, error) { +func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store) (*Service, error) { plog.Debug("initializing") im := datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)) @@ -43,7 +46,8 @@ func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.Co factory := coreplugin.New(backend.ServeOpts{ QueryDataHandler: s, }) - if err := registrar.LoadAndRegister("prometheus", factory); err != nil { + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { plog.Error("Failed to register plugin", "error", err) return nil, err } diff --git a/pkg/tsdb/tempo/tempo.go b/pkg/tsdb/tempo/tempo.go index 74ca3ab733d..49ce72dcacd 100644 --- a/pkg/tsdb/tempo/tempo.go +++ b/pkg/tsdb/tempo/tempo.go @@ -15,15 +15,18 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" + "github.com/grafana/grafana/pkg/setting" "go.opentelemetry.io/collector/model/otlp" ) +const pluginID = "tempo" + type Service struct { im instancemgmt.InstanceManager tlog log.Logger } -func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.CoreBackendRegistrar) (*Service, error) { +func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store) (*Service, error) { im := datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)) s := &Service{ @@ -35,7 +38,8 @@ func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.Co QueryDataHandler: s, }) - if err := registrar.LoadAndRegister("tempo", factory); err != nil { + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { s.tlog.Error("Failed to register plugin", "error", err) return nil, err } diff --git a/pkg/tsdb/testdatasource/testdata.go b/pkg/tsdb/testdatasource/testdata.go index 4bb78afc114..6242d4f8a70 100644 --- a/pkg/tsdb/testdatasource/testdata.go +++ b/pkg/tsdb/testdatasource/testdata.go @@ -1,6 +1,7 @@ package testdatasource import ( + "context" "net/http" "time" @@ -14,7 +15,9 @@ import ( "github.com/grafana/grafana/pkg/setting" ) -func ProvideService(cfg *setting.Cfg, registrar plugins.CoreBackendRegistrar) (*Service, error) { +const pluginID = "testdata" + +func ProvideService(cfg *setting.Cfg, pluginStore plugins.Store) (*Service, error) { s := &Service{ queryMux: datasource.NewQueryTypeMux(), scenarios: map[string]*Scenario{}, @@ -43,7 +46,8 @@ func ProvideService(cfg *setting.Cfg, registrar plugins.CoreBackendRegistrar) (* CallResourceHandler: httpadapter.New(rMux), StreamHandler: s, }) - err := registrar.LoadAndRegister("testdata", factory) + resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) + err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver) if err != nil { return nil, err }