mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
enhance cli to manage dev server
This commit is contained in:
parent
967726fc1b
commit
e98d264c20
45 changed files with 409 additions and 365 deletions
|
@ -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
|
@ -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
71
src/cli/cli.js
Normal 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
59
src/cli/dev/devmode.js
Normal 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$/, '');
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
8
src/cli/dev/kibanaSrcFilter.js
Normal file
8
src/cli/dev/kibanaSrcFilter.js
Normal 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
5
src/cli/dev/package.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "devmode",
|
||||
"main": "devmode.js",
|
||||
"version": "1.0.0"
|
||||
}
|
47
src/cli/dev/watch.js
Normal file
47
src/cli/dev/watch.js
Normal 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
2
src/cli/index.js
Normal 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
50
src/cli/readYamlConfig.js
Normal 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);
|
||||
}, {});
|
||||
};
|
||||
|
|
@ -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();
|
||||
}
|
|
@ -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$/);
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"name": "devServer",
|
||||
"main": "devServer.js",
|
||||
"version": "1.0.0"
|
||||
}
|
|
@ -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}`);
|
||||
});
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
});
|
|
@ -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);
|
||||
}, {});
|
||||
};
|
||||
|
|
@ -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();
|
||||
|
||||
|
|
16
src/server/http/getDefaultRoute.js
Normal file
16
src/server/http/getDefaultRoute.js
Normal 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';
|
||||
});
|
|
@ -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));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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: '*',
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -33,4 +33,4 @@ define(function (require) {
|
|||
|
||||
return ConfigTemplate;
|
||||
|
||||
});
|
||||
});
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue