mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Add semantic version checking. Set minimum elasticsearch version to 1.2.1
This commit is contained in:
parent
e8c9173e6f
commit
b526eb2917
7 changed files with 291 additions and 38 deletions
|
@ -110,7 +110,7 @@ define(function (require) {
|
|||
.catch(function (err) {
|
||||
// TODO: we should probably display a message of some kind
|
||||
if (err instanceof MissingIndices) {
|
||||
index.fetchFieldsError = 'Unable to fetch mapping. Do you have recent indices matching the interval?';
|
||||
index.fetchFieldsError = 'Unable to fetch mapping. Do you have indices matching the pattern?';
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,47 +1,21 @@
|
|||
define(function (require) {
|
||||
return function CheckEsVersionFn(Private, es, configFile, Notifier) {
|
||||
var _ = require('lodash');
|
||||
var versionmath = require('utils/versionmath');
|
||||
return function CheckEsVersionFn(Private, es, configFile, Notifier, minimumElasticsearchVersion) {
|
||||
return function checkEsVersion() {
|
||||
var notify = new Notifier({ location: 'Setup: Elasticsearch version check' });
|
||||
var complete = notify.lifecycle('check es version');
|
||||
|
||||
var SetupError = Private(require('components/setup/_setup_error'));
|
||||
|
||||
|
||||
// core expression for finding a version
|
||||
var versionExp = '([\\d\\.]*\\d)(?:\\.\\w+)?';
|
||||
|
||||
/**
|
||||
* Regular Expression to extract a version number from a string
|
||||
* @type {RegExp}
|
||||
*/
|
||||
var versionRE = new RegExp(versionExp);
|
||||
|
||||
/**
|
||||
* Regular Expression to extract a version range from a string
|
||||
* @type {RegExp}
|
||||
*/
|
||||
var versionRangeRE = new RegExp(versionExp + '\\s*\\-\\s*' + versionExp);
|
||||
|
||||
var int = function (txt) {
|
||||
var i = parseInt(txt, 10);
|
||||
return (!i || isNaN(i)) ? 0 : i;
|
||||
};
|
||||
|
||||
return es.info()
|
||||
return es.nodes.info()
|
||||
.then(function (info) {
|
||||
var raw = info.version.number;
|
||||
var sections = raw.split('-');
|
||||
var someTypeOfBeta = sections.length > 1;
|
||||
var all = sections.shift().split('.');
|
||||
var major = int(all.shift());
|
||||
var minor = int(all.shift());
|
||||
var patch = int(all.shift());
|
||||
|
||||
var currentRelease = major === 1 && minor >= 1;
|
||||
var betaPreRelease = major === 1 && minor === 0 && someTypeOfBeta;
|
||||
|
||||
if (currentRelease || betaPreRelease) return true;
|
||||
else throw SetupError('Incompatible Elasticsearch version "' + raw + '". Expected version 1.1 or a 1.0-Beta release');
|
||||
var versions = _.map(info.nodes, function (v) {
|
||||
// Remove everything after the -, we don't handle beta/rc ES versions
|
||||
return v.version.split('-')[0];
|
||||
});
|
||||
if (versionmath.is('>=' + minimumElasticsearchVersion, versions)) return true;
|
||||
else throw SetupError('This version of Kibana requires at least Elasticsearch ' + minimumElasticsearchVersion);
|
||||
})
|
||||
.then(complete, complete.failure);
|
||||
};
|
||||
|
|
|
@ -25,6 +25,8 @@ define(function (require) {
|
|||
kibana
|
||||
// This stores the Kibana revision number, @REV@ is replaced by grunt.
|
||||
.constant('kbnVersion', '@REV@')
|
||||
// The minimum Elasticsearch version required to run Kibana
|
||||
.constant('minimumElasticsearchVersion', '1.2.1')
|
||||
// Use this for cache busting partials
|
||||
.constant('cacheBust', 'cache-bust=' + Date.now())
|
||||
// attach the route manager's known routes
|
||||
|
|
149
src/kibana/utils/versionmath.js
Normal file
149
src/kibana/utils/versionmath.js
Normal file
|
@ -0,0 +1,149 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
|
||||
function VersionMathException(message) {
|
||||
this.message = message;
|
||||
this.name = 'VersionMathException';
|
||||
}
|
||||
|
||||
// Get the max version in this cluster
|
||||
var max = function (versions) {
|
||||
return _.last(sortVersions(versions));
|
||||
};
|
||||
|
||||
// Return the lowest version in the cluster
|
||||
var min = function (versions) {
|
||||
return _.first(sortVersions(versions));
|
||||
};
|
||||
|
||||
// Sort versions from lowest to highest
|
||||
var sortVersions = function (versions) {
|
||||
var _versions = _.clone(versions),
|
||||
_r = [];
|
||||
|
||||
while (_r.length < versions.length) {
|
||||
var _h = '0';
|
||||
/*jshint -W083 */
|
||||
_.each(_versions, function (v) {
|
||||
if (compare(_h, v)) {
|
||||
_h = v;
|
||||
}
|
||||
});
|
||||
_versions = _.without(_versions, _h);
|
||||
_r.push(_h);
|
||||
}
|
||||
return _r.reverse();
|
||||
};
|
||||
|
||||
/*
|
||||
Takes a version string with one of the following optional comparison prefixes: >,>=,<.<=
|
||||
and evaluates if the cluster meets the requirement. If the prefix is omitted exact match
|
||||
is assumed
|
||||
*/
|
||||
var is = function (equation, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
var _v = equation,
|
||||
_cf;
|
||||
|
||||
if (_v.charAt(0) === '>') {
|
||||
_cf = _v.charAt(1) === '=' ? gte(_v.slice(2), _versions) : gt(_v.slice(1), _versions);
|
||||
} else if (_v.charAt(0) === '<') {
|
||||
_cf = _v.charAt(1) === '=' ? lte(_v.slice(2), _versions) : lt(_v.slice(1), _versions);
|
||||
} else {
|
||||
_cf = eq(_v, _versions);
|
||||
}
|
||||
|
||||
return _cf;
|
||||
};
|
||||
|
||||
// check if lowest version in cluster = `version`
|
||||
var eq = function (version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return version === min(_versions) ? true : false;
|
||||
};
|
||||
|
||||
// version > lowest version in cluster?
|
||||
var gt = function (version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return version === min(_versions) ? false : gte(version, _versions);
|
||||
};
|
||||
|
||||
// version < highest version in cluster?
|
||||
var lt = function (version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return version === max(_versions) ? false : lte(version, _versions);
|
||||
};
|
||||
|
||||
// Check if the lowest version in the cluster is >= to `version`
|
||||
var gte = function (version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return compare(version, min(_versions));
|
||||
};
|
||||
|
||||
// Check if the highest version in the cluster is <= to `version`
|
||||
var lte = function (version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return compare(max(_versions), version);
|
||||
};
|
||||
|
||||
// Determine if a specific version meets the minimum requirement
|
||||
var compare = function (required, installed) {
|
||||
if (_.isUndefined(installed)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!required || !installed) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var a = installed.split('.');
|
||||
var b = required.split('.');
|
||||
var i;
|
||||
|
||||
// leave suffixes as is ("RC1 or -SNAPSHOT")
|
||||
for (i = 0; i < Math.min(a.length, 3); ++i) {
|
||||
a[i] = Number(a[i]);
|
||||
}
|
||||
for (i = 0; i < Math.min(b.length, 3); ++i) {
|
||||
b[i] = Number(b[i]);
|
||||
}
|
||||
if (a.length === 2) {
|
||||
a[2] = 0;
|
||||
}
|
||||
|
||||
if (a[0] > b[0]) { return true; }
|
||||
if (a[0] < b[0]) { return false; }
|
||||
|
||||
if (a[1] > b[1]) { return true; }
|
||||
if (a[1] < b[1]) { return false; }
|
||||
|
||||
if (a[2] > b[2]) { return true; }
|
||||
if (a[2] < b[2]) { return false; }
|
||||
|
||||
if (a.length > 3) {
|
||||
// rc/beta suffix
|
||||
if (b.length <= 3) {
|
||||
return false;
|
||||
} // no suffix on b -> a<b
|
||||
return a[3] >= b[3];
|
||||
}
|
||||
if (b.length > 3) {
|
||||
// b has a suffix but a not -> a>b
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
return {
|
||||
min: min,
|
||||
max: max,
|
||||
is: is,
|
||||
eq: eq,
|
||||
gt: gt,
|
||||
gte: gte,
|
||||
lt: lt,
|
||||
lte: lte
|
||||
};
|
||||
});
|
|
@ -59,6 +59,7 @@
|
|||
'specs/filters/start_from',
|
||||
'specs/utils/datemath',
|
||||
'specs/utils/interval',
|
||||
'specs/utils/versionmath',
|
||||
], function (sinon) {
|
||||
|
||||
var xhr = sinon.useFakeXMLHttpRequest();
|
||||
|
|
|
@ -21,7 +21,6 @@ define(function (require) {
|
|||
|
||||
describe('description', function () {
|
||||
it('returns a readable description for an interval', function () {
|
||||
expect(interval.describe('1ms')).to.be('1ms');
|
||||
expect(interval.describe('1s')).to.be('1s');
|
||||
expect(interval.describe('1m')).to.be('1m');
|
||||
expect(interval.describe('1h')).to.be('1h');
|
||||
|
|
128
test/unit/specs/utils/versionmath.js
Normal file
128
test/unit/specs/utils/versionmath.js
Normal file
|
@ -0,0 +1,128 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
var versionmath = require('utils/versionmath');
|
||||
var versions = [
|
||||
'1.1.12',
|
||||
'0.90.0',
|
||||
'0.90.1',
|
||||
'1.0.0',
|
||||
'1.0',
|
||||
'1.2.3',
|
||||
'2.0.0',
|
||||
'2.0.1',
|
||||
'2.3.1'
|
||||
];
|
||||
|
||||
describe('version math (0.90.0 - 2.3.1)', function () {
|
||||
|
||||
var methods = 'max,min,eq,is,lt,lte,gt,gte'.split(',');
|
||||
describe('methods', function () {
|
||||
it('should have ' + methods.join(', ') + ' methods', function () {
|
||||
_.each(methods, function (method) {
|
||||
expect(versionmath[method]).to.be.a(Function);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('min & max', function () {
|
||||
it('has a max of 2.3.1', function () {
|
||||
expect(versionmath.max(versions)).to.be('2.3.1');
|
||||
});
|
||||
|
||||
it('has a min of 0.90.0', function () {
|
||||
expect(versionmath.min(versions)).to.be('0.90.0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('eq / lowest version', function () {
|
||||
it('should be true for 0.90.0', function () {
|
||||
expect(versionmath.eq('0.90.0', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('should be false for 1.0', function () {
|
||||
expect(versionmath.eq('1.0', versions)).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gt / lowest version', function () {
|
||||
it('is > 0.20.3', function () {
|
||||
expect(versionmath.gt('0.20.3', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('is not > 0.90.0', function () {
|
||||
expect(versionmath.gt('0.90.0', versions)).to.be(false);
|
||||
});
|
||||
|
||||
it('is not > 1.0.0', function () {
|
||||
expect(versionmath.gt('1.0.0', versions)).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gte / lowest version', function () {
|
||||
it('is >= 0.20.3', function () {
|
||||
expect(versionmath.gte('0.20.3', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('is >= 0.90.0', function () {
|
||||
expect(versionmath.gte('0.90.0', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('is not >= 1.0.0', function () {
|
||||
expect(versionmath.gte('1.0.0', versions)).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('lt / highest version', function () {
|
||||
it('is not < 0.20.3', function () {
|
||||
expect(versionmath.lt('0.20.3', versions)).to.be(false);
|
||||
});
|
||||
|
||||
it('is not < 2.3.1', function () {
|
||||
expect(versionmath.lt('2.3.1', versions)).to.be(false);
|
||||
});
|
||||
|
||||
it('is < 2.5', function () {
|
||||
expect(versionmath.lt('2.5', versions)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('lte / highest version', function () {
|
||||
it('is not =< 0.20.3', function () {
|
||||
expect(versionmath.lte('0.20.3', versions)).to.be(false);
|
||||
});
|
||||
|
||||
it('is =< 2.3.1', function () {
|
||||
expect(versionmath.lte('2.3.1', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('is =< 2.5', function () {
|
||||
expect(versionmath.lte('2.5', versions)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('is', function () {
|
||||
it('exactly, <, <=, >, >=', function () {
|
||||
expect(versionmath.is('0.90.0', versions)).to.be(true);
|
||||
expect(versionmath.is('0.20.0', versions)).to.be(false);
|
||||
|
||||
expect(versionmath.is('>0.20.0', versions)).to.be(true);
|
||||
expect(versionmath.is('>0.90.0', versions)).to.be(false);
|
||||
expect(versionmath.is('>0.90.1', versions)).to.be(false);
|
||||
|
||||
expect(versionmath.is('>=0.20.0', versions)).to.be(true);
|
||||
expect(versionmath.is('>=0.90.0', versions)).to.be(true);
|
||||
expect(versionmath.is('>=0.90.1', versions)).to.be(false);
|
||||
|
||||
expect(versionmath.is('<2.5', versions)).to.be(true);
|
||||
expect(versionmath.is('<2.3.1', versions)).to.be(false);
|
||||
expect(versionmath.is('<0.90.1', versions)).to.be(false);
|
||||
|
||||
expect(versionmath.is('<=2.5', versions)).to.be(true);
|
||||
expect(versionmath.is('<=2.3.1', versions)).to.be(true);
|
||||
expect(versionmath.is('<=0.90.1', versions)).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue