server-control-s3 0.0.13 → 0.0.14

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.
@@ -0,0 +1,827 @@
1
+ 'use strict';
2
+
3
+ var require$$0$1 = require('async/each');
4
+ var require$$1$1 = require('async/forever');
5
+ var require$$2$1 = require('async/series');
6
+ var require$$3$1 = require('@aws-sdk/client-auto-scaling');
7
+ var require$$4 = require('@aws-sdk/client-ec2');
8
+ var require$$5 = require('node:child_process');
9
+ var require$$6 = require('node:fs');
10
+ var require$$7 = require('node:path');
11
+ var require$$0 = require('@aws-sdk/client-s3');
12
+ var require$$1 = require('http');
13
+ var require$$2 = require('https');
14
+ var require$$3 = require('url');
15
+
16
+ function getDefaultExportFromCjs (x) {
17
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
18
+ }
19
+
20
+ var src = {};
21
+
22
+ var request = {};
23
+
24
+ var hasRequiredRequest;
25
+
26
+ function requireRequest () {
27
+ if (hasRequiredRequest) return request;
28
+ hasRequiredRequest = 1;
29
+ const {
30
+ S3Client,
31
+ GetObjectCommand,
32
+ HeadObjectCommand,
33
+ } = require$$0;
34
+ const http = require$$1;
35
+ const https = require$$2;
36
+ const url_lib = require$$3;
37
+
38
+ const TIMEOUT = 15 * 1000;
39
+
40
+ request.webRequest = webRequest;
41
+ request.headUrl = headUrl;
42
+ request.fetchFileContents = fetchFileContents;
43
+
44
+ function webRequest(opts, done) {
45
+ if (!opts.timeout) {
46
+ opts.timeout = TIMEOUT;
47
+ }
48
+
49
+ const url = new url_lib.URL(opts.url);
50
+ const transport = url.protocol === 'https:' ? https : http;
51
+
52
+ const request_options = {
53
+ method: opts.method || 'GET',
54
+ timeout: opts.timeout,
55
+ headers: opts.headers || {},
56
+ };
57
+
58
+ let request_body;
59
+ if (opts.json) {
60
+ if (request_options.method === 'GET') {
61
+ Object.keys(opts.json).forEach((key) => {
62
+ url.searchParams.append(key, opts.json[key]);
63
+ });
64
+ } else {
65
+ request_body = JSON.stringify(opts.json);
66
+ request_options.headers['Content-Type'] = 'application/json';
67
+ request_options.headers['Content-Length'] =
68
+ Buffer.byteLength(request_body);
69
+ }
70
+ }
71
+
72
+ const client_req = transport.request(url, request_options, (incoming_res) => {
73
+ let response_body = '';
74
+ incoming_res.on('data', (chunk) => {
75
+ response_body += chunk;
76
+ });
77
+
78
+ incoming_res.on('end', () => {
79
+ const status_code = incoming_res.statusCode;
80
+ let err = null;
81
+ if (status_code < 200 || status_code > 299) {
82
+ err = status_code;
83
+ }
84
+
85
+ const content_type = incoming_res.headers['content-type'] || '';
86
+ if (content_type.includes('application/json')) {
87
+ try {
88
+ response_body = JSON.parse(response_body);
89
+ } catch (e) {
90
+ // ignore
91
+ }
92
+ }
93
+
94
+ done(err, response_body);
95
+ });
96
+ });
97
+
98
+ client_req.on('error', (err) => {
99
+ done(err);
100
+ });
101
+
102
+ client_req.on('timeout', () => {
103
+ client_req.destroy();
104
+ const err = new Error('Request timed out');
105
+ err.code = 'ETIMEDOUT';
106
+ done(err);
107
+ });
108
+
109
+ if (request_body) {
110
+ client_req.write(request_body);
111
+ }
112
+
113
+ client_req.end();
114
+ }
115
+
116
+ function headUrl(url, opts, done) {
117
+ if (typeof opts === 'function') {
118
+ done = opts;
119
+ opts = {};
120
+ }
121
+ if (url.indexOf('http') === 0) {
122
+ webRequest({ url, method: 'HEAD' }, done);
123
+ } else {
124
+ const parts = url.match(/s3:\/\/([^/]*)\/(.*)/);
125
+ const Bucket = parts && parts[1];
126
+ const Key = parts && parts[2];
127
+ const s3 = new S3Client({ region: opts.region });
128
+ const command = new HeadObjectCommand({ Bucket, Key });
129
+ s3.send(command).then(
130
+ (data) => done(null, data),
131
+ (err) => done(err)
132
+ );
133
+ }
134
+ }
135
+ function fetchFileContents(url, opts, done) {
136
+ if (typeof opts === 'function') {
137
+ done = opts;
138
+ opts = {};
139
+ }
140
+ if (url.indexOf('http') === 0) {
141
+ webRequest({ url }, done);
142
+ } else {
143
+ const parts = url.match(/s3:\/\/([^/]*)\/(.*)/);
144
+ const Bucket = parts && parts[1];
145
+ const Key = parts && parts[2];
146
+ const s3 = new S3Client({ region: opts.region });
147
+ const command = new GetObjectCommand({ Bucket, Key });
148
+ s3.send(command).then(
149
+ (data) => {
150
+ const stream = data.Body;
151
+ let body = '';
152
+ stream.on('data', (chunk) => {
153
+ body += chunk.toString();
154
+ });
155
+ stream.on('end', () => {
156
+ done(null, body);
157
+ });
158
+ stream.on('error', (err) => {
159
+ done(err);
160
+ });
161
+ },
162
+ (err) => done(err)
163
+ );
164
+ }
165
+ }
166
+ return request;
167
+ }
168
+
169
+ var hasRequiredSrc;
170
+
171
+ function requireSrc () {
172
+ if (hasRequiredSrc) return src;
173
+ hasRequiredSrc = 1;
174
+ const asyncEach = require$$0$1;
175
+ const asyncForever = require$$1$1;
176
+ const asyncSeries = require$$2$1;
177
+
178
+ const {
179
+ AutoScalingClient,
180
+ DescribeAutoScalingGroupsCommand,
181
+ } = require$$3$1;
182
+ const {
183
+ EC2Client,
184
+ DescribeInstancesCommand,
185
+ DescribeLaunchTemplateVersionsCommand,
186
+ CreateLaunchTemplateVersionCommand,
187
+ ModifyLaunchTemplateCommand,
188
+ } = require$$4;
189
+ const child_process = require$$5;
190
+ const fs = require$$6;
191
+ const { join: pathJoin } = require$$7;
192
+ const { webRequest, headUrl, fetchFileContents } = /*@__PURE__*/ requireRequest();
193
+
194
+ src.init = init;
195
+ src.getGitCommitHash = getGitCommitHash;
196
+
197
+ const MAX_WAIT_COUNT = 12;
198
+ const SERVER_WAIT_MS = 10 * 1000;
199
+ const DEFAULT_CONFIG = {
200
+ route_prefix: '',
201
+ secret: 'secret',
202
+ sc_update_url_key_name: 'SC_UPDATE_URL',
203
+ restart_function: _defaultRestartFunction,
204
+ service_port: 80,
205
+ http_proto: 'http',
206
+ auth_middleware: false,
207
+ repo_dir: process.env.PWD,
208
+ console_log: console.log,
209
+ error_log: console.error,
210
+ update_launch_default: true,
211
+ remove_old_target: true,
212
+ };
213
+ const g_config = {};
214
+ let g_gitCommitHash = false;
215
+ let g_updateHash = '';
216
+
217
+ function init(app, config) {
218
+ Object.assign(g_config, DEFAULT_CONFIG, config);
219
+ if (typeof g_config.route_prefix !== 'string') {
220
+ throw 'server-control route_prefix required';
221
+ }
222
+ if (!g_config.remote_repo_prefix) {
223
+ throw 'server-control remote_repo_prefix required';
224
+ }
225
+ g_config.route_prefix.replace(/\/$/, '');
226
+ g_config.remote_repo_prefix.replace(/\/$/, '');
227
+
228
+ asyncSeries([
229
+ (done) => {
230
+ _getAwsRegion(done);
231
+ },
232
+ (done) => {
233
+ getGitCommitHash();
234
+ const { route_prefix } = g_config;
235
+ if (g_config.remove_old_target) {
236
+ _removeOldTarget();
237
+ }
238
+
239
+ app.all(
240
+ route_prefix + '/server_data',
241
+ _parseQuery,
242
+ _secretOrAuth,
243
+ _serverData
244
+ );
245
+ app.all(
246
+ route_prefix + '/group_data',
247
+ _parseQuery,
248
+ _secretOrAuth,
249
+ _groupData
250
+ );
251
+ app.all(
252
+ route_prefix + '/update_group',
253
+ _parseQuery,
254
+ _secretOrAuth,
255
+ _updateGroup
256
+ );
257
+ app.all(
258
+ route_prefix + '/update_server',
259
+ _parseQuery,
260
+ _secretOrAuth,
261
+ _updateServer
262
+ );
263
+ done();
264
+ },
265
+ ]);
266
+ }
267
+ function _parseQuery(req, res, next) {
268
+ if (typeof req.query === 'string') {
269
+ const query = {};
270
+ req.query.split('&').forEach((key_val) => {
271
+ const split = key_val.split('=');
272
+ query[split[0]] = split[1] || '';
273
+ });
274
+ req.query = query;
275
+ }
276
+ next();
277
+ }
278
+ function _secretOrAuth(req, res, next) {
279
+ if (req.headers && req.headers['x-sc-secret'] === g_config.secret) {
280
+ next();
281
+ } else if (
282
+ req.body &&
283
+ req.body.secret &&
284
+ req.body.secret === g_config.secret
285
+ ) {
286
+ next();
287
+ } else if (
288
+ req.cookies &&
289
+ req.cookies.secret &&
290
+ req.cookies.secret === g_config.secret
291
+ ) {
292
+ next();
293
+ } else if (g_config.auth_middleware) {
294
+ g_config.auth_middleware(req, res, next);
295
+ } else {
296
+ res.sendStatus(403);
297
+ }
298
+ }
299
+ function _serverData(req, res) {
300
+ res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
301
+
302
+ getGitCommitHash((err, git_commit_hash) => {
303
+ const body = {
304
+ git_commit_hash,
305
+ uptime: process.uptime(),
306
+ };
307
+ if (err) {
308
+ res.status(500);
309
+ body.err = err;
310
+ }
311
+ res.send(body);
312
+ });
313
+ }
314
+
315
+ function _groupData(req, res) {
316
+ res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
317
+
318
+ _getGroupData((err, result) => {
319
+ const body = {
320
+ LATEST: result.latest || 'unknown',
321
+ InstanceId: result.InstanceId || 'unknown',
322
+ instance_list: result.instance_list,
323
+ };
324
+
325
+ if (result.auto_scale_group) {
326
+ body.auto_scale_group = {
327
+ AutoScalingGroupName: result.auto_scale_group.AutoScalingGroupName,
328
+ LaunchTemplate: result.auto_scale_group.LaunchTemplate,
329
+ };
330
+ if (result.launch_template) {
331
+ body.launch_template = result.launch_template;
332
+ }
333
+ }
334
+
335
+ if (err) {
336
+ res.status(500).send({ err, body });
337
+ } else {
338
+ res.send(body);
339
+ }
340
+ });
341
+ }
342
+
343
+ function _getGroupData(done) {
344
+ const autoscaling = _getAutoscaling();
345
+ const ec2 = _getEC2();
346
+ let latest = false;
347
+ let InstanceId = false;
348
+ let asg = false;
349
+ let instance_list = false;
350
+ let launch_template = false;
351
+
352
+ asyncSeries(
353
+ [
354
+ (done) => {
355
+ _getLatest((err, result) => {
356
+ if (err) {
357
+ _errorLog('_getGroupData: latest err:', err);
358
+ }
359
+ latest = result;
360
+ done();
361
+ });
362
+ },
363
+ (done) => {
364
+ const opts = {
365
+ url: 'http://169.254.169.254/latest/meta-data/instance-id',
366
+ ...(g_config.metadata_opts || {}),
367
+ };
368
+ webRequest(opts, (err, results) => {
369
+ if (err) {
370
+ _errorLog('_getGroupData: Failed to get instance id:', err);
371
+ }
372
+ InstanceId = results || '';
373
+ done();
374
+ });
375
+ },
376
+ (done) => {
377
+ const command = new DescribeAutoScalingGroupsCommand({});
378
+ autoscaling.send(command).then(
379
+ (data) => {
380
+ asg = data.AutoScalingGroups.find((group) => {
381
+ return (
382
+ group.AutoScalingGroupName === g_config.asg_name ||
383
+ group.Instances.find((i) => i.InstanceId === InstanceId)
384
+ );
385
+ });
386
+ if (!asg) {
387
+ _errorLog('_getGroupData: asg not found:', g_config.asg_name);
388
+ done('asg_not_found');
389
+ } else {
390
+ done();
391
+ }
392
+ },
393
+ (err) => {
394
+ _errorLog('_getGroupData: find asg err:', err);
395
+ done(err);
396
+ }
397
+ );
398
+ },
399
+ (done) => {
400
+ const opts = {
401
+ InstanceIds: asg.Instances.map((i) => i.InstanceId),
402
+ };
403
+ const command = new DescribeInstancesCommand(opts);
404
+ ec2.send(command).then(
405
+ (results) => {
406
+ instance_list = [];
407
+ results.Reservations.forEach((reservation) => {
408
+ reservation.Instances.forEach((i) => {
409
+ instance_list.push({
410
+ InstanceId: i.InstanceId,
411
+ PrivateIpAddress: i.PrivateIpAddress,
412
+ PublicIpAddress: i.PublicIpAddress,
413
+ LaunchTime: i.LaunchTime,
414
+ ImageId: i.ImageId,
415
+ InstanceType: i.InstanceType,
416
+ State: i.State,
417
+ });
418
+ });
419
+ });
420
+ done();
421
+ },
422
+ (err) => {
423
+ _errorLog('_getGroupData: describeInstances err:', err);
424
+ done(err);
425
+ }
426
+ );
427
+ },
428
+ (done) => {
429
+ const list = instance_list.filter((i) => i.State.Name === 'running');
430
+ asyncEach(
431
+ list,
432
+ (instance, done) => {
433
+ _getServerData(instance, (err, body) => {
434
+ instance.git_commit_hash = body && body.git_commit_hash;
435
+ instance.uptime = body && body.uptime;
436
+ done(err);
437
+ });
438
+ },
439
+ done
440
+ );
441
+ },
442
+ (done) => {
443
+ const lt =
444
+ asg.LaunchTemplate ||
445
+ asg.MixedInstancesPolicy?.LaunchTemplate?.LaunchTemplateSpecification;
446
+ const opts = {
447
+ LaunchTemplateId: lt?.LaunchTemplateId,
448
+ Versions: [lt?.Version],
449
+ };
450
+ const command = new DescribeLaunchTemplateVersionsCommand(opts);
451
+ ec2.send(command).then(
452
+ (data) => {
453
+ if (data?.LaunchTemplateVersions?.length > 0) {
454
+ launch_template = data.LaunchTemplateVersions[0];
455
+ const ud = launch_template.LaunchTemplateData.UserData;
456
+ if (ud) {
457
+ const s = Buffer.from(ud, 'base64').toString('utf8');
458
+ launch_template.LaunchTemplateData.UserData = s;
459
+ }
460
+ done();
461
+ } else {
462
+ done('launch_template_not_found');
463
+ }
464
+ },
465
+ (err) => {
466
+ _errorLog('_getGroupData: launch template fetch error:', err);
467
+ done(err);
468
+ }
469
+ );
470
+ },
471
+ ],
472
+ (err) => {
473
+ const ret = {
474
+ latest,
475
+ InstanceId,
476
+ auto_scale_group: asg,
477
+ launch_template,
478
+ instance_list,
479
+ };
480
+ done(err, ret);
481
+ }
482
+ );
483
+ }
484
+
485
+ function _getServerData(instance, done) {
486
+ const proto = g_config.http_proto;
487
+ const ip = instance.PrivateIpAddress;
488
+ const port = g_config.service_port;
489
+ const prefix = g_config.route_prefix;
490
+ const url = `${proto}://${ip}:${port}${prefix}/server_data`;
491
+ const opts = {
492
+ strictSSL: false,
493
+ url,
494
+ method: 'GET',
495
+ headers: {
496
+ 'x-sc-secret': g_config.secret,
497
+ },
498
+ json: {
499
+ secret: g_config.secret,
500
+ },
501
+ };
502
+ webRequest(opts, (err, body) => {
503
+ if (err) {
504
+ _errorLog('_getServerData: request err:', err);
505
+ }
506
+ done(err, body);
507
+ });
508
+ }
509
+ function _updateServer(req, res) {
510
+ res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
511
+ const hash = req.body.hash || req.query.hash;
512
+ if (hash) {
513
+ _updateSelf(hash, (err) => {
514
+ if (err) {
515
+ res.status(500).send(err);
516
+ } else {
517
+ res.send('Restarting server');
518
+ g_config.restart_function();
519
+ }
520
+ });
521
+ } else {
522
+ res.status(400).send('hash is required');
523
+ }
524
+ }
525
+ function _updateSelf(hash, done) {
526
+ const dir = g_config.repo_dir;
527
+ const url = `${g_config.remote_repo_prefix}/${hash}.tar.gz`;
528
+ const cmd = `cd ${dir} && ${__dirname}/../scripts/update_to_hash.sh ${url}`;
529
+ child_process.exec(cmd, (err, stdout, stderr) => {
530
+ if (err) {
531
+ _errorLog(
532
+ '_updateSelf: update_to_hash.sh failed with err:',
533
+ err,
534
+ 'stdout:',
535
+ stdout,
536
+ 'stderr:',
537
+ stderr
538
+ );
539
+ err = 'update_failed';
540
+ } else {
541
+ g_updateHash = hash;
542
+ }
543
+ done(err);
544
+ });
545
+ }
546
+ function _removeOldTarget() {
547
+ const dir = g_config.repo_dir;
548
+ const cmd = `${__dirname}/../scripts/remove_old_target.sh ${dir}`;
549
+ child_process.exec(cmd, (err, stdout, stderr) => {
550
+ if (err) {
551
+ _errorLog(
552
+ '_removeOldTarget: remove_old_target.sh failed with err:',
553
+ err,
554
+ 'stdout:',
555
+ stdout,
556
+ 'stderr:',
557
+ stderr
558
+ );
559
+ }
560
+ });
561
+ }
562
+
563
+ function _updateGroup(req, res) {
564
+ res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
565
+
566
+ const hash = req.body.hash || req.query.hash;
567
+ if (hash) {
568
+ const url = `${g_config.remote_repo_prefix}/${hash}.tar.gz`;
569
+ const key_name = g_config.sc_update_url_key_name;
570
+ const ami_id = req.body.ami_id || req.query.ami_id || false;
571
+
572
+ const ec2 = _getEC2();
573
+ let group_data = false;
574
+ let old_data = '';
575
+ let new_version;
576
+ const server_result = {};
577
+ asyncSeries(
578
+ [
579
+ (done) => {
580
+ _getGroupData((err, result) => {
581
+ if (!err) {
582
+ group_data = result;
583
+ const data = result.launch_template.LaunchTemplateData.UserData;
584
+ data.split('\n').forEach((line) => {
585
+ if (line.length && line.indexOf(key_name) === -1) {
586
+ old_data += line + '\n';
587
+ }
588
+ });
589
+ }
590
+ done(err);
591
+ });
592
+ },
593
+ (done) => {
594
+ headUrl(url, { region: g_config.region }, (err) => {
595
+ if (err) {
596
+ _errorLog('_updateGroup: head url:', url, 'err:', err);
597
+ err = 'url_not_found';
598
+ }
599
+ done(err);
600
+ });
601
+ },
602
+ (done) => {
603
+ const new_data = `${old_data}${key_name}=${url}\n`;
604
+ const opts = {
605
+ LaunchTemplateId: group_data.launch_template.LaunchTemplateId,
606
+ SourceVersion: String(group_data.launch_template.VersionNumber),
607
+ LaunchTemplateData: {
608
+ UserData: Buffer.from(new_data, 'utf8').toString('base64'),
609
+ },
610
+ };
611
+ if (ami_id) {
612
+ opts.LaunchTemplateData.ImageId = ami_id;
613
+ }
614
+ const command = new CreateLaunchTemplateVersionCommand(opts);
615
+ ec2.send(command).then(
616
+ (data) => {
617
+ new_version = data.LaunchTemplateVersion.VersionNumber;
618
+ done();
619
+ },
620
+ (err) => {
621
+ _errorLog('_updateGroup: failed to create version, err:', err);
622
+ done(err);
623
+ }
624
+ );
625
+ },
626
+ (done) => {
627
+ if (g_config.update_launch_default) {
628
+ const opts = {
629
+ DefaultVersion: String(new_version),
630
+ LaunchTemplateId: group_data.launch_template.LaunchTemplateId,
631
+ };
632
+ const command = new ModifyLaunchTemplateCommand(opts);
633
+ ec2.send(command).then(
634
+ () => {
635
+ done();
636
+ },
637
+ (err) => {
638
+ _errorLog('_updateGroup: failed to update default, err:', err);
639
+ done(err);
640
+ }
641
+ );
642
+ } else {
643
+ done();
644
+ }
645
+ },
646
+ (done) => {
647
+ let group_err;
648
+ asyncEach(
649
+ group_data.instance_list,
650
+ (instance, done) => {
651
+ if (instance.InstanceId === group_data.InstanceId) {
652
+ done();
653
+ } else {
654
+ _updateInstance(hash, instance, (err) => {
655
+ if (err) {
656
+ _errorLog(
657
+ '_updateGroup: update instance:',
658
+ instance.InstanceId,
659
+ 'err:',
660
+ err
661
+ );
662
+ group_err = err;
663
+ }
664
+ server_result[instance.InstanceId] = err;
665
+ done();
666
+ });
667
+ }
668
+ },
669
+ () => done(group_err)
670
+ );
671
+ },
672
+ (done) => {
673
+ _updateSelf(hash, (err) => {
674
+ server_result[group_data.InstanceId] = err;
675
+ done(err);
676
+ });
677
+ },
678
+ ],
679
+ (err) => {
680
+ const body = {
681
+ err,
682
+ server_result,
683
+ launch_template_version: new_version,
684
+ };
685
+ if (err) {
686
+ res.status(500).send(body);
687
+ } else {
688
+ body._msg =
689
+ 'Successful updating all servers, restarting this server.';
690
+ res.send(body);
691
+ g_config.restart_function();
692
+ }
693
+ }
694
+ );
695
+ } else {
696
+ res.status(400).send('hash is required');
697
+ }
698
+ }
699
+ function _updateInstance(hash, instance, done) {
700
+ asyncSeries(
701
+ [
702
+ (done) => {
703
+ const proto = g_config.http_proto;
704
+ const ip = instance.PrivateIpAddress;
705
+ const port = g_config.service_port;
706
+ const prefix = g_config.route_prefix;
707
+ const url = `${proto}://${ip}:${port}${prefix}/update_server`;
708
+ const opts = {
709
+ strictSSL: false,
710
+ url,
711
+ method: 'GET',
712
+ headers: {
713
+ 'x-sc-secret': g_config.secret,
714
+ },
715
+ json: {
716
+ hash,
717
+ secret: g_config.secret,
718
+ },
719
+ };
720
+ webRequest(opts, done);
721
+ },
722
+ (done) => _waitForServer({ instance, hash }, done),
723
+ ],
724
+ done
725
+ );
726
+ }
727
+ function _waitForServer(params, done) {
728
+ const { instance, hash } = params;
729
+ let count = 0;
730
+
731
+ asyncForever(
732
+ (done) => {
733
+ count++;
734
+ _getServerData(instance, (err, body) => {
735
+ if (!err && body && body.git_commit_hash === hash) {
736
+ done('stop');
737
+ } else if (count > MAX_WAIT_COUNT) {
738
+ done('too_many_tries');
739
+ } else {
740
+ setTimeout(done, SERVER_WAIT_MS);
741
+ }
742
+ });
743
+ },
744
+ (err) => {
745
+ if (err === 'stop') {
746
+ err = null;
747
+ }
748
+ done(err);
749
+ }
750
+ );
751
+ }
752
+
753
+ function _getLatest(done) {
754
+ const url = g_config.remote_repo_prefix + '/LATEST';
755
+ fetchFileContents(url, { region: g_config.region }, (err, body) => {
756
+ done(err, body && body.trim());
757
+ });
758
+ }
759
+ function getGitCommitHash(done) {
760
+ if (g_gitCommitHash) {
761
+ done && done(null, g_gitCommitHash);
762
+ } else {
763
+ const file = pathJoin(g_config.repo_dir, '.git_commit_hash');
764
+ fs.readFile(file, 'utf8', (err, result) => {
765
+ if (!err && !result) {
766
+ err = 'no_result';
767
+ }
768
+ if (err) {
769
+ _errorLog('getGitCommitHash: err:', err, 'file:', file);
770
+ } else {
771
+ g_gitCommitHash = result.trim();
772
+ }
773
+ done && done(err, g_gitCommitHash);
774
+ });
775
+ }
776
+ }
777
+ function _getAwsRegion(done) {
778
+ if (g_config.region) {
779
+ return done();
780
+ }
781
+ const opts = {
782
+ url: 'http://169.254.169.254/latest/dynamic/instance-identity/document',
783
+ ...(g_config.metadata_opts || {}),
784
+ };
785
+ webRequest(opts, (err, results) => {
786
+ if (err) {
787
+ _errorLog('_getAwsRegion: metadata err:', err);
788
+ } else {
789
+ try {
790
+ const json = JSON.parse(results);
791
+ if (json && json.region) {
792
+ g_config.region = json.region;
793
+ }
794
+ } catch (e) {
795
+ _errorLog('_getAwsRegion: threw:', e);
796
+ }
797
+ }
798
+ done();
799
+ });
800
+ }
801
+
802
+ function _getAutoscaling() {
803
+ return new AutoScalingClient({ region: g_config.region });
804
+ }
805
+ function _getEC2() {
806
+ return new EC2Client({ region: g_config.region });
807
+ }
808
+ function _errorLog(...args) {
809
+ g_config.error_log(...args);
810
+ }
811
+ function _defaultRestartFunction() {
812
+ g_config.console_log(
813
+ 'server-control: updated to: ',
814
+ g_updateHash,
815
+ 'restarting...'
816
+ );
817
+ setTimeout(function () {
818
+ process.exit(0);
819
+ }, 100);
820
+ }
821
+ return src;
822
+ }
823
+
824
+ var srcExports = requireSrc();
825
+ var index = /*@__PURE__*/getDefaultExportFromCjs(srcExports);
826
+
827
+ module.exports = index;