Browse Source

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.
woodsaj 10 years ago
parent
commit
bd4cb549d6

+ 4 - 1
pkg/api/datasources.go

@@ -115,8 +115,11 @@ func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) {
 
 
 func GetDataSourcePlugins(c *middleware.Context) {
 func GetDataSourcePlugins(c *middleware.Context) {
 	dsList := make(map[string]interface{})
 	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 {
 		if !value.BuiltIn {
 			dsList[key] = value
 			dsList[key] = value
 		}
 		}

+ 6 - 2
pkg/api/frontendsettings.go

@@ -29,6 +29,10 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
 	datasources := make(map[string]interface{})
 	datasources := make(map[string]interface{})
 	var defaultDatasource string
 	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 {
 	for _, ds := range orgDataSources {
 		url := ds.Url
 		url := ds.Url
 
 
@@ -42,7 +46,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
 			"url":  url,
 			"url":  url,
 		}
 		}
 
 
-		meta, exists := plugins.DataSources[ds.Type]
+		meta, exists := enabledPlugins.DataSourcePlugins[ds.Type]
 		if !exists {
 		if !exists {
 			log.Error(3, "Could not find plugin definition for data source: %v", ds.Type)
 			log.Error(3, "Could not find plugin definition for data source: %v", ds.Type)
 			continue
 			continue
@@ -107,7 +111,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
 	}
 	}
 
 
 	panels := map[string]interface{}{}
 	panels := map[string]interface{}{}
-	for _, panel := range plugins.Panels {
+	for _, panel := range enabledPlugins.PanelPlugins {
 		panels[panel.Type] = map[string]interface{}{
 		panels[panel.Type] = map[string]interface{}{
 			"module": panel.Module,
 			"module": panel.Module,
 			"name":   panel.Name,
 			"name":   panel.Name,

+ 4 - 1
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 {
 		for _, js := range plugin.Js {
 			data.PluginJs = append(data.PluginJs, js.Module)
 			data.PluginJs = append(data.PluginJs, js.Module)
 		}
 		}

+ 8 - 0
pkg/models/plugin_bundle.go

@@ -0,0 +1,8 @@
+package models
+
+type PluginBundle struct {
+	Id      int64
+	Type    string
+	Org     int64
+	Enabled bool
+}

+ 22 - 0
pkg/plugins/models.go

@@ -61,3 +61,25 @@ type ExternalPlugin struct {
 	MainNavLinks     []*ExternalPluginNavLink `json:"mainNavLinks"`
 	MainNavLinks     []*ExternalPluginNavLink `json:"mainNavLinks"`
 	StaticRootConfig *StaticRootConfig        `json:"staticRoot"`
 	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),
+	}
+}

+ 55 - 6
pkg/plugins/plugins.go

@@ -9,14 +9,16 @@ import (
 	"strings"
 	"strings"
 
 
 	"github.com/grafana/grafana/pkg/log"
 	"github.com/grafana/grafana/pkg/log"
+	"github.com/grafana/grafana/pkg/models"
 	"github.com/grafana/grafana/pkg/setting"
 	"github.com/grafana/grafana/pkg/setting"
 )
 )
 
 
 var (
 var (
 	DataSources     map[string]DataSourcePlugin
 	DataSources     map[string]DataSourcePlugin
-	Panels          []PanelPlugin
-	ExternalPlugins []ExternalPlugin
+	Panels          map[string]PanelPlugin
+	ExternalPlugins map[string]ExternalPlugin
 	StaticRoutes    []*StaticRootConfig
 	StaticRoutes    []*StaticRootConfig
+	Bundles         map[string]PluginBundle
 )
 )
 
 
 type PluginScanner struct {
 type PluginScanner struct {
@@ -26,9 +28,10 @@ type PluginScanner struct {
 
 
 func Init() error {
 func Init() error {
 	DataSources = make(map[string]DataSourcePlugin)
 	DataSources = make(map[string]DataSourcePlugin)
-	ExternalPlugins = make([]ExternalPlugin, 0)
+	ExternalPlugins = make(map[string]ExternalPlugin)
 	StaticRoutes = make([]*StaticRootConfig, 0)
 	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"))
 	scan(path.Join(setting.StaticRootPath, "app/plugins"))
 	checkExternalPluginPaths()
 	checkExternalPluginPaths()
@@ -137,7 +140,7 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error {
 			return errors.New("Did not find type property in plugin.json")
 			return errors.New("Did not find type property in plugin.json")
 		}
 		}
 
 
-		Panels = append(Panels, p)
+		Panels[p.Type] = p
 		addStaticRoot(p.StaticRootConfig, currentDir)
 		addStaticRoot(p.StaticRootConfig, currentDir)
 	}
 	}
 
 
@@ -147,9 +150,55 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error {
 		if err := jsonParser.Decode(&p); err != nil {
 		if err := jsonParser.Decode(&p); err != nil {
 			return err
 			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)
 		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
 	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
+}

+ 8 - 0
public/app/plugins/plugin.json

@@ -0,0 +1,8 @@
+{
+  "pluginType": "bundle",
+  "type": "core",
+  "enabled": true,
+  "panelPlugins": ["graph", "singlestat", "text", "dashlist"],
+  "datasourcePlugins": ["grafana", "graphite"],
+  "externalPlugins": []
+}