Просмотр исходного кода

Merge remote-tracking branch 'origin/master' into panelbase

Torkel Ödegaard 10 лет назад
Родитель
Сommit
11e35f7b68

+ 28 - 46
docker/blocks/graphite/Dockerfile

@@ -1,68 +1,50 @@
-from	ubuntu:14.10
+from  ubuntu:14.04
 
 
-run	apt-get -y update
+run apt-get -y update
 
 
-run apt-get -y install software-properties-common
-
-run	apt-get -y install python-software-properties &&\
-	add-apt-repository ppa:chris-lea/node.js &&\
-	apt-get -y update
-
-run apt-get -y install  python-django-tagging python-simplejson python-memcache \
-			    python-ldap python-cairo python-django python-twisted   \
-			    python-pysqlite2 python-support python-pip gunicorn     \
-			    supervisor nginx-light nodejs git wget curl
-
-# Install statsd
-run mkdir /src && git clone https://github.com/etsy/statsd.git /src/statsd
+run apt-get -y install libcairo2-dev libffi-dev pkg-config python-dev python-pip fontconfig apache2 libapache2-mod-wsgi git-core collectd memcached gcc g++ make supervisor nginx-light gunicorn
 
 
 run cd /usr/local/src && git clone https://github.com/graphite-project/graphite-web.git
 run cd /usr/local/src && git clone https://github.com/graphite-project/graphite-web.git
 run cd /usr/local/src && git clone https://github.com/graphite-project/carbon.git
 run cd /usr/local/src && git clone https://github.com/graphite-project/carbon.git
 run cd /usr/local/src && git clone https://github.com/graphite-project/whisper.git
 run cd /usr/local/src && git clone https://github.com/graphite-project/whisper.git
 
 
 run cd /usr/local/src/whisper && git checkout master && python setup.py install
 run cd /usr/local/src/whisper && git checkout master && python setup.py install
-run cd /usr/local/src/carbon && git checkout 0.9.x && python setup.py install
-run cd /usr/local/src/graphite-web && git checkout 0.9.x && python check-dependencies.py; python setup.py install
-
-# statsd
-add	./files/statsd_config.js /src/statsd/config.js
+run cd /usr/local/src/carbon && git checkout 0.9.x && pip install -r requirements.txt; python setup.py install
+run cd /usr/local/src/graphite-web && git checkout 0.9.x && pip install -r requirements.txt; python check-dependencies.py; python setup.py install
 
 
 # Add graphite config
 # Add graphite config
-add	./files/initial_data.json /opt/graphite/webapp/graphite/initial_data.json
-add	./files/local_settings.py /opt/graphite/webapp/graphite/local_settings.py
-add	./files/carbon.conf /opt/graphite/conf/carbon.conf
-add	./files/storage-schemas.conf /opt/graphite/conf/storage-schemas.conf
-add	./files/storage-aggregation.conf /opt/graphite/conf/storage-aggregation.conf
-add     ./files/events_views.py /opt/graphite/webapp/graphite/events/views.py
-
-run	mkdir -p /opt/graphite/storage/whisper
-run	touch /opt/graphite/storage/graphite.db /opt/graphite/storage/index
-run	chown -R www-data /opt/graphite/storage
-run	chmod 0775 /opt/graphite/storage /opt/graphite/storage/whisper
-run	chmod 0664 /opt/graphite/storage/graphite.db
-run	cd /opt/graphite/webapp/graphite && python manage.py syncdb --noinput
+add ./files/initial_data.json /opt/graphite/webapp/graphite/initial_data.json
+add ./files/local_settings.py /opt/graphite/webapp/graphite/local_settings.py
+add ./files/carbon.conf /opt/graphite/conf/carbon.conf
+add ./files/storage-schemas.conf /opt/graphite/conf/storage-schemas.conf
+add ./files/storage-aggregation.conf /opt/graphite/conf/storage-aggregation.conf
+add ./files/events_views.py /opt/graphite/webapp/graphite/events/views.py
+
+run mkdir -p /opt/graphite/storage/whisper
+run touch /opt/graphite/storage/graphite.db /opt/graphite/storage/index
+run chown -R www-data /opt/graphite/storage
+run chmod 0775 /opt/graphite/storage /opt/graphite/storage/whisper
+run chmod 0664 /opt/graphite/storage/graphite.db
+run cd /opt/graphite/webapp/graphite && python manage.py syncdb --noinput
+
+add ./files/my_htpasswd /etc/nginx/.htpasswd
 
 
 # Add system service config
 # Add system service config
