enhance cli to manage dev server

This commit is contained in:
Spencer Alger 2015-07-08 17:40:44 -07:00
parent 967726fc1b
commit e98d264c20
45 changed files with 409 additions and 365 deletions

View file

@ -1,64 +1,65 @@
# Kibana is served by a back end server. This controls which port to use.
# port: 5601
# server.port: 5601
# The host to bind the server to.
# host: "0.0.0.0"
# server.host: "0.0.0.0"
# The Elasticsearch instance to use for all your queries.
# elasticsearch_url: "http://localhost:9200"
# elasticsearch.url: "http://localhost:9200"
# preserve_elasticsearch_host true will send the hostname specified in `elasticsearch`. If you set it to false,
# then the host you use to connect to *this* Kibana instance will be sent.
# elasticsearch_preserve_host: true
# elasticsearch.preserveHost: true
# Kibana uses an index in Elasticsearch to store saved searches, visualizations
# and dashboards. It will create a new index if it doesn't already exist.
# kibana_index: ".kibana"
# kibana.index: ".kibana"
# The default application to load.
# kibana.defaultAppId: "discover"
# If your Elasticsearch is protected with basic auth, this is the user credentials
# used by the Kibana server to perform maintence on the kibana_index at statup. Your Kibana
# users will still need to authenticate with Elasticsearch (which is proxied thorugh
# the Kibana server)
# kibana_elasticsearch_username: user
# kibana_elasticsearch_password: pass
# elasticsearch.username: user
# elasticsearch.password: pass
# If your Elasticsearch requires client certificate and key
# kibana_elasticsearch_client_crt: /path/to/your/client.crt
# kibana_elasticsearch_client_key: /path/to/your/client.key
# elasticsearch.ssl.cert: /path/to/your/client.crt
# elasticsearch.ssl.key: /path/to/your/client.key
# If you need to provide a CA certificate for your Elasticsarech instance, put
# the path of the pem file here.
# ca: /path/to/your/CA.pem
# The default application to load.
# default_app_id: "discover"
# Time in milliseconds to wait for elasticsearch to respond to pings, defaults to
# request_timeout setting
# ping_timeout: 1500
# Time in milliseconds to wait for responses from the back end or elasticsearch.
# This must be > 0
# request_timeout: 300000
# Time in milliseconds for Elasticsearch to wait for responses from shards.
# Set to 0 to disable.
# shard_timeout: 0
# Time in milliseconds to wait for Elasticsearch at Kibana startup before retrying
# startup_timeout: 5000
# elasticsearch.ssl.ca: /path/to/your/CA.pem
# Set to false to have a complete disregard for the validity of the SSL
# certificate.
# verify_ssl: true
# elasticsearch.ssl.verify: true
# Time in milliseconds to wait for elasticsearch to respond to pings, defaults to
# request_timeout setting
# elasticsearch.pingTimeout: 1500
# Time in milliseconds to wait for responses from the back end or elasticsearch.
# This must be > 0
# elasticsearch.requestTimeout: 300000
# Time in milliseconds for Elasticsearch to wait for responses from shards.
# Set to 0 to disable.
# elasticsearch.shardTimeout: 0
# Time in milliseconds to wait for Elasticsearch at Kibana startup before retrying
# elasticsearch.startupTimeout: 5000
# SSL for outgoing requests from the Kibana Server (PEM formatted)
# ssl_key_file: /path/to/your/server.key
# ssl_cert_file: /path/to/your/server.crt
# server.ssl.cert: /path/to/your/server.key
# server.ssl.key: /path/to/your/server.crt
# Set the path to where you would like the process id file to be created.
# pid_file: /var/run/kibana.pid
# server.pidFile: /var/run/kibana.pid
# If you would like to send the log output to a file you can set the path below.
# This will also turn off the STDOUT log output.
# log_file: ./kibana.log
# logging.dest: stdout
logging.json: false

File diff suppressed because one or more lines are too long

View file

@ -30,7 +30,7 @@
],
"scripts": {
"test": "grunt test",
"start": "node ./src/devServer/run.js",
"start": "node ./src/server/cli/index.js --dev",
"postinstall": "bower install && grunt licenses --check-validity",
"precommit": "grunt lintStagedFiles"
},

File diff suppressed because one or more lines are too long

71
src/cli/cli.js Normal file
View file

