From bd4cb549d6224893e0fb97b665282590b86bbff4 Mon Sep 17 00:00:00 2001 From: woodsaj Date: Thu, 3 Dec 2015 15:52:37 +0800 Subject: [PATCH] add pluginBundle support A plugnBundle is meta plugin that has a set of dependent plugins to enable. This commit includes a plugin.json for a default "core" bundle that enables all of the shipped panels and datasources. --- pkg/api/datasources.go | 5 ++- pkg/api/frontendsettings.go | 8 +++-- pkg/api/index.go | 5 ++- pkg/models/plugin_bundle.go | 8 +++++ pkg/plugins/models.go | 22 ++++++++++++ pkg/plugins/plugins.go | 61 ++++++++++++++++++++++++++++++---- public/app/plugins/plugin.json | 8 +++++ 7 files changed, 107 insertions(+), 10 deletions(-) create mode 100644 pkg/models/plugin_bundle.go create mode 100644 public/app/plugins/plugin.json diff --git a/pkg/api/datasources.go b/pkg/api/datasources.go index 15a13ee60c7..b2c554de0e2 100644 --- a/pkg/api/datasources.go +++ b/pkg/api/datasources.go @@ -115,8 +115,11 @@ func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) { func GetDataSourcePlugins(c *middleware.Context) { dsList := make(map[string]interface{}) + //TODO(awoods): query DB for orgPlugins + orgPlugins := map[string]m.PluginBundle{} + enabledPlugins := plugins.GetEnabledPlugins(orgPlugins) - for key, value := range plugins.DataSources { + for key, value := range enabledPlugins.DataSourcePlugins { if !value.BuiltIn { dsList[key] = value } diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go index 93b08f79eb4..49b679af194 100644 --- a/pkg/api/frontendsettings.go +++ b/pkg/api/frontendsettings.go @@ -29,6 +29,10 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro datasources := make(map[string]interface{}) var defaultDatasource string + //TODO(awoods): query DB to get list of the users plugin preferences. + orgPlugins := map[string]m.PluginBundle{} + enabledPlugins := plugins.GetEnabledPlugins(orgPlugins) + for _, ds := range orgDataSources { url := ds.Url @@ -42,7 +46,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro "url": url, } - meta, exists := plugins.DataSources[ds.Type] + meta, exists := enabledPlugins.DataSourcePlugins[ds.Type] if !exists { log.Error(3, "Could not find plugin definition for data source: %v", ds.Type) continue @@ -107,7 +111,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro } panels := map[string]interface{}{} - for _, panel := range plugins.Panels { + for _, panel := range enabledPlugins.PanelPlugins { panels[panel.Type] = map[string]interface{}{ "module": panel.Module, "name": panel.Name, diff --git a/pkg/api/index.go b/pkg/api/index.go index 5620d5726cd..b9f880faefc 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -62,7 +62,10 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) { }) } - for _, plugin := range plugins.ExternalPlugins { + //TODO(awoods): query DB to get list of the users plugin preferences. + orgPlugins := map[string]m.PluginBundle{} + enabledPlugins := plugins.GetEnabledPlugins(orgPlugins) + for _, plugin := range enabledPlugins.ExternalPlugins { for _, js := range plugin.Js { data.PluginJs = append(data.PluginJs, js.Module) } diff --git a/pkg/models/plugin_bundle.go b/pkg/models/plugin_bundle.go new file mode 100644 index 00000000000..3c126a913ac --- /dev/null +++ b/pkg/models/plugin_bundle.go @@ -0,0 +1,8 @@ +package models + +type PluginBundle struct { + Id int64 + Type string + Org int64 + Enabled bool +} diff --git a/pkg/plugins/models.go b/pkg/plugins/models.go index 8438e96f227..255ea462e67 100644 --- a/pkg/plugins/models.go +++ b/pkg/plugins/models.go @@ -61,3 +61,25 @@ type ExternalPlugin struct { MainNavLinks []*ExternalPluginNavLink `json:"mainNavLinks"` StaticRootConfig *StaticRootConfig `json:"staticRoot"` } + +type PluginBundle struct { + Type string `json:"type"` + Enabled bool `json:"enabled"` + PanelPlugins []string `json:"panelPlugins"` + DatasourcePlugins []string `json:"datasourcePlugins"` + ExternalPlugins []string `json:"externalPlugins"` +} + +type EnabledPlugins struct { + PanelPlugins []*PanelPlugin + DataSourcePlugins map[string]*DataSourcePlugin + ExternalPlugins []*ExternalPlugin +} + +func NewEnabledPlugins() EnabledPlugins { + return EnabledPlugins{ + PanelPlugins: make([]*PanelPlugin, 0), + DataSourcePlugins: make(map[string]*DataSourcePlugin), + ExternalPlugins: make([]*ExternalPlugin, 0), + } +} diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index 16ba1cca7d0..6d45267f8d8 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -9,14 +9,16 @@ import ( "strings" "github.com/grafana/grafana/pkg/log" + "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/setting" ) var ( DataSources map[string]DataSourcePlugin - Panels []PanelPlugin - ExternalPlugins []ExternalPlugin + Panels map[string]PanelPlugin + ExternalPlugins map[string]ExternalPlugin StaticRoutes []*StaticRootConfig + Bundles map[string]PluginBundle ) type PluginScanner struct { @@ -26,9 +28,10 @@ type PluginScanner struct { func Init() error { DataSources = make(map[string]DataSourcePlugin) - ExternalPlugins = make([]ExternalPlugin, 0) + ExternalPlugins = make(map[string]ExternalPlugin) StaticRoutes = make([]*StaticRootConfig, 0) - Panels = make([]PanelPlugin, 0) + Panels = make(map[string]PanelPlugin) + Bundles = make(map[string]PluginBundle) scan(path.Join(setting.StaticRootPath, "app/plugins")) checkExternalPluginPaths() @@ -137,7 +140,7 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error { return errors.New("Did not find type property in plugin.json") } - Panels = append(Panels, p) + Panels[p.Type] = p addStaticRoot(p.StaticRootConfig, currentDir) } @@ -147,9 +150,55 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error { if err := jsonParser.Decode(&p); err != nil { return err } - ExternalPlugins = append(ExternalPlugins, p) + if p.Type == "" { + return errors.New("Did not find type property in plugin.json") + } + ExternalPlugins[p.Type] = p addStaticRoot(p.StaticRootConfig, currentDir) } + if pluginType == "bundle" { + p := PluginBundle{} + reader.Seek(0, 0) + if err := jsonParser.Decode(&p); err != nil { + return err + } + if p.Type == "" { + return errors.New("Did not find type property in plugin.json") + } + Bundles[p.Type] = p + } + return nil } + +func GetEnabledPlugins(bundles map[string]models.PluginBundle) EnabledPlugins { + enabledPlugins := NewEnabledPlugins() + + for bundleType, bundle := range Bundles { + enabled := bundle.Enabled + // check if the bundle is stored in the DB. + if b, ok := bundles[bundleType]; ok { + enabled = b.Enabled + } + + if enabled { + for _, d := range bundle.DatasourcePlugins { + if ds, ok := DataSources[d]; ok { + enabledPlugins.DataSourcePlugins[d] = &ds + } + } + for _, p := range bundle.PanelPlugins { + if panel, ok := Panels[p]; ok { + enabledPlugins.PanelPlugins = append(enabledPlugins.PanelPlugins, &panel) + } + } + for _, e := range bundle.ExternalPlugins { + if external, ok := ExternalPlugins[e]; ok { + enabledPlugins.ExternalPlugins = append(enabledPlugins.ExternalPlugins, &external) + } + } + } + } + return enabledPlugins +} diff --git a/public/app/plugins/plugin.json b/public/app/plugins/plugin.json new file mode 100644 index 00000000000..bbb637bcf9c --- /dev/null +++ b/public/app/plugins/plugin.json @@ -0,0 +1,8 @@ +{ + "pluginType": "bundle", + "type": "core", + "enabled": true, + "panelPlugins": ["graph", "singlestat", "text", "dashlist"], + "datasourcePlugins": ["grafana", "graphite"], + "externalPlugins": [] +}