diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 113fee12c..d4020014a 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,17 +1,10 @@ - - ## What's going wrong? ## How could we reproduce this issue? ## Supporting information - ``` +# Run the following commands $ pm2 report ``` diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml new file mode 100644 index 000000000..7bbd16306 --- /dev/null +++ b/.github/workflows/node.js.yml @@ -0,0 +1,31 @@ +# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs + +name: Node.js CI + +on: [push, pull_request] + +jobs: + build: + + runs-on: ubuntu-latest + timeout-minutes: 30 + + strategy: + matrix: + node-version: [20.x, 18.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v3 + - uses: oven-sh/setup-bun@v1 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - run: sudo apt install python3 + - run: sudo apt install php-cli + - run: npm install + - run: npm run test:e2e + - run: npm run test:unit diff --git a/.gitignore b/.gitignore index eebf45758..5289eb3f4 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ test/child dist/ *.deb *.rpm -package-lock.json .DS_Store *.swp *.swo diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b3ce156c3..000000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: node_js -node_js: - - "16" - - "14" - - "12" - - "10" -git: - depth: 2 -os: - - linux -arch: - - amd64 -before_install: - - sudo apt-get -qq update - - sudo apt-get install python3 - - sudo apt-get install php7.0-cli - - if [[ $(uname -m) == 's390x' ]]; then - sudo apt-get install bc; - fi -services: - - docker -install: - - npm install diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f6654773..3d4635b1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,55 @@ -## 5.1.2 MendriX: - +## 5.3.2 (MendriX): - fix: pipe names in Windows were not unique for each instance (added _suffix made from hashed PM2_HOME path) +## 5.3.1 + +- #5686 Switch from Travis CI to Github Actions +- #5680 Fixed reserved keyword for ES6 Strict Mode when Bundling @juaneth +- #5683 update badges +- #5684 auto switch light and dark mode logos +- #5678 Bugfix/deploy ecosystem filename extension / esm module default ecosystem config name @TeleMediaCC +- #5660 Fix matching logic for logs from namespace when lines = 0 @bawjensen +- fix "vulnerabilities" in axios module + +## 5.3.0 + +- fix: replace non-working condition that blocks flush from clearing the logs #5533 @Sailboat265 +- fix: ESM script loader #5524 @BlueWater86 + +## 5.2.2 + +- fix: correct pm2 ls display when there is a (very) long process id (@dko-slapdash) +- typo: corrections + +## 5.2.1 + +- fix cluster error avoiding process restart (#5396) +- ensure increment_var value is a number (#5435) +- update dependencies +- add node latest to travis testing + +## 5.2.0 + +- replace node-cron by croner (#5183 #5035) +- upgrade mocha deps +- fix pm2 report when daemon not running +- remove semver check for legacy node.js versions +- update node version in setup.deb.sh by using lts (#5201) + openrc +- replace legacy util._extend by Object.assign (#5239) +- add missing start options types (#5242) +- recursive detection of package.json (#5267) +- make tarball module uninstall cross-platform (#5269) +- Fix unnecessary "ENOENT" console.error when serving a spa (#5272) +- fix: used env variable instead of hardcode datetime format (#5277) +- copyright update (#5278) +- fix: remove constants import from VersionCheck (not needed) (#5279) +- Reduce async import (#5280) + +## 5.1.2 + +- easily disable cron-restart strategy via `$ pm2 restart --cron-restart 0` +- allow to update cron-restart on restart + ## 5.1.1 - remove fast-printf and replace with sprintfjs diff --git a/README.md b/README.md index 1d2309c79..22b31fc7a 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,35 @@
-
- - pm2 logo - +
+ + + + + +

P(rocess) M(anager) 2
Runtime Edition

- - + + + Donate + + + Downloads per Month - + Downloads per Year @@ -22,10 +37,6 @@ npm version - - Build Status - -