@ -0,0 +1,71 @@
'use strict';
let _ = require('lodash');
let KbnServer = require('../server/KbnServer');
let program = require('commander');
let fromRoot = require('../utils/fromRoot');
let pkg = require('../utils/closestPackageJson').getSync();
let readYamlConfig = require('./readYamlConfig');
program.description(
'Kibana is an open source (Apache Licensed), browser based analytics ' +
'and search dashboard for Elasticsearch.'
);
program.version(pkg.version);
program.option('-e, --elasticsearch <uri>', 'Elasticsearch instance');
program.option('-c, --config <path>', 'Path to the config file');
program.option('-p, --port <port>', 'The port to bind to', parseInt);
program.option('-q, --quiet', 'Turns off logging');
program.option('--verbose', 'Turns on verbose logging');
program.option('-H, --host <host>', 'The host to bind to');
program.option('-l, --log-file <path>', 'The file to log to');
program.option(
'--plugin-dir <path>',
'A path to scan for plugins, this can be specified multiple ' +
'times to specify multiple directories'
);
program.option(
'--plugin-path <path>',
'A path to a plugin which should be included by the server, ' +
'this can be specified multiple times to specify multiple paths'
);
program.option('--plugins <path>', 'an alias for --plugin-dir');
program.option('--dev', 'Run the server with development mode defaults');
program.option(
'--watch',
'Enable watching the source tree and automatically restarting, ' +
'enabled by --dev, use --no-watch to disable'
);
program.parse(process.argv);
let settings = readYamlConfig(program.config || fromRoot('config/kibana.yml'));
let set = _.partial(_.set, settings);
let get = _.partial(_.get, settings);
if (program.dev) {
set('env', 'development');
set('optimize.watch', true);
}
if (program.watch != null) set('optimize.watch', program.watch);
if (program.elasticsearch) set('elasticsearch.url', program.elasticsearch);
if (program.port) set('server.port', program.port);
if (program.host) set('server.host', program.host);
if (program.quiet) set('logging.quiet', program.quiet);
if (program.logFile) set('logging.dest', program.logFile);
set('plugins.scanDirs', _.compact([].concat(
get('plugins.scanDirs'),
program.plugins,
program.pluginDir,
fromRoot('src/plugins')
)));
set('plugins.paths', [].concat(program.pluginPath || []));
// Start the KbnServer server with the settings fromt he CLI and YAML file
let kibana = new KbnServer(settings);
kibana.listen().catch(function (err) {
console.log(err.stack);
process.exit(1);
});

59
src/cli/dev/devmode.js Normal file
View file

@ -0,0 +1,59 @@
module.exports = function devServerPlugin(kibana) {
var _ = require('lodash');
var KbnServer = require('../server/KbnServer');
var glob = require('glob');
var join = require('path').join;
var basename = require('path').basename;
var relative = require('path').relative;
var normalize = require('path').normalize;
var ROOT = join(__dirname, '..', '..', '..');
var fromRoot = function () {
return normalize(join([ROOT].concat(_.toArray(arguments))));
};
var SRC = fromRoot('src');
var NODE_MODULES = fromRoot('node_modules');
var UI = fromRoot('src/ui');
var TEST = fromRoot('test');
var UNIT = fromRoot('test/unit');
var SPECS = fromRoot('test/unit/specs/**/*.js');
var istanbul = require('./lib/istanbul');
var amdWrapper = require('./lib/amd_wrapper');
var kibanaSrcFilter = require('./lib/kibana_src_filter');
return new kibana.Plugin({
init: function (server, options) {
server.ext('onPreHandler', istanbul({ root: SRC, displayRoot: SRC, filter: kibanaSrcFilter }));
server.ext('onPreHandler', istanbul({ root: UI, displayRoot: SRC, filter: kibanaSrcFilter }));
server.exposeStaticDir('/test/{paths*}', TEST);
server.route({
path: '/amd-wrap/{paths*}',
method: 'GET',
handler: amdWrapper({ root: ROOT })
});
server.route({
path: '/specs',
method: 'GET',
handler: function (request, reply) {
glob(SPECS, function (err, files) {
if (err) return reply(err);
reply(
files
.filter(function (filename) {
return basename(filename).charAt(0) !== '_';
})
.map(function (filename) {
return relative(UNIT, filename).replace(/\\/g, '/').replace(/\.js$/, '');
})
);
});
}
});
}
});
};

View file