-add	./files/nginx.conf /etc/nginx/nginx.conf
-add	./files/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
-
+add ./files/nginx.conf /etc/nginx/nginx.conf
+add ./files/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
+# Nginx
+#
 # graphite
 # graphite
-expose	80
+expose  80
 
 
 # Carbon line receiver port
 # Carbon line receiver port
-expose	2003
+expose  2003
 # Carbon cache query port
 # Carbon cache query port
-expose	7002
-
-# Statsd UDP port
-expose	8125/udp
-# Statsd Management port
-expose	8126
+expose  7002
 
 
-VOLUME ["/var/lib/elasticsearch"]
 VOLUME ["/opt/graphite/storage/whisper"]
 VOLUME ["/opt/graphite/storage/whisper"]
 VOLUME ["/var/lib/log/supervisor"]
 VOLUME ["/var/lib/log/supervisor"]
 
 
-cmd	["/usr/bin/supervisord"]
+cmd ["/usr/bin/supervisord"]
 
 
 # vim:ts=8:noet:
 # vim:ts=8:noet:

+ 7 - 1
docker/blocks/graphite/fig

@@ -1,4 +1,10 @@
 graphite:
 graphite:
   build: blocks/graphite
   build: blocks/graphite
   ports:
   ports:
-    - "8776:80"
+    - "8080:80"
+    - "2003:2003"
+  volumes:
+    - /var/docker/gfdev/graphite:/opt/graphite/storage/whisper
+    - /etc/localtime:/etc/localtime:ro
+    - /etc/timezone:/etc/timezone:ro
+

+ 1 - 0
docker/blocks/graphite/files/my_htpasswd

@@ -0,0 +1 @@
+grafana:$apr1$4R/20xhC$8t37jPP5dbcLr48btdkU//

+ 0 - 7
docker/blocks/graphite/files/supervisord.conf

@@ -24,10 +24,3 @@ stdout_logfile = /var/log/supervisor/%(program_name)s.log
 stderr_logfile = /var/log/supervisor/%(program_name)s.log
 stderr_logfile = /var/log/supervisor/%(program_name)s.log
 autorestart = true
 autorestart = true
 
 
-[program:statsd]
-;user = www-data
-command = /usr/bin/node /src/statsd/stats.js /src/statsd/config.js
-stdout_logfile = /var/log/supervisor/%(program_name)s.log
-stderr_logfile = /var/log/supervisor/%(program_name)s.log
-autorestart = true
-

+ 1 - 1
pkg/api/api.go

@@ -215,7 +215,7 @@ func Register(r *macaron.Macaron) {
 	// rendering
 	// rendering
 	r.Get("/render/*", reqSignedIn, RenderToPng)
 	r.Get("/render/*", reqSignedIn, RenderToPng)
 
 
-	InitApiPluginRoutes(r)
+	InitAppPluginRoutes(r)
 
 
 	r.NotFound(NotFoundHandler)
 	r.NotFound(NotFoundHandler)
 }
 }

+ 13 - 19
pkg/api/api_plugin.go → pkg/api/app_routes.go

@@ -19,10 +19,10 @@ import (
 	"github.com/grafana/grafana/pkg/util"
 	"github.com/grafana/grafana/pkg/util"
 )
 )
 
 
-func InitApiPluginRoutes(r *macaron.Macaron) {
-	for _, plugin := range plugins.ApiPlugins {
-		log.Info("Plugin: Adding proxy routes for api plugin")
+func InitAppPluginRoutes(r *macaron.Macaron) {
+	for _, plugin := range plugins.Apps {
 		for _, route := range plugin.Routes {
 		for _, route := range plugin.Routes {
+			log.Info("Plugin: Adding proxy route for app plugin")
 			url := util.JoinUrlFragments("/api/plugin-proxy/", route.Path)
 			url := util.JoinUrlFragments("/api/plugin-proxy/", route.Path)
 			handlers := make([]macaron.Handler, 0)
 			handlers := make([]macaron.Handler, 0)
 			if route.ReqSignedIn {
 			if route.ReqSignedIn {
@@ -38,24 +38,24 @@ func InitApiPluginRoutes(r *macaron.Macaron) {
 					handlers = append(handlers, middleware.RoleAuth(m.ROLE_EDITOR, m.ROLE_ADMIN))
 					handlers = append(handlers, middleware.RoleAuth(m.ROLE_EDITOR, m.ROLE_ADMIN))
 				}
 				}
 			}
 			}
-			handlers = append(handlers, ApiPlugin(route, plugin.IncludedInAppId))
+			handlers = append(handlers, AppPluginRoute(route, plugin.Id))
 			r.Route(url, route.Method, handlers...)
 			r.Route(url, route.Method, handlers...)
 			log.Info("Plugin: Adding route %s", url)
 			log.Info("Plugin: Adding route %s", url)
 		}
 		}
 	}
 	}
 }
 }
 
 
