1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | 'use strict';
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | var fs = require('fs');
|
15 | var path = require('path');
|
16 | var eachLimit = require('async/eachLimit');
|
17 | var os = require('os');
|
18 | var p = path;
|
19 | var cst = require('../../constants.js');
|
20 | var pkg = require('../../package.json');
|
21 | var pidusage = require('pidusage');
|
22 | var util = require('util');
|
23 | var debug = require('debug')('pm2:ActionMethod');
|
24 | var Utility = require('../Utility');
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | module.exports = function(God) {
|
33 | |
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 | God.getMonitorData = function getMonitorData(env, cb) {
|
41 | var processes = God.getFormatedProcesses();
|
42 | var pids = processes.filter(filterBadProcess)
|
43 | .map(function(pro, i) {
|
44 | var pid = getProcessId(pro)
|
45 | return pid;
|
46 | })
|
47 |
|
48 |
|
49 | if (pids.length === 0) {
|
50 | return cb(null, processes.map(function(pro) {
|
51 | pro['monit'] = {
|
52 | memory : 0,
|
53 | cpu : 0
|
54 | };
|
55 |
|
56 | return pro
|
57 | }))
|
58 | }
|
59 |
|
60 | pidusage(pids, function retPidUsage(err, statistics) {
|
61 |
|
62 | if (err) {
|
63 | console.error('Error caught while calling pidusage');
|
64 | console.error(err);
|
65 |
|
66 | return cb(null, processes.map(function(pro) {
|
67 | pro['monit'] = {
|
68 | memory : 0,
|
69 | cpu : 0
|
70 | };
|
71 | return pro
|
72 | }))
|
73 | }
|
74 |
|
75 | if (!statistics) {
|
76 | console.error('Statistics is not defined!')
|
77 |
|
78 | return cb(null, processes.map(function(pro) {
|
79 | pro['monit'] = {
|
80 | memory : 0,
|
81 | cpu : 0
|
82 | };
|
83 | return pro
|
84 | }))
|
85 | }
|
86 |
|
87 | processes = processes.map(function(pro) {
|
88 | if (filterBadProcess(pro) === false) {
|
89 | pro['monit'] = {
|
90 | memory : 0,
|
91 | cpu : 0
|
92 | };
|
93 |
|
94 | return pro;
|
95 | }
|
96 |
|
97 | var pid = getProcessId(pro);
|
98 | var stat = statistics[pid];
|
99 |
|
100 | if (!stat) {
|
101 | pro['monit'] = {
|
102 | memory : 0,
|
103 | cpu : 0
|
104 | };
|
105 |
|
106 | return pro;
|
107 | }
|
108 |
|
109 | pro['monit'] = {
|
110 | memory: stat.memory,
|
111 | cpu: Math.round(stat.cpu * 10) / 10
|
112 | };
|
113 |
|
114 | return pro;
|
115 | });
|
116 |
|
117 | cb(null, processes);
|
118 | });
|
119 | };
|
120 |
|
121 | |
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 | God.getSystemData = function getSystemData(env, cb) {
|
129 | if (God.system_infos_proc !== null)
|
130 | God.system_infos_proc.query((err, data) => {
|
131 | cb(null, data)
|
132 | })
|
133 | else {
|
134 | cb(new Error('Sysinfos not launched, type: pm2 sysmonit'))
|
135 | }
|
136 | };
|
137 |
|
138 | |
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 | God.dumpProcessList = function(cb) {
|
145 | var process_list = [];
|
146 | var apps = Utility.clone(God.getFormatedProcesses());
|
147 | var that = this;
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 | if (!apps[0]) {
|
154 | debug('[PM2] Did not override dump file because list of processes is empty');
|
155 | return cb(null, {success:true, process_list: process_list});
|
156 | }
|
157 |
|
158 | function fin(err) {
|
159 |
|
160 |
|
161 |
|
162 | if (process_list.length === 0) {
|
163 |
|
164 |
|
165 | if (!fs.existsSync(cst.DUMP_FILE_PATH) && typeof that.clearDump === 'function') {
|
166 | that.clearDump(function(){});
|
167 | }
|
168 |
|
169 |
|
170 |
|
171 | return cb(null, {success:true, process_list: process_list});
|
172 | }
|
173 |
|
174 |
|
175 | try {
|
176 | if (fs.existsSync(cst.DUMP_FILE_PATH)) {
|
177 | fs.writeFileSync(cst.DUMP_BACKUP_FILE_PATH, fs.readFileSync(cst.DUMP_FILE_PATH));
|
178 | }
|
179 | } catch (e) {
|
180 | console.error(e.stack || e);
|
181 | }
|
182 |
|
183 |
|
184 | try {
|
185 | fs.writeFileSync(cst.DUMP_FILE_PATH, JSON.stringify(process_list));
|
186 | } catch (e) {
|
187 | console.error(e.stack || e);
|
188 | try {
|
189 |
|
190 | if (fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)) {
|
191 | fs.writeFileSync(cst.DUMP_FILE_PATH, fs.readFileSync(cst.DUMP_BACKUP_FILE_PATH));
|
192 | }
|
193 | } catch (e) {
|
194 |
|
195 | fs.unlinkSync(cst.DUMP_FILE_PATH);
|
196 | console.error(e.stack || e);
|
197 | }
|
198 | }
|
199 |
|
200 | return cb(null, {success:true, process_list: process_list});
|
201 | }
|
202 |
|
203 | function saveProc(apps) {
|
204 | if (!apps[0])
|
205 | return fin(null);
|
206 | delete apps[0].pm2_env.instances;
|
207 | delete apps[0].pm2_env.pm_id;
|
208 |
|
209 | if (!apps[0].pm2_env.pmx_module)
|
210 | process_list.push(apps[0].pm2_env);
|
211 | apps.shift();
|
212 | return saveProc(apps);
|
213 | }
|
214 | saveProc(apps);
|
215 | };
|
216 |
|
217 | |
218 |
|
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 | God.ping = function(env, cb) {
|
225 | return cb(null, {msg : 'pong'});
|
226 | };
|
227 |
|
228 | |
229 |
|
230 |
|
231 |
|
232 | God.notifyKillPM2 = function() {
|
233 | God.pm2_being_killed = true;
|
234 | };
|
235 |
|
236 | |
237 |
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 | God.duplicateProcessId = function(id, cb) {
|
244 | if (!(id in God.clusters_db))
|
245 | return cb(God.logAndGenerateError(id + ' id unknown'), {});
|
246 |
|
247 | if (!God.clusters_db[id] || !God.clusters_db[id].pm2_env)
|
248 | return cb(God.logAndGenerateError('Error when getting proc || proc.pm2_env'), {});
|
249 |
|
250 | var proc = Utility.clone(God.clusters_db[id].pm2_env);
|
251 |
|
252 |
|
253 | delete proc.created_at;
|
254 | delete proc.pm_id;
|
255 | delete proc.unique_id;
|
256 |
|
257 |
|
258 | proc.unique_id = Utility.generateUUID()
|
259 |
|
260 | God.injectVariables(proc, function inject (_err, proc) {
|
261 | return God.executeApp(Utility.clone(proc), function (err, clu) {
|
262 | if (err) return cb(err);
|
263 | God.notify('start', clu, true);
|
264 | return cb(err, Utility.clone(clu));
|
265 | });
|
266 | });
|
267 | };
|
268 |
|
269 | |
270 |
|
271 |
|
272 |
|
273 |
|
274 |
|
275 |
|
276 | God.startProcessId = function(id, cb) {
|
277 | if (!(id in God.clusters_db))
|
278 | return cb(God.logAndGenerateError(id + ' id unknown'), {});
|
279 |
|
280 | var proc = God.clusters_db[id];
|
281 | if (proc.pm2_env.status == cst.ONLINE_STATUS)
|
282 | return cb(God.logAndGenerateError('process already online'), {});
|
283 | if (proc.pm2_env.status == cst.LAUNCHING_STATUS)
|
284 | return cb(God.logAndGenerateError('process already started'), {});
|
285 | if (proc.process && proc.process.pid)
|
286 | return cb(God.logAndGenerateError('Process with pid ' + proc.process.pid + ' already exists'), {});
|
287 |
|
288 | return God.executeApp(God.clusters_db[id].pm2_env, function(err, proc) {
|
289 | return cb(err, Utility.clone(proc));
|
290 | });
|
291 | };
|
292 |
|
293 |
|
294 | |
295 |
|
296 |
|
297 |
|
298 |
|
299 |
|
300 |
|
301 | God.stopProcessId = function(id, cb) {
|
302 | if (typeof id == 'object' && 'id' in id)
|
303 | id = id.id;
|
304 |
|
305 | if (!(id in God.clusters_db))
|
306 | return cb(God.logAndGenerateError(id + ' : id unknown'), {});
|
307 |
|
308 | var proc = God.clusters_db[id];
|
309 |
|
310 |
|
311 | clearTimeout(proc.pm2_env.restart_task);
|
312 |
|
313 | if (proc.pm2_env.status == cst.STOPPED_STATUS) {
|
314 | proc.process.pid = 0;
|
315 | return cb(null, God.getFormatedProcess(id));
|
316 | }
|
317 |
|
318 | if (proc.state && proc.state === 'none')
|
319 | return setTimeout(function() { God.stopProcessId(id, cb); }, 250);
|
320 |
|
321 | console.log('Stopping app:%s id:%s', proc.pm2_env.name, proc.pm2_env.pm_id);
|
322 | proc.pm2_env.status = cst.STOPPING_STATUS;
|
323 |
|
324 | if (!proc.process.pid) {
|
325 | console.error('app=%s id=%d does not have a pid', proc.pm2_env.name, proc.pm2_env.pm_id);
|
326 | proc.pm2_env.status = cst.STOPPED_STATUS;
|
327 | return cb(null, { error : true, message : 'could not kill process w/o pid'});
|
328 | }
|
329 |
|
330 | God.killProcess(proc.process.pid, proc.pm2_env, function(err) {
|
331 | proc.pm2_env.status = cst.STOPPED_STATUS;
|
332 |
|
333 | God.notify('exit', proc);
|
334 |
|
335 | if (err && err.type && err.type === 'timeout') {
|
336 | console.error('app=%s id=%d pid=%s could not be stopped',
|
337 | proc.pm2_env.name,
|
338 | proc.pm2_env.pm_id,
|
339 | proc.process.pid);
|
340 | proc.pm2_env.status = cst.ERRORED_STATUS;
|
341 | return cb(null, God.getFormatedProcess(id));
|
342 | }
|
343 |
|
344 | if (proc.pm2_env.pm_id.toString().indexOf('_old_') !== 0) {
|
345 | try {
|
346 | fs.unlinkSync(proc.pm2_env.pm_pid_path);
|
347 | } catch (e) {}
|
348 | }
|
349 |
|
350 | if (proc.pm2_env.axm_actions) proc.pm2_env.axm_actions = [];
|
351 | if (proc.pm2_env.axm_monitor) proc.pm2_env.axm_monitor = {};
|
352 |
|
353 | proc.process.pid = 0;
|
354 | return cb(null, God.getFormatedProcess(id));
|
355 | });
|
356 | };
|
357 |
|
358 | God.resetMetaProcessId = function(id, cb) {
|
359 | if (!(id in God.clusters_db))
|
360 | return cb(God.logAndGenerateError(id + ' id unknown'), {});
|
361 |
|
362 | if (!God.clusters_db[id] || !God.clusters_db[id].pm2_env)
|
363 | return cb(God.logAndGenerateError('Error when getting proc || proc.pm2_env'), {});
|
364 |
|
365 | God.clusters_db[id].pm2_env.created_at = Utility.getDate();
|
366 | God.clusters_db[id].pm2_env.unstable_restarts = 0;
|
367 | God.clusters_db[id].pm2_env.restart_time = 0;
|
368 |
|
369 | return cb(null, God.getFormatedProcesses());
|
370 | };
|
371 |
|
372 | |
373 |
|
374 |
|
375 |
|
376 |
|
377 |
|
378 |
|
379 |
|
380 | God.deleteProcessId = function(id, cb) {
|
381 | God.deleteCron(id);
|
382 |
|
383 | God.stopProcessId(id, function(err, proc) {
|
384 | if (err) return cb(God.logAndGenerateError(err), {});
|
385 |
|
386 | delete God.clusters_db[id];
|
387 |
|
388 | if (Object.keys(God.clusters_db).length == 0)
|
389 | God.next_id = 0;
|
390 | return cb(null, proc);
|
391 | });
|
392 | return false;
|
393 | };
|
394 |
|
395 | |
396 |
|
397 |
|
398 |
|
399 |
|
400 |
|
401 |
|
402 |
|
403 |
|
404 | God.restartProcessId = function(opts, cb) {
|
405 | var id = opts.id;
|
406 | var env = opts.env || {};
|
407 |
|
408 | if (typeof(id) === 'undefined')
|
409 | return cb(God.logAndGenerateError('opts.id not passed to restartProcessId', opts));
|
410 | if (!(id in God.clusters_db))
|
411 | return cb(God.logAndGenerateError('God db process id unknown'), {});
|
412 |
|
413 | var proc = God.clusters_db[id];
|
414 |
|
415 | God.resetState(proc.pm2_env);
|
416 |
|
417 | |
418 |
|
419 |
|
420 |
|
421 | Utility.extend(proc.pm2_env.env, env);
|
422 | Utility.extendExtraConfig(proc, opts);
|
423 |
|
424 | if (God.pm2_being_killed) {
|
425 | return cb(God.logAndGenerateError('[RestartProcessId] PM2 is being killed, stopping restart procedure...'));
|
426 | }
|
427 | if (proc.pm2_env.status === cst.ONLINE_STATUS || proc.pm2_env.status === cst.LAUNCHING_STATUS) {
|
428 | God.stopProcessId(id, function(err) {
|
429 | if (God.pm2_being_killed)
|
430 | return cb(God.logAndGenerateError('[RestartProcessId] PM2 is being killed, stopping restart procedure...'));
|
431 | proc.pm2_env.restart_time += 1;
|
432 | return God.startProcessId(id, cb);
|
433 | });
|
434 |
|
435 | return false;
|
436 | }
|
437 | else {
|
438 | debug('[restart] process not online, starting it');
|
439 | return God.startProcessId(id, cb);
|
440 | }
|
441 | };
|
442 |
|
443 |
|
444 | |
445 |
|
446 |
|
447 |
|
448 |
|
449 |
|
450 |
|
451 | God.restartProcessName = function(name, cb) {
|
452 | var processes = God.findByName(name);
|
453 |
|
454 | if (processes && processes.length === 0)
|
455 | return cb(God.logAndGenerateError('Unknown process'), {});
|
456 |
|
457 | eachLimit(processes, cst.CONCURRENT_ACTIONS, function(proc, next) {
|
458 | if (God.pm2_being_killed)
|
459 | return next('[Watch] PM2 is being killed, stopping restart procedure...');
|
460 | if (proc.pm2_env.status === cst.ONLINE_STATUS)
|
461 | return God.restartProcessId({id:proc.pm2_env.pm_id}, next);
|
462 | else if (proc.pm2_env.status !== cst.STOPPING_STATUS
|
463 | && proc.pm2_env.status !== cst.LAUNCHING_STATUS)
|
464 | return God.startProcessId(proc.pm2_env.pm_id, next);
|
465 | else
|
466 | return next(util.format('[Watch] Process name %s is being stopped so I won\'t restart it', name));
|
467 | }, function(err) {
|
468 | if (err) return cb(God.logAndGenerateError(err));
|
469 | return cb(null, God.getFormatedProcesses());
|
470 | });
|
471 |
|
472 | return false;
|
473 | };
|
474 |
|
475 | |
476 |
|
477 |
|
478 |
|
479 |
|
480 |
|
481 |
|
482 | God.sendSignalToProcessId = function(opts, cb) {
|
483 | var id = opts.process_id;
|
484 | var signal = opts.signal;
|
485 |
|
486 | if (!(id in God.clusters_db))
|
487 | return cb(God.logAndGenerateError(id + ' id unknown'), {});
|
488 |
|
489 | var proc = God.clusters_db[id];
|
490 |
|
491 |
|
492 |
|
493 | try {
|
494 | process.kill(God.clusters_db[id].process.pid, signal);
|
495 | } catch(e) {
|
496 | return cb(God.logAndGenerateError('Error when sending signal (signal unknown)'), {});
|
497 | }
|
498 | return cb(null, God.getFormatedProcesses());
|
499 | };
|
500 |
|
501 | |
502 |
|
503 |
|
504 |
|
505 |
|
506 |
|
507 |
|
508 | God.sendSignalToProcessName = function(opts, cb) {
|
509 | var processes = God.findByName(opts.process_name);
|
510 | var signal = opts.signal;
|
511 |
|
512 | if (processes && processes.length === 0)
|
513 | return cb(God.logAndGenerateError('Unknown process name'), {});
|
514 |
|
515 | eachLimit(processes, cst.CONCURRENT_ACTIONS, function(proc, next) {
|
516 | if (proc.pm2_env.status == cst.ONLINE_STATUS || proc.pm2_env.status == cst.LAUNCHING_STATUS) {
|
517 | try {
|
518 | process.kill(proc.process.pid, signal);
|
519 | } catch(e) {
|
520 | return next(e);
|
521 | }
|
522 | }
|
523 | return setTimeout(next, 200);
|
524 | }, function(err) {
|
525 | if (err) return cb(God.logAndGenerateError(err), {});
|
526 | return cb(null, God.getFormatedProcesses());
|
527 | });
|
528 |
|
529 | };
|
530 |
|
531 | |
532 |
|
533 |
|
534 |
|
535 |
|
536 |
|
537 |
|
538 |
|
539 | God.stopWatch = function(method, value, fn) {
|
540 | var env = null;
|
541 |
|
542 | if (method == 'stopAll' || method == 'deleteAll') {
|
543 | var processes = God.getFormatedProcesses();
|
544 |
|
545 | processes.forEach(function(proc) {
|
546 | God.clusters_db[proc.pm_id].pm2_env.watch = false;
|
547 | God.watch.disable(proc.pm2_env);
|
548 | });
|
549 |
|
550 | } else {
|
551 |
|
552 | if (method.indexOf('ProcessId') !== -1) {
|
553 | env = God.clusters_db[value];
|
554 | } else if (method.indexOf('ProcessName') !== -1) {
|
555 | env = God.clusters_db[God.findByName(value)];
|
556 | }
|
557 |
|
558 | if (env) {
|
559 | God.watch.disable(env.pm2_env);
|
560 | env.pm2_env.watch = false;
|
561 | }
|
562 | }
|
563 | return fn(null, {success:true});
|
564 | };
|
565 |
|
566 |
|
567 | |
568 |
|
569 |
|
570 |
|
571 |
|
572 |
|
573 |
|
574 | God.toggleWatch = function(method, value, fn) {
|
575 | var env = null;
|
576 |
|
577 | if (method == 'restartProcessId') {
|
578 | env = God.clusters_db[value.id];
|
579 | } else if(method == 'restartProcessName') {
|
580 | env = God.clusters_db[God.findByName(value)];
|
581 | }
|
582 |
|
583 | if (env) {
|
584 | env.pm2_env.watch = !env.pm2_env.watch;
|
585 | if (env.pm2_env.watch)
|
586 | God.watch.enable(env.pm2_env);
|
587 | else
|
588 | God.watch.disable(env.pm2_env);
|
589 | }
|
590 |
|
591 | return fn(null, {success:true});
|
592 | };
|
593 |
|
594 | |
595 |
|
596 |
|
597 |
|
598 |
|
599 |
|
600 |
|
601 | God.startWatch = function(method, value, fn) {
|
602 | var env = null;
|
603 |
|
604 | if (method == 'restartProcessId') {
|
605 | env = God.clusters_db[value.id];
|
606 | } else if(method == 'restartProcessName') {
|
607 | env = God.clusters_db[God.findByName(value)];
|
608 | }
|
609 |
|
610 | if (env) {
|
611 | if (env.pm2_env.watch)
|
612 | return fn(null, {success:true, notrestarted:true});
|
613 |
|
614 | God.watch.enable(env.pm2_env);
|
615 |
|
616 | env.pm2_env.watch = true;
|
617 | }
|
618 |
|
619 | return fn(null, {success:true});
|
620 | };
|
621 |
|
622 | |
623 |
|
624 |
|
625 |
|
626 |
|
627 |
|
628 |
|
629 | God.reloadLogs = function(opts, cb) {
|
630 | console.log('Reloading logs...');
|
631 | var processIds = Object.keys(God.clusters_db);
|
632 |
|
633 | processIds.forEach(function (id) {
|
634 | var cluster = God.clusters_db[id];
|
635 |
|
636 | console.log('Reloading logs for process id %d', id);
|
637 |
|
638 | if (cluster && cluster.pm2_env) {
|
639 |
|
640 | if (cluster.send && cluster.pm2_env.exec_mode == 'cluster_mode') {
|
641 | try {
|
642 | cluster.send({
|
643 | type:'log:reload'
|
644 | });
|
645 | } catch(e) {
|
646 | console.error(e.message || e);
|
647 | }
|
648 | }
|
649 |
|
650 | else if (cluster._reloadLogs) {
|
651 | cluster._reloadLogs(function(err) {
|
652 | if (err) God.logAndGenerateError(err);
|
653 | });
|
654 | }
|
655 | }
|
656 | });
|
657 |
|
658 | return cb(null, {});
|
659 | };
|
660 |
|
661 | |
662 |
|
663 |
|
664 |
|
665 |
|
666 |
|
667 |
|
668 | God.sendLineToStdin = function(packet, cb) {
|
669 | if (typeof(packet.pm_id) == 'undefined' || !packet.line)
|
670 | return cb(God.logAndGenerateError('pm_id or line field missing'), {});
|
671 |
|
672 | var pm_id = packet.pm_id;
|
673 | var line = packet.line;
|
674 |
|
675 | var proc = God.clusters_db[pm_id];
|
676 |
|
677 | if (!proc)
|
678 | return cb(God.logAndGenerateError('Process with ID <' + pm_id + '> unknown.'), {});
|
679 |
|
680 | if (proc.pm2_env.exec_mode == 'cluster_mode')
|
681 | return cb(God.logAndGenerateError('Cannot send line to processes in cluster mode'), {});
|
682 |
|
683 | if (proc.pm2_env.status != cst.ONLINE_STATUS && proc.pm2_env.status != cst.LAUNCHING_STATUS)
|
684 | return cb(God.logAndGenerateError('Process with ID <' + pm_id + '> offline.'), {});
|
685 |
|
686 | try {
|
687 | proc.stdin.write(line, function() {
|
688 | return cb(null, {
|
689 | pm_id : pm_id,
|
690 | line : line
|
691 | });
|
692 | });
|
693 | } catch(e) {
|
694 | return cb(God.logAndGenerateError(e), {});
|
695 | }
|
696 | }
|
697 |
|
698 | |
699 |
|
700 |
|
701 |
|
702 | God.sendDataToProcessId = function(packet, cb) {
|
703 | if (typeof(packet.id) == 'undefined' ||
|
704 | typeof(packet.data) == 'undefined' ||
|
705 | !packet.topic)
|
706 | return cb(God.logAndGenerateError('ID, DATA or TOPIC field is missing'), {});
|
707 |
|
708 | var pm_id = packet.id;
|
709 | var data = packet.data;
|
710 |
|
711 | var proc = God.clusters_db[pm_id];
|
712 |
|
713 | if (!proc)
|
714 | return cb(God.logAndGenerateError('Process with ID <' + pm_id + '> unknown.'), {});
|
715 |
|
716 | if (proc.pm2_env.status != cst.ONLINE_STATUS && proc.pm2_env.status != cst.LAUNCHING_STATUS)
|
717 | return cb(God.logAndGenerateError('Process with ID <' + pm_id + '> offline.'), {});
|
718 |
|
719 | try {
|
720 | proc.send(packet);
|
721 | }
|
722 | catch(e) {
|
723 | return cb(God.logAndGenerateError(e), {});
|
724 | }
|
725 |
|
726 | return cb(null, {
|
727 | success: true,
|
728 | data : packet
|
729 | });
|
730 | };
|
731 |
|
732 | |
733 |
|
734 |
|
735 |
|
736 |
|
737 |
|
738 |
|
739 | God.msgProcess = function(cmd, cb) {
|
740 | if ('id' in cmd) {
|
741 | var id = cmd.id;
|
742 | if (!(id in God.clusters_db))
|
743 | return cb(God.logAndGenerateError(id + ' id unknown'), {});
|
744 | var proc = God.clusters_db[id];
|
745 |
|
746 | var action_exist = false;
|
747 |
|
748 | proc.pm2_env.axm_actions.forEach(function(action) {
|
749 | if (action.action_name == cmd.msg) {
|
750 | action_exist = true;
|
751 |
|
752 | action.output = [];
|
753 | }
|
754 | });
|
755 | if (action_exist == false) {
|
756 | return cb(God.logAndGenerateError('Action doesn\'t exist ' + cmd.msg + ' for ' + proc.pm2_env.name), {});
|
757 | }
|
758 |
|
759 | if (proc.pm2_env.status == cst.ONLINE_STATUS || proc.pm2_env.status == cst.LAUNCHING_STATUS) {
|
760 | |
761 |
|
762 |
|
763 | if (cmd.opts == null && !cmd.uuid)
|
764 | proc.send(cmd.msg);
|
765 | else
|
766 | proc.send(cmd);
|
767 |
|
768 | return cb(null, { process_count : 1, success : true });
|
769 | }
|
770 | else
|
771 | return cb(God.logAndGenerateError(id + ' : id offline'), {});
|
772 | }
|
773 |
|
774 | else if ('name' in cmd) {
|
775 | |
776 |
|
777 |
|
778 |
|
779 | var name = cmd.name;
|
780 | var arr = Object.keys(God.clusters_db);
|
781 | var sent = 0;
|
782 |
|
783 | (function ex(arr) {
|
784 | if (arr[0] == null || !arr) {
|
785 | return cb(null, {
|
786 | process_count : sent,
|
787 | success : true
|
788 | });
|
789 | }
|
790 |
|
791 | var id = arr[0];
|
792 |
|
793 | if (!God.clusters_db[id] || !God.clusters_db[id].pm2_env) {
|
794 | arr.shift();
|
795 | return ex(arr);
|
796 | }
|
797 |
|
798 | var proc_env = God.clusters_db[id].pm2_env;
|
799 |
|
800 | const isActionAvailable = proc_env.axm_actions.find(action => action.action_name === cmd.msg) !== undefined
|
801 |
|
802 |
|
803 |
|
804 | if (isActionAvailable === false) {
|
805 | arr.shift();
|
806 | return ex(arr);
|
807 | }
|
808 |
|
809 |
|
810 | if ((p.basename(proc_env.pm_exec_path) == name ||
|
811 | proc_env.name == name ||
|
812 | proc_env.namespace == name ||
|
813 | name == 'all') &&
|
814 | (proc_env.status == cst.ONLINE_STATUS ||
|
815 | proc_env.status == cst.LAUNCHING_STATUS)) {
|
816 |
|
817 | proc_env.axm_actions.forEach(function(action) {
|
818 | if (action.action_name == cmd.msg) {
|
819 | action_exist = true;
|
820 | }
|
821 | });
|
822 |
|
823 | if (action_exist == false || proc_env.axm_actions.length == 0) {
|
824 | arr.shift();
|
825 | return ex(arr);
|
826 | }
|
827 |
|
828 | if (cmd.opts == null)
|
829 | God.clusters_db[id].send(cmd.msg);
|
830 | else
|
831 | God.clusters_db[id].send(cmd);
|
832 |
|
833 | sent++;
|
834 | arr.shift();
|
835 | return ex(arr);
|
836 | }
|
837 | else {
|
838 | arr.shift();
|
839 | return ex(arr);
|
840 | }
|
841 | return false;
|
842 | })(arr);
|
843 | }
|
844 |
|
845 | else return cb(God.logAndGenerateError('method requires name or id field'), {});
|
846 | return false;
|
847 | };
|
848 |
|
849 | |
850 |
|
851 |
|
852 |
|
853 |
|
854 |
|
855 |
|
856 | God.getVersion = function(env, cb) {
|
857 | process.nextTick(function() {
|
858 | return cb(null, pkg.version);
|
859 | });
|
860 | };
|
861 |
|
862 | God.monitor = function Monitor(pm_id, cb) {
|
863 | if (!God.clusters_db[pm_id] || !God.clusters_db[pm_id].pm2_env)
|
864 | return cb(new Error('Unknown pm_id'));
|
865 |
|
866 | God.clusters_db[pm_id].pm2_env._km_monitored = true;
|
867 | return cb(null, { success : true, pm_id : pm_id });
|
868 | }
|
869 |
|
870 | God.unmonitor = function Monitor(pm_id, cb) {
|
871 | if (!God.clusters_db[pm_id] || !God.clusters_db[pm_id].pm2_env)
|
872 | return cb(new Error('Unknown pm_id'));
|
873 |
|
874 | God.clusters_db[pm_id].pm2_env._km_monitored = false;
|
875 | return cb(null, { success : true, pm_id : pm_id });
|
876 | }
|
877 |
|
878 | God.getReport = function(arg, cb) {
|
879 | var report = {
|
880 | pm2_version : pkg.version,
|
881 | node_version : 'N/A',
|
882 | node_path : process.env['_'] || 'not found',
|
883 | argv0 : process.argv0,
|
884 | argv : process.argv,
|
885 | user : process.env.USER,
|
886 | uid : (cst.IS_WINDOWS === false && process.geteuid) ? process.geteuid() : 'N/A',
|
887 | gid : (cst.IS_WINDOWS === false && process.getegid) ? process.getegid() : 'N/A',
|
888 | env : process.env,
|
889 | managed_apps : Object.keys(God.clusters_db).length,
|
890 | started_at : God.started_at
|
891 | };
|
892 |
|
893 | if (process.versions && process.versions.node) {
|
894 | report.node_version = process.versions.node;
|
895 | }
|
896 |
|
897 | process.nextTick(function() {
|
898 | return cb(null, report);
|
899 | });
|
900 | };
|
901 | };
|
902 |
|
903 | function filterBadProcess(pro) {
|
904 | if (pro.pm2_env.status !== cst.ONLINE_STATUS) {
|
905 | return false;
|
906 | }
|
907 |
|
908 | if (pro.pm2_env.axm_options && pro.pm2_env.axm_options.pid) {
|
909 | if (isNaN(pro.pm2_env.axm_options.pid)) {
|
910 | return false;
|
911 | }
|
912 | }
|
913 |
|
914 | return true;
|
915 | }
|
916 |
|
917 | function getProcessId(pro) {
|
918 | var pid = pro.pid
|
919 |
|
920 | if (pro.pm2_env.axm_options && pro.pm2_env.axm_options.pid) {
|
921 | pid = pro.pm2_env.axm_options.pid;
|
922 | }
|
923 |
|
924 | return pid
|
925 | }
|