Forráskód Böngészése

A lot of work on backend plugin model for frontend components, right now for data sources, will enable dropin plugins for data sources and panels, #1472

Torkel Ödegaard 10 éve
szülő
commit
c198242292
42 módosított fájl, 159 hozzáadás és 249 törlés
  1. 1 1
      pkg/api/dtos/models.go
  2. 8 0
      pkg/api/frontendsettings.go
  3. 1 1
      pkg/cmd/datasource.go
  4. 2 0
      pkg/cmd/web.go
  5. 3 4
      pkg/models/datasource.go
  6. 30 12
      pkg/plugins/plugins.go
  7. 2 2
      pkg/plugins/plugins_test.go
  8. 0 4
      src/app/app.js
  9. 0 8
      src/app/components/settings.js
  10. 28 21
      src/app/features/panel/panelSrv.js
  11. 1 3
      src/app/panels/dashlist/module.js
  12. 0 4
      src/app/panels/graph/graph.js
  13. 13 15
      src/app/panels/graph/module.js
  14. 2 3
      src/app/panels/singlestat/module.js
  15. 5 1
      src/app/panels/text/module.js
  16. 1 1
      src/app/partials/metrics.html
  17. 0 10
      src/app/plugins/custom.panel.example/editor.html
  18. 0 3
      src/app/plugins/custom.panel.example/module.html
  19. 0 27
      src/app/plugins/custom.panel.example/module.js
  20. 0 55
      src/app/plugins/datasource.example.js
  21. 0 0
      src/app/plugins/datasources/graphite/addGraphiteFunc.js
  22. 0 6
      src/app/plugins/datasources/graphite/datasource.js
  23. 0 0
      src/app/plugins/datasources/graphite/funcEditor.js
  24. 0 0
      src/app/plugins/datasources/graphite/gfunc.js
  25. 0 0
      src/app/plugins/datasources/graphite/lexer.js
  26. 0 20
      src/app/plugins/datasources/graphite/module.js
  27. 0 0
      src/app/plugins/datasources/graphite/parser.js
  28. 0 0
      src/app/plugins/datasources/graphite/partials/annotations.editor.html
  29. 0 0
      src/app/plugins/datasources/graphite/partials/query.editor.html
  30. 16 5
      src/app/plugins/datasources/graphite/plugin.json
  31. 0 0
      src/app/plugins/datasources/graphite/queryCtrl.js
  32. 1 10
      src/app/plugins/datasources/influxdb_08/datasource.js
  33. 0 0
      src/app/plugins/datasources/influxdb_08/funcEditor.js
  34. 0 0
      src/app/plugins/datasources/influxdb_08/influxSeries.js
  35. 0 0
      src/app/plugins/datasources/influxdb_08/partials/annotations.editor.html
  36. 0 0
      src/app/plugins/datasources/influxdb_08/partials/query.editor.html
  37. 18 0
      src/app/plugins/datasources/influxdb_08/plugin.json
  38. 0 0
      src/app/plugins/datasources/influxdb_08/queryBuilder.js
  39. 0 0
      src/app/plugins/datasources/influxdb_08/queryCtrl.js
  40. 18 30
      src/app/services/datasourceSrv.js
  41. 2 2
      src/test/specs/graph-ctrl-specs.js
  42. 7 1
      src/test/specs/helpers.js

+ 1 - 1
pkg/api/dtos/models.go

@@ -40,7 +40,7 @@ type DataSource struct {
 	Id        int64      `json:"id"`
 	OrgId     int64      `json:"orgId"`
 	Name      string     `json:"name"`
-	Type      m.DsType   `json:"type"`
+	Type      string     `json:"type"`
 	Access    m.DsAccess `json:"access"`
 	Url       string     `json:"url"`
 	Password  string     `json:"password"`

+ 8 - 0
pkg/api/frontendsettings.go

@@ -6,6 +6,7 @@ import (
 	"github.com/grafana/grafana/pkg/bus"
 	"github.com/grafana/grafana/pkg/middleware"
 	m "github.com/grafana/grafana/pkg/models"
+	"github.com/grafana/grafana/pkg/plugins"
 	"github.com/grafana/grafana/pkg/setting"
 )
 
@@ -38,6 +39,13 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
 			"url":  url,
 		}
 
+		meta, exists := plugins.DataSources[ds.Type]
+		if !exists {
+			//return nil, errors.New(fmt.Sprintf("Could not find plugin definition for data source: %v", ds.Type))
+		}
+
+		dsMap["meta"] = meta
+
 		if ds.IsDefault {
 			defaultDatasource = ds.Name
 		}

+ 1 - 1
pkg/cmd/datasource.go

@@ -103,7 +103,7 @@ func createDataSource(c *cli.Context) {
 		OrgId:     orgId,
 		Name:      ds,
 		Url:       url,
-		Type:      m.DsType(dsType),
+		Type:      dsType,
 		Access:    m.DsAccess(dsAccess),
 		IsDefault: dsDefault,
 	}

+ 2 - 0
pkg/cmd/web.go

@@ -16,6 +16,7 @@ import (
 	"github.com/grafana/grafana/pkg/api"
 	"github.com/grafana/grafana/pkg/log"
 	"github.com/grafana/grafana/pkg/middleware"
+	"github.com/grafana/grafana/pkg/plugins"
 	"github.com/grafana/grafana/pkg/services/eventpublisher"
 	"github.com/grafana/grafana/pkg/setting"
 	"github.com/grafana/grafana/pkg/social"
@@ -74,6 +75,7 @@ func runWeb(c *cli.Context) {
 
 	social.NewOAuthService()
 	eventpublisher.Init()
+	plugins.Init()
 
 	var err error
 	m := newMacaron()

+ 3 - 4
pkg/models/datasource.go

@@ -20,7 +20,6 @@ var (
 	ErrDataSourceNotFound = errors.New("Data source not found")
 )
 
-type DsType string
 type DsAccess string
 
 type DataSource struct {
@@ -29,7 +28,7 @@ type DataSource struct {
 	Version int
 
 	Name              string
-	Type              DsType
+	Type              string
 	Access            DsAccess
 	Url               string
 	Password          string
@@ -51,7 +50,7 @@ type DataSource struct {
 type AddDataSourceCommand struct {
 	OrgId     int64 `json:"-"`
 	Name      string
-	Type      DsType
+	Type      string
 	Access    DsAccess
 	Url       string
 	Password  string
@@ -67,7 +66,7 @@ type UpdateDataSourceCommand struct {
 	Id        int64
 	OrgId     int64
 	Name      string
-	Type      DsType
+	Type      string
 	Access    DsAccess
 	Url       string
 	Password  string

+ 30 - 12
pkg/plugins/plugins.go

@@ -4,9 +4,11 @@ import (
 	"encoding/json"
 	"errors"
 	"os"
+	"path"
 	"path/filepath"
 
 	"github.com/grafana/grafana/pkg/log"
+	"github.com/grafana/grafana/pkg/setting"
 )
 
 type PluginMeta struct {
@@ -15,7 +17,7 @@ type PluginMeta struct {
 }
 
 var (
-	List []*PluginMeta
+	DataSources map[string]interface{}
 )
 
 type PluginScanner struct {
@@ -23,8 +25,12 @@ type PluginScanner struct {
 	errors     []error
 }
 
-func Scan(pluginDir string) error {
-	List = make([]*PluginMeta, 0)
+func Init() {
+	scan(path.Join(setting.StaticRootPath, "app/plugins"))
+}
+
+func scan(pluginDir string) error {
+	DataSources = make(map[string]interface{})
 
 	scanner := &PluginScanner{
 		pluginPath: pluginDir,
@@ -51,31 +57,43 @@ func (scanner *PluginScanner) walker(path string, f os.FileInfo, err error) erro
 	}
 
 	if f.Name() == "plugin.json" {
-		pluginMeta, err := loadPluginMeta(path)
+		err := scanner.loadPluginJson(path)
 		if err != nil {
 			log.Error(3, "Failed to load plugin json file: %v,  err: %v", path, err)
 			scanner.errors = append(scanner.errors, err)
-		} else {
-			List = append(List, pluginMeta)
 		}
 	}
 	return nil
 }
 
-func loadPluginMeta(path string) (*PluginMeta, error) {
+func (scanner *PluginScanner) loadPluginJson(path string) error {
 	reader, err := os.Open(path)
 	if err != nil {
-		return nil, err
+		return err
 	}
 
 	defer reader.Close()
 
 	jsonParser := json.NewDecoder(reader)
 
-	pluginMeta := &PluginMeta{}
-	if err := jsonParser.Decode(pluginMeta); err != nil {
-		return nil, err
+	pluginJson := make(map[string]interface{})
+	if err := jsonParser.Decode(&pluginJson); err != nil {
+		return err
+	}
+
+	pluginType, exists := pluginJson["pluginType"]
+	if !exists {
+		return errors.New("Did not find pluginType property in plugin.json")
 	}
 
-	return pluginMeta, nil
+	if pluginType == "datasource" {
+		datasourceType, exists := pluginJson["type"]
+		if !exists {
+			return errors.New("Did not find type property in plugin.json")
+		}
+
+		DataSources[datasourceType.(string)] = pluginJson
+	}
+
+	return nil
 }

+ 2 - 2
pkg/plugins/plugins_test.go

@@ -11,9 +11,9 @@ func TestPluginScans(t *testing.T) {
 
 	Convey("When scaning for plugins", t, func() {
 		path, _ := filepath.Abs("../../src/app/plugins")
-		err := Scan(path)
+		err := scan(path)
 
 		So(err, ShouldBeNil)
-		So(len(List), ShouldEqual, 1)
+		So(len(DataSources), ShouldEqual, 1)
 	})
 }

+ 0 - 4
src/app/app.js

@@ -97,10 +97,6 @@ function (angular, $, _, appLevelRequire, config) {
     'routes/backend/all',
   ];
 
-  _.each(config.plugins.dependencies, function(dep) {
-    preBootRequires.push('../plugins/' + dep);
-  });
-
   app.boot = function() {
     require(preBootRequires, function () {
 

+ 0 - 8
src/app/components/settings.js

@@ -52,14 +52,6 @@ function (_) {
     //   if (datasource.type === 'influxdb') { parseMultipleHosts(datasource); }
     // });
 
-    if (settings.plugins.panels) {
-      _.extend(settings.panels, settings.plugins.panels);
-    }
-
-    if (!settings.plugins.dependencies) {
-      settings.plugins.dependencies = [];
-    }
-
     return settings;
   };
 });

+ 28 - 21
src/app/features/panel/panelSrv.js

@@ -57,12 +57,10 @@ function (angular, _, config) {
 
       $scope.setDatasource = function(datasource) {
         $scope.panel.datasource = datasource;
-        $scope.datasource = datasourceSrv.get(datasource);
-
-        if (!$scope.datasource) {
-          $scope.panelMeta.error = "Cannot find datasource " + datasource;
-          return;
-        }
+        debugger;
+        datasourceSrv.get(datasource).then(function(ds) {
+          $scope.datasource = ds;
+        });
       };
 
       $scope.changeDatasource = function(datasource) {
@@ -90,28 +88,37 @@ function (angular, _, config) {
         return $scope.dashboardViewState.fullscreen && !$scope.fullscreen;
       };
 
+      $scope.get_data = function() {
+        if ($scope.otherPanelInFullscreenMode()) { return; }
+
+        delete $scope.panelMeta.error;
+        $scope.panelMeta.loading = true;
+
+        if ($scope.datasource) {
+          return $scope.refreshData($scope.datasource);
+        }
+
+        datasourceSrv.get($scope.panel.datasource).then(function(datasource) {
+          $scope.datasource = datasource;
+          return $scope.refreshData($scope.datasource);
+        });
+      };
+
+      if ($scope.refreshData) {
+        $scope.$on("refresh", $scope.get_data);
+      }
+
       // Post init phase
       $scope.fullscreen = false;
       $scope.editor = { index: 1 };
 
-      // $scope.datasources = datasourceSrv.getMetricSources();
-      // $scope.setDatasource($scope.panel.datasource);
       $scope.dashboardViewState.registerPanel($scope);
+      $scope.datasources = datasourceSrv.getMetricSources();
 
-      if ($scope.get_data) {
-        var panel_get_data = $scope.get_data;
-        $scope.get_data = function() {
-          if ($scope.otherPanelInFullscreenMode()) { return; }
-
-          delete $scope.panelMeta.error;
-          $scope.panelMeta.loading = true;
-
-          panel_get_data();
-        };
-
-        if (!$scope.skipDataOnInit) {
+      if (!$scope.skipDataOnInit) {
+        $timeout(function() {
           $scope.get_data();
-        }
+        }, 30);
       }
     };
   });

+ 1 - 3
src/app/panels/dashlist/module.js

@@ -47,11 +47,9 @@ function (angular, app, _, config, PanelMeta) {
       if ($scope.isNewPanel()) {
         $scope.panel.title = "Starred Dashboards";
       }
-
-      $scope.$on('refresh', $scope.get_data);
     };
 
-    $scope.get_data = function() {
+    $scope.refreshData = function() {
       var params = {
         limit: $scope.panel.limit
       };

+ 0 - 4
src/app/panels/graph/graph.js

@@ -51,10 +51,6 @@ function (angular, $, kbn, moment, _, GraphTooltip) {
           }
         });
 
-        scope.$on('refresh', function() {
-          scope.get_data();
-        });
-
         // Receive render events
         scope.$on('render',function(event, renderData) {
           data = renderData || data;

+ 13 - 15
src/app/panels/graph/module.js

@@ -23,7 +23,7 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
     };
   });
 
-  module.controller('GraphCtrl', function($scope, $rootScope, panelSrv, annotationsSrv, timeSrv, datasourceSrv) {
+  module.controller('GraphCtrl', function($scope, $rootScope, panelSrv, annotationsSrv, timeSrv) {
 
     $scope.panelMeta = new PanelMeta({
       panelName: 'Graph',
@@ -169,7 +169,7 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
       $scope.interval = kbn.calculateInterval($scope.range, $scope.resolution, $scope.panel.interval);
     };
 
-    $scope.get_data = function() {
+    $scope.refreshData = function(datasource) {
       $scope.updateTimeRange();
 
       var metricsQuery = {
@@ -183,17 +183,15 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
 
       $scope.annotationsPromise = annotationsSrv.getAnnotations($scope.rangeUnparsed, $scope.dashboard);
 
-      return datasourceSrv.get($scope.panel.datasource).then(function(ds) {
-        return ds.query(metricsQuery)
-          .then($scope.dataHandler)
-          .then(null, function(err) {
-            $scope.panelMeta.loading = false;
-            $scope.panelMeta.error = err.message || "Timeseries data request error";
-            $scope.inspector.error = err;
-            $scope.seriesList = [];
-            $scope.render([]);
-          });
-      });
+      return datasource.query(metricsQuery)
+        .then($scope.dataHandler)
+        .then(null, function(err) {
+          $scope.panelMeta.loading = false;
+          $scope.panelMeta.error = err.message || "Timeseries data request error";
+          $scope.inspector.error = err;
+          $scope.seriesList = [];
+          $scope.render([]);
+        });
     };
 
     $scope.dataHandler = function(results) {
@@ -230,8 +228,8 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
 
       var series = new TimeSeries({
         datapoints: datapoints,
-        alias: alias,
-        color: color,
+          alias: alias,
+          color: color,
       });
 
       if (datapoints && datapoints.length > 0) {

+ 2 - 3
src/app/panels/singlestat/module.js

@@ -74,7 +74,6 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
 
     $scope.init = function() {
       panelSrv.init($scope);
-      $scope.$on('refresh', $scope.get_data);
     };
 
     $scope.updateTimeRange = function () {
@@ -84,7 +83,7 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
       $scope.interval = kbn.calculateInterval($scope.range, $scope.resolution, $scope.panel.interval);
     };
 
-    $scope.get_data = function() {
+    $scope.refreshData = function(datasource) {
       $scope.updateTimeRange();
 
       var metricsQuery = {
@@ -95,7 +94,7 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
         cacheTimeout: $scope.panel.cacheTimeout
       };
 
-      return $scope.datasource.query(metricsQuery)
+      return datasource.query(metricsQuery)
         .then($scope.dataHandler)
         .then(null, function(err) {
           console.log("err");

+ 5 - 1
src/app/panels/text/module.js

@@ -43,7 +43,11 @@ function (angular, app, _, require, PanelMeta) {
     $scope.init = function() {
       panelSrv.init($scope);
       $scope.ready = false;
-      $scope.$on('refresh', $scope.render);
+      $scope.render();
+    };
+
+    $scope.refreshData = function() {
+      $scope.panelMeta.loading = false;
       $scope.render();
     };
 

+ 1 - 1
src/app/partials/metrics.html

@@ -1,4 +1,4 @@
-<div ng-include src="datasource.editorSrc"></div>
+<div ng-include src="datasource.meta.partials.query"></div>
 
 
 <div class="editor-row" style="margin-top: 30px">

+ 0 - 10
src/app/plugins/custom.panel.example/editor.html

@@ -1,10 +0,0 @@
-<div>
-  <div class="row-fluid">
-    <div class="span4">
-      <label class="small">Mode</label> <select class="input-medium" ng-model="panel.mode" ng-options="f for f in ['html','markdown','text']"></select>
-    </div>
-    <div class="span2" ng-show="panel.mode == 'text'">
-      <label class="small">Font Size</label> <select class="input-mini" ng-model="panel.style['font-size']" ng-options="f for f in ['6pt','7pt','8pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select>
-    </div>
-  </div>
-</div>

+ 0 - 3
src/app/plugins/custom.panel.example/module.html

@@ -1,3 +0,0 @@
-<div ng-controller='CustomPanelCtrl'>
-	<h2>Custom panel</h2>
-</div>

+ 0 - 27
src/app/plugins/custom.panel.example/module.js

@@ -1,27 +0,0 @@
-define([
-  'angular',
-  'app',
-  'lodash',
-  'components/panelmeta',
-],
-function (angular, app, _, PanelMeta) {
-  'use strict';
-
-  var module = angular.module('grafana.panels.custom', []);
-  app.useModule(module);
-
-  module.controller('CustomPanelCtrl', function($scope, panelSrv) {
-
-    $scope.panelMeta = new PanelMeta({
-      description : "A static text panel that can use plain text, markdown, or (sanitized) HTML"
-    });
-
-    // set and populate defaults
-    var _d = {
-    };
-
-    _.defaults($scope.panel, _d);
-
-    panelSrv.init($scope);
-  });
-});

+ 0 - 55
src/app/plugins/datasource.example.js

@@ -1,55 +0,0 @@
-define([
-  'angular',
-  'lodash',
-  'kbn',
-  'moment'
-],
-function (angular, _, kbn) {
-  'use strict';
-
-  var module = angular.module('grafana.services');
-
-  module.factory('CustomDatasource', function($q) {
-
-    // the datasource object passed to constructor
-    // is the same defined in config.js
-    function CustomDatasource(datasource) {
-      this.name = datasource.name;
-      this.supportMetrics = true;
-      this.url = datasource.url;
-    }
-
-    CustomDatasource.prototype.query = function(options) {
-      // get from & to in seconds
-      var from = kbn.parseDate(options.range.from).getTime();
-      var to = kbn.parseDate(options.range.to).getTime();
-
-      var series = [];
-      var stepInSeconds = (to - from) / options.maxDataPoints;
-
-      for (var i = 0; i < 3; i++) {
-        var walker = Math.random() * 100;
-        var time = from;
-        var timeSeries = {
-          target: "Series " + i,
-          datapoints: []
-        };
-
-        for (var j = 0; j < options.maxDataPoints; j++) {
-          timeSeries.datapoints[j] = [walker, time];
-          walker += Math.random() - 0.5;
-          time += stepInSeconds;
-        }
-
-        series.push(timeSeries);
-      }
-
-      return $q.when({data: series });
-
-    };
-
-    return CustomDatasource;
-
-  });
-
-});

+ 0 - 0
src/app/features/graphite/addGraphiteFunc.js → src/app/plugins/datasources/graphite/addGraphiteFunc.js


+ 0 - 6
src/app/features/graphite/datasource.js → src/app/plugins/datasources/graphite/datasource.js

@@ -17,18 +17,12 @@ function (angular, _, $, config, kbn, moment) {
   module.factory('GraphiteDatasource', function($q, $http, templateSrv) {
 
     function GraphiteDatasource(datasource) {
-      this.type = 'graphite';
       this.basicAuth = datasource.basicAuth;
       this.url = datasource.url;
       this.name = datasource.name;
       this.cacheTimeout = datasource.cacheTimeout;
       this.withCredentials = datasource.withCredentials;
       this.render_method = datasource.render_method || 'POST';
-
-      this.supportAnnotations = true;
-      this.supportMetrics = true;
-      this.editorSrc = 'app/features/graphite/partials/query.editor.html';
-      this.annotationEditorSrc = 'app/features/graphite/partials/annotations.editor.html';
     }
 
     GraphiteDatasource.prototype.query = function(options) {

+ 0 - 0
src/app/features/graphite/funcEditor.js → src/app/plugins/datasources/graphite/funcEditor.js


+ 0 - 0
src/app/features/graphite/gfunc.js → src/app/plugins/datasources/graphite/gfunc.js


+ 0 - 0
src/app/features/graphite/lexer.js → src/app/plugins/datasources/graphite/lexer.js


+ 0 - 20
src/app/plugins/datasources/graphite/module.js

@@ -1,20 +0,0 @@
-define([
-  'angular',
-],
-function (angular) {
-  'use strict';
-
-  var module = angular.module('grafana.services');
-
-  module.factory('MyDataSource', function() {
-
-    function MyDataSource(datasource) {
-      this.type = 'my_ds';
-      this.datasource = datasource;
-    }
-
-    return MyDataSource;
-
-  });
-
-});

+ 0 - 0
src/app/features/graphite/parser.js → src/app/plugins/datasources/graphite/parser.js


+ 0 - 0
src/app/features/graphite/partials/annotations.editor.html → src/app/plugins/datasources/graphite/partials/annotations.editor.html


+ 0 - 0
src/app/features/graphite/partials/query.editor.html → src/app/plugins/datasources/graphite/partials/query.editor.html


+ 16 - 5
src/app/plugins/datasources/graphite/plugin.json

@@ -1,7 +1,18 @@
 {
-  "type": "datasource",
-  "name": "My Data source",
-  "keyName": "graphite"
-  "serviceName": "MyDataSource",
-  "editPartial": "./partials/edit.html",
+  "pluginType": "datasource",
+  "description": "Graphite",
+
+  "type": "graphite",
+  "serviceName": "GraphiteDatasource",
+
+  "module": "plugins/datasources/graphite/datasource",
+
+  "partials": {
+    "config": "app/plugins/datasources/graphite/partials/config.html",
+    "query": "app/plugins/datasources/graphite/partials/query.editor.html",
+    "annotations": "app/plugins/datasources/graphite/partials/query.editor.html"
+  },
+
+  "metrics": true,
+  "annotations": true
 }

+ 0 - 0
src/app/features/graphite/queryCtrl.js → src/app/plugins/datasources/graphite/queryCtrl.js


+ 1 - 10
src/app/features/influxdb_08/datasource.js → src/app/plugins/datasources/influxdb_08/datasource.js

@@ -15,23 +15,14 @@ function (angular, _, kbn, InfluxSeries, InfluxQueryBuilder) {
   module.factory('InfluxDatasource_08', function($q, $http, templateSrv) {
 
     function InfluxDatasource(datasource) {
-      this.type = 'influxdb_08';
       this.urls = _.map(datasource.url.split(','), function(url) {
         return url.trim();
       });
+
       this.username = datasource.username;
       this.password = datasource.password;
       this.name = datasource.name;
       this.basicAuth = datasource.basicAuth;
-      this.grafanaDB = datasource.grafanaDB;
-
-      this.saveTemp = _.isUndefined(datasource.save_temp) ? true : datasource.save_temp;
-      this.saveTempTTL = _.isUndefined(datasource.save_temp_ttl) ? '30d' : datasource.save_temp_ttl;
-
-      this.supportAnnotations = true;
-      this.supportMetrics = true;
-      this.editorSrc = 'app/features/influxdb_08/partials/query.editor.html';
-      this.annotationEditorSrc = 'app/features/influxdb_08/partials/annotations.editor.html';
     }
 
     InfluxDatasource.prototype.query = function(options) {

+ 0 - 0
src/app/features/influxdb_08/funcEditor.js → src/app/plugins/datasources/influxdb_08/funcEditor.js


+ 0 - 0
src/app/features/influxdb_08/influxSeries.js → src/app/plugins/datasources/influxdb_08/influxSeries.js


+ 0 - 0
src/app/features/influxdb_08/partials/annotations.editor.html → src/app/plugins/datasources/influxdb_08/partials/annotations.editor.html


+ 0 - 0
src/app/features/influxdb_08/partials/query.editor.html → src/app/plugins/datasources/influxdb_08/partials/query.editor.html


+ 18 - 0
src/app/plugins/datasources/influxdb_08/plugin.json

@@ -0,0 +1,18 @@
+{
+  "pluginType": "datasource",
+  "description": "InfluxDB 0.8.x",
+
+  "type": "influxdb_08",
+  "serviceName": "InfluxDatasource08",
+
+  "module": "plugins/datasources/influxdb_08/datasource",
+
+  "partials": {
+    "config": "app/plugins/datasources/influxdb_08/partials/config.html",
+    "query": "app/plugins/datasources/influxdb_08/partials/query.editor.html",
+    "annotations": "app/plugins/datasources/influxdb_08/partials/query.editor.html"
+  },
+
+  "metrics": true,
+  "annotations": true
+}

+ 0 - 0
src/app/features/influxdb_08/queryBuilder.js → src/app/plugins/datasources/influxdb_08/queryBuilder.js


+ 0 - 0
src/app/features/influxdb_08/queryCtrl.js → src/app/plugins/datasources/influxdb_08/queryCtrl.js


+ 18 - 30
src/app/services/datasourceSrv.js

@@ -7,37 +7,27 @@ function (angular, _, config) {
   'use strict';
 
   var module = angular.module('grafana.services');
-  var typeMap = {
-    'graphite': 'GraphiteDatasource',
-    'influxdb': 'InfluxDatasource',
-    'influxdb_08': 'InfluxDatasource_08',
-    'elasticsearch': 'ElasticDatasource',
-    'opentsdb': 'OpenTSDBDatasource',
-    'grafana': 'GrafanaDatasource',
-  };
-
-  var plugins = {
-    datasources: {
-      'graphite': {
-        'serviceName': 'GraphiteDatasource',
-        'module': 'features/graphite/datasource'
-      }
-    }
-  };
 
   module.service('datasourceSrv', function($q, $injector, $rootScope) {
     var self = this;
 
     this.datasources = {};
+    this.metricSources = [];
+    this.annotationSources = [];
+    this.grafanaDB = new ($injector.get("GrafanaDatasource"));
 
     this.init = function(dsSettingList) {
       config.datasources = dsSettingList;
-    };
 
-    this.datasourceFactory = function(ds) {
-      var type = typeMap[ds.type] || ds.type;
-      var Datasource = $injector.get(type);
-      return new Datasource(ds);
+      _.each(config.datasources, function(value, key) {
+        if (value.meta && value.meta.metrics) {
+          self.metricSources.push({ value: key, name: key });
+        }
+      });
+
+      if (!config.defaultDatasource) {
+        $rootScope.appEvent('alert-error', ["No default data source found", ""]);
+      }
     };
 
     this.get = function(name) {
@@ -53,18 +43,16 @@ function (angular, _, config) {
     };
 
     this.loadDatasource = function(name) {
-      var datasourceConfig = config.datasources[name];
-      var pluginDef = plugins.datasources[datasourceConfig.type];
-
-      if (!pluginDef) {
-        throw { message: "No plugin definition for data source: " + name };
-      }
-
+      var dsConfig = config.datasources[name];
       var deferred = $q.defer();
 
+      var pluginDef = dsConfig.meta;
+
       $rootScope.require([pluginDef.module], function() {
         var AngularService = $injector.get(pluginDef.serviceName);
-        var instance = new AngularService(datasourceConfig);
+        var instance = new AngularService(dsConfig, pluginDef);
+        instance.meta = pluginDef;
+        instance.name = name;
         self.datasources[name] = instance;
         deferred.resolve(instance);
       });

+ 2 - 2
src/test/specs/graph-ctrl-specs.js

@@ -24,7 +24,7 @@ define([
           ]
         }));
         ctx.scope.render = sinon.spy();
-        ctx.scope.get_data();
+        ctx.scope.refreshData(ctx.datasource);
         ctx.scope.$digest();
       });
 
@@ -36,7 +36,7 @@ define([
       describe('get_data failure following success', function() {
         beforeEach(function() {
           ctx.datasource.query = sinon.stub().returns(ctx.$q.reject('Datasource Error'));
-          ctx.scope.get_data();
+          ctx.scope.refreshData(ctx.datasource);
           ctx.scope.$digest();
         });
 

+ 7 - 1
src/test/specs/helpers.js

@@ -14,7 +14,13 @@ define([
     this.templateSrv = new TemplateSrvStub();
     this.datasourceSrv = {
       getMetricSources: function() {},
-      get: function() { return self.datasource; }
+      get: function() {
+        return {
+          then: function(callback) {
+            callback(self.datasource);
+          }
+        };
+      }
     };
 
     this.providePhase = function(mocks) {