@abtnode/core 1.8.68-beta-500af7e5 → 1.8.68
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/bundle-downloader.js +1 -6
- package/lib/blocklet/manager/disk.js +64 -158
- package/lib/blocklet/manager/helper/install-from-backup.js +4 -4
- package/lib/blocklet/storage/backup/blocklet-extras.js +19 -15
- package/lib/blocklet/storage/backup/spaces.js +11 -39
- package/lib/blocklet/storage/restore/base.js +9 -10
- package/lib/blocklet/storage/restore/blocklet-extras.js +16 -21
- package/lib/blocklet/storage/restore/blocklets.js +2 -5
- package/lib/blocklet/storage/restore/spaces.js +38 -45
- package/lib/event.js +2 -18
- package/lib/index.js +3 -21
- package/lib/router/helper.js +5 -7
- package/lib/router/index.js +0 -31
- package/lib/states/audit-log.js +3 -5
- package/lib/states/blocklet.js +5 -21
- package/lib/states/node.js +2 -5
- package/lib/util/blocklet.js +19 -111
- package/lib/util/index.js +0 -24
- package/lib/validators/node.js +0 -1
- package/lib/webhook/index.js +1 -1
- package/package.json +27 -26
- /package/lib/{util/queue.js → queue.js} +0 -0
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @typedef {{
|
|
3
|
-
* did
|
|
4
|
-
* event: import('events').EventEmitter,
|
|
5
|
-
* userDid: string,
|
|
6
|
-
* referrer: string,
|
|
3
|
+
* did?: string
|
|
7
4
|
* }} SpaceBackupInput
|
|
8
5
|
*/
|
|
9
6
|
|
|
10
7
|
const { isValid } = require('@arcblock/did');
|
|
11
|
-
const { BLOCKLET_CONFIGURABLE_KEY
|
|
8
|
+
const { BLOCKLET_CONFIGURABLE_KEY } = require('@blocklet/constant');
|
|
12
9
|
const { getBlockletInfo } = require('@blocklet/meta');
|
|
13
|
-
const { SpaceClient,
|
|
10
|
+
const { SpaceClient, SyncFolderPushCommand } = require('@did-space/client');
|
|
14
11
|
const { ensureDirSync } = require('fs-extra');
|
|
15
12
|
const { isEmpty } = require('lodash');
|
|
16
|
-
const { join
|
|
17
|
-
|
|
18
|
-
const logger = require('@abtnode/logger')('@abtnode/core:storage:backup');
|
|
19
|
-
|
|
13
|
+
const { join } = require('path');
|
|
20
14
|
const states = require('../../../states');
|
|
21
15
|
const { AuditLogBackup } = require('./audit-log');
|
|
22
16
|
const { BlockletBackup } = require('./blocklet');
|
|
@@ -137,22 +131,12 @@ class SpacesBackup {
|
|
|
137
131
|
}
|
|
138
132
|
|
|
139
133
|
async export() {
|
|
140
|
-
this.input.event.emit(BlockletEvents.backupProgress, {
|
|
141
|
-
did: this.input.did,
|
|
142
|
-
message: 'Preparing data for backup...',
|
|
143
|
-
progress: 15,
|
|
144
|
-
});
|
|
145
134
|
await Promise.all(
|
|
146
135
|
this.storages.map((storage) => {
|
|
147
136
|
storage.ensureParams(this);
|
|
148
137
|
return storage.export();
|
|
149
138
|
})
|
|
150
139
|
);
|
|
151
|
-
this.input.event.emit(BlockletEvents.backupProgress, {
|
|
152
|
-
did: this.input.did,
|
|
153
|
-
message: 'Data ready, start backup...',
|
|
154
|
-
progress: 20,
|
|
155
|
-
});
|
|
156
140
|
}
|
|
157
141
|
|
|
158
142
|
async syncToSpaces() {
|
|
@@ -162,34 +146,22 @@ class SpacesBackup {
|
|
|
162
146
|
wallet,
|
|
163
147
|
});
|
|
164
148
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
149
|
+
// FIXME: 在 Spaces 里面预览出 blocklet 的样式,需要规划一个好的数据结构
|
|
150
|
+
const { errorCount } = await spaceClient.send(
|
|
151
|
+
new SyncFolderPushCommand({
|
|
168
152
|
source: join(this.blockletBackupDir, '/'),
|
|
153
|
+
target: join('.did-objects', this.blocklet.appDid),
|
|
169
154
|
debug: true,
|
|
170
|
-
concurrency:
|
|
171
|
-
retryCount:
|
|
155
|
+
concurrency: 64,
|
|
156
|
+
retryCount: 100,
|
|
172
157
|
filter: (object) => {
|
|
173
|
-
// FIXME: @yejianchao 这里需要更完整的黑名单
|
|
174
158
|
return object.name !== '.DS_Store';
|
|
175
159
|
},
|
|
176
|
-
onProgress: (data) => {
|
|
177
|
-
logger.info('backup progress', { appDid: this.input.did, data });
|
|
178
|
-
const percent = (data.completed * 100) / data.total;
|
|
179
|
-
this.input.event.emit(BlockletEvents.backupProgress, {
|
|
180
|
-
did: this.input.did,
|
|
181
|
-
message: `Uploaded file ${basename(data.key)} (${data.completed}/${data.total})`,
|
|
182
|
-
// 0.8 是因为上传文件到 spaces 占进度的 80%,+ 20 是因为需要累加之前的进度
|
|
183
|
-
progress: +Math.ceil(percent * 0.8).toFixed(2) + 20,
|
|
184
|
-
});
|
|
185
|
-
},
|
|
186
|
-
userDid: this.input.userDid,
|
|
187
|
-
referrer: this.input.referrer,
|
|
188
160
|
})
|
|
189
161
|
);
|
|
190
162
|
|
|
191
163
|
if (errorCount !== 0) {
|
|
192
|
-
throw new Error(`Sync to spaces encountered ${errorCount} error
|
|
164
|
+
throw new Error(`Sync to spaces encountered ${errorCount} error`);
|
|
193
165
|
}
|
|
194
166
|
}
|
|
195
167
|
|
|
@@ -13,6 +13,14 @@ class BaseRestore {
|
|
|
13
13
|
*/
|
|
14
14
|
blockletRestoreDir;
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* @description spaces 的 endpoint
|
|
19
|
+
* @type {import('@ocap/wallet').WalletObject}
|
|
20
|
+
* @memberof BaseRestore
|
|
21
|
+
*/
|
|
22
|
+
blockletWallet;
|
|
23
|
+
|
|
16
24
|
/**
|
|
17
25
|
*
|
|
18
26
|
* @description server 的数据目录
|
|
@@ -33,22 +41,13 @@ class BaseRestore {
|
|
|
33
41
|
*/
|
|
34
42
|
ensureParams(spaces) {
|
|
35
43
|
this.blockletRestoreDir = spaces.blockletRestoreDir;
|
|
44
|
+
this.blockletWallet = spaces.blockletWallet;
|
|
36
45
|
this.serverDataDir = spaces.serverDataDir;
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
async import() {
|
|
40
49
|
throw new Error('not implemented');
|
|
41
50
|
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Generate params for BlockletManager to install
|
|
45
|
-
*
|
|
46
|
-
* @return {object}
|
|
47
|
-
* @memberof BaseRestore
|
|
48
|
-
*/
|
|
49
|
-
getInstallParams() {
|
|
50
|
-
return {};
|
|
51
|
-
}
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
module.exports = {
|
|
@@ -2,7 +2,6 @@ const { removeSync, outputJsonSync, readJSONSync } = require('fs-extra');
|
|
|
2
2
|
const { cloneDeep, isArray } = require('lodash');
|
|
3
3
|
const { join } = require('path');
|
|
4
4
|
const security = require('@abtnode/util/lib/security');
|
|
5
|
-
const { BLOCKLET_CONFIGURABLE_KEY } = require('@blocklet/constant');
|
|
6
5
|
const { BaseRestore } = require('./base');
|
|
7
6
|
|
|
8
7
|
class BlockletExtrasRestore extends BaseRestore {
|
|
@@ -25,6 +24,7 @@ class BlockletExtrasRestore extends BaseRestore {
|
|
|
25
24
|
* @type {import('@abtnode/client').BlockletState}
|
|
26
25
|
*/
|
|
27
26
|
const blockletExtra = readJSONSync(join(this.blockletRestoreDir, this.filename));
|
|
27
|
+
|
|
28
28
|
return this.cleanData(blockletExtra);
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -32,6 +32,7 @@ class BlockletExtrasRestore extends BaseRestore {
|
|
|
32
32
|
*
|
|
33
33
|
* @description 清理数据并加密
|
|
34
34
|
* @param {import('@abtnode/client').BlockletState} blockletExtraInput
|
|
35
|
+
* @return {Promise<void>}
|
|
35
36
|
* @memberof BlockletExtrasRestore
|
|
36
37
|
*/
|
|
37
38
|
async cleanData(blockletExtraInput) {
|
|
@@ -42,7 +43,7 @@ class BlockletExtrasRestore extends BaseRestore {
|
|
|
42
43
|
const currentBlockletExtra = queue.pop();
|
|
43
44
|
|
|
44
45
|
// 加解密
|
|
45
|
-
this.
|
|
46
|
+
this.useBlockletDecryptConfigs(currentBlockletExtra.configs);
|
|
46
47
|
|
|
47
48
|
if (currentBlockletExtra?.children) {
|
|
48
49
|
queue.push(...currentBlockletExtra.children);
|
|
@@ -54,37 +55,31 @@ class BlockletExtrasRestore extends BaseRestore {
|
|
|
54
55
|
|
|
55
56
|
/**
|
|
56
57
|
*
|
|
57
|
-
* @description
|
|
58
|
+
* @description 清理数据并加密
|
|
58
59
|
* @param {import('@abtnode/client').ConfigEntry[]} configs
|
|
59
60
|
* @return {void}
|
|
60
61
|
* @memberof BlockletExtrasRestore
|
|
61
62
|
*/
|
|
62
|
-
|
|
63
|
+
useBlockletDecryptConfigs(configs) {
|
|
63
64
|
if (!configs || !isArray(configs)) {
|
|
64
65
|
return;
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
const { appDid, password } = this.input;
|
|
68
68
|
for (const config of configs) {
|
|
69
|
+
// secure 为 true 的配置才需要被加密保存上次到 did spaces
|
|
69
70
|
if (config.secure) {
|
|
70
|
-
const
|
|
71
|
-
const decrypted = security.decrypt(encrypted, appDid, Buffer.from(password));
|
|
72
|
-
config.value = decrypted;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
71
|
+
const encryptByBlocklet = config.value;
|
|
75
72
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
// 再用 blocklet secret 加密,然后才可以上传到 spaces
|
|
74
|
+
const decryptByBlocklet = security.decrypt(
|
|
75
|
+
encryptByBlocklet,
|
|
76
|
+
this.blockletWallet.address,
|
|
77
|
+
Buffer.from(this.blockletWallet.secretKey)
|
|
78
|
+
);
|
|
80
79
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
getInstallParams() {
|
|
85
|
-
return {
|
|
86
|
-
appSk: this.appSk,
|
|
87
|
-
};
|
|
80
|
+
config.value = decryptByBlocklet;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
88
83
|
}
|
|
89
84
|
}
|
|
90
85
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { existsSync, remove
|
|
1
|
+
const { existsSync, remove } = require('fs-extra');
|
|
2
2
|
const { join } = require('path');
|
|
3
3
|
const fg = require('fast-glob');
|
|
4
4
|
const { BaseRestore } = require('./base');
|
|
@@ -10,11 +10,8 @@ class BlockletsRestore extends BaseRestore {
|
|
|
10
10
|
async import() {
|
|
11
11
|
const blockletsDir = join(this.blockletRestoreDir, this.filename);
|
|
12
12
|
|
|
13
|
-
// blockletsDir 可以不存在, 因为还原的 blocklet 可能所有的组件都是来自 store 的
|
|
14
13
|
if (!existsSync(blockletsDir)) {
|
|
15
|
-
|
|
16
|
-
ensureDirSync(blockletsDir);
|
|
17
|
-
return;
|
|
14
|
+
throw new Error(`dir not found: ${blockletsDir}`);
|
|
18
15
|
}
|
|
19
16
|
|
|
20
17
|
const paths = await fg('**/*.zip', {
|
|
@@ -1,24 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @typedef {{
|
|
3
|
-
* appDid: string;
|
|
4
3
|
* endpoint: string;
|
|
5
|
-
*
|
|
6
|
-
* delegation: string;
|
|
7
|
-
* wallet: import('@ocap/wallet').WalletObject;
|
|
8
|
-
* event: import('events').EventEmitter,
|
|
9
|
-
* userDid: string,
|
|
10
|
-
* referrer: string,
|
|
4
|
+
* blockletSecretKey: string;
|
|
11
5
|
* }} SpaceRestoreInput
|
|
12
6
|
*/
|
|
13
7
|
|
|
14
|
-
const
|
|
15
|
-
const {
|
|
16
|
-
const {
|
|
8
|
+
const { SpaceClient, SyncFolderPullCommand } = require('@did-space/client');
|
|
9
|
+
const { types } = require('@ocap/mcrypto');
|
|
10
|
+
const { fromSecretKey, WalletType } = require('@ocap/wallet');
|
|
17
11
|
const { ensureDirSync, existsSync, rmdirSync } = require('fs-extra');
|
|
18
|
-
const { join
|
|
19
|
-
|
|
20
|
-
const logger = require('@abtnode/logger')('@abtnode/core:storage:restore');
|
|
21
|
-
|
|
12
|
+
const { join } = require('path');
|
|
13
|
+
const validUrl = require('valid-url');
|
|
22
14
|
const { BlockletExtrasRestore } = require('./blocklet-extras');
|
|
23
15
|
const { BlockletsRestore } = require('./blocklets');
|
|
24
16
|
|
|
@@ -45,6 +37,14 @@ class SpacesRestore {
|
|
|
45
37
|
*/
|
|
46
38
|
serverDataDir;
|
|
47
39
|
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
* @description spaces 的 endpoint
|
|
43
|
+
* @type {import('@ocap/wallet').WalletObject}
|
|
44
|
+
* @memberof SpacesRestore
|
|
45
|
+
*/
|
|
46
|
+
blockletWallet;
|
|
47
|
+
|
|
48
48
|
storages;
|
|
49
49
|
|
|
50
50
|
/**
|
|
@@ -72,75 +72,68 @@ class SpacesRestore {
|
|
|
72
72
|
|
|
73
73
|
async initialize() {
|
|
74
74
|
this.serverDataDir = process.env.ABT_NODE_DATA_DIR;
|
|
75
|
+
this.blockletWallet = await this.getBlockletWallet();
|
|
75
76
|
|
|
76
|
-
if (!this.input.endpoint.includes(this.
|
|
77
|
-
throw new Error(`endpoint and blocklet.appDid(${this.
|
|
77
|
+
if (!this.input.endpoint.includes(this.blockletWallet.address)) {
|
|
78
|
+
throw new Error(`endpoint and blocklet.appDid(${this.blockletWallet.address}) do not match`);
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
this.blockletRestoreDir = join(process.env.ABT_NODE_DATA_DIR, 'tmp/restore', this.
|
|
81
|
+
this.blockletRestoreDir = join(process.env.ABT_NODE_DATA_DIR, 'tmp/restore', this.blockletWallet.address);
|
|
81
82
|
if (existsSync(this.blockletRestoreDir)) {
|
|
82
83
|
rmdirSync(this.blockletRestoreDir, { recursive: true });
|
|
83
84
|
}
|
|
84
85
|
ensureDirSync(this.blockletRestoreDir);
|
|
85
86
|
}
|
|
86
87
|
|
|
88
|
+
/**
|
|
89
|
+
*
|
|
90
|
+
* @returns {Promise<void>}
|
|
91
|
+
* @memberof SpacesRestore
|
|
92
|
+
*/
|
|
87
93
|
async restore() {
|
|
88
94
|
await this.initialize();
|
|
89
95
|
await this.syncFromSpaces();
|
|
90
96
|
await this.import();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async getBlockletWallet() {
|
|
100
|
+
// @FIXME: blocklet 钱包类型如何得知呢?
|
|
101
|
+
const wallet = fromSecretKey(this.input.blockletSecretKey, WalletType({ role: types.RoleType.ROLE_APPLICATION }));
|
|
91
102
|
|
|
92
|
-
return
|
|
103
|
+
return wallet;
|
|
93
104
|
}
|
|
94
105
|
|
|
95
106
|
async syncFromSpaces() {
|
|
96
|
-
const { endpoint
|
|
107
|
+
const { endpoint } = this.input;
|
|
108
|
+
const wallet = await this.getBlockletWallet();
|
|
97
109
|
|
|
98
110
|
const spaceClient = new SpaceClient({
|
|
99
111
|
endpoint,
|
|
100
|
-
delegation,
|
|
101
112
|
wallet,
|
|
102
113
|
});
|
|
103
114
|
|
|
104
|
-
const { errorCount
|
|
105
|
-
new
|
|
106
|
-
|
|
107
|
-
target:
|
|
115
|
+
const { errorCount } = await spaceClient.send(
|
|
116
|
+
new SyncFolderPullCommand({
|
|
117
|
+
source: join('.did-objects', this.blockletWallet.address, '/'),
|
|
118
|
+
target: this.blockletRestoreDir,
|
|
108
119
|
debug: true,
|
|
109
|
-
concurrency:
|
|
110
|
-
retryCount:
|
|
111
|
-
onProgress: (data) => {
|
|
112
|
-
logger.info('restore progress', { appDid: this.input.appDid, data });
|
|
113
|
-
this.input.event.emit(BlockletEvents.restoreProgress, {
|
|
114
|
-
did: this.input.appDid,
|
|
115
|
-
message: `Downloaded file ${basename(data.key)} (${data.completed}/${data.total})`,
|
|
116
|
-
});
|
|
117
|
-
},
|
|
118
|
-
|
|
119
|
-
userDid: this.input.userDid,
|
|
120
|
-
referrer: this.input.referrer,
|
|
120
|
+
concurrency: 64,
|
|
121
|
+
retryCount: 100,
|
|
121
122
|
})
|
|
122
123
|
);
|
|
123
124
|
|
|
124
125
|
if (errorCount !== 0) {
|
|
125
|
-
throw new Error(`Sync from spaces encountered ${errorCount} error
|
|
126
|
+
throw new Error(`Sync from spaces encountered ${errorCount} error`);
|
|
126
127
|
}
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
async import() {
|
|
130
|
-
this.input.event.emit(BlockletEvents.restoreProgress, {
|
|
131
|
-
did: this.input.appDid,
|
|
132
|
-
message: 'Preparing to import data...',
|
|
133
|
-
});
|
|
134
131
|
await Promise.all(
|
|
135
132
|
this.storages.map((storage) => {
|
|
136
133
|
storage.ensureParams(this);
|
|
137
134
|
return storage.import();
|
|
138
135
|
})
|
|
139
136
|
);
|
|
140
|
-
this.input.event.emit(BlockletEvents.restoreProgress, {
|
|
141
|
-
did: this.input.appDid,
|
|
142
|
-
message: 'Importing data successfully...',
|
|
143
|
-
});
|
|
144
137
|
}
|
|
145
138
|
}
|
|
146
139
|
|
package/lib/event.js
CHANGED
|
@@ -81,7 +81,7 @@ module.exports = ({
|
|
|
81
81
|
}
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
const
|
|
84
|
+
const handleBlockletAdd = async (name, { blocklet, context }) => {
|
|
85
85
|
try {
|
|
86
86
|
const changed = await ensureBlockletRouting(blocklet, context);
|
|
87
87
|
if (changed) {
|
|
@@ -169,17 +169,11 @@ module.exports = ({
|
|
|
169
169
|
});
|
|
170
170
|
};
|
|
171
171
|
|
|
172
|
-
/**
|
|
173
|
-
*
|
|
174
|
-
* @description 事件必须注册在这里才能被发布出去
|
|
175
|
-
* @param {string} eventName
|
|
176
|
-
* @param {any} payload
|
|
177
|
-
*/
|
|
178
172
|
const handleBlockletEvent = async (eventName, payload) => {
|
|
179
173
|
const blocklet = payload.blocklet || payload;
|
|
180
174
|
|
|
181
175
|
if ([BlockletEvents.installed].includes(eventName)) {
|
|
182
|
-
await
|
|
176
|
+
await handleBlockletAdd(eventName, payload);
|
|
183
177
|
|
|
184
178
|
try {
|
|
185
179
|
await node.createAuditLog({
|
|
@@ -279,13 +273,6 @@ module.exports = ({
|
|
|
279
273
|
}
|
|
280
274
|
};
|
|
281
275
|
|
|
282
|
-
/**
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
* @param {*} subject
|
|
286
|
-
* @param {string} event
|
|
287
|
-
* @param {(event: string, data: any) => Promise<void> | void} handler
|
|
288
|
-
*/
|
|
289
276
|
const listen = (subject, event, handler) => subject.on(event, (data) => handler(event, data));
|
|
290
277
|
|
|
291
278
|
[
|
|
@@ -304,9 +291,6 @@ module.exports = ({
|
|
|
304
291
|
BlockletEvents.startFailed,
|
|
305
292
|
BlockletEvents.stopped,
|
|
306
293
|
BlockletEvents.appDidChanged,
|
|
307
|
-
|
|
308
|
-
BlockletEvents.backupProgress,
|
|
309
|
-
BlockletEvents.restoreProgress,
|
|
310
294
|
].forEach((eventName) => {
|
|
311
295
|
listen(blockletManager, eventName, handleBlockletEvent);
|
|
312
296
|
});
|
package/lib/index.js
CHANGED
|
@@ -26,7 +26,7 @@ const Maintain = require('./util/maintain');
|
|
|
26
26
|
const resetNode = require('./util/reset-node');
|
|
27
27
|
const DiskMonitor = require('./util/disk-monitor');
|
|
28
28
|
const StoreUtil = require('./util/store');
|
|
29
|
-
const createQueue = require('./
|
|
29
|
+
const createQueue = require('./queue');
|
|
30
30
|
const createEvents = require('./event');
|
|
31
31
|
const pm2Events = require('./blocklet/manager/pm2-events');
|
|
32
32
|
const { createStateReadyQueue, createStateReadyHandler } = require('./util/ready');
|
|
@@ -99,25 +99,7 @@ function ABTNode(options) {
|
|
|
99
99
|
concurrency,
|
|
100
100
|
maxRetries: 3,
|
|
101
101
|
retryDelay: 5000, // retry after 5 seconds
|
|
102
|
-
maxTimeout: 60 * 1000 * 15, // throw timeout error after
|
|
103
|
-
id: (job) => (job ? md5(`${job.entity}-${job.action}-${job.id}`) : ''),
|
|
104
|
-
},
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
const backupQueue = createQueue({
|
|
108
|
-
daemon: options.daemon,
|
|
109
|
-
name: 'backup_queue',
|
|
110
|
-
dataDir: dataDirs.core,
|
|
111
|
-
onJob: async (job) => {
|
|
112
|
-
if (typeof blockletManager.onJob === 'function') {
|
|
113
|
-
await blockletManager.onJob(job);
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
options: {
|
|
117
|
-
concurrency,
|
|
118
|
-
maxRetries: 3,
|
|
119
|
-
retryDelay: 10000, // retry after 10 seconds
|
|
120
|
-
maxTimeout: 60 * 1000 * 30, // throw timeout error after 30 minutes
|
|
102
|
+
maxTimeout: 60 * 1000 * 15, // throw timeout error after 5 minutes
|
|
121
103
|
id: (job) => (job ? md5(`${job.entity}-${job.action}-${job.id}`) : ''),
|
|
122
104
|
},
|
|
123
105
|
});
|
|
@@ -147,7 +129,6 @@ function ABTNode(options) {
|
|
|
147
129
|
dataDirs,
|
|
148
130
|
startQueue,
|
|
149
131
|
installQueue,
|
|
150
|
-
backupQueue,
|
|
151
132
|
daemon: options.daemon,
|
|
152
133
|
teamManager,
|
|
153
134
|
});
|
|
@@ -211,6 +192,7 @@ function ABTNode(options) {
|
|
|
211
192
|
|
|
212
193
|
// Blocklet manager
|
|
213
194
|
installBlocklet: blockletManager.install.bind(blockletManager),
|
|
195
|
+
installBlockletFromVc: blockletManager.installBlockletFromVc.bind(blockletManager),
|
|
214
196
|
installComponent: blockletManager.installComponent.bind(blockletManager),
|
|
215
197
|
startBlocklet: blockletManager.start.bind(blockletManager),
|
|
216
198
|
stopBlocklet: blockletManager.stop.bind(blockletManager),
|
package/lib/router/helper.js
CHANGED
|
@@ -26,6 +26,7 @@ const {
|
|
|
26
26
|
NAME_FOR_WELLKNOWN_SITE,
|
|
27
27
|
DEFAULT_HTTP_PORT,
|
|
28
28
|
DEFAULT_HTTPS_PORT,
|
|
29
|
+
NODE_MODES,
|
|
29
30
|
ROUTING_RULE_TYPES,
|
|
30
31
|
CERTIFICATE_EXPIRES_OFFSET,
|
|
31
32
|
DEFAULT_SERVICE_PATH,
|
|
@@ -55,7 +56,6 @@ const {
|
|
|
55
56
|
findInterfacePortByName,
|
|
56
57
|
getWellknownSitePort,
|
|
57
58
|
getServerDidDomain,
|
|
58
|
-
isGatewayCacheEnabled,
|
|
59
59
|
} = require('../util');
|
|
60
60
|
const { getIpDnsDomainForBlocklet, getDidDomainForBlocklet } = require('../util/get-domain-for-blocklet');
|
|
61
61
|
const { getFromCache: getAccessibleExternalNodeIp } = require('../util/get-accessible-external-node-ip');
|
|
@@ -382,7 +382,7 @@ const ensureBlockletCache = async (sites = [], blocklets) => {
|
|
|
382
382
|
const clone = cloneDeep(rule);
|
|
383
383
|
clone.from.pathPrefix = joinUrl(rule.from.pathPrefix, cachePrefix);
|
|
384
384
|
clone.to.cacheGroup = 'blockletProxy';
|
|
385
|
-
clone.to.
|
|
385
|
+
clone.to.target = cachePrefix;
|
|
386
386
|
clone.dynamic = true; // mark as dynamic to avoid redundant generated rules
|
|
387
387
|
cacheRules.push(clone);
|
|
388
388
|
});
|
|
@@ -518,7 +518,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
518
518
|
|
|
519
519
|
const ensureDomainCert = async (domain, url) => {
|
|
520
520
|
const cert = await certManager.getByDomain(domain);
|
|
521
|
-
if (!cert
|
|
521
|
+
if (!cert) {
|
|
522
522
|
await downloadCert({
|
|
523
523
|
domain,
|
|
524
524
|
url,
|
|
@@ -1115,7 +1115,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1115
1115
|
configDir: path.join(dataDirs.router, providerName),
|
|
1116
1116
|
httpPort: nodeInfo.routing.httpPort || DEFAULT_HTTP_PORT,
|
|
1117
1117
|
httpsPort: nodeInfo.routing.httpsPort || DEFAULT_HTTPS_PORT,
|
|
1118
|
-
|
|
1118
|
+
cacheDisabled: nodeInfo.mode === NODE_MODES.DEBUG,
|
|
1119
1119
|
}),
|
|
1120
1120
|
getRoutingParams: async () => {
|
|
1121
1121
|
try {
|
|
@@ -1220,7 +1220,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1220
1220
|
configDir: path.join(dataDirs.router, info.routing.provider),
|
|
1221
1221
|
httpPort: info.routing.httpPort || DEFAULT_HTTP_PORT,
|
|
1222
1222
|
httpsPort: info.routing.httpsPort || DEFAULT_HTTPS_PORT,
|
|
1223
|
-
|
|
1223
|
+
cacheDisabled: info.mode === NODE_MODES.DEBUG,
|
|
1224
1224
|
});
|
|
1225
1225
|
await providerInstance.stop();
|
|
1226
1226
|
logger.info('original router stopped:', { provider: info.routing.provider });
|
|
@@ -1408,8 +1408,6 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1408
1408
|
deleteRoutingRule,
|
|
1409
1409
|
addDomainAlias,
|
|
1410
1410
|
deleteDomainAlias,
|
|
1411
|
-
|
|
1412
|
-
isGatewayCacheEnabled,
|
|
1413
1411
|
};
|
|
1414
1412
|
};
|
|
1415
1413
|
|
package/lib/router/index.js
CHANGED
|
@@ -11,11 +11,8 @@ const {
|
|
|
11
11
|
GATEWAY_REQ_LIMIT,
|
|
12
12
|
} = require('@abtnode/constant');
|
|
13
13
|
const { BLOCKLET_UI_INTERFACES, BLOCKLET_MODES } = require('@blocklet/constant');
|
|
14
|
-
|
|
15
14
|
const logger = require('@abtnode/logger')('@abtnode/core:router');
|
|
16
15
|
|
|
17
|
-
const { isGatewayCacheEnabled } = require('../util');
|
|
18
|
-
|
|
19
16
|
const expandSites = (sites = []) => {
|
|
20
17
|
const result = [];
|
|
21
18
|
|
|
@@ -120,7 +117,6 @@ class Router {
|
|
|
120
117
|
services,
|
|
121
118
|
nodeInfo: pick(nodeInfo, ['name', 'version', 'port', 'mode', 'enableWelcomePage', 'routing']),
|
|
122
119
|
requestLimit,
|
|
123
|
-
cacheEnabled: isGatewayCacheEnabled(nodeInfo),
|
|
124
120
|
});
|
|
125
121
|
}
|
|
126
122
|
|
|
@@ -187,10 +183,6 @@ Router.formatSites = (sites = []) => {
|
|
|
187
183
|
result.forEach((site) => {
|
|
188
184
|
if (Array.isArray(site.rules) && site.rules.length > 0) {
|
|
189
185
|
const rules = cloneDeep(site.rules);
|
|
190
|
-
|
|
191
|
-
let hasRootPathBlockletRule = false;
|
|
192
|
-
let tmpBlockletRule;
|
|
193
|
-
|
|
194
186
|
rules.forEach((rule) => {
|
|
195
187
|
if ([ROUTING_RULE_TYPES.BLOCKLET].includes(rule.to.type) === false) {
|
|
196
188
|
return;
|
|
@@ -205,11 +197,6 @@ Router.formatSites = (sites = []) => {
|
|
|
205
197
|
}
|
|
206
198
|
|
|
207
199
|
if (daemonRule) {
|
|
208
|
-
if (rule.from.pathPrefix === '/') {
|
|
209
|
-
hasRootPathBlockletRule = true;
|
|
210
|
-
}
|
|
211
|
-
tmpBlockletRule = rule;
|
|
212
|
-
|
|
213
200
|
// Serve meta js: both prefix and suffix do not contain trailing slash
|
|
214
201
|
// NOTICE: 这里隐含了一个约定
|
|
215
202
|
// 如果安装的 blockletA 和 blockletB 都需要 __blocklet__.js
|
|
@@ -257,24 +244,6 @@ Router.formatSites = (sites = []) => {
|
|
|
257
244
|
});
|
|
258
245
|
}
|
|
259
246
|
});
|
|
260
|
-
|
|
261
|
-
// ensure /__blocklet__.js should be proxy to daemon
|
|
262
|
-
if (daemonRule && !hasRootPathBlockletRule && tmpBlockletRule) {
|
|
263
|
-
site.rules.push({
|
|
264
|
-
from: {
|
|
265
|
-
pathPrefix: '/',
|
|
266
|
-
groupPathPrefix: '/',
|
|
267
|
-
pathSuffix: '/__blocklet__.js',
|
|
268
|
-
},
|
|
269
|
-
to: {
|
|
270
|
-
type: ROUTING_RULE_TYPES.DAEMON,
|
|
271
|
-
port: daemonRule.to.port,
|
|
272
|
-
did: tmpBlockletRule.to.did,
|
|
273
|
-
componentId: tmpBlockletRule.to.did,
|
|
274
|
-
cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
|
|
275
|
-
},
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
247
|
}
|
|
279
248
|
});
|
|
280
249
|
|
package/lib/states/audit-log.js
CHANGED
|
@@ -239,11 +239,9 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
239
239
|
case 'deleteRoutingRule':
|
|
240
240
|
return `deleted routing rule from ${site}`; // prettier-ignore
|
|
241
241
|
case 'updateGateway': {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
];
|
|
246
|
-
const message = `update gateway: ${changes.join('; ')}`;
|
|
242
|
+
let message = args.requestLimit.enabled ? `status: enabled, rate: ${args.requestLimit.rate}` : 'status: disabled';
|
|
243
|
+
message = `update gateway. ${message}`;
|
|
244
|
+
|
|
247
245
|
return message;
|
|
248
246
|
}
|
|
249
247
|
case 'createTransferInvitation':
|