first pass at plugin installer

This commit is contained in:
Jim Unger 2015-06-23 15:13:18 -05:00
parent c0f114d94c
commit 015d3abd83
8 changed files with 300 additions and 50 deletions

View file

@ -1,12 +1,12 @@
#!/usr/bin/env node
var _ = require('lodash');
var Kibana = require('../');
var program = require('commander');
require('../lib/commanderExtensions.js')(program);
var path = require('path');
var writePidFile = require('../lib/write_pid_file');
var loadSettingsFromYAML = require('../lib/load_settings_from_yaml');
var settings = { 'logging.console.json': true };
var startupOptions = require('./startup/startup_options.js');
var startup = require('./startup/startup.js');
var pluginProgram = require('./plugin/plugin');
var env = (process.env.NODE_ENV) ? process.env.NODE_ENV : 'development';
var packagePath = path.resolve(__dirname, '..', '..', '..', 'package.json');
@ -17,51 +17,12 @@ var package = require(packagePath);
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('-H, --host <host>', 'The host to bind to');
program.option('-l, --log-file <path>', 'The file to log to');
program.option('--plugins <path>', 'Path to scan for plugins');
startupOptions(program);
pluginProgram(program);
program.parse(process.argv);
if (program.plugins) {
settings['kibana.externalPluginsFolder'] = program.plugins;
}
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.file'] = program.logFile;
}
var configPath = program.config || process.env.CONFIG_PATH;
if (configPath) {
settings = _.defaults(settings, loadSettingsFromYAML(configPath));
}
// Start the Kibana server with the settings fromt he CLI and YAML file
var kibana = new Kibana(settings);
kibana.listen()
.then(writePidFile)
.catch(function (err) {
process.exit(1);
});
if (!program.isCommandSpecified()) {
startup(program);
}

View file

@ -0,0 +1,49 @@
var _ = require('lodash');
var zlib = require('zlib');
var Promise = require('bluebird');
var request = require('request');
var tar = require('tar');
var Path = require('path');
var fs = Promise.promisifyAll(require('fs'));
var EventEmitter = require('events').EventEmitter;
module.exports = function (source, dest, downloadLogger) {
downloadLogger = downloadLogger || _.noop;
return new Promise(function (resolve, reject) {
var gunzip = zlib.createGunzip();
var progress = new EventEmitter();
var tarExtract = tar.Extract({ path: dest, strip: 1 });
request.get(source)
.on('response', function (resp) {
var total = parseInt(resp.headers['content-length'], 10);
var docInfo = {
level: 'INFO',
type: 'progress',
op: 'downloading',
total: total,
timestamp: new Date(),
message: 'Downloading ' + total + ' bytes'
};
downloadLogger(progress, docInfo);
})
.on('data', function (buffer) {
progress.emit('progress', buffer.length);
})
.on('error', reject)
.on('end', function () {
progress.emit('message', '\nDownload Complete.\n');
progress.emit('message', 'Extracting archive.\n');
})
.pipe(gunzip)
.on('error', reject)
.pipe(tarExtract)
.on('end', function () {
progress.emit('message', 'Extraction complete.\n');
resolve();
})
.on('error', reject);
});
};

View file

@ -0,0 +1,23 @@
var npm = require('npm');
var path = require('path');
var Promise = require('bluebird');
module.exports = function (dest) {
return new Promise(function (resolve, reject) {
//var cwd = process.cwd();
npm.load(function (err) {
process.chdir(dest);
var blah = path.join(dest, 'package.json');
npm.commands.install([blah], function (er, data) {
if (er) {
console.error(er);
}
//process.chdir(cwd);
});
npm.on('log', function (message) {
console.log(message);
});
});
});
};

View file

