@abtnode/core 1.6.23 → 1.6.24
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/lib/blocklet/manager/disk.js +12 -7
- package/lib/event.js +1 -0
- package/lib/index.js +7 -0
- package/lib/router/helper.js +55 -59
- package/lib/router/index.js +10 -5
- package/lib/router/manager.js +4 -4
- package/lib/states/node.js +2 -2
- package/lib/states/site.js +9 -0
- package/lib/util/blocklet.js +1 -1
- package/lib/util/disk-monitor.js +13 -10
- package/lib/util/index.js +3 -5
- package/lib/util/sysinfo.js +79 -0
- package/lib/validators/router.js +7 -0
- package/lib/validators/trusted-passport.js +1 -0
- package/package.json +17 -14
|
@@ -177,6 +177,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
177
177
|
logger.debug('install blocklet', { params, context });
|
|
178
178
|
|
|
179
179
|
const source = getSourceFromInstallParams(params);
|
|
180
|
+
if (typeof context.startImmediately === 'undefined') {
|
|
181
|
+
context.startImmediately = !!params.startImmediately;
|
|
182
|
+
}
|
|
180
183
|
|
|
181
184
|
if (source === BlockletSource.url) {
|
|
182
185
|
return this._installFromUrl({ url: params.url, sync: params.sync }, context);
|
|
@@ -1105,11 +1108,13 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1105
1108
|
blocklet.diskInfo = await getDiskInfo(blocklet, { useFakeDiskInfo: !diskInfo });
|
|
1106
1109
|
|
|
1107
1110
|
try {
|
|
1108
|
-
const app = blocklet.meta.group === BlockletGroup.gateway ? blocklet.children[0]
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
blocklet.status
|
|
1111
|
+
const app = blocklet.meta.group === BlockletGroup.gateway ? blocklet.children[0] : blocklet;
|
|
1112
|
+
if (app) {
|
|
1113
|
+
const { appId } = app.env;
|
|
1114
|
+
blocklet.runtimeInfo = await getRuntimeInfo(appId);
|
|
1115
|
+
if (blocklet.runtimeInfo.status && shouldUpdateBlockletStatus(blocklet.status)) {
|
|
1116
|
+
blocklet.status = statusMap[blocklet.runtimeInfo.status];
|
|
1117
|
+
}
|
|
1113
1118
|
}
|
|
1114
1119
|
} catch (err) {
|
|
1115
1120
|
if (err.code !== 'BLOCKLET_PROCESS_404') {
|
|
@@ -2347,7 +2352,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2347
2352
|
} catch (err) {
|
|
2348
2353
|
const b = await this._rollback(action, did, oldBlocklet);
|
|
2349
2354
|
logger.error(`failed to ${action} blocklet`, { did, version, name, error: err });
|
|
2350
|
-
this.emit(BlockletEvents.updated,
|
|
2355
|
+
this.emit(BlockletEvents.updated, b);
|
|
2351
2356
|
states.notification.create({
|
|
2352
2357
|
title: `Blocklet ${capitalize(action)} Failed`,
|
|
2353
2358
|
description: `Blocklet ${name}@${version} ${action} failed with error: ${err.message}`,
|
|
@@ -2634,7 +2639,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2634
2639
|
const result = await states.blocklet.updateBlocklet(did, oldBlocklet);
|
|
2635
2640
|
await this._setConfigs(did);
|
|
2636
2641
|
logger.info('blocklet rollback successfully', { did });
|
|
2637
|
-
this.emit(BlockletEvents.updated,
|
|
2642
|
+
this.emit(BlockletEvents.updated, result);
|
|
2638
2643
|
return result;
|
|
2639
2644
|
}
|
|
2640
2645
|
|
package/lib/event.js
CHANGED
|
@@ -208,6 +208,7 @@ module.exports = ({
|
|
|
208
208
|
};
|
|
209
209
|
|
|
210
210
|
events.handleBlockletAdd = handleBlockletAdd;
|
|
211
|
+
events.handleBlockletUpgrade = handleBlockletUpgrade;
|
|
211
212
|
events.handleBlockletRemove = handleBlockletRemove;
|
|
212
213
|
events.handleServerEvent = handleServerEvent;
|
|
213
214
|
events.onEvent = onEvent;
|
package/lib/index.js
CHANGED
|
@@ -35,6 +35,7 @@ const createQueue = require('./queue');
|
|
|
35
35
|
const createEvents = require('./event');
|
|
36
36
|
const pm2Events = require('./blocklet/manager/pm2-events');
|
|
37
37
|
const { createStateReadyQueue, createStateReadyHandler } = require('./util/ready');
|
|
38
|
+
const { getSysInfo, SysInfoEmitter } = require('./util/sysinfo');
|
|
38
39
|
const { toStatus, fromStatus, ensureDataDirs, getQueueConcurrencyByMem } = require('./util');
|
|
39
40
|
|
|
40
41
|
/**
|
|
@@ -148,6 +149,7 @@ function ABTNode(options) {
|
|
|
148
149
|
getSitesFromSnapshot,
|
|
149
150
|
getRoutingCrons,
|
|
150
151
|
ensureWildcardCerts,
|
|
152
|
+
getRouterProvider,
|
|
151
153
|
} = getRouterHelpers({ dataDirs, routingSnapshot, routerManager, blockletManager, certManager });
|
|
152
154
|
|
|
153
155
|
const teamManager = new TeamManager({ nodeDid: options.nodeDid, dataDirs, states });
|
|
@@ -367,6 +369,11 @@ function ABTNode(options) {
|
|
|
367
369
|
|
|
368
370
|
// Services
|
|
369
371
|
getServices: (params, context) => getServices({ stringifySchema: true }, context),
|
|
372
|
+
|
|
373
|
+
// Utilities: moved here because some deps require native build
|
|
374
|
+
getSysInfo,
|
|
375
|
+
getSysInfoEmitter: (interval) => new SysInfoEmitter(interval),
|
|
376
|
+
getRouterProvider,
|
|
370
377
|
};
|
|
371
378
|
|
|
372
379
|
const webhook = WebHook({ events, dataDirs, instance });
|
package/lib/router/helper.js
CHANGED
|
@@ -9,12 +9,11 @@ const isEqual = require('lodash/isEqual');
|
|
|
9
9
|
const joinUrl = require('url-join');
|
|
10
10
|
const { getProvider } = require('@abtnode/router-provider');
|
|
11
11
|
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
12
|
-
const
|
|
12
|
+
const getTmpDir = require('@abtnode/util/lib/get-tmp-directory');
|
|
13
13
|
const downloadFile = require('@abtnode/util/lib/download-file');
|
|
14
14
|
const {
|
|
15
15
|
DOMAIN_FOR_DEFAULT_SITE,
|
|
16
16
|
DOMAIN_FOR_IP_SITE_REGEXP,
|
|
17
|
-
ROUTER_PROVIDER_NONE,
|
|
18
17
|
DOMAIN_FOR_INTERNAL_SITE,
|
|
19
18
|
WELLKNOWN_PATH_PREFIX,
|
|
20
19
|
WELLKNOWN_AUTH_PATH_PREFIX,
|
|
@@ -30,6 +29,7 @@ const {
|
|
|
30
29
|
BLOCKLET_SITE_GROUP_SUFFIX,
|
|
31
30
|
WELLKNOWN_ACME_CHALLENGE_PREFIX,
|
|
32
31
|
WELLKNOWN_DID_RESOLVER_PREFIX,
|
|
32
|
+
WELLKNOWN_PING_PREFIX,
|
|
33
33
|
} = require('@abtnode/constant');
|
|
34
34
|
const {
|
|
35
35
|
BLOCKLET_DYNAMIC_PATH_PREFIX,
|
|
@@ -449,7 +449,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
449
449
|
const hasRuleByPrefix = (site, value) => site.rules.find((x) => x.isProtected && get(x, 'from.pathPrefix') === value);
|
|
450
450
|
|
|
451
451
|
const downloadCert = async ({ domain, url }) => {
|
|
452
|
-
const destFolder =
|
|
452
|
+
const destFolder = getTmpDir(path.join(`certificate-${Date.now()}`));
|
|
453
453
|
try {
|
|
454
454
|
const filename = path.join(destFolder, 'certificate.tar.gz');
|
|
455
455
|
fs.ensureDirSync(destFolder);
|
|
@@ -511,11 +511,6 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
511
511
|
|
|
512
512
|
const updateDashboardCertificates = async () => {
|
|
513
513
|
const info = await nodeState.read();
|
|
514
|
-
const provider = getProviderFromNodeInfo(info);
|
|
515
|
-
if (provider === ROUTER_PROVIDER_NONE) {
|
|
516
|
-
return;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
514
|
const https = get(info, 'routing.https', true);
|
|
520
515
|
const ipWildcardDomain = get(info, 'routing.ipWildcardDomain', '');
|
|
521
516
|
const didDomain = info.didDomain;
|
|
@@ -597,6 +592,20 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
597
592
|
to: proxyTarget,
|
|
598
593
|
};
|
|
599
594
|
|
|
595
|
+
const pingWellknownRule = {
|
|
596
|
+
isProtected: true,
|
|
597
|
+
from: { pathPrefix: WELLKNOWN_PING_PREFIX },
|
|
598
|
+
to: {
|
|
599
|
+
type: ROUTING_RULE_TYPES.DIRECT_RESPONSE,
|
|
600
|
+
response: {
|
|
601
|
+
status: 200,
|
|
602
|
+
contentType: 'application/javascript',
|
|
603
|
+
body: "console.log('ping: pong')",
|
|
604
|
+
},
|
|
605
|
+
port: info.port,
|
|
606
|
+
},
|
|
607
|
+
};
|
|
608
|
+
|
|
600
609
|
if (site) {
|
|
601
610
|
const didResolverRuleUpdateRes = await upsertSiteRule(
|
|
602
611
|
{
|
|
@@ -614,7 +623,15 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
614
623
|
context
|
|
615
624
|
);
|
|
616
625
|
|
|
617
|
-
|
|
626
|
+
const pingRuleRes = await upsertSiteRule(
|
|
627
|
+
{
|
|
628
|
+
site,
|
|
629
|
+
rule: pingWellknownRule,
|
|
630
|
+
},
|
|
631
|
+
context
|
|
632
|
+
);
|
|
633
|
+
|
|
634
|
+
return didResolverRuleUpdateRes || acmeRuleUpdateRes || pingRuleRes;
|
|
618
635
|
}
|
|
619
636
|
|
|
620
637
|
await routerManager.addRoutingSite(
|
|
@@ -623,7 +640,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
623
640
|
domain: DOMAIN_FOR_INTERNAL_SITE,
|
|
624
641
|
port: await getWellknownSitePort(),
|
|
625
642
|
name: NAME_FOR_WELLKNOWN_SITE,
|
|
626
|
-
rules: [didResolverWellknownRule, acmeChallengeWellknownRule],
|
|
643
|
+
rules: [didResolverWellknownRule, acmeChallengeWellknownRule, pingWellknownRule],
|
|
627
644
|
isProtected: true,
|
|
628
645
|
},
|
|
629
646
|
skipCheckDynamicBlacklist: true,
|
|
@@ -647,12 +664,6 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
647
664
|
*/
|
|
648
665
|
const ensureDashboardRouting = async (context = {}) => {
|
|
649
666
|
const info = await nodeState.read();
|
|
650
|
-
|
|
651
|
-
const provider = getProviderFromNodeInfo(info);
|
|
652
|
-
if (provider === ROUTER_PROVIDER_NONE) {
|
|
653
|
-
return false;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
667
|
const sites = await siteState.getSites();
|
|
657
668
|
let dashboardSite = (sites || []).find((x) => x.domain === DOMAIN_FOR_IP_SITE);
|
|
658
669
|
const updatedResult = [];
|
|
@@ -893,6 +904,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
893
904
|
* Add system routing rules for blocklet in dashboard site
|
|
894
905
|
*
|
|
895
906
|
* @returns {boolean} if routing changed
|
|
907
|
+
* TODO: do we still need this?
|
|
896
908
|
*/
|
|
897
909
|
const _ensureBlockletRulesForDashboardSite = async (blocklet, sites, nodeInfo, context = {}) => {
|
|
898
910
|
// blocklet level duplication detection
|
|
@@ -993,12 +1005,6 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
993
1005
|
*/
|
|
994
1006
|
const ensureBlockletRouting = async (blocklet, context = {}) => {
|
|
995
1007
|
const nodeInfo = await nodeState.read();
|
|
996
|
-
|
|
997
|
-
const provider = getProviderFromNodeInfo(nodeInfo);
|
|
998
|
-
if (provider === ROUTER_PROVIDER_NONE) {
|
|
999
|
-
return false;
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
1008
|
const hasWebInterface = (blocklet.meta.interfaces || []).some((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB);
|
|
1003
1009
|
if (!hasWebInterface) {
|
|
1004
1010
|
return false;
|
|
@@ -1098,12 +1104,6 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1098
1104
|
* @returns {boolean} if routing changed
|
|
1099
1105
|
*/
|
|
1100
1106
|
const ensureBlockletRoutingForUpgrade = async (blocklet, context = {}) => {
|
|
1101
|
-
const nodeInfo = await nodeState.read();
|
|
1102
|
-
const provider = getProviderFromNodeInfo(nodeInfo);
|
|
1103
|
-
if (provider === ROUTER_PROVIDER_NONE) {
|
|
1104
|
-
return false;
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1107
1107
|
await routerManager.deleteRoutingRulesItemByDid(
|
|
1108
1108
|
{ did: blocklet.meta.did, ruleFilter: (x) => x.isProtected },
|
|
1109
1109
|
context
|
|
@@ -1158,14 +1158,11 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1158
1158
|
return rules.filter((rule) => rule.to.did === did);
|
|
1159
1159
|
}
|
|
1160
1160
|
|
|
1161
|
-
const
|
|
1161
|
+
const providers = {}; // we need to keep reference for different router instances
|
|
1162
1162
|
const handleRouting = async (nodeInfo) => {
|
|
1163
1163
|
const providerName = get(nodeInfo, 'routing.provider', null);
|
|
1164
1164
|
const httpsEnabled = get(nodeInfo, 'routing.https', true);
|
|
1165
1165
|
logger.debug('handle routing', { providerName, httpsEnabled });
|
|
1166
|
-
if (providerName === ROUTER_PROVIDER_NONE) {
|
|
1167
|
-
return;
|
|
1168
|
-
}
|
|
1169
1166
|
|
|
1170
1167
|
const Provider = getProvider(providerName);
|
|
1171
1168
|
const checkResult = await Provider.check({ configDir: dataDirs.router });
|
|
@@ -1173,12 +1170,12 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1173
1170
|
throw new Error(`${providerName} pre-check failed, ${checkResult.error}`);
|
|
1174
1171
|
}
|
|
1175
1172
|
|
|
1176
|
-
if (
|
|
1177
|
-
await
|
|
1173
|
+
if (providers[providerName]) {
|
|
1174
|
+
await providers[providerName].reload();
|
|
1178
1175
|
} else {
|
|
1179
|
-
|
|
1176
|
+
providers[providerName] = new Router({
|
|
1180
1177
|
provider: new Provider({
|
|
1181
|
-
|
|
1178
|
+
configDir: path.join(dataDirs.router, providerName),
|
|
1182
1179
|
httpPort: nodeInfo.routing.httpPort || DEFAULT_HTTP_PORT,
|
|
1183
1180
|
httpsPort: nodeInfo.routing.httpsPort || DEFAULT_HTTPS_PORT,
|
|
1184
1181
|
cacheDisabled: nodeInfo.mode === NODE_MODES.DEBUG,
|
|
@@ -1216,11 +1213,11 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1216
1213
|
},
|
|
1217
1214
|
});
|
|
1218
1215
|
|
|
1219
|
-
certManager.on('cert.added', () =>
|
|
1220
|
-
certManager.on('cert.removed', () =>
|
|
1221
|
-
certManager.on('cert.issued', () =>
|
|
1216
|
+
certManager.on('cert.added', () => providers[providerName].reload());
|
|
1217
|
+
certManager.on('cert.removed', () => providers[providerName].reload());
|
|
1218
|
+
certManager.on('cert.issued', () => providers[providerName].reload());
|
|
1222
1219
|
|
|
1223
|
-
await
|
|
1220
|
+
await providers[providerName].start();
|
|
1224
1221
|
}
|
|
1225
1222
|
};
|
|
1226
1223
|
|
|
@@ -1228,8 +1225,8 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1228
1225
|
const info = await nodeState.read();
|
|
1229
1226
|
const providerName = get(info, 'routing.provider', null);
|
|
1230
1227
|
|
|
1231
|
-
if (providerName &&
|
|
1232
|
-
await
|
|
1228
|
+
if (providerName && providers[providerName] && typeof providers[providerName].rotateLogs === 'function') {
|
|
1229
|
+
await providers[providerName].rotateLogs();
|
|
1233
1230
|
}
|
|
1234
1231
|
};
|
|
1235
1232
|
|
|
@@ -1258,30 +1255,28 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1258
1255
|
await handleRouting(result);
|
|
1259
1256
|
|
|
1260
1257
|
if (newProvider !== info.routing.provider) {
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
const
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
const ensureBlockletResults = await Promise.all(blocklets.map((x) => ensureBlocklet(x)));
|
|
1258
|
+
// Ensure we have system sites for daemon
|
|
1259
|
+
await ensureDashboardRouting(context);
|
|
1260
|
+
|
|
1261
|
+
// Ensure we have system rules for blocklets
|
|
1262
|
+
const blocklets = await blockletState.getBlocklets();
|
|
1263
|
+
const ensureBlocklet = async (x) => {
|
|
1264
|
+
const blocklet = await blockletManager.ensureBlocklet(x.meta.did);
|
|
1265
|
+
return ensureBlockletRouting(blocklet, context);
|
|
1266
|
+
};
|
|
1267
|
+
const ensureBlockletResults = await Promise.all(blocklets.map((x) => ensureBlocklet(x)));
|
|
1272
1268
|
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
}
|
|
1269
|
+
// We need to take snapshot after system rules ensured
|
|
1270
|
+
if (ensureBlockletResults.filter(Boolean).length) {
|
|
1271
|
+
await takeRoutingSnapshot({ message: `Switch routing engine to ${newProvider}`, dryRun: false }, context);
|
|
1272
|
+
logger.info(`take routing snapshot on switch engine: ${newProvider}`, { ensureBlockletResults });
|
|
1278
1273
|
}
|
|
1279
1274
|
|
|
1280
1275
|
const Provider = getProvider(info.routing.provider);
|
|
1281
1276
|
if (Provider) {
|
|
1282
1277
|
try {
|
|
1283
1278
|
const providerInstance = new Provider({
|
|
1284
|
-
|
|
1279
|
+
configDir: path.join(dataDirs.router, info.routing.provider),
|
|
1285
1280
|
httpPort: info.routing.httpPort || DEFAULT_HTTP_PORT,
|
|
1286
1281
|
httpsPort: info.routing.httpsPort || DEFAULT_HTTPS_PORT,
|
|
1287
1282
|
cacheDisabled: info.mode === NODE_MODES.DEBUG,
|
|
@@ -1424,6 +1419,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1424
1419
|
ensureWildcardCerts,
|
|
1425
1420
|
addWellknownSite,
|
|
1426
1421
|
upsertSiteRule,
|
|
1422
|
+
getRouterProvider: (name) => providers[name],
|
|
1427
1423
|
|
|
1428
1424
|
getRoutingCrons: () => [
|
|
1429
1425
|
{
|
package/lib/router/index.js
CHANGED
|
@@ -117,12 +117,7 @@ class Router {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
async update() {
|
|
120
|
-
if (!this.provider) {
|
|
121
|
-
throw new Error('use setProvider() to set provider first');
|
|
122
|
-
}
|
|
123
|
-
|
|
124
120
|
logger.info('router: update');
|
|
125
|
-
|
|
126
121
|
await this.updateRoutingTable();
|
|
127
122
|
await this.provider.reload();
|
|
128
123
|
}
|
|
@@ -139,6 +134,12 @@ class Router {
|
|
|
139
134
|
return this.provider.restart();
|
|
140
135
|
}
|
|
141
136
|
|
|
137
|
+
async reload() {
|
|
138
|
+
logger.info('router: reload');
|
|
139
|
+
await this.updateRoutingTable();
|
|
140
|
+
return this.provider.reload();
|
|
141
|
+
}
|
|
142
|
+
|
|
142
143
|
stop() {
|
|
143
144
|
logger.info('router: stop');
|
|
144
145
|
return this.provider.stop();
|
|
@@ -153,6 +154,10 @@ class Router {
|
|
|
153
154
|
logger.info('router: rotate logs');
|
|
154
155
|
await this.provider.rotateLogs();
|
|
155
156
|
}
|
|
157
|
+
|
|
158
|
+
getLogFilesForToday() {
|
|
159
|
+
return this.provider.getLogFilesForToday();
|
|
160
|
+
}
|
|
156
161
|
}
|
|
157
162
|
|
|
158
163
|
Router.formatSites = (sites = []) => {
|
package/lib/router/manager.js
CHANGED
|
@@ -594,8 +594,8 @@ class RouterManager extends EventEmitter {
|
|
|
594
594
|
// get provider
|
|
595
595
|
const providerName = getProviderFromNodeInfo(info);
|
|
596
596
|
const Provider = getProvider(providerName);
|
|
597
|
-
const
|
|
598
|
-
const provider = new Provider({
|
|
597
|
+
const tmpDir = path.join(os.tmpdir(), `${providerName}-${Date.now()}`);
|
|
598
|
+
const provider = new Provider({ configDir: tmpDir });
|
|
599
599
|
const tempRouter = new Router({
|
|
600
600
|
provider,
|
|
601
601
|
getRoutingParams: async () => ({
|
|
@@ -610,10 +610,10 @@ class RouterManager extends EventEmitter {
|
|
|
610
610
|
await tempRouter.updateRoutingTable();
|
|
611
611
|
try {
|
|
612
612
|
await tempRouter.validateConfig();
|
|
613
|
-
await fse.remove(
|
|
613
|
+
await fse.remove(tmpDir);
|
|
614
614
|
} catch (error) {
|
|
615
615
|
logger.error('validate router config failed', { error, action, data });
|
|
616
|
-
await fse.remove(
|
|
616
|
+
await fse.remove(tmpDir);
|
|
617
617
|
throw error;
|
|
618
618
|
}
|
|
619
619
|
}
|
package/lib/states/node.js
CHANGED
|
@@ -6,7 +6,7 @@ const isEmpty = require('lodash/isEmpty');
|
|
|
6
6
|
const security = require('@abtnode/util/lib/security');
|
|
7
7
|
const { isFromPublicKey } = require('@arcblock/did');
|
|
8
8
|
const logger = require('@abtnode/logger')('@abtnode/core:node');
|
|
9
|
-
const {
|
|
9
|
+
const { NODE_MODES, DISK_ALERT_THRESHOLD_PERCENT } = require('@abtnode/constant');
|
|
10
10
|
|
|
11
11
|
const BaseState = require('./base');
|
|
12
12
|
const { validateOwner } = require('../util');
|
|
@@ -87,7 +87,7 @@ class NodeState extends BaseState {
|
|
|
87
87
|
nodeOwner,
|
|
88
88
|
port,
|
|
89
89
|
version,
|
|
90
|
-
routing = { provider:
|
|
90
|
+
routing = { provider: 'default' },
|
|
91
91
|
docker,
|
|
92
92
|
mode,
|
|
93
93
|
runtimeConfig,
|
package/lib/states/site.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const logger = require('@abtnode/logger')('@abtnode/core:states:site');
|
|
2
|
+
const { toSlotDomain } = require('@abtnode/router-provider/lib/util');
|
|
2
3
|
|
|
3
4
|
const BaseState = require('./base');
|
|
4
5
|
|
|
@@ -75,6 +76,14 @@ class SiteState extends BaseState {
|
|
|
75
76
|
|
|
76
77
|
return count > 0;
|
|
77
78
|
}
|
|
79
|
+
|
|
80
|
+
async findOneByDomain(domain) {
|
|
81
|
+
// eslint-disable-next-line no-param-reassign
|
|
82
|
+
domain = toSlotDomain(domain);
|
|
83
|
+
return this.asyncDB.findOne({
|
|
84
|
+
$or: [{ domain }, { domainAliases: domain }, { 'domainAliases.value': domain }],
|
|
85
|
+
});
|
|
86
|
+
}
|
|
78
87
|
}
|
|
79
88
|
|
|
80
89
|
module.exports = SiteState;
|
package/lib/util/blocklet.js
CHANGED
|
@@ -456,7 +456,7 @@ const startBlockletProcess = async (blocklet, { preStart = noop, nodeEnvironment
|
|
|
456
456
|
|
|
457
457
|
const clusterMode = get(b.meta, 'capabilities.clusterMode', false);
|
|
458
458
|
if (clusterMode && blocklet.mode !== BLOCKLET_MODES.DEVELOPMENT) {
|
|
459
|
-
const clusterSize = Number(blocklet.configObj.BLOCKLET_CLUSTER_SIZE) ||
|
|
459
|
+
const clusterSize = Number(blocklet.configObj.BLOCKLET_CLUSTER_SIZE) || +process.env.ABT_NODE_MAX_CLUSTER_SIZE;
|
|
460
460
|
options.execMode = 'cluster';
|
|
461
461
|
options.mergeLogs = true;
|
|
462
462
|
options.instances = Math.min(os.cpus().length, clusterSize);
|
package/lib/util/disk-monitor.js
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
|
-
const systeminformation = require('@abtnode/util/lib/sys-info');
|
|
2
1
|
const logger = require('@abtnode/logger')('@abtnode/disk-monitor');
|
|
2
|
+
const info = require('./sysinfo');
|
|
3
3
|
|
|
4
4
|
const states = require('../states');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* @param {number} threshold Threshold for disk alarms, percentage
|
|
7
|
+
* @param {number} threshold Threshold for disk alerts, percentage
|
|
9
8
|
*/
|
|
10
9
|
const check = async (threshold) => {
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const { disks } = await info.getSysInfo();
|
|
11
|
+
for (const disk of disks) {
|
|
12
|
+
const usageRatio = (disk.used / disk.total) * 100;
|
|
13
|
+
const usageRatioPercent = `${usageRatio.toFixed(2)}%`;
|
|
14
|
+
logger.info('check disk usage', { usage: usageRatioPercent, threshold });
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
if (usageRatio < threshold) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// eslint-disable-next-line no-await-in-loop
|
|
17
21
|
await states.notification.create({
|
|
18
22
|
title: 'Disk Usage Alert',
|
|
19
|
-
description: `More than ${
|
|
23
|
+
description: `More than ${usageRatioPercent} space has been used for disk ${disk.device}, the blocklet server may not function properly.`,
|
|
20
24
|
entityType: 'node',
|
|
21
25
|
severity: 'warning',
|
|
22
26
|
sticky: true,
|
|
@@ -30,7 +34,6 @@ const getCron = () => ({
|
|
|
30
34
|
fn: async () => {
|
|
31
35
|
const nodeInfo = await states.node.read();
|
|
32
36
|
const threshold = nodeInfo.diskAlertThreshold;
|
|
33
|
-
|
|
34
37
|
await check(threshold);
|
|
35
38
|
},
|
|
36
39
|
options: { runOnInit: true },
|
package/lib/util/index.js
CHANGED
|
@@ -20,7 +20,6 @@ const { validateMeta, fixAndValidateService } = require('@blocklet/meta/lib/vali
|
|
|
20
20
|
const { BlockletStatus, BLOCKLET_INTERFACE_WELLKNOWN } = require('@blocklet/meta/lib/constants');
|
|
21
21
|
const {
|
|
22
22
|
StatusCode,
|
|
23
|
-
ROUTER_PROVIDER_NONE,
|
|
24
23
|
DOMAIN_FOR_DEFAULT_SITE,
|
|
25
24
|
DOMAIN_FOR_IP_SITE,
|
|
26
25
|
DOMAIN_FOR_IP_SITE_REGEXP,
|
|
@@ -242,7 +241,7 @@ const getBlockletInterfaces = ({ blocklet, context, nodeInfo, routingRules, node
|
|
|
242
241
|
return uniqBy(interfaces, 'url');
|
|
243
242
|
};
|
|
244
243
|
|
|
245
|
-
const isRoutingEnabled = (routing) => !!routing && !!routing.provider
|
|
244
|
+
const isRoutingEnabled = (routing) => !!routing && !!routing.provider;
|
|
246
245
|
|
|
247
246
|
const isInProgress = (status) =>
|
|
248
247
|
[
|
|
@@ -283,7 +282,7 @@ const asyncExec = (command, options) =>
|
|
|
283
282
|
});
|
|
284
283
|
});
|
|
285
284
|
|
|
286
|
-
const getProviderFromNodeInfo = (
|
|
285
|
+
const getProviderFromNodeInfo = (info) => get(info, 'routing.provider', 'default');
|
|
287
286
|
|
|
288
287
|
const isCLI = () => !process.env.ABT_NODE_SK;
|
|
289
288
|
|
|
@@ -370,9 +369,8 @@ const getBaseUrls = async (node, ips) => {
|
|
|
370
369
|
return { protocol, port };
|
|
371
370
|
};
|
|
372
371
|
|
|
373
|
-
if (info.routing.provider
|
|
372
|
+
if (info.routing.provider && info.routing.snapshotHash && info.routing.adminPath) {
|
|
374
373
|
const sites = await node.getSitesFromSnapshot();
|
|
375
|
-
|
|
376
374
|
const { ipWildcardDomain } = info.routing;
|
|
377
375
|
const adminPath = normalizePathPrefix(info.routing.adminPath);
|
|
378
376
|
const tmpHttpPort = getPort(httpPort, DEFAULT_HTTP_PORT);
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const EventEmitter = require('events');
|
|
2
|
+
const driveList = require('drivelist');
|
|
3
|
+
const si = require('systeminformation');
|
|
4
|
+
const checkDiskSpace = require('check-disk-space').default;
|
|
5
|
+
|
|
6
|
+
const getSysInfo = async () => {
|
|
7
|
+
const [info, drives] = await Promise.all([
|
|
8
|
+
si.get({
|
|
9
|
+
cpu: 'physicalCores',
|
|
10
|
+
mem: '*',
|
|
11
|
+
currentLoad: '*',
|
|
12
|
+
osInfo: 'platform',
|
|
13
|
+
}),
|
|
14
|
+
driveList.list(),
|
|
15
|
+
]);
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
cpu: {
|
|
19
|
+
...info.currentLoad,
|
|
20
|
+
...info.cpu,
|
|
21
|
+
},
|
|
22
|
+
mem: info.mem,
|
|
23
|
+
os: info.osInfo,
|
|
24
|
+
disks: await Promise.all(
|
|
25
|
+
drives
|
|
26
|
+
.filter((x) => x.isSystem && x.isVirtual === false && x.mountpoints.length)
|
|
27
|
+
.map(async (x) => {
|
|
28
|
+
const result = await checkDiskSpace(x.mountpoints[0].path);
|
|
29
|
+
return {
|
|
30
|
+
device: x.device,
|
|
31
|
+
mountPoint: result.diskPath,
|
|
32
|
+
total: result.size,
|
|
33
|
+
used: result.size - result.free,
|
|
34
|
+
free: result.free,
|
|
35
|
+
};
|
|
36
|
+
})
|
|
37
|
+
),
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
class SysInfoEmitter extends EventEmitter {
|
|
42
|
+
constructor(interval = 3000) {
|
|
43
|
+
super();
|
|
44
|
+
this.timer = null;
|
|
45
|
+
this.polling = false;
|
|
46
|
+
this.interval = interval;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
startPolling() {
|
|
50
|
+
if (this.polling) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (this.timer) {
|
|
55
|
+
clearInterval(this.timer);
|
|
56
|
+
this.timer = null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
this.polling = true;
|
|
60
|
+
this.timer = setInterval(() => {
|
|
61
|
+
getSysInfo().then((info) => {
|
|
62
|
+
if (info) {
|
|
63
|
+
this.emit('info', info);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}, this.interval);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
stopPolling() {
|
|
70
|
+
if (this.timer) {
|
|
71
|
+
clearInterval(this.timer);
|
|
72
|
+
this.timer = null;
|
|
73
|
+
this.polling = false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports.getSysInfo = getSysInfo;
|
|
79
|
+
module.exports.SysInfoEmitter = SysInfoEmitter;
|
package/lib/validators/router.js
CHANGED
|
@@ -39,6 +39,7 @@ const ruleSchema = {
|
|
|
39
39
|
ROUTING_RULE_TYPES.BLOCKLET,
|
|
40
40
|
ROUTING_RULE_TYPES.REDIRECT,
|
|
41
41
|
ROUTING_RULE_TYPES.GENERAL_PROXY,
|
|
42
|
+
ROUTING_RULE_TYPES.DIRECT_RESPONSE,
|
|
42
43
|
ROUTING_RULE_TYPES.NONE
|
|
43
44
|
)
|
|
44
45
|
.required(),
|
|
@@ -54,6 +55,12 @@ const ruleSchema = {
|
|
|
54
55
|
.label('interface name')
|
|
55
56
|
.when('type', { is: ROUTING_RULE_TYPES.BLOCKLET, then: Joi.required() }),
|
|
56
57
|
realInterfaceName: Joi.string().label('real interface name'), // child blocklet interface
|
|
58
|
+
response: Joi.object({ status: Joi.number().required(), contentType: Joi.string(), body: Joi.string().required() })
|
|
59
|
+
.label('response')
|
|
60
|
+
.when('type', {
|
|
61
|
+
is: ROUTING_RULE_TYPES.DIRECT_RESPONSE,
|
|
62
|
+
then: Joi.required(),
|
|
63
|
+
}),
|
|
57
64
|
},
|
|
58
65
|
|
|
59
66
|
// List of services that manipulate the request before the upstream blocklet
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.6.
|
|
6
|
+
"version": "1.6.24",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,22 +19,22 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/certificate-manager": "1.6.
|
|
23
|
-
"@abtnode/constant": "1.6.
|
|
24
|
-
"@abtnode/cron": "1.6.
|
|
25
|
-
"@abtnode/db": "1.6.
|
|
26
|
-
"@abtnode/logger": "1.6.
|
|
27
|
-
"@abtnode/queue": "1.6.
|
|
28
|
-
"@abtnode/rbac": "1.6.
|
|
29
|
-
"@abtnode/router-provider": "1.6.
|
|
30
|
-
"@abtnode/static-server": "1.6.
|
|
31
|
-
"@abtnode/timemachine": "1.6.
|
|
32
|
-
"@abtnode/util": "1.6.
|
|
22
|
+
"@abtnode/certificate-manager": "1.6.24",
|
|
23
|
+
"@abtnode/constant": "1.6.24",
|
|
24
|
+
"@abtnode/cron": "1.6.24",
|
|
25
|
+
"@abtnode/db": "1.6.24",
|
|
26
|
+
"@abtnode/logger": "1.6.24",
|
|
27
|
+
"@abtnode/queue": "1.6.24",
|
|
28
|
+
"@abtnode/rbac": "1.6.24",
|
|
29
|
+
"@abtnode/router-provider": "1.6.24",
|
|
30
|
+
"@abtnode/static-server": "1.6.24",
|
|
31
|
+
"@abtnode/timemachine": "1.6.24",
|
|
32
|
+
"@abtnode/util": "1.6.24",
|
|
33
33
|
"@arcblock/did": "^1.14.19",
|
|
34
34
|
"@arcblock/event-hub": "1.14.19",
|
|
35
35
|
"@arcblock/pm2-events": "^0.0.5",
|
|
36
36
|
"@arcblock/vc": "^1.14.19",
|
|
37
|
-
"@blocklet/meta": "1.6.
|
|
37
|
+
"@blocklet/meta": "1.6.24",
|
|
38
38
|
"@fidm/x509": "^1.2.1",
|
|
39
39
|
"@nedb/core": "^1.2.2",
|
|
40
40
|
"@nedb/multi": "^1.2.2",
|
|
@@ -45,8 +45,10 @@
|
|
|
45
45
|
"axios": "^0.25.0",
|
|
46
46
|
"axon": "^2.0.3",
|
|
47
47
|
"chalk": "^4.0.0",
|
|
48
|
+
"check-disk-space": "^3.2.0",
|
|
48
49
|
"deep-diff": "^1.0.2",
|
|
49
50
|
"detect-port": "^1.3.0",
|
|
51
|
+
"drivelist": "^9.2.4",
|
|
50
52
|
"flat": "^5.0.2",
|
|
51
53
|
"fs-extra": "^10.0.0",
|
|
52
54
|
"get-port": "^5.1.1",
|
|
@@ -64,6 +66,7 @@
|
|
|
64
66
|
"ssri": "^8.0.0",
|
|
65
67
|
"stream-throttle": "^0.1.3",
|
|
66
68
|
"stream-to-promise": "^3.0.0",
|
|
69
|
+
"systeminformation": "^5.11.5",
|
|
67
70
|
"tar": "^6.1.0",
|
|
68
71
|
"unzipper": "^0.10.11",
|
|
69
72
|
"url-join": "^4.0.1",
|
|
@@ -75,5 +78,5 @@
|
|
|
75
78
|
"express": "^4.17.1",
|
|
76
79
|
"jest": "^27.4.5"
|
|
77
80
|
},
|
|
78
|
-
"gitHead": "
|
|
81
|
+
"gitHead": "6bd8792a155ebbbefea6ca3d42c5b59b354d9879"
|
|
79
82
|
}
|