@zappinginc/zm2 6.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/.claude/settings.local.json +8 -0
  2. package/.gitattributes +4 -0
  3. package/.mocharc.js +14 -0
  4. package/CHANGELOG.md +2416 -0
  5. package/CLAUDE.md +84 -0
  6. package/CONTRIBUTING.md +124 -0
  7. package/GNU-AGPL-3.0.txt +665 -0
  8. package/LICENSE +1 -0
  9. package/README.md +248 -0
  10. package/bin/zm2 +3 -0
  11. package/bin/zm2-dev +3 -0
  12. package/bin/zm2-docker +3 -0
  13. package/bin/zm2-runtime +3 -0
  14. package/bin/zm2-windows +3 -0
  15. package/bin/zm2.ps1 +3 -0
  16. package/bun.lock +421 -0
  17. package/constants.js +114 -0
  18. package/index.js +13 -0
  19. package/lib/API/Configuration.js +212 -0
  20. package/lib/API/Containerizer.js +335 -0
  21. package/lib/API/Dashboard.js +459 -0
  22. package/lib/API/Deploy.js +117 -0
  23. package/lib/API/Extra.js +775 -0
  24. package/lib/API/ExtraMgmt/Docker.js +30 -0
  25. package/lib/API/Log.js +315 -0
  26. package/lib/API/LogManagement.js +371 -0
  27. package/lib/API/Modules/LOCAL.js +122 -0
  28. package/lib/API/Modules/Modularizer.js +148 -0
  29. package/lib/API/Modules/NPM.js +445 -0
  30. package/lib/API/Modules/TAR.js +362 -0
  31. package/lib/API/Modules/flagExt.js +46 -0
  32. package/lib/API/Modules/index.js +120 -0
  33. package/lib/API/Monit.js +247 -0
  34. package/lib/API/Serve.js +343 -0
  35. package/lib/API/Startup.js +629 -0
  36. package/lib/API/UX/helpers.js +213 -0
  37. package/lib/API/UX/index.js +9 -0
  38. package/lib/API/UX/pm2-describe.js +193 -0
  39. package/lib/API/UX/pm2-ls-minimal.js +31 -0
  40. package/lib/API/UX/pm2-ls.js +483 -0
  41. package/lib/API/Version.js +382 -0
  42. package/lib/API/interpreter.json +12 -0
  43. package/lib/API/pm2-plus/PM2IO.js +372 -0
  44. package/lib/API/pm2-plus/auth-strategies/CliAuth.js +288 -0
  45. package/lib/API/pm2-plus/auth-strategies/WebAuth.js +187 -0
  46. package/lib/API/pm2-plus/helpers.js +97 -0
  47. package/lib/API/pm2-plus/link.js +126 -0
  48. package/lib/API/pm2-plus/pres/motd +16 -0
  49. package/lib/API/pm2-plus/pres/motd.update +26 -0
  50. package/lib/API/pm2-plus/pres/welcome +28 -0
  51. package/lib/API/pm2-plus/process-selector.js +52 -0
  52. package/lib/API/schema.json +379 -0
  53. package/lib/API.js +1931 -0
  54. package/lib/Client.js +776 -0
  55. package/lib/Common.js +911 -0
  56. package/lib/Configuration.js +304 -0
  57. package/lib/Daemon.js +456 -0
  58. package/lib/Event.js +37 -0
  59. package/lib/God/ActionMethods.js +909 -0
  60. package/lib/God/ClusterMode.js +97 -0
  61. package/lib/God/ForkMode.js +297 -0
  62. package/lib/God/Methods.js +265 -0
  63. package/lib/God/Reload.js +240 -0
  64. package/lib/God.js +632 -0
  65. package/lib/HttpInterface.js +76 -0
  66. package/lib/ProcessContainer.js +305 -0
  67. package/lib/ProcessContainerBun.js +360 -0
  68. package/lib/ProcessContainerFork.js +42 -0
  69. package/lib/ProcessContainerForkBun.js +33 -0
  70. package/lib/ProcessUtils.js +55 -0
  71. package/lib/TreeKill.js +118 -0
  72. package/lib/Utility.js +430 -0
  73. package/lib/VersionCheck.js +46 -0
  74. package/lib/Watcher.js +117 -0
  75. package/lib/Worker.js +169 -0
  76. package/lib/binaries/CLI.js +1041 -0
  77. package/lib/binaries/DevCLI.js +183 -0
  78. package/lib/binaries/Runtime.js +101 -0
  79. package/lib/binaries/Runtime4Docker.js +192 -0
  80. package/lib/completion.js +229 -0
  81. package/lib/completion.sh +40 -0
  82. package/lib/motd +36 -0
  83. package/lib/templates/Dockerfiles/Dockerfile-java.tpl +7 -0
  84. package/lib/templates/Dockerfiles/Dockerfile-nodejs.tpl +8 -0
  85. package/lib/templates/Dockerfiles/Dockerfile-ruby.tpl +7 -0
  86. package/lib/templates/ecosystem-es.tpl +24 -0
  87. package/lib/templates/ecosystem-simple-es.tpl +8 -0
  88. package/lib/templates/ecosystem-simple.tpl +6 -0
  89. package/lib/templates/ecosystem.tpl +22 -0
  90. package/lib/templates/init-scripts/launchd.tpl +35 -0
  91. package/lib/templates/init-scripts/openrc.tpl +52 -0
  92. package/lib/templates/init-scripts/pm2-init-amazon.sh +86 -0
  93. package/lib/templates/init-scripts/rcd-openbsd.tpl +41 -0
  94. package/lib/templates/init-scripts/rcd.tpl +44 -0
  95. package/lib/templates/init-scripts/smf.tpl +43 -0
  96. package/lib/templates/init-scripts/systemd-online.tpl +22 -0
  97. package/lib/templates/init-scripts/systemd.tpl +22 -0
  98. package/lib/templates/init-scripts/upstart.tpl +103 -0
  99. package/lib/templates/logrotate.d/pm2 +10 -0
  100. package/lib/templates/sample-apps/http-server/README.md +14 -0
  101. package/lib/templates/sample-apps/http-server/api.js +9 -0
  102. package/lib/templates/sample-apps/http-server/ecosystem.config.js +14 -0
  103. package/lib/templates/sample-apps/http-server/package.json +11 -0
  104. package/lib/templates/sample-apps/pm2-plus-metrics-actions/README.md +45 -0
  105. package/lib/templates/sample-apps/pm2-plus-metrics-actions/custom-metrics.js +66 -0
  106. package/lib/templates/sample-apps/pm2-plus-metrics-actions/ecosystem.config.js +12 -0
  107. package/lib/templates/sample-apps/pm2-plus-metrics-actions/package.json +11 -0
  108. package/lib/templates/sample-apps/python-app/README.md +4 -0
  109. package/lib/templates/sample-apps/python-app/echo.py +7 -0
  110. package/lib/templates/sample-apps/python-app/ecosystem.config.js +12 -0
  111. package/lib/templates/sample-apps/python-app/package.json +11 -0
  112. package/lib/tools/Config.js +248 -0
  113. package/lib/tools/IsAbsolute.js +20 -0
  114. package/lib/tools/copydirSync.js +101 -0
  115. package/lib/tools/deleteFolderRecursive.js +19 -0
  116. package/lib/tools/find-package-json.js +74 -0
  117. package/lib/tools/fmt.js +72 -0
  118. package/lib/tools/isbinaryfile.js +94 -0
  119. package/lib/tools/json5.js +752 -0
  120. package/lib/tools/open.js +63 -0
  121. package/lib/tools/passwd.js +58 -0
  122. package/lib/tools/promise.min.js +1 -0
  123. package/lib/tools/sexec.js +55 -0
  124. package/lib/tools/treeify.js +113 -0
  125. package/lib/tools/which.js +120 -0
  126. package/lib/tools/xdg-open +861 -0
  127. package/package.json +219 -0
  128. package/paths.js +93 -0
  129. package/pm2 +11 -0
  130. package/preinstall.js +24 -0
  131. package/run.sh +9 -0
  132. package/types/index.d.ts +722 -0
  133. package/types/tsconfig.json +14 -0
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Copyright 2013-2022 the PM2 project authors. All rights reserved.
3
+ * Use of this source code is governed by a license that
4
+ * can be found in the LICENSE file.
5
+ */
6
+ var url = require('url');
7
+ // Inject custom modules
8
+ var ProcessUtils = require('./ProcessUtils')
9
+ ProcessUtils.injectModules()
10
+
11
+ if (typeof(process.env.source_map_support) != "undefined" &&
12
+ process.env.source_map_support !== "false") {
13
+ require('source-map-support').install();
14
+ }
15
+
16
+ // Rename the process
17
+ process.title = process.env.PROCESS_TITLE || 'bun ' + process.env.pm_exec_path;
18
+
19
+ if (process.connected &&
20
+ process.send &&
21
+ process.versions &&
22
+ process.versions.node)
23
+ process.send({
24
+ 'node_version': process.versions.node
25
+ });
26
+
27
+ require(process.env.pm_exec_path);
28
+
29
+ // Change some values to make node think that the user's application
30
+ // was started directly such as `node app.js`
31
+ process.mainModule = process.mainModule || {};
32
+ process.mainModule.loaded = false;
33
+ require.main = process.mainModule;
@@ -0,0 +1,55 @@
1
+ 'use strict'
2
+
3
+ module.exports = {
4
+ injectModules: function() {
5
+ if (process.env.pmx !== 'false') {
6
+ const pmx = require('@pm2/io')
7
+
8
+ let conf = {}
9
+ const hasSpecificConfig = typeof process.env.io === 'string' || process.env.trace === 'true'
10
+ // pmx is already init, no need to do it twice
11
+ if (hasSpecificConfig === false) return
12
+
13
+ if (process.env.io) {
14
+ const io = JSON.parse(process.env.io)
15
+ conf = io.conf ? io.conf : conf
16
+ }
17
+ pmx.init(Object.assign({
18
+ tracing: process.env.trace === 'true' || false
19
+ }, conf))
20
+ }
21
+ },
22
+ isESModule(exec_path) {
23
+ var fs = require('fs')
24
+ var path = require('path')
25
+ var semver = require('semver')
26
+ var data
27
+
28
+ var findPackageJson = function(directory) {
29
+ var file = path.join(directory, 'package.json')
30
+ if (fs.existsSync(file) && fs.statSync(file).isFile()) {
31
+ return file;
32
+ }
33
+ var parent = path.resolve(directory, '..')
34
+ if (parent === directory) {
35
+ return null;
36
+ }
37
+ return findPackageJson(parent)
38
+ }
39
+
40
+ if (semver.satisfies(process.version, '< 13.3.0'))
41
+ return false
42
+
43
+ if (path.extname(exec_path) === '.mjs')
44
+ return true
45
+
46
+ try {
47
+ data = JSON.parse(fs.readFileSync(findPackageJson(path.dirname(exec_path))))
48
+ if (data.type === 'module')
49
+ return true
50
+ else
51
+ return false
52
+ } catch(e) {
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,118 @@
1
+ 'use strict';
2
+
3
+ // From https://raw.githubusercontent.com/pkrumins/node-tree-kill/master/index.js
4
+
5
+ var childProcess = require('child_process');
6
+ var spawn = childProcess.spawn;
7
+ var exec = childProcess.exec;
8
+
9
+ module.exports = function (pid, signal, callback) {
10
+ var tree = {};
11
+ var pidsToProcess = {};
12
+ tree[pid] = [];
13
+ pidsToProcess[pid] = 1;
14
+
15
+ switch (process.platform) {
16
+ case 'win32':
17
+ exec('taskkill /pid ' + pid + ' /T /F', { windowsHide: true }, callback);
18
+ break;
19
+ case 'freebsd':
20
+ case 'darwin':
21
+ buildProcessTree(pid, tree, pidsToProcess, function (parentPid) {
22
+ return spawn('pgrep', ['-P', parentPid]);
23
+ }, function () {
24
+ killAll(tree, signal, callback);
25
+ });
26
+ break;
27
+ // case 'sunos':
28
+ // buildProcessTreeSunOS(pid, tree, pidsToProcess, function () {
29
+ // killAll(tree, signal, callback);
30
+ // });
31
+ // break;
32
+ default: // Linux
33
+ buildProcessTree(pid, tree, pidsToProcess, function (parentPid) {
34
+ return spawn('ps', ['-o', 'pid', '--no-headers', '--ppid', parentPid]);
35
+ }, function () {
36
+ killAll(tree, signal, callback);
37
+ });
38
+ break;
39
+ }
40
+ };
41
+
42
+ function killAll (tree, signal, callback) {
43
+ var killed = {};
44
+ try {
45
+ Object.keys(tree).forEach(function (pid) {
46
+ tree[pid].forEach(function (pidpid) {
47
+ if (!killed[pidpid]) {
48
+ killPid(pidpid, signal);
49
+ killed[pidpid] = 1;
50
+ }
51
+ });
52
+ if (!killed[pid]) {
53
+ killPid(pid, signal);
54
+ killed[pid] = 1;
55
+ }
56
+ });
57
+ } catch (err) {
58
+ if (callback) {
59
+ return callback(err);
60
+ } else {
61
+ console.error(err);
62
+ }
63
+ }
64
+ if (callback) {
65
+ return callback();
66
+ }
67
+ }
68
+
69
+ function killPid(pid, signal) {
70
+ try {
71
+ process.kill(parseInt(pid, 10), signal);
72
+ }
73
+ catch (err) {
74
+ if (err.code !== 'ESRCH')
75
+ console.error(err);
76
+ }
77
+ }
78
+
79
+ function buildProcessTree (parentPid, tree, pidsToProcess, spawnChildProcessesList, cb) {
80
+ var ps = spawnChildProcessesList(parentPid);
81
+ var allData = '';
82
+
83
+ ps.on('error', function(err) {
84
+ console.error(err);
85
+ });
86
+
87
+ if (ps.stdout) {
88
+ ps.stdout.on('data', function (data) {
89
+ data = data.toString('ascii');
90
+ allData += data;
91
+ });
92
+ }
93
+
94
+ var onClose = function (code) {
95
+ delete pidsToProcess[parentPid];
96
+
97
+ if (code !== 0) {
98
+ // no more parent processes
99
+ if (Object.keys(pidsToProcess).length == 0) {
100
+ cb();
101
+ }
102
+ return;
103
+ }
104
+ var pids = allData.match(/\d+/g) || [];
105
+ if (pids.length === 0)
106
+ return cb();
107
+
108
+ pids.forEach(function (pid) {
109
+ pid = parseInt(pid, 10);
110
+ tree[parentPid].push(pid);
111
+ tree[pid] = [];
112
+ pidsToProcess[pid] = 1;
113
+ buildProcessTree(pid, tree, pidsToProcess, spawnChildProcessesList, cb);
114
+ });
115
+ };
116
+
117
+ ps.on('close', onClose);
118
+ }
package/lib/Utility.js ADDED
@@ -0,0 +1,430 @@
1
+ /**
2
+ * Copyright 2013-2022 the PM2 project authors. All rights reserved.
3
+ * Use of this source code is governed by a license that
4
+ * can be found in the LICENSE file.
5
+ */
6
+
7
+ /**
8
+ * Common Utilities ONLY USED IN ->DAEMON<-
9
+ */
10
+
11
+ var fclone = require('fclone');
12
+ var fs = require('fs');
13
+ var dgram = require('dgram');
14
+ var os = require('os');
15
+ var cst = require('../constants.js');
16
+ var waterfall = require('async/waterfall');
17
+ var util = require('util');
18
+ var url = require('url');
19
+ var dayjs = require('dayjs');
20
+ var findPackageJson = require('./tools/find-package-json')
21
+
22
+ /**
23
+ * Syslog severity levels
24
+ */
25
+ var SYSLOG_SEVERITY = {
26
+ err: 3, // LOG_ERR
27
+ out: 6, // LOG_INFO
28
+ std: 6 // LOG_INFO
29
+ };
30
+
31
+ var SYSLOG_FACILITY_USER = 1;
32
+
33
+ /**
34
+ * Resolve the syslog unix socket path based on platform
35
+ */
36
+ function getSyslogSocketPath() {
37
+ if (os.platform() === 'darwin')
38
+ return '/var/run/syslog';
39
+ return '/dev/log';
40
+ }
41
+
42
+ /**
43
+ * SyslogStream - A writable stream that sends messages to syslog via unix socket.
44
+ * Implements the same interface as fs.WriteStream so it can be used as a drop-in
45
+ * replacement in PM2's logging pipeline.
46
+ *
47
+ * @param {string} appName - Application name for syslog tag
48
+ * @param {number} pid - Process ID
49
+ * @param {string} type - Stream type: 'out', 'err', or 'std'
50
+ * @param {string} filePath - Original file path (stored as _file for reload compatibility)
51
+ */
52
+ function SyslogStream(appName, pid, type, filePath) {
53
+ this._appName = appName || 'pm2';
54
+ this._pid = pid || process.pid;
55
+ this._type = type || 'out';
56
+ this._file = filePath;
57
+ this._destroyed = false;
58
+
59
+ var severity = SYSLOG_SEVERITY[this._type] || 6;
60
+ this._priority = SYSLOG_FACILITY_USER * 8 + severity;
61
+
62
+ this._socketPath = getSyslogSocketPath();
63
+ this._socket = null;
64
+
65
+ try {
66
+ this._socket = dgram.createSocket('unix_dgram');
67
+ this._socket.on('error', function(err) {
68
+ console.error('PM2 syslog socket error:', err.message);
69
+ });
70
+ } catch (e) {
71
+ console.error('PM2 syslog: failed to create unix_dgram socket:', e.message);
72
+ }
73
+ }
74
+
75
+ SyslogStream.prototype.write = function(data, encoding, cb) {
76
+ if (this._destroyed || !this._socket) {
77
+ if (cb) cb();
78
+ return true;
79
+ }
80
+
81
+ var lines = data.toString().split('\n');
82
+ for (var i = 0; i < lines.length; i++) {
83
+ if (lines[i].length === 0) continue;
84
+
85
+ var msg = '<' + this._priority + '>' + this._appName + '[' + this._pid + ']: ' + lines[i];
86
+ var buf = Buffer.from(msg);
87
+
88
+ try {
89
+ this._socket.send(buf, 0, buf.length, this._socketPath);
90
+ } catch (e) {
91
+ // Socket may be unavailable; swallow error to avoid crashing the app
92
+ }
93
+ }
94
+
95
+ if (cb) cb();
96
+ return true;
97
+ };
98
+
99
+ SyslogStream.prototype.destroy = function() {
100
+ if (this._destroyed) return;
101
+ this._destroyed = true;
102
+ if (this._socket) {
103
+ try { this._socket.close(); } catch (e) {}
104
+ this._socket = null;
105
+ }
106
+ };
107
+
108
+ SyslogStream.prototype.end = function() { this.destroy(); };
109
+ SyslogStream.prototype.close = function() { this.destroy(); };
110
+
111
+ /**
112
+ * DualStream - Writes to both a file stream and a syslog stream.
113
+ *
114
+ * @param {object} fileStream - fs.WriteStream instance
115
+ * @param {object} syslogStream - SyslogStream instance
116
+ * @param {string} filePath - Original file path (stored as _file for reload compatibility)
117
+ */
118
+ function DualStream(fileStream, syslogStream, filePath) {
119
+ this._fileStream = fileStream;
120
+ this._syslogStream = syslogStream;
121
+ this._file = filePath;
122
+ this._destroyed = false;
123
+ }
124
+
125
+ DualStream.prototype.write = function(data, encoding, cb) {
126
+ if (this._destroyed) {
127
+ if (cb) cb();
128
+ return true;
129
+ }
130
+ this._syslogStream.write(data, encoding);
131
+ return this._fileStream.write(data, encoding, cb);
132
+ };
133
+
134
+ DualStream.prototype.destroy = function() {
135
+ if (this._destroyed) return;
136
+ this._destroyed = true;
137
+ if (this._fileStream && this._fileStream.destroy) this._fileStream.destroy();
138
+ if (this._syslogStream) this._syslogStream.destroy();
139
+ };
140
+
141
+ DualStream.prototype.end = function() { this.destroy(); };
142
+ DualStream.prototype.close = function() { this.destroy(); };
143
+
144
+ var Utility = module.exports = {
145
+ findPackageVersion : function(fullpath) {
146
+ var version
147
+
148
+ try {
149
+ version = findPackageJson(fullpath).next().value.version
150
+ } catch(e) {
151
+ version = 'N/A'
152
+ }
153
+ return version
154
+ },
155
+ getDate : function() {
156
+ return Date.now();
157
+ },
158
+ extendExtraConfig : function(proc, opts) {
159
+ if (opts.env && opts.env.current_conf) {
160
+ if (opts.env.current_conf.env &&
161
+ typeof(opts.env.current_conf.env) === 'object' &&
162
+ Object.keys(opts.env.current_conf.env).length === 0)
163
+ delete opts.env.current_conf.env
164
+
165
+ Utility.extendMix(proc.pm2_env, opts.env.current_conf);
166
+ delete opts.env.current_conf;
167
+ }
168
+ },
169
+ formatCLU : function(process) {
170
+ if (!process.pm2_env) {
171
+ return process;
172
+ }
173
+
174
+ var obj = Utility.clone(process.pm2_env);
175
+ delete obj.env;
176
+
177
+ return obj;
178
+ },
179
+ extend : function(destination, source){
180
+ if (!source || typeof source != 'object') return destination;
181
+
182
+ Object.keys(source).forEach(function(new_key) {
183
+ if (source[new_key] != '[object Object]')
184
+ destination[new_key] = source[new_key];
185
+ });
186
+
187
+ return destination;
188
+ },
189
+ // Same as extend but drop value with 'null'
190
+ extendMix : function(destination, source){
191
+ if (!source || typeof source != 'object') return destination;
192
+
193
+ Object.keys(source).forEach(function(new_key) {
194
+ if (source[new_key] == 'null')
195
+ delete destination[new_key];
196
+ else
197
+ destination[new_key] = source[new_key]
198
+ });
199
+
200
+ return destination;
201
+ },
202
+
203
+ whichFileExists : function(file_arr) {
204
+ var f = null;
205
+
206
+ file_arr.some(function(file) {
207
+ try {
208
+ fs.statSync(file);
209
+ } catch(e) {
210
+ return false;
211
+ }
212
+ f = file;
213
+ return true;
214
+ });
215
+ return f;
216
+ },
217
+ clone : function(obj) {
218
+ if (obj === null || obj === undefined) return {};
219
+ return fclone(obj);
220
+ },
221
+ overrideConsole : function(bus) {
222
+ if (cst.PM2_LOG_DATE_FORMAT && typeof cst.PM2_LOG_DATE_FORMAT == 'string') {
223
+ // Generate timestamp prefix
224
+ function timestamp(){
225
+ return `${dayjs(Date.now()).format(cst.PM2_LOG_DATE_FORMAT)}:`;
226
+ }
227
+
228
+ var hacks = ['info', 'log', 'error', 'warn'], consoled = {};
229
+
230
+ // store console functions.
231
+ hacks.forEach(function(method){
232
+ consoled[method] = console[method];
233
+ });
234
+
235
+ hacks.forEach(function(k){
236
+ console[k] = function(){
237
+ if (bus) {
238
+ bus.emit('log:PM2', {
239
+ process : {
240
+ pm_id : 'PM2',
241
+ name : 'PM2',
242
+ rev : null
243
+ },
244
+ at : Utility.getDate(),
245
+ data : util.format.apply(this, arguments) + '\n'
246
+ });
247
+ }
248
+ // do not destroy variable insertion
249
+ arguments[0] && (arguments[0] = timestamp() + ' PM2 ' + k + ': ' + arguments[0]);
250
+ consoled[k].apply(console, arguments);
251
+ };
252
+ });
253
+ }
254
+ },
255
+ startLogging : function(stds, pm2_env, callback) {
256
+ /**
257
+ * Start log outgoing messages
258
+ * @method startLogging
259
+ * @param {object} stds - Stream targets {out, err, std}
260
+ * @param {object} [pm2_env] - Process environment (optional, for backward compat)
261
+ * @param {function} callback
262
+ * @return
263
+ */
264
+
265
+ // Backward compatibility: startLogging(stds, callback)
266
+ if (typeof pm2_env === 'function') {
267
+ callback = pm2_env;
268
+ pm2_env = null;
269
+ }
270
+
271
+ var transport = (pm2_env && pm2_env.log_transport) || 'file';
272
+
273
+ // waterfall.
274
+ var flows = [];
275
+ // types of stdio, should be sorted as `std(entire log)`, `out`, `err`.
276
+ var types = Object.keys(stds).sort(function(x, y){
277
+ return -x.charCodeAt(0) + y.charCodeAt(0);
278
+ });
279
+
280
+ // Create write streams.
281
+ (function createWS(io){
282
+ if(io.length != 1){
283
+ return false;
284
+ }
285
+ io = io[0];
286
+
287
+ // If `std` is a Stream type, try next `std`.
288
+ // compatible with `pm2 reloadLogs`
289
+ if(typeof stds[io] == 'object' && !isNaN(stds[io].fd)){
290
+ return createWS(types.splice(0, 1));
291
+ }
292
+
293
+ flows.push(function(next){
294
+ var file = stds[io];
295
+
296
+ // if file contains ERR or /dev/null, dont try to create stream since he dont want logs
297
+ if (!file || file.indexOf('NULL') > -1 || file.indexOf('/dev/null') > -1)
298
+ return next();
299
+
300
+ if (transport === 'syslog') {
301
+ var appName = (pm2_env && pm2_env.name) || 'pm2';
302
+ var pid = (pm2_env && pm2_env.pm_id) || process.pid;
303
+ stds[io] = new SyslogStream(appName, pid, io, file);
304
+ stds[io]._file = file;
305
+ return next();
306
+ }
307
+
308
+ if (transport === 'both') {
309
+ var appName = (pm2_env && pm2_env.name) || 'pm2';
310
+ var pid = (pm2_env && pm2_env.pm_id) || process.pid;
311
+ var sysStream = new SyslogStream(appName, pid, io, file);
312
+
313
+ var fileStream = fs.createWriteStream(file, {flags: 'a'})
314
+ .once('error', next)
315
+ .on('open', function(){
316
+ fileStream.removeListener('error', next);
317
+ fileStream.on('error', function(err) {
318
+ console.error(err);
319
+ });
320
+
321
+ stds[io] = new DualStream(fileStream, sysStream, file);
322
+ stds[io]._file = file;
323
+ next();
324
+ });
325
+ return;
326
+ }
327
+
328
+ // Default: file transport
329
+ stds[io] = fs.createWriteStream(file, {flags: 'a'})
330
+ .once('error', next)
331
+ .on('open', function(){
332
+ stds[io].removeListener('error', next);
333
+
334
+ stds[io].on('error', function(err) {
335
+ console.error(err);
336
+ });
337
+
338
+ next();
339
+ });
340
+ stds[io]._file = file;
341
+ });
342
+ return createWS(types.splice(0, 1));
343
+ })(types.splice(0, 1));
344
+
345
+ waterfall(flows, callback);
346
+ },
347
+
348
+ /**
349
+ * Function parse the module name and returns it as canonic:
350
+ * - Makes the name based on installation filename.
351
+ * - Removes the Github author, module version and git branch from original name.
352
+ *
353
+ * @param {string} module_name
354
+ * @returns {string} Canonic module name (without trimed parts).
355
+ * @example Always returns 'pm2-slack' for inputs 'ma-zal/pm2-slack', 'ma-zal/pm2-slack#own-branch',
356
+ * 'pm2-slack-1.0.0.tgz' or 'pm2-slack@1.0.0'.
357
+ */
358
+ getCanonicModuleName: function(module_name) {
359
+ if (typeof module_name !== 'string') return null;
360
+ var canonic_module_name = module_name;
361
+
362
+ // Returns the module name from a .tgz package name (or the original name if it is not a valid pkg).
363
+ // Input: The package name (e.g. "foo.tgz", "foo-1.0.0.tgz", "folder/foo.tgz")
364
+ // Output: The module name
365
+ if (canonic_module_name.match(/\.tgz($|\?)/)) {
366
+ if (canonic_module_name.match(/^(.+\/)?([^\/]+)\.tgz($|\?)/)) {
367
+ canonic_module_name = canonic_module_name.match(/^(.+\/)?([^\/]+)\.tgz($|\?)/)[2];
368
+ if (canonic_module_name.match(/^(.+)-[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9_]+\.[0-9]+)?$/)) {
369
+ canonic_module_name = canonic_module_name.match(/^(.+)-[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9_]+\.[0-9]+)?$/)[1];
370
+ }
371
+ }
372
+ }
373
+
374
+ //pm2 install git+https://github.com/user/module
375
+ if(canonic_module_name.indexOf('git+') !== -1) {
376
+ canonic_module_name = canonic_module_name.split('/').pop();
377
+ }
378
+
379
+ //pm2 install https://github.com/user/module
380
+ if(canonic_module_name.indexOf('http') !== -1) {
381
+ var uri = url.parse(canonic_module_name);
382
+ canonic_module_name = uri.pathname.split('/').pop();
383
+ }
384
+
385
+ //pm2 install file:///home/user/module
386
+ else if(canonic_module_name.indexOf('file://') === 0) {
387
+ canonic_module_name = canonic_module_name.replace(/\/$/, '').split('/').pop();
388
+ }
389
+
390
+ //pm2 install username/module
391
+ else if(canonic_module_name.indexOf('/') !== -1) {
392
+ if (canonic_module_name.charAt(0) !== "@"){
393
+ canonic_module_name = canonic_module_name.split('/')[1];
394
+ }
395
+ }
396
+
397
+ //pm2 install @somescope/module@2.1.0-beta
398
+ if(canonic_module_name.lastIndexOf('@') > 0) {
399
+ canonic_module_name = canonic_module_name.substr(0,canonic_module_name.lastIndexOf("@"));
400
+ }
401
+
402
+ //pm2 install module#some-branch
403
+ if(canonic_module_name.indexOf('#') !== -1) {
404
+ canonic_module_name = canonic_module_name.split('#')[0];
405
+ }
406
+
407
+ if (canonic_module_name.indexOf('.git') !== -1) {
408
+ canonic_module_name = canonic_module_name.replace('.git', '');
409
+ }
410
+
411
+ return canonic_module_name;
412
+ },
413
+
414
+ checkPathIsNull: function(path) {
415
+ return path === 'NULL' || path === '/dev/null' || path === '\\\\.\\NUL';
416
+ },
417
+
418
+ generateUUID: function () {
419
+ var s = [];
420
+ var hexDigits = "0123456789abcdef";
421
+ for (var i = 0; i < 36; i++) {
422
+ s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
423
+ }
424
+ s[14] = "4";
425
+ s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
426
+ s[8] = s[13] = s[18] = s[23] = "-";
427
+ return s.join("");
428
+ }
429
+
430
+ };
@@ -0,0 +1,46 @@
1
+
2
+ var vCheck = require('@pm2/pm2-version-check')
3
+ var semver = require('semver')
4
+ var fs = require('fs')
5
+ var os = require('os')
6
+
7
+ function hasDockerEnv() {
8
+ try {
9
+ fs.statSync('/.dockerenv');
10
+ return true;
11
+ } catch (_) {
12
+ return false;
13
+ }
14
+ }
15
+
16
+ function hasDockerCGroup() {
17
+ try {
18
+ return fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker');
19
+ } catch (_) {
20
+ return false;
21
+ }
22
+ }
23
+
24
+ module.exports = function (opts) {
25
+ var params = {
26
+ state: opts.state,
27
+ version: opts.version
28
+ }
29
+
30
+ try {
31
+ params.os = os.type()
32
+ params.uptime = Math.floor(process.uptime())
33
+ params.nodev = process.versions.node
34
+ params.docker = hasDockerEnv() || hasDockerCGroup()
35
+ } catch(e) {
36
+ }
37
+
38
+ vCheck.runCheck(params, (err, pkg) => {
39
+ if (err) return false
40
+ if (!pkg.current_version) return false
41
+ if (opts.version && semver.lt(opts.version, pkg.current_version)) {
42
+ console.log('[PM2] This PM2 is not UP TO DATE')
43
+ console.log('[PM2] Upgrade to version %s', pkg.current_version)
44
+ }
45
+ })
46
+ }