@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,97 @@
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
+ 'use strict';
7
+
8
+ /**
9
+ * @file Cluster execution functions related
10
+ * @author Alexandre Strzelewicz <as@unitech.io>
11
+ * @project PM2
12
+ */
13
+ var cluster = require('cluster');
14
+ var Utility = require('../Utility.js');
15
+ var pkg = require('../../package.json');
16
+
17
+ /**
18
+ * Description
19
+ * @method exports
20
+ * @param {} God
21
+ * @return
22
+ */
23
+ module.exports = function ClusterMode(God) {
24
+
25
+ /**
26
+ * For Node apps - Cluster mode
27
+ * It will wrap the code and enable load-balancing mode
28
+ * @method nodeApp
29
+ * @param {} env_copy
30
+ * @param {} cb
31
+ * @return Literal
32
+ */
33
+ God.nodeApp = function nodeApp(env_copy, cb){
34
+ var clu = null;
35
+
36
+ console.log(`App [${env_copy.name}:${env_copy.pm_id}] starting in -cluster mode-`)
37
+ if (env_copy.node_args && Array.isArray(env_copy.node_args)) {
38
+ cluster.settings.execArgv = env_copy.node_args;
39
+ }
40
+
41
+ env_copy._pm2_version = pkg.version;
42
+
43
+ try {
44
+ // node.js cluster clients can not receive deep-level objects or arrays in the forked process, e.g.:
45
+ // { "args": ["foo", "bar"], "env": { "foo1": "bar1" }} will be parsed to
46
+ // { "args": "foo, bar", "env": "[object Object]"}
47
+ // So we passing a stringified JSON here.
48
+ clu = cluster.fork({pm2_env: JSON.stringify(env_copy), windowsHide: true});
49
+ } catch(e) {
50
+ God.logAndGenerateError(e);
51
+ return cb(e);
52
+ }
53
+
54
+ clu.pm2_env = env_copy;
55
+
56
+ /**
57
+ * Broadcast message to God
58
+ */
59
+ clu.on('message', function cluMessage(msg) {
60
+ /*********************************
61
+ * If you edit this function
62
+ * Do the same in ForkMode.js !
63
+ *********************************/
64
+ if (msg.data && msg.type) {
65
+ return God.bus.emit(msg.type ? msg.type : 'process:msg', {
66
+ at : Utility.getDate(),
67
+ data : msg.data,
68
+ process : {
69
+ pm_id : clu.pm2_env.pm_id,
70
+ name : clu.pm2_env.name,
71
+ rev : (clu.pm2_env.versioning && clu.pm2_env.versioning.revision) ? clu.pm2_env.versioning.revision : null,
72
+ namespace : clu.pm2_env.namespace
73
+ }
74
+ });
75
+ }
76
+ else {
77
+
78
+ if (typeof msg == 'object' && 'node_version' in msg) {
79
+ clu.pm2_env.node_version = msg.node_version;
80
+ return false;
81
+ }
82
+
83
+ return God.bus.emit('process:msg', {
84
+ at : Utility.getDate(),
85
+ raw : msg,
86
+ process : {
87
+ pm_id : clu.pm2_env.pm_id,
88
+ name : clu.pm2_env.name,
89
+ namespace : clu.pm2_env.namespace
90
+ }
91
+ });
92
+ }
93
+ });
94
+
95
+ return cb(null, clu);
96
+ };
97
+ };
@@ -0,0 +1,297 @@
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
+ 'use strict';
7
+
8
+ /**
9
+ * @file Fork execution related functions
10
+ * @author Alexandre Strzelewicz <as@unitech.io>
11
+ * @project PM2
12
+ */
13
+ var log = require('debug')('zm2:fork_mode');
14
+ var fs = require('fs');
15
+ var Utility = require('../Utility.js');
16
+ var path = require('path');
17
+ var dayjs = require('dayjs');
18
+ var semver = require('semver')
19
+ var cst = require('../../constants.js');
20
+
21
+ /**
22
+ * Description
23
+ * @method exports
24
+ * @param {} God
25
+ * @return
26
+ */
27
+ module.exports = function ForkMode(God) {
28
+ /**
29
+ * For all apps - FORK MODE
30
+ * fork the app
31
+ * @method forkMode
32
+ * @param {} pm2_env
33
+ * @param {} cb
34
+ * @return
35
+ */
36
+ God.forkMode = function forkMode(pm2_env, cb) {
37
+ var command = '';
38
+ var args = [];
39
+
40
+ console.log(`App [${pm2_env.name}:${pm2_env.pm_id}] starting in -fork mode-`)
41
+ var spawn = require('child_process').spawn;
42
+
43
+ var interpreter = pm2_env.exec_interpreter || process.execPath;
44
+ var pidFile = pm2_env.pm_pid_path;
45
+
46
+ if (interpreter !== 'none') {
47
+ command = interpreter;
48
+
49
+ if (pm2_env.node_args && Array.isArray(pm2_env.node_args)) {
50
+ args = args.concat(pm2_env.node_args);
51
+ }
52
+
53
+ // Deprecated - to remove at some point
54
+ if (process.env.PM2_NODE_OPTIONS) {
55
+ args = args.concat(process.env.PM2_NODE_OPTIONS.split(' '));
56
+ }
57
+
58
+ if (interpreter === 'node' || RegExp('node$').test(interpreter)) {
59
+ args.push(path.resolve(path.dirname(module.filename), '..', 'ProcessContainerFork.js'));
60
+ }
61
+ else if (interpreter.includes('bun') === true) {
62
+ args.push(path.resolve(path.dirname(module.filename), '..', 'ProcessContainerForkBun.js'));
63
+ }
64
+ else
65
+ args.push(pm2_env.pm_exec_path);
66
+ }
67
+ else {
68
+ command = pm2_env.pm_exec_path;
69
+ args = [ ];
70
+ }
71
+
72
+ if (pm2_env.args) {
73
+ args = args.concat(pm2_env.args);
74
+ }
75
+
76
+ // piping stream o file
77
+ var stds = {
78
+ out: pm2_env.pm_out_log_path,
79
+ err: pm2_env.pm_err_log_path
80
+ };
81
+
82
+ // entire log std if necessary.
83
+ if ('pm_log_path' in pm2_env){
84
+ stds.std = pm2_env.pm_log_path;
85
+ }
86
+
87
+ log("stds: %j", stds);
88
+
89
+ Utility.startLogging(stds, pm2_env, function(err, result) {
90
+ if (err) {
91
+ God.logAndGenerateError(err);
92
+ return cb(err);
93
+ };
94
+
95
+ try {
96
+ var options = {
97
+ env : pm2_env,
98
+ detached : true,
99
+ cwd : pm2_env.pm_cwd || process.cwd(),
100
+ stdio : ['pipe', 'pipe', 'pipe', 'ipc'] //Same as fork() in node core
101
+ }
102
+
103
+ if (typeof(pm2_env.windowsHide) === "boolean") {
104
+ options.windowsHide = pm2_env.windowsHide;
105
+ } else {
106
+ options.windowsHide = true;
107
+ }
108
+
109
+ if (pm2_env.uid) {
110
+ options.uid = pm2_env.uid
111
+ }
112
+
113
+ if (pm2_env.gid) {
114
+ options.gid = pm2_env.gid
115
+ }
116
+
117
+ var cspr = spawn(command, args, options);
118
+ } catch(e) {
119
+ God.logAndGenerateError(e);
120
+ return cb(e);
121
+ }
122
+
123
+ if (!cspr || !cspr.stderr || !cspr.stdout) {
124
+ var fatalError = new Error('Process could not be forked properly, check your system health')
125
+ God.logAndGenerateError(fatalError);
126
+ return cb(fatalError);
127
+ }
128
+
129
+ cspr.process = {};
130
+ cspr.process.pid = cspr.pid;
131
+ cspr.pm2_env = pm2_env;
132
+
133
+ function transformLogToJson(pm2_env, type, data) {
134
+ return JSON.stringify({
135
+ message : data.toString(),
136
+ timestamp : pm2_env.log_date_format ? dayjs().format(pm2_env.log_date_format) : new Date().toISOString(),
137
+ type : type,
138
+ process_id : cspr.pm2_env.pm_id,
139
+ app_name : cspr.pm2_env.name
140
+ }) + '\n'
141
+ }
142
+
143
+ function prefixLogWithDate(pm2_env, data) {
144
+ var log_data = []
145
+ log_data = data.toString().split('\n')
146
+ if (log_data.length > 1)
147
+ log_data.pop()
148
+ log_data = log_data.map(line => `${dayjs().format(pm2_env.log_date_format)}: ${line}\n`)
149
+ log_data = log_data.join('')
150
+ return log_data
151
+ }
152
+
153
+ cspr.stderr.on('data', function forkErrData(data) {
154
+ var log_data = null;
155
+
156
+ // via --out /dev/null --err /dev/null
157
+ if (pm2_env.disable_logs === true) return false;
158
+
159
+ if (pm2_env.log_type && pm2_env.log_type === 'json')
160
+ log_data = transformLogToJson(pm2_env, 'err', data)
161
+ else if (pm2_env.log_date_format)
162
+ log_data = prefixLogWithDate(pm2_env, data)
163
+ else
164
+ log_data = data.toString();
165
+
166
+ God.bus.emit('log:err', {
167
+ process : {
168
+ pm_id : cspr.pm2_env.pm_id,
169
+ name : cspr.pm2_env.name,
170
+ rev : (cspr.pm2_env.versioning && cspr.pm2_env.versioning.revision) ? cspr.pm2_env.versioning.revision : null,
171
+ namespace : cspr.pm2_env.namespace
172
+ },
173
+ at : Utility.getDate(),
174
+ data : log_data
175
+ });
176
+
177
+ if (Utility.checkPathIsNull(pm2_env.pm_err_log_path) &&
178
+ (!pm2_env.pm_log_path || Utility.checkPathIsNull(pm2_env.pm_log_path))) {
179
+ return false;
180
+ }
181
+
182
+ stds.std && stds.std.write && stds.std.write(log_data);
183
+ stds.err && stds.err.write && stds.err.write(log_data);
184
+ });
185
+
186
+ cspr.stdout.on('data', function forkOutData(data) {
187
+ var log_data = null;
188
+
189
+ if (pm2_env.disable_logs === true)
190
+ return false;
191
+
192
+ if (pm2_env.log_type && pm2_env.log_type === 'json')
193
+ log_data = transformLogToJson(pm2_env, 'out', data)
194
+ else if (pm2_env.log_date_format)
195
+ log_data = prefixLogWithDate(pm2_env, data)
196
+ else
197
+ log_data = data.toString()
198
+
199
+ God.bus.emit('log:out', {
200
+ process : {
201
+ pm_id : cspr.pm2_env.pm_id,
202
+ name : cspr.pm2_env.name,
203
+ rev : (cspr.pm2_env.versioning && cspr.pm2_env.versioning.revision) ? cspr.pm2_env.versioning.revision : null,
204
+ namespace : cspr.pm2_env.namespace
205
+ },
206
+ at : Utility.getDate(),
207
+ data : log_data
208
+ });
209
+
210
+ if (Utility.checkPathIsNull(pm2_env.pm_out_log_path) &&
211
+ (!pm2_env.pm_log_path || Utility.checkPathIsNull(pm2_env.pm_log_path)))
212
+ return false;
213
+
214
+ stds.std && stds.std.write && stds.std.write(log_data);
215
+ stds.out && stds.out.write && stds.out.write(log_data);
216
+ });
217
+
218
+ /**
219
+ * Broadcast message to God
220
+ */
221
+ cspr.on('message', function forkMessage(msg) {
222
+ /*********************************
223
+ * If you edit this function
224
+ * Do the same in ClusterMode.js !
225
+ *********************************/
226
+ if (msg.data && msg.type) {
227
+ process.nextTick(function() {
228
+ return God.bus.emit(msg.type ? msg.type : 'process:msg', {
229
+ at : Utility.getDate(),
230
+ data : msg.data,
231
+ process : {
232
+ pm_id : cspr.pm2_env.pm_id,
233
+ name : cspr.pm2_env.name,
234
+ versioning : cspr.pm2_env.versioning,
235
+ namespace : cspr.pm2_env.namespace
236
+ }
237
+ });
238
+ });
239
+ }
240
+ else {
241
+
242
+ if (typeof msg == 'object' && 'node_version' in msg) {
243
+ cspr.pm2_env.node_version = msg.node_version;
244
+ return false;
245
+ }
246
+
247
+ return God.bus.emit('process:msg', {
248
+ at : Utility.getDate(),
249
+ raw : msg,
250
+ process : {
251
+ pm_id : cspr.pm2_env.pm_id,
252
+ name : cspr.pm2_env.name,
253
+ namespace : cspr.pm2_env.namespace
254
+ }
255
+ });
256
+ }
257
+ });
258
+
259
+ try {
260
+ var pid = cspr.pid
261
+ if (typeof(pid) !== 'undefined')
262
+ fs.writeFileSync(pidFile, pid.toString());
263
+ } catch (e) {
264
+ console.error(e.stack || e);
265
+ }
266
+
267
+ cspr.once('exit', function forkClose(status) {
268
+ try {
269
+ for(var k in stds){
270
+ if (stds[k] && stds[k].destroy) stds[k].destroy();
271
+ else if (stds[k] && stds[k].end) stds[k].end();
272
+ else if (stds[k] && stds[k].close) stds[k].close();
273
+ stds[k] = stds[k]._file;
274
+ }
275
+ } catch(e) { God.logAndGenerateError(e);}
276
+ });
277
+
278
+ cspr._reloadLogs = function(cb) {
279
+ try {
280
+ for (var k in stds){
281
+ if (stds[k] && stds[k].destroy) stds[k].destroy();
282
+ else if (stds[k] && stds[k].end) stds[k].end();
283
+ else if (stds[k] && stds[k].close) stds[k].close();
284
+ stds[k] = stds[k]._file;
285
+ }
286
+ } catch(e) { God.logAndGenerateError(e);}
287
+ //cspr.removeAllListeners();
288
+ Utility.startLogging(stds, pm2_env, cb);
289
+ };
290
+
291
+ cspr.unref();
292
+
293
+ return cb(null, cspr);
294
+ });
295
+
296
+ };
297
+ };
@@ -0,0 +1,265 @@
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
+ 'use strict';
7
+
8
+ /**
9
+ * @file Utilities for PM2
10
+ * @author Alexandre Strzelewicz <as@unitech.io>
11
+ * @project PM2
12
+ */
13
+ var p = require('path');
14
+ var treekill = require('../TreeKill');
15
+ var cst = require('../../constants.js');
16
+
17
+ /**
18
+ * Description
19
+ * @method exports
20
+ * @param {} God
21
+ * @return
22
+ */
23
+ module.exports = function(God) {
24
+
25
+ /**
26
+ * Description
27
+ * @method logAndGenerateError
28
+ * @param {} err
29
+ * @return NewExpression
30
+ */
31
+ God.logAndGenerateError = function(err) {
32
+ // Is an Error object
33
+ if (err instanceof Error) {
34
+ console.trace(err);
35
+ return err;
36
+ }
37
+ // Is a JSON or simple string
38
+ console.error(err);
39
+ return new Error(err);
40
+ };
41
+
42
+ /**
43
+ * Utility functions
44
+ * @method getProcesses
45
+ * @return MemberExpression
46
+ */
47
+ God.getProcesses = function() {
48
+ return God.clusters_db;
49
+ };
50
+
51
+ God.getFormatedProcess = function getFormatedProcesses(id) {
52
+ if (God.clusters_db[id])
53
+ return {
54
+ pid : God.clusters_db[id].process.pid,
55
+ name : God.clusters_db[id].pm2_env.name,
56
+ pm2_env : God.clusters_db[id].pm2_env,
57
+ pm_id : God.clusters_db[id].pm2_env.pm_id
58
+ };
59
+ return {};
60
+ };
61
+
62
+ /**
63
+ * Get formated processes
64
+ * @method getFormatedProcesses
65
+ * @return {Array} formated processes
66
+ */
67
+ God.getFormatedProcesses = function getFormatedProcesses() {
68
+ var keys = Object.keys(God.clusters_db);
69
+ var arr = new Array();
70
+ var kl = keys.length;
71
+
72
+ for (var i = 0; i < kl; i++) {
73
+ var key = keys[i];
74
+
75
+ if (!God.clusters_db[key]) continue;
76
+ // Avoid _old type pm_ids
77
+ if (isNaN(God.clusters_db[key].pm2_env.pm_id)) continue;
78
+
79
+ arr.push({
80
+ pid : God.clusters_db[key].process.pid,
81
+ name : God.clusters_db[key].pm2_env.name,
82
+ pm2_env : God.clusters_db[key].pm2_env,
83
+ pm_id : God.clusters_db[key].pm2_env.pm_id
84
+ })
85
+ }
86
+ return arr;
87
+ };
88
+
89
+ /**
90
+ * Description
91
+ * @method findProcessById
92
+ * @param {} id
93
+ * @return ConditionalExpression
94
+ */
95
+ God.findProcessById = function findProcessById(id) {
96
+ return God.clusters_db[id] ? God.clusters_db[id] : null;
97
+ };
98
+
99
+ /**
100
+ * Description
101
+ * @method findByName
102
+ * @param {} name
103
+ * @return arr
104
+ */
105
+ God.findByName = function(name) {
106
+ var db = God.clusters_db;
107
+ var arr = [];
108
+
109
+ if (name == 'all') {
110
+ for (var key in db) {
111
+ // Avoid _old_proc process style
112
+ if (typeof(God.clusters_db[key].pm2_env.pm_id) === 'number')
113
+ arr.push(db[key]);
114
+ }
115
+ return arr;
116
+ }
117
+
118
+ for (var key in db) {
119
+ if (God.clusters_db[key].pm2_env.name == name ||
120
+ God.clusters_db[key].pm2_env.pm_exec_path == p.resolve(name)) {
121
+ arr.push(db[key]);
122
+ }
123
+ }
124
+ return arr;
125
+ };
126
+
127
+ /**
128
+ * Check if a process is alive in system processes
129
+ * Return TRUE if process online
130
+ * @method checkProcess
131
+ * @param {} pid
132
+ * @return
133
+ */
134
+ God.checkProcess = function(pid) {
135
+ if (!pid) return false;
136
+
137
+ try {
138
+ // Sending 0 signal do not kill the process
139
+ process.kill(pid, 0);
140
+ return true;
141
+ }
142
+ catch (err) {
143
+ return false;
144
+ }
145
+ };
146
+
147
+ /**
148
+ * Description
149
+ * @method processIsDead
150
+ * @param {} pid
151
+ * @param {} cb
152
+ * @return Literal
153
+ */
154
+ God.processIsDead = function(pid, pm2_env, cb, sigkill) {
155
+ if (!pid) return cb({type : 'param:missing', msg : 'no pid passed'});
156
+
157
+ var timeout = null;
158
+ var kill_timeout = (pm2_env && pm2_env.kill_timeout) ? pm2_env.kill_timeout : cst.KILL_TIMEOUT;
159
+ var mode = pm2_env.exec_mode;
160
+
161
+ var timer = setInterval(function() {
162
+ if (God.checkProcess(pid) === false) {
163
+ console.log('pid=%d msg=process killed', pid);
164
+ clearTimeout(timeout);
165
+ clearInterval(timer);
166
+ return cb(null, true);
167
+ }
168
+ console.log('pid=%d msg=failed to kill - retrying in %dms', pid, pm2_env.kill_retry_time);
169
+ return false;
170
+ }, pm2_env.kill_retry_time);
171
+
172
+ timeout = setTimeout(function() {
173
+ clearInterval(timer);
174
+ if (sigkill) {
175
+ console.log('Process with pid %d could not be killed', pid);
176
+ return cb({type : 'timeout', msg : 'timeout'});
177
+ }
178
+ else {
179
+ console.log('Process with pid %d still alive after %sms, sending it SIGKILL now...', pid, kill_timeout);
180
+
181
+ if (pm2_env.treekill !== true) {
182
+ try {
183
+ process.kill(parseInt(pid), 'SIGKILL');
184
+ } catch(e) {
185
+ console.error('[SimpleKill][SIGKILL] %s pid can not be killed', pid, e.stack, e.message);
186
+ }
187
+ return God.processIsDead(pid, pm2_env, cb, true);
188
+ }
189
+ else {
190
+ treekill(parseInt(pid), 'SIGKILL', function(err) {
191
+ return God.processIsDead(pid, pm2_env, cb, true);
192
+ });
193
+ }
194
+ }
195
+ }, kill_timeout);
196
+ return false;
197
+ };
198
+
199
+ /**
200
+ * Description
201
+ * @method killProcess
202
+ * @param int pid
203
+ * @param Object pm2_env
204
+ * @param function cb
205
+ * @return CallExpression
206
+ */
207
+ God.killProcess = function(pid, pm2_env, cb) {
208
+ if (!pid) return cb({msg : 'no pid passed or null'});
209
+
210
+ if (typeof(pm2_env.pm_id) === 'number' &&
211
+ (cst.KILL_USE_MESSAGE || pm2_env.shutdown_with_message == true)) {
212
+ var proc = God.clusters_db[pm2_env.pm_id];
213
+
214
+ if (proc && proc.send) {
215
+ try {
216
+ proc.send('shutdown');
217
+ } catch (e) {
218
+ console.error(`[AppKill] Cannot send "shutdown" message to ${pid}`)
219
+ console.error(e.stack, e.message)
220
+ }
221
+ return God.processIsDead(pid, pm2_env, cb);
222
+ }
223
+ else {
224
+ console.log(`[AppKill] ${pid} pid cannot be notified with send()`)
225
+ }
226
+ }
227
+
228
+ if (pm2_env.treekill !== true) {
229
+ try {
230
+ process.kill(parseInt(pid), cst.KILL_SIGNAL);
231
+ } catch(e) {
232
+ console.error('[SimpleKill] %s pid can not be killed', pid, e.stack, e.message);
233
+ }
234
+ return God.processIsDead(pid, pm2_env, cb);
235
+ }
236
+ else {
237
+ treekill(parseInt(pid), cst.KILL_SIGNAL, function(err) {
238
+ return God.processIsDead(pid, pm2_env, cb);
239
+ });
240
+ }
241
+ };
242
+
243
+ /**
244
+ * Description
245
+ * @method getNewId
246
+ * @return UpdateExpression
247
+ */
248
+ God.getNewId = function() {
249
+ return God.next_id++;
250
+ };
251
+
252
+ /**
253
+ * When a process is restarted or reloaded reset fields
254
+ * to monitor unstable starts
255
+ * @method resetState
256
+ * @param {} pm2_env
257
+ * @return
258
+ */
259
+ God.resetState = function(pm2_env) {
260
+ pm2_env.created_at = Date.now();
261
+ pm2_env.unstable_restarts = 0;
262
+ pm2_env.prev_restart_delay = 0;
263
+ };
264
+
265
+ };