@@ -40,7 +51,7 @@ Starting an application in production mode is as easy as: $ pm2 start app.js ``` -PM2 is constantly assailed by [more than 1800 tests](https://travis-ci.org/Unitech/pm2). +PM2 is constantly assailed by [more than 1800 tests](https://github.com/Unitech/pm2/actions/workflows/node.js.yml). Official website: [https://pm2.keymetrics.io/](https://pm2.keymetrics.io/) @@ -55,7 +66,7 @@ With NPM: $ npm install pm2 -g ``` -You can install Node.js easily with [NVM](https://riptutorial.com/node-js/example/4578/using-node-version-manager--nvm-) or [ASDF](https://blog.natterstefan.me/how-to-use-multiple-node-version-with-asdf) +You can install Node.js easily with [NVM](https://github.com/nvm-sh/nvm#installing-and-updating) or [FNM](https://github.com/Schniz/fnm). ### Start an application @@ -71,7 +82,7 @@ Your app is now daemonized, monitored and kept alive forever. Once applications are started you can manage them easily: -![Process listing](https://github.com/unitech/pm2/raw/master/pres/pm2-list.png) +![Process listing](https://github.com/Unitech/pm2/raw/master/pres/pm2-ls-v2.png) To list all running applications: @@ -99,13 +110,14 @@ To monitor logs, custom metrics, application information: $ pm2 monit ``` - [More about Process Management](https://pm2.keymetrics.io/docs/usage/process-management/) ### Cluster Mode: Node.js Load Balancing & Zero Downtime Reload The Cluster mode is a special mode when starting a Node.js application, it starts multiple processes and load-balance HTTP/TCP/UDP queries between them. This increase overall performance (by a factor of x10 on 16 cores machines) and reliability (faster socket re-balancing in case of unhandled errors). +![Framework supported](https://raw.githubusercontent.com/Unitech/PM2/master/pres/cluster.png) + Starting a Node.js application in cluster mode that will leverage all CPUs available: ```bash @@ -122,10 +134,6 @@ Hot Reload allows to update an application without any downtime: $ pm2 reload all ``` -Seamlessly supported by all major Node.js frameworks and any Node.js applications without any code change: - -![Framework supported](https://raw.githubusercontent.com/Unitech/PM2/master/pres/cluster-support.png) - [More informations about how PM2 make clustering easy](https://pm2.keymetrics.io/docs/usage/cluster-mode/) ### Container Support @@ -140,6 +148,19 @@ CMD [ "pm2-runtime", "npm", "--", "start" ] [Read More about the dedicated integration](https://pm2.keymetrics.io/docs/usage/docker-pm2-nodejs/) +### Host monitoring speedbar + +PM2 allows to monitor your host/server vitals with a monitoring speedbar. + +To enable host monitoring: + +```bash +$ pm2 set pm2:sysmonit true +$ pm2 update +``` + +![Framework supported](https://raw.githubusercontent.com/Unitech/PM2/master/pres/vitals.png) + ### Terminal Based Monitoring ![Monit](https://github.com/Unitech/pm2/raw/master/pres/pm2-monit.png) @@ -171,11 +192,17 @@ $ pm2 flush # Flush all logs $ pm2 reloadLogs # Reload all logs ``` +To enable log rotation install the following module + +```bash +$ pm2 install pm2-logrotate +``` + [More about log management](https://pm2.keymetrics.io/docs/usage/log-management/) ### Startup Scripts Generation -PM2 can generates and configure a Startup Script to keep PM2 and your processes alive at every server restart. +PM2 can generate and configure a Startup Script to keep PM2 and your processes alive at every server restart. Init Systems Supported: **systemd**, **upstart**, **launchd**, **rc.d** @@ -192,19 +219,6 @@ $ pm2 unstartup [More about Startup Scripts Generation](https://pm2.keymetrics.io/docs/usage/startup/) -### PM2 Modules - -PM2 embeds a simple and powerful module system. Installing a module is straightforward: - -```bash -$ pm2 install -``` - -Here are some PM2 compatible modules (standalone Node.js applications managed by PM2): - -[**pm2-logrotate**](https://www.npmjs.com/package/pm2-logrotate) automatically rotate logs and limit logs size
-[**pm2-server-monit**](https://www.npmjs.com/package/pm2-server-monit) monitor the current server with more than 20+ metrics and 8 actions
- ### Updating PM2 ```bash diff --git a/constants.js b/constants.js index f6d1bf0da..2624eef45 100644 --- a/constants.js +++ b/constants.js @@ -1,5 +1,5 @@ /** - * Copyright 2013 the PM2 project authors. All rights reserved. + * Copyright 2013-2022 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. */ @@ -109,4 +109,4 @@ var csts = { }; -module.exports = util._extend(csts, path_structure); +module.exports = Object.assign(csts, path_structure); diff --git a/examples/cluster-http/http.js b/examples/cluster-http/http.js index a31018318..ae4801186 100644 --- a/examples/cluster-http/http.js +++ b/examples/cluster-http/http.js @@ -5,5 +5,5 @@ var server = http.createServer(function(req, res) { res.writeHead(200); res.end('hey'); }).listen(process.env.PORT || 8089, '0.0.0.0', function() { - console.log('App listening on port %d', server.address().port); + console.log('App listening on port 8089'); }); diff --git a/examples/send-msg/pm2-app.js b/examples/send-msg/pm2-app.js new file mode 100644 index 000000000..b49167b14 --- /dev/null +++ b/examples/send-msg/pm2-app.js @@ -0,0 +1,9 @@ + +process.on('message', function(packet) { + process.send({ + type : 'process:msg', + data : { + success : true + } + }); +}); diff --git a/examples/send-msg/pm2-msg.js b/examples/send-msg/pm2-msg.js new file mode 100644 index 000000000..9df5fdb7b --- /dev/null +++ b/examples/send-msg/pm2-msg.js @@ -0,0 +1,29 @@ + +const pm2 = require('../..') + +console.log(pm2) + +pm2.connect(function() { + pm2.sendDataToProcessId({ + // id of procces from "pm2 list" command or from pm2.list(errback) method + id : '1', + + // process:msg will be send as 'message' on target process + type : 'process:msg', + + // Data to be sent + data : { + some : 'data' + }, + + topic: true + }, function(err, res) { + }) +}) + +// Listen to messages from application +pm2.launchBus(function(err, pm2_bus) { + pm2_bus.on('process:msg', function(packet) { + console.log(packet) + }) +}) diff --git a/examples/send-msg/t2.js b/examples/send-msg/t2.js new file mode 100644 index 000000000..6190469cc --- /dev/null +++ b/examples/send-msg/t2.js @@ -0,0 +1,16 @@ + +var tx2 = require('tx2') +var http = require('http') + +var meter = tx2.meter({ + name : 'req/sec', + samples : 1, + timeframe : 60 +}) + +http.createServer(function (req, res) { + meter.mark() + res.writeHead(200, {'Content-Type': 'text/plain'}) + res.write('Hello World!') + res.end() +}).listen(6001) diff --git a/examples/sourcemap-auto-resolve/API.js b/examples/sourcemap-auto-resolve/API.js index abc03fa95..99ed05920 100644 --- a/examples/sourcemap-auto-resolve/API.js +++ b/examples/sourcemap-auto-resolve/API.js @@ -1,5 +1,5 @@ /** - * Copyright 2013 the PM2 project authors. All rights reserved. + * Copyright 2013-2022 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. */ @@ -150,7 +150,7 @@ API.prototype.connect = function(noDaemon, cb) { return cb(err, meta); // If new pm2 instance has been popped - // Lauch all modules + // Launch all modules Modularizer.launchAll(that, function(err_mod) { return cb(err, meta); }); diff --git a/index.js b/index.js index 7c59ed702..98a0ffcf9 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ /** - * Copyright 2013 the PM2 project authors. All rights reserved. + * Copyright 2013-2022 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. */ diff --git a/lib/API.js b/lib/API.js index f0931a50f..945c822d4 100644 --- a/lib/API.js +++ b/lib/API.js @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 the PM2 project authors. All rights reserved. + * Copyright 2013-2022 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. */ @@ -27,7 +27,6 @@ var UX = require('./API/UX'); var pkg = require('../package.json'); var hf = require('./API/Modules/flagExt.js'); var Configuration = require('./Configuration.js'); -const semver = require('semver') const sexec = require('./tools/sexec.js') var IMMUTABLE_MSG = chalk.bold.blue('Use --update-env to update environment variables'); @@ -81,7 +80,7 @@ class API { if (opts.pm2_home) { // Override default conf file this.pm2_home = opts.pm2_home; - conf = util._extend(conf, path_structure(this.pm2_home)); + conf = Object.assign(conf, path_structure(this.pm2_home)); } else if (opts.independent == true && conf.IS_WINDOWS === false) { // Create an unique pm2 instance @@ -93,7 +92,7 @@ class API { // 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)); + conf = Object.assign(conf, path_structure(this.pm2_home)); } this._conf = conf; @@ -183,7 +182,7 @@ class API { that.launchSysMonitoring(() => {}) // If new pm2 instance has been popped - // Lauch all modules + // Launch all modules that.launchAll(that, function(err_mod) { return cb(err, meta); }); @@ -322,10 +321,6 @@ class API { } if (!opts) opts = {}; - if (semver.lt(process.version, '6.0.0')) { - Common.printOut(conf.PREFIX_MSG_WARNING + 'Node 4 is deprecated, please upgrade to use pm2 to have all features'); - } - 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; @@ -876,7 +871,7 @@ class API { resolved_paths.env['PM2_HOME'] = that.pm2_home; var additional_env = Modularizer.getAdditionalConf(resolved_paths.name); - util._extend(resolved_paths.env, additional_env); + Object.assign(resolved_paths.env, additional_env); // Is KM linked? resolved_paths.km_link = that.gl_is_km_linked; @@ -1072,7 +1067,7 @@ class API { // 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); + return Object.assign(e1, e2); }); // When we are processing JSON, allow to keep the new env by default @@ -1147,7 +1142,7 @@ class API { resolved_paths.env['PM2_HOME'] = that.pm2_home; var additional_env = Modularizer.getAdditionalConf(resolved_paths.name); - util._extend(resolved_paths.env, additional_env); + Object.assign(resolved_paths.env, additional_env); resolved_paths.env = Common.mergeEnvironmentVariables(resolved_paths, opts.env, deployConf); @@ -1368,7 +1363,7 @@ class API { if (conf.PM2_PROGRAMMATIC == true) new_env = Common.safeExtend({}, process.env); else - new_env = util._extend({}, process.env); + new_env = Object.assign({}, process.env); Object.keys(envs).forEach(function(k) { new_env[k] = envs[k]; @@ -1510,7 +1505,7 @@ class API { * if yes load configuration variables and merge with the current environment */ var additional_env = Modularizer.getAdditionalConf(process_name); - util._extend(envs, additional_env); + Object.assign(envs, additional_env); return processIds(ids, cb); } @@ -1529,7 +1524,7 @@ class API { * if yes load configuration variables and merge with the current environment */ var ns_additional_env = Modularizer.getAdditionalConf(process_name); - util._extend(envs, ns_additional_env); + Object.assign(envs, ns_additional_env); return processIds(ns_process_ids, cb); }); }); diff --git a/lib/API/Dashboard.js b/lib/API/Dashboard.js index 971909b6c..64b127722 100644 --- a/lib/API/Dashboard.js +++ b/lib/API/Dashboard.js @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 the PM2 project authors. All rights reserved. + * Copyright 2013-2022 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. */ diff --git a/lib/API/Deploy.js b/lib/API/Deploy.js index b87d0ac69..41bc4da73 100644 --- a/lib/API/Deploy.js +++ b/lib/API/Deploy.js @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 the PM2 project authors. All rights reserved. + * Copyright 2013-2022 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. */ @@ -67,7 +67,8 @@ module.exports = function(CLI) { // Find ecosystem file by default if (!Common.isConfigFile(file)) { env = args[0]; - var defaultConfigNames = ['ecosystem.config.js', 'ecosystem.json', 'ecosystem.json5', 'package.json']; + var defaultConfigNames = [ ...Common.getConfigFileCandidates('ecosystem'), 'ecosystem.json5', 'package.json']; + file = Utility.whichFileExists(defaultConfigNames); if (!file) { diff --git a/lib/API/Extra.js b/lib/API/Extra.js index a2d2b3e24..e30aba121 100644 --- a/lib/API/Extra.js +++ b/lib/API/Extra.js @@ -14,7 +14,6 @@ var fs = require('fs'); var fmt = require('../tools/fmt.js'); var dayjs = require('dayjs'); var pkg = require('../../package.json'); -const semver = require('semver'); const copyDirSync = require('../tools/copydirSync.js') module.exports = function(CLI) { @@ -35,7 +34,6 @@ module.exports = function(CLI) { * Install pm2-sysmonit */ CLI.prototype.launchSysMonitoring = function(cb) { - if ((this.pm2_configuration && this.pm2_configuration.sysmonit != 'true') || process.env.TRAVIS || global.it === 'function' || @@ -102,6 +100,7 @@ module.exports = function(CLI) { var Log = require('./Log'); that.Client.executeRemote('getReport', {}, function(err, report) { + console.log() console.log() console.log() @@ -109,16 +108,19 @@ module.exports = function(CLI) { fmt.title('PM2 report') fmt.field('Date', new Date()); fmt.sep(); - fmt.title(chalk.bold.blue('Daemon')); - fmt.field('pm2d version', report.pm2_version); - fmt.field('node version', report.node_version); - fmt.field('node path', report.node_path); - fmt.field('argv', report.argv); - fmt.field('argv0', report.argv0); - fmt.field('user', report.user); - fmt.field('uid', report.uid); - fmt.field('gid', report.gid); - fmt.field('uptime', dayjs(new Date()).diff(report.started_at, 'minute') + 'min'); + + if (report && !err) { + fmt.title(chalk.bold.blue('Daemon')); + fmt.field('pm2d version', report.pm2_version); + fmt.field('node version', report.node_version); + fmt.field('node path', report.node_path); + fmt.field('argv', report.argv); + fmt.field('argv0', report.argv0); + fmt.field('user', report.user); + fmt.field('uid', report.uid); + fmt.field('gid', report.gid); + fmt.field('uptime', dayjs(new Date()).diff(report.started_at, 'minute') + 'min'); + } fmt.sep(); fmt.title(chalk.bold.blue('CLI')); @@ -274,9 +276,10 @@ module.exports = function(CLI) { var i = 0 var projects = [] var enquirer = require('enquirer') + const forEach = require('async/forEach') fs.readdir(path.join(__dirname, '../templates/sample-apps'), (err, items) => { - require('async').forEach(items, (app, next) => { + forEach(items, (app, next) => { var fp = path.join(__dirname, '../templates/sample-apps', app) fs.readFile(path.join(fp, 'package.json'), (err, dt) => { var meta = JSON.parse(dt) @@ -754,24 +757,19 @@ module.exports = function(CLI) { 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 !!!`); - } + 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(`Unable to activate inspect mode on ${app_name} !!!`); + 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/Log.js b/lib/API/Log.js index 30194760f..ba72fe7c5 100644 --- a/lib/API/Log.js +++ b/lib/API/Log.js @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 the PM2 project authors. All rights reserved. + * Copyright 2013-2022 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. */ @@ -98,9 +98,12 @@ Log.stream = function(Client, id, raw, timestamp, exclusive, highlight) { var min_padding = 3 bus.on('log:*', function(type, packet) { - if (id !== 'all' - && packet.process.name != id - && packet.process.pm_id != id) + var isMatchingProcess = id === 'all' + || packet.process.name == id + || packet.process.pm_id == id + || packet.process.namespace == id; + + if (!isMatchingProcess) return; if ((type === 'out' && exclusive === 'err') diff --git a/lib/API/LogManagement.js b/lib/API/LogManagement.js index 531f50269..55bae4356 100644 --- a/lib/API/LogManagement.js +++ b/lib/API/LogManagement.js @@ -41,21 +41,23 @@ module.exports = function(CLI) { fs.closeSync(fs.openSync(l.pm2_env.pm_out_log_path, 'w')); fs.closeSync(fs.openSync(l.pm2_env.pm_err_log_path, 'w')); } - else if (l.pm2_env.name === api) { + else if (l.pm2_env.pm_id == api || l.pm2_env.name === api) { Common.printOut(cst.PREFIX_MSG + 'Flushing:'); - Common.printOut(cst.PREFIX_MSG + l.pm2_env.pm_out_log_path); - Common.printOut(cst.PREFIX_MSG + l.pm2_env.pm_err_log_path); - if (l.pm2_env.pm_log_path && - l.pm2_env.pm_log_path.lastIndexOf('/') < l.pm2_env.pm_log_path.lastIndexOf(api)) { + if (l.pm2_env.pm_log_path && fs.existsSync(l.pm2_env.pm_log_path)) { Common.printOut(cst.PREFIX_MSG + l.pm2_env.pm_log_path); fs.closeSync(fs.openSync(l.pm2_env.pm_log_path, 'w')); } - if (l.pm2_env.pm_out_log_path.lastIndexOf('/') < l.pm2_env.pm_out_log_path.lastIndexOf(api)) + if (l.pm2_env.pm_out_log_path && fs.existsSync(l.pm2_env.pm_out_log_path)) { + Common.printOut(cst.PREFIX_MSG + l.pm2_env.pm_out_log_path); fs.closeSync(fs.openSync(l.pm2_env.pm_out_log_path, 'w')); - if (l.pm2_env.pm_err_log_path.lastIndexOf('/') < l.pm2_env.pm_err_log_path.lastIndexOf(api)) + } + + if (l.pm2_env.pm_err_log_path && fs.existsSync(l.pm2_env.pm_err_log_path)) { + Common.printOut(cst.PREFIX_MSG + l.pm2_env.pm_err_log_path); fs.closeSync(fs.openSync(l.pm2_env.pm_err_log_path, 'w')); + } } }); diff --git a/lib/API/Modules/Modularizer.js b/lib/API/Modules/Modularizer.js index 89433a018..614e6e71b 100644 --- a/lib/API/Modules/Modularizer.js +++ b/lib/API/Modules/Modularizer.js @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 the PM2 project authors. All rights reserved. + * Copyright 2013-2022 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. */ diff --git a/lib/API/Modules/TAR.js b/lib/API/Modules/TAR.js index 89675ad08..1cd223f88 100644 --- a/lib/API/Modules/TAR.js +++ b/lib/API/Modules/TAR.js @@ -3,7 +3,8 @@ var Configuration = require('../../Configuration.js'); var cst = require('../../../constants.js'); var Common = require('../../Common'); var forEachLimit = require('async/forEachLimit'); -const sexec = require('../../tools/sexec.js') +const sexec = require('../../tools/sexec.js'); +const deleteFolderRecursive = require('../../tools/deleteFolderRecursive.js'); var path = require('path'); var fs = require('fs'); @@ -17,7 +18,7 @@ module.exports = { uninstall, start, publish, - package + packager } /** @@ -108,7 +109,7 @@ function installLocal(PM2, module_filepath, opts, cb) { function deleteModulePath(module_name) { var sanitized = module_name.replace(/\./g, '') - execSync(`rm -r ${path.join(cst.DEFAULT_MODULE_PATH, module_name)}`, { silent: true }) + deleteFolderRecursive(path.join(cst.DEFAULT_MODULE_PATH, module_name)); } function runInstall(PM2, target_path, module_name, opts, cb) { @@ -269,7 +270,7 @@ function getModuleName(module_filepath, cb) { }); } -function package(module_path, target_path, cb) { +function packager(module_path, target_path, cb) { var base_folder = path.dirname(module_path) var module_folder_name = path.basename(module_path) var pkg = require(path.join(module_path, 'package.json')) @@ -315,7 +316,7 @@ function publish(PM2, folder, cb) { Common.logMod(`Starting publishing procedure for ${module_name}@${pkg.version}`) - package(current_path, target_path, (err, res) => { + packager(current_path, target_path, (err, res) => { if (err) { Common.errMod('Can\'t package, exiting') process.exit(1) diff --git a/lib/API/Monit.js b/lib/API/Monit.js index b42de8f78..511157850 100644 --- a/lib/API/Monit.js +++ b/lib/API/Monit.js @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 the PM2 project authors. All rights reserved. + * Copyright 2013-2022 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. */ diff --git a/lib/API/Serve.js b/lib/API/Serve.js index bd7d04f91..178b9c36c 100644 --- a/lib/API/Serve.js +++ b/lib/API/Serve.js @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 the PM2 project authors. All rights reserved. + * Copyright 2013-2022 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. */ @@ -10,19 +10,13 @@ var http = require('http'); var url = require('url'); var path = require('path'); var debug = require('debug')('pm2:serve'); -var semver = require('semver') - -var isNode4 = require('semver').lt(process.version, '6.0.0') - -if (!isNode4) { - var probe = require('@pm2/io'); - var errorMeter = probe.meter({ - name : '404/sec', - samples : 1, - timeframe : 60 - }) -} +var probe = require('@pm2/io'); +var errorMeter = probe.meter({ + name : '404/sec', + samples : 1, + timeframe : 60 +}) /** * list of supported content types. */ @@ -272,12 +266,11 @@ function serveFile(uri, request, response) { fs.readFile(filePath, function (error, content) { if (error) { - if ((!options.spa || request.wantHomepage)) { + if ((!options.spa || file === options.homepage)) { console.error('[%s] Error while serving %s with content-type %s : %s', new Date(), filePath, contentType, error.message || error); } - if (!isNode4) - errorMeter.mark(); + errorMeter.mark(); if (error.code === 'ENOENT') { if (options.spa && !request.wantHomepage) { request.wantHomepage = true; @@ -295,7 +288,13 @@ function serveFile(uri, request, response) { response.writeHead(500); return response.end('Sorry, check with the site admin for error: ' + error.code + ' ..\n'); } - response.writeHead(200, { 'Content-Type': contentType }); + + // Add CORS headers to allow browsers to fetch data directly + response.writeHead(200, { + 'Content-Type': contentType, + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET' + }); if (options.monitorBucket && contentType === 'text/html') { content = content.toString().replace('', `