From 0515489092fc0527746980b293c08979bf9c2f27 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 17 Aug 2016 12:39:47 -0700 Subject: [PATCH 1/5] uuid: rewrite using path.data file instead of .kibana index --- .../elasticsearch/lib/health_check.js | 3 - .../elasticsearch/lib/manage_uuid.js | 81 ------------------- src/core_plugins/kibana/index.js | 4 + .../kibana/server/lib/manage_uuid.js | 73 +++++++++++++++++ 4 files changed, 77 insertions(+), 84 deletions(-) delete mode 100644 src/core_plugins/elasticsearch/lib/manage_uuid.js create mode 100644 src/core_plugins/kibana/server/lib/manage_uuid.js diff --git a/src/core_plugins/elasticsearch/lib/health_check.js b/src/core_plugins/elasticsearch/lib/health_check.js index 6920b4eb593f9..cca77e2f2398a 100644 --- a/src/core_plugins/elasticsearch/lib/health_check.js +++ b/src/core_plugins/elasticsearch/lib/health_check.js @@ -5,7 +5,6 @@ import exposeClient from './expose_client'; import migrateConfig from './migrate_config'; import createKibanaIndex from './create_kibana_index'; import checkEsVersion from './check_es_version'; -import manageUuid from './manage_uuid'; const NoConnections = elasticsearch.errors.NoConnections; import util from 'util'; const format = util.format; @@ -19,7 +18,6 @@ const REQUEST_DELAY = 2500; module.exports = function (plugin, server) { const config = server.config(); const client = server.plugins.elasticsearch.client; - const uuidManagement = manageUuid(server); plugin.status.yellow('Waiting for Elasticsearch'); @@ -89,7 +87,6 @@ module.exports = function (plugin, server) { return waitForPong() .then(_.partial(checkEsVersion, server)) .then(waitForShards) - .then(uuidManagement) .then(setGreenStatus) .then(_.partial(migrateConfig, server)) .catch(err => plugin.status.red(err)); diff --git a/src/core_plugins/elasticsearch/lib/manage_uuid.js b/src/core_plugins/elasticsearch/lib/manage_uuid.js deleted file mode 100644 index 43be6c9654268..0000000000000 --- a/src/core_plugins/elasticsearch/lib/manage_uuid.js +++ /dev/null @@ -1,81 +0,0 @@ -import uuid from 'node-uuid'; -import { hostname } from 'os'; -const serverHostname = hostname(); - -/* Handle different scenarios: - * - config uuid exists, data uuid exists and matches - * - nothing to do - * - config uuid missing, data uuid exists - * - set uuid from data as config uuid - * - config uuid exists, data uuid exists but mismatches - * - update data uuid with config uuid - * - config uuid missing, data uuid missing - * - generate new uuid, set in config and insert in data - * ("config uuid" = uuid in server.config, - * "data uuid" = uuid in .kibana index) - */ -export default function manageUuid(server) { - const TYPE = 'server'; - const config = server.config(); - const serverPort = server.info.port; - const client = server.plugins.elasticsearch.client; - - return function uuidManagement() { - const fieldId = `${serverHostname}-${serverPort}`; - const kibanaIndex = config.get('kibana.index'); - let kibanaUuid = config.get('uuid'); - - function logToServer(msg) { - server.log(['server', 'uuid', fieldId], msg); - } - - return client.get({ - index: kibanaIndex, - ignore: [404], - type: TYPE, - id: fieldId - }).then(result => { - if (result.found) { - if (kibanaUuid === result._source.uuid) { - // config uuid exists, data uuid exists and matches - logToServer(`Kibana instance UUID: ${kibanaUuid}`); - return; - } - - if (!kibanaUuid) { - // config uuid missing, data uuid exists - kibanaUuid = result._source.uuid; - logToServer(`Resuming persistent Kibana instance UUID: ${kibanaUuid}`); - config.set('uuid', kibanaUuid); - return; - } - - if (kibanaUuid !== result._source.uuid) { - // config uuid exists, data uuid exists but mismatches - logToServer(`Updating Kibana instance UUID to: ${kibanaUuid} (was: ${result._source.uuid})`); - return client.update({ - index: kibanaIndex, - type: TYPE, - id: fieldId, - body: { doc: { uuid: kibanaUuid } } - }); - } - } - - // data uuid missing - if (!kibanaUuid) { - // config uuid missing - kibanaUuid = uuid.v4(); - config.set('uuid', kibanaUuid); - } - - logToServer(`Setting new Kibana instance UUID: ${kibanaUuid}`); - return client.index({ - index: kibanaIndex, - type: TYPE, - id: fieldId, - body: { uuid: kibanaUuid } - }); - }); - }; -} diff --git a/src/core_plugins/kibana/index.js b/src/core_plugins/kibana/index.js index 35ee2915f0bf0..ac337892136a9 100644 --- a/src/core_plugins/kibana/index.js +++ b/src/core_plugins/kibana/index.js @@ -1,3 +1,4 @@ +import manageUuid from './server/lib/manage_uuid'; import ingest from './server/routes/api/ingest'; import search from './server/routes/api/search'; import settings from './server/routes/api/settings'; @@ -84,6 +85,9 @@ module.exports = function (kibana) { }, init: function (server, options) { + // uuid + manageUuid(server); + // routes ingest(server); search(server); settings(server); diff --git a/src/core_plugins/kibana/server/lib/manage_uuid.js b/src/core_plugins/kibana/server/lib/manage_uuid.js new file mode 100644 index 0000000000000..12ff07b19728c --- /dev/null +++ b/src/core_plugins/kibana/server/lib/manage_uuid.js @@ -0,0 +1,73 @@ +import uuid from 'node-uuid'; +import Promise from 'bluebird'; +import { hostname } from 'os'; +import { join as pathJoin } from 'path'; +import { readFile as readFileCallback, writeFile as writeFileCallback } from 'fs'; + +const serverHostname = hostname(); +const FILE_ENCODING = 'utf8'; + +export default async function manageUuid(server) { + const config = server.config(); + const serverPort = server.info.port; + const fileName = `${serverHostname}:${serverPort}`; + const uuidFile = pathJoin(config.get('path.data'), fileName); + + async function detectUuid() { + const readFile = Promise.promisify(readFileCallback); + try { + const result = await readFile(uuidFile); + return result.toString(FILE_ENCODING); + } catch (e) { + return false; + } + } + + async function writeUuid(uuid) { + const writeFile = Promise.promisify(writeFileCallback); + try { + return await writeFile(uuidFile, uuid, { encoding: FILE_ENCODING }); + } catch (e) { + return false; + } + } + + // detect if uuid exists already from before a restart + const logToServer = (msg) => server.log(['server', 'uuid', fileName], msg); + const dataFileUuid = await detectUuid(); + let serverConfigUuid = config.get('uuid'); // check if already set in config + + if (dataFileUuid) { + // data uuid found + if (serverConfigUuid === dataFileUuid) { + // config uuid exists, data uuid exists and matches + logToServer(`Kibana instance UUID: ${dataFileUuid}`); + return; + } + + if (!serverConfigUuid) { + // config uuid missing, data uuid exists + serverConfigUuid = dataFileUuid; + logToServer(`Resuming persistent Kibana instance UUID: ${serverConfigUuid}`); + config.set('uuid', serverConfigUuid); + return; + } + + if (serverConfigUuid !== dataFileUuid) { + // config uuid exists, data uuid exists but mismatches + logToServer(`Updating Kibana instance UUID to: ${serverConfigUuid} (was: ${dataFileUuid})`); + return writeUuid(serverConfigUuid); + } + } + + // data uuid missing + + if (!serverConfigUuid) { + // config uuid missing + serverConfigUuid = uuid.v4(); + config.set('uuid', serverConfigUuid); + } + + logToServer(`Setting new Kibana instance UUID: ${serverConfigUuid}`); + return writeUuid(serverConfigUuid); +} From 56e25323533c4d97a6f5b0a98d895fa25e9a87e8 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 17 Aug 2016 22:21:13 -0700 Subject: [PATCH 2/5] test/uuid: simplify test to not rely on elasticsearch --- .../server}/lib/__tests__/manage_uuid.js | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) rename src/core_plugins/{elasticsearch => kibana/server}/lib/__tests__/manage_uuid.js (79%) diff --git a/src/core_plugins/elasticsearch/lib/__tests__/manage_uuid.js b/src/core_plugins/kibana/server/lib/__tests__/manage_uuid.js similarity index 79% rename from src/core_plugins/elasticsearch/lib/__tests__/manage_uuid.js rename to src/core_plugins/kibana/server/lib/__tests__/manage_uuid.js index 80a0687f9ab0d..312ed4471c5b0 100644 --- a/src/core_plugins/elasticsearch/lib/__tests__/manage_uuid.js +++ b/src/core_plugins/kibana/server/lib/__tests__/manage_uuid.js @@ -1,11 +1,11 @@ import expect from 'expect.js'; import sinon from 'sinon'; import Joi from 'joi'; -import * as kbnTestServer from '../../../../../test/utils/kbn_server.js'; -import fromRoot from '../../../../utils/from_root'; +import * as kbnTestServer from '../../../../../../test/utils/kbn_server.js'; +import fromRoot from '../../../../../utils/from_root'; import manageUuid from '../manage_uuid'; -describe('plugins/elasticsearch', function () { +describe('core_plugins/kibana/server/lib', function () { describe('manage_uuid', function () { const testUuid = 'c4add484-0cba-4e05-86fe-4baa112d9e53'; let kbnServer; @@ -23,7 +23,6 @@ describe('plugins/elasticsearch', function () { }); await kbnServer.ready(); - await kbnServer.server.plugins.elasticsearch.waitUntilReady(); }); // clear uuid stuff from previous test runs @@ -49,42 +48,37 @@ describe('plugins/elasticsearch', function () { }); it('finds the previously set uuid with config match', async function () { - const uuidManagement = manageUuid(kbnServer.server); const msg = `Kibana instance UUID: ${testUuid}`; config.set('uuid', testUuid); - await uuidManagement(); - await uuidManagement(); + await manageUuid(kbnServer.server); + await manageUuid(kbnServer.server); expect(kbnServer.server.log.lastCall.args[1]).to.be.eql(msg); }); it('updates the previously set uuid with config value', async function () { - const uuidManagement = manageUuid(kbnServer.server); config.set('uuid', testUuid); - await uuidManagement(); + await manageUuid(kbnServer.server); const newUuid = '5b2de169-2785-441b-ae8c-186a1936b17d'; const msg = `Updating Kibana instance UUID to: ${newUuid} (was: ${testUuid})`; config.set('uuid', newUuid); - await uuidManagement(); + await manageUuid(kbnServer.server); expect(kbnServer.server.log.lastCall.args[1]).to.be(msg); }); it('resumes the uuid stored in data and sets it to the config', async function () { - const uuidManagement = manageUuid(kbnServer.server); const partialMsg = 'Resuming persistent Kibana instance UUID'; config.set('uuid'); // set to undefined - await uuidManagement(); + await manageUuid(kbnServer.server); expect(config.get('uuid')).to.be.ok(); // not undefined any more expect(kbnServer.server.log.lastCall.args[1]).to.match(new RegExp(`^${partialMsg}`)); }); - - }); }); From fa6b33eba29aff3e63a5640fa4043bd140075787 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Thu, 18 Aug 2016 09:28:00 -0700 Subject: [PATCH 3/5] uuid: config key rename `uuid` => `server.uuid` --- .../kibana/server/lib/__tests__/manage_uuid.js | 16 ++++++++-------- .../kibana/server/lib/manage_uuid.js | 6 +++--- src/server/config/schema.js | 2 +- src/server/status/index.js | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/core_plugins/kibana/server/lib/__tests__/manage_uuid.js b/src/core_plugins/kibana/server/lib/__tests__/manage_uuid.js index 312ed4471c5b0..9b0d16faafe4e 100644 --- a/src/core_plugins/kibana/server/lib/__tests__/manage_uuid.js +++ b/src/core_plugins/kibana/server/lib/__tests__/manage_uuid.js @@ -37,11 +37,11 @@ describe('core_plugins/kibana/server/lib', function () { }); it('ensure config uuid is validated as a guid', async function () { - config.set('uuid', testUuid); - expect(config.get('uuid')).to.be(testUuid); + config.set('server.uuid', testUuid); + expect(config.get('server.uuid')).to.be(testUuid); expect(() => { - config.set('uuid', 'foouid'); + config.set('server.uuid', 'foouid'); }).to.throwException((e) => { expect(e.name).to.be('ValidationError'); }); @@ -49,7 +49,7 @@ describe('core_plugins/kibana/server/lib', function () { it('finds the previously set uuid with config match', async function () { const msg = `Kibana instance UUID: ${testUuid}`; - config.set('uuid', testUuid); + config.set('server.uuid', testUuid); await manageUuid(kbnServer.server); await manageUuid(kbnServer.server); @@ -58,14 +58,14 @@ describe('core_plugins/kibana/server/lib', function () { }); it('updates the previously set uuid with config value', async function () { - config.set('uuid', testUuid); + config.set('server.uuid', testUuid); await manageUuid(kbnServer.server); const newUuid = '5b2de169-2785-441b-ae8c-186a1936b17d'; const msg = `Updating Kibana instance UUID to: ${newUuid} (was: ${testUuid})`; - config.set('uuid', newUuid); + config.set('server.uuid', newUuid); await manageUuid(kbnServer.server); expect(kbnServer.server.log.lastCall.args[1]).to.be(msg); @@ -73,11 +73,11 @@ describe('core_plugins/kibana/server/lib', function () { it('resumes the uuid stored in data and sets it to the config', async function () { const partialMsg = 'Resuming persistent Kibana instance UUID'; - config.set('uuid'); // set to undefined + config.set('server.uuid'); // set to undefined await manageUuid(kbnServer.server); - expect(config.get('uuid')).to.be.ok(); // not undefined any more + expect(config.get('server.uuid')).to.be.ok(); // not undefined any more expect(kbnServer.server.log.lastCall.args[1]).to.match(new RegExp(`^${partialMsg}`)); }); }); diff --git a/src/core_plugins/kibana/server/lib/manage_uuid.js b/src/core_plugins/kibana/server/lib/manage_uuid.js index 12ff07b19728c..df99fbb3e8e0f 100644 --- a/src/core_plugins/kibana/server/lib/manage_uuid.js +++ b/src/core_plugins/kibana/server/lib/manage_uuid.js @@ -35,7 +35,7 @@ export default async function manageUuid(server) { // detect if uuid exists already from before a restart const logToServer = (msg) => server.log(['server', 'uuid', fileName], msg); const dataFileUuid = await detectUuid(); - let serverConfigUuid = config.get('uuid'); // check if already set in config + let serverConfigUuid = config.get('server.uuid'); // check if already set in config if (dataFileUuid) { // data uuid found @@ -49,7 +49,7 @@ export default async function manageUuid(server) { // config uuid missing, data uuid exists serverConfigUuid = dataFileUuid; logToServer(`Resuming persistent Kibana instance UUID: ${serverConfigUuid}`); - config.set('uuid', serverConfigUuid); + config.set('server.uuid', serverConfigUuid); return; } @@ -65,7 +65,7 @@ export default async function manageUuid(server) { if (!serverConfigUuid) { // config uuid missing serverConfigUuid = uuid.v4(); - config.set('uuid', serverConfigUuid); + config.set('server.uuid', serverConfigUuid); } logToServer(`Setting new Kibana instance UUID: ${serverConfigUuid}`); diff --git a/src/server/config/schema.js b/src/server/config/schema.js index 074ccec05b579..dbabdeae2d91e 100644 --- a/src/server/config/schema.js +++ b/src/server/config/schema.js @@ -30,9 +30,9 @@ module.exports = () => Joi.object({ exclusive: Joi.boolean().default(false) }).default(), - uuid: Joi.string().guid().default(), server: Joi.object({ + uuid: Joi.string().guid().default(), name: Joi.string().default(os.hostname()), host: Joi.string().hostname().default('localhost'), port: Joi.number().default(5601), diff --git a/src/server/status/index.js b/src/server/status/index.js index 597401df7e478..487621ba6a768 100644 --- a/src/server/status/index.js +++ b/src/server/status/index.js @@ -18,7 +18,7 @@ export default function (kbnServer, server, config) { handler: function (request, reply) { return reply({ name: config.get('server.name'), - uuid: config.get('uuid'), + uuid: config.get('server.uuid'), status: kbnServer.status.toJSON(), metrics: kbnServer.metrics }); From 73cf57aee48c6d18c63d0646715712a19337ca33 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Tue, 23 Aug 2016 09:49:22 -0700 Subject: [PATCH 4/5] uuid: use server.config for hostname --- src/core_plugins/kibana/server/lib/manage_uuid.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core_plugins/kibana/server/lib/manage_uuid.js b/src/core_plugins/kibana/server/lib/manage_uuid.js index df99fbb3e8e0f..b6c13550f92f5 100644 --- a/src/core_plugins/kibana/server/lib/manage_uuid.js +++ b/src/core_plugins/kibana/server/lib/manage_uuid.js @@ -1,15 +1,14 @@ import uuid from 'node-uuid'; import Promise from 'bluebird'; -import { hostname } from 'os'; import { join as pathJoin } from 'path'; import { readFile as readFileCallback, writeFile as writeFileCallback } from 'fs'; -const serverHostname = hostname(); const FILE_ENCODING = 'utf8'; export default async function manageUuid(server) { const config = server.config(); const serverPort = server.info.port; + const serverHostname = config.get('server.host'); const fileName = `${serverHostname}:${serverPort}`; const uuidFile = pathJoin(config.get('path.data'), fileName); From 56e452700691abaa211dc7b78d93085612fdafa8 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Mon, 29 Aug 2016 14:11:04 -0700 Subject: [PATCH 5/5] doc: release notes: add uuid line --- docs/releasenotes.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/releasenotes.asciidoc b/docs/releasenotes.asciidoc index 69a78d1af27d7..70c7e9ff14db9 100644 --- a/docs/releasenotes.asciidoc +++ b/docs/releasenotes.asciidoc @@ -16,6 +16,7 @@ The {version} release of Kibana requires Elasticsearch {esversion} or later. * {k4issue}6531[Issue 6531]: Improved warning for URL lengths that approach browser limits. * {k4issue}6602[Issue 6602]: Improves dark theme support. * {k4issue}6791[Issue 6791]: Enables composition of custom user toast notifications in Advanced Settings. +* {k4pull}8014[Pull Request 8014]: Changes the UUID config setting from `uuid` to `server.uuid`, and puts UUID storage into data file instead of Elasticsearch. [float] [[bugfixes]]