mirror of
https://github.com/Unitech/pm2.git
synced 2025-12-08 20:35:53 +00:00
Merge branch 'development' into master
This commit is contained in:
commit
f5668331db
@ -4,7 +4,6 @@ node_js:
|
||||
- "4"
|
||||
- "6"
|
||||
- "8"
|
||||
- "0.12"
|
||||
os:
|
||||
- linux
|
||||
before_install:
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
- [Without Keymetrics](#without-keymetrics)
|
||||
- [With Keymetrics](#with-keymetrics)
|
||||
|
||||
### Deployment - ecosystem.json
|
||||
### Deployment - ecosystem.config.js
|
||||
|
||||
- [Getting started with deployment](#deployment)
|
||||
- [Deployment options](#deployment-help)
|
||||
|
||||
33
README.md
33
README.md
@ -13,7 +13,7 @@
|
||||
<img src="https://badge.fury.io/js/pm2.svg" alt="npm version" height="18">
|
||||
</a>
|
||||
|
||||
<a href="https://www.npmjs.com/package/pm2" title="PM2 on NPM">
|
||||
<a href="https://npmcharts.com/compare/pm2?minimal=true" title="PM2 on NPM">
|
||||
<img alt="NPM Downloads" src="https://img.shields.io/npm/dm/pm2.svg?style=flat-square"/>
|
||||
</a>
|
||||
|
||||
@ -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
|
||||
|
||||

|
||||
@ -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
|
||||
|
||||
|
||||
193
bin/pm2
193
bin/pm2
@ -33,24 +33,29 @@ if (process.argv.indexOf('-v') > -1) {
|
||||
var pm2 = new PM2();
|
||||
|
||||
commander.version(pkg.version)
|
||||
.option('-v --version', 'get version')
|
||||
.option('-v --version', 'print pm2 version')
|
||||
.option('-s --silent', 'hide all messages', false)
|
||||
.option('-n --name <name>', 'set a name for the process in the process list')
|
||||
.option('-m --mini-list', 'display a compacted list without formatting')
|
||||
.option('--interpreter <interpreter>', 'set a specific interpreter to use for executing app, default: node')
|
||||
.option('--interpreter-args <arguments>', 'set arguments to pass to the interpreter (alias of --node-args)')
|
||||
.option('--node-args <node_args>', 'space delimited arguments to pass to node')
|
||||
.option('-o --output <path>', 'specify log file for stdout')
|
||||
.option('-e --error <path>', 'specify log file for stderr')
|
||||
.option('-l --log [path]', 'specify log file which gathers both stdout and stderr')
|
||||
.option('--log-type <type>', 'specify log output style (raw by default, json optional)')
|
||||
.option('--log-date-format <date format>', 'add custom prefix timestamp to logs')
|
||||
.option('--disable-logs', 'disable all logs storage')
|
||||
.option('--env <environment_name>', 'specify which set of environment variables from ecosystem file must be injected')
|
||||
.option('-a --update-env', 'force an update of the environment with restart/reload (-a <=> apply)')
|
||||
.option('-f --force', 'force actions')
|
||||
.option('--disable-logs', 'do not write logs')
|
||||
.option('-n --name <name>', 'set a <name> for script')
|
||||
.option('-i --instances <number>', 'launch [number] instances (for networked app)(load balanced)')
|
||||
.option('--parallel <number>', 'number of parallel actions (for restart/reload)')
|
||||
.option('-l --log [path]', 'specify entire log file (error and out are both included)')
|
||||
.option('-o --output <path>', 'specify out log file')
|
||||
.option('-e --error <path>', 'specify error log file')
|
||||
.option('-p --pid <pid>', 'specify pid file')
|
||||
.option('-k --kill-timeout <delay>', 'delay before sending final SIGKILL signal to process')
|
||||
.option('--listen-timeout <delay>', 'listen timeout on application reload')
|
||||
.option('--max-memory-restart <memory>', 'specify max memory amount used to autorestart (in octet or use syntax like 100M)')
|
||||
.option('--max-memory-restart <memory>', 'Restart the app if an amount of memory is exceeded (in bytes)')
|
||||
.option('--restart-delay <delay>', 'specify a delay between restarts (in milliseconds)')
|
||||
.option('--env <environment_name>', 'specify environment to get specific env variables (for JSON declaration)')
|
||||
.option('--log-type <type>', 'specify log output style (raw by default, json optional)')
|
||||
.option('-x --execute-command', 'execute a program using fork system')
|
||||
.option('--max-restarts [count]', 'only restart the script COUNT times')
|
||||
.option('-u --user <username>', 'define user when generating startup script')
|
||||
@ -62,19 +67,14 @@ commander.version(pkg.version)
|
||||
.option('--service-name <name>', 'define service name when generating startup script')
|
||||
.option('-c --cron <cron_pattern>', 'restart a running process based on a cron pattern')
|
||||
.option('-w --write', 'write configuration in local folder')
|
||||
.option('--interpreter <interpreter>', 'the interpreter pm2 should use for executing app (bash, python...)')
|
||||
.option('--interpreter-args <arguments>', 'interpret options (alias of --node-args)')
|
||||
.option('--log-date-format <date format>', 'add custom prefix timestamp to logs')
|
||||
.option('--no-daemon', 'run pm2 daemon in the foreground if it doesn\'t exist already')
|
||||
.option('-a --update-env', 'update environment on restart/reload (-a <=> apply)')
|
||||
.option('--source-map-support', 'force source map support')
|
||||
.option('--only <application-name>', 'with json declaration, allow to only act on one application')
|
||||
.option('--disable-source-map-support', 'force source map support')
|
||||
.option('--wait-ready', 'ask pm2 to wait for ready event from your app')
|
||||
.option('--merge-logs', 'merge logs from different instances but keep error and out separated')
|
||||
.option('--watch [paths]', 'watch application folder for changes', function(v, m) { m.push(v); return m;}, [])
|
||||
.option('--ignore-watch <folders|files>', 'folder/files to be ignored watching, should be a specific name or regex - e.g. --ignore-watch="test node_modules \"some scripts\""')
|
||||
.option('--node-args <node_args>', 'space delimited arguments to pass to node in cluster mode - e.g. --node-args="--debug=7001 --trace-deprecation"')
|
||||
.option('--ignore-watch <folders|files>', 'List of paths to ignore (name or regex)')
|
||||
.option('--no-color', 'skip colors')
|
||||
.option('--no-vizion', 'start an app without vizion feature (versioning control)')
|
||||
.option('--no-autorestart', 'start an app without automatic restart')
|
||||
@ -90,38 +90,50 @@ commander.version(pkg.version)
|
||||
.option('--deep-monitoring', 'enable all monitoring tools (equivalent to --v8 --event-loop-inspector --trace)')
|
||||
.usage('[cmd] app');
|
||||
|
||||
commander.on('--help', function() {
|
||||
console.log(' Basic Examples:');
|
||||
console.log('');
|
||||
console.log(' Start an app using all CPUs available + set a name :');
|
||||
console.log(' $ pm2 start app.js -i 0 --name "api"');
|
||||
console.log('');
|
||||
console.log(' Restart the previous app launched, by name :');
|
||||
console.log(' $ pm2 restart api');
|
||||
console.log('');
|
||||
console.log(' Stop the app :');
|
||||
console.log(' $ pm2 stop api');
|
||||
console.log('');
|
||||
console.log(' Restart the app that is stopped :');
|
||||
console.log(' $ pm2 restart api');
|
||||
console.log('');
|
||||
console.log(' Remove the app from the process list :');
|
||||
console.log(' $ pm2 delete api');
|
||||
console.log('');
|
||||
console.log(' Kill daemon pm2 :');
|
||||
console.log(' $ pm2 kill');
|
||||
console.log('');
|
||||
console.log(' Update pm2 :');
|
||||
console.log(' $ npm install pm2@latest -g ; pm2 update');
|
||||
console.log('');
|
||||
console.log(' More examples in https://github.com/Unitech/pm2#usagefeatures');
|
||||
console.log('');
|
||||
console.log(' Deployment help:');
|
||||
console.log('');
|
||||
console.log(' $ pm2 deploy help');
|
||||
console.log('');
|
||||
console.log('');
|
||||
});
|
||||
function displayUsage() {
|
||||
console.log('usage: pm2 [options] <command>')
|
||||
console.log('');
|
||||
console.log('pm2 -h, --help all available commands and options');
|
||||
console.log('pm2 examples display pm2 usage examples');
|
||||
console.log('pm2 <command> -h help on a specific command');
|
||||
console.log('');
|
||||
console.log('Access pm2 files in ~/.pm2');
|
||||
}
|
||||
|
||||
function displayExamples() {
|
||||
console.log('- Start and add a process to the pm2 process list:')
|
||||
console.log('');
|
||||
console.log(chalk.cyan(' $ pm2 start app.js --name app'));
|
||||
console.log('');
|
||||
console.log('- Show the process list:');
|
||||
console.log('');
|
||||
console.log(chalk.cyan(' $ pm2 ls'));
|
||||
console.log('');
|
||||
console.log('- Stop and delete a process from the pm2 process list:');
|
||||
console.log('');
|
||||
console.log(chalk.cyan(' $ pm2 delete app'));
|
||||
console.log('');
|
||||
console.log('- Stop, start and restart a process from the process list:');
|
||||
console.log('');
|
||||
console.log(chalk.cyan(' $ pm2 stop app'));
|
||||
console.log(chalk.cyan(' $ pm2 start app'));
|
||||
console.log(chalk.cyan(' $ pm2 restart app'));
|
||||
console.log('');
|
||||
console.log('- Clusterize an app to all CPU cores available:');
|
||||
console.log('');
|
||||
console.log(chalk.cyan(' $ pm2 start -i max'));
|
||||
console.log('');
|
||||
console.log('- Update pm2 :');
|
||||
console.log('');
|
||||
console.log(chalk.cyan(' $ npm install pm2 -g && pm2 update'));
|
||||
console.log('');
|
||||
console.log('- Install pm2 auto completion:')
|
||||
console.log('');
|
||||
console.log(chalk.cyan(' $ pm2 completion install'))
|
||||
console.log('');
|
||||
console.log('Check the full documentation on https://pm2.io/doc');
|
||||
console.log('');
|
||||
}
|
||||
|
||||
if (process.argv.indexOf('-s') > -1) {
|
||||
for(var key in console){
|
||||
@ -155,7 +167,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){
|
||||
@ -253,7 +265,7 @@ function patchCommanderArg(cmd) {
|
||||
//
|
||||
// Start command
|
||||
//
|
||||
commander.command('start <file|json|stdin|app_name|pm_id...>')
|
||||
commander.command('start <name|file|ecosystem|id...>')
|
||||
.option('--watch', 'Watch folder for changes')
|
||||
.option('--fresh', 'Rebuild Dockerfile')
|
||||
.option('--daemon', 'Run container in Daemon mode (debug purposes)')
|
||||
@ -280,6 +292,9 @@ commander.command('start <file|json|stdin|app_name|pm_id...>')
|
||||
else {
|
||||
// Commander.js patch
|
||||
cmd = patchCommanderArg(cmd);
|
||||
if (cmd.length === 0) {
|
||||
cmd = [cst.APP_CONF_DEFAULT_FILE];
|
||||
}
|
||||
async.forEachLimit(cmd, 1, function(script, next) {
|
||||
pm2.start(script, commander, next);
|
||||
}, function(err) {
|
||||
@ -329,7 +344,7 @@ commander.command('startOrGracefulReload <json>')
|
||||
//
|
||||
commander.command('stop <id|name|all|json|stdin...>')
|
||||
.option('--watch', 'Stop watching folder for changes')
|
||||
.description('stop a process (to start it again, do pm2 restart <app>)')
|
||||
.description('stop a process')
|
||||
.action(function(param) {
|
||||
async.forEachLimit(param, 1, function(script, next) {
|
||||
pm2.stop(script, next);
|
||||
@ -390,21 +405,19 @@ commander.command('reload <name|all>')
|
||||
pm2.reload(pm2_id, commander);
|
||||
});
|
||||
|
||||
//
|
||||
// Reload process(es)
|
||||
//
|
||||
commander.command('gracefulReload <name|all>')
|
||||
.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 <name>')
|
||||
.description('get process id by name')
|
||||
.action(function(name) {
|
||||
pm2.getProcessIdByName(name);
|
||||
});
|
||||
|
||||
// Inspect a process
|
||||
commander.command('inspect <name>')
|
||||
.description('inspect a process')
|
||||
.action(function(cmd) {
|
||||
pm2.inspect(cmd, commander);
|
||||
});
|
||||
|
||||
//
|
||||
// Stop and delete a process by name from database
|
||||
//
|
||||
@ -464,11 +477,11 @@ commander.command('update')
|
||||
/**
|
||||
* Module specifics
|
||||
*/
|
||||
commander.command('install [module|git:// url|json]')
|
||||
commander.command('install <module|git:// url>')
|
||||
.alias('module:install')
|
||||
.option('--v1', 'install module in v1 manner (do not use it)')
|
||||
.option('--safe [time]', 'keep module backup, if new module fail = restore with previous')
|
||||
.description('install or update a module (or a set of modules) and run it forever')
|
||||
.description('install or update a module and run it forever')
|
||||
.action(function(plugin_name, opts) {
|
||||
if (opts.v1)
|
||||
commander.v1 = true;
|
||||
@ -553,41 +566,41 @@ commander.command('report')
|
||||
commander.command('link [secret] [public] [name]')
|
||||
.alias('interact')
|
||||
.option('--info-node [url]', 'set url info node')
|
||||
.description('linking action to keymetrics.io - command can be stop|info|delete|restart')
|
||||
.description('link with the pm2 monitoring dashboard')
|
||||
.action(pm2._pre_interact.bind(pm2));
|
||||
|
||||
commander.command('unlink')
|
||||
.description('linking action to keymetrics.io - command can be stop|info|delete|restart')
|
||||
.description('unlink with the pm2 monitoring dashboard')
|
||||
.action(function() {
|
||||
pm2.unlink();
|
||||
});
|
||||
|
||||
commander.command('unmonitor [name]')
|
||||
.description('unmonitor target process')
|
||||
.action(function(name) {
|
||||
pm2.monitorState('unmonitor', name);
|
||||
});
|
||||
|
||||
commander.command('monitor [name]')
|
||||
.description('monitor target process')
|
||||
.action(function(name) {
|
||||
pm2.monitorState('monitor', name);
|
||||
});
|
||||
|
||||
commander.command('unmonitor [name]')
|
||||
.description('unmonitor target process')
|
||||
.action(function(name) {
|
||||
pm2.monitorState('unmonitor', name);
|
||||
});
|
||||
|
||||
commander.command('open')
|
||||
.description('open dashboard in browser')
|
||||
.description('open the pm2 monitoring dashboard')
|
||||
.action(function(name) {
|
||||
pm2.openDashboard();
|
||||
});
|
||||
|
||||
commander.command('register')
|
||||
.description('create an account on keymetrics')
|
||||
.description('register on pm2 monitoring')
|
||||
.action(function(name) {
|
||||
pm2.registerToKM();
|
||||
});
|
||||
|
||||
commander.command('login')
|
||||
.description('login to keymetrics and link current PM2')
|
||||
.description('use login to link with the pm2 monitoring dashboard')
|
||||
.action(function(name) {
|
||||
pm2.loginToKM();
|
||||
});
|
||||
@ -612,6 +625,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
|
||||
//
|
||||
@ -645,7 +667,7 @@ commander.command('resurrect')
|
||||
// Set pm2 to startup
|
||||
//
|
||||
commander.command('unstartup [platform]')
|
||||
.description('disable and clear auto startup - [platform]=systemd,upstart,launchd,rcd')
|
||||
.description('disable the pm2 startup hook')
|
||||
.action(function(platform) {
|
||||
pm2.uninstallStartup(platform, commander);
|
||||
});
|
||||
@ -654,7 +676,7 @@ commander.command('unstartup [platform]')
|
||||
// Set pm2 to startup
|
||||
//
|
||||
commander.command('startup [platform]')
|
||||
.description('setup script for pm2 at boot - [platform]=systemd,upstart,launchd,rcd')
|
||||
.description('enable the pm2 startup hook')
|
||||
.action(function(platform) {
|
||||
pm2.startup(platform, commander);
|
||||
});
|
||||
@ -891,15 +913,6 @@ commander.command('backward <name>')
|
||||
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
|
||||
//
|
||||
@ -919,13 +932,21 @@ commander.command('serve [path] [port]')
|
||||
pm2.serve(path, port, commander);
|
||||
});
|
||||
|
||||
commander.command('examples')
|
||||
.description('display pm2 usage examples')
|
||||
.action(() => {
|
||||
console.log(cst.PREFIX_MSG + chalk.grey('pm2 usage examples:\n'));
|
||||
displayExamples();
|
||||
process.exit(cst.SUCCESS_EXIT);
|
||||
})
|
||||
|
||||
//
|
||||
// Catch all
|
||||
//
|
||||
commander.command('*')
|
||||
.action(function() {
|
||||
console.log(cst.PREFIX_MSG + '\nCommand not found');
|
||||
commander.outputHelp();
|
||||
console.log(cst.PREFIX_MSG + 'Command not found\n');
|
||||
displayUsage();
|
||||
// Check if it does not forget to close fds from RPC
|
||||
process.exit(cst.ERROR_EXIT);
|
||||
});
|
||||
@ -935,7 +956,7 @@ commander.command('*')
|
||||
//
|
||||
if (process.argv.length == 2) {
|
||||
commander.parse(process.argv);
|
||||
commander.outputHelp();
|
||||
displayUsage();
|
||||
// Check if it does not forget to close fds from RPC
|
||||
process.exit(cst.ERROR_EXIT);
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ var csts = {
|
||||
|
||||
TEMPLATE_FOLDER : p.join(__dirname, 'lib/templates'),
|
||||
|
||||
APP_CONF_DEFAULT_FILE : 'ecosystem.json',
|
||||
APP_CONF_DEFAULT_FILE : 'ecosystem.config.js',
|
||||
APP_CONF_TPL : 'ecosystem.tpl',
|
||||
APP_CONF_TPL_SIMPLE : 'ecosystem-simple.tpl',
|
||||
SAMPLE_CONF_FILE : 'sample-conf.js',
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Example of graceful exit
|
||||
*
|
||||
* $ pm2 gracefulReload all
|
||||
* $ pm2 reload all
|
||||
*/
|
||||
|
||||
process.on('message', function(msg) {
|
||||
|
||||
@ -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
|
||||
*
|
||||
|
||||
3194
lib/API.js
3194
lib/API.js
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@ -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');
|
||||
@ -47,7 +48,7 @@ var KNOWN_MODULES = {
|
||||
* - Generate sample module via pm2 module:generate <module_name>
|
||||
*/
|
||||
Modularizer.install = function (CLI, moduleName, opts, cb) {
|
||||
// if user want to install module from ecosystem.json file
|
||||
// if user want to install module from ecosystem.config.js file
|
||||
// it can also be a custom json file's name
|
||||
if (!moduleName || moduleName.length === 0 || moduleName.indexOf('.json') > 0) {
|
||||
var file = moduleName || cst.APP_CONF_DEFAULT_FILE;
|
||||
@ -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',
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -2,23 +2,87 @@
|
||||
"script": {
|
||||
"type": "string",
|
||||
"require": true,
|
||||
"alias" : "exec"
|
||||
"alias" : "exec",
|
||||
"docDescription": "Path of the script to launch, required field"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"docDefault": "Script filename without the extension (app for app.js)",
|
||||
"docDescription": "Process name in the process list"
|
||||
},
|
||||
"cwd": {
|
||||
"type": "string",
|
||||
"docDefault": "CWD of the current environment (from your shell)",
|
||||
"docDescription": "Current working directory to start the process with"
|
||||
},
|
||||
"args": {
|
||||
"type": [
|
||||
"array",
|
||||
"string"
|
||||
]
|
||||
],
|
||||
"docDescription": "Arguments to pass to the script"
|
||||
},
|
||||
"exec_interpreter": {
|
||||
"type": "string",
|
||||
"alias": "interpreter",
|
||||
"docDefault": "node",
|
||||
"docDescription": "Interpreter absolute path"
|
||||
},
|
||||
"node_args": {
|
||||
"type": [
|
||||
"array",
|
||||
"string"
|
||||
],
|
||||
"alias": ["interpreterArgs", "interpreter_args"]
|
||||
"alias": ["interpreterArgs", "interpreter_args"],
|
||||
"docDescription": "Arguments to pass to the interpreter"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
"out_file": {
|
||||
"type": "string",
|
||||
"alias": ["out", "output", "out_log"],
|
||||
"docDefault": "~/.pm2/logs/<app_name>-out.log",
|
||||
"docDescription": "File path for stdout (each line is appended to this file)"
|
||||
},
|
||||
"error_file": {
|
||||
"type": "string",
|
||||
"alias": ["error", "err", "err_file", "err_log"],
|
||||
"docDefault": "~/.pm2/logs/<app_name>-error.err",
|
||||
"docDescription": "File path for stderr (each line is appended to this file)"
|
||||
},
|
||||
"log_file": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"string"
|
||||
],
|
||||
"alias": "log",
|
||||
"docDefault": "/dev/null",
|
||||
"docDescription": "File path for combined stdout and stderr (each line is appended to this file)"
|
||||
},
|
||||
"disable_logs": {
|
||||
"type": "boolean",
|
||||
"docDefault": false,
|
||||
"docDescription": "Disable all logs storage"
|
||||
},
|
||||
"log_type": {
|
||||
"type": "string",
|
||||
"docDescription": "Define a specific log output type, possible value: json"
|
||||
},
|
||||
"log_date_format": {
|
||||
"type": "string",
|
||||
"docDescription": "Format for log timestamps in moment.js format (eg YYYY-MM-DD HH:mm Z)"
|
||||
},
|
||||
"env": {
|
||||
"type": [
|
||||
"object",
|
||||
"string"
|
||||
],
|
||||
"docDescription": "Specify environment variables to be injected"
|
||||
},
|
||||
"^env_\\S*$": {
|
||||
"type": [
|
||||
"object",
|
||||
"string"
|
||||
],
|
||||
"docDescription": "Specify environment variables to be injected when using --env <env_name>"
|
||||
},
|
||||
"max_memory_restart": {
|
||||
"type": [
|
||||
@ -27,124 +91,91 @@
|
||||
],
|
||||
"regex": "^\\d+(G|M|K)?$",
|
||||
"ext_type": "sbyte",
|
||||
"desc": "it should be a NUMBER - byte, \"[NUMBER]G\"(Gigabyte), \"[NUMBER]M\"(Megabyte) or \"[NUMBER]K\"(Kilobyte)"
|
||||
},
|
||||
"uid" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"gid" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"restart_delay": {
|
||||
"type" : "number"
|
||||
},
|
||||
"source_map_support" : {
|
||||
"type": "boolean"
|
||||
},
|
||||
"wait_ready" : {
|
||||
"type": "boolean"
|
||||
},
|
||||
"disable_source_map_support" : {
|
||||
"type": "boolean"
|
||||
},
|
||||
"instances": {
|
||||
"type": "number"
|
||||
},
|
||||
"kill_timeout": {
|
||||
"type": "number"
|
||||
},
|
||||
"listen_timeout": {
|
||||
"type": "number"
|
||||
},
|
||||
"port": {
|
||||
"type": "number"
|
||||
},
|
||||
"log_file": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"string"
|
||||
],
|
||||
"alias": "log"
|
||||
},
|
||||
"error_file": {
|
||||
"type": "string",
|
||||
"alias": ["error", "err", "err_file", "err_log"]
|
||||
},
|
||||
"log_type": {
|
||||
"type": "string"
|
||||
},
|
||||
"out_file": {
|
||||
"type": "string",
|
||||
"alias": ["output", "out", "out_log"]
|
||||
"desc": "it should be a NUMBER - byte, \"[NUMBER]G\"(Gigabyte), \"[NUMBER]M\"(Megabyte) or \"[NUMBER]K\"(Kilobyte)",
|
||||
"docDescription": "Restart the app if an amount of memory is exceeded (format: /[0-9](K|M|G)?/ K for KB, 'M' for MB, 'G' for GB, default to B)"
|
||||
},
|
||||
"pid_file": {
|
||||
"type": "string",
|
||||
"alias": "pid"
|
||||
"alias": "pid",
|
||||
"docDefault": "~/.pm2/pids/app_name-id.pid",
|
||||
"docDescription": "File path where the pid of the started process is written by pm2"
|
||||
},
|
||||
"restart_delay": {
|
||||
"type" : "number",
|
||||
"docDefault": 0,
|
||||
"docDescription": "Time in ms to wait before restarting a crashing app"
|
||||
},
|
||||
"source_map_support": {
|
||||
"type": "boolean",
|
||||
"docDefault": true,
|
||||
"docDescription": "Enable or disable the source map support"
|
||||
},
|
||||
"disable_source_map_support": {
|
||||
"type": "boolean",
|
||||
"docDefault": false,
|
||||
"docDescription": "Enable or disable the source map support"
|
||||
},
|
||||
"wait_ready": {
|
||||
"type": "boolean",
|
||||
"docDefault": false,
|
||||
"docDescription": "Make the process wait for a process.send('ready')"
|
||||
},
|
||||
"instances": {
|
||||
"type": "number",
|
||||
"docDefault": 1,
|
||||
"docDescription": "Number of instances to be started in cluster mode"
|
||||
},
|
||||
"kill_timeout": {
|
||||
"type": "number",
|
||||
"docDefault": 1600,
|
||||
"docDescription": "Time in ms before sending the final SIGKILL signal after SIGINT"
|
||||
},
|
||||
"listen_timeout": {
|
||||
"type": "number",
|
||||
"docDescription": "Time in ms before forcing a reload if app is still not listening/has still note sent ready"
|
||||
},
|
||||
"cron_restart": {
|
||||
"type": "string",
|
||||
"alias": "cron"
|
||||
},
|
||||
"cwd": {
|
||||
"type": "string"
|
||||
"alias": "cron",
|
||||
"docDescription": "A cron pattern to restart your app"
|
||||
},
|
||||
"merge_logs": {
|
||||
"type": "boolean",
|
||||
"alias" : "combine_logs"
|
||||
"alias" : "combine_logs",
|
||||
"docDefault": false,
|
||||
"docDescription": "In cluster mode, merge each type of logs into a single file (instead of having one for each cluster)"
|
||||
},
|
||||
"vizion" : {
|
||||
"vizion": {
|
||||
"type": "boolean",
|
||||
"default" : true
|
||||
"default" : true,
|
||||
"docDefault" : "True",
|
||||
"docDescription": "Enable or disable the versioning metadatas (vizion library)"
|
||||
},
|
||||
"pmx" : {
|
||||
"autorestart": {
|
||||
"type": "boolean",
|
||||
"default" : true
|
||||
},
|
||||
"automation" : {
|
||||
"type": "boolean",
|
||||
"default" : true
|
||||
},
|
||||
"autorestart" : {
|
||||
"type": "boolean",
|
||||
"default" : true
|
||||
},
|
||||
"treekill" : {
|
||||
"type": "boolean",
|
||||
"default" : true
|
||||
"default": true,
|
||||
"docDefault": "True",
|
||||
"docDescription": "Enable or disable auto restart after process failure"
|
||||
},
|
||||
"watch": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"array",
|
||||
"string"
|
||||
]
|
||||
],
|
||||
"docDefault": false,
|
||||
"docDescription": "Enable or disable the watch mode"
|
||||
},
|
||||
"ignore_watch": {
|
||||
"type": [
|
||||
"array",
|
||||
"string"
|
||||
]
|
||||
],
|
||||
"docDescription": "List of paths to ignore (regex)"
|
||||
},
|
||||
"watch_options": {
|
||||
"type": "object"
|
||||
},
|
||||
"env": {
|
||||
"type": [
|
||||
"object",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"^env_\\S*$": {
|
||||
"type": [
|
||||
"object",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"disable_logs" : {
|
||||
"type": "boolean"
|
||||
},
|
||||
"log_date_format": {
|
||||
"type": "string"
|
||||
"type": "object",
|
||||
"docDescription": "Object that will be used as an options with chokidar (refer to chokidar documentation)"
|
||||
},
|
||||
"min_uptime": {
|
||||
"type": [
|
||||
@ -154,43 +185,51 @@
|
||||
"regex": "^\\d+(h|m|s)?$",
|
||||
"desc": "it should be a NUMBER - milliseconds, \"[NUMBER]h\"(hours), \"[NUMBER]m\"(minutes) or \"[NUMBER]s\"(seconds)",
|
||||
"min": 100,
|
||||
"ext_type": "stime"
|
||||
"ext_type": "stime",
|
||||
"docDefault": 1000,
|
||||
"docDescription": "Minimum uptime of the app to be considered started (format is /[0-9]+(h|m|s)?/, for hours, minutes, seconds, docDefault to ms)"
|
||||
},
|
||||
"max_restarts": {
|
||||
"type": "number",
|
||||
"min": 0
|
||||
"min": 0,
|
||||
"docDefault": 16,
|
||||
"docDescription": "Number of times a script is restarted when it exits in less than min_uptime"
|
||||
},
|
||||
"exec_mode": {
|
||||
"type": "string",
|
||||
"regex": "^(cluster|fork)(_mode)?$",
|
||||
"alias": "executeCommand",
|
||||
"desc": "it should be \"cluster\"(\"cluster_mode\") or \"fork\"(\"fork_mode\") only"
|
||||
},
|
||||
"exec_interpreter": {
|
||||
"type": "string",
|
||||
"alias": "interpreter"
|
||||
},
|
||||
"write": {
|
||||
"type": "boolean"
|
||||
"desc": "it should be \"cluster\"(\"cluster_mode\") or \"fork\"(\"fork_mode\") only",
|
||||
"docDefault": "fork",
|
||||
"docDescription": "Set the execution mode, possible values: fork|cluster"
|
||||
},
|
||||
"force": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"docDefault": false,
|
||||
"docDescription": "Start a script even if it is already running (only the script path is considered)"
|
||||
},
|
||||
"append_env_to_name": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"docDefault": false,
|
||||
"docDescription": "Append the environment name to the app name"
|
||||
},
|
||||
"post_update": {
|
||||
"type": "array"
|
||||
},
|
||||
"disable_trace": {
|
||||
"type": [
|
||||
"boolean"
|
||||
]
|
||||
"type": "array",
|
||||
"docDescription": "List of commands executed after a pull/upgrade operation performed from Keymetrics dashboard"
|
||||
},
|
||||
"trace": {
|
||||
"type": [
|
||||
"boolean"
|
||||
]
|
||||
],
|
||||
"docDefault": false,
|
||||
"docDescription": "Enable or disable the transaction tracing"
|
||||
},
|
||||
"disable_trace": {
|
||||
"type": [
|
||||
"boolean"
|
||||
],
|
||||
"docDefault": true,
|
||||
"docDescription": "Enable or disable the transaction tracing"
|
||||
},
|
||||
"v8": {
|
||||
"type": [
|
||||
@ -208,18 +247,58 @@
|
||||
]
|
||||
},
|
||||
"increment_var": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"docDescription": "Specify the name of an environment variable to inject which increments for each cluster"
|
||||
},
|
||||
"instance_var": {
|
||||
"type": "string",
|
||||
"default" : "NODE_APP_INSTANCE"
|
||||
},
|
||||
"default": "NODE_APP_INSTANCE",
|
||||
"docDefault": "NODE_APP_INSTANCE",
|
||||
"docDescription": "Rename the NODE_APP_INSTANCE environment variable"
|
||||
},
|
||||
"pmx": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"docDefault": "True",
|
||||
"docDescription": "Enable or disable pmx wrapping"
|
||||
},
|
||||
"automation": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"docDefault": "True",
|
||||
"docDescription": "Enable or disable pmx wrapping"
|
||||
},
|
||||
"treekill": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"docDefault": "True",
|
||||
"docDescription": "Only kill the main process, not detached children"
|
||||
},
|
||||
"port": {
|
||||
"type": "number",
|
||||
"docDescription": "Shortcut to inject a PORT environment variable"
|
||||
},
|
||||
"uid": {
|
||||
"type" : "string",
|
||||
"docDefault": "Current user uid",
|
||||
"docDescription": "Set user id"
|
||||
},
|
||||
"gid": {
|
||||
"type" : "string",
|
||||
"docDefault": "Current user gid",
|
||||
"docDescription": "Set group id"
|
||||
},
|
||||
"windowsHide": {
|
||||
"type": "boolean",
|
||||
"default" : true
|
||||
"docDefault": "True",
|
||||
"docDescription": "Enable or disable the Windows popup when starting an app",
|
||||
"default": true
|
||||
},
|
||||
"kill_retry_time": {
|
||||
"type": "number",
|
||||
"default" : 100
|
||||
},
|
||||
"write": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
});
|
||||
};
|
||||
|
||||
@ -247,20 +247,22 @@ 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses a config file like ecosystem.json. Supported formats: JS, JSON, JSON5, YAML.
|
||||
* Parses a config file like ecosystem.config.js. Supported formats: JS, JSON, JSON5, YAML.
|
||||
* @param {string} confString contents of the config file
|
||||
* @param {string} filename path to the config file
|
||||
* @return {Object} config object
|
||||
@ -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);
|
||||
|
||||
@ -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,
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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});
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@ -174,7 +174,7 @@ function hardReload(God, id, wait_msg, cb) {
|
||||
module.exports = function(God) {
|
||||
|
||||
/**
|
||||
* GracefulReload
|
||||
* Reload
|
||||
* @method softReloadProcessId
|
||||
* @param {} id
|
||||
* @param {} cb
|
||||
|
||||
@ -21,7 +21,6 @@ var Password = require('../Password.js');
|
||||
var PM2_REMOTE_METHOD_ALLOWED = {
|
||||
'restart' : {},
|
||||
'reload' : {},
|
||||
'gracefulReload' : {},
|
||||
'reset' : {},
|
||||
'scale' : {},
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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") {
|
||||
|
||||
29
lib/ProcessUtils.js
Normal file
29
lib/ProcessUtils.js
Normal file
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -215,7 +215,6 @@ Satan.remoteWrapper = function() {
|
||||
|
||||
killMe : God.killMe,
|
||||
notifyKillPM2 : God.notifyKillPM2,
|
||||
forceGc : God.forceGc,
|
||||
|
||||
findByFullPath : God.findByFullPath,
|
||||
|
||||
|
||||
19
package.json
19
package.json
@ -3,7 +3,7 @@
|
||||
"preferGlobal": true,
|
||||
"version": "2.10.1",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
"node": ">=4.0.0"
|
||||
},
|
||||
"directories": {
|
||||
"bin": "./bin",
|
||||
@ -161,19 +161,20 @@
|
||||
"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",
|
||||
"pidusage": "^2.0.0",
|
||||
"pm2-axon": "3.1.0",
|
||||
"pm2-axon-rpc": "0.5.0",
|
||||
"pm2-deploy": "^0.3.9",
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
@ -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"
|
||||
@ -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"
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
2
test/fixtures/graceful-exit-no-listen.js
vendored
2
test/fixtures/graceful-exit-no-listen.js
vendored
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Example of graceful exit that does not listen
|
||||
*
|
||||
* $ pm2 gracefulReload all
|
||||
* $ pm2 reload all
|
||||
*/
|
||||
|
||||
process.on('message', function(msg) {
|
||||
|
||||
2
test/fixtures/graceful-exit-send.js
vendored
2
test/fixtures/graceful-exit-send.js
vendored
@ -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) {
|
||||
|
||||
2
test/fixtures/graceful-exit.js
vendored
2
test/fixtures/graceful-exit.js
vendored
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Example of graceful exit
|
||||
*
|
||||
* $ pm2 gracefulReload all
|
||||
* $ pm2 reload all
|
||||
*/
|
||||
|
||||
process.on('message', function(msg) {
|
||||
|
||||
@ -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) {
|
||||
/**
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user