Merge pull request #12415 from grafana/cp-5.2.0

Cherry-picks for v5.2.0 stable
This commit is contained in:
Marcus Efraimsson
2018-06-27 09:38:18 +02:00
committed by GitHub
12 changed files with 170 additions and 47 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
{
"stable": "5.1.3",
"testing": "5.1.3"
"stable": "5.2.0",
"testing": "5.2.0"
}
+1 -1
View File
@@ -4,7 +4,7 @@
"company": "Grafana Labs"
},
"name": "grafana",
"version": "5.2.0-beta3",
"version": "5.2.0",
"repository": {
"type": "git",
"url": "http://github.com/grafana/grafana.git"
+11
View File
@@ -3,7 +3,9 @@ package api
import (
"fmt"
"net/http"
"runtime"
"strconv"
"strings"
"time"
m "github.com/grafana/grafana/pkg/models"
@@ -55,6 +57,15 @@ func (hs *HTTPServer) RenderToPng(c *m.ReqContext) {
return
}
if err != nil && err == rendering.ErrPhantomJSNotInstalled {
if strings.HasPrefix(runtime.GOARCH, "arm") {
c.Handle(500, "Rendering failed - PhantomJS isn't included in arm build per default", err)
} else {
c.Handle(500, "Rendering failed - PhantomJS isn't installed correctly", err)
}
return
}
if err != nil {
c.Handle(500, "Rendering failed.", err)
return
+1
View File
@@ -10,6 +10,7 @@ import (
var ErrTimeout = errors.New("Timeout error. You can set timeout in seconds with &timeout url parameter")
var ErrNoRenderer = errors.New("No renderer plugin found nor is an external render server configured")
var ErrPhantomJSNotInstalled = errors.New("PhantomJS executable not found")
type Opts struct {
Width int
+5
View File
@@ -24,6 +24,11 @@ func (rs *RenderingService) renderViaPhantomJS(ctx context.Context, opts Opts) (
url := rs.getURL(opts.Path)
binPath, _ := filepath.Abs(filepath.Join(rs.Cfg.PhantomDir, executable))
if _, err := os.Stat(binPath); os.IsNotExist(err) {
rs.log.Error("executable not found", "executable", binPath)
return nil, ErrPhantomJSNotInstalled
}
scriptPath, _ := filepath.Abs(filepath.Join(rs.Cfg.PhantomDir, "render.js"))
pngPath := rs.getFilePathForNewImage()
@@ -7,7 +7,7 @@ export class DatasourceSrv {
datasources: any;
/** @ngInject */
constructor(private $q, private $injector, $rootScope, private templateSrv) {
constructor(private $q, private $injector, private $rootScope, private templateSrv) {
this.init();
}
@@ -61,7 +61,7 @@ export class DatasourceSrv {
this.datasources[name] = instance;
deferred.resolve(instance);
})
.catch(function(err) {
.catch(err => {
this.$rootScope.appEvent('alert-error', [dsConfig.name + ' plugin failed', err.toString()]);
});
@@ -179,4 +179,38 @@ describe('VariableSrv init', function() {
expect(variable.options[2].selected).to.be(false);
});
});
describeInitScenario('when template variable is present in url multiple times using key/values', scenario => {
scenario.setup(() => {
scenario.variables = [
{
name: 'apps',
type: 'query',
multi: true,
current: { text: 'Val1', value: 'val1' },
options: [
{ text: 'Val1', value: 'val1' },
{ text: 'Val2', value: 'val2' },
{ text: 'Val3', value: 'val3', selected: true },
],
},
];
scenario.urlParams['var-apps'] = ['val2', 'val1'];
});
it('should update current value', function() {
var variable = ctx.variableSrv.variables[0];
expect(variable.current.value.length).to.be(2);
expect(variable.current.value[0]).to.be('val2');
expect(variable.current.value[1]).to.be('val1');
expect(variable.current.text).to.be('Val2 + Val1');
expect(variable.options[0].selected).to.be(true);
expect(variable.options[1].selected).to.be(true);
});
it('should set options that are not in value to selected false', function() {
var variable = ctx.variableSrv.variables[0];
expect(variable.options[2].selected).to.be(false);
});
});
});
+18 -1
View File
@@ -209,7 +209,24 @@ export class VariableSrv {
return op.text === urlValue || op.value === urlValue;
});
option = option || { text: urlValue, value: urlValue };
let defaultText = urlValue;
let defaultValue = urlValue;
if (!option && _.isArray(urlValue)) {
defaultText = [];
for (let n = 0; n < urlValue.length; n++) {
let t = _.find(variable.options, op => {
return op.value === urlValue[n];
});
if (t) {
defaultText.push(t.text);
}
}
}
option = option || { text: defaultText, value: defaultValue };
return variable.setValue(option);
});
}
@@ -11,14 +11,30 @@ export default class ResponseParser {
return [];
}
var influxdb11format = query.toLowerCase().indexOf('show tag values') >= 0;
var normalizedQuery = query.toLowerCase();
var isValueFirst =
normalizedQuery.indexOf('show field keys') >= 0 || normalizedQuery.indexOf('show retention policies') >= 0;
var res = {};
_.each(influxResults.series, serie => {
_.each(serie.values, value => {
if (_.isArray(value)) {
if (influxdb11format) {
addUnique(res, value[1] || value[0]);
// In general, there are 2 possible shapes for the returned value.
// The first one is a two-element array,
// where the first element is somewhat a metadata value:
// the tag name for SHOW TAG VALUES queries,
// the time field for SELECT queries, etc.
// The second shape is an one-element array,
// that is containing an immediate value.
// For example, SHOW FIELD KEYS queries return such shape.
// Note, pre-0.11 versions return
// the second shape for SHOW TAG VALUES queries
// (while the newer versions—first).
if (isValueFirst) {
addUnique(res, value[0]);
} else if (value[1] !== undefined) {
addUnique(res, value[1]);
} else {
addUnique(res, value[0]);
}
@@ -29,7 +45,7 @@ export default class ResponseParser {
});
return _.map(res, value => {
return { text: value };
return { text: value.toString() };
});
}
}
@@ -85,30 +85,36 @@ describe('influxdb response parser', () => {
});
});
describe('SELECT response', () => {
var query = 'SELECT "usage_iowait" FROM "cpu" LIMIT 10';
var response = {
results: [
{
series: [
{
name: 'cpu',
columns: ['time', 'usage_iowait'],
values: [[1488465190006040638, 0.0], [1488465190006040638, 15.0], [1488465190006040638, 20.2]],
},
],
},
],
};
var result = parser.parse(query, response);
it('should return second column', () => {
expect(_.size(result)).toBe(3);
expect(result[0].text).toBe('0');
expect(result[1].text).toBe('15');
expect(result[2].text).toBe('20.2');
});
});
describe('SHOW FIELD response', () => {
var query = 'SHOW FIELD KEYS FROM "cpu"';
describe('response from 0.10.0', () => {
var response = {
results: [
{
series: [
{
name: 'measurements',
columns: ['name'],
values: [['cpu'], ['derivative'], ['logins.count'], ['logs'], ['payment.ended'], ['payment.started']],
},
],
},
],
};
var result = parser.parse(query, response);
it('should get two responses', () => {
expect(_.size(result)).toBe(6);
});
});
describe('response from 0.11.0', () => {
describe('response from pre-1.0', () => {
var response = {
results: [
{
@@ -129,5 +135,28 @@ describe('influxdb response parser', () => {
expect(_.size(result)).toBe(1);
});
});
describe('response from 1.0', () => {
var response = {
results: [
{
series: [
{
name: 'cpu',
columns: ['fieldKey', 'fieldType'],
values: [['time', 'float']],
},
],
},
],
};
var result = parser.parse(query, response);
it('should return first column', () => {
expect(_.size(result)).toBe(1);
expect(result[0].text).toBe('time');
});
});
});
});
+10 -3
View File
@@ -25,7 +25,7 @@
display: inline-block;
padding-right: 2px;
&::after {
content: " | ";
content: ' | ';
padding-left: 2px;
}
}
@@ -33,14 +33,21 @@
li:last-child {
&::after {
padding-left: 0;
content: "";
content: '';
}
}
}
.login-page {
.footer {
padding: 1rem 0 1rem 0;
}
}
@include media-breakpoint-up(md) {
.footer {
bottom: $spacer;
position: absolute;
bottom: $spacer;
padding: 5rem 0 1rem 0;
}
}
+16 -13
View File
@@ -1,9 +1,8 @@
$login-border: #8daac5;
.login {
background-position: center;
min-height: 85vh;
height: 80vh;
background-position: center;
background-repeat: no-repeat;
min-width: 100%;
margin-left: 0;
@@ -95,7 +94,7 @@ select:-webkit-autofill:focus {
position: relative;
justify-content: center;
z-index: 1;
height: 320px;
min-height: 320px;
}
.login-branding {
@@ -106,6 +105,7 @@ select:-webkit-autofill:focus {
align-items: center;
justify-content: center;
flex-grow: 0;
padding-top: 2rem;
.logo-icon {
width: 70px;
@@ -127,7 +127,7 @@ select:-webkit-autofill:focus {
.login-inner-box {
text-align: center;
padding: 2rem 4rem;
padding: 2rem;
display: flex;
flex-direction: column;
align-items: center;
@@ -243,7 +243,7 @@ select:-webkit-autofill:focus {
justify-content: space-between;
.login-divider-line {
width: 110px;
width: 100px;
height: 10px;
border-bottom: 1px solid $login-border;
@@ -323,7 +323,10 @@ select:-webkit-autofill:focus {
width: 35%;
padding: 4rem 2rem;
border-right: 1px solid $login-border;
justify-content: flex-start;
.logo-icon {
width: 80px;
}
}
.login-inner-box {
@@ -331,14 +334,18 @@ select:-webkit-autofill:focus {
padding: 1rem 2rem;
}
.login-branding {
.logo-icon {
width: 80px;
.login-divider {
.login-divider-line {
width: 110px;
}
}
}
@include media-breakpoint-up(md) {
.login {
min-height: 100vh;
}
.login-content {
flex: 1 0 100%;
}
@@ -373,10 +380,6 @@ select:-webkit-autofill:focus {
}
@include media-breakpoint-up(lg) {
.login {
min-height: 100vh;
}
.login-form-input {
min-width: 300px;
}