@ -0,0 +1,8 @@
'use strict';
module.exports = function (filename) {
let isJs = filename.match(/\.js$/);
let inSrc = filename.match(/\/src\//);
let isRison = filename.match(/rison\.js$/);
return isJs && inSrc && !isRison;
};

5
src/cli/dev/package.json Normal file
View file

@ -0,0 +1,5 @@
{
"name": "devmode",
"main": "devmode.js",
"version": "1.0.0"
}

47
src/cli/dev/watch.js Normal file
View file

@ -0,0 +1,47 @@
'use strict';
let _ = require('lodash');
let nodemon = require('nodemon');
let join = require('path').join;
let relative = require('path').relative;
let normalize = require('path').normalize;
let ansicolors = require('ansicolors');
let root = join(__dirname, '..', '..', '..');
let fromRoot = _.restParam(function (segs) {
return normalize(join.apply(null, [root].concat(segs)));
});
let rel = _.partial(relative, root);
let green = _.flow(ansicolors.black, ansicolors.bgGreen);
let red = _.flow(ansicolors.white, ansicolors.bgRed);
let yellow = _.flow(ansicolors.black, ansicolors.bgYellow);
let crash = red(' Kibana Crashed ');
let restart = yellow(' Kibana Restarted ');
let start = green(' Kibana Started ');
let args = _.without(process.argv.slice(2), '--watch');
console.log(yellow(' Kibana starting '), 'and watching for changes');
nodemon({
script: fromRoot('src/cli/index.js'),
args: args,
watch: [
fromRoot('src/'),
fromRoot('config/'),
],
ignore: fromRoot('src/**/public/'),
ext: 'js,json,tmpl,yml'
});
nodemon.on('start', _.bindKey(console, 'log', start));
nodemon.on('crash', _.bindKey(console, 'log', crash));
nodemon.on('restart', function (files) {
var prefix = files.length > 1 ? '\n - ' : '';
var fileList = files.reduce(function (list, file, i, files) {
return `${list || ''}${prefix}"${rel(file)}"`;
}, '');
console.log(`${restart} due to changes in ${fileList}`);
});

2
src/cli/index.js Normal file
View file

@ -0,0 +1,2 @@
if (process.argv.slice(2).indexOf('--watch') > -1) require('./dev/watch');
else require('./cli');

50
src/cli/readYamlConfig.js Normal file
View file

@ -0,0 +1,50 @@
var _ = require('lodash');
var fs = require('fs');
var yaml = require('js-yaml');
var fromRoot = require('../utils/fromRoot');
var legacySettingMap = {
// server
port: 'server.port',
host: 'server.host',
pid_file: 'server.pidFile',
ssl_cert_file: 'server.ssl.cert',
ssl_key_file: 'server.ssl.key',
// logging
log_file: 'logging.dest',
// kibana
kibana_index: 'kibana.index',
default_app_id: 'kibana.defaultAppId',
// es
ca: 'elasticsearch.ssl.ca',
elasticsearch_preserve_host: 'elasticsearch.preserveHost',
elasticsearch_url: 'elasticsearch.url',
kibana_elasticsearch_client_crt: 'elasticsearch.ssl.cert',
kibana_elasticsearch_client_key: 'elasticsearch.ssl.key',
kibana_elasticsearch_password: 'elasticsearch.password',
kibana_elasticsearch_username: 'elasticsearch.username',
ping_timeout: 'elasticsearch.pingTimeout',
request_timeout: 'elasticsearch.requestTimeout',
shard_timeout: 'elasticsearch.shardTimeout',
startup_timeout: 'elasticsearch.startupTimeout',
verify_ssl: 'elasticsearch.ssl.verify',
};
module.exports = function (path) {
if (!path) return {};
var file = yaml.safeLoad(fs.readFileSync(path, 'utf8'));
// transform legeacy options into new namespaced versions
return _.transform(file, function (config, val, key) {
if (legacySettingMap.hasOwnProperty(key)) {
key = legacySettingMap[key];
}
_.set(config, key, val);
}, {});
};

View file

@ -1,79 +0,0 @@
var _ = require('lodash');
var resolve = require('path').resolve.bind(null, __dirname, '..', '..');
var KbnServer = require('../server/KbnServer');
function kibanaPlugin(kibana) {
var path = require('path');
var glob = require('glob');
var join = path.join;
var rel = join.bind(null, __dirname);
var ROOT = rel('../../../');
var SRC = join(ROOT, 'src');
var NODE_MODULES = join(ROOT, 'node_modules');
var APP = join(SRC, 'kibana');
var TEST = join(ROOT, 'test');
var istanbul = require('./lib/istanbul');
var amdWrapper = require('./lib/amd_wrapper');
var kibanaSrcFilter = require('./lib/kibana_src_filter');
return new kibana.Plugin({
init: function (server, options) {
server.ext('onPreHandler', istanbul({ root: SRC, displayRoot: SRC, filter: kibanaSrcFilter }));
server.ext('onPreHandler', istanbul({ root: APP, displayRoot: SRC, filter: kibanaSrcFilter }));
server.route({
path: '/test/{paths*}',
method: 'GET',
handler: {
directory: {
path: TEST
}
}
});
server.route({
path: '/amd-wrap/{paths*}',
method: 'GET',
handler: amdWrapper({ root: ROOT })
});
server.route({
path: '/specs',
method: 'GET',
handler: function (request, reply) {
var unit = join(ROOT, '/test/unit/');
glob(join(unit, 'specs/**/*.js'), function (er, files) {
var moduleIds = files
.filter(function (filename) {
return path.basename(filename).charAt(0) !== '_';
})
.map(function (filename) {
return path.relative(unit, filename).replace(/\\/g, '/').replace(/\.js$/, '');
});
return reply(moduleIds);
});
}
});
}
});
}
function run(port, quiet) {
return (new KbnServer({
'env': 'development',
'kibana.server.port': port || 5601,
'plugins.paths': [ __dirname ],
'plugins.scanDirs': [ resolve('src/plugins') ],
'optimize.bundleDir': resolve('bundles'),
}))
.listen();
}
module.exports = kibanaPlugin;
module.exports.run = run;
if (require.main === module) {
run().done();
}

View file

@ -1,5 +0,0 @@
module.exports = function (filename) {
return filename.match(/.*\/src\/.*\.js$/)
&& !filename.match(/.*\/src\/kibana\/bower_components\/.*\.js$/)
&& !filename.match(/.*\/src\/kibana\/utils\/(event_emitter|rison)\.js$/);
};

View file

@ -1,5 +0,0 @@
{
"name": "devServer",
"main": "devServer.js",
"version": "1.0.0"
}

View file

@ -1,38 +0,0 @@
'use strict';
let _ = require('lodash');
let nodemon = require('nodemon');
let join = require('path').join;
let relative = require('path').relative;
let normalize = require('path').normalize;
let ansicolors = require('ansicolors');
let root = join(__dirname, '..', '..');
let fromRoot = _.restParam(function (args) {
return normalize(join.apply(null, [root].concat(args)));
});
let rel = _.partial(relative, root);
let crash = _.flow(ansicolors.white, ansicolors.bgRed)(' Kibana crashed ');
let restart = _.flow(ansicolors.black, ansicolors.bgGreen)(' Kibana restarted ');
nodemon({
script: fromRoot('src/devServer/devServer.js'),
watch: [
fromRoot('src/'),
'!' + fromRoot('src/plugins/*/public/**/*')
],
ext: 'js,json,tmpl'
});
nodemon.on('crash', function () {
console.log(crash);
});
nodemon.on('restart', function (files) {
var prefix = files.length > 1 ? '\n - ' : '';
var fileList = files.reduce(function (list, file, i, files) {
return `${list || ''}${prefix}"${rel(file)}"`;
}, '');
console.log(`${restart} due to changes in ${fileList}`);
});

View file

@ -4,6 +4,27 @@ module.exports = function (kibana) {
var createProxy = require('./lib/create_proxy');
return new kibana.Plugin({
config: function (Joi) {
return Joi.object({
url: Joi.string().uri({ scheme: ['http', 'https'] }).default('http://localhost:9200'),
preserveHost: Joi.boolean().default(true),
username: Joi.string(),
password: Joi.string(),
shardTimeout: Joi.number().default(0),
requestTimeout: Joi.number().default(30000),
pingTimeout: Joi.number().default(30000),
startupTimeout: Joi.number().default(5000),
ssl: Joi.object({
verify: Joi.boolean().default(true),
ca: Joi.string(),
cert: Joi.string(),
key: Joi.string()
}).default(),
minimumVerison: Joi.string().default('1.4.4')
}).default();
},
init: function (server, options) {
var config = server.config();
@ -35,7 +56,7 @@ module.exports = function (kibana) {
);
// Set up the health check service and start it.
// healthCheck(this, server).start();
healthCheck(this, server).start();
}
});

View file

@ -1,18 +1,19 @@
var semver = require('semver');
var pkg = require('../../../utils/closestPackageJson').getSync();
var rcVersionRegex = /(\d+\.\d+\.\d+)\-rc(\d+)/i;
module.exports = function (server, doc) {
var config = server.config();
if (/beta|snapshot/i.test(doc._id)) return false;
if (!doc._id) return false;
if (doc._id === config.get('kibana.package.version')) return false;
if (doc._id === pkg.version) return false;
var packageRcRelease = Infinity;
var rcRelease = Infinity;
var packageVersion = config.get('kibana.package.version');
var packageVersion = pkg.version;
var version = doc._id;
var matches = doc._id.match(rcVersionRegex);
var packageMatches = config.get('kibana.package.version').match(rcVersionRegex);
var packageMatches = pkg.version.match(rcVersionRegex);
if (matches) {
version = matches[1];

View file

@ -1,5 +1,6 @@
var Promise = require('bluebird');
var isUpgradeable = require('./is_upgradeable');
var pkg = require('../../../utils/closestPackageJson').getSync();
var _ = require('lodash');
var format = require('util').format;
module.exports = function (server) {
@ -12,7 +13,7 @@ module.exports = function (server) {
if (response.hits.hits.length === 0) return Promise.resolve();
// if we already have a the current version in the index then we need to stop
if (_.find(response.hits.hits, { _id: config.get('kibana.package.version') })) {
if (_.find(response.hits.hits, { _id: pkg.version })) {
return Promise.resolve();
}
@ -29,13 +30,17 @@ module.exports = function (server) {
body._source.buildNum = parseInt(config.get('kibana.buildNum'), 10);
}
var logMsg = format('[ elasticsearch ] Upgrade config from %s to %s', body._id, config.get('kibana.package.version'));
server.log('plugin', logMsg);
server.log('plugin', {
tmpl: '[ elasticsearch ] Upgrade config from <%= prevVersion %> to <%= newVersion %>',
prevVersion: body._id,
newVersion: pkg.version
});
return client.create({
index: config.get('kibana.index'),
type: 'config',
body: body._source,
id: config.get('kibana.package.version')
id: pkg.version
});
};
};

View file

@ -3,6 +3,14 @@ module.exports = function (kibana) {
var ng = jq.concat('angular');
return new kibana.Plugin({
config: function (Joi) {
return Joi.object({
index: Joi.string().default('.kibana'),
buildNum: Joi.string().default('@@buildNum')
}).default();
},
uiExports: {
app: {
title: 'Kibana',
@ -12,7 +20,12 @@ module.exports = function (kibana) {
uses: [
'visTypes',
'spyModes'
]
],
constants: function (server, options) {
return {
defaultAppId: options.defaultAppId
};
}
},
modules: {

View file

@ -3,8 +3,8 @@ var Promise = require('bluebird');
var Hapi = require('hapi');
var dirname = require('path').dirname;
var rootDir = require('./utils/fromRoot')('.');
var package = require('./utils/closestPackageJson').getSync();
var rootDir = require('../utils/fromRoot')('.');
var package = require('../utils/closestPackageJson').getSync();
function KbnServer(settings) {
this.name = package.name;

View file

@ -1,66 +0,0 @@
var _ = require('lodash');
var KbnServer = require('../KbnServer');
var program = require('commander');
var package = require('./utils/closestPackageJson').getSync();
var readYamlConfig = require('./readYamlConfig');
program.description('Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch.');
program.version(package.version);
program.option('-e, --elasticsearch <uri>', 'Elasticsearch instance');
program.option('-c, --config <path>', 'Path to the config file');
program.option('-p, --port <port>', 'The port to bind to', parseInt);
program.option('-q, --quiet', 'Turns off logging');
program.option('--verbose', 'Turns on verbose logging');
program.option('-H, --host <host>', 'The host to bind to');
program.option('-l, --log-file <path>', 'The file to log to');
program.option(
'--plugin-dir <path>',
'A path to scan for plugins, this can be specified multiple ' +
'times to specify multiple directories'
);
program.option(
'--plugin-path <path>',
'A path to a plugin which should be included by the server, ' +
'this can be specified multiple times to specify multiple paths'
);
program.option('--plguins <path>', 'an alias for --plugin-dir');
program.parse(process.argv);
var settings = _.defaults(readYamlConfig(program.config || process.env.CONFIG_PATH), {
'logging.console.json': true
});
if (program.elasticsearch) {
settings['elasticsearch.url'] = program.elasticsearch;
}
if (program.port) {
settings['kibana.server.port'] = program.port;
}
if (program.host) {
settings['kibana.server.host'] = program.host;
}
if (program.quiet) {
settings['logging.quiet'] = program.quiet;
}
if (program.logFile) {
settings['logging.dest'] = program.logFile;
}
if (program.plugins || program.pluginDir) {
settings['plugins.scanDirs'] = [].concat(program.plugins, program.pluginDir).filter(Boolean);
}
if (program.pluginPath) {
settings['plugins.paths'] = [].concat(program.pluginPath);
}
// Start the KbnServer server with the settings fromt he CLI and YAML file
var kibana = new KbnServer(settings);
kibana.listen().catch(function (err) {
console.log(err.stack);
process.exit(1);
});

View file

@ -1,43 +0,0 @@
var _ = require('lodash');
var fs = require('fs');
var yaml = require('js-yaml');
var legacySettingMap = {
port: 'kibana.server.port',
host: 'kibana.server.host',
elasticsearch_url: 'elasticsearch.url',
elasticsearch_preserve_host: 'elasticsearch.preserveHost',
config_index: 'config.index',
config_elasticsearch_username: 'elasticsearch.username',
config_elasticsearch_password: 'elasticsearch.password',
config_elasticsearch_client_crt: 'elasticsearch.ssl.cert',
config_elasticsearch_client_key: 'elasticsearch.ssl.key',
ca: 'elasticsearch.ssl.ca',
verify_ssl: 'elasticsearch.ssl.verify',
default_app_id: 'kibana.defaultAppId',
ping_timeout: 'elastcsearch.pingTimeout',
request_timeout: 'elastcsearch.requestTimeout',
shard_timeout: 'elastcsearch.shardTimeout',
startup_timeout: 'elastcsearch.startupTimeout',
ssl_cert_file: 'kibana.server.ssl.cert',
ssl_key_file: 'kibana.server.ssl.key',
pid_file: 'config.server.pidFile',
log_file: 'logging.file',
bundled_plugin_ids: 'kibana.bundledPluginIds'
};
module.exports = function (path) {
if (!path) return {};
var file = yaml.safeLoad(fs.readFileSync(path, 'utf8'));
// transform legeacy options into new namespaced versions
return _.transform(file, function (config, val, key) {
if (legacySettingMap.hasOwnProperty(key)) {
key = legacySettingMap[key];
}
_.set(config, key, val);
}, {});
};

View file

@ -1,8 +1,8 @@
var Joi = require('joi');
var fs = require('fs');
var path = require('path');
var package = require('../utils/closestPackageJson').getSync();
var fromRoot = require('../utils/fromRoot');
var package = require('../../utils/closestPackageJson').getSync();
var fromRoot = require('../../utils/fromRoot');
module.exports = Joi.object({
env: Joi.object({
@ -11,42 +11,15 @@ module.exports = Joi.object({
prod: Joi.boolean().default(Joi.ref('$prod'))
}).default(),
kibana: Joi.object({
package: Joi.any().default(package),
server: Joi.object({
host: Joi.string().hostname().default('0.0.0.0'),
port: Joi.number().default(5601),
maxSockets: Joi.any().default(Infinity),
pidFile: Joi.string(),
root: Joi.string().default(path.normalize(path.join(__dirname, '..'))),
ssl: Joi.object({
cert: Joi.string(),
key: Joi.string()
}).default()
}).default(),
index: Joi.string().default('.kibana'),
defaultRoute: Joi.string().default('/app/kibana/'),
buildNum: Joi.string().default('@@buildNum'),
bundledPluginIds: Joi.array().items(Joi.string())
}).default(),
elasticsearch: Joi.object({
url: Joi.string().uri({ scheme: ['http', 'https'] }).default('http://localhost:9200'),
preserveHost: Joi.boolean().default(true),
username: Joi.string(),
password: Joi.string(),
shardTimeout: Joi.number().default(0),
requestTimeout: Joi.number().default(30000),
pingTimeout: Joi.number().default(30000),
startupTimeout: Joi.number().default(5000),
server: Joi.object({
host: Joi.string().hostname().default('0.0.0.0'),
port: Joi.number().default(5601),
defaultRoute: Joi.string(),
pidFile: Joi.string(),
ssl: Joi.object({
verify: Joi.boolean().default(true),
ca: Joi.string(),
cert: Joi.string(),
key: Joi.string()
}).default(),
minimumVerison: Joi.string().default('1.4.4')
}).default()
}).default(),
logging: Joi.object().keys({
@ -63,7 +36,7 @@ module.exports = Joi.object({
.when('quiet', {
is: true,
then: Joi.valid(false).default(false),
otherwise: Joi.default(true)
otherwise: Joi.default(false)
}),
dest: Joi.string().default('stdout'),
@ -76,14 +49,14 @@ module.exports = Joi.object({
plugins: Joi.object({
paths: Joi.array().items(Joi.string()).default([]),
scanDirs: Joi.array().items(Joi.string()).default([])
}),
}).default(),
optimize: Joi.object({
bundleDir: Joi.string().default(fromRoot('src/server/optimize/bundles')),
bundleDir: Joi.string().default(fromRoot('optimize/bundles')),
viewCaching: Joi.boolean().default(Joi.ref('$prod')),
watch: Joi.boolean().default(Joi.ref('$dev')),
sourceMaps: Joi.boolean().default(Joi.ref('$dev'))
})
}).default()
}).default();

View file

@ -0,0 +1,16 @@
'use strict';
let _ = require('lodash');
module.exports = _.once(function (kbnServer) {
// user configured default route
let defaultConfig = kbnServer.server.config().get('server.defaultRoute');
if (defaultConfig) return defaultConfig;
// redirect to the single app
if (kbnServer.uiExports.apps.length === 1) {
return `/app/${kbnServer.uiExports.apps[0].id}`;
}
return '/apps';
});

View file

@ -2,11 +2,12 @@ module.exports = function (kbnServer, server, config) {
var Boom = require('boom');
var parse = require('url').parse;
var format = require('url').format;
var getDefaultRoute = require('./getDefaultRoute');
// Create a new connection
server.connection({
host: config.get('kibana.server.host'),
port: config.get('kibana.server.port')
host: config.get('server.host'),
port: config.get('server.port')
});
// provide a simple way to expose static directories
@ -54,7 +55,7 @@ module.exports = function (kbnServer, server, config) {
path: '/',
method: 'GET',
handler: function (req, reply) {
reply.redirect(config.get('kibana.defaultRoute'));
reply.redirect(getDefaultRoute(kbnServer));
}
});

View file

@ -7,14 +7,24 @@ module.exports = function (kbnServer, server, config) {
return fromNode(function (cb) {
let events = config.get('logging.events');
if (config.get('logging.quiet')) {
if (config.get('logging.silent')) {
_.defaults(events, {});
}
else if (config.get('logging.quiet')) {
_.defaults(events, {
log: ['error', 'fatal'],
error: '*'
});
}
if (config.get('logging.verbose')) {
else if (config.get('logging.verbose')) {
_.defaults(events, {
log: '*',
ops: '*',
response: '*',
error: '*'
});
}
else {
_.defaults(events, {
log: ['info', 'warning', 'error', 'fatal'],
response: '*',

View file

@ -8,7 +8,7 @@ var write = require('fs').writeFileSync;
var webpack = require('webpack');
var assets = require('../ui/assets');
var fromRoot = require('../utils/fromRoot');
var fromRoot = require('../../utils/fromRoot');
var OptmzBundles = require('./OptmzBundles');
var OptmzUiModules = require('./OptmzUiModules');
var DirectoryNameAsDefaultFile = require('./DirectoryNameAsDefaultFile');
@ -22,7 +22,7 @@ class Optimizer extends EventEmitter {
this.watch = opts.watch || false;
this.sourceMaps = opts.sourceMaps || false;
this.modules = new OptmzUiModules(opts.plugins);
this.bundles = new OptmzBundles(opts.bundleDir, opts.apps);
this.bundles = new OptmzBundles(opts);
}
init() {
@ -87,16 +87,11 @@ class Optimizer extends EventEmitter {
compiler.plugin('done', function (stats) {
var errCount = _.size(stats.compilation.errors);
if (errCount || self.verbose) {
console.log(`\n${ stats.toString({ colors: true }) }`);
}
if (errCount) {
self.emit('error', new Error('Failed to compile bundle'));
return;
self.emit('error', stats, new Error('Failed to compile bundle'));
} else {
self.emit('done', stats);
}
self.emit('done');
});
compiler.plugin('failed', onFail);

View file

@ -3,7 +3,7 @@
*
* This is programatically created and updated, do not modify
*
* built using: Kibana <%= kbnVersion %>
* built using: Kibana <%= version %>
* includes code from:
<%
deps.sort().forEach(function (plugin) {

View file

@ -15,10 +15,14 @@ let readdir = promify(require('fs').readdir);
let readSync = require('fs').readFileSync;
let appEntryTmpl = _.template(readSync(join(__dirname, 'OptmzAppEntry.js.tmpl')));
let kbnVersion = require('../utils/closestPackageJson').getSync().version;
let serverVersion = require('../../utils/closestPackageJson').getSync().version;
class OptmzBundles {
constructor(dir, apps) {
constructor(opts) {
let dir = _.get(opts, 'bundleDir');
let apps = _.get(opts, 'apps');
let versionTag = _.get(opts, 'sourceMaps') ? ' (with source maps)' : '';
this.dir = dir;
if (!_.isString(this.dir)) {
throw new TypeError('Optimizer requires a working directory');
@ -34,7 +38,9 @@ class OptmzBundles {
bundlePath: join(dir, app.id + '.js')
};
entry.content = appEntryTmpl(_.defaults({ kbnVersion: kbnVersion }, entry));
entry.content = appEntryTmpl(_.defaults({
version: `${serverVersion}${versionTag}`
}, entry));
return entry;
});

View file

@ -1,7 +1,7 @@
module.exports = function (kbnServer, server, config) {
var _ = require('lodash');
var resolve = require('path').resolve;
var fromRoot = require('../utils/fromRoot');
var fromRoot = require('../../utils/fromRoot');
var Optimizer = require('./Optimizer');
var bundleDir = resolve(config.get('optimize.bundleDir'));
@ -14,7 +14,6 @@ module.exports = function (kbnServer, server, config) {
}
return (new Optimizer({
verbose: config.get('logging.verbose'),
watch: config.get('optimize.watch'),
sourceMaps: config.get('optimize.sourceMaps'),
bundleDir: bundleDir,
@ -33,11 +32,12 @@ module.exports = function (kbnServer, server, config) {
.on('watch-run', _.after(2, function () {
status.yellow('Source file change detected, reoptimizing source files');
}))
.on('done', function () {
.on('done', function (stats) {
server.log(['optimize', 'debug'], `\n${ stats.toString({ colors: true }) }`);
status.green('Optimization complete');
})
.on('error', function (err) {
server.log('fatal', err);
.on('error', function (stats, err) {
server.log(['optimize', 'fatal'], `\n${ stats.toString({ colors: true }) }`);
status.red('Optimization failure! ' + err.message);
})
.init();

View file

@ -3,11 +3,8 @@ var Promise = require('bluebird');
var writeFile = Promise.promisify(require('fs').writeFile);
var unlink = require('fs').unlinkSync;
module.exports = Promise.method(function (kibana) {
var server = kibana.server;
var config = server.config();
var path = config.get('kibana.server.pidFile');
module.exports = Promise.method(function (kbnServer, server, config) {
var path = config.get('server.pidFile');
var pid = String(process.pid);
if (!path) return;

View file

@ -5,8 +5,8 @@ module.exports = function (kbnServer, server, config) {
var stat = Promise.promisify(require('fs').stat);
var join = require('path').join;
var scanDirs = [].concat(config.get('plugins.scanDirs'));
var absolutePaths = [].concat(config.get('plugins.paths'));
var scanDirs = [].concat(config.get('plugins.scanDirs') || []);
var absolutePaths = [].concat(config.get('plugins.paths') || []);
var debug = _.bindKey(server, 'log', ['plugins', 'debug']);
return Promise.map(scanDirs, function (dir) {

View file

@ -13,7 +13,7 @@ module.exports = function (kbnServer) {
server.exposeStaticDir('/status/{path*}', join(__dirname, 'public'));
server.plugins.good.monitor.on('ops', function (event) {
var port = config.get('kibana.server.port');
var port = config.get('server.port');
kbnServer.metrics.add({
rss: event.psmem.rss,

View file

@ -10,7 +10,9 @@ module.exports = function (kbnServer, server, config) {
path: '/apps',
method: 'GET',
handler: function (req, reply) {
return reply.renderApp(hiddenApps.byId.switcher);
var switcher = hiddenApps.byId.switcher;
if (!switcher) return reply(Boom.notFound('app switcher not installed'));
return reply.renderApp(switcher);
}
});

View file

@ -1,4 +1,4 @@
var fromRoot = require('../utils/fromRoot');
var fromRoot = require('../../utils/fromRoot');
var readdir = require('fs').readdirSync;
var stat = require('fs').statSync;
var join = require('path').join;

View file

@ -1,5 +1,5 @@
<kbn-notifications list="notifList"></kbn-notifications>
<div class="content" style="display: none;">
<div class="content" style="display: none;" chrome-context >
<nav
ng-style="{ background: chrome.navBackground }"
ng-class="{ show: !chrome.embedded }"
@ -45,7 +45,7 @@
</li>
</ul>
<ul chrome-context ng-show="timefilter.enabled" class="nav navbar-nav navbar-right navbar-timepicker">
<ul ng-show="timefilter.enabled" class="nav navbar-nav navbar-right navbar-timepicker">
<li>
<a ng-click="toggleRefresh()" ng-show="timefilter.refreshInterval.value > 0">
<i class="fa" ng-class="timefilter.refreshInterval.pause ? 'fa-play' : 'fa-pause'"></i>
@ -57,7 +57,7 @@
ng-show="timefilter.refreshInterval.value > 0 || !!pickerTemplate.current"
class="to-body">
<a ng-click="pickerTemplate.toggle('refreshInterval')" class="navbar-timepicker-auto-refresh-desc">
<a ng-click="pickerTemplate.toggle('interval')" class="navbar-timepicker-auto-refresh-desc">
<span ng-show="timefilter.refreshInterval.value === 0"><i class="fa fa-repeat"></i> Auto-refresh</span>
<span ng-show="timefilter.refreshInterval.value > 0">{{timefilter.refreshInterval.display}}</span>
</a>
@ -87,9 +87,9 @@
<config
ng-show="timefilter.enabled"
config-template="globalConfigTemplate"
config-template="pickerTemplate"
config-object="timefilter"
config-close="toggleTimepicker">
config-close="pickerTemplate.close">
</config>
<div class="application" ng-class="'tab-' + chrome.getActiveTabId('-none-')" ng-view></div>

View file

@ -33,4 +33,4 @@ define(function (require) {
return ConfigTemplate;
});
});

File diff suppressed because one or more lines are too long