@ -0,0 +1,109 @@
module.exports = function (program) {
var expiry = require('expiry-js');
var downloadAndExpand = require('./downloadAndExpand.js');
var npmInstall = require('./npmInstall.js');
var baseUrl = 'https://s3.amazonaws.com/jimtars/';
var settings;
function parseSeconds(val) {
var result;
try {
//Is there is no unit specified, assume seconds
var re = /([a-zA-Z]+)/g;
if (!re.exec(val)) {
val += 's';
}
var timeVal = expiry(val);
result = timeVal.asSeconds();
} catch (ex) { }
return result;
}
function parseSettings(options) {
var settings = {
timeout: 0,
silent: false
};
if (options.timeout) {
settings.timeout = options.timeout;
}
if (options.silent) {
settings.silent = options.silent;
}
if (options.install) {
settings.action = 'install';
settings.plugin = options.install;
}
if (options.remove) {
settings.action = 'remove';
settings.plugin = options.remove;
}
return settings;
}
function log(message) {
if (settings.silent) return;
process.stdout.write(message);
}
function downloadLogger(progress, docInfo) {
var totalBytes = docInfo.total;
var runningTotal = 0;
log(docInfo.message + '\n');
progress.on('progress', function (data) {
runningTotal += data;
var percent = Math.round(runningTotal / totalBytes * 100);
if (percent % 10 === 0) {
log('.');
}
});
progress.on('message', function (message) {
log(message);
});
}
function processCommand(command, options) {
settings = parseSettings(command);
if (!settings.action) {
console.error('Please specify either --install or --remove.');
process.exit(1);
}
if (settings.action === 'install') {
//require('./plugin_install.js')(settings);
log('Running download and install.\n');
var sourceUrl = 'https://download.elastic.co/kibana/plugins/test-plugin-1.0.0.tgz';
var destPath = './plugins/' + settings.plugin;
downloadAndExpand(sourceUrl, destPath, downloadLogger)
.catch(function (e) {
console.error('Error installing plugin: ' + e);
})
.then(function () {
npmInstall(destPath);
});
}
}
program
.command('plugin')
.description('Maintain Plugins')
.option('-i, --install <plugin>', 'The plugin to install')
.option('-r, --remove <plugin>', 'The plugin to remove')
.option('-s, --silent', 'Disable process messaging')
.option('-t, --timeout <duration>', 'Length of time before failing; 0 for never fail', parseSeconds)
.action(processCommand);
};

View file

@ -0,0 +1,41 @@
module.exports = function (settings) {
var downloadAndExpand = require('./downloadAndExpand.js');
var npmInstall = require('./npmInstall.js');
function log(message) {
if (settings.silent) return;
process.stdout.write(message);
}
function downloadLogger(progress, docInfo) {
var totalBytes = docInfo.total;
var runningTotal = 0;
log(docInfo.message + '\n');
progress.on('progress', function (data) {
runningTotal += data;
var percent = Math.round(runningTotal / totalBytes * 100);
if (percent % 10 === 0) {
log('.');
}
});
progress.on('message', function (message) {
log(message);
});
}
log('Running download and install.\n');
var sourceUrl = 'https://download.elastic.co/kibana/plugins/test-plugin-1.0.0.tgz';
var destPath = './plugins/' + settings.plugin;
downloadAndExpand(sourceUrl, destPath, downloadLogger)
.catch(function (e) {
console.error('Error installing plugin: ' + e);
})
.then(function () {
npmInstall(destPath);
});
};

View file

@ -0,0 +1,49 @@
module.exports = function (program) {
var _ = require('lodash');
var path = require('path');
var Kibana = require('../../');
var writePidFile = require('../../lib/write_pid_file');
var loadSettingsFromYAML = require('../../lib/load_settings_from_yaml');
var settings = { 'logging.console.json': true };
function parseSettings() {
if (program.plugins) {
settings['kibana.externalPluginsFolder'] = program.plugins;
}
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.file'] = program.logFile;
}
var configPath = program.config || process.env.CONFIG_PATH;
if (configPath) {
settings = _.defaults(settings, loadSettingsFromYAML(configPath));
}
}
parseSettings();
// Start the Kibana server with the settings fromt he CLI and YAML file
var kibana = new Kibana(settings);
kibana.listen()
.then(writePidFile)
.catch(function (err) {
process.exit(1);
});
};

View file

@ -0,0 +1,9 @@
module.exports = function (program) {
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('-H, --host <host>', 'The host to bind to');
program.option('-l, --log-file <path>', 'The file to log to');
program.option('--plugins <path>', 'Path to scan for plugins');
};

View file

@ -0,0 +1,9 @@
module.exports = function (program) {
function isCommand(val) {
return typeof val === 'object' && val._name;
}
program.isCommandSpecified = function () {
return program.args.some(isCommand);
};
};