server-control-s3 0.0.13 → 0.0.15
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.
- package/dist/server_control.d.ts +28 -0
- package/dist/server_control.js +701 -0
- package/package.json +34 -12
- package/npm-shrinkwrap.json +0 -1015
- package/src/index.js +0 -620
- package/src/request.js +0 -40
package/src/index.js
DELETED
|
@@ -1,620 +0,0 @@
|
|
|
1
|
-
const async = require('async');
|
|
2
|
-
require('aws-sdk/lib/maintenance_mode_message').suppress = true;
|
|
3
|
-
const AWS = require('aws-sdk');
|
|
4
|
-
const body_parser = require('body-parser');
|
|
5
|
-
const child_process = require('child_process');
|
|
6
|
-
const cookie_parser = require('cookie-parser');
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const { join: pathJoin } = require('path');
|
|
9
|
-
const { webRequest, headUrl, fetchFileContents } = require('./request');
|
|
10
|
-
|
|
11
|
-
exports.init = init;
|
|
12
|
-
exports.getGitCommitHash = getGitCommitHash;
|
|
13
|
-
|
|
14
|
-
const MAX_WAIT_COUNT = 12;
|
|
15
|
-
const SERVER_WAIT_MS = 10 * 1000;
|
|
16
|
-
const DEFAULT_CONFIG = {
|
|
17
|
-
route_prefix: '',
|
|
18
|
-
secret: 'secret',
|
|
19
|
-
sc_update_url_key_name: 'SC_UPDATE_URL',
|
|
20
|
-
restart_function: _defaultRestartFunction,
|
|
21
|
-
service_port: 80,
|
|
22
|
-
http_proto: 'http',
|
|
23
|
-
auth_middleware: false,
|
|
24
|
-
repo_dir: process.env.PWD,
|
|
25
|
-
console_log: console.log,
|
|
26
|
-
error_log: console.error,
|
|
27
|
-
update_launch_default: true,
|
|
28
|
-
remove_old_target: true,
|
|
29
|
-
};
|
|
30
|
-
const g_config = {};
|
|
31
|
-
let g_gitCommitHash = false;
|
|
32
|
-
let g_updateHash = '';
|
|
33
|
-
|
|
34
|
-
function init(app, config) {
|
|
35
|
-
Object.assign(g_config, DEFAULT_CONFIG, config);
|
|
36
|
-
if (typeof g_config.route_prefix !== 'string') {
|
|
37
|
-
throw 'server-control route_prefix required';
|
|
38
|
-
}
|
|
39
|
-
if (!g_config.remote_repo_prefix) {
|
|
40
|
-
throw 'server-control remote_repo_prefix required';
|
|
41
|
-
}
|
|
42
|
-
g_config.route_prefix.replace(/\/$/, '');
|
|
43
|
-
g_config.remote_repo_prefix.replace(/\/$/, '');
|
|
44
|
-
|
|
45
|
-
_getAwsRegion();
|
|
46
|
-
getGitCommitHash();
|
|
47
|
-
const { route_prefix } = g_config;
|
|
48
|
-
if (g_config.remove_old_target) {
|
|
49
|
-
_removeOldTarget();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
app.get(
|
|
53
|
-
route_prefix + '/server_data',
|
|
54
|
-
_parseQuery,
|
|
55
|
-
body_parser.json(),
|
|
56
|
-
body_parser.urlencoded({ extended: false }),
|
|
57
|
-
cookie_parser(),
|
|
58
|
-
_secretOrAuth,
|
|
59
|
-
_serverData
|
|
60
|
-
);
|
|
61
|
-
app.get(
|
|
62
|
-
route_prefix + '/group_data',
|
|
63
|
-
_parseQuery,
|
|
64
|
-
body_parser.json(),
|
|
65
|
-
body_parser.urlencoded({ extended: false }),
|
|
66
|
-
cookie_parser(),
|
|
67
|
-
_secretOrAuth,
|
|
68
|
-
_groupData
|
|
69
|
-
);
|
|
70
|
-
app.get(
|
|
71
|
-
route_prefix + '/update_group',
|
|
72
|
-
_parseQuery,
|
|
73
|
-
body_parser.json(),
|
|
74
|
-
body_parser.urlencoded({ extended: false }),
|
|
75
|
-
cookie_parser(),
|
|
76
|
-
_secretOrAuth,
|
|
77
|
-
_updateGroup
|
|
78
|
-
);
|
|
79
|
-
app.get(
|
|
80
|
-
route_prefix + '/update_server',
|
|
81
|
-
_parseQuery,
|
|
82
|
-
body_parser.json(),
|
|
83
|
-
body_parser.urlencoded({ extended: false }),
|
|
84
|
-
cookie_parser(),
|
|
85
|
-
_secretOrAuth,
|
|
86
|
-
_updateServer
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
function _parseQuery(req, res, next) {
|
|
90
|
-
if (typeof req.query === 'string') {
|
|
91
|
-
const query = {};
|
|
92
|
-
req.query.split('&').forEach((key_val) => {
|
|
93
|
-
const split = key_val.split('=');
|
|
94
|
-
query[split[0]] = split[1] || '';
|
|
95
|
-
});
|
|
96
|
-
req.query = query;
|
|
97
|
-
}
|
|
98
|
-
next();
|
|
99
|
-
}
|
|
100
|
-
function _secretOrAuth(req, res, next) {
|
|
101
|
-
if (req.headers && req.headers['x-sc-secret'] === g_config.secret) {
|
|
102
|
-
next();
|
|
103
|
-
} else if (
|
|
104
|
-
req.body &&
|
|
105
|
-
req.body.secret &&
|
|
106
|
-
req.body.secret === g_config.secret
|
|
107
|
-
) {
|
|
108
|
-
next();
|
|
109
|
-
} else if (
|
|
110
|
-
req.cookies &&
|
|
111
|
-
req.cookies.secret &&
|
|
112
|
-
req.cookies.secret === g_config.secret
|
|
113
|
-
) {
|
|
114
|
-
next();
|
|
115
|
-
} else if (g_config.auth_middleware) {
|
|
116
|
-
g_config.auth_middleware(req, res, next);
|
|
117
|
-
} else {
|
|
118
|
-
res.sendStatus(403);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
function _serverData(req, res) {
|
|
122
|
-
res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
123
|
-
|
|
124
|
-
getGitCommitHash((err, git_commit_hash) => {
|
|
125
|
-
const body = {
|
|
126
|
-
git_commit_hash,
|
|
127
|
-
uptime: process.uptime(),
|
|
128
|
-
};
|
|
129
|
-
if (err) {
|
|
130
|
-
res.status(500);
|
|
131
|
-
body.err = err;
|
|
132
|
-
}
|
|
133
|
-
res.send(body);
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function _groupData(req, res) {
|
|
138
|
-
res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
139
|
-
|
|
140
|
-
_getGroupData((err, result) => {
|
|
141
|
-
const body = {
|
|
142
|
-
LATEST: result.latest || 'unknown',
|
|
143
|
-
InstanceId: result.InstanceId || 'unknown',
|
|
144
|
-
instance_list: result.instance_list,
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
if (result.auto_scale_group) {
|
|
148
|
-
body.auto_scale_group = {
|
|
149
|
-
AutoScalingGroupName: result.auto_scale_group.AutoScalingGroupName,
|
|
150
|
-
LaunchTemplate: result.auto_scale_group.LaunchTemplate,
|
|
151
|
-
};
|
|
152
|
-
if (result.launch_template) {
|
|
153
|
-
body.launch_template = result.launch_template;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (err) {
|
|
158
|
-
res.status(500).send({ err, body });
|
|
159
|
-
} else {
|
|
160
|
-
res.send(body);
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function _getGroupData(done) {
|
|
166
|
-
const autoscaling = _getAutoscaling();
|
|
167
|
-
const ec2 = _getEC2();
|
|
168
|
-
let latest = false;
|
|
169
|
-
let InstanceId = false;
|
|
170
|
-
let asg = false;
|
|
171
|
-
let instance_list = false;
|
|
172
|
-
let launch_template = false;
|
|
173
|
-
|
|
174
|
-
async.series(
|
|
175
|
-
[
|
|
176
|
-
(done) => {
|
|
177
|
-
_getLatest((err, result) => {
|
|
178
|
-
if (err) {
|
|
179
|
-
_errorLog('_getGroupData: latest err:', err);
|
|
180
|
-
}
|
|
181
|
-
latest = result;
|
|
182
|
-
done();
|
|
183
|
-
});
|
|
184
|
-
},
|
|
185
|
-
(done) => {
|
|
186
|
-
const meta = _getMetadataService();
|
|
187
|
-
meta.request('/latest/meta-data/instance-id', (err, results) => {
|
|
188
|
-
if (err) {
|
|
189
|
-
_errorLog('_getGroupData: Failed to get instance id:', err);
|
|
190
|
-
}
|
|
191
|
-
InstanceId = results || '';
|
|
192
|
-
done();
|
|
193
|
-
});
|
|
194
|
-
},
|
|
195
|
-
(done) => {
|
|
196
|
-
autoscaling.describeAutoScalingGroups({}, (err, data) => {
|
|
197
|
-
if (err) {
|
|
198
|
-
_errorLog('_getGroupData: find asg err:', err);
|
|
199
|
-
} else {
|
|
200
|
-
asg = data.AutoScalingGroups.find((group) => {
|
|
201
|
-
return (
|
|
202
|
-
group.AutoScalingGroupName === g_config.asg_name ||
|
|
203
|
-
group.Instances.find((i) => i.InstanceId === InstanceId)
|
|
204
|
-
);
|
|
205
|
-
});
|
|
206
|
-
if (!asg) {
|
|
207
|
-
err = 'asg_not_found';
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
done(err);
|
|
211
|
-
});
|
|
212
|
-
},
|
|
213
|
-
(done) => {
|
|
214
|
-
const opts = {
|
|
215
|
-
InstanceIds: asg.Instances.map((i) => i.InstanceId),
|
|
216
|
-
};
|
|
217
|
-
ec2.describeInstances(opts, (err, results) => {
|
|
218
|
-
if (err) {
|
|
219
|
-
_errorLog('_getGroupData: describeInstances err:', err);
|
|
220
|
-
} else {
|
|
221
|
-
instance_list = [];
|
|
222
|
-
results.Reservations.forEach((reservation) => {
|
|
223
|
-
reservation.Instances.forEach((i) => {
|
|
224
|
-
instance_list.push({
|
|
225
|
-
InstanceId: i.InstanceId,
|
|
226
|
-
PrivateIpAddress: i.PrivateIpAddress,
|
|
227
|
-
PublicIpAddress: i.PublicIpAddress,
|
|
228
|
-
LaunchTime: i.LaunchTime,
|
|
229
|
-
ImageId: i.ImageId,
|
|
230
|
-
InstanceType: i.InstanceType,
|
|
231
|
-
State: i.State,
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
done(err);
|
|
237
|
-
});
|
|
238
|
-
},
|
|
239
|
-
(done) => {
|
|
240
|
-
const list = instance_list.filter((i) => i.State.Name === 'running');
|
|
241
|
-
async.each(
|
|
242
|
-
list,
|
|
243
|
-
(instance, done) => {
|
|
244
|
-
_getServerData(instance, (err, body) => {
|
|
245
|
-
instance.git_commit_hash = body && body.git_commit_hash;
|
|
246
|
-
instance.uptime = body && body.uptime;
|
|
247
|
-
done(err);
|
|
248
|
-
});
|
|
249
|
-
},
|
|
250
|
-
done
|
|
251
|
-
);
|
|
252
|
-
},
|
|
253
|
-
(done) => {
|
|
254
|
-
const lt =
|
|
255
|
-
asg.LaunchTemplate ||
|
|
256
|
-
asg.MixedInstancesPolicy?.LaunchTemplate?.LaunchTemplateSpecification;
|
|
257
|
-
const opts = {
|
|
258
|
-
LaunchTemplateId: lt?.LaunchTemplateId,
|
|
259
|
-
Versions: [lt?.Version],
|
|
260
|
-
};
|
|
261
|
-
ec2.describeLaunchTemplateVersions(opts, (err, data) => {
|
|
262
|
-
if (err) {
|
|
263
|
-
_errorLog('_getGroupData: launch template fetch error:', err);
|
|
264
|
-
} else if (data?.LaunchTemplateVersions?.length > 0) {
|
|
265
|
-
launch_template = data.LaunchTemplateVersions[0];
|
|
266
|
-
const ud = launch_template.LaunchTemplateData.UserData;
|
|
267
|
-
if (ud) {
|
|
268
|
-
const s = Buffer.from(ud, 'base64').toString('utf8');
|
|
269
|
-
launch_template.LaunchTemplateData.UserData = s;
|
|
270
|
-
}
|
|
271
|
-
} else {
|
|
272
|
-
err = 'launch_template_not_found';
|
|
273
|
-
}
|
|
274
|
-
done(err);
|
|
275
|
-
});
|
|
276
|
-
},
|
|
277
|
-
],
|
|
278
|
-
(err) => {
|
|
279
|
-
const ret = {
|
|
280
|
-
latest,
|
|
281
|
-
InstanceId,
|
|
282
|
-
auto_scale_group: asg,
|
|
283
|
-
launch_template,
|
|
284
|
-
instance_list,
|
|
285
|
-
};
|
|
286
|
-
done(err, ret);
|
|
287
|
-
}
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
function _getServerData(instance, done) {
|
|
292
|
-
const proto = g_config.http_proto;
|
|
293
|
-
const ip = instance.PrivateIpAddress;
|
|
294
|
-
const port = g_config.service_port;
|
|
295
|
-
const prefix = g_config.route_prefix;
|
|
296
|
-
const url = `${proto}://${ip}:${port}${prefix}/server_data`;
|
|
297
|
-
const opts = {
|
|
298
|
-
strictSSL: false,
|
|
299
|
-
url,
|
|
300
|
-
method: 'GET',
|
|
301
|
-
headers: {
|
|
302
|
-
'x-sc-secret': g_config.secret,
|
|
303
|
-
},
|
|
304
|
-
json: {
|
|
305
|
-
secret: g_config.secret,
|
|
306
|
-
},
|
|
307
|
-
};
|
|
308
|
-
webRequest(opts, (err, body) => {
|
|
309
|
-
if (err) {
|
|
310
|
-
_errorLog('_getServerData: request err:', err);
|
|
311
|
-
}
|
|
312
|
-
done(err, body);
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
function _updateServer(req, res) {
|
|
316
|
-
res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
317
|
-
const hash = req.body.hash || req.query.hash;
|
|
318
|
-
if (hash) {
|
|
319
|
-
_updateSelf(hash, (err) => {
|
|
320
|
-
if (err) {
|
|
321
|
-
res.status(500).send(err);
|
|
322
|
-
} else {
|
|
323
|
-
res.send('Restarting server');
|
|
324
|
-
g_config.restart_function();
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
} else {
|
|
328
|
-
res.status(400).send('hash is required');
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
function _updateSelf(hash, done) {
|
|
332
|
-
const dir = g_config.repo_dir;
|
|
333
|
-
const url = `${g_config.remote_repo_prefix}/${hash}.tar.gz`;
|
|
334
|
-
const cmd = `cd ${dir} && ${__dirname}/../scripts/update_to_hash.sh ${url}`;
|
|
335
|
-
child_process.exec(cmd, (err, stdout, stderr) => {
|
|
336
|
-
if (err) {
|
|
337
|
-
_errorLog(
|
|
338
|
-
'_updateSelf: update_to_hash.sh failed with err:',
|
|
339
|
-
err,
|
|
340
|
-
'stdout:',
|
|
341
|
-
stdout,
|
|
342
|
-
'stderr:',
|
|
343
|
-
stderr
|
|
344
|
-
);
|
|
345
|
-
err = 'update_failed';
|
|
346
|
-
} else {
|
|
347
|
-
g_updateHash = hash;
|
|
348
|
-
}
|
|
349
|
-
done(err);
|
|
350
|
-
});
|
|
351
|
-
}
|
|
352
|
-
function _removeOldTarget() {
|
|
353
|
-
const dir = g_config.repo_dir;
|
|
354
|
-
const cmd = `${__dirname}/../scripts/remove_old_target.sh ${dir}`;
|
|
355
|
-
child_process.exec(cmd, (err, stdout, stderr) => {
|
|
356
|
-
if (err) {
|
|
357
|
-
_errorLog(
|
|
358
|
-
'_removeOldTarget: remove_old_target.sh failed with err:',
|
|
359
|
-
err,
|
|
360
|
-
'stdout:',
|
|
361
|
-
stdout,
|
|
362
|
-
'stderr:',
|
|
363
|
-
stderr
|
|
364
|
-
);
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
function _updateGroup(req, res) {
|
|
370
|
-
res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
371
|
-
|
|
372
|
-
const hash = req.body.hash || req.query.hash;
|
|
373
|
-
if (hash) {
|
|
374
|
-
const url = `${g_config.remote_repo_prefix}/${hash}.tar.gz`;
|
|
375
|
-
const key_name = g_config.sc_update_url_key_name;
|
|
376
|
-
const ami_id = req.body.ami_id || req.query.ami_id || false;
|
|
377
|
-
|
|
378
|
-
const ec2 = _getEC2();
|
|
379
|
-
let group_data = false;
|
|
380
|
-
let old_data = '';
|
|
381
|
-
let new_version;
|
|
382
|
-
const server_result = {};
|
|
383
|
-
async.series(
|
|
384
|
-
[
|
|
385
|
-
(done) => {
|
|
386
|
-
_getGroupData((err, result) => {
|
|
387
|
-
if (!err) {
|
|
388
|
-
group_data = result;
|
|
389
|
-
const data = result.launch_template.LaunchTemplateData.UserData;
|
|
390
|
-
data.split('\n').forEach((line) => {
|
|
391
|
-
if (line.length && line.indexOf(key_name) === -1) {
|
|
392
|
-
old_data += line + '\n';
|
|
393
|
-
}
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
done(err);
|
|
397
|
-
});
|
|
398
|
-
},
|
|
399
|
-
(done) => {
|
|
400
|
-
headUrl(url, (err) => {
|
|
401
|
-
if (err) {
|
|
402
|
-
_errorLog('_updateGroup: head url:', url, 'err:', err);
|
|
403
|
-
err = 'url_not_found';
|
|
404
|
-
}
|
|
405
|
-
done(err);
|
|
406
|
-
});
|
|
407
|
-
},
|
|
408
|
-
(done) => {
|
|
409
|
-
const new_data = `${old_data}${key_name}=${url}\n`;
|
|
410
|
-
const opts = {
|
|
411
|
-
LaunchTemplateId: group_data.launch_template.LaunchTemplateId,
|
|
412
|
-
SourceVersion: String(group_data.launch_template.VersionNumber),
|
|
413
|
-
LaunchTemplateData: {
|
|
414
|
-
UserData: Buffer.from(new_data, 'utf8').toString('base64'),
|
|
415
|
-
},
|
|
416
|
-
};
|
|
417
|
-
if (ami_id) {
|
|
418
|
-
opts.LaunchTemplateData.ImageId = ami_id;
|
|
419
|
-
}
|
|
420
|
-
ec2.createLaunchTemplateVersion(opts, (err, data) => {
|
|
421
|
-
if (err) {
|
|
422
|
-
_errorLog('_updateGroup: failed to create version, err:', err);
|
|
423
|
-
} else {
|
|
424
|
-
new_version = data.LaunchTemplateVersion.VersionNumber;
|
|
425
|
-
}
|
|
426
|
-
done(err);
|
|
427
|
-
});
|
|
428
|
-
},
|
|
429
|
-
(done) => {
|
|
430
|
-
if (g_config.update_launch_default) {
|
|
431
|
-
const opts = {
|
|
432
|
-
DefaultVersion: String(new_version),
|
|
433
|
-
LaunchTemplateId: group_data.launch_template.LaunchTemplateId,
|
|
434
|
-
};
|
|
435
|
-
ec2.modifyLaunchTemplate(opts, function (err) {
|
|
436
|
-
if (err) {
|
|
437
|
-
_errorLog('_updateGroup: failed to update default, err:', err);
|
|
438
|
-
}
|
|
439
|
-
done(err);
|
|
440
|
-
});
|
|
441
|
-
} else {
|
|
442
|
-
done();
|
|
443
|
-
}
|
|
444
|
-
},
|
|
445
|
-
(done) => {
|
|
446
|
-
let group_err;
|
|
447
|
-
async.each(
|
|
448
|
-
group_data.instance_list,
|
|
449
|
-
(instance, done) => {
|
|
450
|
-
if (instance.InstanceId === group_data.InstanceId) {
|
|
451
|
-
done();
|
|
452
|
-
} else {
|
|
453
|
-
_updateInstance(hash, instance, (err) => {
|
|
454
|
-
if (err) {
|
|
455
|
-
_errorLog(
|
|
456
|
-
'_updateGroup: update instance:',
|
|
457
|
-
instance.InstanceId,
|
|
458
|
-
'err:',
|
|
459
|
-
err
|
|
460
|
-
);
|
|
461
|
-
group_err = err;
|
|
462
|
-
}
|
|
463
|
-
server_result[instance.InstanceId] = err;
|
|
464
|
-
done();
|
|
465
|
-
});
|
|
466
|
-
}
|
|
467
|
-
},
|
|
468
|
-
() => done(group_err)
|
|
469
|
-
);
|
|
470
|
-
},
|
|
471
|
-
(done) => {
|
|
472
|
-
_updateSelf(hash, (err) => {
|
|
473
|
-
server_result[group_data.InstanceId] = err;
|
|
474
|
-
done(err);
|
|
475
|
-
});
|
|
476
|
-
},
|
|
477
|
-
],
|
|
478
|
-
(err) => {
|
|
479
|
-
const body = {
|
|
480
|
-
err,
|
|
481
|
-
server_result,
|
|
482
|
-
launch_template_version: new_version,
|
|
483
|
-
};
|
|
484
|
-
if (err) {
|
|
485
|
-
res.status(500).send(body);
|
|
486
|
-
} else {
|
|
487
|
-
body._msg =
|
|
488
|
-
'Successful updating all servers, restarting this server.';
|
|
489
|
-
res.send(body);
|
|
490
|
-
g_config.restart_function();
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
);
|
|
494
|
-
} else {
|
|
495
|
-
res.status(400).send('hash is required');
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
function _updateInstance(hash, instance, done) {
|
|
499
|
-
async.series(
|
|
500
|
-
[
|
|
501
|
-
(done) => {
|
|
502
|
-
const proto = g_config.http_proto;
|
|
503
|
-
const ip = instance.PrivateIpAddress;
|
|
504
|
-
const port = g_config.service_port;
|
|
505
|
-
const prefix = g_config.route_prefix;
|
|
506
|
-
const url = `${proto}://${ip}:${port}${prefix}/update_server`;
|
|
507
|
-
const opts = {
|
|
508
|
-
strictSSL: false,
|
|
509
|
-
url,
|
|
510
|
-
method: 'GET',
|
|
511
|
-
headers: {
|
|
512
|
-
'x-sc-secret': g_config.secret,
|
|
513
|
-
},
|
|
514
|
-
json: {
|
|
515
|
-
hash,
|
|
516
|
-
secret: g_config.secret,
|
|
517
|
-
},
|
|
518
|
-
};
|
|
519
|
-
webRequest(opts, done);
|
|
520
|
-
},
|
|
521
|
-
(done) => _waitForServer({ instance, hash }, done),
|
|
522
|
-
],
|
|
523
|
-
done
|
|
524
|
-
);
|
|
525
|
-
}
|
|
526
|
-
function _waitForServer(params, done) {
|
|
527
|
-
const { instance, hash } = params;
|
|
528
|
-
let count = 0;
|
|
529
|
-
|
|
530
|
-
async.forever(
|
|
531
|
-
(done) => {
|
|
532
|
-
count++;
|
|
533
|
-
_getServerData(instance, (err, body) => {
|
|
534
|
-
if (!err && body && body.git_commit_hash === hash) {
|
|
535
|
-
done('stop');
|
|
536
|
-
} else if (count > MAX_WAIT_COUNT) {
|
|
537
|
-
done('too_many_tries');
|
|
538
|
-
} else {
|
|
539
|
-
setTimeout(done, SERVER_WAIT_MS);
|
|
540
|
-
}
|
|
541
|
-
});
|
|
542
|
-
},
|
|
543
|
-
(err) => {
|
|
544
|
-
if (err === 'stop') {
|
|
545
|
-
err = null;
|
|
546
|
-
}
|
|
547
|
-
done(err);
|
|
548
|
-
}
|
|
549
|
-
);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
function _getLatest(done) {
|
|
553
|
-
const url = g_config.remote_repo_prefix + '/LATEST';
|
|
554
|
-
fetchFileContents(url, (err, body) => {
|
|
555
|
-
done(err, body && body.trim());
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
function getGitCommitHash(done) {
|
|
559
|
-
if (g_gitCommitHash) {
|
|
560
|
-
done && done(null, g_gitCommitHash);
|
|
561
|
-
} else {
|
|
562
|
-
const file = pathJoin(g_config.repo_dir, '.git_commit_hash');
|
|
563
|
-
fs.readFile(file, 'utf8', (err, result) => {
|
|
564
|
-
if (!err && !result) {
|
|
565
|
-
err = 'no_result';
|
|
566
|
-
}
|
|
567
|
-
if (err) {
|
|
568
|
-
_errorLog('getGitCommitHash: err:', err, 'file:', file);
|
|
569
|
-
} else {
|
|
570
|
-
g_gitCommitHash = result.trim();
|
|
571
|
-
}
|
|
572
|
-
done && done(err, g_gitCommitHash);
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
function _getAwsRegion() {
|
|
577
|
-
if (!g_config.region) {
|
|
578
|
-
const meta = _getMetadataService();
|
|
579
|
-
meta.request(
|
|
580
|
-
'/latest/dynamic/instance-identity/document',
|
|
581
|
-
(err, results) => {
|
|
582
|
-
if (err) {
|
|
583
|
-
_errorLog('_getAwsRegion: metadata err:', err);
|
|
584
|
-
} else {
|
|
585
|
-
try {
|
|
586
|
-
const json = JSON.parse(results);
|
|
587
|
-
if (json && json.region) {
|
|
588
|
-
g_config.region = json.region;
|
|
589
|
-
}
|
|
590
|
-
} catch (e) {
|
|
591
|
-
_errorLog('_getAwsRegion: threw:', e);
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
);
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
function _getMetadataService() {
|
|
599
|
-
const opts = g_config.metadata_opts || {};
|
|
600
|
-
return new AWS.MetadataService(opts);
|
|
601
|
-
}
|
|
602
|
-
function _getAutoscaling() {
|
|
603
|
-
return new AWS.AutoScaling({ region: g_config.region });
|
|
604
|
-
}
|
|
605
|
-
function _getEC2() {
|
|
606
|
-
return new AWS.EC2({ region: g_config.region });
|
|
607
|
-
}
|
|
608
|
-
function _errorLog(...args) {
|
|
609
|
-
g_config.error_log(...args);
|
|
610
|
-
}
|
|
611
|
-
function _defaultRestartFunction() {
|
|
612
|
-
g_config.console_log(
|
|
613
|
-
'server-control: updated to: ',
|
|
614
|
-
g_updateHash,
|
|
615
|
-
'restarting...'
|
|
616
|
-
);
|
|
617
|
-
setTimeout(function () {
|
|
618
|
-
process.exit(0);
|
|
619
|
-
}, 100);
|
|
620
|
-
}
|
package/src/request.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
const AWS = require('aws-sdk');
|
|
2
|
-
const request = require('request');
|
|
3
|
-
|
|
4
|
-
exports.webRequest = webRequest;
|
|
5
|
-
exports.headUrl = headUrl;
|
|
6
|
-
exports.fetchFileContents = fetchFileContents;
|
|
7
|
-
|
|
8
|
-
function webRequest(opts, done) {
|
|
9
|
-
request(opts, (err, response, body) => {
|
|
10
|
-
const statusCode = response && response.statusCode;
|
|
11
|
-
if (!err && (statusCode < 200 || statusCode > 299)) {
|
|
12
|
-
err = statusCode;
|
|
13
|
-
}
|
|
14
|
-
done(err, body);
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
function headUrl(url, done) {
|
|
18
|
-
if (url.indexOf('http') === 0) {
|
|
19
|
-
webRequest({ url, method: 'HEAD' }, done);
|
|
20
|
-
} else {
|
|
21
|
-
const parts = url.match(/s3:\/\/([^/]*)\/(.*)/);
|
|
22
|
-
const Bucket = parts && parts[1];
|
|
23
|
-
const Key = parts && parts[2];
|
|
24
|
-
const s3 = new AWS.S3();
|
|
25
|
-
s3.headObject({ Bucket, Key }, done);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
function fetchFileContents(url, done) {
|
|
29
|
-
if (url.indexOf('http') === 0) {
|
|
30
|
-
webRequest({ url }, done);
|
|
31
|
-
} else {
|
|
32
|
-
const parts = url.match(/s3:\/\/([^/]*)\/(.*)/);
|
|
33
|
-
const Bucket = parts && parts[1];
|
|
34
|
-
const Key = parts && parts[2];
|
|
35
|
-
const s3 = new AWS.S3();
|
|
36
|
-
s3.getObject({ Bucket, Key }, (err, data) => {
|
|
37
|
-
done(err, data && data.Body && data.Body.toString('utf8'));
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
}
|