diff --git a/.circleci/config.yml b/.circleci/config.yml index a4bb2d67855..fe72996797e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -170,6 +170,7 @@ jobs: - scripts/*.sh - scripts/publish - scripts/build/release_publisher/release_publisher + - scripts/build/publish.sh build: docker: diff --git a/package.json b/package.json index 333cd361ac4..f4ca54c2926 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "company": "Grafana Labs" }, "name": "grafana", - "version": "5.3.0", + "version": "5.3.1", "repository": { "type": "git", "url": "http://github.com/grafana/grafana.git" diff --git a/pkg/api/org_users.go b/pkg/api/org_users.go index 4e2ed36431e..13af654e4c7 100644 --- a/pkg/api/org_users.go +++ b/pkg/api/org_users.go @@ -45,7 +45,7 @@ func addOrgUserHelper(cmd m.AddOrgUserCommand) Response { // GET /api/org/users func GetOrgUsersForCurrentOrg(c *m.ReqContext) Response { - return getOrgUsersHelper(c.OrgId, c.Params("query"), c.ParamsInt("limit")) + return getOrgUsersHelper(c.OrgId, c.Query("query"), c.QueryInt("limit")) } // GET /api/orgs/:orgId/users diff --git a/pkg/tsdb/elasticsearch/time_series_query.go b/pkg/tsdb/elasticsearch/time_series_query.go index fddcf3cb8b3..869e23e21ce 100644 --- a/pkg/tsdb/elasticsearch/time_series_query.go +++ b/pkg/tsdb/elasticsearch/time_series_query.go @@ -171,6 +171,10 @@ func addTermsAgg(aggBuilder es.AggBuilder, bucketAgg *BucketAgg, metrics []*Metr } else { a.Size = 500 } + if a.Size == 0 { + a.Size = 500 + } + if minDocCount, err := bucketAgg.Settings.Get("min_doc_count").Int(); err == nil { a.MinDocCount = &minDocCount } diff --git a/pkg/tsdb/elasticsearch/time_series_query_test.go b/pkg/tsdb/elasticsearch/time_series_query_test.go index 49bf5f5bc75..fe8ae0fa8f2 100644 --- a/pkg/tsdb/elasticsearch/time_series_query_test.go +++ b/pkg/tsdb/elasticsearch/time_series_query_test.go @@ -60,7 +60,7 @@ func TestExecuteTimeSeriesQuery(t *testing.T) { _, err := executeTsdbQuery(c, `{ "timeField": "@timestamp", "bucketAggs": [ - { "type": "terms", "field": "@host", "id": "2" }, + { "type": "terms", "field": "@host", "id": "2", "settings": { "size": "0", "order": "asc" } }, { "type": "date_histogram", "field": "@timestamp", "id": "3" } ], "metrics": [{"type": "count", "id": "1" }] @@ -69,7 +69,9 @@ func TestExecuteTimeSeriesQuery(t *testing.T) { sr := c.multisearchRequests[0].Requests[0] firstLevel := sr.Aggs[0] So(firstLevel.Key, ShouldEqual, "2") - So(firstLevel.Aggregation.Aggregation.(*es.TermsAggregation).Field, ShouldEqual, "@host") + termsAgg := firstLevel.Aggregation.Aggregation.(*es.TermsAggregation) + So(termsAgg.Field, ShouldEqual, "@host") + So(termsAgg.Size, ShouldEqual, 500) secondLevel := firstLevel.Aggregation.Aggs[0] So(secondLevel.Key, ShouldEqual, "3") So(secondLevel.Aggregation.Aggregation.(*es.DateHistogramAgg).Field, ShouldEqual, "@timestamp") diff --git a/public/app/core/utils/dag.test.ts b/public/app/core/utils/dag.test.ts index 064da13806b..4ee0dd7134b 100644 --- a/public/app/core/utils/dag.test.ts +++ b/public/app/core/utils/dag.test.ts @@ -104,5 +104,17 @@ describe('Directed acyclic graph', () => { const actual = nodeH.getOptimizedInputEdges(); expect(actual).toHaveLength(0); }); + + it('when linking non-existing input node with existing output node should throw error', () => { + expect(() => { + dag.link('non-existing', 'A'); + }).toThrowError("cannot link input node named non-existing since it doesn't exist in graph"); + }); + + it('when linking existing input node with non-existing output node should throw error', () => { + expect(() => { + dag.link('A', 'non-existing'); + }).toThrowError("cannot link output node named non-existing since it doesn't exist in graph"); + }); }); }); diff --git a/public/app/core/utils/dag.ts b/public/app/core/utils/dag.ts index eb7ff1c3b1a..48c00a4c8c3 100644 --- a/public/app/core/utils/dag.ts +++ b/public/app/core/utils/dag.ts @@ -15,6 +15,14 @@ export class Edge { } link(inputNode: Node, outputNode: Node) { + if (!inputNode) { + throw Error('inputNode is required'); + } + + if (!outputNode) { + throw Error('outputNode is required'); + } + this.unlink(); this.inputNode = inputNode; this.outputNode = outputNode; @@ -152,7 +160,11 @@ export class Graph { for (let n = 0; n < inputArr.length; n++) { const i = inputArr[n]; if (typeof i === 'string') { - inputNodes.push(this.getNode(i)); + const n = this.getNode(i); + if (!n) { + throw Error(`cannot link input node named ${i} since it doesn't exist in graph`); + } + inputNodes.push(n); } else { inputNodes.push(i); } @@ -161,7 +173,11 @@ export class Graph { for (let n = 0; n < outputArr.length; n++) { const i = outputArr[n]; if (typeof i === 'string') { - outputNodes.push(this.getNode(i)); + const n = this.getNode(i); + if (!n) { + throw Error(`cannot link output node named ${i} since it doesn't exist in graph`); + } + outputNodes.push(n); } else { outputNodes.push(i); } diff --git a/public/app/features/templating/variable_srv.ts b/public/app/features/templating/variable_srv.ts index 8c0f1f11f77..75e2ca35ec7 100644 --- a/public/app/features/templating/variable_srv.ts +++ b/public/app/features/templating/variable_srv.ts @@ -291,9 +291,11 @@ export class VariableSrv { createGraph() { const g = new Graph(); - this.variables.forEach(v1 => { - g.createNode(v1.name); + this.variables.forEach(v => { + g.createNode(v.name); + }); + this.variables.forEach(v1 => { this.variables.forEach(v2 => { if (v1 === v2) { return; diff --git a/public/app/plugins/datasource/influxdb/influx_series.ts b/public/app/plugins/datasource/influxdb/influx_series.ts index d2a8482eced..10c1584f488 100644 --- a/public/app/plugins/datasource/influxdb/influx_series.ts +++ b/public/app/plugins/datasource/influxdb/influx_series.ts @@ -99,9 +99,6 @@ export default class InfluxSeries { if (column === 'sequence_number') { return; } - if (!titleCol) { - titleCol = index; - } if (column === this.annotation.titleColumn) { titleCol = index; return; @@ -114,6 +111,10 @@ export default class InfluxSeries { textCol = index; return; } + // legacy case + if (!titleCol && textCol !== index) { + titleCol = index; + } }); _.each(series.values, value => { diff --git a/public/app/plugins/datasource/prometheus/metric_find_query.ts b/public/app/plugins/datasource/prometheus/metric_find_query.ts index feada28deea..680f7a8fb98 100644 --- a/public/app/plugins/datasource/prometheus/metric_find_query.ts +++ b/public/app/plugins/datasource/prometheus/metric_find_query.ts @@ -12,7 +12,7 @@ export default class PrometheusMetricFindQuery { } process() { - const labelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]+)\)\s*$/; + const labelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]*)\)\s*$/; const metricNamesRegex = /^metrics\((.+)\)\s*$/; const queryResultRegex = /^query_result\((.+)\)\s*$/; diff --git a/public/app/plugins/datasource/stackdriver/filter_segments.ts b/public/app/plugins/datasource/stackdriver/filter_segments.ts index 8d193f663c2..9eb27f31975 100644 --- a/public/app/plugins/datasource/stackdriver/filter_segments.ts +++ b/public/app/plugins/datasource/stackdriver/filter_segments.ts @@ -87,7 +87,7 @@ export class FilterSegments { } // remove condition if it is first segment - if (index === 0 && this.filterSegments[0].type === 'condition') { + if (index === 0 && this.filterSegments.length > 0 && this.filterSegments[0].type === 'condition') { this.filterSegments.splice(0, 1); } } diff --git a/public/app/plugins/panel/graph/graph.ts b/public/app/plugins/panel/graph/graph.ts index 33db0e7220a..7a8e24539f7 100755 --- a/public/app/plugins/panel/graph/graph.ts +++ b/public/app/plugins/panel/graph/graph.ts @@ -713,7 +713,9 @@ class GraphElement { if (min && max && ticks) { const range = max - min; const secPerTick = range / ticks / 1000; - const oneDay = 86400000; + // Need have 10 milisecond margin on the day range + // As sometimes last 24 hour dashboard evaluates to more than 86400000 + const oneDay = 86400010; const oneYear = 31536000000; if (secPerTick <= 45) { diff --git a/public/sass/components/_panel_graph.scss b/public/sass/components/_panel_graph.scss index 01fcc5a3e64..63d9169a4f8 100644 --- a/public/sass/components/_panel_graph.scss +++ b/public/sass/components/_panel_graph.scss @@ -137,6 +137,7 @@ .graph-legend-table { display: table; + width: auto; .graph-legend-scroll { display: table; diff --git a/public/sass/pages/_playlist.scss b/public/sass/pages/_playlist.scss index 5dd1c92cbd2..b8802940818 100644 --- a/public/sass/pages/_playlist.scss +++ b/public/sass/pages/_playlist.scss @@ -84,11 +84,11 @@ background-color: $list-item-bg; margin-bottom: 4px; .search-result-icon:before { - content: "\f009"; + content: '\f009'; } &.search-item-dash-home .search-result-icon:before { - content: "\f015"; + content: '\f015'; } } @@ -105,7 +105,10 @@ .playlist-available-list { td { line-height: 2rem; + max-width: 335px; white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; } .add-dashboard {