mirror of
https://github.com/Unitech/pm2.git
synced 2025-12-08 20:35:53 +00:00
#136 add smart interpreter selection and execution mode depending on filename extension
This commit is contained in:
commit
10d39704ec
@ -1,4 +1,9 @@
|
||||
|
||||
# 0.6.8
|
||||
|
||||
- Homogeneize JSON #186
|
||||
- Auto intepreter selection (you can do pm2 start app.php)
|
||||
|
||||
# 0.5.6
|
||||
|
||||
- Coffeescript support
|
||||
@ -11,10 +16,10 @@
|
||||
- with the --name option when launching file
|
||||
- with the "name" parameter for JSON files
|
||||
- Ability to restart a script by name + tests
|
||||
- Upgrade node-usage to 0.3.8 - fix monitoring feedback for MacOSx
|
||||
- Upgrade node-usage to 0.3.8 - fix monitoring feedback for MacOSx
|
||||
- require.main now require the right file (activate it by modifying MODIFY_REQUIRE in constants.js)
|
||||
- CentOS startup script with pm2 startup centos
|
||||
- 0 downtime reload
|
||||
- 0 downtime reload
|
||||
|
||||
# 0.5.4
|
||||
|
||||
|
||||
8
examples/echo.php
Normal file
8
examples/echo.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
while (1) {
|
||||
echo 'lol i hate php !';
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
?>
|
||||
15
lib/CLI.js
15
lib/CLI.js
@ -12,6 +12,7 @@ var Satan = require('./Satan');
|
||||
var Common = require('./Common');
|
||||
var cst = require('../constants.js');
|
||||
var pkg = require('../package.json');
|
||||
var extItps = require('./interpreter.json');
|
||||
|
||||
var CLI = module.exports = {};
|
||||
require('colors');
|
||||
@ -35,16 +36,21 @@ CLI.startFile = function(script) {
|
||||
if (commander.cron)
|
||||
appConf['cron_restart'] = commander.cron;
|
||||
|
||||
if (commander.interpreter)
|
||||
appConf['exec_interpreter'] = commander.interpreter;
|
||||
else
|
||||
appConf['exec_interpreter'] = 'node';
|
||||
|
||||
if (commander.executeCommand)
|
||||
appConf['exec_mode'] = 'fork_mode';
|
||||
else
|
||||
appConf['exec_mode'] = 'cluster_mode';
|
||||
|
||||
if (commander.interpreter)
|
||||
appConf['exec_interpreter'] = commander.interpreter;
|
||||
else if (extItps[path.extname(script)]) {
|
||||
appConf['exec_interpreter'] = extItps[path.extname(script)];
|
||||
appConf['exec_mode'] = 'fork_mode';
|
||||
}
|
||||
else
|
||||
appConf['exec_interpreter'] = 'node';
|
||||
|
||||
if (commander.startOneTime)
|
||||
appConf['one_launch_only'] = cst.ONE_LAUNCH_STATUS;
|
||||
|
||||
@ -518,6 +524,5 @@ function resolvePaths(appConf) {
|
||||
console.error(cst.PREFIX_MSG_ERR + app.message);
|
||||
process.exit(cst.ERROR_EXIT);
|
||||
}
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ UX.dispAsTable = function(list) {
|
||||
head: ["App Name", "id", "mode","PID","status", "port", "Restarted", "Uptime", "memory", "err logs"],
|
||||
colAligns : ['left', 'left', 'left', 'left','left', 'left', 'right', 'left', 'right']
|
||||
});
|
||||
|
||||
|
||||
list.forEach(function(l) {
|
||||
var obj = {};
|
||||
|
||||
@ -18,7 +18,7 @@ UX.dispAsTable = function(list) {
|
||||
var status = l.pm2_env.status;
|
||||
var port = l.pm2_env.port;
|
||||
var key = l.pm2_env.name.bold || p.basename(l.pm2_env.pm_exec_path.script).bold;
|
||||
|
||||
|
||||
obj[key] = [
|
||||
l.pm2_env.pm_id,
|
||||
mode == 'fork' ? 'fork'.inverse.bold : 'cluster'.blue.bold,
|
||||
|
||||
@ -12,7 +12,7 @@ var cst = require('../constants.js');
|
||||
/**
|
||||
* Common methods (used by CLI and God)
|
||||
*/
|
||||
|
||||
|
||||
var Common = module.exports;
|
||||
|
||||
/**
|
||||
@ -25,12 +25,12 @@ var Common = module.exports;
|
||||
Common.resolveAppPaths = function(app, cwd, outputter) {
|
||||
|
||||
var err = Common.validateApp(app, outputter);
|
||||
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
||||
cwd = cwd || process.cwd();
|
||||
|
||||
|
||||
app.env = {
|
||||
pm_cwd: cwd
|
||||
};
|
||||
@ -46,7 +46,7 @@ Common.resolveAppPaths = function(app, cwd, outputter) {
|
||||
|
||||
|
||||
if (fs.existsSync(app.pm_exec_path) == false) {
|
||||
return new Error('script not found : ' + app.pm_exec_path)
|
||||
return new Error('script not found : ' + app.pm_exec_path);
|
||||
}
|
||||
|
||||
if (app.out_file)
|
||||
@ -109,6 +109,6 @@ Common.validateApp = function(appConf, outputter) {
|
||||
return new Error('Cron pattern is not valid !');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
};
|
||||
};
|
||||
|
||||
@ -141,6 +141,7 @@ function forkMode(pm2_env, cb) {
|
||||
var spawn = require('child_process').spawn;
|
||||
|
||||
var interpreter = pm2_env.exec_interpreter || 'node';
|
||||
|
||||
var script = [pm2_env.pm_exec_path];
|
||||
|
||||
var out = fs.openSync(pm2_env.pm_out_log_path, 'a');
|
||||
|
||||
@ -19,7 +19,7 @@ http.createServer(function (req, res) {
|
||||
|
||||
console.log('Access on PM2 monit point %s', path);
|
||||
|
||||
|
||||
|
||||
if (path == '/') {
|
||||
// Main monit route
|
||||
Satan.executeRemote('getMonitorData', {}, function(err, data_proc) {
|
||||
@ -35,7 +35,7 @@ http.createServer(function (req, res) {
|
||||
},
|
||||
processes: data_proc
|
||||
};
|
||||
|
||||
|
||||
res.write(JSON.stringify(data));
|
||||
return res.end();
|
||||
});
|
||||
|
||||
18
lib/Monit.js
18
lib/Monit.js
@ -1,5 +1,5 @@
|
||||
// pm2-htop
|
||||
// Library who interacts with PM2 to display processes resources in htop way
|
||||
// Library who interacts with PM2 to display processes resources in htop way
|
||||
// by Strzelewicz Alexandre
|
||||
|
||||
var multimeter = require('pm2-multimeter');
|
||||
@ -24,10 +24,10 @@ var Monit = module.exports = {};
|
||||
Monit.init = function(processes, debug) {
|
||||
if (processes === undefined || processes[0] == null)
|
||||
throw new Error('No processes passed to init');
|
||||
|
||||
|
||||
if (!processes[0].monit)
|
||||
throw new Error('No monit assigned to processes');
|
||||
|
||||
|
||||
if (processes[0].monit.error)
|
||||
throw new Error(JSON.stringify(processes[0].monit.error));
|
||||
|
||||
@ -46,9 +46,9 @@ Monit.init = function(processes, debug) {
|
||||
var status = proc.pm2_env.status == 'online' ? '●'.green.bold : '●'.red.bold;
|
||||
|
||||
Monit.multi.write(' ' + status + ' ' + process_name.green.bold);
|
||||
Monit.multi.write('\n');
|
||||
Monit.multi.write('\n');
|
||||
Monit.multi.write('[' + proc.pm2_env.pm_id + '] [' + proc.pm2_env.exec_mode + ']\n');
|
||||
|
||||
|
||||
var bar_cpu = Monit.multi(40, (i * 2) + 3 + i, {
|
||||
width: 30,
|
||||
solid: {
|
||||
@ -75,7 +75,7 @@ Monit.init = function(processes, debug) {
|
||||
|
||||
bar_cpu.percent(proc.monit.cpu);
|
||||
Monit.drawRatio(bar_memory, proc.monit.memory);
|
||||
|
||||
|
||||
bars[proc.pid] = {};
|
||||
bars[proc.pid].memory = bar_memory;
|
||||
bars[proc.pid].cpu = bar_cpu;
|
||||
@ -95,7 +95,7 @@ Monit.drawRatio = function(bar_memory, memory) {
|
||||
else if (memory < RATIO_T2) scale = RATIO_T2;
|
||||
else if (memory < RATIO_T3) scale = RATIO_T3;
|
||||
else scale = RATIO_T4;
|
||||
|
||||
|
||||
bar_memory.ratio(memory,
|
||||
scale,
|
||||
CliUx.bytesToSize(memory, 3));
|
||||
@ -104,10 +104,10 @@ Monit.drawRatio = function(bar_memory, memory) {
|
||||
Monit.refresh = function(dt) {
|
||||
dt.forEach(function(proc, i) {
|
||||
if (proc && proc.monit && bars[proc.pid]) {
|
||||
|
||||
|
||||
bars[proc.pid].cpu.percent(proc.monit.cpu);
|
||||
Monit.drawRatio(bars[proc.pid].memory, proc.monit.memory);
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@ -15,27 +15,27 @@ require('coffee-script');
|
||||
|
||||
(function ProcessContainer() {
|
||||
var fs = require('fs');
|
||||
var worker = require('cluster').worker;
|
||||
|
||||
var worker = require('cluster').worker;
|
||||
|
||||
var outFile = process.env.pm_out_log_path;
|
||||
var errFile = process.env.pm_err_log_path;
|
||||
var pmId = process.env.pm_id;
|
||||
var pidFile = [process.env.pm_pid_path, pmId, '.pid'].join('');
|
||||
var script = process.env.pm_exec_path;
|
||||
var cronRestart = process.env.cron_restart;
|
||||
|
||||
|
||||
if (cst.MODIFY_REQUIRE)
|
||||
require.main.filename = process.env.pm_exec_path;
|
||||
|
||||
|
||||
|
||||
fs.writeFileSync(pidFile, process.pid);
|
||||
|
||||
|
||||
process.on('exit', function () {
|
||||
try {
|
||||
fs.unlinkSync(pidFile);
|
||||
}catch(e) {}
|
||||
});
|
||||
|
||||
|
||||
// Add args to process if args specified on start
|
||||
if (process.env.args != null)
|
||||
process.argv = process.argv.concat(eval(process.env.args));
|
||||
@ -45,7 +45,7 @@ require('coffee-script');
|
||||
process.title = 'pm2: ' + process.env.name;
|
||||
|
||||
exec(script, outFile, errFile);
|
||||
|
||||
|
||||
if (cronRestart)
|
||||
cronize(cronRestart);
|
||||
})();
|
||||
@ -66,7 +66,7 @@ function cronize(cron_pattern) {
|
||||
}
|
||||
|
||||
function exec(script, outFile, errFile) {
|
||||
// Change dir to fix process.cwd
|
||||
// Change dir to fix process.cwd
|
||||
process.chdir(process.env.PWD || p.dirname(script));
|
||||
|
||||
var stderr, stdout;
|
||||
@ -89,7 +89,7 @@ function exec(script, outFile, errFile) {
|
||||
stdout.write(string);
|
||||
};
|
||||
})(process.stdout.write);
|
||||
|
||||
|
||||
process.on('uncaughtException', function(err) {
|
||||
stderr.write(err.stack);
|
||||
|
||||
@ -98,7 +98,7 @@ function exec(script, outFile, errFile) {
|
||||
type : 'uncaughtException',
|
||||
stack : err.stack
|
||||
});
|
||||
|
||||
|
||||
process.exit(cst.CODE_UNCAUGHTEXCEPTION);
|
||||
});
|
||||
|
||||
|
||||
12
lib/Satan.js
12
lib/Satan.js
@ -27,7 +27,7 @@ var cst = require('../constants.js');
|
||||
|
||||
var Satan = module.exports = {};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Code switcher
|
||||
* It will switch between Daemon part and Client part
|
||||
*
|
||||
@ -68,7 +68,7 @@ Satan.onReady = function() {
|
||||
*/
|
||||
|
||||
Satan.remoteWrapper = function() {
|
||||
|
||||
|
||||
if (process.env.SILENT == "true") {
|
||||
// Redirect output to files
|
||||
var stdout = fs.createWriteStream(cst.PM2_LOG_FILE_PATH, {
|
||||
@ -132,12 +132,12 @@ Satan.remoteWrapper = function() {
|
||||
|
||||
debug('Daemon lauched bind on port %s addr %s', cst.DAEMON_PUB_PORT, cst.DAEMON_BIND_HOST);
|
||||
pub.bind(cst.DAEMON_PUB_PORT, cst.DAEMON_BIND_HOST);
|
||||
|
||||
|
||||
God.bus.onAny(function(data) {
|
||||
debug(this.event);
|
||||
pub.emit(this.event, data);
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@ -158,7 +158,7 @@ Satan.launchDaemon = function(cb) {
|
||||
debug('Launching daemon');
|
||||
|
||||
var SatanJS = p.resolve(p.dirname(module.filename), 'Satan.js');
|
||||
|
||||
|
||||
var child = require("child_process").fork(SatanJS, [], {
|
||||
silent : false,
|
||||
detached : true,
|
||||
@ -219,7 +219,7 @@ Satan.launchRPC = function() {
|
||||
Satan.ev = req.connect(cst.DAEMON_RPC_PORT, cst.DAEMON_BIND_HOST);
|
||||
Satan.ev.on('connect', function() {
|
||||
debug('Connected to Daemon');
|
||||
|
||||
|
||||
process.emit('satan:client:ready');
|
||||
});
|
||||
};
|
||||
|
||||
8
lib/interpreter.json
Normal file
8
lib/interpreter.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
".coffee": "coffee",
|
||||
".sh": "bash",
|
||||
".py": "python",
|
||||
".rb": "ruby",
|
||||
".php": "php",
|
||||
".go": "go"
|
||||
}
|
||||
@ -16,6 +16,9 @@
|
||||
}, {
|
||||
"name" : "Devo.ps",
|
||||
"email" : "contact@devo.ps"
|
||||
},{
|
||||
"name" : "Bret Copeland",
|
||||
"email" : "bret@atlantisflight.org"
|
||||
}, {
|
||||
"name" : "John Hurliman",
|
||||
"email" : "jhurliman@jhurliman.org"
|
||||
|
||||
17
test/cli2.sh
17
test/cli2.sh
@ -49,18 +49,15 @@ function ispec {
|
||||
success "$1"
|
||||
}
|
||||
|
||||
|
||||
function should()
|
||||
{
|
||||
function should {
|
||||
OUT=`$pm2 prettylist | grep -o "$2" | wc -l`
|
||||
[ $OUT -eq $3 ] || fail "$1"
|
||||
success "$1"
|
||||
|
||||
}
|
||||
|
||||
cd $file_path
|
||||
|
||||
########## TEST
|
||||
############# TEST
|
||||
|
||||
echo -e "\033[1mRunning tests:\033[0m"
|
||||
|
||||
@ -109,7 +106,7 @@ should 'should app be stopped' 'stopped' 1
|
||||
$pm2 start test/fixtures/echo.js
|
||||
should 'should app be online' 'online' 1
|
||||
|
||||
cd -
|
||||
cd -
|
||||
|
||||
###############
|
||||
$pm2 kill
|
||||
@ -124,7 +121,7 @@ should 'should restart a second time (BY SCRIPT NAME)' 'restart_time: 2' 4
|
||||
$pm2 restart child
|
||||
should 'should restart a third time (BY NAME)' 'restart_time: 3' 4
|
||||
$pm2 reload all
|
||||
should 'should RELOAD a fourd time' 'restart_time: 4' 4
|
||||
should 'should RELOAD a fourth time' 'restart_time: 4' 4
|
||||
|
||||
|
||||
########### DELETED STUFF BY ID
|
||||
@ -132,14 +129,14 @@ $pm2 kill
|
||||
|
||||
$pm2 start echo.js
|
||||
$pm2 delete 0
|
||||
should 'should has been deleted process by id' '' 0
|
||||
should 'should has been deleted process by id' "name: 'echo'" 0
|
||||
|
||||
########### DELETED STUFF BY NAME
|
||||
$pm2 kill
|
||||
|
||||
$pm2 start echo.js --name test
|
||||
$pm2 delete test
|
||||
should 'should has been deleted process by name' '' 0
|
||||
should 'should has been deleted process by name' "name: 'test'" 0
|
||||
|
||||
########### DELETED STUFF BY SCRIPT
|
||||
$pm2 kill
|
||||
@ -147,7 +144,7 @@ $pm2 kill
|
||||
$pm2 start echo.js
|
||||
$pm2 delete echo.js
|
||||
$pm2 list
|
||||
should 'should has been deleted process by script' '' 0
|
||||
should 'should has been deleted process by script' "name: 'echo'" 0
|
||||
|
||||
|
||||
########### OPTIONS OUTPUT FILES
|
||||
|
||||
3
test/fixtures/echo.coffee
vendored
Normal file
3
test/fixtures/echo.coffee
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env coffee
|
||||
|
||||
setInterval (-> console.log 'ok'), 500
|
||||
12
test/fork.sh
12
test/fork.sh
@ -49,13 +49,10 @@ function ispec {
|
||||
success "$1"
|
||||
}
|
||||
|
||||
|
||||
function should()
|
||||
{
|
||||
function should {
|
||||
OUT=`$pm2 prettylist | grep -o "$2" | wc -l`
|
||||
[ $OUT -eq $3 ] || fail "$1"
|
||||
success "$1"
|
||||
|
||||
}
|
||||
|
||||
cd $file_path
|
||||
@ -75,6 +72,13 @@ $pm2 kill
|
||||
$pm2 start bashscript.sh -x --interpreter bash
|
||||
should 'should has forked app' 'fork' 1
|
||||
|
||||
########### Auto Detective Interpreter In Fork mode
|
||||
|
||||
$pm2 kill
|
||||
|
||||
$pm2 start echo.coffee -x
|
||||
should 'should has forked app' 'fork' 1
|
||||
|
||||
### Dump resurect should be ok
|
||||
$pm2 dump
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user