-func ApiPlugin(route *plugins.ApiPluginRoute, includedInAppId string) macaron.Handler {
+func AppPluginRoute(route *plugins.AppPluginRoute, appId string) macaron.Handler {
 	return func(c *middleware.Context) {
 	return func(c *middleware.Context) {
 		path := c.Params("*")
 		path := c.Params("*")
 
 
-		proxy := NewApiPluginProxy(c, path, route, includedInAppId)
+		proxy := NewApiPluginProxy(c, path, route, appId)
 		proxy.Transport = dataProxyTransport
 		proxy.Transport = dataProxyTransport
 		proxy.ServeHTTP(c.Resp, c.Req.Request)
 		proxy.ServeHTTP(c.Resp, c.Req.Request)
 	}
 	}
 }
 }
 
 
-func NewApiPluginProxy(ctx *middleware.Context, proxyPath string, route *plugins.ApiPluginRoute, includedInAppId string) *httputil.ReverseProxy {
+func NewApiPluginProxy(ctx *middleware.Context, proxyPath string, route *plugins.AppPluginRoute, appId string) *httputil.ReverseProxy {
 	targetUrl, _ := url.Parse(route.Url)
 	targetUrl, _ := url.Parse(route.Url)
 
 
 	director := func(req *http.Request) {
 	director := func(req *http.Request) {
@@ -87,21 +87,15 @@ func NewApiPluginProxy(ctx *middleware.Context, proxyPath string, route *plugins
 				return
 				return
 			}
 			}
 
 
-			jsonData := make(map[string]interface{})
+			//lookup appSettings
+			query := m.GetAppSettingByAppIdQuery{OrgId: ctx.OrgId, AppId: appId}
 
 
-			if includedInAppId != "" {
-				//lookup appSettings
-				query := m.GetAppSettingByAppIdQuery{OrgId: ctx.OrgId, AppId: includedInAppId}
-
-				if err := bus.Dispatch(&query); err != nil {
-					ctx.JsonApiErr(500, "failed to get AppSettings of includedAppId.", err)
-					return
-				}
-
-				jsonData = query.Result.JsonData
+			if err := bus.Dispatch(&query); err != nil {
+				ctx.JsonApiErr(500, "failed to get AppSettings.", err)
+				return
 			}
 			}
 
 
-			err = t.Execute(&contentBuf, jsonData)
+			err = t.Execute(&contentBuf, query.Result.JsonData)
 			if err != nil {
 			if err != nil {
 				ctx.JsonApiErr(500, fmt.Sprintf("failed to execute header content template for header %s.", header.Name), err)
 				ctx.JsonApiErr(500, fmt.Sprintf("failed to execute header content template for header %s.", header.Name), err)
 				return
 				return

+ 0 - 38
pkg/plugins/api_plugin.go

@@ -1,38 +0,0 @@
-package plugins
-
-import (
-	"encoding/json"
-
-	"github.com/grafana/grafana/pkg/models"
-)
-
-type ApiPluginRoute struct {
-	Path            string            `json:"path"`
-	Method          string            `json:"method"`
-	ReqSignedIn     bool              `json:"reqSignedIn"`
-	ReqGrafanaAdmin bool              `json:"reqGrafanaAdmin"`
-	ReqRole         models.RoleType   `json:"reqRole"`
-	Url             string            `json:"url"`
-	Headers         []ApiPluginHeader `json:"headers"`
-}
-
-type ApiPlugin struct {
-	PluginBase
-	Routes []*ApiPluginRoute `json:"routes"`
-}
-
-type ApiPluginHeader struct {
-	Name    string `json:"name"`
-	Content string `json:"content"`
-}
-
-func (app *ApiPlugin) Load(decoder *json.Decoder, pluginDir string) error {
-	if err := decoder.Decode(&app); err != nil {
-		return err
-	}
-
-	app.PluginDir = pluginDir
-
-	ApiPlugins[app.Id] = app
-	return nil
-}

+ 19 - 15
pkg/plugins/app_plugin.go

@@ -26,14 +26,30 @@ type AppIncludeInfo struct {
 
 
 type AppPlugin struct {
 type AppPlugin struct {
 	FrontendPluginBase
 	FrontendPluginBase
-	Css      *AppPluginCss    `json:"css"`
-	Pages    []AppPluginPage  `json:"pages"`
-	Includes []AppIncludeInfo `json:"-"`
+	Css      *AppPluginCss     `json:"css"`
+	Pages    []AppPluginPage   `json:"pages"`
+	Routes   []*AppPluginRoute `json:"routes"`
+	Includes []AppIncludeInfo  `json:"-"`
 
 
 	Pinned  bool `json:"-"`
 	Pinned  bool `json:"-"`
 	Enabled bool `json:"-"`
 	Enabled bool `json:"-"`
 }
 }
 
 
+type AppPluginRoute struct {
+	Path            string                 `json:"path"`
+	Method          string                 `json:"method"`
+	ReqSignedIn     bool                   `json:"reqSignedIn"`
+	ReqGrafanaAdmin bool                   `json:"reqGrafanaAdmin"`
+	ReqRole         models.RoleType        `json:"reqRole"`
+	Url             string                 `json:"url"`
+	Headers         []AppPluginRouteHeader `json:"headers"`
+}
+
+type AppPluginRouteHeader struct {
+	Name    string `json:"name"`
+	Content string `json:"content"`
+}
+
 func (app *AppPlugin) Load(decoder *json.Decoder, pluginDir string) error {
 func (app *AppPlugin) Load(decoder *json.Decoder, pluginDir string) error {
 	if err := decoder.Decode(&app); err != nil {
 	if err := decoder.Decode(&app); err != nil {
 		return err
 		return err
@@ -59,18 +75,6 @@ func (app *AppPlugin) Load(decoder *json.Decoder, pluginDir string) error {
 		}
 		}
 	}
 	}
 
 
-	// check if we have child apiPlugins
-	for _, plugin := range ApiPlugins {
-		if strings.HasPrefix(plugin.PluginDir, app.PluginDir) {
-			plugin.IncludedInAppId = app.Id
-			app.Includes = append(app.Includes, AppIncludeInfo{
-				Name: plugin.Name,
-				Id:   plugin.Id,
-				Type: plugin.Type,
-			})
-		}
-	}
-
 	Apps[app.Id] = app
 	Apps[app.Id] = app
 	return nil
 	return nil
 }
 }

+ 0 - 2
pkg/plugins/models.go

@@ -45,7 +45,6 @@ type PluginStaticRoute struct {
 type EnabledPlugins struct {
 type EnabledPlugins struct {
 	Panels      []*PanelPlugin
 	Panels      []*PanelPlugin
 	DataSources map[string]*DataSourcePlugin
 	DataSources map[string]*DataSourcePlugin
-	ApiList     []*ApiPlugin
 	Apps        []*AppPlugin
 	Apps        []*AppPlugin
 }
 }
 
 
@@ -53,7 +52,6 @@ func NewEnabledPlugins() EnabledPlugins {
 	return EnabledPlugins{
 	return EnabledPlugins{
 		Panels:      make([]*PanelPlugin, 0),
 		Panels:      make([]*PanelPlugin, 0),
 		DataSources: make(map[string]*DataSourcePlugin),
 		DataSources: make(map[string]*DataSourcePlugin),
-		ApiList:     make([]*ApiPlugin, 0),
 		Apps:        make([]*AppPlugin, 0),
 		Apps:        make([]*AppPlugin, 0),
 	}
 	}
 }
 }

+ 0 - 3
pkg/plugins/plugins.go

@@ -17,7 +17,6 @@ import (
 var (
 var (
 	DataSources  map[string]*DataSourcePlugin
 	DataSources  map[string]*DataSourcePlugin
 	Panels       map[string]*PanelPlugin
 	Panels       map[string]*PanelPlugin
-	ApiPlugins   map[string]*ApiPlugin
 	StaticRoutes []*PluginStaticRoute
 	StaticRoutes []*PluginStaticRoute
 	Apps         map[string]*AppPlugin
 	Apps         map[string]*AppPlugin
 	PluginTypes  map[string]interface{}
 	PluginTypes  map[string]interface{}
@@ -30,14 +29,12 @@ type PluginScanner struct {
 
 
 func Init() error {
 func Init() error {
 	DataSources = make(map[string]*DataSourcePlugin)
 	DataSources = make(map[string]*DataSourcePlugin)
-	ApiPlugins = make(map[string]*ApiPlugin)
 	StaticRoutes = make([]*PluginStaticRoute, 0)
 	StaticRoutes = make([]*PluginStaticRoute, 0)
 	Panels = make(map[string]*PanelPlugin)
 	Panels = make(map[string]*PanelPlugin)
 	Apps = make(map[string]*AppPlugin)
 	Apps = make(map[string]*AppPlugin)
 	PluginTypes = map[string]interface{}{
 	PluginTypes = map[string]interface{}{
 		"panel":      PanelPlugin{},
 		"panel":      PanelPlugin{},
 		"datasource": DataSourcePlugin{},
 		"datasource": DataSourcePlugin{},
-		"api":        ApiPlugin{},
 		"app":        AppPlugin{},
 		"app":        AppPlugin{},
 	}
 	}
 
 

+ 0 - 6
pkg/plugins/queries.go

@@ -68,11 +68,5 @@ func GetEnabledPlugins(orgId int64) (*EnabledPlugins, error) {
 		}
 		}
 	}
 	}
 
 
-	for _, api := range ApiPlugins {
-		if isPluginEnabled(api.IncludedInAppId) {
-			enabledPlugins.ApiList = append(enabledPlugins.ApiList, api)
-		}
-	}
-
 	return &enabledPlugins, nil
 	return &enabledPlugins, nil
 }
 }

+ 4 - 0
public/app/plugins/datasource/opentsdb/datasource.js

@@ -272,6 +272,10 @@ function (angular, _, dateMath) {
         }
         }
 
 
         query.downsample = interval + "-" + target.downsampleAggregator;
         query.downsample = interval + "-" + target.downsampleAggregator;
+
+        if (target.downsampleFillPolicy !== "none") {
+          query.downsample += "-" + target.downsampleFillPolicy;
+        }
       }
       }
 
 
       query.tags = angular.copy(target.tags);
       query.tags = angular.copy(target.tags);

+ 14 - 2
public/app/plugins/datasource/opentsdb/partials/query.editor.html

@@ -104,8 +104,20 @@
 			</select>
 			</select>
 		</li>
 		</li>
 
 
-		<li class="tight-form-item query-keyword">
-			Disable downsampling <editor-checkbox text="" model="target.disableDownsampling" change="targetBlur()"></editor-checkbox>
+    <li class="tight-form-item query-keyword">
+      Fill policy
+      <tip>Available since OpenTSDB 2.2</tip>
+    </li>
+
+    <li>
+      <select ng-model="target.downsampleFillPolicy" class="tight-form-input input-small"
+              ng-options="agg for agg in fillPolicies"
+              ng-change="targetBlur()">
+      </select>
+    </li>
+
+    <li class="tight-form-item query-keyword">
+      Disable downsampling <editor-checkbox text="" model="target.disableDownsampling" change="targetBlur()"></editor-checkbox>
 		</li>
 		</li>
 
 
 	</ul>
 	</ul>

+ 5 - 0
public/app/plugins/datasource/opentsdb/queryCtrl.js

@@ -13,6 +13,7 @@ function (angular, _, kbn) {
     $scope.init = function() {
     $scope.init = function() {
       $scope.target.errors = validateTarget($scope.target);
       $scope.target.errors = validateTarget($scope.target);
       $scope.aggregators = ['avg', 'sum', 'min', 'max', 'dev', 'zimsum', 'mimmin', 'mimmax'];
       $scope.aggregators = ['avg', 'sum', 'min', 'max', 'dev', 'zimsum', 'mimmin', 'mimmax'];
+      $scope.fillPolicies = ['none', 'nan', 'null', 'zero'];
 
 
       if (!$scope.target.aggregator) {
       if (!$scope.target.aggregator) {
         $scope.target.aggregator = 'sum';
         $scope.target.aggregator = 'sum';
@@ -22,6 +23,10 @@ function (angular, _, kbn) {
         $scope.target.downsampleAggregator = 'avg';
         $scope.target.downsampleAggregator = 'avg';
       }
       }
 
 
+      if (!$scope.target.downsampleFillPolicy) {
+        $scope.target.downsampleFillPolicy = 'none';
+      }
+
       $scope.datasource.getAggregators().then(function(aggs) {
       $scope.datasource.getAggregators().then(function(aggs) {
         $scope.aggregators = aggs;
         $scope.aggregators = aggs;
       });
       });