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