Merge branch 'development' of github.com:Unitech/PM2 into development

This commit is contained in:
Antoine Bluchet 2015-09-03 11:03:34 +02:00
commit 05901e725f
13 changed files with 215 additions and 52 deletions

View File

@ -5,6 +5,7 @@
- New command: pm2 module:update <module_name> -> Update a module
- New command: pm2 module:publish -> Publish module in current folder + Git push
- New command: pm2 module:generate -> Generate a sample module
- Feature: configuration system for raw Node.js applications
- alias pm2 install with pm2 i
# 0.14.7

View File

@ -354,10 +354,10 @@ commander.command('module:update <module|git:// url>')
});
commander.command('module:generate')
commander.command('module:generate [app_name]')
.description('Generate a sample module in current folder')
.action(function() {
CLI.generateModuleSample();
.action(function(app_name) {
CLI.generateModuleSample(app_name);
});
commander.command('uninstall <module>')

54
examples/http.js Normal file
View File

@ -0,0 +1,54 @@
var pmx = require('pmx');
var conf = pmx.init();
var http = require('http');
http.createServer(function(req, res) {
res.writeHead(200);
res.end('hey');
}).listen(8000);
var Probe = pmx.probe();
var value_to_inspect = 0;
/**
* .metric, .counter, .meter, .histogram are also available (cf doc)
*/
var val = Probe.metric({
name : 'test-probe',
value : function() {
return value_to_inspect;
},
/**
* Here we set a default value threshold, to receive a notification
* These options can be overriden via Keymetrics or via pm2
* More: http://bit.ly/1O02aap
*/
alert : {
mode : 'threshold',
value : 20,
msg : 'test-probe alert!',
action : function(val) {
// Besides the automatic alert sent via Keymetrics
// You can also configure your own logic to do something
console.log('Value has reached %d', val);
}
}
});
setInterval(function() {
// Then we can see that this value increase over the time in Keymetrics
value_to_inspect++;
}, 300);
process.on('message', function(msg) {
if (msg == 'shutdown') {
console.log('Closing all connections...');
setTimeout(function() {
console.log('Finished closing connections');
process.exit(0);
}, 500);
}
});

View File

@ -219,6 +219,10 @@ CLI._startScript = function(script, opts, cb) {
printOut(cst.PREFIX_MSG + 'Starting %s in %s (%d instance' + (resolved_paths.instances > 1 ? 's' : '') + ')',
script, resolved_paths.exec_mode, resolved_paths.instances);
if (!resolved_paths.env) resolved_paths.env = {};
var additional_env = Modularizer.getAdditionalConf(resolved_paths.name);
util._extend(resolved_paths.env, additional_env);
Satan.executeRemote('prepare', resolved_paths, function(err, data) {
if (err) {
printError(cst.PREFIX_MSG_ERR + 'Error while launching application', err.stack || err);
@ -317,10 +321,11 @@ CLI._startJson = function(cmd, opts, jsonVia, cb) {
app.name = opts.force_name;
if (opts.started_as_module)
app.pmx_module = true;
if (opts.additional_env) {
if (!app.env) app.env = {};
util._extend(app.env, opts.additional_env);
}
if (!app.env)
app.env = {};
var additional_env = Modularizer.getAdditionalConf(app.name);
util._extend(app.env, additional_env);
mergeEnvironmentVariables(app, opts.env, deployConf);
var resolved_paths = null;
@ -1180,11 +1185,15 @@ CLI._jsonStartOrAction = function(action, json_conf, opts, cb) {
CLI._operate = function(action_name, process_name, envs, cb) {
// Make sure all options exist
if (!envs)
envs = {};
if (typeof(envs) == 'function'){
cb = envs;
envs = {};
}
/**
* Operate action on specific process id
*/
@ -1259,13 +1268,8 @@ CLI._operate = function(action_name, process_name, envs, cb) {
* Determine if the process to restart is a module
* if yes load configuration variables and merge with the current environment
*/
if (full_detail && typeof(ids[0]) !== 'undefined' && full_detail[ids[0]] &&
full_detail[ids[0]].pm2_env && full_detail[ids[0]].pm2_env.pmx_module === true) {
var additional_env = Modularizer.getAdditionalConf(process_name);
util._extend(envs, additional_env);
}
var additional_env = Modularizer.getAdditionalConf(process_name);
util._extend(envs, additional_env);
return processIds(ids, cb);
});
@ -1849,8 +1853,8 @@ CLI.publish = function(module_name, cb) {
/**
* Publish module on NPM + Git push
*/
CLI.generateModuleSample = function(cb) {
Modularizer.generateSample(function(err, data) {
CLI.generateModuleSample = function(app_name, cb) {
Modularizer.generateSample(app_name, function(err, data) {
if (err)
return cb ? cb(err) : exitCli(cst.ERROR_EXIT);
return cb ? cb(null, data) : exitCli(cst.SUCCESS_EXIT);

View File

@ -16,8 +16,7 @@ Configuration.set = function(key, value, cb) {
if (key.indexOf('.') > -1)
values = key.split('.');
if (key.indexOf(':') > -1)
else if (key.indexOf(':') > -1)
values = key.split(':');
if (values.length > 0) {
@ -66,8 +65,7 @@ Configuration.unset = function(key, cb) {
if (key.indexOf('.') > -1)
values = key.split('.');
if (key.indexOf(':') > -1)
else if (key.indexOf(':') > -1)
values = key.split(':');
if (values.length > 0) {
@ -113,8 +111,7 @@ Configuration.get = function(key, cb) {
if (key.indexOf('.') > -1)
climb = key.split('.');
if (key.indexOf(':') > -1)
else if (key.indexOf(':') > -1)
climb = key.split(':');
climb.some(function(val) {
@ -142,8 +139,7 @@ Configuration.getSync = function(key) {
if (key.indexOf('.') > -1)
climb = key.split('.');
if (key.indexOf(':') > -1)
else if (key.indexOf(':') > -1)
climb = key.split(':');
climb.some(function(val) {

View File

@ -56,18 +56,6 @@ function startModule(opts, cb) {
}
}
/**
* Attach some more arguments to applications configuration
*/
if (Array.isArray(package_json.apps) === true) {
package_json.apps.forEach(function(app) {
app.node_args = ['--harmony'];
});
}
else if (package_json.apps) {
package_json.apps.node_args = ['--harmony'];
}
/**
* Verify that the module is valid
* If not, delete
@ -78,18 +66,12 @@ function startModule(opts, cb) {
return cb({msg:'Invalid module'});
}
/**
* Only merge configuration variables for this module
*/
var additional_env = Modularizer.getAdditionalConf(package_json.name);
// Start the module
CLI.start(package_json, {
cwd : opts.proc_path,
watch : opts.development_mode,
force_name : package_json.name,
started_as_module : true,
additional_env : additional_env
started_as_module : true
}, function(err, data) {
if (err) return cb(err);
return cb(null, data);
@ -325,14 +307,13 @@ Modularizer.publish = function(cb) {
});
};
Modularizer.generateSample = function(cb) {
Modularizer.generateSample = function(app_name, cb) {
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question(cst.PREFIX_MSG_MOD + "Module name: ", function(module_name) {
function samplize(module_name) {
var cmd1 = 'git clone https://github.com/pm2-hive/sample-module.git ' + module_name + '; cd ' + module_name + '; rm -rf .git';
var cmd2 = 'cd ' + module_name + ' ; sed -i "s:sample-module:'+ module_name +':g" package.json';
var cmd3 = 'cd ' + module_name + ' ; npm install';
@ -366,7 +347,12 @@ Modularizer.generateSample = function(cb) {
});
});
});
}
if (app_name) return samplize(app_name);
rl.question(cst.PREFIX_MSG_MOD + "Module name: ", function(module_name) {
samplize(module_name);
});
};

View File

@ -163,7 +163,7 @@
"nssocket" : "0.5.3",
"pidusage" : "0.1.1",
"pmx" : "beta",
"pmx" : "latest",
"vizion" : "latest",
"pm2-axon" : "latest",

View File

@ -0,0 +1,56 @@
#!/usr/bin/env bash
SRC=$(cd $(dirname "$0"); pwd)
source "${SRC}/include.sh"
echo -e "\033[1mRunning tests:\033[0m"
cd $file_path
$pm2 unset echo
spec "Should unset echo variables"
$pm2 start echo.js --name "echo"
should 'should app be online' 'online' 1
should 'should not have config variable' "config_var: 'false'" 0
$pm2 set echo.config_var false
exists 'should NOW have config variable' "config_var: 'false'"
$pm2 set echo.probes false
exists 'should NOW have config variable' "config_var: 'false'"
$pm2 delete all
#
#
#
#
$pm2 unset "probe-test"
$pm2 start probes.js --name "probe-test"
echo "Wait for init..."
sleep 1
exists 'probe test-probe exist' "test-probe"
exists 'probe Loop delay exist' "Loop delay"
exists 'probe Loop delay default value' "agg_type: 'avg', alert: {} }"
# Set new value for alert probe
$pm2 set probe-test.probes.Loop\ delay.value 25
sleep 1
exists 'probe Loop delay alerted' "alert: { mode: 'threshold', value: 25, cmp: '>' } } }"
# Override value for test-probe
$pm2 set probe-test.probes.test-probe.value 30
sleep 2
exists 'probe Loop delay alerted' "alert: { mode: 'threshold', value: 30, cmp: '>' } }"

View File

@ -213,7 +213,7 @@ $pm2 kill
PROC_NAME='ECHONEST'
# Launch a script with name option
$pm2 start echo.js --name $PROC_NAME -f
should 'should have started app with name' 'ECHONEST' 5
should 'should have started app with name' 'ECHONEST' 7
# Restart a process by name
$pm2 restart $PROC_NAME

View File

@ -72,3 +72,11 @@ function shouldnot {
[ $OUT -ne $3 ] || fail "$1"
success "$1"
}
function exists {
sleep 0.5
$pm2 prettylist > /tmp/tmp_out.txt
OUT=`cat /tmp/tmp_out.txt | grep -o "$2" | wc -l`
[ $OUT -ge 1 ] || fail "$1"
success "$1"
}

View File

@ -33,7 +33,7 @@ spec "Module should be installed"
# Should configuration variable be present two times
# one time in the raw env, and a second time prefixed with the module name
#
should 'should have config variable' "config1xxx: 'true'" 4
exists 'should have config variable' "config1xxx: 'true'" 4
#
# Change variable value
@ -43,7 +43,7 @@ $pm2 set 'pm2-probe:config1xxx' false
sleep 1
should 'should have config variable' "config1xxx: 'false'" 4
exists 'should have config variable' "config1xxx: 'false'" 4
$pm2 update
spec "Should update succesfully"

55
test/fixtures/probes.js vendored Normal file
View File

@ -0,0 +1,55 @@
var pmx = require('pmx');
var conf = pmx.init();
var http = require('http');
http.createServer(function(req, res) {
res.writeHead(200);
res.end('hey');
}).listen(8000);
var Probe = pmx.probe();
var value_to_inspect = 0;
/**
* .metric, .counter, .meter, .histogram are also available (cf doc)
*/
var val = Probe.metric({
name : 'test-probe',
value : function() {
return value_to_inspect;
},
/**
* Here we set a default value threshold, to receive a notification
* These options can be overriden via Keymetrics or via pm2
* More: http://bit.ly/1O02aap
*/
alert : {
mode : 'threshold',
value : 20,
msg : 'test-probe alert!',
action : function(val) {
// Besides the automatic alert sent via Keymetrics
// You can also configure your own logic to do something
console.log('Value has reached %d', val);
}
}
});
setInterval(function() {
// Then we can see that this value increase over the time in Keymetrics
value_to_inspect++;
}, 30);
process.on('message', function(msg) {
if (msg == 'shutdown') {
console.log('Closing all connections...');
setTimeout(function() {
console.log('Finished closing connections');
process.exit(0);
}, 500);
}
});

View File

@ -21,8 +21,9 @@ echo "###################### !DEBUG! ###########################"
bash ./test/bash/file-descriptor.sh
spec "testing file descriptors"
bash ./test/bash/pmx_injection.sh
spec "automatic pmx injection"
# Automatic PMX http disabled
# bash ./test/bash/pmx_injection.sh
# spec "automatic pmx injection"
bash ./test/bash/log-timestamp.sh
spec "timetstamp prefix of pm2.log"
bash ./test/bash/smart-start.sh
@ -77,6 +78,8 @@ bash ./test/bash/vizion.sh
spec "vizion features (versioning control)"
bash ./test/bash/wrapped_fork.sh
spec "wrapped fork"
bash ./test/bash/app_configuration.sh
spec "App configuration"
bash ./test/bash/inside-pm2.sh
spec "Starting a process inside a PM2 process"