1 | 'use strict'
|
2 |
|
3 | const log = require('debug')('interactor:pm2:interface')
|
4 | const path = require('path')
|
5 | const async = require('async')
|
6 | const fs = require('fs')
|
7 | const cst = require('../constants')
|
8 |
|
9 | module.exports = class PM2Interface {
|
10 | constructor (rpc) {
|
11 | log('PM2Interface instantiate')
|
12 | this.rpc = rpc
|
13 | }
|
14 |
|
15 | getProcessByName (name, cb) {
|
16 | var foundProc = []
|
17 |
|
18 | this.rpc.getMonitorData({}, (err, list) => {
|
19 | if (err) {
|
20 | log('Error retrieving process list: ' + err)
|
21 | return cb(err)
|
22 | }
|
23 |
|
24 | list.forEach((proc) => {
|
25 | if (proc.pm2_env.name === name || proc.pm2_env.pm_exec_path === path.resolve(name.toString())) {
|
26 | foundProc.push(proc)
|
27 | }
|
28 | })
|
29 |
|
30 | return cb(null, foundProc)
|
31 | })
|
32 | }
|
33 |
|
34 | |
35 |
|
36 |
|
37 |
|
38 | scale (opts, cb) {
|
39 | const self = this
|
40 | const appName = opts.name
|
41 | let number = opts.number
|
42 |
|
43 | function addProcs (proc, value, cb) {
|
44 | (function ex (proc, number) {
|
45 | if (number-- === 0) return cb()
|
46 | log('Scaling up application')
|
47 | self.rpc.duplicateProcessId(proc.pm2_env.pm_id, ex.bind(this, proc, number))
|
48 | })(proc, number)
|
49 | }
|
50 |
|
51 | function rmProcs (procs, value, cb) {
|
52 | let i = 0;
|
53 |
|
54 | (function ex (procs, number) {
|
55 | if (number++ === 0) return cb()
|
56 | self.rpc.deleteProcessId(procs[i++].pm2_env.pm_id, ex.bind(this, procs, number))
|
57 | })(procs, number)
|
58 | }
|
59 |
|
60 | let end = () => {
|
61 | return cb ? cb(null, {success: true}) : log('Successfuly scale')
|
62 | }
|
63 |
|
64 | this.getProcessByName(appName, (err, procs) => {
|
65 | if (err) {
|
66 | return cb ? cb(err) : log(err)
|
67 | }
|
68 |
|
69 | if (!procs || procs.length === 0) {
|
70 | log('Application %s not found', appName)
|
71 | return cb ? cb(new Error('App not found')) : log('App not found')
|
72 | }
|
73 |
|
74 | let procNumber = procs.length
|
75 |
|
76 | if (typeof (number) === 'string' && number.indexOf('+') >= 0) {
|
77 | number = parseInt(number, 10)
|
78 | return addProcs(procs[0], number, end)
|
79 | } else if (typeof (number) === 'string' && number.indexOf('-') >= 0) {
|
80 | number = parseInt(number, 10)
|
81 | return rmProcs(procs, number, end)
|
82 | } else {
|
83 | number = parseInt(number, 10)
|
84 | number = number - procNumber
|
85 |
|
86 | if (number < 0) {
|
87 | return rmProcs(procs, number, end)
|
88 | } else if (number > 0) {
|
89 | return addProcs(procs[0], number, end)
|
90 | } else {
|
91 | log('Nothing to do')
|
92 | return cb ? cb(new Error('Same process number')) : log('Same process number')
|
93 | }
|
94 | }
|
95 | })
|
96 | }
|
97 |
|
98 | |
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 | dump (cb) {
|
105 | var envArr = []
|
106 |
|
107 | this.rpc.getMonitorData({}, (err, list) => {
|
108 | if (err) {
|
109 | return typeof cb === 'function' ? cb(err) : false
|
110 | }
|
111 |
|
112 | |
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 | const end = () => {
|
119 |
|
120 | try {
|
121 | fs.writeFileSync(cst.DUMP_FILE_PATH, JSON.stringify(envArr, '', 2))
|
122 | } catch (e) {
|
123 | log('Dump error', e.stack || e)
|
124 | return cb(e)
|
125 | }
|
126 | return (cb) ? cb(null, {success: true}) : true
|
127 | }
|
128 |
|
129 | async.each(list, (app, done) => {
|
130 | delete app.pm2_env.instances
|
131 | delete app.pm2_env.pm_id
|
132 | if (!app.pm2_env.pmx_module) {
|
133 | envArr.push(app.pm2_env)
|
134 | }
|
135 | done()
|
136 | }, end)
|
137 | })
|
138 | }
|
139 |
|
140 | _callWithProcessId (fn, params, cb) {
|
141 | if (params.id === undefined) {
|
142 | this.getProcessByName(params.name, (err, processes) => {
|
143 | if (err) return cb(err)
|
144 |
|
145 |
|
146 |
|
147 | if (processes.length === 0) {
|
148 | return fn(Object.assign({ id: params.name }, params), cb)
|
149 | }
|
150 |
|
151 | async.eachOf(processes, (process, _key, localCb) => {
|
152 | params.id = process.pm_id
|
153 | fn(params, localCb)
|
154 | }, cb)
|
155 | })
|
156 | } else {
|
157 | fn(params, cb)
|
158 | }
|
159 | }
|
160 |
|
161 | restart (params, cb) {
|
162 | this._callWithProcessId(this.rpc.restartProcessId, params, cb)
|
163 | }
|
164 |
|
165 | reload (params, cb) {
|
166 | this._callWithProcessId(this.rpc.reloadProcessId, params, cb)
|
167 | }
|
168 |
|
169 | reset (params, cb) {
|
170 | this._callWithProcessId(
|
171 | (newParams, cb) => this.rpc.resetMetaProcessId(newParams.id, cb),
|
172 | params,
|
173 | cb
|
174 | )
|
175 | }
|
176 |
|
177 | ping (params, cb) {
|
178 | this._callWithProcessId(this.rpc.ping, params, cb)
|
179 | }
|
180 | }
|