diff --git a/.travis.yml b/.travis.yml
index d76fc89cc..25b0a3678 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,7 +4,6 @@ node_js:
- "4"
- "6"
- "8"
- - "0.12"
os:
- linux
before_install:
diff --git a/README.md b/README.md
index 1ef3279ae..3b07141dd 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@
-
+
@@ -70,6 +70,21 @@ Your app is now daemonized, monitored and kept alive forever.
[More about Process Management](http://pm2.keymetrics.io/docs/usage/process-management/)
+### Container Support
+
+With the drop-in replacement command for `node`, called `pm2-runtime`, run your Node.js application in a proper production environment.
+We also offer an [officialy supported Docker image](https://hub.docker.com/r/keymetrics/pm2/).
+
+Using it is seamless:
+
+```
+FROM keymetrics/pm2:latest-alpine
+[...]
+CMD [ "pm2-runtime", "npm", "--", "start" ]
+```
+
+[Read More about the dedicated integration](http://pm2.keymetrics.io/docs/usage/docker-pm2-nodejs/)
+
### Managing a Process
Once applications are started you can manage them easily:
@@ -130,21 +145,6 @@ Seamlessly supported by all major Node.js frameworks and any Node.js application
[More informations about how PM2 make clustering easy](https://keymetrics.io/2015/03/26/pm2-clustering-made-easy/)
-### Container Support
-
-With the drop-in replacement command for `node`, called `pm2-runtime`, run your Node.js application in a proper production environment.
-We also offer an [officialy supported Docker image](https://hub.docker.com/r/keymetrics/pm2/).
-
-Using it is seamless:
-
-```
-FROM keymetrics/pm2:latest-alpine
-[...]
-CMD [ "pm2-runtime", "npm", "--", "start" ]
-```
-
-[Read More about the dedicated integration](http://pm2.keymetrics.io/docs/usage/docker-pm2-nodejs/)
-
### Terminal Based Monitoring
![Monit](https://github.com/Unitech/pm2/raw/master/pres/pm2-monit.png)
@@ -293,7 +293,6 @@ $ pm2 reset [app-name] # Reset all counters
$ pm2 stop all # Stop all apps
$ pm2 stop 0 # Stop process with id 0
$ pm2 restart all # Restart all apps
-$ pm2 gracefulReload all # Gracefully reload all apps in cluster mode
$ pm2 delete all # Kill and delete all apps
$ pm2 delete 0 # Delete app with id 0
diff --git a/bin/pm2 b/bin/pm2
index 05072f4bc..840dc84c6 100755
--- a/bin/pm2
+++ b/bin/pm2
@@ -155,7 +155,7 @@ function checkCompletion(){
return data.short;
}), data);
// array containing commands after which process name should be listed
- var cmdProcess = ['stop', 'restart', 'scale', 'reload', 'gracefulReload', 'delete', 'reset', 'pull', 'forward', 'backward', 'logs', 'describe', 'desc', 'show'];
+ var cmdProcess = ['stop', 'restart', 'scale', 'reload', 'delete', 'reset', 'pull', 'forward', 'backward', 'logs', 'describe', 'desc', 'show'];
if (cmdProcess.indexOf(data.prev) > -1) {
pm2.list(function(err, list){
@@ -390,21 +390,19 @@ commander.command('reload ')
pm2.reload(pm2_id, commander);
});
-//
-// Reload process(es)
-//
-commander.command('gracefulReload ')
- .description('gracefully reload a process. Send a "shutdown" message to close all connections.')
- .action(function(pm2_id) {
- pm2.gracefulReload(pm2_id, commander);
- });
-
commander.command('id ')
.description('get process id by name')
.action(function(name) {
pm2.getProcessIdByName(name);
});
+// Inspect a process
+commander.command('inspect ')
+ .description('inspect a process')
+ .action(function(cmd) {
+ pm2.inspect(cmd, commander);
+ });
+
//
// Stop and delete a process by name from database
//
@@ -612,6 +610,15 @@ commander.command('dump')
pm2.dump();
}));
+//
+// Delete dump file
+//
+commander.command('cleardump')
+ .description('Create empty dump file')
+ .action(failOnUnknown(function() {
+ pm2.clearDump();
+ }));
+
//
// Save processes to file
//
@@ -891,15 +898,6 @@ commander.command('backward ')
pm2.backward(pm2_name);
});
-//
-// Force PM2 to trigger garbage collection
-//
-commander.command('gc')
- .description('force PM2 to trigger garbage collection')
- .action(function() {
- pm2.forceGc();
- });
-
//
// Perform a deep update of PM2
//
diff --git a/examples/misc-examples/graceful-exit.js b/examples/misc-examples/graceful-exit.js
index df593d447..a35fc3e85 100644
--- a/examples/misc-examples/graceful-exit.js
+++ b/examples/misc-examples/graceful-exit.js
@@ -2,7 +2,7 @@
/*
* Example of graceful exit
*
- * $ pm2 gracefulReload all
+ * $ pm2 reload all
*/
process.on('message', function(msg) {
diff --git a/examples/sourcemap-auto-resolve/API.js b/examples/sourcemap-auto-resolve/API.js
index ed62bdecb..544138794 100644
--- a/examples/sourcemap-auto-resolve/API.js
+++ b/examples/sourcemap-auto-resolve/API.js
@@ -399,33 +399,6 @@ API.prototype.update = function(cb) {
return false;
};
-/**
- * Graceful Reload an application
- *
- * @param {String} process_name Application Name or All
- * @param {Object} opts Options
- * @param {Function} cb Callback
- */
-API.prototype.gracefulReload = function(process_name, opts, cb) {
- var that = this;
-
- if (typeof(opts) == "function") {
- cb = opts;
- opts = {};
- }
-
- //Common.printOut(conf.PREFIX_MSG_WARNING + chalk.bold.yellow('Warning gracefulReload will be soon deprecated'));
- //Common.printOut(conf.PREFIX_MSG_WARNING + chalk.bold.yellow('Use http://pm2.keymetrics.io/docs/usage/signals-clean-restart/ instead'));
-
- if (Common.isConfigFile(process_name))
- that._startJson(process_name, commander, 'softReloadProcessId');
- else {
- if (opts && !opts.updateEnv)
- Common.printOut(IMMUTABLE_MSG);
- that._operate('softReloadProcessId', process_name, opts, cb);
- }
-};
-
/**
* Reload an application
*
diff --git a/lib/API.js b/lib/API.js
index 59bc227f1..0296c2d31 100644
--- a/lib/API.js
+++ b/lib/API.js
@@ -3,15 +3,16 @@
* Use of this source code is governed by a license that
* can be found in the LICENSE file.
*/
+'use strict';
-var commander = require('commander');
-var fs = require('fs');
-var path = require('path');
-var async = require('async');
-var debug = require('debug')('pm2:cli');
-var util = require('util');
-var chalk = require('chalk');
-var fclone = require('fclone');
+const commander = require('commander');
+const fs = require('fs');
+const path = require('path');
+const async = require('async');
+const debug = require('debug')('pm2:cli');
+const util = require('util');
+const chalk = require('chalk');
+const fclone = require('fclone');
var conf = require('../constants.js');
var Client = require('./Client');
@@ -45,366 +46,351 @@ var IMMUTABLE_MSG = chalk.bold.blue('Use --update-env to update environment vari
* @param {String} [opts.secret_key=null] keymetrics bucket secret key
* @param {String} [opts.machine_name=null] keymetrics instance name
*/
-var API = module.exports = function(opts) {
- if (!opts) opts = {};
- var that = this;
+class API {
- this.daemon_mode = typeof(opts.daemon_mode) == 'undefined' ? true : opts.daemon_mode;
- this.pm2_home = conf.PM2_ROOT_PATH;
- this.public_key = process.env.KEYMETRICS_SECRET || opts.public_key || null;
- this.secret_key = process.env.KEYMETRICS_PUBLIC || opts.secret_key || null;
- this.machine_name = process.env.INSTANCE_NAME || opts.machine_name || null
+ constructor (opts) {
+ if (!opts) opts = {};
+ const that = this;
- /**
- * CWD resolution
- */
- this.cwd = process.cwd();
- if (opts.cwd) {
- this.cwd = path.resolve(opts.cwd);
- }
+ this.daemon_mode = typeof(opts.daemon_mode) == 'undefined' ? true : opts.daemon_mode;
+ this.pm2_home = conf.PM2_ROOT_PATH;
+ this.public_key = process.env.KEYMETRICS_SECRET || opts.public_key || null;
+ this.secret_key = process.env.KEYMETRICS_PUBLIC || opts.secret_key || null;
+ this.machine_name = process.env.INSTANCE_NAME || opts.machine_name || null
- /**
- * PM2 HOME resolution
- */
- if (opts.pm2_home && opts.independent == true)
- throw new Error('You cannot set a pm2_home and independent instance in same time');
+ /**
+ * CWD resolution
+ */
+ this.cwd = process.cwd();
+ if (opts.cwd) {
+ this.cwd = path.resolve(opts.cwd);
+ }
- if (opts.pm2_home) {
- // Override default conf file
- this.pm2_home = opts.pm2_home;
- conf = util._extend(conf, path_structure(this.pm2_home));
- }
- else if (opts.independent == true && conf.IS_WINDOWS === false) {
- // Create an unique pm2 instance
- var crypto = require('crypto');
- var random_file = crypto.randomBytes(8).toString('hex');
- this.pm2_home = path.join('/tmp', random_file);
-
- // If we dont explicitly tell to have a daemon
- // It will go as in proc
- if (typeof(opts.daemon_mode) == 'undefined')
- this.daemon_mode = false;
- conf = util._extend(conf, path_structure(this.pm2_home));
- }
+ /**
+ * PM2 HOME resolution
+ */
+ if (opts.pm2_home && opts.independent == true)
+ throw new Error('You cannot set a pm2_home and independent instance in same time');
- this._conf = conf;
+ if (opts.pm2_home) {
+ // Override default conf file
+ this.pm2_home = opts.pm2_home;
+ conf = util._extend(conf, path_structure(this.pm2_home));
+ }
+ else if (opts.independent == true && conf.IS_WINDOWS === false) {
+ // Create an unique pm2 instance
+ const crypto = require('crypto');
+ const random_file = crypto.randomBytes(8).toString('hex');
+ this.pm2_home = path.join('/tmp', random_file);
+
+ // If we dont explicitly tell to have a daemon
+ // It will go as in proc
+ if (typeof(opts.daemon_mode) == 'undefined')
+ this.daemon_mode = false;
+ conf = util._extend(conf, path_structure(this.pm2_home));
+ }
- if (conf.IS_WINDOWS) {
- // Weird fix, may need to be dropped
- // @todo windows connoisseur double check
- if (process.stdout._handle && process.stdout._handle.setBlocking)
- process.stdout._handle.setBlocking(true);
- }
+ this._conf = conf;
- this.Client = new Client({
- pm2_home : that.pm2_home,
- conf : this._conf,
- secret_key : this.secret_key,
- public_key : this.public_key,
- daemon_mode : this.daemon_mode,
- machine_name : this.machine_name
- });
-
- this.gl_interact_infos = null;
- this.gl_is_km_linked = false;
-
- try {
- var pid = fs.readFileSync(conf.INTERACTOR_PID_PATH);
- pid = parseInt(pid.toString().trim());
- process.kill(pid, 0);
- that.gl_is_km_linked = true;
- } catch(e) {
- that.gl_is_km_linked = false;
- }
+ if (conf.IS_WINDOWS) {
+ // Weird fix, may need to be dropped
+ // @todo windows connoisseur double check
+ if (process.stdout._handle && process.stdout._handle.setBlocking)
+ process.stdout._handle.setBlocking(true);
+ }
- // For testing purposes
- if (this.secret_key && process.env.NODE_ENV == 'local_test')
- that.gl_is_km_linked = true;
+ this.Client = new Client({
+ pm2_home: that.pm2_home,
+ conf: this._conf,
+ secret_key: this.secret_key,
+ public_key: this.public_key,
+ daemon_mode: this.daemon_mode,
+ machine_name: this.machine_name
+ });
- KMDaemon.getInteractInfo(this._conf, function(i_err, interact) {
- that.gl_interact_infos = interact;
- });
-};
+ this.gl_interact_infos = null;
+ this.gl_is_km_linked = false;
+ try {
+ const pid = fs.readFileSync(conf.INTERACTOR_PID_PATH);
+ pid = parseInt(pid.toString().trim());
+ process.kill(pid, 0);
+ that.gl_is_km_linked = true;
+ } catch (e) {
+ that.gl_is_km_linked = false;
+ }
-//////////////////////////
-// Load all API methods //
-//////////////////////////
+ // For testing purposes
+ if (this.secret_key && process.env.NODE_ENV == 'local_test')
+ that.gl_is_km_linked = true;
-require('./API/Extra.js')(API);
-require('./API/Interaction.js')(API);
-require('./API/Deploy.js')(API);
-require('./API/Modules/Modules.js')(API);
-require('./API/Keymetrics/cli-api.js')(API);
-require('./API/Configuration.js')(API);
-require('./API/Version.js')(API);
-require('./API/Startup.js')(API);
-require('./API/LogManagement.js')(API);
-require('./API/Containerizer.js')(API);
+ KMDaemon.getInteractInfo(this._conf, function (i_err, interact) {
+ that.gl_interact_infos = interact;
+ });
-/**
- * Connect to PM2
- * Calling this command is now optional
- *
- * @param {Function} cb callback once pm2 is ready for commands
- */
-API.prototype.connect = function(noDaemon, cb) {
- var that = this;
- this.start_timer = new Date();
-
- if (typeof(cb) == 'undefined') {
- cb = noDaemon;
- noDaemon = false;
- } else if (noDaemon === true) {
- // Backward compatibility with PM2 1.x
- this.Client.daemon_mode = false;
- this.daemon_mode = false;
+ this.gl_retry = 0;
}
- this.Client.start(function(err, meta) {
- if (err)
- return cb(err);
+ /**
+ * Connect to PM2
+ * Calling this command is now optional
+ *
+ * @param {Function} cb callback once pm2 is ready for commands
+ */
+ connect (noDaemon, cb) {
+ var that = this;
+ this.start_timer = new Date();
+
+ if (typeof(cb) == 'undefined') {
+ cb = noDaemon;
+ noDaemon = false;
+ } else if (noDaemon === true) {
+ // Backward compatibility with PM2 1.x
+ this.Client.daemon_mode = false;
+ this.daemon_mode = false;
+ }
+
+ this.Client.start(function(err, meta) {
+ if (err)
+ return cb(err);
- if (meta.new_pm2_instance == false && that.daemon_mode === true)
- return cb(err, meta);
+ if (meta.new_pm2_instance == false && that.daemon_mode === true)
+ return cb(err, meta);
- // If new pm2 instance has been popped
- // Lauch all modules
- Modularizer.launchAll(that, function(err_mod) {
- return cb(err, meta);
+ // If new pm2 instance has been popped
+ // Lauch all modules
+ Modularizer.launchAll(that, function(err_mod) {
+ return cb(err, meta);
+ });
});
- });
-}
+ }
-/**
- * Usefull when custom PM2 created with independent flag set to true
- * This will cleanup the newly created instance
- * by removing folder, killing PM2 and so on
- *
- * @param {Function} cb callback once cleanup is successfull
- */
-API.prototype.destroy = function(cb) {
- var exec = require('shelljs').exec;
- var that = this;
+ /**
+ * Usefull when custom PM2 created with independent flag set to true
+ * This will cleanup the newly created instance
+ * by removing folder, killing PM2 and so on
+ *
+ * @param {Function} cb callback once cleanup is successfull
+ */
+ destroy (cb) {
+ var exec = require('shelljs').exec;
+ var that = this;
- debug('Killing and deleting current deamon');
+ debug('Killing and deleting current deamon');
- this.killDaemon(function() {
- var cmd = 'rm -rf ' + that.pm2_home;
- var test_path = path.join(that.pm2_home, 'module_conf.json');
- var test_path_2 = path.join(that.pm2_home, 'pm2.pid');
+ this.killDaemon(function() {
+ var cmd = 'rm -rf ' + that.pm2_home;
+ var test_path = path.join(that.pm2_home, 'module_conf.json');
+ var test_path_2 = path.join(that.pm2_home, 'pm2.pid');
- if (that.pm2_home.indexOf('.pm2') > -1)
- return cb(new Error('Destroy is not a allowed method on .pm2'));
+ if (that.pm2_home.indexOf('.pm2') > -1)
+ return cb(new Error('Destroy is not a allowed method on .pm2'));
- if (fs.accessSync) {
fs.access(test_path, fs.R_OK, function(err) {
if (err) return cb(err);
debug('Deleting temporary folder %s', that.pm2_home);
exec(cmd, cb);
});
- return false;
- }
-
- // Support for Node 0.10
- fs.exists(test_path, function(exist) {
- if (exist) {
- debug('Deleting temporary folder %s', that.pm2_home);
- exec(cmd, cb);
- }
- return cb(null);
});
- });
-};
+ }
-/**
- * Disconnect from PM2 instance
- * This will allow your software to exit by itself
- *
- * @param {Function} [cb] optional callback once connection closed
- */
-API.prototype.disconnect = API.prototype.close = function(cb) {
- var that = this;
+ /**
+ * Disconnect from PM2 instance
+ * This will allow your software to exit by itself
+ *
+ * @param {Function} [cb] optional callback once connection closed
+ */
+ disconnect (cb) {
+ var that = this;
- if (!cb) cb = function() {};
+ if (!cb) cb = function() {};
- this.Client.close(function(err, data) {
- debug('The session lasted %ds', (new Date() - that.start_timer) / 1000);
- return cb(err, data);
- });
-};
+ this.Client.close(function(err, data) {
+ debug('The session lasted %ds', (new Date() - that.start_timer) / 1000);
+ return cb(err, data);
+ });
+ };
-/**
- * Launch modules
- *
- * @param {Function} cb callback once pm2 has launched modules
- */
-API.prototype.launchModules = function(cb) {
- Modularizer.launchAll(this, cb);
-};
+ /**
+ * Alias on disconnect
+ * @param cb
+ */
+ close (cb) {
+ this.disconnect(cb);
+ }
-/**
- * Enable bus allowing to retrieve various process event
- * like logs, restarts, reloads
- *
- * @param {Function} cb callback called with 1st param err and 2nb param the bus
- */
-API.prototype.launchBus = function(cb) {
- this.Client.launchBus(cb);
-};
+ /**
+ * Launch modules
+ *
+ * @param {Function} cb callback once pm2 has launched modules
+ */
+ launchModules (cb) {
+ Modularizer.launchAll(this, cb);
+ }
-/**
- * Exit methods for API
- * @param {Integer} code exit code for terminal
- */
-API.prototype.exitCli = function(code) {
- var that = this;
-
- // Do nothing if PM2 called programmatically (also in speedlist)
- if (conf.PM2_PROGRAMMATIC && process.env.PM2_USAGE != 'CLI') return false;
-
- KMDaemon.disconnectRPC(function() {
- that.Client.close(function() {
- code = code || 0;
- // Safe exits process after all streams are drained.
- // file descriptor flag.
- var fds = 0;
- // exits process when stdout (1) and sdterr(2) are both drained.
- function tryToExit() {
- if ((fds & 1) && (fds & 2)) {
- debug('This command took %ds to execute', (new Date() - that.start_timer) / 1000);
- process.exit(code);
+ /**
+ * Enable bus allowing to retrieve various process event
+ * like logs, restarts, reloads
+ *
+ * @param {Function} cb callback called with 1st param err and 2nb param the bus
+ */
+ launchBus (cb) {
+ this.Client.launchBus(cb);
+ }
+
+ /**
+ * Exit methods for API
+ * @param {Integer} code exit code for terminal
+ */
+ exitCli (code) {
+ var that = this;
+
+ // Do nothing if PM2 called programmatically (also in speedlist)
+ if (conf.PM2_PROGRAMMATIC && process.env.PM2_USAGE != 'CLI') return false;
+
+ KMDaemon.disconnectRPC(function() {
+ that.Client.close(function() {
+ code = code || 0;
+ // Safe exits process after all streams are drained.
+ // file descriptor flag.
+ var fds = 0;
+ // exits process when stdout (1) and sdterr(2) are both drained.
+ function tryToExit() {
+ if ((fds & 1) && (fds & 2)) {
+ debug('This command took %ds to execute', (new Date() - that.start_timer) / 1000);
+ process.exit(code);
+ }
}
- }
- [process.stdout, process.stderr].forEach(function(std) {
- var fd = std.fd;
- if (!std.bufferSize) {
- // bufferSize equals 0 means current stream is drained.
- fds = fds | fd;
- } else {
- // Appends nothing to the std queue, but will trigger `tryToExit` event on `drain`.
- std.write && std.write('', function() {
+ [process.stdout, process.stderr].forEach(function(std) {
+ var fd = std.fd;
+ if (!std.bufferSize) {
+ // bufferSize equals 0 means current stream is drained.
fds = fds | fd;
- tryToExit();
- });
- }
- // Does not write anything more.
- delete std.write;
+ } else {
+ // Appends nothing to the std queue, but will trigger `tryToExit` event on `drain`.
+ std.write && std.write('', function() {
+ fds = fds | fd;
+ tryToExit();
+ });
+ }
+ // Does not write anything more.
+ delete std.write;
+ });
+ tryToExit();
});
- tryToExit();
});
- });
-};
+ }
////////////////////////////
// Application management //
////////////////////////////
-/**
- * Start a file or json with configuration
- * @param {Object||String} cmd script to start or json
- * @param {Function} cb called when application has been started
- */
-API.prototype.start = function(cmd, opts, cb) {
- if (typeof(opts) == "function") {
- cb = opts;
- opts = {};
- }
- if (!opts)
- opts = {};
+ /**
+ * Start a file or json with configuration
+ * @param {Object||String} cmd script to start or json
+ * @param {Function} cb called when application has been started
+ */
+ start (cmd, opts, cb) {
+ if (typeof(opts) == "function") {
+ cb = opts;
+ opts = {};
+ }
+ if (!opts)
+ opts = {};
- var that = this;
+ var that = this;
- if (util.isArray(opts.watch) && opts.watch.length === 0)
- opts.watch = (opts.rawArgs ? !!~opts.rawArgs.indexOf('--watch') : !!~process.argv.indexOf('--watch')) || false;
+ if (util.isArray(opts.watch) && opts.watch.length === 0)
+ opts.watch = (opts.rawArgs ? !!~opts.rawArgs.indexOf('--watch') : !!~process.argv.indexOf('--watch')) || false;
- if (Common.isConfigFile(cmd) || (typeof(cmd) === 'object'))
- that._startJson(cmd, opts, 'restartProcessId', cb);
- else {
- that._startScript(cmd, opts, cb);
+ if (Common.isConfigFile(cmd) || (typeof(cmd) === 'object'))
+ that._startJson(cmd, opts, 'restartProcessId', cb);
+ else {
+ that._startScript(cmd, opts, cb);
+ }
}
-};
-/**
- * Reset process counters
- *
- * @method resetMetaProcess
- */
-API.prototype.reset = function(process_name, cb) {
- var that = this;
-
- function processIds(ids, cb) {
- async.eachLimit(ids, conf.CONCURRENT_ACTIONS, function(id, next) {
- that.Client.executeRemote('resetMetaProcessId', id, function(err, res) {
- if (err) console.error(err);
- Common.printOut(conf.PREFIX_MSG + 'Resetting meta for process id %d', id);
- return next();
+ /**
+ * Reset process counters
+ *
+ * @method resetMetaProcess
+ */
+ reset (process_name, cb) {
+ var that = this;
+
+ function processIds(ids, cb) {
+ async.eachLimit(ids, conf.CONCURRENT_ACTIONS, function(id, next) {
+ that.Client.executeRemote('resetMetaProcessId', id, function(err, res) {
+ if (err) console.error(err);
+ Common.printOut(conf.PREFIX_MSG + 'Resetting meta for process id %d', id);
+ return next();
+ });
+ }, function(err) {
+ if (err) return cb(Common.retErr(err));
+ return cb ? cb(null, {success:true}) : that.speedList();
});
- }, function(err) {
- if (err) return cb(Common.retErr(err));
- return cb ? cb(null, {success:true}) : that.speedList();
- });
- }
+ }
- if (process_name == 'all') {
- that.Client.getAllProcessId(function(err, ids) {
- if (err) {
- Common.printError(err);
- return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
- }
- return processIds(ids, cb);
- });
- }
- else if (isNaN(process_name)) {
- that.Client.getProcessIdByName(process_name, function(err, ids) {
- if (err) {
- Common.printError(err);
- return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
- }
- if (ids.length === 0) {
- Common.printError('Unknown process name');
- return cb ? cb(new Error('Unknown process name')) : that.exitCli(conf.ERROR_EXIT);
- }
- return processIds(ids, cb);
- });
- } else {
- processIds([process_name], cb);
+ if (process_name == 'all') {
+ that.Client.getAllProcessId(function(err, ids) {
+ if (err) {
+ Common.printError(err);
+ return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
+ }
+ return processIds(ids, cb);
+ });
+ }
+ else if (isNaN(process_name)) {
+ that.Client.getProcessIdByName(process_name, function(err, ids) {
+ if (err) {
+ Common.printError(err);
+ return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
+ }
+ if (ids.length === 0) {
+ Common.printError('Unknown process name');
+ return cb ? cb(new Error('Unknown process name')) : that.exitCli(conf.ERROR_EXIT);
+ }
+ return processIds(ids, cb);
+ });
+ } else {
+ processIds([process_name], cb);
+ }
}
-};
-/**
- * Update daemonized PM2 Daemon
- *
- * @param {Function} cb callback when pm2 has been upgraded
- */
-API.prototype.update = function(cb) {
- var that = this;
+ /**
+ * Update daemonized PM2 Daemon
+ *
+ * @param {Function} cb callback when pm2 has been upgraded
+ */
+ update (cb) {
+ var that = this;
- Common.printOut('Be sure to have the latest version by doing `npm install pm2@latest -g` before doing this procedure.');
+ Common.printOut('Be sure to have the latest version by doing `npm install pm2@latest -g` before doing this procedure.');
- // Dump PM2 processes
- that.Client.executeRemote('notifyKillPM2', {}, function() {});
+ // Dump PM2 processes
+ that.Client.executeRemote('notifyKillPM2', {}, function() {});
- that.getVersion(function(err, new_version) {
- // If not linked to keymetrics, and update pm2 to latest, display motd.update
- if (!that.gl_is_km_linked && !err && (pkg.version != new_version)) {
- var dt = fs.readFileSync(path.join(__dirname, that._conf.KEYMETRICS_UPDATE));
- console.log(dt.toString());
- }
+ that.getVersion(function(err, new_version) {
+ // If not linked to keymetrics, and update pm2 to latest, display motd.update
+ if (!that.gl_is_km_linked && !err && (pkg.version != new_version)) {
+ var dt = fs.readFileSync(path.join(__dirname, that._conf.KEYMETRICS_UPDATE));
+ console.log(dt.toString());
+ }
- that.dump(function(err) {
- debug('Dumping successfull', err);
- that.killDaemon(function() {
- debug('------------------ Everything killed', arguments);
- that.Client.launchDaemon({interactor:false}, function(err, child) {
- that.Client.launchRPC(function() {
- that.resurrect(function() {
- Common.printOut(chalk.blue.bold('>>>>>>>>>> PM2 updated'));
- Modularizer.launchAll(that, function() {
- KMDaemon.launchAndInteract(that._conf, null, function(err, data, interactor_proc) {
- // Interactor error can be skipped here
- return cb ? cb(null, {success:true}) : that.speedList();
+ that.dump(function(err) {
+ debug('Dumping successfull', err);
+ that.killDaemon(function() {
+ debug('------------------ Everything killed', arguments);
+ that.Client.launchDaemon({interactor:false}, function(err, child) {
+ that.Client.launchRPC(function() {
+ that.resurrect(function() {
+ Common.printOut(chalk.blue.bold('>>>>>>>>>> PM2 updated'));
+ Modularizer.launchAll(that, function() {
+ KMDaemon.launchAndInteract(that._conf, null, function(err, data, interactor_proc) {
+ // Interactor error can be skipped here
+ return cb ? cb(null, {success:true}) : that.speedList();
+ });
});
});
});
@@ -412,1276 +398,1262 @@ API.prototype.update = function(cb) {
});
});
});
- });
-
- return false;
-};
-
-/**
- * Graceful Reload an application
- *
- * @param {String} process_name Application Name or All
- * @param {Object} opts Options
- * @param {Function} cb Callback
- */
-API.prototype.gracefulReload = function(process_name, opts, cb) {
- var that = this;
- if (typeof(opts) == "function") {
- cb = opts;
- opts = {};
- }
-
- //Common.printOut(conf.PREFIX_MSG_WARNING + chalk.bold.yellow('Warning gracefulReload will be soon deprecated'));
- //Common.printOut(conf.PREFIX_MSG_WARNING + chalk.bold.yellow('Use http://pm2.keymetrics.io/docs/usage/signals-clean-restart/ instead'));
-
- if (Common.isConfigFile(process_name))
- that._startJson(process_name, commander, 'softReloadProcessId');
- else {
- if (opts && !opts.updateEnv)
- Common.printOut(IMMUTABLE_MSG);
- that._operate('softReloadProcessId', process_name, opts, cb);
+ return false;
}
-};
-/**
- * Reload an application
- *
- * @param {String} process_name Application Name or All
- * @param {Object} opts Options
- * @param {Function} cb Callback
- */
-API.prototype.reload = function(process_name, opts, cb) {
- var that = this;
+ /**
+ * Reload an application
+ *
+ * @param {String} process_name Application Name or All
+ * @param {Object} opts Options
+ * @param {Function} cb Callback
+ */
+ reload (process_name, opts, cb) {
+ var that = this;
- if (typeof(opts) == "function") {
- cb = opts;
- opts = {};
- }
+ if (typeof(opts) == "function") {
+ cb = opts;
+ opts = {};
+ }
- var delay = Common.lockReload();
+ var delay = Common.lockReload();
- if (delay > 0 && opts.force != true) {
- Common.printError(conf.PREFIX_MSG_ERR + 'Reload already in progress, please try again in ' + Math.floor((conf.RELOAD_LOCK_TIMEOUT - delay) / 1000) + ' seconds or use --force');
- return cb ? cb(new Error('Reload in progress')) : that.exitCli(conf.ERROR_EXIT);
- }
+ if (delay > 0 && opts.force != true) {
+ Common.printError(conf.PREFIX_MSG_ERR + 'Reload already in progress, please try again in ' + Math.floor((conf.RELOAD_LOCK_TIMEOUT - delay) / 1000) + ' seconds or use --force');
+ return cb ? cb(new Error('Reload in progress')) : that.exitCli(conf.ERROR_EXIT);
+ }
- if (Common.isConfigFile(process_name))
- that._startJson(process_name, opts, 'reloadProcessId', function(err, apps) {
- Common.unlockReload();
- if (err)
- return cb ? cb(err) : that.exitCli(conf.ERROR_EXIT);
- return cb ? cb(null, apps) : that.exitCli(conf.SUCCESS_EXIT);;
- });
- else {
- if (opts && !opts.updateEnv)
- Common.printOut(IMMUTABLE_MSG);
+ if (Common.isConfigFile(process_name))
+ that._startJson(process_name, opts, 'reloadProcessId', function(err, apps) {
+ Common.unlockReload();
+ if (err)
+ return cb ? cb(err) : that.exitCli(conf.ERROR_EXIT);
+ return cb ? cb(null, apps) : that.exitCli(conf.SUCCESS_EXIT);;
+ });
+ else {
+ if (opts && !opts.updateEnv)
+ Common.printOut(IMMUTABLE_MSG);
- that._operate('reloadProcessId', process_name, opts, function(err, apps) {
- Common.unlockReload();
+ that._operate('reloadProcessId', process_name, opts, function(err, apps) {
+ Common.unlockReload();
- if (err)
- return cb ? cb(err) : that.exitCli(conf.ERROR_EXIT);
- return cb ? cb(null, apps) : that.exitCli(conf.SUCCESS_EXIT);;
- });
+ if (err)
+ return cb ? cb(err) : that.exitCli(conf.ERROR_EXIT);
+ return cb ? cb(null, apps) : that.exitCli(conf.SUCCESS_EXIT);;
+ });
+ }
}
-};
-/**
- * Restart process
- *
- * @param {String} cmd Application Name / Process id / JSON application file / 'all'
- * @param {Object} opts Extra options to be updated
- * @param {Function} cb Callback
- */
-API.prototype.restart = function(cmd, opts, cb) {
- if (typeof(opts) == "function") {
- cb = opts;
- opts = {};
- }
- var that = this;
-
- if (typeof(cmd) === 'number')
- cmd = cmd.toString();
-
- if (cmd == "-") {
- // Restart from PIPED JSON
- process.stdin.resume();
- process.stdin.setEncoding('utf8');
- process.stdin.on('data', function (param) {
- process.stdin.pause();
- that.actionFromJson('restartProcessId', param, opts, 'pipe', cb);
- });
- }
- else if (Common.isConfigFile(cmd) || typeof(cmd) === 'object')
- that._startJson(cmd, opts, 'restartProcessId', cb);
- else {
- if (opts && !opts.updateEnv)
- Common.printOut(IMMUTABLE_MSG);
- that._operate('restartProcessId', cmd, opts, cb);
+ /**
+ * Restart process
+ *
+ * @param {String} cmd Application Name / Process id / JSON application file / 'all'
+ * @param {Object} opts Extra options to be updated
+ * @param {Function} cb Callback
+ */
+ restart (cmd, opts, cb) {
+ if (typeof(opts) == "function") {
+ cb = opts;
+ opts = {};
+ }
+ var that = this;
+
+ if (typeof(cmd) === 'number')
+ cmd = cmd.toString();
+
+ if (cmd == "-") {
+ // Restart from PIPED JSON
+ process.stdin.resume();
+ process.stdin.setEncoding('utf8');
+ process.stdin.on('data', function (param) {
+ process.stdin.pause();
+ that.actionFromJson('restartProcessId', param, opts, 'pipe', cb);
+ });
+ }
+ else if (Common.isConfigFile(cmd) || typeof(cmd) === 'object')
+ that._startJson(cmd, opts, 'restartProcessId', cb);
+ else {
+ if (opts && !opts.updateEnv)
+ Common.printOut(IMMUTABLE_MSG);
+ that._operate('restartProcessId', cmd, opts, cb);
+ }
}
-};
-/**
- * Delete process
- *
- * @param {String} process_name Application Name / Process id / Application file / 'all'
- * @param {Function} cb Callback
- */
-API.prototype.delete = function(process_name, jsonVia, cb) {
- var that = this;
-
- if (typeof(jsonVia) === "function") {
- cb = jsonVia;
- jsonVia = null;
- }
- if (typeof(process_name) === "number") {
- process_name = process_name.toString();
- }
+ /**
+ * Delete process
+ *
+ * @param {String} process_name Application Name / Process id / Application file / 'all'
+ * @param {Function} cb Callback
+ */
+ delete (process_name, jsonVia, cb) {
+ var that = this;
- if (jsonVia == 'pipe')
- return that.actionFromJson('deleteProcessId', process_name, commander, 'pipe', cb);
- if (Common.isConfigFile(process_name))
- return that.actionFromJson('deleteProcessId', process_name, commander, 'file', cb);
- else
- that._operate('deleteProcessId', process_name, cb);
-};
+ if (typeof(jsonVia) === "function") {
+ cb = jsonVia;
+ jsonVia = null;
+ }
+ if (typeof(process_name) === "number") {
+ process_name = process_name.toString();
+ }
-/**
- * Stop process
- *
- * @param {String} process_name Application Name / Process id / Application file / 'all'
- * @param {Function} cb Callback
- */
-API.prototype.stop = function(process_name, cb) {
- var that = this;
-
- if (typeof(process_name) === 'number')
- process_name = process_name.toString();
-
- if (process_name == "-") {
- process.stdin.resume();
- process.stdin.setEncoding('utf8');
- process.stdin.on('data', function (param) {
- process.stdin.pause();
- that.actionFromJson('stopProcessId', param, commander, 'pipe', cb);
- });
+ if (jsonVia == 'pipe')
+ return that.actionFromJson('deleteProcessId', process_name, commander, 'pipe', cb);
+ if (Common.isConfigFile(process_name))
+ return that.actionFromJson('deleteProcessId', process_name, commander, 'file', cb);
+ else
+ that._operate('deleteProcessId', process_name, cb);
}
- else if (Common.isConfigFile(process_name))
- that.actionFromJson('stopProcessId', process_name, commander, 'file', cb);
- else
- that._operate('stopProcessId', process_name, cb);
-};
-
-/**
- * Get list of all processes managed
- *
- * @param {Function} cb Callback
- */
-API.prototype.list = function(opts, cb) {
- var that = this;
- if (typeof(opts) == 'function') {
- cb = opts;
- opts = null;
+ /**
+ * Stop process
+ *
+ * @param {String} process_name Application Name / Process id / Application file / 'all'
+ * @param {Function} cb Callback
+ */
+ stop (process_name, cb) {
+ var that = this;
+
+ if (typeof(process_name) === 'number')
+ process_name = process_name.toString();
+
+ if (process_name == "-") {
+ process.stdin.resume();
+ process.stdin.setEncoding('utf8');
+ process.stdin.on('data', function (param) {
+ process.stdin.pause();
+ that.actionFromJson('stopProcessId', param, commander, 'pipe', cb);
+ });
+ }
+ else if (Common.isConfigFile(process_name))
+ that.actionFromJson('stopProcessId', process_name, commander, 'file', cb);
+ else
+ that._operate('stopProcessId', process_name, cb);
}
- that.Client.executeRemote('getMonitorData', {}, function(err, list) {
- if (err) {
- Common.printError(err);
- return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
+ /**
+ * Get list of all processes managed
+ *
+ * @param {Function} cb Callback
+ */
+ list (opts, cb) {
+ var that = this;
+
+ if (typeof(opts) == 'function') {
+ cb = opts;
+ opts = null;
}
- if (opts && opts.rawArgs && opts.rawArgs.indexOf('--watch') > -1) {
- var moment = require('moment');
- function show() {
- process.stdout.write('\033[2J');
- process.stdout.write('\033[0f');
- console.log('Last refresh: ', moment().format('LTS'));
- that.Client.executeRemote('getMonitorData', {}, function(err, list) {
- UX.dispAsTable(list, null);
- });
+ that.Client.executeRemote('getMonitorData', {}, function(err, list) {
+ if (err) {
+ Common.printError(err);
+ return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
}
- show();
- setInterval(show, 900);
- return false;
- }
+ if (opts && opts.rawArgs && opts.rawArgs.indexOf('--watch') > -1) {
+ var moment = require('moment');
+ function show() {
+ process.stdout.write('\\033[2J');
+ process.stdout.write('\\033[0f');
+ console.log('Last refresh: ', moment().format('LTS'));
+ that.Client.executeRemote('getMonitorData', {}, function(err, list) {
+ UX.dispAsTable(list, null);
+ });
+ }
- return cb ? cb(null, list) : that.speedList();
- });
-};
+ show();
+ setInterval(show, 900);
+ return false;
+ }
-/**
- * Kill Daemon
- *
- * @param {Function} cb Callback
- */
-API.prototype.killDaemon = API.prototype.kill = function(cb) {
- var that = this;
+ return cb ? cb(null, list) : that.speedList();
+ });
+ }
- var semver = require('semver');
- Common.printOut(conf.PREFIX_MSG + 'Stopping PM2...');
+ /**
+ * Kill Daemon
+ *
+ * @param {Function} cb Callback
+ */
+ killDaemon (cb) {
+ var that = this;
- that.Client.executeRemote('notifyKillPM2', {}, function() {});
+ var semver = require('semver');
+ Common.printOut(conf.PREFIX_MSG + 'Stopping PM2...');
- that.killAllModules(function() {
- that._operate('deleteProcessId', 'all', function(err, list) {
- Common.printOut(conf.PREFIX_MSG + 'All processes have been stopped and deleted');
- process.env.PM2_SILENT = 'false';
+ that.Client.executeRemote('notifyKillPM2', {}, function() {});
- that.killInteract(function(err, data) {
- that.Client.killDaemon(function(err, res) {
- if (err) Common.printError(err);
- Common.printOut(conf.PREFIX_MSG + 'PM2 stopped');
- return cb ? cb(err, res) : that.exitCli(conf.SUCCESS_EXIT);
+ that.killAllModules(function() {
+ that._operate('deleteProcessId', 'all', function(err, list) {
+ Common.printOut(conf.PREFIX_MSG + 'All processes have been stopped and deleted');
+ process.env.PM2_SILENT = 'false';
+
+ that.killInteract(function(err, data) {
+ that.Client.killDaemon(function(err, res) {
+ if (err) Common.printError(err);
+ Common.printOut(conf.PREFIX_MSG + 'PM2 stopped');
+ return cb ? cb(err, res) : that.exitCli(conf.SUCCESS_EXIT);
+ });
});
});
});
- });
-};
-
-/////////////////////
-// Private methods //
-/////////////////////
+ }
-/**
- * Method to START / RESTART a script
- *
- * @private
- * @param {string} script script name (will be resolved according to location)
- */
-API.prototype._startScript = function(script, opts, cb) {
- if (typeof opts == "function") {
- cb = opts;
- opts = {};
+ kill (cb) {
+ this.killDaemon(cb);
}
- var that = this;
- var app_conf = Config.transCMDToConf(opts);
- var appConf = {};
+ /////////////////////
+ // Private methods //
+ /////////////////////
- if (!!opts.executeCommand)
- app_conf.exec_mode = 'fork';
- else if (opts.instances !== undefined)
- app_conf.exec_mode = 'cluster';
- else
- app_conf.exec_mode = 'fork';
+ /**
+ * Method to START / RESTART a script
+ *
+ * @private
+ * @param {string} script script name (will be resolved according to location)
+ */
+ _startScript (script, opts, cb) {
+ if (typeof opts == "function") {
+ cb = opts;
+ opts = {};
+ }
+ var that = this;
- // Options set via environment variables
- if (process.env.PM2_DEEP_MONITORING)
- app_conf.deep_monitoring = true;
+ var app_conf = Config.transCMDToConf(opts);
+ var appConf = {};
- if (typeof app_conf.name == 'function'){
- delete app_conf.name;
- }
+ if (!!opts.executeCommand)
+ app_conf.exec_mode = 'fork';
+ else if (opts.instances !== undefined)
+ app_conf.exec_mode = 'cluster';
+ else
+ app_conf.exec_mode = 'fork';
- delete app_conf.args;
+ // Options set via environment variables
+ if (process.env.PM2_DEEP_MONITORING)
+ app_conf.deep_monitoring = true;
- var argsIndex;
+ if (typeof app_conf.name == 'function'){
+ delete app_conf.name;
+ }
- if (opts.rawArgs && (argsIndex = opts.rawArgs.indexOf('--')) >= 0) {
- app_conf.args = opts.rawArgs.slice(argsIndex + 1);
- }
- else if (opts.scriptArgs) {
- app_conf.args = opts.scriptArgs;
- }
+ delete app_conf.args;
- app_conf.script = script;
+ var argsIndex;
- if ((appConf = Common.verifyConfs(app_conf)) instanceof Error)
- return cb ? cb(Common.retErr(appConf)) : that.exitCli(conf.ERROR_EXIT);
+ if (opts.rawArgs && (argsIndex = opts.rawArgs.indexOf('--')) >= 0) {
+ app_conf.args = opts.rawArgs.slice(argsIndex + 1);
+ }
+ else if (opts.scriptArgs) {
+ app_conf.args = opts.scriptArgs;
+ }
- app_conf = appConf[0];
+ app_conf.script = script;
- app_conf.username = Common.getCurrentUsername();
+ if ((appConf = Common.verifyConfs(app_conf)) instanceof Error)
+ return cb ? cb(Common.retErr(appConf)) : that.exitCli(conf.ERROR_EXIT);
- /**
- * If -w option, write configuration to configuration.json file
- */
- if (appConf.write) {
- var dst_path = path.join(process.env.PWD || process.cwd(), app_conf.name + '-pm2.json');
- Common.printOut(conf.PREFIX_MSG + 'Writing configuration to', chalk.blue(dst_path));
- // pretty JSON
- try {
- fs.writeFileSync(dst_path, JSON.stringify(app_conf, null, 2));
- } catch (e) {
- console.error(e.stack || e);
+ app_conf = appConf[0];
+
+ app_conf.username = Common.getCurrentUsername();
+
+ /**
+ * If -w option, write configuration to configuration.json file
+ */
+ if (appConf.write) {
+ var dst_path = path.join(process.env.PWD || process.cwd(), app_conf.name + '-pm2.json');
+ Common.printOut(conf.PREFIX_MSG + 'Writing configuration to', chalk.blue(dst_path));
+ // pretty JSON
+ try {
+ fs.writeFileSync(dst_path, JSON.stringify(app_conf, null, 2));
+ } catch (e) {
+ console.error(e.stack || e);
+ }
}
- }
- /**
- * If start start/restart application
- */
- function restartExistingProcessName(cb) {
- if (!isNaN(script) ||
+ /**
+ * If start start/restart application
+ */
+ function restartExistingProcessName(cb) {
+ if (!isNaN(script) ||
(typeof script === 'string' && script.indexOf('/') != -1) ||
(typeof script === 'string' && path.extname(script) !== ''))
- return cb(null);
-
- if (script !== 'all') {
- that.Client.getProcessIdByName(script, function(err, ids) {
- if (err && cb) return cb(err);
- if (ids.length > 0) {
- that._operate('restartProcessId', script, opts, function(err, list) {
- if (err) return cb(err);
- Common.printOut(conf.PREFIX_MSG + 'Process successfully started');
- return cb(true, list);
- });
- }
- else return cb(null);
- });
+ return cb(null);
+
+ if (script !== 'all') {
+ that.Client.getProcessIdByName(script, function(err, ids) {
+ if (err && cb) return cb(err);
+ if (ids.length > 0) {
+ that._operate('restartProcessId', script, opts, function(err, list) {
+ if (err) return cb(err);
+ Common.printOut(conf.PREFIX_MSG + 'Process successfully started');
+ return cb(true, list);
+ });
+ }
+ else return cb(null);
+ });
+ }
+ else {
+ that._operate('restartProcessId', 'all', function(err, list) {
+ if (err) return cb(err);
+ Common.printOut(conf.PREFIX_MSG + 'Process successfully started');
+ return cb(true, list);
+ });
+ }
}
- else {
- that._operate('restartProcessId', 'all', function(err, list) {
+
+ function restartExistingProcessId(cb) {
+ if (isNaN(script)) return cb(null);
+
+ that._operate('restartProcessId', script, opts, function(err, list) {
if (err) return cb(err);
Common.printOut(conf.PREFIX_MSG + 'Process successfully started');
return cb(true, list);
});
}
- }
- function restartExistingProcessId(cb) {
- if (isNaN(script)) return cb(null);
-
- that._operate('restartProcessId', script, opts, function(err, list) {
- if (err) return cb(err);
- Common.printOut(conf.PREFIX_MSG + 'Process successfully started');
- return cb(true, list);
- });
- }
-
- /**
- * Restart a process with the same full path
- * Or start it
- */
- function restartExistingProcessPath(cb) {
- that.Client.executeRemote('getMonitorData', {}, function(err, procs) {
- if (err) return cb ? cb(new Error(err)) : that.exitCli(conf.ERROR_EXIT);
+ /**
+ * Restart a process with the same full path
+ * Or start it
+ */
+ function restartExistingProcessPath(cb) {
+ that.Client.executeRemote('getMonitorData', {}, function(err, procs) {
+ if (err) return cb ? cb(new Error(err)) : that.exitCli(conf.ERROR_EXIT);
- var full_path = path.resolve(that.cwd, script);
- var managed_script = null;
+ var full_path = path.resolve(that.cwd, script);
+ var managed_script = null;
- procs.forEach(function(proc) {
- if (proc.pm2_env.pm_exec_path == full_path &&
+ procs.forEach(function(proc) {
+ if (proc.pm2_env.pm_exec_path == full_path &&
proc.pm2_env.name == app_conf.name)
- managed_script = proc;
- });
+ managed_script = proc;
+ });
- if (managed_script &&
+ if (managed_script &&
(managed_script.pm2_env.status == conf.STOPPED_STATUS ||
- managed_script.pm2_env.status == conf.STOPPING_STATUS ||
- managed_script.pm2_env.status == conf.ERRORED_STATUS)) {
- // Restart process if stopped
- var app_name = managed_script.pm2_env.name;
+ managed_script.pm2_env.status == conf.STOPPING_STATUS ||
+ managed_script.pm2_env.status == conf.ERRORED_STATUS)) {
+ // Restart process if stopped
+ var app_name = managed_script.pm2_env.name;
- that._operate('restartProcessId', app_name, opts, function(err, list) {
- if (err) return cb ? cb(new Error(err)) : that.exitCli(conf.ERROR_EXIT);
- Common.printOut(conf.PREFIX_MSG + 'Process successfully started');
- return cb(true, list);
- });
- return false;
- }
- else if (managed_script && !opts.force) {
- Common.printError(conf.PREFIX_MSG_ERR + 'Script already launched, add -f option to force re-execution');
- return cb(new Error('Script already launched'));
- }
+ that._operate('restartProcessId', app_name, opts, function(err, list) {
+ if (err) return cb ? cb(new Error(err)) : that.exitCli(conf.ERROR_EXIT);
+ Common.printOut(conf.PREFIX_MSG + 'Process successfully started');
+ return cb(true, list);
+ });
+ return false;
+ }
+ else if (managed_script && !opts.force) {
+ Common.printError(conf.PREFIX_MSG_ERR + 'Script already launched, add -f option to force re-execution');
+ return cb(new Error('Script already launched'));
+ }
- var resolved_paths = null;
+ var resolved_paths = null;
- try {
- resolved_paths = Common.resolveAppAttributes({
- cwd : that.cwd,
- pm2_home : that.pm2_home
- }, app_conf);
- } catch(e) {
- Common.printError(e);
- return cb(Common.retErr(e));
- }
+ try {
+ resolved_paths = Common.resolveAppAttributes({
+ cwd : that.cwd,
+ pm2_home : that.pm2_home
+ }, app_conf);
+ } catch(e) {
+ Common.printError(e);
+ return cb(Common.retErr(e));
+ }
- Common.printOut(conf.PREFIX_MSG + 'Starting %s in %s (%d instance' + (resolved_paths.instances > 1 ? 's' : '') + ')',
- resolved_paths.pm_exec_path, resolved_paths.exec_mode, resolved_paths.instances);
+ Common.printOut(conf.PREFIX_MSG + 'Starting %s in %s (%d instance' + (resolved_paths.instances > 1 ? 's' : '') + ')',
+ resolved_paths.pm_exec_path, resolved_paths.exec_mode, resolved_paths.instances);
- if (!resolved_paths.env) resolved_paths.env = {};
+ if (!resolved_paths.env) resolved_paths.env = {};
- // Set PM2 HOME in case of child process using PM2 API
- resolved_paths.env['PM2_HOME'] = that.pm2_home;
+ // Set PM2 HOME in case of child process using PM2 API
+ resolved_paths.env['PM2_HOME'] = that.pm2_home;
- var additional_env = Modularizer.getAdditionalConf(resolved_paths.name);
- util._extend(resolved_paths.env, additional_env);
+ var additional_env = Modularizer.getAdditionalConf(resolved_paths.name);
+ util._extend(resolved_paths.env, additional_env);
- // Is KM linked?
- resolved_paths.km_link = that.gl_is_km_linked;
+ // Is KM linked?
+ resolved_paths.km_link = that.gl_is_km_linked;
- that.Client.executeRemote('prepare', resolved_paths, function(err, data) {
- if (err) {
- Common.printError(conf.PREFIX_MSG_ERR + 'Error while launching application', err.stack || err);
- return cb(Common.retErr(err));
- }
+ that.Client.executeRemote('prepare', resolved_paths, function(err, data) {
+ if (err) {
+ Common.printError(conf.PREFIX_MSG_ERR + 'Error while launching application', err.stack || err);
+ return cb(Common.retErr(err));
+ }
- Common.printOut(conf.PREFIX_MSG + 'Done.');
- return cb(true, data);
+ Common.printOut(conf.PREFIX_MSG + 'Done.');
+ return cb(true, data);
+ });
+ return false;
});
- return false;
- });
- }
-
- async.series([
- restartExistingProcessName,
- restartExistingProcessId,
- restartExistingProcessPath
- ], function(err, data) {
+ }
- if (err instanceof Error)
- return cb ? cb(err) : that.exitCli(conf.ERROR_EXIT);
+ async.series([
+ restartExistingProcessName,
+ restartExistingProcessId,
+ restartExistingProcessPath
+ ], function(err, data) {
- var ret = {};
- data.forEach(function(_dt) {
- if (_dt !== undefined)
- ret = _dt;
- });
+ if (err instanceof Error)
+ return cb ? cb(err) : that.exitCli(conf.ERROR_EXIT);
- return cb ? cb(null, ret) : that.speedList();
- });
-};
+ var ret = {};
+ data.forEach(function(_dt) {
+ if (_dt !== undefined)
+ ret = _dt;
+ });
-/**
- * Method to start/restart/reload processes from a JSON file
- * It will start app not started
- * Can receive only option to skip applications
- *
- * @private
- */
-API.prototype._startJson = function(file, opts, action, pipe, cb) {
- var config = {};
- var appConf = {};
- var deployConf = {};
- var apps_info = [];
- var that = this;
-
- if (typeof(cb) === 'undefined' && typeof(pipe) === 'function') {
- cb = pipe;
+ return cb ? cb(null, ret) : that.speedList();
+ });
}
- if (typeof(file) === 'object') {
- config = file;
- } else if (pipe === 'pipe') {
- config = Common.parseConfig(file, 'pipe');
- } else {
- var data = null;
-
- var isAbsolute = false
+ /**
+ * Method to start/restart/reload processes from a JSON file
+ * It will start app not started
+ * Can receive only option to skip applications
+ *
+ * @private
+ */
+ _startJson (file, opts, action, pipe, cb) {
+ var config = {};
+ var appConf = {};
+ var deployConf = {};
+ var apps_info = [];
+ var that = this;
+
+ if (typeof(cb) === 'undefined' && typeof(pipe) === 'function') {
+ cb = pipe;
+ }
- //node 0.11 compatibility #2815
- if (typeof path.isAbsolute === 'function') {
- isAbsolute = path.isAbsolute(file)
+ if (typeof(file) === 'object') {
+ config = file;
+ } else if (pipe === 'pipe') {
+ config = Common.parseConfig(file, 'pipe');
} else {
- isAbsolute = require('./tools/IsAbsolute.js')(file)
- }
+ var data = null;
- var file_path = isAbsolute ? file : path.join(that.cwd, file);
+ var isAbsolute = path.isAbsolute(file)
+ var file_path = isAbsolute ? file : path.join(that.cwd, file);
- debug('Resolved filepath %s', file_path);
+ debug('Resolved filepath %s', file_path);
- try {
- data = fs.readFileSync(file_path);
- } catch(e) {
- Common.printError(conf.PREFIX_MSG_ERR + 'File ' + file +' not found');
- return cb ? cb(Common.retErr(e)) : that.exitCli(conf.ERROR_EXIT);
- }
+ try {
+ data = fs.readFileSync(file_path);
+ } catch(e) {
+ Common.printError(conf.PREFIX_MSG_ERR + 'File ' + file +' not found');
+ return cb ? cb(Common.retErr(e)) : that.exitCli(conf.ERROR_EXIT);
+ }
- try {
- config = Common.parseConfig(data, file);
- } catch(e) {
- Common.printError(conf.PREFIX_MSG_ERR + 'File ' + file + ' malformated');
- console.error(e);
- return cb ? cb(Common.retErr(e)) : that.exitCli(conf.ERROR_EXIT);
+ try {
+ config = Common.parseConfig(data, file);
+ } catch(e) {
+ Common.printError(conf.PREFIX_MSG_ERR + 'File ' + file + ' malformated');
+ console.error(e);
+ return cb ? cb(Common.retErr(e)) : that.exitCli(conf.ERROR_EXIT);
+ }
}
- }
-
- if (config.deploy)
- deployConf = config.deploy;
- if (config.apps)
- appConf = config.apps;
- else if (config.pm2)
- appConf = config.pm2;
- else
- appConf = config;
+ if (config.deploy)
+ deployConf = config.deploy;
- if (!Array.isArray(appConf))
- appConf = [appConf]; //convert to array
+ if (config.apps)
+ appConf = config.apps;
+ else if (config.pm2)
+ appConf = config.pm2;
+ else
+ appConf = config;
- if ((appConf = Common.verifyConfs(appConf)) instanceof Error)
- return cb ? cb(appConf) : that.exitCli(conf.ERROR_EXIT);
+ if (!Array.isArray(appConf))
+ appConf = [appConf]; //convert to array
- process.env.PM2_JSON_PROCESSING = true;
+ if ((appConf = Common.verifyConfs(appConf)) instanceof Error)
+ return cb ? cb(appConf) : that.exitCli(conf.ERROR_EXIT);
- // Get App list
- var apps_name = [];
- var proc_list = {};
+ process.env.PM2_JSON_PROCESSING = true;
- // Here we pick only the field we want from the CLI when starting a JSON
- appConf.forEach(function(app) {
- // --only
- if (opts.only && opts.only != app.name)
- return false;
- // --watch
- if (!app.watch && opts.watch && opts.watch === true)
- app.watch = true;
- // --ignore-watch
- if (!app.ignore_watch && opts.ignore_watch)
- app.ignore_watch = opts.ignore_watch;
- // --instances
- if (opts.instances && typeof(opts.instances) === 'number')
- app.instances = opts.instances;
- // --uid
- if (opts.uid)
- app.uid = opts.uid;
- // --gid
- if (opts.gid)
- app.gid = opts.gid;
- // Specific
- if (app.append_env_to_name && opts.env)
- app.name += ('-' + opts.env);
- app.username = Common.getCurrentUsername();
- apps_name.push(app.name);
- });
-
- that.Client.executeRemote('getMonitorData', {}, function(err, raw_proc_list) {
- if (err) {
- Common.printError(err);
- return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
- }
+ // Get App list
+ var apps_name = [];
+ var proc_list = {};
- /**
- * Uniquify in memory process list
- */
- raw_proc_list.forEach(function(proc) {
- proc_list[proc.name] = proc;
+ // Here we pick only the field we want from the CLI when starting a JSON
+ appConf.forEach(function(app) {
+ // --only
+ if (opts.only && opts.only != app.name)
+ return false;
+ // --watch
+ if (!app.watch && opts.watch && opts.watch === true)
+ app.watch = true;
+ // --ignore-watch
+ if (!app.ignore_watch && opts.ignore_watch)
+ app.ignore_watch = opts.ignore_watch;
+ // --instances
+ if (opts.instances && typeof(opts.instances) === 'number')
+ app.instances = opts.instances;
+ // --uid
+ if (opts.uid)
+ app.uid = opts.uid;
+ // --gid
+ if (opts.gid)
+ app.gid = opts.gid;
+ // Specific
+ if (app.append_env_to_name && opts.env)
+ app.name += ('-' + opts.env);
+ app.username = Common.getCurrentUsername();
+ apps_name.push(app.name);
});
- /**
- * Auto detect application already started
- * and act on them depending on action
- */
- async.eachLimit(Object.keys(proc_list), conf.CONCURRENT_ACTIONS, function(proc_name, next) {
- // Skip app name (--only option)
- if (apps_name.indexOf(proc_name) == -1)
- return next();
+ that.Client.executeRemote('getMonitorData', {}, function(err, raw_proc_list) {
+ if (err) {
+ Common.printError(err);
+ return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
+ }
+
+ /**
+ * Uniquify in memory process list
+ */
+ raw_proc_list.forEach(function(proc) {
+ proc_list[proc.name] = proc;
+ });
- if (!(action == 'reloadProcessId' ||
+ /**
+ * Auto detect application already started
+ * and act on them depending on action
+ */
+ async.eachLimit(Object.keys(proc_list), conf.CONCURRENT_ACTIONS, function(proc_name, next) {
+ // Skip app name (--only option)
+ if (apps_name.indexOf(proc_name) == -1)
+ return next();
+
+ if (!(action == 'reloadProcessId' ||
action == 'softReloadProcessId' ||
action == 'restartProcessId'))
- throw new Error('Wrong action called');
+ throw new Error('Wrong action called');
- var apps = appConf.filter(function(app) {
- return app.name == proc_name;
- });
+ var apps = appConf.filter(function(app) {
+ return app.name == proc_name;
+ });
- var envs = apps.map(function(app){
- // Binds env_diff to env and returns it.
- return Common.mergeEnvironmentVariables(app, opts.env, deployConf);
- });
+ var envs = apps.map(function(app){
+ // Binds env_diff to env and returns it.
+ return Common.mergeEnvironmentVariables(app, opts.env, deployConf);
+ });
- // Assigns own enumerable properties of all
- // Notice: if people use the same name in different apps,
- // duplicated envs will be overrode by the last one
- var env = envs.reduce(function(e1, e2){
- return util._extend(e1, e2);
- });
+ // Assigns own enumerable properties of all
+ // Notice: if people use the same name in different apps,
+ // duplicated envs will be overrode by the last one
+ var env = envs.reduce(function(e1, e2){
+ return util._extend(e1, e2);
+ });
- // When we are processing JSON, allow to keep the new env by default
- env.updateEnv = true;
+ // When we are processing JSON, allow to keep the new env by default
+ env.updateEnv = true;
- // Pass `env` option
- that._operate(action, proc_name, env, function(err, ret) {
- if (err) Common.printError(err);
+ // Pass `env` option
+ that._operate(action, proc_name, env, function(err, ret) {
+ if (err) Common.printError(err);
- // For return
- apps_info = apps_info.concat(ret);
+ // For return
+ apps_info = apps_info.concat(ret);
- that.Client.notifyGod(action, proc_name);
- // And Remove from array to spy
- apps_name.splice(apps_name.indexOf(proc_name), 1);
- return next();
- });
+ that.Client.notifyGod(action, proc_name);
+ // And Remove from array to spy
+ apps_name.splice(apps_name.indexOf(proc_name), 1);
+ return next();
+ });
- }, function(err) {
- if (err) return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
- if (apps_name.length > 0 && action != 'start')
- Common.printOut(conf.PREFIX_MSG_WARNING + 'Applications %s not running, starting...', apps_name.join(', '));
- // Start missing apps
- return startApps(apps_name, function(err, apps) {
- apps_info = apps_info.concat(apps);
- return cb ? cb(err, apps_info) : that.speedList(err ? 1 : 0);
+ }, function(err) {
+ if (err) return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
+ if (apps_name.length > 0 && action != 'start')
+ Common.printOut(conf.PREFIX_MSG_WARNING + 'Applications %s not running, starting...', apps_name.join(', '));
+ // Start missing apps
+ return startApps(apps_name, function(err, apps) {
+ apps_info = apps_info.concat(apps);
+ return cb ? cb(err, apps_info) : that.speedList(err ? 1 : 0);
+ });
});
- });
- return false;
- });
-
- function startApps(app_name_to_start, cb) {
- var apps_to_start = [];
- var apps_started = [];
-
- appConf.forEach(function(app, i) {
- if (app_name_to_start.indexOf(app.name) != -1) {
- apps_to_start.push(appConf[i]);
- }
+ return false;
});
- async.eachLimit(apps_to_start, conf.CONCURRENT_ACTIONS, function(app, next) {
- if (opts.cwd)
- app.cwd = opts.cwd;
- if (opts.force_name)
- app.name = opts.force_name;
- if (opts.started_as_module)
- app.pmx_module = true;
+ function startApps(app_name_to_start, cb) {
+ var apps_to_start = [];
+ var apps_started = [];
- var resolved_paths = null;
-
- // hardcode script name to use `serve` feature inside a process file
- if (app.script === 'serve') {
- app.script = path.resolve(__dirname, 'API', 'Serve.js')
- }
+ appConf.forEach(function(app, i) {
+ if (app_name_to_start.indexOf(app.name) != -1) {
+ apps_to_start.push(appConf[i]);
+ }
+ });
- try {
- resolved_paths = Common.resolveAppAttributes({
- cwd : that.cwd,
- pm2_home : that.pm2_home
- }, app);
- } catch (e) {
- return next();
- }
+ async.eachLimit(apps_to_start, conf.CONCURRENT_ACTIONS, function(app, next) {
+ if (opts.cwd)
+ app.cwd = opts.cwd;
+ if (opts.force_name)
+ app.name = opts.force_name;
+ if (opts.started_as_module)
+ app.pmx_module = true;
- if (!resolved_paths.env) resolved_paths.env = {};
+ var resolved_paths = null;
- // Set PM2 HOME in case of child process using PM2 API
- resolved_paths.env['PM2_HOME'] = that.pm2_home;
+ // hardcode script name to use `serve` feature inside a process file
+ if (app.script === 'serve') {
+ app.script = path.resolve(__dirname, 'API', 'Serve.js')
+ }
- var additional_env = Modularizer.getAdditionalConf(resolved_paths.name);
- util._extend(resolved_paths.env, additional_env);
+ try {
+ resolved_paths = Common.resolveAppAttributes({
+ cwd : that.cwd,
+ pm2_home : that.pm2_home
+ }, app);
+ } catch (e) {
+ return next();
+ }
- resolved_paths.env = Common.mergeEnvironmentVariables(resolved_paths, opts.env, deployConf);
+ if (!resolved_paths.env) resolved_paths.env = {};
- delete resolved_paths.env.current_conf;
+ // Set PM2 HOME in case of child process using PM2 API
+ resolved_paths.env['PM2_HOME'] = that.pm2_home;
- // Is KM linked?
- resolved_paths.km_link = that.gl_is_km_linked;
+ var additional_env = Modularizer.getAdditionalConf(resolved_paths.name);
+ util._extend(resolved_paths.env, additional_env);
- that.Client.executeRemote('prepare', resolved_paths, function(err, data) {
- if (err) {
- Common.printError(conf.PREFIX_MSG_ERR + 'Process failed to launch %s', err.message ? err.message : err);
- return next();
- }
- if (data.length === 0) {
- Common.printError(conf.PREFIX_MSG_ERR + 'Process config loading failed', data);
- return next();
- }
+ resolved_paths.env = Common.mergeEnvironmentVariables(resolved_paths, opts.env, deployConf);
- Common.printOut(conf.PREFIX_MSG + 'App [%s] launched (%d instances)', data[0].pm2_env.name, data.length);
- apps_started = apps_started.concat(data);
- next();
- });
+ delete resolved_paths.env.current_conf;
- }, function(err) {
- return cb ? cb(err || null, apps_started) : that.speedList();
- });
- return false;
- }
-};
+ // Is KM linked?
+ resolved_paths.km_link = that.gl_is_km_linked;
-/**
- * Apply a RPC method on the json file
- * @private
- * @method actionFromJson
- * @param {string} action RPC Method
- * @param {object} options
- * @param {string|object} file file
- * @param {string} jsonVia action type (=only 'pipe' ?)
- * @param {Function}
- */
-API.prototype.actionFromJson = function(action, file, opts, jsonVia, cb) {
- var appConf = {};
- var ret_processes = [];
- var that = this;
-
- //accept programmatic calls
- if (typeof file == 'object') {
- cb = typeof jsonVia == 'function' ? jsonVia : cb;
- appConf = file;
- }
- else if (jsonVia == 'file') {
- var data = null;
+ that.Client.executeRemote('prepare', resolved_paths, function(err, data) {
+ if (err) {
+ Common.printError(conf.PREFIX_MSG_ERR + 'Process failed to launch %s', err.message ? err.message : err);
+ return next();
+ }
+ if (data.length === 0) {
+ Common.printError(conf.PREFIX_MSG_ERR + 'Process config loading failed', data);
+ return next();
+ }
- try {
- data = fs.readFileSync(file);
- } catch(e) {
- Common.printError(conf.PREFIX_MSG_ERR + 'File ' + file +' not found');
- return cb ? cb(Common.retErr(e)) : that.exitCli(conf.ERROR_EXIT);
- }
+ Common.printOut(conf.PREFIX_MSG + 'App [%s] launched (%d instances)', data[0].pm2_env.name, data.length);
+ apps_started = apps_started.concat(data);
+ next();
+ });
- try {
- appConf = Common.parseConfig(data, file);
- } catch(e) {
- Common.printError(conf.PREFIX_MSG_ERR + 'File ' + file + ' malformated');
- console.error(e);
- return cb ? cb(Common.retErr(e)) : that.exitCli(conf.ERROR_EXIT);
+ }, function(err) {
+ return cb ? cb(err || null, apps_started) : that.speedList();
+ });
+ return false;
}
- } else if (jsonVia == 'pipe') {
- appConf = Common.parseConfig(file, 'pipe');
- } else {
- Common.printError('Bad call to actionFromJson, jsonVia should be one of file, pipe');
- return that.exitCli(conf.ERROR_EXIT);
}
- // Backward compatibility
- if (appConf.apps)
- appConf = appConf.apps;
+ /**
+ * Apply a RPC method on the json file
+ * @private
+ * @method actionFromJson
+ * @param {string} action RPC Method
+ * @param {object} options
+ * @param {string|object} file file
+ * @param {string} jsonVia action type (=only 'pipe' ?)
+ * @param {Function}
+ */
+ actionFromJson (action, file, opts, jsonVia, cb) {
+ var appConf = {};
+ var ret_processes = [];
+ var that = this;
+
+ //accept programmatic calls
+ if (typeof file == 'object') {
+ cb = typeof jsonVia == 'function' ? jsonVia : cb;
+ appConf = file;
+ }
+ else if (jsonVia == 'file') {
+ var data = null;
- if (!Array.isArray(appConf))
- appConf = [appConf];
+ try {
+ data = fs.readFileSync(file);
+ } catch(e) {
+ Common.printError(conf.PREFIX_MSG_ERR + 'File ' + file +' not found');
+ return cb ? cb(Common.retErr(e)) : that.exitCli(conf.ERROR_EXIT);
+ }
- if ((appConf = Common.verifyConfs(appConf)) instanceof Error)
- return cb ? cb(appConf) : that.exitCli(conf.ERROR_EXIT);
+ try {
+ appConf = Common.parseConfig(data, file);
+ } catch(e) {
+ Common.printError(conf.PREFIX_MSG_ERR + 'File ' + file + ' malformated');
+ console.error(e);
+ return cb ? cb(Common.retErr(e)) : that.exitCli(conf.ERROR_EXIT);
+ }
+ } else if (jsonVia == 'pipe') {
+ appConf = Common.parseConfig(file, 'pipe');
+ } else {
+ Common.printError('Bad call to actionFromJson, jsonVia should be one of file, pipe');
+ return that.exitCli(conf.ERROR_EXIT);
+ }
- async.eachLimit(appConf, conf.CONCURRENT_ACTIONS, function(proc, next1) {
- var name = '';
- var new_env;
+ // Backward compatibility
+ if (appConf.apps)
+ appConf = appConf.apps;
- if (!proc.name)
- name = path.basename(proc.script);
- else
- name = proc.name;
+ if (!Array.isArray(appConf))
+ appConf = [appConf];
- if (opts.only && opts.only != name)
- return process.nextTick(next1);
+ if ((appConf = Common.verifyConfs(appConf)) instanceof Error)
+ return cb ? cb(appConf) : that.exitCli(conf.ERROR_EXIT);
- if (opts && opts.env)
- new_env = Common.mergeEnvironmentVariables(proc, opts.env);
- else
- new_env = Common.mergeEnvironmentVariables(proc);
+ async.eachLimit(appConf, conf.CONCURRENT_ACTIONS, function(proc, next1) {
+ var name = '';
+ var new_env;
- that.Client.getProcessIdByName(name, function(err, ids) {
- if (err) {
- Common.printError(err);
- return next1();
- }
- if (!ids) return next1();
+ if (!proc.name)
+ name = path.basename(proc.script);
+ else
+ name = proc.name;
- async.eachLimit(ids, conf.CONCURRENT_ACTIONS, function(id, next2) {
- var opts = {};
+ if (opts.only && opts.only != name)
+ return process.nextTick(next1);
- //stopProcessId could accept options to?
- if (action == 'restartProcessId') {
- opts = {id : id, env : new_env};
- } else {
- opts = id;
+ if (opts && opts.env)
+ new_env = Common.mergeEnvironmentVariables(proc, opts.env);
+ else
+ new_env = Common.mergeEnvironmentVariables(proc);
+
+ that.Client.getProcessIdByName(name, function(err, ids) {
+ if (err) {
+ Common.printError(err);
+ return next1();
}
+ if (!ids) return next1();
- that.Client.executeRemote(action, opts, function(err, res) {
- ret_processes.push(res);
- if (err) {
- Common.printError(err);
- return next2();
- }
+ async.eachLimit(ids, conf.CONCURRENT_ACTIONS, function(id, next2) {
+ var opts = {};
+ //stopProcessId could accept options to?
if (action == 'restartProcessId') {
- that.Client.notifyGod('restart', id);
- } else if (action == 'deleteProcessId') {
- that.Client.notifyGod('delete', id);
- } else if (action == 'stopProcessId') {
- that.Client.notifyGod('stop', id);
+ opts = {id : id, env : new_env};
+ } else {
+ opts = id;
}
- Common.printOut(conf.PREFIX_MSG + '[%s](%d) \u2713', name, id);
- return next2();
+ that.Client.executeRemote(action, opts, function(err, res) {
+ ret_processes.push(res);
+ if (err) {
+ Common.printError(err);
+ return next2();
+ }
+
+ if (action == 'restartProcessId') {
+ that.Client.notifyGod('restart', id);
+ } else if (action == 'deleteProcessId') {
+ that.Client.notifyGod('delete', id);
+ } else if (action == 'stopProcessId') {
+ that.Client.notifyGod('stop', id);
+ }
+
+ Common.printOut(conf.PREFIX_MSG + '[%s](%d) \u2713', name, id);
+ return next2();
+ });
+ }, function(err) {
+ return next1(null, ret_processes);
});
- }, function(err) {
- return next1(null, ret_processes);
});
+ }, function(err) {
+ if (cb) return cb(null, ret_processes);
+ else return that.speedList();
});
- }, function(err) {
- if (cb) return cb(null, ret_processes);
- else return that.speedList();
- });
-};
-
-
-/**
- * Main function to operate with PM2 daemon
- *
- * @param {String} action_name Name of action (restartProcessId, deleteProcessId, stopProcessId)
- * @param {String} process_name can be 'all', a id integer or process name
- * @param {Object} envs object with CLI options / environment
- */
-API.prototype._operate = function(action_name, process_name, envs, cb) {
- var that = this;
- var update_env = false;
- var ret = [];
-
- // Make sure all options exist
- if (!envs)
- envs = {};
-
- if (typeof(envs) == 'function'){
- cb = envs;
- envs = {};
}
- // Set via env.update (JSON processing)
- if (envs.updateEnv === true)
- update_env = true;
-
- var concurrent_actions = envs.parallel || conf.CONCURRENT_ACTIONS;
-
- if (!process.env.PM2_JSON_PROCESSING || envs.commands) {
- envs = that._handleAttributeUpdate(envs);
- }
/**
- * Set current updated configuration if not passed
+ * Main function to operate with PM2 daemon
+ *
+ * @param {String} action_name Name of action (restartProcessId, deleteProcessId, stopProcessId)
+ * @param {String} process_name can be 'all', a id integer or process name
+ * @param {Object} envs object with CLI options / environment
*/
- if (!envs.current_conf) {
- var _conf = fclone(envs);
- envs = {
- current_conf : _conf
+ _operate (action_name, process_name, envs, cb) {
+ var that = this;
+ var update_env = false;
+ var ret = [];
+
+ // Make sure all options exist
+ if (!envs)
+ envs = {};
+
+ if (typeof(envs) == 'function'){
+ cb = envs;
+ envs = {};
}
- // Is KM linked?
- envs.current_conf.km_link = that.gl_is_km_linked;
- }
+ // Set via env.update (JSON processing)
+ if (envs.updateEnv === true)
+ update_env = true;
- /**
- * Operate action on specific process id
- */
- function processIds(ids, cb) {
- Common.printOut(conf.PREFIX_MSG + 'Applying action %s on app [%s](ids: %s)', action_name, process_name, ids);
+ var concurrent_actions = envs.parallel || conf.CONCURRENT_ACTIONS;
+
+ if (!process.env.PM2_JSON_PROCESSING || envs.commands) {
+ envs = that._handleAttributeUpdate(envs);
+ }
+
+ /**
+ * Set current updated configuration if not passed
+ */
+ if (!envs.current_conf) {
+ var _conf = fclone(envs);
+ envs = {
+ current_conf : _conf
+ }
+
+ // Is KM linked?
+ envs.current_conf.km_link = that.gl_is_km_linked;
+ }
+
+ /**
+ * Operate action on specific process id
+ */
+ function processIds(ids, cb) {
+ Common.printOut(conf.PREFIX_MSG + 'Applying action %s on app [%s](ids: %s)', action_name, process_name, ids);
- if (action_name == 'deleteProcessId')
- concurrent_actions = 10;
+ if (action_name == 'deleteProcessId')
+ concurrent_actions = 10;
- async.eachLimit(ids, concurrent_actions, function(id, next) {
- var opts;
+ async.eachLimit(ids, concurrent_actions, function(id, next) {
+ var opts;
- // These functions need extra param to be passed
- if (action_name == 'restartProcessId' ||
+ // These functions need extra param to be passed
+ if (action_name == 'restartProcessId' ||
action_name == 'reloadProcessId' ||
action_name == 'softReloadProcessId') {
- var new_env = {};
+ var new_env = {};
- if (update_env === true) {
- if (conf.PM2_PROGRAMMATIC == true)
- new_env = Common.safeExtend({}, process.env);
- else
- new_env = util._extend({}, process.env);
+ if (update_env === true) {
+ if (conf.PM2_PROGRAMMATIC == true)
+ new_env = Common.safeExtend({}, process.env);
+ else
+ new_env = util._extend({}, process.env);
- Object.keys(envs).forEach(function(k) {
- new_env[k] = envs[k];
- });
+ Object.keys(envs).forEach(function(k) {
+ new_env[k] = envs[k];
+ });
+ }
+ else {
+ new_env = envs;
+ }
+
+ opts = {
+ id : id,
+ env : new_env
+ };
}
else {
- new_env = envs;
+ opts = id;
}
- opts = {
- id : id,
- env : new_env
- };
- }
- else {
- opts = id;
- }
-
- that.Client.executeRemote(action_name, opts, function(err, res) {
- if (err) {
- Common.printError(conf.PREFIX_MSG_ERR + 'Process %s not found', id);
- return next('Process not found');
- }
+ that.Client.executeRemote(action_name, opts, function(err, res) {
+ if (err) {
+ Common.printError(conf.PREFIX_MSG_ERR + 'Process %s not found', id);
+ return next('Process not found');
+ }
- if (action_name == 'restartProcessId') {
- that.Client.notifyGod('restart', id);
- } else if (action_name == 'deleteProcessId') {
- that.Client.notifyGod('delete', id);
- } else if (action_name == 'stopProcessId') {
- that.Client.notifyGod('stop', id);
- } else if (action_name == 'reloadProcessId') {
- that.Client.notifyGod('reload', id);
- } else if (action_name == 'softReloadProcessId') {
- that.Client.notifyGod('graceful reload', id);
- }
+ if (action_name == 'restartProcessId') {
+ that.Client.notifyGod('restart', id);
+ } else if (action_name == 'deleteProcessId') {
+ that.Client.notifyGod('delete', id);
+ } else if (action_name == 'stopProcessId') {
+ that.Client.notifyGod('stop', id);
+ } else if (action_name == 'reloadProcessId') {
+ that.Client.notifyGod('reload', id);
+ } else if (action_name == 'softReloadProcessId') {
+ that.Client.notifyGod('graceful reload', id);
+ }
- if (!Array.isArray(res))
- res = [res];
+ if (!Array.isArray(res))
+ res = [res];
- // Filter return
- res.forEach(function(proc) {
- Common.printOut(conf.PREFIX_MSG + '[%s](%d) \u2713', proc.pm2_env ? proc.pm2_env.name : process_name, id);
+ // Filter return
+ res.forEach(function(proc) {
+ Common.printOut(conf.PREFIX_MSG + '[%s](%d) \u2713', proc.pm2_env ? proc.pm2_env.name : process_name, id);
- if (!proc.pm2_env) return false;
+ if (!proc.pm2_env) return false;
- ret.push({
- name : proc.pm2_env.name,
- pm_id : proc.pm2_env.pm_id,
- status : proc.pm2_env.status,
- restart_time : proc.pm2_env.restart_time,
- pm2_env : {
+ ret.push({
name : proc.pm2_env.name,
pm_id : proc.pm2_env.pm_id,
status : proc.pm2_env.status,
restart_time : proc.pm2_env.restart_time,
- env : proc.pm2_env.env
- }
+ pm2_env : {
+ name : proc.pm2_env.name,
+ pm_id : proc.pm2_env.pm_id,
+ status : proc.pm2_env.status,
+ restart_time : proc.pm2_env.restart_time,
+ env : proc.pm2_env.env
+ }
+ });
});
- });
- return next();
+ return next();
+ });
+ }, function(err) {
+ if (err) return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
+ return cb ? cb(null, ret) : that.speedList();
});
- }, function(err) {
- if (err) return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
- return cb ? cb(null, ret) : that.speedList();
- });
- }
-
- if (process_name == 'all') {
- that.Client.getAllProcessId(function(err, ids) {
- if (err) {
- Common.printError(err);
- return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
- }
- if (!ids || ids.length === 0) {
- Common.printError(conf.PREFIX_MSG_WARNING + 'No process found');
- return cb ? cb(new Error('process name not found')) : that.exitCli(conf.ERROR_EXIT);
- }
-
- return processIds(ids, cb);
- });
- }
- // operate using regex
- else if (isNaN(process_name) && process_name[0] === '/' && process_name[process_name.length - 1] === '/') {
- var regex = new RegExp(process_name.replace(/\//g, ''));
+ }
- that.Client.executeRemote('getMonitorData', {}, function(err, list) {
- if (err) {
- Common.printError('Error retrieving process list: ' + err);
- return cb(err);
- }
- var found_proc = [];
- list.forEach(function(proc) {
- if (regex.test(proc.pm2_env.name)) {
- found_proc.push(proc.pm_id);
+ if (process_name == 'all') {
+ that.Client.getAllProcessId(function(err, ids) {
+ if (err) {
+ Common.printError(err);
+ return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
+ }
+ if (!ids || ids.length === 0) {
+ Common.printError(conf.PREFIX_MSG_WARNING + 'No process found');
+ return cb ? cb(new Error('process name not found')) : that.exitCli(conf.ERROR_EXIT);
}
- });
- if (found_proc.length === 0) {
- Common.printError(conf.PREFIX_MSG_WARNING + 'No process found');
- return cb ? cb(new Error('process name not found')) : that.exitCli(conf.ERROR_EXIT);
- }
+ return processIds(ids, cb);
+ });
+ }
+ // operate using regex
+ else if (isNaN(process_name) && process_name[0] === '/' && process_name[process_name.length - 1] === '/') {
+ var regex = new RegExp(process_name.replace(/\//g, ''));
- return processIds(found_proc, cb);
- });
- }
- else if (isNaN(process_name)) {
- /**
- * We can not stop or delete a module but we can restart it
- * to refresh configuration variable
- */
- var allow_module_restart = action_name == 'restartProcessId' ? true : false;
+ that.Client.executeRemote('getMonitorData', {}, function(err, list) {
+ if (err) {
+ Common.printError('Error retrieving process list: ' + err);
+ return cb(err);
+ }
+ var found_proc = [];
+ list.forEach(function(proc) {
+ if (regex.test(proc.pm2_env.name)) {
+ found_proc.push(proc.pm_id);
+ }
+ });
- that.Client.getProcessIdByName(process_name, allow_module_restart, function(err, ids) {
- if (err) {
- Common.printError(err);
- return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
- }
- if (!ids || ids.length === 0) {
- Common.printError(conf.PREFIX_MSG_ERR + 'Process %s not found', process_name);
- return cb ? cb(new Error('process name not found')) : that.exitCli(conf.ERROR_EXIT);
- }
+ if (found_proc.length === 0) {
+ Common.printError(conf.PREFIX_MSG_WARNING + 'No process found');
+ return cb ? cb(new Error('process name not found')) : that.exitCli(conf.ERROR_EXIT);
+ }
+ return processIds(found_proc, cb);
+ });
+ }
+ else if (isNaN(process_name)) {
/**
- * Determine if the process to restart is a module
- * if yes load configuration variables and merge with the current environment
+ * We can not stop or delete a module but we can restart it
+ * to refresh configuration variable
*/
- var additional_env = Modularizer.getAdditionalConf(process_name);
- util._extend(envs, additional_env);
-
- return processIds(ids, cb);
- });
- } else {
- // Check if application name as number is an app name
- that.Client.getProcessIdByName(process_name, function(err, ids) {
- if (ids.length > 0)
- return processIds(ids, cb);
- // Else operate on pm id
- return processIds([process_name], cb);
- });
- }
-};
-
-/**
- * Converts CamelCase Commander.js arguments
- * to Underscore
- * (nodeArgs -> node_args)
- */
-API.prototype._handleAttributeUpdate = function(opts) {
- var conf = Config.transCMDToConf(opts);
- var that = this;
-
- if (typeof(conf.name) != 'string')
- delete conf.name;
+ var allow_module_restart = action_name == 'restartProcessId' ? true : false;
- var argsIndex = 0;
- if (opts.rawArgs && (argsIndex = opts.rawArgs.indexOf('--')) >= 0) {
- conf.args = opts.rawArgs.slice(argsIndex + 1);
- }
+ that.Client.getProcessIdByName(process_name, allow_module_restart, function(err, ids) {
+ if (err) {
+ Common.printError(err);
+ return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
+ }
+ if (!ids || ids.length === 0) {
+ Common.printError(conf.PREFIX_MSG_ERR + 'Process %s not found', process_name);
+ return cb ? cb(new Error('process name not found')) : that.exitCli(conf.ERROR_EXIT);
+ }
- var appConf = Common.verifyConfs(conf)[0];
+ /**
+ * Determine if the process to restart is a module
+ * if yes load configuration variables and merge with the current environment
+ */
+ var additional_env = Modularizer.getAdditionalConf(process_name);
+ util._extend(envs, additional_env);
- if (appConf instanceof Error) {
- Common.printError('Error while transforming CamelCase args to underscore');
- return appConf;
+ return processIds(ids, cb);
+ });
+ } else {
+ // Check if application name as number is an app name
+ that.Client.getProcessIdByName(process_name, function(err, ids) {
+ if (ids.length > 0)
+ return processIds(ids, cb);
+ // Else operate on pm id
+ return processIds([process_name], cb);
+ });
+ }
}
- if (argsIndex == -1)
- delete appConf.args;
- if (appConf.name == 'undefined')
- delete appConf.name;
-
- delete appConf.exec_mode;
+ /**
+ * Converts CamelCase Commander.js arguments
+ * to Underscore
+ * (nodeArgs -> node_args)
+ */
+ _handleAttributeUpdate (opts) {
+ var conf = Config.transCMDToConf(opts);
+ var that = this;
- if (util.isArray(appConf.watch) && appConf.watch.length === 0) {
- if (!~opts.rawArgs.indexOf('--watch'))
- delete appConf.watch
- }
+ if (typeof(conf.name) != 'string')
+ delete conf.name;
- // Options set via environment variables
- if (process.env.PM2_DEEP_MONITORING)
- appConf.deep_monitoring = true;
-
- // Force deletion of defaults values set by commander
- // to avoid overriding specified configuration by user
- if (appConf.treekill === true)
- delete appConf.treekill;
- if (appConf.pmx === true)
- delete appConf.pmx;
- if (appConf.vizion === true)
- delete appConf.vizion;
- if (appConf.automation === true)
- delete appConf.automation;
- if (appConf.autorestart === true)
- delete appConf.autorestart;
-
- return appConf;
-};
+ var argsIndex = 0;
+ if (opts.rawArgs && (argsIndex = opts.rawArgs.indexOf('--')) >= 0) {
+ conf.args = opts.rawArgs.slice(argsIndex + 1);
+ }
-API.prototype.getProcessIdByName = function(name, cb) {
- var that = this;
+ var appConf = Common.verifyConfs(conf)[0];
- this.Client.getProcessIdByName(name, function(err, id) {
- if (err) {
- Common.printError(err);
- return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
+ if (appConf instanceof Error) {
+ Common.printError('Error while transforming CamelCase args to underscore');
+ return appConf;
}
- console.log(id);
- return cb ? cb(null, id) : that.exitCli(conf.SUCCESS_EXIT);
- });
-};
-/**
- * Description
- * @method jlist
- * @param {} debug
- * @return
- */
-API.prototype.jlist = function(debug) {
- var that = this;
+ if (argsIndex == -1)
+ delete appConf.args;
+ if (appConf.name == 'undefined')
+ delete appConf.name;
- that.Client.executeRemote('getMonitorData', {}, function(err, list) {
- if (err) {
- Common.printError(err);
- that.exitCli(conf.ERROR_EXIT);
- }
+ delete appConf.exec_mode;
- if (debug) {
- process.stdout.write(util.inspect(list, false, null, false));
- }
- else {
- process.stdout.write(JSON.stringify(list));
+ if (util.isArray(appConf.watch) && appConf.watch.length === 0) {
+ if (!~opts.rawArgs.indexOf('--watch'))
+ delete appConf.watch
}
- that.exitCli(conf.SUCCESS_EXIT);
+ // Options set via environment variables
+ if (process.env.PM2_DEEP_MONITORING)
+ appConf.deep_monitoring = true;
+
+ // Force deletion of defaults values set by commander
+ // to avoid overriding specified configuration by user
+ if (appConf.treekill === true)
+ delete appConf.treekill;
+ if (appConf.pmx === true)
+ delete appConf.pmx;
+ if (appConf.vizion === true)
+ delete appConf.vizion;
+ if (appConf.automation === true)
+ delete appConf.automation;
+ if (appConf.autorestart === true)
+ delete appConf.autorestart;
- });
-};
+ return appConf;
+ }
-var gl_retry = 0;
+ getProcessIdByName (name, cb) {
+ var that = this;
-/**
- * Description
- * @method speedList
- * @return
- */
-API.prototype.speedList = function(code) {
- var that = this;
+ this.Client.getProcessIdByName(name, function(err, id) {
+ if (err) {
+ Common.printError(err);
+ return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
+ }
+ console.log(id);
+ return cb ? cb(null, id) : that.exitCli(conf.SUCCESS_EXIT);
+ });
+ }
- // Do nothing if PM2 called programmatically and not called from CLI (also in exitCli)
- if (conf.PM2_PROGRAMMATIC && process.env.PM2_USAGE != 'CLI') return false;
+ /**
+ * Description
+ * @method jlist
+ * @param {} debug
+ * @return
+ */
+ jlist (debug) {
+ var that = this;
- that.Client.executeRemote('getMonitorData', {}, function(err, list) {
- if (err) {
- if (gl_retry == 0) {
- gl_retry += 1;
- return setTimeout(that.speedList.bind(that), 1400);
+ that.Client.executeRemote('getMonitorData', {}, function(err, list) {
+ if (err) {
+ Common.printError(err);
+ that.exitCli(conf.ERROR_EXIT);
}
- console.error('Error retrieving process list: %s.\nA process seems to be on infinite loop, retry in 5 seconds',err);
- return that.exitCli(conf.ERROR_EXIT);
- }
- if (process.stdout.isTTY === false) {
- UX.miniDisplay(list);
- }
- else if (commander.miniList && !commander.silent)
- UX.miniDisplay(list);
- else if (!commander.silent) {
- if (that.gl_interact_infos) {
- Common.printOut(chalk.green.bold('●') + ' Agent Online | Dashboard Access: ' + chalk.bold('https://app.keymetrics.io/#/r/%s') + ' | Server name: %s', that.gl_interact_infos.public_key, that.gl_interact_infos.machine_name);
+
+ if (debug) {
+ process.stdout.write(util.inspect(list, false, null, false));
+ }
+ else {
+ process.stdout.write(JSON.stringify(list));
}
- UX.dispAsTable(list, commander);
- Common.printOut(chalk.white.italic(' Use `pm2 show ` to get more details about an app'));
- }
- if (that.Client.daemon_mode == false) {
- Common.printOut('[--no-daemon] Continue to stream logs');
- Common.printOut('[--no-daemon] Exit on target PM2 exit pid=' + fs.readFileSync(conf.PM2_PID_FILE_PATH).toString());
- global._auto_exit = true;
- return that.streamLogs('all', 0, false, 'HH:mm:ss', false);
- }
- else if (commander.attach === true) {
- return that.streamLogs('all', 0, false, null, false);
- }
- else {
- return that.exitCli(code ? code : conf.SUCCESS_EXIT);
- }
- });
-}
+ that.exitCli(conf.SUCCESS_EXIT);
-/**
- * Scale up/down a process
- * @method scale
- */
-API.prototype.scale = function(app_name, number, cb) {
- var that = this;
-
- function addProcs(proc, value, cb) {
- (function ex(proc, number) {
- if (number-- === 0) return cb();
- Common.printOut(conf.PREFIX_MSG + 'Scaling up application');
- that.Client.executeRemote('duplicateProcessId', proc.pm2_env.pm_id, ex.bind(this, proc, number));
- })(proc, number);
+ });
}
- function rmProcs(procs, value, cb) {
- var i = 0;
+ /**
+ * Description
+ * @method speedList
+ * @return
+ */
+ speedList (code) {
+ var that = this;
- (function ex(procs, number) {
- if (number++ === 0) return cb();
- that._operate('deleteProcessId', procs[i++].pm2_env.pm_id, ex.bind(this, procs, number));
- })(procs, number);
- }
+ // Do nothing if PM2 called programmatically and not called from CLI (also in exitCli)
+ if (conf.PM2_PROGRAMMATIC && process.env.PM2_USAGE != 'CLI') return false;
- function end() {
- return cb ? cb(null, {success:true}) : that.speedList();
- }
+ that.Client.executeRemote('getMonitorData', {}, function(err, list) {
+ if (err) {
+ if (gl_retry == 0) {
+ gl_retry += 1;
+ return setTimeout(that.speedList.bind(that), 1400);
+ }
+ console.error('Error retrieving process list: %s.\nA process seems to be on infinite loop, retry in 5 seconds',err);
+ return that.exitCli(conf.ERROR_EXIT);
+ }
+ if (process.stdout.isTTY === false) {
+ UX.miniDisplay(list);
+ }
+ else if (commander.miniList && !commander.silent)
+ UX.miniDisplay(list);
+ else if (!commander.silent) {
+ if (that.gl_interact_infos) {
+ Common.printOut(chalk.green.bold('●') + ' Agent Online | Dashboard Access: ' + chalk.bold('https://app.keymetrics.io/#/r/%s') + ' | Server name: %s', that.gl_interact_infos.public_key, that.gl_interact_infos.machine_name);
+ }
+ UX.dispAsTable(list, commander);
+ Common.printOut(chalk.white.italic(' Use `pm2 show ` to get more details about an app'));
+ }
- this.Client.getProcessByName(app_name, function(err, procs) {
- if (err) {
- Common.printError(err);
- return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
- }
+ if (that.Client.daemon_mode == false) {
+ Common.printOut('[--no-daemon] Continue to stream logs');
+ Common.printOut('[--no-daemon] Exit on target PM2 exit pid=' + fs.readFileSync(conf.PM2_PID_FILE_PATH).toString());
+ global._auto_exit = true;
+ return that.streamLogs('all', 0, false, 'HH:mm:ss', false);
+ }
+ else if (commander.attach === true) {
+ return that.streamLogs('all', 0, false, null, false);
+ }
+ else {
+ return that.exitCli(code ? code : conf.SUCCESS_EXIT);
+ }
+ });
+ }
- if (!procs || procs.length === 0) {
- Common.printError(conf.PREFIX_MSG_ERR + 'Application %s not found', app_name);
- return cb ? cb(new Error('App not found')) : that.exitCli(conf.ERROR_EXIT);
+ /**
+ * Scale up/down a process
+ * @method scale
+ */
+ scale (app_name, number, cb) {
+ var that = this;
+
+ function addProcs(proc, value, cb) {
+ (function ex(proc, number) {
+ if (number-- === 0) return cb();
+ Common.printOut(conf.PREFIX_MSG + 'Scaling up application');
+ that.Client.executeRemote('duplicateProcessId', proc.pm2_env.pm_id, ex.bind(this, proc, number));
+ })(proc, number);
}
- var proc_number = procs.length;
+ function rmProcs(procs, value, cb) {
+ var i = 0;
- if (typeof(number) === 'string' && number.indexOf('+') >= 0) {
- number = parseInt(number, 10);
- return addProcs(procs[0], number, end);
+ (function ex(procs, number) {
+ if (number++ === 0) return cb();
+ that._operate('deleteProcessId', procs[i++].pm2_env.pm_id, ex.bind(this, procs, number));
+ })(procs, number);
}
- else if (typeof(number) === 'string' && number.indexOf('-') >= 0) {
- number = parseInt(number, 10);
- return rmProcs(procs[0], number, end);
+
+ function end() {
+ return cb ? cb(null, {success:true}) : that.speedList();
}
- else {
- number = parseInt(number, 10);
- number = number - proc_number;
- if (number < 0)
- return rmProcs(procs, number, end);
- else if (number > 0)
+ this.Client.getProcessByName(app_name, function(err, procs) {
+ if (err) {
+ Common.printError(err);
+ return cb ? cb(Common.retErr(err)) : that.exitCli(conf.ERROR_EXIT);
+ }
+
+ if (!procs || procs.length === 0) {
+ Common.printError(conf.PREFIX_MSG_ERR + 'Application %s not found', app_name);
+ return cb ? cb(new Error('App not found')) : that.exitCli(conf.ERROR_EXIT);
+ }
+
+ var proc_number = procs.length;
+
+ if (typeof(number) === 'string' && number.indexOf('+') >= 0) {
+ number = parseInt(number, 10);
return addProcs(procs[0], number, end);
+ }
+ else if (typeof(number) === 'string' && number.indexOf('-') >= 0) {
+ number = parseInt(number, 10);
+ return rmProcs(procs[0], number, end);
+ }
else {
- Common.printError(conf.PREFIX_MSG_ERR + 'Nothing to do');
- return cb ? cb(new Error('Same process number')) : that.exitCli(conf.ERROR_EXIT);
+ number = parseInt(number, 10);
+ number = number - proc_number;
+
+ if (number < 0)
+ return rmProcs(procs, number, end);
+ else if (number > 0)
+ return addProcs(procs[0], number, end);
+ else {
+ Common.printError(conf.PREFIX_MSG_ERR + 'Nothing to do');
+ return cb ? cb(new Error('Same process number')) : that.exitCli(conf.ERROR_EXIT);
+ }
}
- }
- });
-};
+ });
+ }
-/**
- * Description
- * @method describeProcess
- * @param {} pm2_id
- * @return
- */
-API.prototype.describe = function(pm2_id, cb) {
- var that = this;
+ /**
+ * Description
+ * @method describeProcess
+ * @param {} pm2_id
+ * @return
+ */
+ describe (pm2_id, cb) {
+ var that = this;
- var found_proc = [];
+ var found_proc = [];
- that.Client.executeRemote('getMonitorData', {}, function(err, list) {
- if (err) {
- Common.printError('Error retrieving process list: ' + err);
- that.exitCli(conf.ERROR_EXIT);
- }
+ that.Client.executeRemote('getMonitorData', {}, function(err, list) {
+ if (err) {
+ Common.printError('Error retrieving process list: ' + err);
+ that.exitCli(conf.ERROR_EXIT);
+ }
- list.forEach(function(proc) {
- if ((!isNaN(pm2_id) && proc.pm_id == pm2_id) ||
+ list.forEach(function(proc) {
+ if ((!isNaN(pm2_id) && proc.pm_id == pm2_id) ||
(typeof(pm2_id) === 'string' && proc.name == pm2_id)) {
- found_proc.push(proc);
+ found_proc.push(proc);
+ }
+ });
+
+ if (found_proc.length === 0) {
+ Common.printError(conf.PREFIX_MSG_WARNING + '%s doesn\'t exist', pm2_id);
+ return cb ? cb(null, []) : that.exitCli(conf.ERROR_EXIT);
+ }
+
+ if (!cb) {
+ found_proc.forEach(function(proc) {
+ UX.describeTable(proc);
+ });
}
+
+ return cb ? cb(null, found_proc) : that.exitCli(conf.SUCCESS_EXIT);
});
+ }
- if (found_proc.length === 0) {
- Common.printError(conf.PREFIX_MSG_WARNING + '%s doesn\'t exist', pm2_id);
- return cb ? cb(null, []) : that.exitCli(conf.ERROR_EXIT);
- }
+ /**
+ * API method to perform a deep update of PM2
+ * @method deepUpdate
+ */
+ deepUpdate (cb) {
+ var that = this;
- if (!cb) {
- found_proc.forEach(function(proc) {
- UX.describeTable(proc);
- });
- }
+ Common.printOut(conf.PREFIX_MSG + 'Updating PM2...');
- return cb ? cb(null, found_proc) : that.exitCli(conf.SUCCESS_EXIT);
- });
+ var exec = require('shelljs').exec;
+ var child = exec("npm i -g pm2@latest; pm2 update", {async : true});
+
+ child.stdout.on('end', function() {
+ Common.printOut(conf.PREFIX_MSG + 'PM2 successfully updated');
+ cb ? cb(null, {success:true}) : that.exitCli(conf.SUCCESS_EXIT);
+ });
+ }
};
-/**
- * API method to perform a deep update of PM2
- * @method deepUpdate
- */
-API.prototype.deepUpdate = function(cb) {
- var that = this;
- Common.printOut(conf.PREFIX_MSG + 'Updating PM2...');
+//////////////////////////
+// Load all API methods //
+//////////////////////////
+
+require('./API/Extra.js')(API);
+require('./API/Interaction.js')(API);
+require('./API/Deploy.js')(API);
+require('./API/Modules/Modules.js')(API);
+require('./API/Keymetrics/cli-api.js')(API);
+require('./API/Configuration.js')(API);
+require('./API/Version.js')(API);
+require('./API/Startup.js')(API);
+require('./API/LogManagement.js')(API);
+require('./API/Containerizer.js')(API);
- var exec = require('shelljs').exec;
- var child = exec("npm i -g pm2@latest; pm2 update", {async : true});
- child.stdout.on('end', function() {
- Common.printOut(conf.PREFIX_MSG + 'PM2 successfully updated');
- cb ? cb(null, {success:true}) : that.exitCli(conf.SUCCESS_EXIT);
- });
-};
+module.exports = API;
diff --git a/lib/API/Extra.js b/lib/API/Extra.js
index 00f445dde..cf7a23fcf 100644
--- a/lib/API/Extra.js
+++ b/lib/API/Extra.js
@@ -15,6 +15,7 @@ var fs = require('fs');
var fmt = require('../tools/fmt.js');
var moment = require('moment');
var pkg = require('../../package.json');
+const semver = require('semver');
module.exports = function(CLI) {
@@ -38,7 +39,6 @@ module.exports = function(CLI) {
*/
CLI.prototype.report = function() {
var that = this;
- var semver = require('semver');
function reporting(cb) {
@@ -639,4 +639,27 @@ module.exports = function(CLI) {
launchMonitor();
};
+
+ CLI.prototype.inspect = function(app_name, cb) {
+ const that = this;
+ if(semver.satisfies(process.versions.node, '>= 8.0.0')) {
+ this.trigger(app_name, 'internal:inspect', function (err, res) {
+
+ if(res && res[0]) {
+ if (res[0].data.return === '') {
+ Common.printOut(`Inspect disabled on ${app_name}`);
+ } else {
+ Common.printOut(`Inspect enabled on ${app_name} => go to chrome : chrome://inspect !!!`);
+ }
+ } else {
+ Common.printOut(`Unable to activate inspect mode on ${app_name} !!!`);
+ }
+
+ that.exitCli(cst.SUCCESS_EXIT);
+ });
+ } else {
+ Common.printOut('Inspect is available for node version >=8.x !');
+ that.exitCli(cst.SUCCESS_EXIT);
+ }
+ };
};
diff --git a/lib/API/Modules/Modularizer.js b/lib/API/Modules/Modularizer.js
index 7093324bf..e738255ed 100644
--- a/lib/API/Modules/Modularizer.js
+++ b/lib/API/Modules/Modularizer.js
@@ -6,6 +6,7 @@
var shelljs = require('shelljs');
var path = require('path');
var fs = require('fs');
+var os = require('os');
var async = require('async');
var p = path;
var readline = require('readline');
@@ -185,7 +186,7 @@ Modularizer.installModule = function(CLI, module_name, opts, cb) {
var install_path = path.join(cst.DEFAULT_MODULE_PATH, canonic_module_name);
mkdirp(install_path, function() {
- process.chdir(process.env.HOME);
+ process.chdir(os.homedir());
var install_instance = spawn(cst.IS_WINDOWS ? 'npm.cmd' : 'npm', ['install', module_name, '--loglevel=error', '--prefix', install_path ], {
stdio : 'inherit',
diff --git a/lib/API/Startup.js b/lib/API/Startup.js
index 5249acc5d..b96877fe8 100644
--- a/lib/API/Startup.js
+++ b/lib/API/Startup.js
@@ -7,6 +7,7 @@ var debug = require('debug')('pm2:cli:startup');
var chalk = require('chalk');
var path = require('path');
var fs = require('fs');
+const fsExtra = require('fs-extra');
var async = require('async');
var exec = require('child_process').exec;
var Common = require('../Common.js');
@@ -371,13 +372,32 @@ module.exports = function(CLI) {
* @return
*/
function fin(err) {
+
+ // try to fix issues with empty dump file
+ // like #3485
+ if (env_arr.length === 0) {
+
+ // fix : if no dump file, no process, only module and after pm2 update
+ if (!fs.existsSync(cst.DUMP_FILE_PATH)) {
+ that.clearDump(function(){});
+ }
+
+ // if no process in list don't modify dump file
+ // process list should not be empty
+ if(cb) {
+ return cb(null, {success: true});
+ } else {
+ Common.printOut(cst.PREFIX_MSG + 'Nothing to save !!!');
+ Common.printOut(cst.PREFIX_MSG + 'In this case we keep old dump file. To clear dump file you can delete it manually !');
+ that.exitCli(cst.SUCCESS_EXIT);
+ return;
+ }
+ }
+
// Back up dump file
try {
if (fs.existsSync(cst.DUMP_FILE_PATH)) {
- if (fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)) {
- fs.unlinkSync(cst.DUMP_BACKUP_FILE_PATH);
- }
- fs.renameSync(cst.DUMP_FILE_PATH, cst.DUMP_BACKUP_FILE_PATH);
+ fsExtra.copySync(cst.DUMP_FILE_PATH, cst.DUMP_BACKUP_FILE_PATH);
}
} catch (e) {
console.error(e.stack || e);
@@ -390,8 +410,13 @@ module.exports = function(CLI) {
} catch (e) {
console.error(e.stack || e);
try {
- fs.unlinkSync(cst.DUMP_FILE_PATH);
+ // try to backup file
+ if(fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)) {
+ fsExtra.copySync(cst.DUMP_BACKUP_FILE_PATH, cst.DUMP_FILE_PATH);
+ }
} catch (e) {
+ // don't keep broken file
+ fs.unlinkSync(cst.DUMP_FILE_PATH);
console.error(e.stack || e);
}
Common.printOut(cst.PREFIX_MSG_ERR + 'Failed to save dump file in %s', cst.DUMP_FILE_PATH);
@@ -415,6 +440,21 @@ module.exports = function(CLI) {
});
};
+ /**
+ * Remove DUMP_FILE_PATH file and DUMP_BACKUP_FILE_PATH file
+ * @method dump
+ * @param {} cb
+ * @return
+ */
+ CLI.prototype.clearDump = function(cb) {
+ fs.writeFileSync(cst.DUMP_FILE_PATH, JSON.stringify([]));
+
+ if(cb && typeof cb === 'function') return cb();
+
+ Common.printOut(cst.PREFIX_MSG + 'Successfully created %s', cst.DUMP_FILE_PATH);
+ return this.exitCli(cst.SUCCESS_EXIT);
+ };
+
/**
* Resurrect processes
* @method resurrect
diff --git a/lib/API/Version.js b/lib/API/Version.js
index 8f5bb93ba..844953174 100644
--- a/lib/API/Version.js
+++ b/lib/API/Version.js
@@ -21,11 +21,11 @@ module.exports = function(CLI) {
printOut(cst.PREFIX_MSG + 'Updating repository for process name %s', process_name);
- that.Client.getProcessByName(process_name, function(err, processes) {
+ that.Client.getProcessByNameOrId(process_name, function (err, processes) {
- if (processes.length === 0) {
- printError('No processes with this name: %s', process_name);
- return cb ? cb({msg:'Process not found: '+process_name}) : that.exitCli(cst.ERROR_EXIT);
+ if (err || processes.length === 0) {
+ printError('No processes with this name or id : %s', process_name);
+ return cb ? cb({msg: 'Process not found: ' + process_name}) : that.exitCli(cst.ERROR_EXIT);
}
var proc = processes[0];
@@ -82,11 +82,11 @@ module.exports = function(CLI) {
printOut(cst.PREFIX_MSG + 'Updating repository for process name %s', process_name);
- that.Client.getProcessByName(process_name, function(err, processes) {
+ that.Client.getProcessByNameOrId(process_name, function (err, processes) {
- if (processes.length === 0) {
- printError('No processes with this name: %s', process_name);
- return cb ? cb({msg:'Process not found: ' + process_name}) : that.exitCli(cst.ERROR_EXIT);
+ if (err || processes.length === 0) {
+ printError('No processes with this name or id : %s', process_name);
+ return cb ? cb({msg: 'Process not found: ' + process_name}) : that.exitCli(cst.ERROR_EXIT);
}
var proc = processes[0];
@@ -138,14 +138,16 @@ module.exports = function(CLI) {
var that = this;
printOut(cst.PREFIX_MSG + 'Downgrading to previous commit repository for process name %s', process_name);
- that.Client.getProcessByName(process_name, function(err, processes) {
+ that.Client.getProcessByNameOrId(process_name, function (err, processes) {
- if (processes.length === 0) {
- printError('No processes with this name: %s', process_name);
- return cb ? cb({msg:'Process not found: '+process_name}) : that.exitCli(cst.ERROR_EXIT);
+ if (err || processes.length === 0) {
+ printError('No processes with this name or id : %s', process_name);
+ return cb ? cb({msg: 'Process not found: ' + process_name}) : that.exitCli(cst.ERROR_EXIT);
}
var proc = processes[0];
+ // in case user searched by id/pid
+ process_name = proc.name;
if (proc.pm2_env.versioning === undefined ||
proc.pm2_env.versioning === null)
@@ -194,14 +196,16 @@ module.exports = function(CLI) {
var that = this;
printOut(cst.PREFIX_MSG + 'Updating to next commit repository for process name %s', process_name);
- that.Client.getProcessByName(process_name, function(err, processes) {
+ that.Client.getProcessByNameOrId(process_name, function (err, processes) {
- if (processes.length === 0) {
- printError('No processes with this name: %s', process_name);
- return cb ? cb({msg:'Process not found: '+process_name}) : that.exitCli(cst.ERROR_EXIT);
+ if (err || processes.length === 0) {
+ printError('No processes with this name or id: %s', process_name);
+ return cb ? cb({msg: 'Process not found: ' + process_name}) : that.exitCli(cst.ERROR_EXIT);
}
var proc = processes[0];
+ // in case user searched by id/pid
+ process_name = proc.name;
if (proc.pm2_env.versioning) {
vizion.next({folder: proc.pm2_env.versioning.repo_path}, function(err, meta) {
if (err !== null)
@@ -366,16 +370,6 @@ module.exports = function(CLI) {
this._pull({process_name: process_name, action: 'reload'}, cb);
};
- /**
- * CLI method for updating a repository
- * @method pullAndGracefulReload
- * @param {string} process_name name of processes to pull
- * @return
- */
- CLI.prototype.pullAndGracefulReload = function (process_name, cb) {
- this._pull({process_name: process_name, action: 'gracefulReload'}, cb);
- };
-
/**
* CLI method for updating a repository to a specific commit id
* @method pullCommitId
diff --git a/lib/API/schema.json b/lib/API/schema.json
index 79bef624e..7bafbea8a 100644
--- a/lib/API/schema.json
+++ b/lib/API/schema.json
@@ -246,21 +246,6 @@
"boolean"
]
},
- "v8": {
- "type": [
- "boolean"
- ]
- },
- "event_loop_inspector": {
- "type": [
- "boolean"
- ]
- },
- "deep_monitoring": {
- "type": [
- "boolean"
- ]
- },
"increment_var": {
"type": "string",
"docDescription": "Specify the name of an environment variable to inject which increments for each cluster"
diff --git a/lib/Client.js b/lib/Client.js
index 74103fd3b..0b7855157 100644
--- a/lib/Client.js
+++ b/lib/Client.js
@@ -717,3 +717,25 @@ Client.prototype.getProcessByName = function(name, cb) {
return cb(null, found_proc);
});
};
+
+Client.prototype.getProcessByNameOrId = function (nameOrId, cb) {
+ var foundProc = [];
+
+ this.executeRemote('getMonitorData', {}, function (err, list) {
+ if (err) {
+ Common.printError('Error retrieving process list: ' + err);
+ return cb(err);
+ }
+
+ list.forEach(function (proc) {
+ if (proc.pm2_env.name === nameOrId ||
+ proc.pm2_env.pm_exec_path === path.resolve(nameOrId) ||
+ proc.pid === parseInt(nameOrId) ||
+ proc.pm2_env.pm_id === parseInt(nameOrId)) {
+ foundProc.push(proc);
+ }
+ });
+
+ return cb(null, foundProc);
+ });
+};
diff --git a/lib/Common.js b/lib/Common.js
index 2dd053aab..a8eeec1ff 100644
--- a/lib/Common.js
+++ b/lib/Common.js
@@ -247,15 +247,17 @@ Common.prepareAppConf = function(opts, app) {
* @param {string} filename
* @return {mixed} null if not conf file, json or yaml if conf
*/
-Common.isConfigFile = function(filename) {
- if (typeof(filename) != 'string')
+Common.isConfigFile = function (filename) {
+ if (typeof (filename) !== 'string')
return null;
- if (filename.indexOf('.json') != -1)
+ if (filename.indexOf('.json') !== -1)
return 'json';
if (filename.indexOf('.yml') > -1 || filename.indexOf('.yaml') > -1)
return 'yaml';
- if (filename.indexOf('.config.js') != -1)
+ if (filename.indexOf('.config.js') !== -1)
return 'js';
+ if (filename.indexOf('.config.mjs') !== -1)
+ return 'mjs';
return null;
};
@@ -288,7 +290,7 @@ Common.parseConfig = function(confObj, filename) {
filename.indexOf('.yaml') > -1) {
return yamljs.parse(confObj.toString());
}
- else if (filename.indexOf('.config.js') > -1) {
+ else if (filename.indexOf('.config.js') > -1 || filename.indexOf('.config.mjs') > -1) {
var confPath = require.resolve(path.resolve(filename));
delete require.cache[confPath];
return require(confPath);
diff --git a/lib/Daemon.js b/lib/Daemon.js
index 26c9c98ef..c1d7019ff 100644
--- a/lib/Daemon.js
+++ b/lib/Daemon.js
@@ -153,7 +153,7 @@ Daemon.prototype.innerStart = function(cb) {
var profiler;
try {
- profiler = require('v8-profiler');
+ profiler = require('v8-profiler-node8');
} catch(e) {
profiler = null;
}
@@ -231,7 +231,6 @@ Daemon.prototype.innerStart = function(cb) {
notifyByProcessId : God.notifyByProcessId,
notifyKillPM2 : God.notifyKillPM2,
- forceGc : God.forceGc,
monitor : God.monitor,
unmonitor : God.unmonitor,
diff --git a/lib/God/ActionMethods.js b/lib/God/ActionMethods.js
index 65cb64157..1556a1652 100644
--- a/lib/God/ActionMethods.js
+++ b/lib/God/ActionMethods.js
@@ -12,6 +12,7 @@
*/
var fs = require('fs');
+const fsExtra = require('fs-extra');
var path = require('path');
var async = require('async');
var os = require('os');
@@ -137,13 +138,25 @@ module.exports = function(God) {
}
function fin(err) {
+
+ // try to fix issues with empty dump file
+ // like #3485
+ if (process_list.length === 0) {
+
+ // fix : if no dump file, no process, only module and after pm2 update
+ if (!fs.existsSync(cst.DUMP_FILE_PATH)) {
+ that.clearDump(function(){});
+ }
+
+ // if no process in list don't modify dump file
+ // process list should not be empty
+ return cb(null, {success:true, process_list: process_list});
+ }
+
// Back up dump file
try {
if (fs.existsSync(cst.DUMP_FILE_PATH)) {
- if (fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)) {
- fs.unlinkSync(cst.DUMP_BACKUP_FILE_PATH);
- }
- fs.renameSync(cst.DUMP_FILE_PATH, cst.DUMP_BACKUP_FILE_PATH);
+ fsExtra.copySync(cst.DUMP_FILE_PATH, cst.DUMP_BACKUP_FILE_PATH);
}
} catch (e) {
console.error(e.stack || e);
@@ -155,8 +168,13 @@ module.exports = function(God) {
} catch (e) {
console.error(e.stack || e);
try {
- fs.unlinkSync(cst.DUMP_FILE_PATH);
+ // try to backup file
+ if(fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)) {
+ fsExtra.copySync(cst.DUMP_BACKUP_FILE_PATH, cst.DUMP_FILE_PATH);
+ }
} catch (e) {
+ // don't keep broken file
+ fs.unlinkSync(cst.DUMP_FILE_PATH);
console.error(e.stack || e);
}
}
diff --git a/lib/God/Methods.js b/lib/God/Methods.js
index e7b8e9fa3..ea6753a2c 100644
--- a/lib/God/Methods.js
+++ b/lib/God/Methods.js
@@ -247,21 +247,4 @@ module.exports = function(God) {
pm2_env.unstable_restarts = 0;
};
- /**
- * Description
- * @method forcegc
- * @return
- */
- God.forceGc = function(opts, cb) {
- if (global.gc) {
- global.gc();
- debug('Garbage collection triggered successfully');
- if (cb) cb(null, {success: true});
- }
- else {
- debug('Garbage collection failed');
- if (cb) cb(null, {success: false});
- }
- };
-
};
diff --git a/lib/God/Reload.js b/lib/God/Reload.js
index d55cad1cc..5472f3b4e 100644
--- a/lib/God/Reload.js
+++ b/lib/God/Reload.js
@@ -174,7 +174,7 @@ function hardReload(God, id, wait_msg, cb) {
module.exports = function(God) {
/**
- * GracefulReload
+ * Reload
* @method softReloadProcessId
* @param {} id
* @param {} cb
diff --git a/lib/Interactor/RemoteActions/Pm2Actions.js b/lib/Interactor/RemoteActions/Pm2Actions.js
index a6de7c611..b5edd93bb 100644
--- a/lib/Interactor/RemoteActions/Pm2Actions.js
+++ b/lib/Interactor/RemoteActions/Pm2Actions.js
@@ -21,7 +21,6 @@ var Password = require('../Password.js');
var PM2_REMOTE_METHOD_ALLOWED = {
'restart' : {},
'reload' : {},
- 'gracefulReload' : {},
'reset' : {},
'scale' : {},
diff --git a/lib/ProcessContainer.js b/lib/ProcessContainer.js
index db9540dd6..0d739bac9 100644
--- a/lib/ProcessContainer.js
+++ b/lib/ProcessContainer.js
@@ -30,15 +30,7 @@ delete process.env.pm2_env;
(function ProcessContainer() {
var fs = require('fs');
- if (process.env.pmx !== 'false') {
- require('pmx').init({
- transactions: (process.env.km_link === 'true' && (process.env.trace === 'true' || process.env.deep_monitoring === 'true')) || false,
- http: process.env.km_link === 'true' || false,
- v8: process.env.v8 === 'true' || process.env.deep_monitoring === 'true' || false,
- event_loop_dump: process.env.event_loop_inspector === 'true' || process.env.deep_monitoring === 'true' || false,
- deep_metrics: process.env.deep_monitoring === 'true' || false
- });
- }
+ require('./ProcessUtils').injectModules();
var stdFile = pm2_env.pm_log_path;
var outFile = pm2_env.pm_out_log_path;
diff --git a/lib/ProcessContainerFork.js b/lib/ProcessContainerFork.js
index 6d1b0cebb..59c45d3fb 100644
--- a/lib/ProcessContainerFork.js
+++ b/lib/ProcessContainerFork.js
@@ -1,18 +1,10 @@
-/**
+ /**
* Copyright 2013 the PM2 project authors. All rights reserved.
* Use of this source code is governed by a license that
* can be found in the LICENSE file.
*/
// Inject custom modules
-if (process.env.pmx !== 'false') {
- require('pmx').init({
- transactions: (process.env.km_link === 'true' && (process.env.trace === 'true' || process.env.deep_monitoring === 'true')) || false,
- http: process.env.km_link === 'true' || false,
- v8: process.env.v8 === 'true' || process.env.deep_monitoring === 'true' || false,
- event_loop_dump: process.env.event_loop_inspector === 'true' || process.env.deep_monitoring === 'true' || false,
- deep_metrics: process.env.deep_monitoring === 'true' || false
- });
-}
+require('./ProcessUtils').injectModules();
if (typeof(process.env.source_map_support) != "undefined" &&
process.env.source_map_support !== "false") {
diff --git a/lib/ProcessUtils.js b/lib/ProcessUtils.js
new file mode 100644
index 000000000..3e90117e3
--- /dev/null
+++ b/lib/ProcessUtils.js
@@ -0,0 +1,29 @@
+module.exports = {
+ injectModules: function() {
+ if (process.env.pmx !== 'false') {
+ const pmx = require('pmx');
+ pmx.init({
+ transactions: (process.env.km_link === 'true' && (process.env.trace === 'true' || process.env.deep_monitoring === 'true')) || false,
+ http: process.env.km_link === 'true' || false,
+ v8: process.env.v8 === 'true' || process.env.deep_monitoring === 'true' || false,
+ event_loop_dump: process.env.event_loop_inspector === 'true' || process.env.deep_monitoring === 'true' || false,
+ deep_metrics: process.env.deep_monitoring === 'true' || false
+ });
+
+ if(require('semver').satisfies(process.versions.node, '>= 8.0.0')) {
+ var url = '';
+ pmx.action('internal:inspect', function(reply) {
+ const inspector = require('inspector');
+ if(url === '') {
+ inspector.open();
+ url = inspector.url();
+ } else {
+ inspector.close();
+ url = '';
+ }
+ reply(url);
+ });
+ }
+ }
+ }
+};
diff --git a/lib/Satan.js b/lib/Satan.js
index e6df06ba9..1fc6651e7 100644
--- a/lib/Satan.js
+++ b/lib/Satan.js
@@ -215,7 +215,6 @@ Satan.remoteWrapper = function() {
killMe : God.killMe,
notifyKillPM2 : God.notifyKillPM2,
- forceGc : God.forceGc,
findByFullPath : God.findByFullPath,
diff --git a/package.json b/package.json
index 1855d6c34..4acaa133d 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"preferGlobal": true,
"version": "2.10.1",
"engines": {
- "node": ">=0.12"
+ "node": ">=4.0.0"
},
"directories": {
"bin": "./bin",
@@ -161,17 +161,18 @@
"dependencies": {
"async": "^2.5",
"blessed": "^0.1.81",
- "chalk": "^1.1",
- "chokidar": "^2",
+ "chalk": "^2.3.1",
+ "chokidar": "^2.0.2",
"cli-table-redemption": "^1.0.0",
- "commander": "2.13.0",
+ "commander": "2.14.1",
"cron": "^1.3",
"debug": "^3.0",
- "eventemitter2": "1.0.5",
+ "eventemitter2": "5.0.1",
"fclone": "1.0.11",
+ "fs-extra": "^5.0.0",
"mkdirp": "0.5.1",
"moment": "^2.19",
- "needle": "^2.1.0",
+ "needle": "^2.2.0",
"nssocket": "0.6.0",
"pidusage": "^1.2.0",
"pm2-axon": "3.1.0",
@@ -181,7 +182,7 @@
"pmx": "^1.6",
"promptly": "2.2.0",
"semver": "^5.3",
- "shelljs": "0.7.8",
+ "shelljs": "0.8.1",
"source-map-support": "^0.5",
"sprintf-js": "1.1.1",
"v8-compile-cache": "^1.1.0",
@@ -190,7 +191,7 @@
},
"devDependencies": {
"mocha": "^3.5",
- "should": "^11"
+ "should": "^13"
},
"optionalDependencies": {
"gkt": "https://tgz.pm2.io/gkt-1.0.0.tgz"
diff --git a/test/bash/app-config-update.sh b/test/bash/app-config-update.sh
index 8ef0a532c..1807110eb 100644
--- a/test/bash/app-config-update.sh
+++ b/test/bash/app-config-update.sh
@@ -58,14 +58,10 @@ $pm2 reload app-config-update/echo.js --node-args="--harmony"
$pm2 prettylist | grep "node_args: \[ '--harmony' \]"
spec "Should application have one node argument"
-$pm2 gracefulReload app-config-update/echo.js --node-args="--harmony"
-$pm2 prettylist | grep "node_args: \[ '--harmony' \]"
-spec "Should application have two node arguments"
-
$pm2 prettylist | grep "node_args"
spec "Should have found parameter"
# Now set node-args to null
-$pm2 gracefulReload app-config-update/echo.js --node-args=null
+$pm2 reload app-config-update/echo.js --node-args=null
# Should not find node_args anymore
$pm2 prettylist | grep "node_args"
ispec "Should have deleted cli parameter when passing null"
@@ -74,8 +70,3 @@ $pm2 reload echo --name="new-name"
$pm2 reset all
$pm2 restart new-name
should 'should reload processes with new name' 'restart_time: 1' 1
-
-$pm2 gracefulReload new-name --name="new-name-2"
-$pm2 reset all
-$pm2 restart new-name-2
-should 'should graceful reload processes with new name' 'restart_time: 1' 1
diff --git a/test/bash/gracefulReload.sh b/test/bash/gracefulReload.sh
deleted file mode 100644
index e7ed9fce5..000000000
--- a/test/bash/gracefulReload.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env bash
-
-SRC=$(cd $(dirname "$0"); pwd)
-source "${SRC}/include.sh"
-
-cd $file_path
-
-echo "################## GRACEFUL RELOAD ###################"
-
-###############
-
-echo "Launching"
-$pm2 start graceful-exit.js -i 4 --name="graceful" -o "grace.log" -e "grace-err.log"
-should 'should start processes' 'online' 4
-
-OUT_LOG=`$pm2 prettylist | grep -m 1 -E "pm_out_log_path:" | sed "s/.*'\([^']*\)',/\1/"`
-cat /dev/null > $OUT_LOG
-
-#### Graceful reload all
-
-$pm2 gracefulReload all
-
-OUT=`grep "Finished closing connections" "$OUT_LOG" | wc -l`
-[ $OUT -eq 1 ] || fail "Process not restarted gracefuly"
-success "Process restarted gracefuly"
-
-
-cat /dev/null > $OUT_LOG
-
-#### Graceful reload name
-$pm2 gracefulReload graceful
-
-OUT=`grep "Finished closing connections" "$OUT_LOG" | wc -l`
-[ $OUT -eq 1 ] || fail "Process not restarted gracefuly"
-success "Process restarted gracefuly"
diff --git a/test/bash/gracefulReload2.sh b/test/bash/gracefulReload2.sh
deleted file mode 100644
index b7c25fdd4..000000000
--- a/test/bash/gracefulReload2.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env bash
-
-SRC=$(cd $(dirname "$0"); pwd)
-source "${SRC}/include.sh"
-
-cd $file_path
-
-echo "################## GRACEFUL RELOAD 2 ###################"
-
-echo "Launching"
-$pm2 start graceful-exit-no-listen.js -i 2 --name="graceful2" -o "grace2.log" -e "grace-err2.log"
-should 'should start processes' 'online' 2
-
-OUT_LOG=`$pm2 prettylist | grep -m 1 -E "pm_out_log_path:" | sed "s/.*'\([^']*\)',/\1/"`
-cat /dev/null > $OUT_LOG
-
-#### Graceful reload name
-$pm2 gracefulReload graceful2
-
-echo "PATH: $OUT_LOG"
-
-TEXT=$(cat $OUT_LOG)
-
-echo "TEXT: $TEXT"
-
-OUT=`grep "Finished closing connections" "$OUT_LOG" | wc -l`
-[ $OUT -eq 1 ] || fail "Non-listening process not restarted gracefuly"
-success "Non-listening process restarted gracefuly"
diff --git a/test/bash/gracefulReload3.sh b/test/bash/gracefulReload3.sh
deleted file mode 100644
index 307d74f6b..000000000
--- a/test/bash/gracefulReload3.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env bash
-
-SRC=$(cd $(dirname "$0"); pwd)
-source "${SRC}/include.sh"
-
-cd $file_path
-
-echo "################## GRACEFUL RELOAD 3 ###################"
-
-echo "Launching"
-$pm2 start graceful-exit-send.js -i 2 --name="graceful3" -o "grace3.log" -e "grace-err3.log"
-should 'should start processes' 'online' 2
-
-OUT_LOG=`$pm2 prettylist | grep -m 1 -E "pm_out_log_path:" | sed "s/.*'\([^']*\)',/\1/"`
-cat /dev/null > $OUT_LOG
-
-#### Graceful reload name
-$pm2 gracefulReload graceful3
-
-OUT=`grep "Finished closing connections" "$OUT_LOG" | wc -l`
-[ $OUT -eq 1 ] || fail "Process that sends 'online' not restarted gracefuly"
-success "Process that sends 'online' restarted gracefuly"
diff --git a/test/bash/json-file.sh b/test/bash/json-file.sh
index 50c3ff352..08ce5543b 100644
--- a/test/bash/json-file.sh
+++ b/test/bash/json-file.sh
@@ -36,18 +36,13 @@ sleep 1
should 'should reload processes' 'online' 6
should 'should all script been restarted one time' 'restart_time: 2' 6
-$pm2 gracefulReload all.json
-sleep 1
-should 'should graceful reload processes' 'online' 6
-should 'should all script been restarted one time' 'restart_time: 3' 6
-
##
## Smart restart
##
$pm2 start all.json
sleep 1
should 'should smart restart processes' 'online' 6
-should 'should all script been restarted one time' 'restart_time: 4' 6
+should 'should all script been restarted one time' 'restart_time: 3' 6
$pm2 stop all.json
sleep 1
diff --git a/test/bash/reload.sh b/test/bash/reload.sh
index d659a1b6c..88ad94165 100644
--- a/test/bash/reload.sh
+++ b/test/bash/reload.sh
@@ -50,8 +50,6 @@ $pm2 restart delayed_exit.js
should 'should restart processes' 'restart_time: 1' 2
$pm2 reload delayed_exit.js
should 'should restart processes' 'restart_time: 2' 2
-$pm2 gracefulReload delayed_exit.js
-should 'should restart processes' 'restart_time: 3' 2
$pm2 kill
$pm2 start child.js -i 4
diff --git a/test/fixtures/graceful-exit-no-listen.js b/test/fixtures/graceful-exit-no-listen.js
index 37cfba2dc..814d3845c 100644
--- a/test/fixtures/graceful-exit-no-listen.js
+++ b/test/fixtures/graceful-exit-no-listen.js
@@ -2,7 +2,7 @@
/*
* Example of graceful exit that does not listen
*
- * $ pm2 gracefulReload all
+ * $ pm2 reload all
*/
process.on('message', function(msg) {
diff --git a/test/fixtures/graceful-exit-send.js b/test/fixtures/graceful-exit-send.js
index 7142c3f5d..94d461f00 100644
--- a/test/fixtures/graceful-exit-send.js
+++ b/test/fixtures/graceful-exit-send.js
@@ -2,7 +2,7 @@
/*
* Example of graceful exit that does not listen but sends 'online'
*
- * $ pm2 gracefulReload all
+ * $ pm2 reload all
*/
process.on('message', function(msg) {
diff --git a/test/fixtures/graceful-exit.js b/test/fixtures/graceful-exit.js
index 43e8212a9..5b1461a18 100644
--- a/test/fixtures/graceful-exit.js
+++ b/test/fixtures/graceful-exit.js
@@ -2,7 +2,7 @@
/*
* Example of graceful exit
*
- * $ pm2 gracefulReload all
+ * $ pm2 reload all
*/
process.on('message', function(msg) {
diff --git a/test/interface/remote.mocha.js b/test/interface/remote.mocha.js
index d1ded5a12..87adbcd41 100644
--- a/test/interface/remote.mocha.js
+++ b/test/interface/remote.mocha.js
@@ -145,30 +145,6 @@ describe('REMOTE PM2 ACTIONS', function() {
});
});
- it('should gracefulRELOAD', function(done) {
- send_cmd.once('trigger:pm2:result', function(pck) {
- /**
- * Once remote command is finished...
- */
-
- should(pck.ret.err).be.null();
-
- pm2.list(function(err, ret) {
- ret.forEach(function(proc) {
- proc.pm2_env.restart_time.should.eql(3);
- });
- });
-
- done();
- });
-
- send_cmd.emit('cmd', {
- _type : 'trigger:pm2:action',
- method_name : 'gracefulReload',
- parameters : {name : 'child' }
- });
- });
-
it('should RESET metadata', function(done) {
send_cmd.once('trigger:pm2:result', function(pck) {
/**
diff --git a/test/pm2_behavior_tests.sh b/test/pm2_behavior_tests.sh
index 6b1fa6306..9d212a11d 100644
--- a/test/pm2_behavior_tests.sh
+++ b/test/pm2_behavior_tests.sh
@@ -81,12 +81,6 @@ bash ./test/bash/right-exit-code.sh
spec "Verification exit code"
bash ./test/bash/log-reload.sh
spec "Log reload"
-bash ./test/bash/gracefulReload.sh
-spec "gracefulReload system 1"
-bash ./test/bash/gracefulReload2.sh
-spec "gracefulReload system 2"
-bash ./test/bash/gracefulReload3.sh
-spec "gracefulReload system 3"
bash ./test/bash/misc.sh
spec "MISC features"
bash ./test/bash/fork.sh
diff --git a/test/programmatic/programmatic.js b/test/programmatic/programmatic.js
index e71f0aecf..478e13618 100644
--- a/test/programmatic/programmatic.js
+++ b/test/programmatic/programmatic.js
@@ -18,7 +18,12 @@ describe('PM2 programmatic calls', function() {
});
after(function(done) {
- pm2.kill(done);
+ pm2.delete('all', function(err, ret) {
+ // clean dump file
+ pm2.clearDump(function(err) {
+ pm2.kill(done);
+ });
+ });
});
before(function(done) {
diff --git a/test/programmatic/signals.js b/test/programmatic/signals.js
index 6c9c93b30..fad65206e 100644
--- a/test/programmatic/signals.js
+++ b/test/programmatic/signals.js
@@ -162,21 +162,6 @@ describe('Signal kill (+delayed)', function() {
});
});
-
- it('should graceful reload script', function(done) {
- setTimeout(function() {
- pm2.list(function(err, list) {
- list[0].pm2_env.status.should.eql('online');
- list[0].pm2_env.restart_time.should.eql(2);
- done();
- });
- }, 1500);
-
- pm2.gracefulReload('delayed-sigint', function(err, app) {
- //done(err);
- });
-
- });
});
describe('with 4000ms via kill_timeout (json/cli option)', function() {