1 |
|
2 | var cst = require('../../constants.js');
|
3 | var Common = require('../Common.js');
|
4 | var fs = require('fs');
|
5 | var eachSeries = require('async/eachSeries');
|
6 | var child = require('child_process');
|
7 |
|
8 | var printError = Common.printError;
|
9 | var printOut = Common.printOut;
|
10 |
|
11 | module.exports = function(CLI) {
|
12 |
|
13 | var EXEC_TIMEOUT = 60000;
|
14 |
|
15 | CLI.prototype._pull = function(opts, cb) {
|
16 | var that = this;
|
17 |
|
18 | var process_name = opts.process_name;
|
19 | var reload_type = opts.action;
|
20 |
|
21 | printOut(cst.PREFIX_MSG + 'Updating repository for process name %s', process_name);
|
22 |
|
23 | that.Client.getProcessByNameOrId(process_name, function (err, processes) {
|
24 |
|
25 | if (err || processes.length === 0) {
|
26 | printError('No processes with this name or id : %s', process_name);
|
27 | return cb ? cb({msg: 'Process not found: ' + process_name}) : that.exitCli(cst.ERROR_EXIT);
|
28 | }
|
29 |
|
30 | var proc = processes[0];
|
31 | if (!proc.pm2_env.versioning) {
|
32 | printOut(cst.PREFIX_MSG + 'No versioning system found for process %s', process_name);
|
33 | return cb ? cb({success:false, msg: 'No versioning system found for process'}) : that.exitCli(cst.SUCCESS_EXIT);
|
34 | }
|
35 | require('vizion').update({
|
36 | folder: proc.pm2_env.versioning.repo_path
|
37 | }, function(err, meta) {
|
38 | if (err !== null) {
|
39 | return cb ? cb({msg:err}) : that.exitCli(cst.ERROR_EXIT);
|
40 | }
|
41 |
|
42 | if (meta.success === true) {
|
43 | getPostUpdateCmds(proc.pm2_env.versioning.repo_path, process_name, function (command_list) {
|
44 | execCommands(proc.pm2_env.versioning.repo_path, command_list, function(err, res) {
|
45 | if (err !== null) {
|
46 | printError(err);
|
47 | return cb ? cb({msg: meta.output + err}) : that.exitCli(cst.ERROR_EXIT);
|
48 | }
|
49 | else {
|
50 | printOut(cst.PREFIX_MSG + 'Process successfully updated %s', process_name);
|
51 | printOut(cst.PREFIX_MSG + 'Current commit %s', meta.current_revision);
|
52 | return that[reload_type](process_name, function(err, procs) {
|
53 | if (err && cb) return cb(err);
|
54 | if (err) console.error(err);
|
55 | return cb ? cb(null, meta.output + res) : that.exitCli(cst.SUCCESS_EXIT);
|
56 | });
|
57 | }
|
58 | });
|
59 | });
|
60 | }
|
61 | else {
|
62 | printOut(cst.PREFIX_MSG + 'Already up-to-date or an error occured for app: %s', process_name);
|
63 | return cb ? cb({success:false, msg : 'Already up to date'}) : that.exitCli(cst.SUCCESS_EXIT);
|
64 | }
|
65 | return false;
|
66 | });
|
67 | return false;
|
68 | });
|
69 | };
|
70 |
|
71 | |
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 | CLI.prototype.pullCommitId = function(process_name, commit_id, cb) {
|
79 | var reload_type = 'reload';
|
80 | var that = this;
|
81 |
|
82 | printOut(cst.PREFIX_MSG + 'Updating repository for process name %s', process_name);
|
83 |
|
84 | that.Client.getProcessByNameOrId(process_name, function (err, processes) {
|
85 |
|
86 | if (err || processes.length === 0) {
|
87 | printError('No processes with this name or id : %s', process_name);
|
88 | return cb ? cb({msg: 'Process not found: ' + process_name}) : that.exitCli(cst.ERROR_EXIT);
|
89 | }
|
90 |
|
91 | var proc = processes[0];
|
92 | if (proc.pm2_env.versioning) {
|
93 | require('vizion').isUpToDate({folder: proc.pm2_env.versioning.repo_path}, function(err, meta) {
|
94 | if (err !== null)
|
95 | return cb ? cb({msg:err}) : that.exitCli(cst.ERROR_EXIT);
|
96 | require('vizion').revertTo(
|
97 | {revision: commit_id,
|
98 | folder: proc.pm2_env.versioning.repo_path},
|
99 | function(err2, meta2) {
|
100 | if (!err2 && meta2.success) {
|
101 | getPostUpdateCmds(proc.pm2_env.versioning.repo_path, process_name, function (command_list) {
|
102 | execCommands(proc.pm2_env.versioning.repo_path, command_list, function(err, res) {
|
103 | if (err !== null)
|
104 | {
|
105 | printError(err);
|
106 | return cb ? cb({msg:err}) : that.exitCli(cst.ERROR_EXIT);
|
107 | }
|
108 | else {
|
109 | printOut(cst.PREFIX_MSG + 'Process successfully updated %s', process_name);
|
110 | printOut(cst.PREFIX_MSG + 'Current commit %s', commit_id);
|
111 | return that[reload_type](process_name, cb);
|
112 | }
|
113 | });
|
114 | });
|
115 | }
|
116 | else {
|
117 | printOut(cst.PREFIX_MSG + 'Already up-to-date or an error occured: %s', process_name);
|
118 | return cb ? cb(null, {success:meta.success}) : that.exitCli(cst.SUCCESS_EXIT);
|
119 | }
|
120 | });
|
121 | });
|
122 | }
|
123 | else {
|
124 | printOut(cst.PREFIX_MSG + 'No versioning system found for process %s', process_name);
|
125 | return cb ? cb(null, {success:false}) : that.exitCli(cst.SUCCESS_EXIT);
|
126 | }
|
127 | });
|
128 | };
|
129 |
|
130 | |
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 | CLI.prototype.backward = function(process_name, cb) {
|
137 | var that = this;
|
138 | printOut(cst.PREFIX_MSG + 'Downgrading to previous commit repository for process name %s', process_name);
|
139 |
|
140 | that.Client.getProcessByNameOrId(process_name, function (err, processes) {
|
141 |
|
142 | if (err || processes.length === 0) {
|
143 | printError('No processes with this name or id : %s', process_name);
|
144 | return cb ? cb({msg: 'Process not found: ' + process_name}) : that.exitCli(cst.ERROR_EXIT);
|
145 | }
|
146 |
|
147 | var proc = processes[0];
|
148 |
|
149 | process_name = proc.name;
|
150 |
|
151 | if (proc.pm2_env.versioning === undefined ||
|
152 | proc.pm2_env.versioning === null)
|
153 | return cb({msg : 'Versioning unknown'});
|
154 |
|
155 | require('vizion').prev({
|
156 | folder: proc.pm2_env.versioning.repo_path
|
157 | }, function(err, meta) {
|
158 | if (err)
|
159 | return cb ? cb({msg:err, data : meta}) : that.exitCli(cst.ERROR_EXIT);
|
160 |
|
161 | if (meta.success !== true) {
|
162 | printOut(cst.PREFIX_MSG + 'No versioning system found for process %s', process_name);
|
163 | return cb ? cb({msg:err, data : meta}) : that.exitCli(cst.ERROR_EXIT);
|
164 | }
|
165 |
|
166 | getPostUpdateCmds(proc.pm2_env.versioning.repo_path, process_name, function (command_list) {
|
167 | execCommands(proc.pm2_env.versioning.repo_path, command_list, function(err, res) {
|
168 | if (err !== null) {
|
169 | require('vizion').next({folder: proc.pm2_env.versioning.repo_path}, function(err2, meta2) {
|
170 | printError(err);
|
171 | return cb ? cb({msg: meta.output + err}) : that.exitCli(cst.ERROR_EXIT);
|
172 | });
|
173 | return false;
|
174 | }
|
175 |
|
176 | printOut(cst.PREFIX_MSG + 'Process successfully updated %s', process_name);
|
177 | printOut(cst.PREFIX_MSG + 'Current commit %s', meta.current_revision);
|
178 | that.reload(process_name, function(err, procs) {
|
179 | if (err) return cb(err);
|
180 | return cb ? cb(null, meta.output + res) : that.exitCli(cst.SUCCESS_EXIT);
|
181 | });
|
182 | });
|
183 | });
|
184 | });
|
185 | });
|
186 | };
|
187 |
|
188 | |
189 |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 | CLI.prototype.forward = function(process_name, cb) {
|
195 | var that = this;
|
196 | printOut(cst.PREFIX_MSG + 'Updating to next commit repository for process name %s', process_name);
|
197 |
|
198 | that.Client.getProcessByNameOrId(process_name, function (err, processes) {
|
199 |
|
200 | if (err || processes.length === 0) {
|
201 | printError('No processes with this name or id: %s', process_name);
|
202 | return cb ? cb({msg: 'Process not found: ' + process_name}) : that.exitCli(cst.ERROR_EXIT);
|
203 | }
|
204 |
|
205 | var proc = processes[0];
|
206 |
|
207 | process_name = proc.name;
|
208 | if (proc.pm2_env.versioning) {
|
209 | require('vizion').next({folder: proc.pm2_env.versioning.repo_path}, function(err, meta) {
|
210 | if (err !== null)
|
211 | return cb ? cb({msg:err}) : that.exitCli(cst.ERROR_EXIT);
|
212 | if (meta.success === true) {
|
213 | getPostUpdateCmds(proc.pm2_env.versioning.repo_path, process_name, function (command_list) {
|
214 | execCommands(proc.pm2_env.versioning.repo_path, command_list, function(err, res) {
|
215 | if (err !== null)
|
216 | {
|
217 | require('vizion').prev({folder: proc.pm2_env.versioning.repo_path}, function(err2, meta2) {
|
218 | printError(err);
|
219 | return cb ? cb({msg:meta.output + err}) : that.exitCli(cst.ERROR_EXIT);
|
220 | });
|
221 | }
|
222 | else {
|
223 | printOut(cst.PREFIX_MSG + 'Process successfully updated %s', process_name);
|
224 | printOut(cst.PREFIX_MSG + 'Current commit %s', meta.current_revision);
|
225 | that.reload(process_name, function(err, procs) {
|
226 | if (err) return cb(err);
|
227 | return cb ? cb(null, meta.output + res) : that.exitCli(cst.SUCCESS_EXIT);
|
228 | });
|
229 | }
|
230 | });
|
231 | });
|
232 | }
|
233 | else {
|
234 | printOut(cst.PREFIX_MSG + 'Already up-to-date or an error occured: %s', process_name);
|
235 | return cb ? cb(null, {success:meta.success}) : that.exitCli(cst.SUCCESS_EXIT);
|
236 | }
|
237 | });
|
238 | }
|
239 | else {
|
240 | printOut(cst.PREFIX_MSG + 'No versioning system found for process %s', process_name);
|
241 | return cb ? cb({success:false, msg: 'No versioning system found'}) : that.exitCli(cst.SUCCESS_EXIT);
|
242 | }
|
243 | });
|
244 | };
|
245 |
|
246 | var exec = function (cmd, callback) {
|
247 | var output = '';
|
248 |
|
249 | var c = child.exec(cmd, {
|
250 | env: process.env,
|
251 | maxBuffer: 3*1024*1024,
|
252 | timeout: EXEC_TIMEOUT
|
253 | }, function(err) {
|
254 | if (callback)
|
255 | callback(err ? err.code : 0, output);
|
256 | });
|
257 |
|
258 | c.stdout.on('data', function(data) {
|
259 | output += data;
|
260 | });
|
261 |
|
262 | c.stderr.on('data', function(data) {
|
263 | output += data;
|
264 | });
|
265 | };
|
266 |
|
267 | |
268 |
|
269 |
|
270 |
|
271 |
|
272 |
|
273 |
|
274 | var execCommands = function(repo_path, command_list, cb) {
|
275 | var stdout = '';
|
276 |
|
277 | eachSeries(command_list, function(command, callback) {
|
278 | stdout += '\n' + command;
|
279 | exec('cd '+repo_path+';'+command,
|
280 | function(code, output) {
|
281 | stdout += '\n' + output;
|
282 | if (code === 0)
|
283 | callback();
|
284 | else
|
285 | callback('`'+command+'` failed');
|
286 | });
|
287 | }, function(err) {
|
288 | if (err)
|
289 | return cb(stdout + '\n' + err);
|
290 | return cb(null, stdout);
|
291 | });
|
292 | }
|
293 |
|
294 | |
295 |
|
296 |
|
297 |
|
298 |
|
299 |
|
300 |
|
301 | var getPostUpdateCmds = function(repo_path, proc_name, cb) {
|
302 | if (typeof repo_path !== 'string')
|
303 | return cb([]);
|
304 | if (repo_path[repo_path.length - 1] !== '/')
|
305 | repo_path += '/';
|
306 |
|
307 | var searchForCommands = function(file, callback) {
|
308 | fs.exists(repo_path+file, function(exists) {
|
309 | if (exists) {
|
310 | try {
|
311 | var conf_string = fs.readFileSync(repo_path + file);
|
312 | var data = Common.parseConfig(conf_string, repo_path + file);
|
313 | } catch (e) {
|
314 | console.error(e.message || e);
|
315 | }
|
316 |
|
317 | if (data && data.apps) {
|
318 | eachSeries(data.apps, function(item, callb) {
|
319 | if (item.name && item.name === proc_name) {
|
320 | if (item.post_update && typeof(item.post_update) === 'object') {
|
321 | if (item.exec_timeout)
|
322 | EXEC_TIMEOUT = parseInt(item.exec_timeout);
|
323 | return callb(item.post_update);
|
324 | }
|
325 | else {
|
326 | return callb();
|
327 | }
|
328 | }
|
329 | else
|
330 | return callb();
|
331 | }, function(final) {
|
332 | return callback(final);
|
333 | });
|
334 | }
|
335 | else {
|
336 | return callback();
|
337 | }
|
338 | }
|
339 | else {
|
340 | return callback();
|
341 | }
|
342 | });
|
343 | };
|
344 |
|
345 | eachSeries(['ecosystem.json', 'process.json', 'package.json'], searchForCommands,
|
346 | function(final) {
|
347 | return cb(final ? final : []);
|
348 | });
|
349 | };
|
350 |
|
351 |
|
352 | |
353 |
|
354 |
|
355 |
|
356 |
|
357 |
|
358 | CLI.prototype.pullAndRestart = function (process_name, cb) {
|
359 | this._pull({process_name: process_name, action: 'reload'}, cb);
|
360 | };
|
361 |
|
362 | |
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 | CLI.prototype.pullAndReload = function (process_name, cb) {
|
369 | this._pull({process_name: process_name, action: 'reload'}, cb);
|
370 | };
|
371 |
|
372 | |
373 |
|
374 |
|
375 |
|
376 |
|
377 |
|
378 | CLI.prototype._pullCommitId = function (opts, cb) {
|
379 | this.pullCommitId(opts.pm2_name, opts.commit_id, cb);
|
380 | };
|
381 |
|
382 | }
|