@abtnode/core 1.17.8-beta-20260109-075740-5f484e08 → 1.17.8-beta-20260113-015027-32a1cec4
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/api/team/access-key-manager.js +104 -0
- package/lib/api/team/invitation-manager.js +461 -0
- package/lib/api/team/notification-manager.js +189 -0
- package/lib/api/team/oauth-manager.js +60 -0
- package/lib/api/team/org-crud-manager.js +202 -0
- package/lib/api/team/org-manager.js +56 -0
- package/lib/api/team/org-member-manager.js +403 -0
- package/lib/api/team/org-query-manager.js +126 -0
- package/lib/api/team/org-resource-manager.js +186 -0
- package/lib/api/team/passport-manager.js +670 -0
- package/lib/api/team/rbac-manager.js +335 -0
- package/lib/api/team/session-manager.js +540 -0
- package/lib/api/team/store-manager.js +198 -0
- package/lib/api/team/tag-manager.js +230 -0
- package/lib/api/team/user-auth-manager.js +132 -0
- package/lib/api/team/user-manager.js +78 -0
- package/lib/api/team/user-query-manager.js +299 -0
- package/lib/api/team/user-social-manager.js +354 -0
- package/lib/api/team/user-update-manager.js +224 -0
- package/lib/api/team/verify-code-manager.js +161 -0
- package/lib/api/team.js +439 -3287
- package/lib/blocklet/manager/disk/auth-manager.js +68 -0
- package/lib/blocklet/manager/disk/backup-manager.js +288 -0
- package/lib/blocklet/manager/disk/cleanup-manager.js +157 -0
- package/lib/blocklet/manager/disk/component-manager.js +83 -0
- package/lib/blocklet/manager/disk/config-manager.js +191 -0
- package/lib/blocklet/manager/disk/controller-manager.js +64 -0
- package/lib/blocklet/manager/disk/delete-reset-manager.js +328 -0
- package/lib/blocklet/manager/disk/download-manager.js +96 -0
- package/lib/blocklet/manager/disk/env-config-manager.js +311 -0
- package/lib/blocklet/manager/disk/federated-manager.js +651 -0
- package/lib/blocklet/manager/disk/hook-manager.js +124 -0
- package/lib/blocklet/manager/disk/install-component-manager.js +95 -0
- package/lib/blocklet/manager/disk/install-core-manager.js +448 -0
- package/lib/blocklet/manager/disk/install-download-manager.js +313 -0
- package/lib/blocklet/manager/disk/install-manager.js +36 -0
- package/lib/blocklet/manager/disk/install-upgrade-manager.js +340 -0
- package/lib/blocklet/manager/disk/job-manager.js +467 -0
- package/lib/blocklet/manager/disk/lifecycle-manager.js +26 -0
- package/lib/blocklet/manager/disk/notification-manager.js +343 -0
- package/lib/blocklet/manager/disk/query-manager.js +562 -0
- package/lib/blocklet/manager/disk/settings-manager.js +507 -0
- package/lib/blocklet/manager/disk/start-manager.js +611 -0
- package/lib/blocklet/manager/disk/stop-restart-manager.js +292 -0
- package/lib/blocklet/manager/disk/update-manager.js +153 -0
- package/lib/blocklet/manager/disk.js +669 -5796
- package/lib/blocklet/manager/helper/blue-green-start-blocklet.js +5 -0
- package/lib/blocklet/manager/lock.js +18 -0
- package/lib/event/index.js +28 -24
- package/lib/util/blocklet/app-utils.js +192 -0
- package/lib/util/blocklet/blocklet-loader.js +258 -0
- package/lib/util/blocklet/config-manager.js +232 -0
- package/lib/util/blocklet/did-document.js +240 -0
- package/lib/util/blocklet/environment.js +555 -0
- package/lib/util/blocklet/health-check.js +449 -0
- package/lib/util/blocklet/install-utils.js +365 -0
- package/lib/util/blocklet/logo.js +57 -0
- package/lib/util/blocklet/meta-utils.js +269 -0
- package/lib/util/blocklet/port-manager.js +141 -0
- package/lib/util/blocklet/process-manager.js +504 -0
- package/lib/util/blocklet/runtime-info.js +105 -0
- package/lib/util/blocklet/validation.js +418 -0
- package/lib/util/blocklet.js +98 -3066
- package/lib/util/wallet-app-notification.js +40 -0
- package/package.json +22 -22
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
/* eslint-disable no-await-in-loop */
|
|
2
|
+
const flat = require('flat');
|
|
3
|
+
const get = require('lodash/get');
|
|
4
|
+
const groupBy = require('lodash/groupBy');
|
|
5
|
+
const isEmpty = require('lodash/isEmpty');
|
|
6
|
+
const logger = require('@abtnode/logger')('@abtnode/core:blocklet:manager:query');
|
|
7
|
+
const { BLOCKLET_SITE_GROUP_SUFFIX, STATIC_SERVER_ENGINE_DID } = require('@abtnode/constant');
|
|
8
|
+
const { MONITOR_RECORD_INTERVAL_SEC } = require('@abtnode/constant');
|
|
9
|
+
const {
|
|
10
|
+
BlockletStatus,
|
|
11
|
+
forEachBlocklet,
|
|
12
|
+
forEachBlockletSync,
|
|
13
|
+
forEachChildSync,
|
|
14
|
+
forEachComponentV2,
|
|
15
|
+
hasStartEngine,
|
|
16
|
+
isBeforeInstalled,
|
|
17
|
+
getComponentId,
|
|
18
|
+
findComponentByIdV2,
|
|
19
|
+
isInProgress,
|
|
20
|
+
} = require('@blocklet/meta/lib/util');
|
|
21
|
+
const { getBlockletEngine } = require('@blocklet/meta/lib/engine');
|
|
22
|
+
const { toBlockletDid } = require('@blocklet/meta/lib/did');
|
|
23
|
+
const { isCustomDomain, isDidDomain } = require('@abtnode/util/lib/url-evaluation');
|
|
24
|
+
const { get: getEngine } = require('../engine');
|
|
25
|
+
|
|
26
|
+
const states = require('../../../states');
|
|
27
|
+
const util = require('../../../util');
|
|
28
|
+
const { getFromCache: getAccessibleExternalNodeIp } = require('../../../util/get-accessible-external-node-ip');
|
|
29
|
+
const getHistoryList = require('../../../monitor/get-history-list');
|
|
30
|
+
const { getBackupList } = require('../../storage/utils/disk');
|
|
31
|
+
const {
|
|
32
|
+
getAppSystemEnvironments,
|
|
33
|
+
getComponentSystemEnvironments,
|
|
34
|
+
getAppOverwrittenEnvironments,
|
|
35
|
+
pruneBlockletBundle,
|
|
36
|
+
getProcessState,
|
|
37
|
+
getBlockletStatus,
|
|
38
|
+
shouldSkipComponent,
|
|
39
|
+
getDiskInfo,
|
|
40
|
+
} = require('../../../util/blocklet');
|
|
41
|
+
|
|
42
|
+
const { formatEnvironments } = util;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Get blocklet detail
|
|
46
|
+
*/
|
|
47
|
+
async function detail(
|
|
48
|
+
manager,
|
|
49
|
+
{
|
|
50
|
+
domain,
|
|
51
|
+
did,
|
|
52
|
+
attachConfig = true,
|
|
53
|
+
attachRuntimeInfo = false,
|
|
54
|
+
attachDiskInfo = false,
|
|
55
|
+
useCache = false,
|
|
56
|
+
getOptionalComponents = false,
|
|
57
|
+
},
|
|
58
|
+
context
|
|
59
|
+
) {
|
|
60
|
+
let targetDid = did;
|
|
61
|
+
if (domain) {
|
|
62
|
+
const aliasDomainSite = await states.site.findByDomainAlias(domain);
|
|
63
|
+
if (!aliasDomainSite) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
targetDid = (aliasDomainSite.domain || '').replace(BLOCKLET_SITE_GROUP_SUFFIX, '');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!targetDid) {
|
|
70
|
+
throw new Error('did should not be empty');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!attachConfig) {
|
|
74
|
+
return states.blocklet.getBlocklet(targetDid);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (attachRuntimeInfo) {
|
|
78
|
+
return _attachRuntimeInfo(manager, { did: targetDid, diskInfo: !!attachDiskInfo, context, getOptionalComponents });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
return manager.getBlocklet(targetDid, { throwOnNotExist: false, getOptionalComponents, useCache });
|
|
83
|
+
} catch (e) {
|
|
84
|
+
logger.error('get blocklet detail error', { error: e });
|
|
85
|
+
return states.blocklet.getBlocklet(targetDid);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* List blocklets
|
|
91
|
+
*/
|
|
92
|
+
async function list(manager, { includeRuntimeInfo = true, query, paging, search, external, sort } = {}, context) {
|
|
93
|
+
if (sort && typeof sort !== 'object') {
|
|
94
|
+
throw new Error('sort must be an object with field and direction properties');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (!isEmpty(paging)) {
|
|
98
|
+
const result = await states.blocklet.findPaginated({ search, external, paging, sort });
|
|
99
|
+
|
|
100
|
+
if (includeRuntimeInfo) {
|
|
101
|
+
result.list = await _attachBlockletListRuntimeInfo(manager, { blocklets: result.list }, context);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
blocklets: result.list,
|
|
106
|
+
paging: result.paging,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const condition = { ...flat(query || {}) };
|
|
111
|
+
const blocklets = await states.blocklet.getBlocklets(condition);
|
|
112
|
+
if (includeRuntimeInfo) {
|
|
113
|
+
return {
|
|
114
|
+
blocklets: await _attachBlockletListRuntimeInfo(manager, { blocklets }, context),
|
|
115
|
+
paging: { total: blocklets.length },
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return { blocklets, paging: { total: blocklets.length } };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* List backups
|
|
124
|
+
*/
|
|
125
|
+
function listBackups(manager) {
|
|
126
|
+
return getBackupList(manager.dataDirs.data);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Get blocklet status
|
|
131
|
+
*/
|
|
132
|
+
async function status(manager, did, { forceSync = false, componentDids } = {}) {
|
|
133
|
+
const blocklet = await manager.getBlocklet(did);
|
|
134
|
+
|
|
135
|
+
if (!blocklet.structVersion) {
|
|
136
|
+
return blocklet;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const updates = new Map();
|
|
140
|
+
const addToUpdates = (componentDid, statusValue) => {
|
|
141
|
+
if (updates.has(statusValue)) {
|
|
142
|
+
updates.get(statusValue).push(componentDid);
|
|
143
|
+
} else {
|
|
144
|
+
updates.set(statusValue, [componentDid]);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
await forEachComponentV2(
|
|
149
|
+
blocklet,
|
|
150
|
+
async (component) => {
|
|
151
|
+
if (!forceSync && !util.shouldUpdateBlockletStatus(component.status)) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (shouldSkipComponent(component.meta.did, componentDids)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (!hasStartEngine(component.meta)) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (getBlockletEngine(component.meta)?.interpreter === 'blocklet') {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
const statusValue = await getProcessState(component.env.processId);
|
|
169
|
+
const oldStatus = component.status;
|
|
170
|
+
if (!isInProgress(statusValue) && component.status !== statusValue) {
|
|
171
|
+
component.status = statusValue;
|
|
172
|
+
addToUpdates(component.meta.did, statusValue);
|
|
173
|
+
logger.info('will sync status from pm2', {
|
|
174
|
+
did,
|
|
175
|
+
status: statusValue,
|
|
176
|
+
oldStatus,
|
|
177
|
+
componentDid: component.meta.did,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
} catch (error) {
|
|
181
|
+
if (
|
|
182
|
+
![
|
|
183
|
+
BlockletStatus.added,
|
|
184
|
+
BlockletStatus.waiting,
|
|
185
|
+
BlockletStatus.downloading,
|
|
186
|
+
BlockletStatus.installing,
|
|
187
|
+
BlockletStatus.installed,
|
|
188
|
+
BlockletStatus.upgrading,
|
|
189
|
+
].includes(component.status) &&
|
|
190
|
+
(error.code !== 'BLOCKLET_PROCESS_404' ||
|
|
191
|
+
![BlockletStatus.stopped, BlockletStatus.error].includes(component.status))
|
|
192
|
+
) {
|
|
193
|
+
const oldStatus = component.status;
|
|
194
|
+
const statusValue = BlockletStatus.stopped;
|
|
195
|
+
component.status = statusValue;
|
|
196
|
+
addToUpdates(component.meta.did, statusValue);
|
|
197
|
+
logger.info('will sync status from pm2', {
|
|
198
|
+
did,
|
|
199
|
+
status: statusValue,
|
|
200
|
+
oldStatus,
|
|
201
|
+
componentDid: component.meta.did,
|
|
202
|
+
error: error.message,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
{ parallel: true }
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
if (updates.size > 0) {
|
|
211
|
+
for (const [statusValue, dids] of updates) {
|
|
212
|
+
logger.info('sync status from pm2', { did, status: statusValue, componentDids: dids });
|
|
213
|
+
await states.blocklet.setBlockletStatus(did, statusValue, { componentDids: dids });
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
blocklet.status = getBlockletStatus(blocklet);
|
|
218
|
+
|
|
219
|
+
return blocklet;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Get runtime history
|
|
224
|
+
*/
|
|
225
|
+
async function getRuntimeHistory(manager, { did, hours }) {
|
|
226
|
+
const metaDid = await states.blocklet.getBlockletMetaDid(did);
|
|
227
|
+
const history = await manager.runtimeMonitor.getHistory(metaDid, hours);
|
|
228
|
+
|
|
229
|
+
const groupedHistory = groupBy(
|
|
230
|
+
history.map((x) => ({
|
|
231
|
+
...x,
|
|
232
|
+
did: x.did.includes('/') ? x.did.split('/').pop() : x.did,
|
|
233
|
+
})),
|
|
234
|
+
'did'
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
const historyList = Object.entries(groupedHistory).map(([key, value]) => ({
|
|
238
|
+
key,
|
|
239
|
+
value: getHistoryList({
|
|
240
|
+
history: value,
|
|
241
|
+
hours,
|
|
242
|
+
recordIntervalSec: MONITOR_RECORD_INTERVAL_SEC,
|
|
243
|
+
props: ['date', 'cpu', 'mem'],
|
|
244
|
+
}),
|
|
245
|
+
}));
|
|
246
|
+
|
|
247
|
+
return historyList;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Refresh list cache
|
|
252
|
+
*/
|
|
253
|
+
function refreshListCache(manager) {
|
|
254
|
+
list(manager, { useCache: false }).catch((err) => {
|
|
255
|
+
logger.error('refresh blocklet list failed', { error: err });
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Update all blocklet environment
|
|
261
|
+
*/
|
|
262
|
+
async function updateAllBlockletEnvironment(manager) {
|
|
263
|
+
const blocklets = await states.blocklet.getBlocklets();
|
|
264
|
+
for (let i = 0; i < blocklets.length; i++) {
|
|
265
|
+
const blocklet = blocklets[i];
|
|
266
|
+
await _updateBlockletEnvironment(manager, blocklet.meta.did);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Prune blocklet bundles
|
|
272
|
+
*/
|
|
273
|
+
async function prune(manager) {
|
|
274
|
+
const blocklets = await states.blocklet.getBlocklets();
|
|
275
|
+
const settings = await states.blockletExtras.listSettings();
|
|
276
|
+
await pruneBlockletBundle({
|
|
277
|
+
installDir: manager.dataDirs.blocklets,
|
|
278
|
+
blocklets,
|
|
279
|
+
blockletSettings: settings.filter((x) => x.settings.children && x.settings.children.length).map((x) => x.settings),
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Get blocklet environments
|
|
285
|
+
*/
|
|
286
|
+
async function getBlockletEnvironments(manager, did) {
|
|
287
|
+
const blockletWithEnv = await manager.getBlocklet(did);
|
|
288
|
+
const nodeInfo = await states.node.read();
|
|
289
|
+
const appSystemEnvironments = {
|
|
290
|
+
...getAppSystemEnvironments(blockletWithEnv, nodeInfo, manager.dataDirs),
|
|
291
|
+
...getAppOverwrittenEnvironments(blockletWithEnv, nodeInfo),
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
return {
|
|
295
|
+
all: formatEnvironments({
|
|
296
|
+
...getComponentSystemEnvironments(blockletWithEnv),
|
|
297
|
+
...appSystemEnvironments,
|
|
298
|
+
}),
|
|
299
|
+
appSystemEnvironments,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Update blocklet environment
|
|
305
|
+
*/
|
|
306
|
+
async function _updateBlockletEnvironment(manager, did) {
|
|
307
|
+
const blockletWithEnv = await manager.getBlocklet(did);
|
|
308
|
+
const blocklet = await states.blocklet.getBlocklet(did);
|
|
309
|
+
|
|
310
|
+
const { all, appSystemEnvironments } = await getBlockletEnvironments(manager, did);
|
|
311
|
+
blocklet.environments = all;
|
|
312
|
+
|
|
313
|
+
const envMap = {};
|
|
314
|
+
forEachBlockletSync(blockletWithEnv, (child, { ancestors }) => {
|
|
315
|
+
const id = getComponentId(child, ancestors);
|
|
316
|
+
envMap[id] = child;
|
|
317
|
+
});
|
|
318
|
+
forEachChildSync(blocklet, (child, { ancestors }) => {
|
|
319
|
+
const id = getComponentId(child, ancestors);
|
|
320
|
+
const childWithEnv = envMap[id];
|
|
321
|
+
if (childWithEnv) {
|
|
322
|
+
child.environments = formatEnvironments({
|
|
323
|
+
...getComponentSystemEnvironments(childWithEnv),
|
|
324
|
+
...appSystemEnvironments,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
blocklet.appDid = appSystemEnvironments.BLOCKLET_APP_ID;
|
|
330
|
+
if (!Array.isArray(blocklet.migratedFrom)) {
|
|
331
|
+
blocklet.migratedFrom = [];
|
|
332
|
+
}
|
|
333
|
+
if (!blocklet.appPid) {
|
|
334
|
+
blocklet.appPid = appSystemEnvironments.BLOCKLET_APP_PID;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
await states.blockletExtras.updateByDid(did, { appDid: blocklet.appDid });
|
|
338
|
+
return states.blocklet.updateBlocklet(did, blocklet);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Attach runtime info to blocklet list
|
|
343
|
+
*/
|
|
344
|
+
async function _attachBlockletListRuntimeInfo(manager, { blocklets }, context) {
|
|
345
|
+
const nodeInfo = await states.node.read();
|
|
346
|
+
return (
|
|
347
|
+
await Promise.all(
|
|
348
|
+
blocklets.map((x) => {
|
|
349
|
+
if (isBeforeInstalled(x.status)) {
|
|
350
|
+
return x;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return _attachRuntimeInfo(manager, {
|
|
354
|
+
did: x.meta.did,
|
|
355
|
+
nodeInfo,
|
|
356
|
+
diskInfo: false,
|
|
357
|
+
context,
|
|
358
|
+
});
|
|
359
|
+
})
|
|
360
|
+
)
|
|
361
|
+
).filter(Boolean);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Get domain aliases
|
|
366
|
+
*/
|
|
367
|
+
async function getDomainAliases(manager, { blocklet, nodeInfo }, context = {}) {
|
|
368
|
+
if (blocklet?.site?.domainAliases?.length) {
|
|
369
|
+
const nodeIp = await getAccessibleExternalNodeIp(nodeInfo || (await states.node.read()));
|
|
370
|
+
return blocklet.site.domainAliases.map((x) => ({
|
|
371
|
+
...x,
|
|
372
|
+
value: util.replaceDomainSlot({ domain: x.value, context, nodeIp }),
|
|
373
|
+
}));
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return [];
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Attach runtime info to blocklet
|
|
381
|
+
*/
|
|
382
|
+
async function _attachRuntimeInfo(manager, { did, nodeInfo, diskInfo = false, context, getOptionalComponents }) {
|
|
383
|
+
if (!did) {
|
|
384
|
+
throw new Error('did should not be empty');
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
try {
|
|
388
|
+
const blocklet = await manager.getBlocklet(did, { throwOnNotExist: false, getOptionalComponents });
|
|
389
|
+
|
|
390
|
+
if (!blocklet) {
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (blocklet.site) {
|
|
395
|
+
blocklet.site.domainAliases = await getDomainAliases(
|
|
396
|
+
manager,
|
|
397
|
+
{ blocklet, nodeInfo: nodeInfo || (await states.node.read()) },
|
|
398
|
+
context
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// app runtime info, app status
|
|
403
|
+
const cpus = manager.nodeAPI.getRealtimeData().cpu?.cpus || [];
|
|
404
|
+
blocklet.appRuntimeInfo = {
|
|
405
|
+
cpus,
|
|
406
|
+
...manager.runtimeMonitor.getRuntimeInfo(did),
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
forEachBlockletSync(blocklet, (component) => {
|
|
410
|
+
if (component.meta.did === did) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
component.appRuntimeInfo = {
|
|
415
|
+
cpus,
|
|
416
|
+
...manager.runtimeMonitor.getRuntimeInfo(did, `${did}/${component.meta.did}`),
|
|
417
|
+
};
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
// app disk info, component runtime info, component engine
|
|
421
|
+
await forEachBlocklet(blocklet, async (component, { level }) => {
|
|
422
|
+
const engine = getBlockletEngine(component.meta);
|
|
423
|
+
if (engine.interpreter === 'blocklet') {
|
|
424
|
+
const engineId = toBlockletDid(engine.source.name);
|
|
425
|
+
const engineComponent = findComponentByIdV2(blocklet, [engineId]);
|
|
426
|
+
if (engineComponent) {
|
|
427
|
+
component.engine = {
|
|
428
|
+
name: engineComponent.meta.did,
|
|
429
|
+
displayName: engineComponent.meta.title,
|
|
430
|
+
description: engineComponent.meta.description,
|
|
431
|
+
version: engineComponent.meta.version,
|
|
432
|
+
available: true,
|
|
433
|
+
visible: true,
|
|
434
|
+
// FIXME: @wangshijun this should be dynamic
|
|
435
|
+
logo: '',
|
|
436
|
+
};
|
|
437
|
+
} else if (engineId !== STATIC_SERVER_ENGINE_DID) {
|
|
438
|
+
// Note: the component maybe in dev mode or removed
|
|
439
|
+
logger.warn(`engine component ${engineId} not found for ${did}`);
|
|
440
|
+
}
|
|
441
|
+
} else {
|
|
442
|
+
component.engine = getEngine(engine.interpreter)?.describe();
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if (level === 0) {
|
|
446
|
+
component.diskInfo = await getDiskInfo(component, {
|
|
447
|
+
useFakeDiskInfo: !diskInfo || isBeforeInstalled(component.status),
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
component.runtimeInfo = manager.runtimeMonitor.getRuntimeInfo(blocklet.meta.did, component.env.id);
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
return blocklet;
|
|
455
|
+
} catch (err) {
|
|
456
|
+
const simpleState = await states.blocklet.getBlocklet(did);
|
|
457
|
+
logger.error('failed to get blocklet info', {
|
|
458
|
+
did,
|
|
459
|
+
name: get(simpleState, 'meta.name'),
|
|
460
|
+
status: get(simpleState, 'status'),
|
|
461
|
+
error: err,
|
|
462
|
+
});
|
|
463
|
+
return simpleState;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Update blocklet certificate
|
|
469
|
+
*/
|
|
470
|
+
async function _updateBlockletCertificate(manager, did) {
|
|
471
|
+
const blocklet = await manager.getBlocklet(did);
|
|
472
|
+
const domainAliases = get(blocklet, 'site.domainAliases') || [];
|
|
473
|
+
const customAliases = domainAliases.filter((x) => isCustomDomain(x.value));
|
|
474
|
+
const cnameDomain = domainAliases.find((item) => isDidDomain(item.value));
|
|
475
|
+
|
|
476
|
+
const issueCert = (alias) =>
|
|
477
|
+
manager.certManager
|
|
478
|
+
.issue({
|
|
479
|
+
domain: alias.value,
|
|
480
|
+
did,
|
|
481
|
+
siteId: blocklet.site.id,
|
|
482
|
+
inBlockletSetup: false,
|
|
483
|
+
})
|
|
484
|
+
.catch((error) => {
|
|
485
|
+
logger.error('cron update issue cert for domain alias failed', { error });
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
await Promise.all(
|
|
489
|
+
customAliases.map(async (alias) => {
|
|
490
|
+
const dns = await manager.routerManager.checkDomainDNS(alias.value, cnameDomain?.value);
|
|
491
|
+
logger.info('dns info', { dns });
|
|
492
|
+
if (!dns.isDnsResolved || !dns.isCnameMatch) {
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
const foundCert = await manager.routerManager.getHttpsCert({ domain: alias.value });
|
|
497
|
+
logger.info('cron check dns global certificate', { foundCert: !!foundCert, domain: alias.value });
|
|
498
|
+
if (foundCert) {
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
if (!alias.certificateId) {
|
|
503
|
+
logger.info('cron check dns no certificate');
|
|
504
|
+
await issueCert(alias);
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
const cert = await states.certificate.get(alias.certificateId, 'id');
|
|
509
|
+
logger.info('cron check dns current certificate', {
|
|
510
|
+
cert: cert ? { ...cert, key: '', certificate: '' } : null,
|
|
511
|
+
domain: alias.value,
|
|
512
|
+
});
|
|
513
|
+
if (!cert) {
|
|
514
|
+
await issueCert(alias);
|
|
515
|
+
}
|
|
516
|
+
})
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Update all blocklet certificates
|
|
522
|
+
*/
|
|
523
|
+
async function updateAllBlockletCertificate(manager) {
|
|
524
|
+
try {
|
|
525
|
+
const blocklets = await states.blocklet.getBlocklets();
|
|
526
|
+
|
|
527
|
+
for (const blocklet of blocklets) {
|
|
528
|
+
const domainAliases = get(blocklet, 'site.domainAliases') || [];
|
|
529
|
+
const customAliases = domainAliases.filter((x) => isCustomDomain(x.value));
|
|
530
|
+
|
|
531
|
+
if (!customAliases.length) {
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
try {
|
|
536
|
+
await _updateBlockletCertificate(manager, blocklet.meta.did);
|
|
537
|
+
} catch (error) {
|
|
538
|
+
logger.error('cron update blocklet certificate failed', { error, did: blocklet.meta.did });
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
} catch (error) {
|
|
542
|
+
logger.error('cron update all blocklet certificate failed', { error });
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
module.exports = {
|
|
547
|
+
detail,
|
|
548
|
+
list,
|
|
549
|
+
listBackups,
|
|
550
|
+
status,
|
|
551
|
+
getRuntimeHistory,
|
|
552
|
+
refreshListCache,
|
|
553
|
+
updateAllBlockletEnvironment,
|
|
554
|
+
prune,
|
|
555
|
+
getBlockletEnvironments,
|
|
556
|
+
_updateBlockletEnvironment,
|
|
557
|
+
_attachBlockletListRuntimeInfo,
|
|
558
|
+
getDomainAliases,
|
|
559
|
+
_attachRuntimeInfo,
|
|
560
|
+
_updateBlockletCertificate,
|
|
561
|
+
updateAllBlockletCertificate,
|
|
562
|
+
};
|