From f3bc726001bfbc707597bce5fa169b46e992eb7a Mon Sep 17 00:00:00 2001 From: Hereward Cooper Date: Sat, 31 Oct 2015 19:06:03 -0700 Subject: [PATCH 01/18] Dynamically reorder hovercard --- public/app/panels/graph/graph.tooltip.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/public/app/panels/graph/graph.tooltip.js b/public/app/panels/graph/graph.tooltip.js index 8a747b61e0c..65891af324c 100644 --- a/public/app/panels/graph/graph.tooltip.js +++ b/public/app/panels/graph/graph.tooltip.js @@ -74,9 +74,9 @@ function ($) { // Stacked series can increase its length on each new stacked serie if null points found, // to speed the index search we begin always on the last found hoverIndex. var newhoverIndex = this.findHoverIndexFromDataPoints(pos.x, series, hoverIndex); - results.push({ value: value, hoverIndex: newhoverIndex}); + results.push({ value: value, hoverIndex: newhoverIndex, color: series.color, label: series.label }); } else { - results.push({ value: value, hoverIndex: hoverIndex}); + results.push({ value: value, hoverIndex: hoverIndex, color: series.color, label: series.label }); } } @@ -119,6 +119,11 @@ function ($) { seriesHtml = ''; timestamp = dashboard.formatDate(seriesHoverInfo.time); + // Dynamically reorder the hovercard for the current time point. + seriesHoverInfo.sort(function(a, b) { + return parseFloat(b.value) - parseFloat(a.value); + }); + for (i = 0; i < seriesHoverInfo.length; i++) { hoverInfo = seriesHoverInfo[i]; @@ -130,7 +135,7 @@ function ($) { value = series.formatValue(hoverInfo.value); seriesHtml += '
'; - seriesHtml += ' ' + series.label + ':
'; + seriesHtml += ' ' + hoverInfo.label + ':
'; seriesHtml += '
' + value + '
'; plot.highlight(i, hoverInfo.hoverIndex); } From ea566fff24ed0e1a68cd2e0f53fb616cd9782fc7 Mon Sep 17 00:00:00 2001 From: Daniel Low Date: Tue, 24 Nov 2015 16:17:21 +0000 Subject: [PATCH 02/18] Add TLS for mysql Use ssl_mode for mysql and add docs add docs for the new parameters in config Tolerate ssl_mode without client authentication Client cert is not necessary for a SSL connection. So we tolerate failure if client cert is not provided. Improve error message if missing server_cert_name and mode is not skip-verify. --- conf/defaults.ini | 8 ++++- docs/sources/installation/configuration.md | 19 +++++++++- pkg/services/sqlstore/sqlstore.go | 27 ++++++++++++++ pkg/services/sqlstore/tls_mysql.go | 41 ++++++++++++++++++++++ 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 pkg/services/sqlstore/tls_mysql.go diff --git a/conf/defaults.ini b/conf/defaults.ini index 3655a48a18a..bef3269132c 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -63,9 +63,15 @@ name = grafana user = root password = -# For "postgres" only, either "disable", "require" or "verify-full" +# For "postgres", use either "disable", "require" or "verify-full" +# For "mysql", use either "true", "false", or "skip-verify". ssl_mode = disable +ca_cert_path = +client_key_path = +client_cert_path = +server_cert_name = + # For "sqlite3" only, path relative to data_path setting path = grafana.db diff --git a/docs/sources/installation/configuration.md b/docs/sources/installation/configuration.md index daa2d665e07..247cfbb0d19 100644 --- a/docs/sources/installation/configuration.md +++ b/docs/sources/installation/configuration.md @@ -156,7 +156,24 @@ The database user's password (not applicable for `sqlite3`). ### ssl_mode -For `postgres` only, either `disable`, `require` or `verify-full`. +For Postgres, use either `disable`, `require` or `verify-full`. +For MySQL, use either `true`, `false`, or `skip-verify`. + +### ca_cert_path + +(MySQL only) The path to the CA certificate to use. On many linux systems, certs can be found in `/etc/ssl/certs`. + +### client_key_path + +(MySQL only) The path to the client key. Only if server requires client authentication. + +### client_cert_path + +(MySQL only) The path to the client cert. Only if server requires client authentication. + +### server_cert_name + +(MySQL only) The common name field of the certificate used by the `mysql` server. Not necessary if `ssl_mode` is set to `skip-verify`.
diff --git a/pkg/services/sqlstore/sqlstore.go b/pkg/services/sqlstore/sqlstore.go index 88c35d630f8..9217d6c32ec 100644 --- a/pkg/services/sqlstore/sqlstore.go +++ b/pkg/services/sqlstore/sqlstore.go @@ -18,8 +18,17 @@ import ( "github.com/go-xorm/xorm" _ "github.com/lib/pq" _ "github.com/mattn/go-sqlite3" + "github.com/go-sql-driver/mysql" ) +type MySQLConfig struct { + SslMode string + CaCertPath string + ClientKeyPath string + ClientCertPath string + ServerCertName string +} + var ( x *xorm.Engine dialect migrator.Dialect @@ -30,6 +39,8 @@ var ( Type, Host, Name, User, Pwd, Path, SslMode string } + mysqlConfig MySQLConfig + UseSQLite3 bool ) @@ -115,6 +126,14 @@ func getEngine() (*xorm.Engine, error) { case "mysql": cnnstr = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8", DbCfg.User, DbCfg.Pwd, DbCfg.Host, DbCfg.Name) + if mysqlConfig.SslMode == "true" || mysqlConfig.SslMode == "skip-verify" { + tlsCert, err := makeCert("custom", mysqlConfig) + if err != nil { + return nil, err + } + mysql.RegisterTLSConfig("custom", tlsCert) + cnnstr += "&tls=custom" + } case "postgres": var host, port = "127.0.0.1", "5432" fields := strings.Split(DbCfg.Host, ":") @@ -156,4 +175,12 @@ func LoadConfig() { } DbCfg.SslMode = sec.Key("ssl_mode").String() DbCfg.Path = sec.Key("path").MustString("data/grafana.db") + + if DbCfg.Type == "mysql" { + mysqlConfig.SslMode = DbCfg.SslMode + mysqlConfig.CaCertPath = sec.Key("ca_cert_path").String() + mysqlConfig.ClientKeyPath = sec.Key("client_key_path").String() + mysqlConfig.ClientCertPath = sec.Key("client_cert_path").String() + mysqlConfig.ServerCertName = sec.Key("server_cert_name").String() + } } diff --git a/pkg/services/sqlstore/tls_mysql.go b/pkg/services/sqlstore/tls_mysql.go new file mode 100644 index 00000000000..f5c25a63149 --- /dev/null +++ b/pkg/services/sqlstore/tls_mysql.go @@ -0,0 +1,41 @@ +package sqlstore + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "io/ioutil" +) + +func makeCert(tlsPoolName string, config MySQLConfig) (*tls.Config, error) { + rootCertPool := x509.NewCertPool() + pem, err := ioutil.ReadFile(config.CaCertPath) + if err != nil { + return nil, fmt.Errorf("Could not read DB CA Cert path: %v", config.CaCertPath) + } + if ok := rootCertPool.AppendCertsFromPEM(pem); !ok { + return nil, err + } + clientCert := make([]tls.Certificate, 0, 1) + if (config.ClientCertPath != "" && config.ClientKeyPath != "") { + + certs, err := tls.LoadX509KeyPair(config.ClientCertPath, config.ClientKeyPath) + if err != nil { + return nil, err + } + clientCert = append(clientCert, certs) + } + tlsConfig := &tls.Config{ + RootCAs: rootCertPool, + Certificates: clientCert, + } + tlsConfig.ServerName = config.ServerCertName + if config.SslMode == "skip-verify" { + tlsConfig.InsecureSkipVerify = true + } + // Return more meaningful error before it is too late + if config.ServerCertName == "" && !tlsConfig.InsecureSkipVerify{ + return nil, fmt.Errorf("server_cert_name is missing. Consider using ssl_mode = skip-verify.") + } + return tlsConfig, nil +} From 3f9f0679ecbef5232c11d6bf9d7550a650fa2ce3 Mon Sep 17 00:00:00 2001 From: Daniel Low Date: Tue, 22 Dec 2015 13:10:34 +0000 Subject: [PATCH 03/18] gofmt --- pkg/services/sqlstore/sqlstore.go | 6 +++--- pkg/services/sqlstore/tls_mysql.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/services/sqlstore/sqlstore.go b/pkg/services/sqlstore/sqlstore.go index 9217d6c32ec..221edc51155 100644 --- a/pkg/services/sqlstore/sqlstore.go +++ b/pkg/services/sqlstore/sqlstore.go @@ -14,16 +14,16 @@ import ( "github.com/grafana/grafana/pkg/services/sqlstore/migrator" "github.com/grafana/grafana/pkg/setting" + "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql" "github.com/go-xorm/xorm" _ "github.com/lib/pq" _ "github.com/mattn/go-sqlite3" - "github.com/go-sql-driver/mysql" ) type MySQLConfig struct { - SslMode string - CaCertPath string + SslMode string + CaCertPath string ClientKeyPath string ClientCertPath string ServerCertName string diff --git a/pkg/services/sqlstore/tls_mysql.go b/pkg/services/sqlstore/tls_mysql.go index f5c25a63149..fb55eb401c9 100644 --- a/pkg/services/sqlstore/tls_mysql.go +++ b/pkg/services/sqlstore/tls_mysql.go @@ -17,7 +17,7 @@ func makeCert(tlsPoolName string, config MySQLConfig) (*tls.Config, error) { return nil, err } clientCert := make([]tls.Certificate, 0, 1) - if (config.ClientCertPath != "" && config.ClientKeyPath != "") { + if config.ClientCertPath != "" && config.ClientKeyPath != "" { certs, err := tls.LoadX509KeyPair(config.ClientCertPath, config.ClientKeyPath) if err != nil { @@ -34,7 +34,7 @@ func makeCert(tlsPoolName string, config MySQLConfig) (*tls.Config, error) { tlsConfig.InsecureSkipVerify = true } // Return more meaningful error before it is too late - if config.ServerCertName == "" && !tlsConfig.InsecureSkipVerify{ + if config.ServerCertName == "" && !tlsConfig.InsecureSkipVerify { return nil, fmt.Errorf("server_cert_name is missing. Consider using ssl_mode = skip-verify.") } return tlsConfig, nil From cd23ab995593175ee7b36acbc516975d8e213e06 Mon Sep 17 00:00:00 2001 From: Ed Dawley Date: Wed, 23 Dec 2015 01:33:46 -0600 Subject: [PATCH 04/18] Issue 3461: Session table is now created automatically --- pkg/services/sqlstore/migrations/migrations.go | 1 + pkg/services/sqlstore/migrations/session_mig.go | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 pkg/services/sqlstore/migrations/session_mig.go diff --git a/pkg/services/sqlstore/migrations/migrations.go b/pkg/services/sqlstore/migrations/migrations.go index 569d26282ed..4c9283e36ac 100644 --- a/pkg/services/sqlstore/migrations/migrations.go +++ b/pkg/services/sqlstore/migrations/migrations.go @@ -19,6 +19,7 @@ func AddMigrations(mg *Migrator) { addDashboardSnapshotMigrations(mg) addQuotaMigration(mg) addPluginBundleMigration(mg) + addSessionMigration(mg) } func addMigrationLogMigrations(mg *Migrator) { diff --git a/pkg/services/sqlstore/migrations/session_mig.go b/pkg/services/sqlstore/migrations/session_mig.go new file mode 100644 index 00000000000..ed675ede8fd --- /dev/null +++ b/pkg/services/sqlstore/migrations/session_mig.go @@ -0,0 +1,16 @@ +package migrations + +import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator" + +func addSessionMigration(mg *Migrator) { + var sessionV1 = Table{ + Name: "session", + Columns: []*Column{ + {Name: "key", Type: DB_Char, IsPrimaryKey: true, Length: 16}, + {Name: "data", Type: DB_Blob}, + {Name: "expiry", Type: DB_Integer, Length: 255, Nullable: false}, + }, + } + + mg.AddMigration("create session table", NewAddTableMigration(sessionV1)) +} From 4da56b65ab5f19564fea10abbf8f338b40a45c68 Mon Sep 17 00:00:00 2001 From: Ed Dawley Date: Wed, 23 Dec 2015 15:06:28 -0600 Subject: [PATCH 05/18] Fixes #2818. Adds support for mysql backends via unix sockets --- conf/defaults.ini | 4 +++- pkg/services/sqlstore/sqlstore.go | 9 +++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/conf/defaults.ini b/conf/defaults.ini index 3655a48a18a..c241fc3643c 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -79,7 +79,9 @@ provider = file # file: session dir path, is relative to grafana data_path # redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana` # postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable -# mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name` +# mysql: go-sql-driver/mysql dsn config string, examples: +# `user:password@tcp(127.0.0.1:3306)/database_name` +# `user:password@unix(1/var/run/mysqld/mysqld.sock)/database_name` # memcache: 127.0.0.1:11211 diff --git a/pkg/services/sqlstore/sqlstore.go b/pkg/services/sqlstore/sqlstore.go index 88c35d630f8..50b6e931c7c 100644 --- a/pkg/services/sqlstore/sqlstore.go +++ b/pkg/services/sqlstore/sqlstore.go @@ -113,8 +113,13 @@ func getEngine() (*xorm.Engine, error) { cnnstr := "" switch DbCfg.Type { case "mysql": - cnnstr = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8", - DbCfg.User, DbCfg.Pwd, DbCfg.Host, DbCfg.Name) + protocol := "tcp" + if strings.HasPrefix(DbCfg.Host, "/") { + protocol = "unix" + } + + cnnstr = fmt.Sprintf("%s:%s@%s(%s)/%s?charset=utf8", + DbCfg.User, DbCfg.Pwd, protocol, DbCfg.Host, DbCfg.Name) case "postgres": var host, port = "127.0.0.1", "5432" fields := strings.Split(DbCfg.Host, ":") From ec36e2836878cbad0ba4bb536bf1461668ad15ba Mon Sep 17 00:00:00 2001 From: Ed Dawley Date: Wed, 23 Dec 2015 15:15:59 -0600 Subject: [PATCH 06/18] Small typo in comment --- conf/defaults.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/defaults.ini b/conf/defaults.ini index c241fc3643c..0693044dbbb 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -81,7 +81,7 @@ provider = file # postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable # mysql: go-sql-driver/mysql dsn config string, examples: # `user:password@tcp(127.0.0.1:3306)/database_name` -# `user:password@unix(1/var/run/mysqld/mysqld.sock)/database_name` +# `user:password@unix(/var/run/mysqld/mysqld.sock)/database_name` # memcache: 127.0.0.1:11211 From c0cf0cb802adad24252ce1307c4c896edd566870 Mon Sep 17 00:00:00 2001 From: Qtax Date: Sat, 5 Dec 2015 22:08:30 +0100 Subject: [PATCH 07/18] Added an option to set a min-width for the graphs side table/area. --- public/app/plugins/panels/graph/axisEditor.html | 7 +++++++ public/app/plugins/panels/graph/legend.js | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/public/app/plugins/panels/graph/axisEditor.html b/public/app/plugins/panels/graph/axisEditor.html index d8a537dda46..13bc78b7dfe 100644 --- a/public/app/plugins/panels/graph/axisEditor.html +++ b/public/app/plugins/panels/graph/axisEditor.html @@ -181,6 +181,13 @@
  • +
  • + Side width +
  • +
  • + +
  • diff --git a/public/app/plugins/panels/graph/legend.js b/public/app/plugins/panels/graph/legend.js index 4f4a0d8ee06..2d3f8ac3b90 100644 --- a/public/app/plugins/panels/graph/legend.js +++ b/public/app/plugins/panels/graph/legend.js @@ -101,6 +101,10 @@ function (angular, _, $) { $container.empty(); + // Set min-width if side style and there is a value, otherwise remove the CSS propery + var width = panel.legend.rightSide && panel.legend.sideWidth ? panel.legend.sideWidth + "px" : ""; + $container.css("min-width", width); + $container.toggleClass('graph-legend-table', panel.legend.alignAsTable === true); if (panel.legend.alignAsTable) { From be48caf59f891138699786c7431b799b838adbc7 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Thu, 31 Dec 2015 15:47:42 +0900 Subject: [PATCH 08/18] fix Prometheus link, expand template variable in expression --- public/app/plugins/datasource/prometheus/query_ctrl.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/query_ctrl.js b/public/app/plugins/datasource/prometheus/query_ctrl.js index bbbaff4aa56..0b0377bf81b 100644 --- a/public/app/plugins/datasource/prometheus/query_ctrl.js +++ b/public/app/plugins/datasource/prometheus/query_ctrl.js @@ -7,7 +7,7 @@ function (angular, _) { var module = angular.module('grafana.controllers'); - module.controller('PrometheusQueryCtrl', function($scope) { + module.controller('PrometheusQueryCtrl', function($scope, templateSrv) { $scope.init = function() { var target = $scope.target; @@ -48,7 +48,7 @@ function (angular, _) { var range = Math.ceil(($scope.range.to.valueOf() - $scope.range.from.valueOf()) / 1000); var endTime = $scope.range.to.utc().format('YYYY-MM-DD HH:MM'); var expr = { - expr: $scope.target.expr, + expr: templateSrv.replace($scope.target.expr, $scope.panel.scopedVars), range_input: range + 's', end_input: endTime, step_input: '', From ebf0bd5fc95a707c45b4419b0a8f4ef43851695c Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Thu, 31 Dec 2015 15:57:15 +0900 Subject: [PATCH 09/18] fix end time of Prometheus link --- public/app/plugins/datasource/prometheus/query_ctrl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/prometheus/query_ctrl.js b/public/app/plugins/datasource/prometheus/query_ctrl.js index 0b0377bf81b..83d92ae74a2 100644 --- a/public/app/plugins/datasource/prometheus/query_ctrl.js +++ b/public/app/plugins/datasource/prometheus/query_ctrl.js @@ -46,7 +46,7 @@ function (angular, _) { $scope.linkToPrometheus = function() { var range = Math.ceil(($scope.range.to.valueOf() - $scope.range.from.valueOf()) / 1000); - var endTime = $scope.range.to.utc().format('YYYY-MM-DD HH:MM'); + var endTime = $scope.range.to.utc().format('YYYY-MM-DD HH:mm'); var expr = { expr: templateSrv.replace($scope.target.expr, $scope.panel.scopedVars), range_input: range + 's', From cc1ed98fc43653e4876f002b1eec2233466a4478 Mon Sep 17 00:00:00 2001 From: AQNOUCH Mohammed Date: Fri, 1 Jan 2016 01:30:43 +0000 Subject: [PATCH 10/18] Updated copyright to 2016 --- LICENSE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index db0c6ac0cb6..2699d589e8e 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright 2014-2015 Torkel Ödegaard, Raintank Inc. +Copyright 2014-2016 Torkel Ödegaard, Raintank Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may From 5af3fe93f277647a0380816c54feaf24d26d8434 Mon Sep 17 00:00:00 2001 From: Henri DF Date: Mon, 4 Jan 2016 21:48:47 -0800 Subject: [PATCH 11/18] Docs: add example with filter in ES template --- docs/sources/datasources/elasticsearch.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/sources/datasources/elasticsearch.md b/docs/sources/datasources/elasticsearch.md index de9ada2bf58..314a0f4870b 100644 --- a/docs/sources/datasources/elasticsearch.md +++ b/docs/sources/datasources/elasticsearch.md @@ -77,6 +77,11 @@ The Elasticsearch datasource supports two types of queries you can use to fill t {"find": "fields", "type": "string"} ``` +### Fields filtered by type, with filter +```json +{"find": "fields", "type": "string", "query": } +``` + ### Multi format / All format Use lucene format. From 5de69b288f0ff4540188b5415b1073e3ad20c256 Mon Sep 17 00:00:00 2001 From: bergquist Date: Tue, 5 Jan 2016 19:21:12 +0100 Subject: [PATCH 12/18] feat(singlestat): make sparkline height dynamic closes #3553 --- public/app/plugins/panels/singlestat/singleStatPanel.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/app/plugins/panels/singlestat/singleStatPanel.js b/public/app/plugins/panels/singlestat/singleStatPanel.js index b04f1c57dcd..a176ea974ae 100644 --- a/public/app/plugins/panels/singlestat/singleStatPanel.js +++ b/public/app/plugins/panels/singlestat/singleStatPanel.js @@ -97,7 +97,8 @@ function (angular, app, _, $) { plotCss.bottom = '5px'; plotCss.left = '-5px'; plotCss.width = (width - 10) + 'px'; - plotCss.height = (height - 45) + 'px'; + var dynamicHeightMargin = height <= 100 ? 5 : (Math.round((height/100)) * 15) + 5; + plotCss.height = (height - dynamicHeightMargin) + 'px'; } else { plotCss.bottom = "0px"; From 9343b0378df4eebeab8e77113173632da2f9c034 Mon Sep 17 00:00:00 2001 From: bergquist Date: Wed, 6 Jan 2016 11:57:17 +0100 Subject: [PATCH 13/18] feat(plugins): adds warn log for scanning folders symlinks outside to plugin folder can cause problems. This commit makes sure to warn about it in the logs --- pkg/plugins/plugins.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index e7de4d5f2dd..89cb3c75ed0 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -55,6 +55,7 @@ func scan(pluginDir string) error { } if err := util.Walk(pluginDir, true, true, scanner.walker); err != nil { + log.Warn("Failed to scan dir \"%v\" error: %s", pluginDir, err) return err } From 5792a162226a6426e2a67ec5b3c246b20b4f932d Mon Sep 17 00:00:00 2001 From: bergquist Date: Thu, 7 Jan 2016 08:51:31 +0100 Subject: [PATCH 14/18] fix(plugins): removes warnings for missing folder Remove warnings when scanning for plugins in the default catalog data/plugins closes #3663 --- pkg/plugins/plugins.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index 89cb3c75ed0..23b927e5ea9 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -55,7 +55,9 @@ func scan(pluginDir string) error { } if err := util.Walk(pluginDir, true, true, scanner.walker); err != nil { - log.Warn("Failed to scan dir \"%v\" error: %s", pluginDir, err) + if pluginDir != "data/plugins" { + log.Warn("Could not scan dir \"%v\" error: %s", pluginDir, err) + } return err } From f5565d48148712e878348210dd4e228d2a4f0860 Mon Sep 17 00:00:00 2001 From: bergquist Date: Thu, 7 Jan 2016 17:39:25 +0100 Subject: [PATCH 15/18] docs(changelog): add note about ssl support for mysql --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe810822cdc..565a84d032d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### Enhancements ### * **Sessions**: Support for memcached as session storage, closes [#3458](https://github.com/grafana/grafana/pull/3458) +* **mysql**: Grafana now supports ssl for mysql, closes [#3584](https://github.com/grafana/grafana/pull/3584) # 2.6.1 (unrelased, 2.6.x branch) From bcdddfe4e8aa9641398666c45e3a2bd51dee0c15 Mon Sep 17 00:00:00 2001 From: bergquist Date: Thu, 7 Jan 2016 18:09:51 +0100 Subject: [PATCH 16/18] style(tooltip): removed comment and extrated sort --- public/app/plugins/panels/graph/graph.tooltip.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/public/app/plugins/panels/graph/graph.tooltip.js b/public/app/plugins/panels/graph/graph.tooltip.js index 95e0f6ae181..99fb20b2ed5 100644 --- a/public/app/plugins/panels/graph/graph.tooltip.js +++ b/public/app/plugins/panels/graph/graph.tooltip.js @@ -126,10 +126,7 @@ function ($) { relativeTime = dashboard.getRelativeTime(seriesHoverInfo.time); absoluteTime = dashboard.formatDate(seriesHoverInfo.time); - // Dynamically reorder the hovercard for the current time point. - seriesHoverInfo.sort(function(a, b) { - return parseFloat(b.value) - parseFloat(a.value); - }); + seriesHoverInfo.sort(byToolTipValue); for (i = 0; i < seriesHoverInfo.length; i++) { hoverInfo = seriesHoverInfo[i]; @@ -179,5 +176,9 @@ function ($) { }); } + function byToolTipValue(a, b) { + return parseFloat(b.value) - parseFloat(a.value); + } + return GraphTooltip; }); From 52644bb28a59974b4f71ba4502be0ff3fadebf4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 7 Jan 2016 20:50:45 +0100 Subject: [PATCH 17/18] fix(timepicker): fixed recent breaking of datetime picker when swithing from requirejs to systemjs --- .../dashboard/timepicker/input_date.js | 44 ------------------- .../dashboard/timepicker/input_date.ts | 41 +++++++++++++++++ .../dashboard/timepicker/timepicker.ts | 6 +-- public/app/grafana.ts | 2 +- 4 files changed, 45 insertions(+), 48 deletions(-) delete mode 100644 public/app/features/dashboard/timepicker/input_date.js create mode 100644 public/app/features/dashboard/timepicker/input_date.ts diff --git a/public/app/features/dashboard/timepicker/input_date.js b/public/app/features/dashboard/timepicker/input_date.js deleted file mode 100644 index caec5ba55fe..00000000000 --- a/public/app/features/dashboard/timepicker/input_date.js +++ /dev/null @@ -1,44 +0,0 @@ -define([ - "angular", - "lodash", - "moment", -],function (angular, _, moment) { - 'use strict'; - - angular. - module("grafana.directives"). - directive('inputDatetime', function () { - return { - restrict: 'A', - require: 'ngModel', - link: function ($scope, $elem, attrs, ngModel) { - var format = 'YYYY-MM-DD HH:mm:ss'; - - var fromUser = function (text) { - if (text.indexOf('now') !== -1) { - return text; - } - var parsed; - if ($scope.ctrl.isUtc) { - parsed = moment.utc(text, format); - } else { - parsed = moment(text, format); - } - - return parsed.isValid() ? parsed : undefined; - }; - - var toUser = function (currentValue) { - if (moment.isMoment(currentValue)) { - return currentValue.format(format); - } else { - return currentValue; - } - }; - - ngModel.$parsers.push(fromUser); - ngModel.$formatters.push(toUser); - } - }; - }); -}); diff --git a/public/app/features/dashboard/timepicker/input_date.ts b/public/app/features/dashboard/timepicker/input_date.ts new file mode 100644 index 00000000000..66173ffd1b9 --- /dev/null +++ b/public/app/features/dashboard/timepicker/input_date.ts @@ -0,0 +1,41 @@ +/// + +import _ from 'lodash'; +import angular from 'angular'; +import moment from 'moment'; + +export function inputDateDirective() { + return { + restrict: 'A', + require: 'ngModel', + link: function ($scope, $elem, attrs, ngModel) { + var format = 'YYYY-MM-DD HH:mm:ss'; + + var fromUser = function (text) { + if (text.indexOf('now') !== -1) { + return text; + } + var parsed; + if ($scope.ctrl.isUtc) { + parsed = moment.utc(text, format); + } else { + parsed = moment(text, format); + } + + return parsed.isValid() ? parsed : undefined; + }; + + var toUser = function (currentValue) { + if (moment.isMoment(currentValue)) { + return currentValue.format(format); + } else { + return currentValue; + } + }; + + ngModel.$parsers.push(fromUser); + ngModel.$formatters.push(toUser); + } + }; +} + diff --git a/public/app/features/dashboard/timepicker/timepicker.ts b/public/app/features/dashboard/timepicker/timepicker.ts index 6ac7d73436e..b44f6ed8a9a 100644 --- a/public/app/features/dashboard/timepicker/timepicker.ts +++ b/public/app/features/dashboard/timepicker/timepicker.ts @@ -1,5 +1,4 @@ /// -/// import _ from 'lodash'; import kbn from 'app/core/utils/kbn'; @@ -9,8 +8,6 @@ import moment from 'moment'; import * as dateMath from 'app/core/utils/datemath'; import * as rangeUtil from 'app/core/utils/rangeutil'; -declare var inputDate: any; - export class TimePickerCtrl { static tooltipFormat = 'MMM D, YYYY HH:mm:ss'; @@ -179,3 +176,6 @@ export function timePickerDirective() { angular.module('grafana.directives').directive('gfTimePickerSettings', settingsDirective); angular.module('grafana.directives').directive('gfTimePicker', timePickerDirective); + +import {inputDateDirective} from './input_date'; +angular.module("grafana.directives").directive('inputDatetime', inputDateDirective); diff --git a/public/app/grafana.ts b/public/app/grafana.ts index bc126e7b56f..11d521e6757 100644 --- a/public/app/grafana.ts +++ b/public/app/grafana.ts @@ -56,7 +56,7 @@ export class GrafanaApp { 'ang-drag-drop', 'grafana', 'pasvaz.bindonce', - 'ui.bootstrap.tabs', + 'ui.bootstrap', 'ui.bootstrap.tpls', ]; From 255901ca7ca696ecf6ea866ee4e59a8fa2f27a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 7 Jan 2016 21:59:55 +0100 Subject: [PATCH 18/18] fix(graph panel): fixed bug in typeahead when adding series style override, fixes #3554 --- CHANGELOG.md | 3 +++ public/app/core/directives/dropdown_typeahead.js | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 850ebfee008..923498aefc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ ### New Features * **Elasticsearch**: Support for derivative unit option, closes [#3512](https://github.com/grafana/grafana/issues/3512) +### Bug fixes +* **Graph Panel**: Fixed typehead when adding series style override, closes [#3554](https://github.com/grafana/grafana/issues/3554) + # 2.6.0 (2015-12-14) ### New Features diff --git a/public/app/core/directives/dropdown_typeahead.js b/public/app/core/directives/dropdown_typeahead.js index ad484bb18d7..902aaae44fa 100644 --- a/public/app/core/directives/dropdown_typeahead.js +++ b/public/app/core/directives/dropdown_typeahead.js @@ -74,11 +74,10 @@ function (_, $, coreModule) { updater: function (value) { var result = {}; _.each($scope.menuItems, function(menuItem) { - result.$item = menuItem; - _.each(menuItem.submenu, function(submenuItem) { if (value === (menuItem.text + ' ' + submenuItem.text)) { result.$subItem = submenuItem; + result.$item = menuItem; } }); });