diff --git a/bin/pm2 b/bin/pm2 index f8a43413..aacfeddc 100755 --- a/bin/pm2 +++ b/bin/pm2 @@ -59,12 +59,17 @@ commander.command('stopAll') // // Stop specific id // -commander.command('stop ') - .description('stop specific process pm2 id') +commander.command('stop ') + .description('stop specific process pm2 id or script name (=script basepath)') .action(function(pm2_id) { - console.log(PREFIX_MSG + 'Stopping process ' + pm2_id); UX.processing.start(); - CLI.stopId(pm2_id); + if (isNaN(parseInt(pm2_id))) { + console.log(PREFIX_MSG + 'Stopping process by name ' + pm2_id); + CLI.stopProcessName(pm2_id); + } else { + console.log(PREFIX_MSG + 'Stopping process by id ' + pm2_id); + CLI.stopId(pm2_id); + } }); // @@ -538,6 +543,18 @@ CLI.stopAll = function() { }); }; +CLI.stopProcessName = function(name) { + Satan.executeRemote('stopProcessName', { + name : name + }, function(err, list) { + if (err) process.exit(ERROR_EXIT); + console.log('\n'); + UX.dispAsTable(list); + UX.processing.stop(); + process.exit(SUCCESS_EXIT); + }); +}; + CLI.stopId = function(pm2_id) { Satan.executeRemote('stopId', { id : pm2_id @@ -546,8 +563,8 @@ CLI.stopId = function(pm2_id) { console.log('\n' + PREFIX_MSG_ERR + pm2_id + ' : pm2 id not found'); process.exit(ERROR_EXIT); } - console.log('\n'); + UX.dispAsTable(list); console.log(PREFIX_MSG + 'Process stopped'); UX.processing.stop(); process.exit(SUCCESS_EXIT); diff --git a/lib/God.js b/lib/God.js index 68caa2be..eedd311f 100644 --- a/lib/God.js +++ b/lib/God.js @@ -146,7 +146,8 @@ God.startProcessId = function(id, cb) { }; God.stopProcess = function(clu, cb) { - if (!God.clusters_db[clu.pm_id]) return cb(); + if (!God.clusters_db[clu.pm_id]) + return cb(); if (God.clusters_db[clu.pm_id].status != 'stopped'){ process.kill(God.clusters_db[clu.pm_id].process.pid); } @@ -161,12 +162,34 @@ God.stopProcessId = function(id, cb) { process.kill(God.clusters_db[id].process.pid); God.clusters_db[id].process.pid = -1; setTimeout(function() { - cb(null, null); + cb(null, God.getFormatedProcesses()); }, 200); }; // -// Public method +// Stop a process by script name (script path basename) +// +God.stopProcessName = function(name, cb) { + var arr = Object.keys(God.clusters_db); + + (function ex(arr) { + if (arr[0] == null) return cb(null, God.getFormatedProcesses()); + var key = arr[0]; + if (p.basename(God.clusters_db[key].opts.pm_exec_path) == name) { + God.stopProcessId(key, function() { + arr.shift(); + return ex(arr); + }); + } + else { + arr.shift(); + return ex(arr); + } + })(arr); +}; + +// +// Main entrance for script execution // God.prepare = function(opts, cb) { if (opts.instances) { diff --git a/lib/Satan.js b/lib/Satan.js index 89ec4393..d78ad17a 100644 --- a/lib/Satan.js +++ b/lib/Satan.js @@ -125,9 +125,12 @@ Satan.remoteWrapper = function() { if (err) fn(new Error('Process not found')); else - fn(err, stringifyOnce(clu, undefined, 0)); + fn(err, clu); }); }, + stopProcessName : function(opts, fn) { + God.stopProcessName(opts.name, fn); + }, stopAll : function(opts, fn) { God.stopAll(fn); }, diff --git a/test/cli.sh b/test/cli.sh index a1e8bfc5..b97f6721 100755 --- a/test/cli.sh +++ b/test/cli.sh @@ -54,6 +54,37 @@ cd $file_path $pm2 kill spec "kill daemon" + +# +# Different way to stop process +# +$pm2 start echo.js +$pm2 start echo.js -f +$pm2 start echo.js -f + +OUT=`$pm2 jlist | grep -o "restart_time" | wc -l` +[ $OUT -eq 3 ] || fail "$1" +success "$1" + +$pm2 stop 0 + +OUT=`$pm2 jlist | grep -o "restart_time" | wc -l` +[ $OUT -eq 2 ] || fail "$1" +success "$1" + +$pm2 stop echo.js + +OUT=`$pm2 jlist | grep -o "restart_time" | wc -l` +[ $OUT -eq 0 ] || fail "$1" +success "$1" + + +# +# Main tests +# +$pm2 kill +spec "kill daemon" + $pm2 start eyayimfake ispec "should fail if script doesnt exist" diff --git a/test/god.mocha.js b/test/god.mocha.js index e1bcba38..07d0bde7 100644 --- a/test/god.mocha.js +++ b/test/god.mocha.js @@ -16,9 +16,32 @@ describe('God', function() { God.should.have.property('stopProcessId'); }); + describe('Special functions for God', function() { + it('should kill a process by name', function(done) { + God.prepare({ + pm_exec_path : path.resolve(process.cwd(), 'test/fixtures/echo.js'), + pm_err_log_path : path.resolve(process.cwd(), 'test/errLog.log'), + pm_out_log_path : path.resolve(process.cwd(), 'test/outLog.log'), + pm_pid_path : path.resolve(process.cwd(), 'test/child'), + instances : 2 + }, function(err, procs) { + God.getFormatedProcesses().length.should.equal(2); + + God.stopProcessName('echo.js', function() { + God.getFormatedProcesses().length.should.equal(0); + God.stopAll(done); + }); + }); + }); + }); + describe('One process', function() { var proc, pid; + before(function(done) { + God.stopAll(done); + }); + after(function(done) { God.stopAll(done); }); @@ -104,6 +127,7 @@ describe('God', function() { }, 500); }); }); + it('should cron restart', function(done) { God.prepare({ pm_exec_path : path.resolve(process.cwd(), 'test/fixtures/args.js'), @@ -122,4 +146,5 @@ describe('God', function() { }); }); + }); diff --git a/test/satan.mocha.js b/test/satan.mocha.js index b416d96f..f53d25c6 100644 --- a/test/satan.mocha.js +++ b/test/satan.mocha.js @@ -54,6 +54,7 @@ describe('Satan', function() { methods.should.have.property('list'); methods.should.have.property('stopId'); methods.should.have.property('stopAll'); + methods.should.have.property('stopProcessName'); methods.should.have.property('killMe'); methods.should.have.property('daemonData'); done();