server-control-s3 0.0.15 → 1.0.1
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 +17 -15
- package/dist/server_control.js +63 -98
- package/package.json +4 -2
package/dist/server_control.d.ts
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
|
|
1
3
|
declare const _default: {
|
|
2
4
|
init: typeof init;
|
|
3
5
|
getGitCommitHash: typeof getGitCommitHash;
|
|
4
6
|
};
|
|
5
7
|
|
|
6
8
|
interface Config {
|
|
7
|
-
route_prefix: string;
|
|
8
9
|
secret: string;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
routePrefix: string;
|
|
11
|
+
updateUrlKeyName: string;
|
|
12
|
+
restartFunction: () => void;
|
|
13
|
+
port: number;
|
|
14
|
+
httpProto: string;
|
|
15
|
+
authMiddleware?: (req: Request, res: Response, next: NextFunction) => void;
|
|
16
|
+
repoDir: string;
|
|
17
|
+
consoleLog: (...args: any[]) => void;
|
|
18
|
+
errorLog: (...args: any[]) => void;
|
|
19
|
+
updateLaunchDefault: boolean;
|
|
20
|
+
removeOldTarget: boolean;
|
|
21
|
+
remoteRepoPrefix?: string;
|
|
22
|
+
metadataOpts?: any;
|
|
23
|
+
asgName?: string;
|
|
22
24
|
region?: string;
|
|
23
25
|
}
|
|
24
|
-
declare function init(
|
|
26
|
+
declare function init(router: any, config: Partial<Config>): void;
|
|
25
27
|
declare function getGitCommitHash(done: (err: any, result?: string) => void): void;
|
|
26
28
|
|
|
27
29
|
export { _default as default, getGitCommitHash, init };
|
package/dist/server_control.js
CHANGED
|
@@ -81,17 +81,20 @@ function webRequest(opts, done) {
|
|
|
81
81
|
// ignore
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
done(err, response_body);
|
|
84
|
+
done?.(err, response_body);
|
|
85
|
+
done = undefined;
|
|
85
86
|
});
|
|
86
87
|
});
|
|
87
88
|
client_req.on('error', (err) => {
|
|
88
|
-
done(err);
|
|
89
|
+
done?.(err);
|
|
90
|
+
done = undefined;
|
|
89
91
|
});
|
|
90
92
|
client_req.on('timeout', () => {
|
|
91
93
|
client_req.destroy();
|
|
92
94
|
const err = new Error('Request timed out');
|
|
93
95
|
err.code = 'ETIMEDOUT';
|
|
94
|
-
done(err);
|
|
96
|
+
done?.(err);
|
|
97
|
+
done = undefined;
|
|
95
98
|
});
|
|
96
99
|
if (request_body) {
|
|
97
100
|
client_req.write(request_body);
|
|
@@ -158,77 +161,49 @@ var index = {
|
|
|
158
161
|
const MAX_WAIT_COUNT = 12;
|
|
159
162
|
const SERVER_WAIT_MS = 10 * 1000;
|
|
160
163
|
const DEFAULT_CONFIG = {
|
|
161
|
-
route_prefix: '',
|
|
162
164
|
secret: 'secret',
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
165
|
+
routePrefix: '',
|
|
166
|
+
updateUrlKeyName: 'SC_UPDATE_URL',
|
|
167
|
+
restartFunction: _defaultRestartFunction,
|
|
168
|
+
port: 80,
|
|
169
|
+
httpProto: 'http',
|
|
170
|
+
repoDir: process.env.PWD || '.',
|
|
171
|
+
consoleLog: console.log,
|
|
172
|
+
errorLog: console.error,
|
|
173
|
+
updateLaunchDefault: true,
|
|
174
|
+
removeOldTarget: true,
|
|
173
175
|
};
|
|
174
176
|
const g_config = {};
|
|
175
177
|
let g_gitCommitHash = false;
|
|
176
178
|
let g_updateHash = '';
|
|
177
|
-
function init(
|
|
179
|
+
function init(router, config) {
|
|
178
180
|
Object.assign(g_config, DEFAULT_CONFIG, config);
|
|
179
|
-
if (
|
|
180
|
-
throw 'server-control route_prefix required';
|
|
181
|
-
}
|
|
182
|
-
if (!g_config.remote_repo_prefix) {
|
|
181
|
+
if (!g_config.remoteRepoPrefix) {
|
|
183
182
|
throw 'server-control remote_repo_prefix required';
|
|
184
183
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
(
|
|
189
|
-
_getAwsRegion(done);
|
|
190
|
-
},
|
|
191
|
-
(done) => {
|
|
192
|
-
getGitCommitHash(() => { });
|
|
193
|
-
const { route_prefix } = g_config;
|
|
194
|
-
if (g_config.remove_old_target) {
|
|
195
|
-
_removeOldTarget();
|
|
196
|
-
}
|
|
197
|
-
app.all(route_prefix + '/server_data', _parseQuery, _secretOrAuth, _serverData);
|
|
198
|
-
app.all(route_prefix + '/group_data', _parseQuery, _secretOrAuth, _groupData);
|
|
199
|
-
app.all(route_prefix + '/update_group', _parseQuery, _secretOrAuth, _updateGroup);
|
|
200
|
-
app.all(route_prefix + '/update_server', _parseQuery, _secretOrAuth, _updateServer);
|
|
201
|
-
done();
|
|
202
|
-
},
|
|
203
|
-
]);
|
|
204
|
-
}
|
|
205
|
-
function _parseQuery(req, res, next) {
|
|
206
|
-
if (typeof req.query === 'string') {
|
|
207
|
-
const query = {};
|
|
208
|
-
req.query.split('&').forEach((key_val) => {
|
|
209
|
-
const split = key_val.split('=');
|
|
210
|
-
query[split[0]] = split[1] || '';
|
|
211
|
-
});
|
|
212
|
-
req.query = query;
|
|
184
|
+
_getAwsRegion(() => { });
|
|
185
|
+
getGitCommitHash(() => { });
|
|
186
|
+
if (g_config.removeOldTarget) {
|
|
187
|
+
_removeOldTarget();
|
|
213
188
|
}
|
|
214
|
-
|
|
189
|
+
router.use(_secretOrAuth);
|
|
190
|
+
router.all('/server_data', _serverData);
|
|
191
|
+
router.all('/group_data', _groupData);
|
|
192
|
+
router.all('/update_group', _updateGroup);
|
|
193
|
+
router.all('/update_server', _updateServer);
|
|
215
194
|
}
|
|
216
195
|
function _secretOrAuth(req, res, next) {
|
|
217
196
|
if (req.headers && req.headers['x-sc-secret'] === g_config.secret) {
|
|
218
197
|
next();
|
|
219
198
|
}
|
|
220
|
-
else if (req.body
|
|
221
|
-
req.body.secret &&
|
|
222
|
-
req.body.secret === g_config.secret) {
|
|
199
|
+
else if (req.body?.secret === g_config.secret) {
|
|
223
200
|
next();
|
|
224
201
|
}
|
|
225
|
-
else if (req.cookies
|
|
226
|
-
req.cookies.secret &&
|
|
227
|
-
req.cookies.secret === g_config.secret) {
|
|
202
|
+
else if (req.cookies?.secret === g_config.secret) {
|
|
228
203
|
next();
|
|
229
204
|
}
|
|
230
|
-
else if (
|
|
231
|
-
g_config.
|
|
205
|
+
else if (g_config.authMiddleware) {
|
|
206
|
+
g_config.authMiddleware(req, res, next);
|
|
232
207
|
}
|
|
233
208
|
else {
|
|
234
209
|
res.sendStatus(403);
|
|
@@ -254,15 +229,15 @@ function _groupData(req, res) {
|
|
|
254
229
|
const body = {
|
|
255
230
|
LATEST: result.latest || 'unknown',
|
|
256
231
|
InstanceId: result.InstanceId || 'unknown',
|
|
257
|
-
|
|
232
|
+
InstanceList: result.instance_list,
|
|
258
233
|
};
|
|
259
234
|
if (result.auto_scale_group) {
|
|
260
|
-
body.
|
|
235
|
+
body.AutoScaleGroup = {
|
|
261
236
|
AutoScalingGroupName: result.auto_scale_group.AutoScalingGroupName,
|
|
262
237
|
LaunchTemplate: result.auto_scale_group.LaunchTemplate,
|
|
263
238
|
};
|
|
264
239
|
if (result.launch_template) {
|
|
265
|
-
body.
|
|
240
|
+
body.LaunchTemplate = result.launch_template;
|
|
266
241
|
}
|
|
267
242
|
}
|
|
268
243
|
if (err) {
|
|
@@ -294,7 +269,7 @@ function _getGroupData(done) {
|
|
|
294
269
|
(done) => {
|
|
295
270
|
const opts = {
|
|
296
271
|
url: 'http://169.254.169.254/latest/meta-data/instance-id',
|
|
297
|
-
...(g_config.
|
|
272
|
+
...(g_config.metadataOpts || {}),
|
|
298
273
|
};
|
|
299
274
|
webRequest(opts, (err, results) => {
|
|
300
275
|
if (err) {
|
|
@@ -308,11 +283,11 @@ function _getGroupData(done) {
|
|
|
308
283
|
const command = new clientAutoScaling.DescribeAutoScalingGroupsCommand({});
|
|
309
284
|
autoscaling.send(command).then((data) => {
|
|
310
285
|
asg = data.AutoScalingGroups.find((group) => {
|
|
311
|
-
return (group.AutoScalingGroupName === g_config.
|
|
286
|
+
return (group.AutoScalingGroupName === g_config.asgName ||
|
|
312
287
|
group.Instances.find((i) => i.InstanceId === InstanceId));
|
|
313
288
|
});
|
|
314
289
|
if (!asg) {
|
|
315
|
-
_errorLog('_getGroupData: asg not found:', g_config.
|
|
290
|
+
_errorLog('_getGroupData: asg not found:', g_config.asgName);
|
|
316
291
|
done('asg_not_found');
|
|
317
292
|
}
|
|
318
293
|
else {
|
|
@@ -397,20 +372,16 @@ function _getGroupData(done) {
|
|
|
397
372
|
});
|
|
398
373
|
}
|
|
399
374
|
function _getServerData(instance, done) {
|
|
400
|
-
const proto = g_config.
|
|
375
|
+
const proto = g_config.httpProto;
|
|
401
376
|
const ip = instance.PrivateIpAddress;
|
|
402
|
-
const port = g_config.
|
|
403
|
-
const prefix = g_config.
|
|
377
|
+
const port = g_config.port;
|
|
378
|
+
const prefix = g_config.routePrefix;
|
|
404
379
|
const url = `${proto}://${ip}:${port}${prefix}/server_data`;
|
|
405
380
|
const opts = {
|
|
406
381
|
url,
|
|
407
382
|
method: 'GET',
|
|
408
|
-
headers: {
|
|
409
|
-
|
|
410
|
-
},
|
|
411
|
-
json: {
|
|
412
|
-
secret: g_config.secret,
|
|
413
|
-
},
|
|
383
|
+
headers: { 'x-sc-secret': g_config.secret },
|
|
384
|
+
json: { secret: g_config.secret },
|
|
414
385
|
};
|
|
415
386
|
webRequest(opts, (err, body) => {
|
|
416
387
|
if (err) {
|
|
@@ -421,7 +392,7 @@ function _getServerData(instance, done) {
|
|
|
421
392
|
}
|
|
422
393
|
function _updateServer(req, res) {
|
|
423
394
|
res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
424
|
-
const hash = req.body
|
|
395
|
+
const hash = req.body?.hash ?? req.query.hash;
|
|
425
396
|
if (hash) {
|
|
426
397
|
_updateSelf(hash, (err) => {
|
|
427
398
|
if (err) {
|
|
@@ -429,7 +400,7 @@ function _updateServer(req, res) {
|
|
|
429
400
|
}
|
|
430
401
|
else {
|
|
431
402
|
res.send('Restarting server');
|
|
432
|
-
g_config.
|
|
403
|
+
g_config.restartFunction();
|
|
433
404
|
}
|
|
434
405
|
});
|
|
435
406
|
}
|
|
@@ -438,8 +409,8 @@ function _updateServer(req, res) {
|
|
|
438
409
|
}
|
|
439
410
|
}
|
|
440
411
|
function _updateSelf(hash, done) {
|
|
441
|
-
const dir = g_config.
|
|
442
|
-
const url = `${g_config.
|
|
412
|
+
const dir = g_config.repoDir;
|
|
413
|
+
const url = `${g_config.remoteRepoPrefix}/${hash}.tar.gz`;
|
|
443
414
|
const cmd = `cd ${dir} && ${__dirname}/../scripts/update_to_hash.sh ${url}`;
|
|
444
415
|
child_process__namespace.exec(cmd, (err, stdout, stderr) => {
|
|
445
416
|
if (err) {
|
|
@@ -453,7 +424,7 @@ function _updateSelf(hash, done) {
|
|
|
453
424
|
});
|
|
454
425
|
}
|
|
455
426
|
function _removeOldTarget() {
|
|
456
|
-
const dir = g_config.
|
|
427
|
+
const dir = g_config.repoDir;
|
|
457
428
|
const cmd = `${__dirname}/../scripts/remove_old_target.sh ${dir}`;
|
|
458
429
|
child_process__namespace.exec(cmd, (err, stdout, stderr) => {
|
|
459
430
|
if (err) {
|
|
@@ -463,11 +434,11 @@ function _removeOldTarget() {
|
|
|
463
434
|
}
|
|
464
435
|
function _updateGroup(req, res) {
|
|
465
436
|
res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
466
|
-
const hash = req.body
|
|
437
|
+
const hash = req.body?.hash ?? req.query.hash;
|
|
467
438
|
if (hash) {
|
|
468
|
-
const url = `${g_config.
|
|
469
|
-
const key_name = g_config.
|
|
470
|
-
const ami_id = req.body
|
|
439
|
+
const url = `${g_config.remoteRepoPrefix}/${hash}.tar.gz`;
|
|
440
|
+
const key_name = g_config.updateUrlKeyName;
|
|
441
|
+
const ami_id = req.body?.ami_id ?? req.query.ami_id ?? false;
|
|
471
442
|
const ec2 = _getEC2();
|
|
472
443
|
let group_data = false;
|
|
473
444
|
let old_data = '';
|
|
@@ -519,7 +490,7 @@ function _updateGroup(req, res) {
|
|
|
519
490
|
});
|
|
520
491
|
},
|
|
521
492
|
(done) => {
|
|
522
|
-
if (g_config.
|
|
493
|
+
if (g_config.updateLaunchDefault) {
|
|
523
494
|
const opts = {
|
|
524
495
|
DefaultVersion: String(new_version),
|
|
525
496
|
LaunchTemplateId: group_data.launch_template.LaunchTemplateId,
|
|
@@ -573,7 +544,7 @@ function _updateGroup(req, res) {
|
|
|
573
544
|
body._msg =
|
|
574
545
|
'Successful updating all servers, restarting this server.';
|
|
575
546
|
res.send(body);
|
|
576
|
-
g_config.
|
|
547
|
+
g_config.restartFunction();
|
|
577
548
|
}
|
|
578
549
|
});
|
|
579
550
|
}
|
|
@@ -584,21 +555,16 @@ function _updateGroup(req, res) {
|
|
|
584
555
|
function _updateInstance(hash, instance, done) {
|
|
585
556
|
asyncSeries([
|
|
586
557
|
(done) => {
|
|
587
|
-
const proto = g_config.
|
|
558
|
+
const proto = g_config.httpProto;
|
|
588
559
|
const ip = instance.PrivateIpAddress;
|
|
589
|
-
const port = g_config.
|
|
590
|
-
const prefix = g_config.
|
|
560
|
+
const port = g_config.port;
|
|
561
|
+
const prefix = g_config.routePrefix;
|
|
591
562
|
const url = `${proto}://${ip}:${port}${prefix}/update_server`;
|
|
592
563
|
const opts = {
|
|
593
564
|
url,
|
|
594
565
|
method: 'GET',
|
|
595
|
-
headers: {
|
|
596
|
-
|
|
597
|
-
},
|
|
598
|
-
json: {
|
|
599
|
-
hash,
|
|
600
|
-
secret: g_config.secret,
|
|
601
|
-
},
|
|
566
|
+
headers: { 'x-sc-secret': g_config.secret },
|
|
567
|
+
json: { hash, secret: g_config.secret },
|
|
602
568
|
};
|
|
603
569
|
webRequest(opts, done);
|
|
604
570
|
},
|
|
@@ -629,7 +595,7 @@ function _waitForServer(params, done) {
|
|
|
629
595
|
});
|
|
630
596
|
}
|
|
631
597
|
function _getLatest(done) {
|
|
632
|
-
const url = g_config.
|
|
598
|
+
const url = g_config.remoteRepoPrefix + '/LATEST';
|
|
633
599
|
fetchFileContents(url, { region: g_config.region }, (err, body) => {
|
|
634
600
|
done(err, body && body.trim());
|
|
635
601
|
});
|
|
@@ -639,7 +605,7 @@ function getGitCommitHash(done) {
|
|
|
639
605
|
done && done(null, g_gitCommitHash);
|
|
640
606
|
}
|
|
641
607
|
else {
|
|
642
|
-
const file = node_path.join(g_config.
|
|
608
|
+
const file = node_path.join(g_config.repoDir, '.git_commit_hash');
|
|
643
609
|
fs__namespace.readFile(file, 'utf8', (err, result) => {
|
|
644
610
|
if (!err && !result) {
|
|
645
611
|
err = 'no_result';
|
|
@@ -660,7 +626,7 @@ function _getAwsRegion(done) {
|
|
|
660
626
|
}
|
|
661
627
|
const opts = {
|
|
662
628
|
url: 'http://169.254.169.254/latest/dynamic/instance-identity/document',
|
|
663
|
-
...(g_config.
|
|
629
|
+
...(g_config.metadataOpts || {}),
|
|
664
630
|
};
|
|
665
631
|
webRequest(opts, (err, results) => {
|
|
666
632
|
if (err) {
|
|
@@ -677,7 +643,6 @@ function _getAwsRegion(done) {
|
|
|
677
643
|
_errorLog('_getAwsRegion: threw:', e);
|
|
678
644
|
}
|
|
679
645
|
}
|
|
680
|
-
done();
|
|
681
646
|
});
|
|
682
647
|
}
|
|
683
648
|
function _getAutoscaling() {
|
|
@@ -687,10 +652,10 @@ function _getEC2() {
|
|
|
687
652
|
return new clientEc2.EC2Client({ region: g_config.region });
|
|
688
653
|
}
|
|
689
654
|
function _errorLog(...args) {
|
|
690
|
-
g_config.
|
|
655
|
+
g_config.errorLog(...args);
|
|
691
656
|
}
|
|
692
657
|
function _defaultRestartFunction() {
|
|
693
|
-
g_config.
|
|
658
|
+
g_config.consoleLog('server-control: updated to: ', g_updateHash, 'restarting...');
|
|
694
659
|
setTimeout(function () {
|
|
695
660
|
process.exit(0);
|
|
696
661
|
}, 100);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "server-control-s3",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Jim Lake"
|
|
6
6
|
},
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"types": "dist/server_control.d.ts",
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "rm -rf dist && rollup -c",
|
|
27
|
-
"lint": "eslint src
|
|
27
|
+
"lint": "eslint src && eslint test",
|
|
28
|
+
"ts-check": "tsc --noEmit",
|
|
28
29
|
"pretty": "prettier --write \"src/*.ts\" \"example/*.js\" \"test/*.ts\"",
|
|
29
30
|
"test": "npm run build && npm run test-only",
|
|
30
31
|
"test-only": "NODE_OPTIONS='--import=tsx' mocha --require test/local_setup.ts \"test/*.test.ts\""
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
"@rollup/plugin-typescript": "^12.1.4",
|
|
42
43
|
"@types/async": "^3.2.24",
|
|
43
44
|
"@types/chai": "^5.2.2",
|
|
45
|
+
"@types/express": "^5.0.3",
|
|
44
46
|
"@types/mocha": "^10.0.10",
|
|
45
47
|
"@types/supertest": "^6.0.3",
|
|
46
48
|
"@typescript-eslint/eslint-plugin": "^8.36.0",
|