@abtnode/core 1.16.15-beta-d8e7b6c0 → 1.16.15-beta-9318a201
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/downloader/blocklet-downloader.js +0 -9
- package/lib/blocklet/downloader/resolve-download.js +2 -4
- package/lib/blocklet/manager/disk.js +52 -9
- package/lib/blocklet/manager/helper/install-component-from-upload.js +6 -1
- package/lib/blocklet/storage/backup/spaces.js +6 -1
- package/lib/monitor/blocklet-runtime-monitor.js +4 -3
- package/lib/router/index.js +1 -0
- package/lib/router/manager.js +3 -2
- package/lib/states/blocklet.js +4 -0
- package/lib/util/blocklet.js +87 -85
- package/package.json +20 -20
|
@@ -8,7 +8,6 @@ const { toBase58 } = require('@ocap/util');
|
|
|
8
8
|
const defaultLogger = require('@abtnode/logger')('@abtnode/core:blocklet-downloader');
|
|
9
9
|
|
|
10
10
|
const { forEachComponentV2Sync, getComponentBundleId } = require('@blocklet/meta/lib/util');
|
|
11
|
-
const validateBlockletEntry = require('@blocklet/meta/lib/entry');
|
|
12
11
|
|
|
13
12
|
const { BlockletSource, BLOCKLET_META_FILE, BLOCKLET_META_FILE_ALT, BLOCKLET_MODES } = require('@blocklet/constant');
|
|
14
13
|
|
|
@@ -54,14 +53,6 @@ const needDownload = (
|
|
|
54
53
|
return true;
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
// check bundle broken
|
|
58
|
-
try {
|
|
59
|
-
validateBlockletEntry(bundleDir, component.meta);
|
|
60
|
-
} catch (err) {
|
|
61
|
-
logger.error('bundle is broken', { bundleId, msg: err.message });
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
56
|
if (!isSourceAccessible(component)) {
|
|
66
57
|
return false;
|
|
67
58
|
}
|
|
@@ -2,7 +2,6 @@ const path = require('path');
|
|
|
2
2
|
const fs = require('fs-extra');
|
|
3
3
|
const { Throttle } = require('stream-throttle');
|
|
4
4
|
|
|
5
|
-
const validateBlockletEntry = require('@blocklet/meta/lib/entry');
|
|
6
5
|
const { BLOCKLET_BUNDLE_FOLDER } = require('@blocklet/constant');
|
|
7
6
|
|
|
8
7
|
const defaultLogger = require('@abtnode/logger')('@abtnode/core:resolve-download');
|
|
@@ -71,7 +70,7 @@ const resolveDownload = async (
|
|
|
71
70
|
await fs.move(dir, downloadDir, { overwrite: true });
|
|
72
71
|
fs.removeSync(tmp);
|
|
73
72
|
|
|
74
|
-
meta = getBlockletMeta(downloadDir
|
|
73
|
+
meta = getBlockletMeta(downloadDir);
|
|
75
74
|
const { did, name, version } = meta;
|
|
76
75
|
|
|
77
76
|
// validate
|
|
@@ -79,7 +78,6 @@ const resolveDownload = async (
|
|
|
79
78
|
logger.error('Meta has differences', { originalMeta, meta });
|
|
80
79
|
throw new Error('There are differences between the meta from tarball file and the original meta');
|
|
81
80
|
}
|
|
82
|
-
await validateBlockletEntry(downloadDir, meta);
|
|
83
81
|
|
|
84
82
|
if (typeof onProgress === 'function') {
|
|
85
83
|
onProgress({ name: 'blocklet.zip' });
|
|
@@ -152,7 +150,7 @@ const resolveDiffDownload = async (
|
|
|
152
150
|
};
|
|
153
151
|
await walkDiff(diffDir);
|
|
154
152
|
fs.removeSync(diffDir);
|
|
155
|
-
const meta = getBlockletMeta(downloadDir
|
|
153
|
+
const meta = getBlockletMeta(downloadDir);
|
|
156
154
|
|
|
157
155
|
await ensureBlockletExpanded(meta, downloadDir);
|
|
158
156
|
|
|
@@ -41,12 +41,13 @@ const {
|
|
|
41
41
|
getRolesFromAuthConfig,
|
|
42
42
|
isInProgress,
|
|
43
43
|
isBeforeInstalled,
|
|
44
|
-
getComponentsInternalInfo,
|
|
45
44
|
forEachComponentV2,
|
|
46
45
|
forEachComponentV2Sync,
|
|
47
46
|
findComponentByIdV2,
|
|
48
47
|
isGatewayBlocklet,
|
|
48
|
+
hasStartEngine,
|
|
49
49
|
} = require('@blocklet/meta/lib/util');
|
|
50
|
+
const { getComponentsInternalInfo } = require('@blocklet/meta/lib/blocklet');
|
|
50
51
|
const { update: updateMetaFile } = require('@blocklet/meta/lib/file');
|
|
51
52
|
const { titleSchema, updateMountPointSchema, environmentNameSchema } = require('@blocklet/meta/lib/schema');
|
|
52
53
|
const { emailConfigSchema } = require('@blocklet/sdk/lib/validators/email');
|
|
@@ -383,7 +384,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
383
384
|
logger.info('dev component', { folder, rootDid, mountPoint });
|
|
384
385
|
|
|
385
386
|
const meta = getBlockletMeta(folder, { defaultStoreUrl });
|
|
386
|
-
if (meta.group !== 'static' && (!meta.scripts || !meta.scripts.dev)) {
|
|
387
|
+
if (meta.group !== 'static' && hasStartEngine(meta) && (!meta.scripts || !meta.scripts.dev)) {
|
|
387
388
|
throw new Error('Incorrect blocklet.yml: missing `scripts.dev` field');
|
|
388
389
|
}
|
|
389
390
|
|
|
@@ -522,6 +523,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
522
523
|
|
|
523
524
|
if (checkHealthImmediately) {
|
|
524
525
|
await this._onCheckIfStarted(params, { throwOnError });
|
|
526
|
+
blocklet.status = BlockletStatus.running;
|
|
525
527
|
} else {
|
|
526
528
|
this.startQueue.push({
|
|
527
529
|
entity: 'blocklet',
|
|
@@ -613,6 +615,13 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
613
615
|
// send notification to wallet
|
|
614
616
|
this.emit(BlockletEvents.stopped, { ...res, componentDids });
|
|
615
617
|
|
|
618
|
+
this.emit(BlockletInternalEvents.componentStopped, {
|
|
619
|
+
appDid: blocklet.appDid,
|
|
620
|
+
components: componentDids?.length
|
|
621
|
+
? componentDids.map((x) => ({ did: x }))
|
|
622
|
+
: blocklet.children.map((x) => ({ did: x.meta.did })),
|
|
623
|
+
});
|
|
624
|
+
// for backward compatibility
|
|
616
625
|
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
617
626
|
appDid: blocklet.appDid,
|
|
618
627
|
components: getComponentsInternalInfo(res),
|
|
@@ -939,6 +948,11 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
939
948
|
componentDids: [child.meta.did],
|
|
940
949
|
});
|
|
941
950
|
|
|
951
|
+
this.emit(BlockletInternalEvents.componentRemoved, {
|
|
952
|
+
appDid: blocklet.appDid,
|
|
953
|
+
components: [{ did: child.meta.did }],
|
|
954
|
+
});
|
|
955
|
+
// for backward compatibility
|
|
942
956
|
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
943
957
|
appDid: blocklet.appDid,
|
|
944
958
|
components: getComponentsInternalInfo(newBlocklet),
|
|
@@ -1395,6 +1409,11 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1395
1409
|
await states.blocklet.updateBlocklet(rootDid, { mountPoint: blocklet.mountPoint, children: blocklet.children });
|
|
1396
1410
|
|
|
1397
1411
|
this.emit(BlockletEvents.upgraded, { blocklet, context: { ...context, createAuditLog: false } }); // trigger router refresh
|
|
1412
|
+
this.emit(BlockletInternalEvents.componentUpdated, {
|
|
1413
|
+
appDid: blocklet.appDid,
|
|
1414
|
+
components: getComponentsInternalInfo(blocklet).filter((x) => x.did === component.meta.did),
|
|
1415
|
+
});
|
|
1416
|
+
// for backward compatibility
|
|
1398
1417
|
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
1399
1418
|
appDid: blocklet.appDid,
|
|
1400
1419
|
components: getComponentsInternalInfo(blocklet),
|
|
@@ -1514,6 +1533,10 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1514
1533
|
return;
|
|
1515
1534
|
}
|
|
1516
1535
|
|
|
1536
|
+
if (!hasStartEngine(component.meta)) {
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1517
1540
|
try {
|
|
1518
1541
|
const status = await getProcessState(component.env.processId);
|
|
1519
1542
|
const oldStatus = component.status;
|
|
@@ -2044,6 +2067,11 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2044
2067
|
|
|
2045
2068
|
const res = await this.getBlocklet(did);
|
|
2046
2069
|
|
|
2070
|
+
this.emit(BlockletInternalEvents.componentStarted, {
|
|
2071
|
+
appDid: blocklet.appDid,
|
|
2072
|
+
components: (componentDids || []).map((x) => ({ did: x })),
|
|
2073
|
+
});
|
|
2074
|
+
// for backward compatibility
|
|
2047
2075
|
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
2048
2076
|
appDid: blocklet.appDid,
|
|
2049
2077
|
components: getComponentsInternalInfo(res),
|
|
@@ -2051,11 +2079,14 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2051
2079
|
|
|
2052
2080
|
this.emit(BlockletEvents.statusChange, res);
|
|
2053
2081
|
this.emit(BlockletEvents.started, { ...res, componentDids });
|
|
2082
|
+
|
|
2083
|
+
const componentNames = getComponentNamesWithVersion(blocklet, componentDids);
|
|
2084
|
+
const description = componentNames
|
|
2085
|
+
? `${getComponentNamesWithVersion(blocklet, componentDids)} is successfully started for ${blocklet.meta.title}.`
|
|
2086
|
+
: `${blocklet.meta.title} is successfully started`;
|
|
2054
2087
|
this._createNotification(did, {
|
|
2055
2088
|
title: '',
|
|
2056
|
-
description
|
|
2057
|
-
blocklet.meta.title
|
|
2058
|
-
}.`,
|
|
2089
|
+
description,
|
|
2059
2090
|
entityType: 'blocklet',
|
|
2060
2091
|
entityId: did,
|
|
2061
2092
|
severity: 'success',
|
|
@@ -2074,9 +2105,10 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2074
2105
|
await this.deleteProcess({ did, componentDids }, context);
|
|
2075
2106
|
const doc = await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
|
|
2076
2107
|
|
|
2077
|
-
const
|
|
2078
|
-
|
|
2079
|
-
|
|
2108
|
+
const componentNames = getComponentNamesWithVersion(blocklet, componentDids);
|
|
2109
|
+
const description = componentNames
|
|
2110
|
+
? `${getComponentNamesWithVersion(blocklet, componentDids)} start failed for ${title}: ${error.message}`
|
|
2111
|
+
: `${blocklet.meta.title} start failed: ${error.message}`;
|
|
2080
2112
|
|
|
2081
2113
|
this._createNotification(did, {
|
|
2082
2114
|
title: '',
|
|
@@ -2671,7 +2703,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2671
2703
|
logger.info('updated blocklet for upgrading', { did, version, source, name });
|
|
2672
2704
|
|
|
2673
2705
|
if (oldBlocklet.status === BlockletStatus.running) {
|
|
2674
|
-
// start new process
|
|
2675
2706
|
try {
|
|
2676
2707
|
await this.start({ did, componentDids }, context);
|
|
2677
2708
|
logger.info('started blocklet for upgrading', { did, version, componentDids });
|
|
@@ -2723,6 +2754,18 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2723
2754
|
|
|
2724
2755
|
await this._rollbackCache.remove({ did: blocklet.meta.did });
|
|
2725
2756
|
|
|
2757
|
+
if (oldBlocklet.status === BlockletStatus.running) {
|
|
2758
|
+
this.emit(
|
|
2759
|
+
action === INSTALL_ACTIONS.INSTALL_COMPONENT
|
|
2760
|
+
? BlockletInternalEvents.componentInstalled
|
|
2761
|
+
: BlockletInternalEvents.componentUpgraded,
|
|
2762
|
+
{
|
|
2763
|
+
appDid: blocklet.appDid,
|
|
2764
|
+
components: getComponentsInternalInfo(blocklet).filter((c) => componentDids.includes(c.did)),
|
|
2765
|
+
}
|
|
2766
|
+
);
|
|
2767
|
+
}
|
|
2768
|
+
// for backward compatibility
|
|
2726
2769
|
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
2727
2770
|
appDid: blocklet.appDid,
|
|
2728
2771
|
components: getComponentsInternalInfo(blocklet),
|
|
@@ -92,15 +92,20 @@ const installComponentFromUpload = async ({
|
|
|
92
92
|
if (index >= 0) {
|
|
93
93
|
// if upgrade, do not update mountPoint
|
|
94
94
|
newChild.mountPoint = newBlocklet.children[index].mountPoint;
|
|
95
|
+
newChild.installedAt = newBlocklet.children[index].installedAt || new Date();
|
|
95
96
|
newBlocklet.children.splice(index, 1, newChild);
|
|
96
97
|
} else {
|
|
98
|
+
newChild.installedAt = new Date();
|
|
97
99
|
newBlocklet.children.push(newChild);
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
const action = index >= 0 ? INSTALL_ACTIONS.UPGRADE_COMPONENT : INSTALL_ACTIONS.INSTALL_COMPONENT;
|
|
101
103
|
|
|
102
104
|
const { dynamicComponents } = await parseComponents(newChild);
|
|
103
|
-
const newChildren = filterDuplicateComponents(dynamicComponents, newBlocklet.children)
|
|
105
|
+
const newChildren = filterDuplicateComponents(dynamicComponents, newBlocklet.children).map((x) => ({
|
|
106
|
+
...x,
|
|
107
|
+
installedAt: new Date(),
|
|
108
|
+
}));
|
|
104
109
|
|
|
105
110
|
newBlocklet.children.push(...newChildren);
|
|
106
111
|
|
|
@@ -215,6 +215,12 @@ class SpacesBackup extends BaseBackup {
|
|
|
215
215
|
return object.name !== '.DS_Store';
|
|
216
216
|
},
|
|
217
217
|
onAfterUpload: async (data) => {
|
|
218
|
+
// @note: 当备份失败时 && 偶然会存在一些其他的备份请求后来发送成功了,此时会造成备份进度紊乱(明明失败了,错误信息显示上传某个文件成功了)的情况,所以失败的备份不需要再发送事件了
|
|
219
|
+
const currentBackup = await states.backup.findOne({ id: this.input.backup.id });
|
|
220
|
+
if (currentBackup.status === 1) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
218
224
|
logger.info('backup progress', { appDid: this.input.appDid, data });
|
|
219
225
|
const percent = (data.completed * 100) / data.total;
|
|
220
226
|
// 0.8 是因为上传文件到 spaces 占进度的 80%,+ 20 是因为需要累加之前的进度
|
|
@@ -225,7 +231,6 @@ class SpacesBackup extends BaseBackup {
|
|
|
225
231
|
progress,
|
|
226
232
|
message: progressMessage,
|
|
227
233
|
});
|
|
228
|
-
|
|
229
234
|
this.input.event.emit(BlockletEvents.backupProgress, {
|
|
230
235
|
appDid: this.input.appDid,
|
|
231
236
|
meta: { did: this.input.appDid },
|
|
@@ -2,10 +2,10 @@ const EventEmitter = require('events');
|
|
|
2
2
|
|
|
3
3
|
const cloneDeep = require('lodash/cloneDeep');
|
|
4
4
|
const pLimit = require('p-limit');
|
|
5
|
-
const { forEachBlocklet } = require('@blocklet/meta/lib/util');
|
|
5
|
+
const { forEachBlocklet, isGatewayBlocklet, hasStartEngine } = require('@blocklet/meta/lib/util');
|
|
6
6
|
const getComponentProcessId = require('@blocklet/meta/lib/get-component-process-id');
|
|
7
7
|
const { EVENTS } = require('@abtnode/constant');
|
|
8
|
-
const { BlockletStatus
|
|
8
|
+
const { BlockletStatus } = require('@blocklet/constant');
|
|
9
9
|
const defaultLogger = require('@abtnode/logger')('blocklet-runtime-monitor');
|
|
10
10
|
|
|
11
11
|
const { getRuntimeInfo } = require('../util/blocklet');
|
|
@@ -109,7 +109,8 @@ class BlockletRuntimeMonitor extends EventEmitter {
|
|
|
109
109
|
await forEachBlocklet(
|
|
110
110
|
blocklet,
|
|
111
111
|
async (component, { id: componentId, ancestors }) => {
|
|
112
|
-
|
|
112
|
+
const { meta } = component;
|
|
113
|
+
if (!isGatewayBlocklet(meta) && hasStartEngine(meta) && component.status === BlockletStatus.running) {
|
|
113
114
|
const processId = getComponentProcessId(component, ancestors);
|
|
114
115
|
try {
|
|
115
116
|
const runtimeInfo = await getRuntimeInfo(processId);
|
package/lib/router/index.js
CHANGED
package/lib/router/manager.js
CHANGED
|
@@ -30,7 +30,7 @@ const {
|
|
|
30
30
|
BLOCKLET_INTERFACE_TYPE_WEB,
|
|
31
31
|
BlockletGroup,
|
|
32
32
|
} = require('@blocklet/constant');
|
|
33
|
-
const { forEachChildSync } = require('@blocklet/meta/lib/util');
|
|
33
|
+
const { forEachChildSync, hasStartEngine, isGatewayBlocklet } = require('@blocklet/meta/lib/util');
|
|
34
34
|
|
|
35
35
|
const {
|
|
36
36
|
validateAddSite,
|
|
@@ -625,7 +625,8 @@ class RouterManager extends EventEmitter {
|
|
|
625
625
|
}
|
|
626
626
|
|
|
627
627
|
forEachChildSync(blocklet, (component, { id, ancestors }) => {
|
|
628
|
-
|
|
628
|
+
const { meta } = component;
|
|
629
|
+
if (isGatewayBlocklet(meta) || !hasStartEngine(meta)) {
|
|
629
630
|
return;
|
|
630
631
|
}
|
|
631
632
|
|
package/lib/states/blocklet.js
CHANGED
|
@@ -249,6 +249,9 @@ class BlockletState extends BaseState {
|
|
|
249
249
|
const ports = await this.getBlockletPorts({ interfaces: sanitized.interfaces || [] });
|
|
250
250
|
const children = await this.fillChildrenPorts(rawChildren, { defaultPort: getMaxPort(ports) });
|
|
251
251
|
fixChildren(children);
|
|
252
|
+
children.forEach((x) => {
|
|
253
|
+
x.installedAt = new Date();
|
|
254
|
+
});
|
|
252
255
|
|
|
253
256
|
// add to db
|
|
254
257
|
doc = await this.insert({
|
|
@@ -646,6 +649,7 @@ class BlockletState extends BaseState {
|
|
|
646
649
|
mode,
|
|
647
650
|
status: BlockletStatus.added,
|
|
648
651
|
children: child.children,
|
|
652
|
+
installedAt: new Date(),
|
|
649
653
|
});
|
|
650
654
|
|
|
651
655
|
fixChildren(newChildren);
|
package/lib/util/blocklet.js
CHANGED
|
@@ -28,7 +28,6 @@ const sleep = require('@abtnode/util/lib/sleep');
|
|
|
28
28
|
const getPm2ProcessInfo = require('@abtnode/util/lib/get-pm2-process-info');
|
|
29
29
|
const { formatEnv } = require('@abtnode/util/lib/security');
|
|
30
30
|
const ensureEndpointHealthy = require('@abtnode/util/lib/ensure-endpoint-healthy');
|
|
31
|
-
const CustomError = require('@abtnode/util/lib/custom-error');
|
|
32
31
|
const getFolderSize = require('@abtnode/util/lib/get-folder-size');
|
|
33
32
|
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
34
33
|
const hashFiles = require('@abtnode/util/lib/hash-files');
|
|
@@ -51,6 +50,7 @@ const {
|
|
|
51
50
|
} = require('@blocklet/resolver');
|
|
52
51
|
const formatBackSlash = require('@abtnode/util/lib/format-back-slash');
|
|
53
52
|
const { isPortsOccupiedByOtherProcess, killProcessOccupiedPorts } = require('@abtnode/util/lib/port');
|
|
53
|
+
const { getComponentApiKey } = require('@abtnode/util/lib/blocklet');
|
|
54
54
|
const { toSvg: createDidLogo } =
|
|
55
55
|
process.env.NODE_ENV !== 'test' ? require('@arcblock/did-motif') : require('@arcblock/did-motif/dist/did-motif.cjs');
|
|
56
56
|
const { createBlockiesSvg } = require('@blocklet/meta/lib/blockies');
|
|
@@ -61,7 +61,6 @@ const {
|
|
|
61
61
|
BlockletStatus,
|
|
62
62
|
BlockletSource,
|
|
63
63
|
BlockletGroup,
|
|
64
|
-
BLOCKLET_GROUPS,
|
|
65
64
|
BLOCKLET_MODES,
|
|
66
65
|
BLOCKLET_BUNDLE_FILE,
|
|
67
66
|
BLOCKLET_ENTRY_FILE,
|
|
@@ -88,11 +87,12 @@ const {
|
|
|
88
87
|
getComponentName,
|
|
89
88
|
isEnvShareable,
|
|
90
89
|
getBlockletAppIdList,
|
|
91
|
-
isBeforeInstalled,
|
|
92
90
|
getChainInfo,
|
|
93
91
|
isInProgress,
|
|
94
92
|
isRunning,
|
|
93
|
+
hasStartEngine,
|
|
95
94
|
} = require('@blocklet/meta/lib/util');
|
|
95
|
+
const { getComponentsInternalInfo } = require('@blocklet/meta/lib/blocklet');
|
|
96
96
|
const { titleSchema, descriptionSchema, logoSchema } = require('@blocklet/meta/lib/schema');
|
|
97
97
|
const { getBlockletMetaFromUrl } = require('@blocklet/meta/lib/util-meta');
|
|
98
98
|
const getComponentProcessId = require('@blocklet/meta/lib/get-component-process-id');
|
|
@@ -141,47 +141,20 @@ const PRIVATE_NODE_ENVS = [
|
|
|
141
141
|
];
|
|
142
142
|
|
|
143
143
|
/**
|
|
144
|
-
* @returns { dataDir, logsDir, cacheDir,
|
|
144
|
+
* @returns { dataDir, logsDir, cacheDir, appDir }
|
|
145
145
|
* dataDir: dataDirs.data/name (root component) or dataDirs.data/name/childName (child component)
|
|
146
146
|
* logsDir: dataDirs.log/name
|
|
147
147
|
* cacheDir: dataDirs.cache/name (root component) or dataDirs.cache/name/childName (child component)
|
|
148
148
|
* appDir: component bundle dir
|
|
149
|
-
* mainDir: appDir (dapp) or appDir/main (static). Used for for static component
|
|
150
|
-
* appMain: app entry file or script (run appMain to start component process)
|
|
151
|
-
* appCwd: cwd of appMain
|
|
152
149
|
*/
|
|
153
|
-
const getComponentDirs = (
|
|
154
|
-
component,
|
|
155
|
-
{ dataDirs, ensure = false, e2eMode = false, validate = false, ancestors = [] } = {}
|
|
156
|
-
) => {
|
|
157
|
-
// FIXME 这个函数做了太多的事
|
|
158
|
-
// get data dirs
|
|
159
|
-
|
|
150
|
+
const getComponentDirs = (component, { dataDirs, ensure = false, ancestors = [] } = {}) => {
|
|
160
151
|
const componentName = getComponentName(component, ancestors);
|
|
161
152
|
|
|
162
153
|
const logsDir = path.join(dataDirs.logs, componentName);
|
|
163
154
|
const dataDir = path.join(dataDirs.data, componentName);
|
|
164
155
|
const cacheDir = path.join(dataDirs.cache, componentName);
|
|
165
156
|
|
|
166
|
-
// get app dirs
|
|
167
|
-
|
|
168
|
-
const { main, group } = component.meta;
|
|
169
|
-
|
|
170
|
-
let startFromDevEntry = '';
|
|
171
|
-
if (component.mode === BLOCKLET_MODES.DEVELOPMENT && component.meta.scripts) {
|
|
172
|
-
startFromDevEntry = component.meta.scripts.dev;
|
|
173
|
-
if (e2eMode && component.meta.scripts.e2eDev) {
|
|
174
|
-
startFromDevEntry = component.meta.scripts.e2eDev;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (validate && !main && !startFromDevEntry && group !== BlockletGroup.gateway) {
|
|
179
|
-
throw new Error('Incorrect blocklet.yml: missing `main` field');
|
|
180
|
-
}
|
|
181
|
-
|
|
182
157
|
let appDir = null;
|
|
183
|
-
let mainDir = null;
|
|
184
|
-
|
|
185
158
|
if (component.source === BlockletSource.local) {
|
|
186
159
|
appDir = component.deployedFrom;
|
|
187
160
|
} else {
|
|
@@ -203,37 +176,57 @@ const getComponentDirs = (
|
|
|
203
176
|
}
|
|
204
177
|
}
|
|
205
178
|
|
|
206
|
-
|
|
179
|
+
return { dataDir, logsDir, cacheDir, appDir };
|
|
180
|
+
};
|
|
207
181
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
182
|
+
/**
|
|
183
|
+
* @returns { cwd, script, args, environmentObj, interpreter, interpreterArgs }
|
|
184
|
+
*/
|
|
185
|
+
const getComponentStartEngine = (component, { e2eMode = false } = {}) => {
|
|
186
|
+
if (!hasStartEngine(component.meta)) {
|
|
187
|
+
return {};
|
|
214
188
|
}
|
|
215
189
|
|
|
216
|
-
|
|
217
|
-
|
|
190
|
+
const { appDir } = component.env;
|
|
191
|
+
|
|
192
|
+
const cwd = appDir;
|
|
193
|
+
|
|
194
|
+
// get app dirs
|
|
195
|
+
const { main, group } = component.meta;
|
|
196
|
+
|
|
197
|
+
let startFromDevEntry = '';
|
|
198
|
+
if (component.mode === BLOCKLET_MODES.DEVELOPMENT && component.meta.scripts) {
|
|
199
|
+
startFromDevEntry = component.meta.scripts.dev;
|
|
200
|
+
if (e2eMode && component.meta.scripts.e2eDev) {
|
|
201
|
+
startFromDevEntry = component.meta.scripts.e2eDev;
|
|
202
|
+
}
|
|
218
203
|
}
|
|
219
204
|
|
|
220
|
-
|
|
221
|
-
|
|
205
|
+
const blockletEngineInfo = getBlockletEngine(component.meta);
|
|
206
|
+
|
|
207
|
+
let script = null;
|
|
208
|
+
let interpreter = '';
|
|
209
|
+
let interpreterArgs = '';
|
|
210
|
+
const environmentObj = {};
|
|
211
|
+
let args = [];
|
|
212
|
+
|
|
222
213
|
if (startFromDevEntry) {
|
|
223
|
-
|
|
224
|
-
appCwd = appDir;
|
|
214
|
+
script = startFromDevEntry;
|
|
225
215
|
} else if (group === 'dapp') {
|
|
226
|
-
|
|
227
|
-
|
|
216
|
+
script = blockletEngineInfo.script || BLOCKLET_ENTRY_FILE;
|
|
217
|
+
args = blockletEngineInfo.args || [];
|
|
228
218
|
} else if (group === 'static') {
|
|
229
|
-
|
|
219
|
+
script = require.resolve('@abtnode/static-server');
|
|
220
|
+
environmentObj.BLOCKLET_MAIN_DIR = path.join(appDir, main);
|
|
221
|
+
}
|
|
230
222
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
223
|
+
if (component.mode !== BLOCKLET_MODES.DEVELOPMENT) {
|
|
224
|
+
const engine = getEngine(blockletEngineInfo.interpreter);
|
|
225
|
+
interpreter = engine.interpreter === 'node' ? '' : engine.interpreter;
|
|
226
|
+
interpreterArgs = engine.args || '';
|
|
234
227
|
}
|
|
235
228
|
|
|
236
|
-
return {
|
|
229
|
+
return { cwd, script, args, environmentObj, interpreter, interpreterArgs };
|
|
237
230
|
};
|
|
238
231
|
|
|
239
232
|
/**
|
|
@@ -372,7 +365,6 @@ const getComponentSystemEnvironments = (blocklet) => {
|
|
|
372
365
|
BLOCKLET_LOG_DIR: blocklet.env.logsDir,
|
|
373
366
|
BLOCKLET_CACHE_DIR: blocklet.env.cacheDir,
|
|
374
367
|
BLOCKLET_APP_DIR: blocklet.env.appDir,
|
|
375
|
-
BLOCKLET_MAIN_DIR: blocklet.env.mainDir,
|
|
376
368
|
...portEnvironments,
|
|
377
369
|
};
|
|
378
370
|
};
|
|
@@ -409,22 +401,7 @@ const getRuntimeEnvironments = (blocklet, nodeEnvironments, ancestors) => {
|
|
|
409
401
|
}
|
|
410
402
|
});
|
|
411
403
|
|
|
412
|
-
const
|
|
413
|
-
for (const x of root.children || []) {
|
|
414
|
-
const mountPoint = {
|
|
415
|
-
title: x.meta.title,
|
|
416
|
-
did: x.meta.bundleDid,
|
|
417
|
-
name: x.meta.bundleName,
|
|
418
|
-
mountPoint: x.mountPoint || '',
|
|
419
|
-
};
|
|
420
|
-
|
|
421
|
-
const webInterface = findWebInterface(x);
|
|
422
|
-
if (webInterface && x.environmentObj[webInterface.port]) {
|
|
423
|
-
mountPoint.port = x.environmentObj[webInterface.port];
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
mountPoints.push(mountPoint);
|
|
427
|
-
}
|
|
404
|
+
const componentsInternalInfo = getComponentsInternalInfo(root);
|
|
428
405
|
|
|
429
406
|
// use index 1 as the path to derive deterministic encryption key for blocklet
|
|
430
407
|
const tmp = get(nodeEnvironments, 'ABT_NODE_SK')
|
|
@@ -433,17 +410,24 @@ const getRuntimeEnvironments = (blocklet, nodeEnvironments, ancestors) => {
|
|
|
433
410
|
|
|
434
411
|
const BLOCKLET_APP_IDS = getBlockletAppIdList(root).join(',');
|
|
435
412
|
|
|
413
|
+
const componentApiKey = getComponentApiKey({
|
|
414
|
+
serverSk: nodeEnvironments.ABT_NODE_SK,
|
|
415
|
+
app: root,
|
|
416
|
+
component: blocklet,
|
|
417
|
+
});
|
|
418
|
+
|
|
436
419
|
const env = {
|
|
437
420
|
...blocklet.configObj,
|
|
438
421
|
...getSharedConfigObj(blocklet, ancestors),
|
|
439
422
|
...blocklet.environmentObj,
|
|
440
423
|
...devEnvironments,
|
|
441
424
|
BLOCKLET_WEB_PORTS: JSON.stringify(ports),
|
|
442
|
-
BLOCKLET_MOUNT_POINTS: JSON.stringify(
|
|
425
|
+
BLOCKLET_MOUNT_POINTS: JSON.stringify(componentsInternalInfo),
|
|
443
426
|
BLOCKLET_MODE: blocklet.mode || BLOCKLET_MODES.PRODUCTION,
|
|
444
427
|
BLOCKLET_APP_EK: tmp?.secretKey,
|
|
445
428
|
BLOCKLET_APP_VERSION: root.meta.version,
|
|
446
429
|
BLOCKLET_APP_IDS,
|
|
430
|
+
BLOCKLET_COMPONENT_API_KEY: componentApiKey,
|
|
447
431
|
...nodeEnvironments,
|
|
448
432
|
...safeNodeEnvironments,
|
|
449
433
|
};
|
|
@@ -513,6 +497,8 @@ const startBlockletProcess = async (
|
|
|
513
497
|
throw new Error('blocklet should not be empty');
|
|
514
498
|
}
|
|
515
499
|
|
|
500
|
+
const now = Date.now();
|
|
501
|
+
|
|
516
502
|
await forEachBlocklet(
|
|
517
503
|
blocklet,
|
|
518
504
|
async (b, { ancestors }) => {
|
|
@@ -520,7 +506,11 @@ const startBlockletProcess = async (
|
|
|
520
506
|
return;
|
|
521
507
|
}
|
|
522
508
|
|
|
523
|
-
|
|
509
|
+
if (!hasStartEngine(b.meta)) {
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
const { processId, logsDir, appDir } = b.env;
|
|
524
514
|
|
|
525
515
|
if (skippedProcessIds.includes(processId)) {
|
|
526
516
|
logger.info(`skip start skipped process ${processId}`);
|
|
@@ -532,6 +522,14 @@ const startBlockletProcess = async (
|
|
|
532
522
|
return;
|
|
533
523
|
}
|
|
534
524
|
|
|
525
|
+
if (b.mode !== BLOCKLET_MODES.DEVELOPMENT) {
|
|
526
|
+
validateBlockletEntry(appDir, b.meta);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
const { cwd, script, args, environmentObj, interpreter, interpreterArgs } = getComponentStartEngine(b, {
|
|
530
|
+
e2eMode,
|
|
531
|
+
});
|
|
532
|
+
|
|
535
533
|
// get env
|
|
536
534
|
const env = getRuntimeEnvironments(b, nodeEnvironments, ancestors);
|
|
537
535
|
const startedAt = Date.now();
|
|
@@ -553,7 +551,7 @@ const startBlockletProcess = async (
|
|
|
553
551
|
const options = {
|
|
554
552
|
namespace: 'blocklets',
|
|
555
553
|
name: processId,
|
|
556
|
-
cwd
|
|
554
|
+
cwd,
|
|
557
555
|
// FIXME @linchen [] does not work, so use () here
|
|
558
556
|
log_date_format: '(YYYY-MM-DD HH:mm:ss)',
|
|
559
557
|
output: path.join(logsDir, 'output.log'),
|
|
@@ -563,9 +561,15 @@ const startBlockletProcess = async (
|
|
|
563
561
|
max_memory_restart: `${maxMemoryRestart}M`,
|
|
564
562
|
max_restarts: b.mode === BLOCKLET_MODES.DEVELOPMENT ? 0 : 3,
|
|
565
563
|
env: {
|
|
564
|
+
...environmentObj,
|
|
566
565
|
...env,
|
|
567
566
|
NODE_ENV: 'production',
|
|
567
|
+
BLOCKLET_START_AT: now,
|
|
568
568
|
},
|
|
569
|
+
script,
|
|
570
|
+
args,
|
|
571
|
+
interpreter,
|
|
572
|
+
interpreterArgs,
|
|
569
573
|
};
|
|
570
574
|
|
|
571
575
|
const clusterMode = get(b.meta, 'capabilities.clusterMode', false);
|
|
@@ -580,10 +584,9 @@ const startBlockletProcess = async (
|
|
|
580
584
|
options.env.NODE_ENV = e2eMode ? 'e2e' : 'development';
|
|
581
585
|
options.env.BROWSER = 'none';
|
|
582
586
|
options.env.PORT = options.env[BLOCKLET_DEFAULT_PORT_NAME];
|
|
583
|
-
options.script = appMain;
|
|
584
587
|
|
|
585
588
|
if (process.platform === 'win32') {
|
|
586
|
-
const [cmd, ...
|
|
589
|
+
const [cmd, ...argList] = options.script.split(' ').filter(Boolean);
|
|
587
590
|
|
|
588
591
|
if (!SCRIPT_ENGINES_WHITE_LIST.includes(cmd)) {
|
|
589
592
|
throw new Error(`${cmd} script is not supported, ${SCRIPT_ENGINES_WHITE_LIST.join(', ')} are supported`);
|
|
@@ -597,16 +600,8 @@ const startBlockletProcess = async (
|
|
|
597
600
|
const cmdBinPath = pkg.bin[cmd];
|
|
598
601
|
|
|
599
602
|
options.script = path.resolve(cmdPath, cmdBinPath);
|
|
600
|
-
options.args = [...
|
|
603
|
+
options.args = [...argList].join(' ');
|
|
601
604
|
}
|
|
602
|
-
} else {
|
|
603
|
-
const blockletEngineInfo = getBlockletEngine(b.meta);
|
|
604
|
-
options.args = blockletEngineInfo.args || [];
|
|
605
|
-
|
|
606
|
-
const engine = getEngine(blockletEngineInfo.interpreter);
|
|
607
|
-
options.interpreter = engine.interpreter === 'node' ? '' : engine.interpreter;
|
|
608
|
-
options.interpreterArgs = engine.args || '';
|
|
609
|
-
options.script = blockletEngineInfo.script || appMain;
|
|
610
605
|
}
|
|
611
606
|
|
|
612
607
|
await pm2.startAsync(options);
|
|
@@ -657,6 +652,10 @@ const deleteBlockletProcess = async (blocklet, { preDelete = noop, skippedProces
|
|
|
657
652
|
return;
|
|
658
653
|
}
|
|
659
654
|
|
|
655
|
+
if (!hasStartEngine(b.meta)) {
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
|
|
660
659
|
await preDelete(b, { ancestors });
|
|
661
660
|
await deleteProcess(b.env.processId);
|
|
662
661
|
},
|
|
@@ -732,7 +731,7 @@ const reloadProcess = (processId) =>
|
|
|
732
731
|
});
|
|
733
732
|
|
|
734
733
|
const validateBlocklet = (blocklet) =>
|
|
735
|
-
|
|
734
|
+
forEachComponentV2(blocklet, (b) => {
|
|
736
735
|
isRequirementsSatisfied(b.meta.requirements);
|
|
737
736
|
validateEngine(getBlockletEngineNameByPlatform(b.meta));
|
|
738
737
|
});
|
|
@@ -760,6 +759,10 @@ const checkBlockletProcessHealthy = async (blocklet, { minConsecutiveTime, timeo
|
|
|
760
759
|
return;
|
|
761
760
|
}
|
|
762
761
|
|
|
762
|
+
if (!hasStartEngine(b.meta)) {
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
|
|
763
766
|
if (shouldSkipComponent(b.meta.did, componentDids)) {
|
|
764
767
|
logger.info('skip check component healthy not selected', { id: b.env.id, processId: b.env.processId });
|
|
765
768
|
return;
|
|
@@ -1270,7 +1273,6 @@ const getBlocklet = async ({
|
|
|
1270
1273
|
...getComponentDirs(component, {
|
|
1271
1274
|
dataDirs,
|
|
1272
1275
|
ensure: ensureIntegrity,
|
|
1273
|
-
validate: ensureIntegrity,
|
|
1274
1276
|
ancestors,
|
|
1275
1277
|
e2eMode: level === 0 ? e2eMode : false,
|
|
1276
1278
|
}),
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.15-beta-
|
|
6
|
+
"version": "1.16.15-beta-9318a201",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,19 +19,19 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/analytics": "1.16.15-beta-
|
|
23
|
-
"@abtnode/auth": "1.16.15-beta-
|
|
24
|
-
"@abtnode/certificate-manager": "1.16.15-beta-
|
|
25
|
-
"@abtnode/constant": "1.16.15-beta-
|
|
26
|
-
"@abtnode/cron": "1.16.15-beta-
|
|
27
|
-
"@abtnode/logger": "1.16.15-beta-
|
|
28
|
-
"@abtnode/models": "1.16.15-beta-
|
|
29
|
-
"@abtnode/queue": "1.16.15-beta-
|
|
30
|
-
"@abtnode/rbac": "1.16.15-beta-
|
|
31
|
-
"@abtnode/router-provider": "1.16.15-beta-
|
|
32
|
-
"@abtnode/static-server": "1.16.15-beta-
|
|
33
|
-
"@abtnode/timemachine": "1.16.15-beta-
|
|
34
|
-
"@abtnode/util": "1.16.15-beta-
|
|
22
|
+
"@abtnode/analytics": "1.16.15-beta-9318a201",
|
|
23
|
+
"@abtnode/auth": "1.16.15-beta-9318a201",
|
|
24
|
+
"@abtnode/certificate-manager": "1.16.15-beta-9318a201",
|
|
25
|
+
"@abtnode/constant": "1.16.15-beta-9318a201",
|
|
26
|
+
"@abtnode/cron": "1.16.15-beta-9318a201",
|
|
27
|
+
"@abtnode/logger": "1.16.15-beta-9318a201",
|
|
28
|
+
"@abtnode/models": "1.16.15-beta-9318a201",
|
|
29
|
+
"@abtnode/queue": "1.16.15-beta-9318a201",
|
|
30
|
+
"@abtnode/rbac": "1.16.15-beta-9318a201",
|
|
31
|
+
"@abtnode/router-provider": "1.16.15-beta-9318a201",
|
|
32
|
+
"@abtnode/static-server": "1.16.15-beta-9318a201",
|
|
33
|
+
"@abtnode/timemachine": "1.16.15-beta-9318a201",
|
|
34
|
+
"@abtnode/util": "1.16.15-beta-9318a201",
|
|
35
35
|
"@arcblock/did": "1.18.89",
|
|
36
36
|
"@arcblock/did-auth": "1.18.89",
|
|
37
37
|
"@arcblock/did-ext": "^1.18.89",
|
|
@@ -42,11 +42,11 @@
|
|
|
42
42
|
"@arcblock/pm2-events": "^0.0.5",
|
|
43
43
|
"@arcblock/validator": "^1.18.89",
|
|
44
44
|
"@arcblock/vc": "1.18.89",
|
|
45
|
-
"@blocklet/constant": "1.16.15-beta-
|
|
46
|
-
"@blocklet/meta": "1.16.15-beta-
|
|
47
|
-
"@blocklet/resolver": "1.16.15-beta-
|
|
48
|
-
"@blocklet/sdk": "1.16.15-beta-
|
|
49
|
-
"@did-space/client": "^0.2.
|
|
45
|
+
"@blocklet/constant": "1.16.15-beta-9318a201",
|
|
46
|
+
"@blocklet/meta": "1.16.15-beta-9318a201",
|
|
47
|
+
"@blocklet/resolver": "1.16.15-beta-9318a201",
|
|
48
|
+
"@blocklet/sdk": "1.16.15-beta-9318a201",
|
|
49
|
+
"@did-space/client": "^0.2.163",
|
|
50
50
|
"@fidm/x509": "^1.2.1",
|
|
51
51
|
"@ocap/mcrypto": "1.18.89",
|
|
52
52
|
"@ocap/util": "1.18.89",
|
|
@@ -98,5 +98,5 @@
|
|
|
98
98
|
"jest": "^27.5.1",
|
|
99
99
|
"unzipper": "^0.10.11"
|
|
100
100
|
},
|
|
101
|
-
"gitHead": "
|
|
101
|
+
"gitHead": "f3722cbd4fe10c5fa083cad7e859ecff6095060d"
|
|
102
102
|
}
|