@abtnode/core 1.16.11-beta-0ae58a71 → 1.16.11-beta-f74663ac
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/node.js +1 -1
- package/lib/api/team.js +5 -5
- package/lib/blocklet/downloader/blocklet-downloader.js +34 -19
- package/lib/blocklet/downloader/bundle-downloader.js +2 -2
- package/lib/blocklet/hooks.js +1 -1
- package/lib/blocklet/manager/base.js +9 -9
- package/lib/blocklet/manager/disk.js +286 -172
- package/lib/blocklet/manager/helper/install-application-from-backup.js +1 -1
- package/lib/blocklet/manager/helper/install-application-from-general.js +18 -3
- package/lib/blocklet/manager/helper/install-component-from-dev.js +0 -1
- package/lib/blocklet/manager/helper/install-component-from-upload.js +8 -4
- package/lib/blocklet/manager/helper/install-component-from-url.js +4 -2
- package/lib/blocklet/manager/helper/upgrade-components.js +7 -7
- package/lib/blocklet/manager/pm2-events.js +3 -3
- package/lib/blocklet/migration.js +2 -2
- package/lib/blocklet/storage/backup/base.js +1 -0
- package/lib/blocklet/storage/backup/blocklet-extras.js +1 -1
- package/lib/blocklet/storage/backup/blocklet.js +1 -1
- package/lib/blocklet/storage/backup/disk.js +1 -0
- package/lib/blocklet/storage/restore/blocklet-extras.js +1 -1
- package/lib/blocklet/storage/restore/blocklet.js +1 -1
- package/lib/blocklet/storage/restore/disk.js +1 -1
- package/lib/blocklet/storage/restore/spaces.js +1 -1
- package/lib/cert.js +5 -5
- package/lib/crons/rotate-pm2-logs/index.js +1 -1
- package/lib/event.js +11 -1
- package/lib/index.js +8 -2
- package/lib/migrations/1.16.11-component-status.js +22 -0
- package/lib/migrations/index.js +3 -3
- package/lib/monitor/blocklet-runtime-monitor.js +7 -2
- package/lib/processes/updater.js +1 -1
- package/lib/router/helper.js +5 -5
- package/lib/states/audit-log.js +1 -1
- package/lib/states/backup.js +5 -4
- package/lib/states/blocklet-extras.js +11 -1
- package/lib/states/blocklet.js +46 -39
- package/lib/states/cache.js +1 -1
- package/lib/states/node.js +6 -2
- package/lib/states/notification.js +1 -1
- package/lib/states/routing-snapshot.js +1 -1
- package/lib/states/site.js +1 -1
- package/lib/states/user.js +12 -6
- package/lib/team/manager.js +6 -6
- package/lib/util/blocklet.js +130 -118
- package/lib/util/launcher.js +238 -0
- package/lib/util/reset-node.js +19 -16
- package/lib/util/rpc.js +1 -1
- package/lib/util/store.js +1 -1
- package/lib/validators/space-gateway.js +3 -0
- package/lib/validators/util.js +3 -0
- package/lib/webhook/sender/api/index.js +1 -1
- package/lib/webhook/sender/slack/index.js +1 -1
- package/package.json +17 -17
|
@@ -203,7 +203,7 @@ const installApplicationFromBackup = async ({
|
|
|
203
203
|
// 从 store 下载 blocklet
|
|
204
204
|
await manager.blockletDownloader.download(blockletState, {
|
|
205
205
|
skipCheckIntegrity: true,
|
|
206
|
-
onProgress:
|
|
206
|
+
onProgress: (data) => {
|
|
207
207
|
manager.emit(BlockletEvents.downloadBundleProgress, { appDid: wallet.address, meta: { did }, ...data });
|
|
208
208
|
},
|
|
209
209
|
});
|
|
@@ -54,9 +54,7 @@ const installApplicationFromGeneral = async ({
|
|
|
54
54
|
|
|
55
55
|
// check install count
|
|
56
56
|
if (controller?.nftId) {
|
|
57
|
-
// sometimes nedb will throw error if use states.blocklet.count({ ['controller.nftId']: controller.nftId })
|
|
58
57
|
const installedCount = await states.blockletExtras.count({ 'controller.nftId': controller.nftId });
|
|
59
|
-
|
|
60
58
|
if (installedCount >= (controller.appMaxCount || 1)) {
|
|
61
59
|
throw new Error(
|
|
62
60
|
`You can only install ${controller.appMaxCount} blocklet with this credential: ${controller.nftId}`
|
|
@@ -120,7 +118,24 @@ const installApplicationFromGeneral = async ({
|
|
|
120
118
|
},
|
|
121
119
|
]);
|
|
122
120
|
} catch (err) {
|
|
123
|
-
|
|
121
|
+
const componentDid = component?.meta?.did;
|
|
122
|
+
logger.error('failed to create blocklet extras', { did, componentDid, error: err });
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
await manager._rollback('install', did, {});
|
|
126
|
+
} catch (e) {
|
|
127
|
+
logger.error('failed to remove blocklet on create extras error', { did, componentDid, error: e });
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
manager._createNotification(did, {
|
|
131
|
+
title: 'Blocklet Install Failed',
|
|
132
|
+
description: `Blocklet ${title || component?.meta?.title} install failed with error: ${err.message}`,
|
|
133
|
+
entityType: 'blocklet',
|
|
134
|
+
entityId: did,
|
|
135
|
+
severity: 'error',
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
throw err;
|
|
124
139
|
}
|
|
125
140
|
|
|
126
141
|
if (!blocklet.children.length) {
|
|
@@ -56,7 +56,6 @@ const installComponentFromDev = async ({ folder, meta, rootDid, mountPoint, mana
|
|
|
56
56
|
const newBlocklet = await states.blocklet.getBlocklet(rootDid);
|
|
57
57
|
await validateBlocklet(newBlocklet);
|
|
58
58
|
await manager._downloadBlocklet(newBlocklet);
|
|
59
|
-
await states.blocklet.setBlockletStatus(rootDid, BlockletStatus.stopped);
|
|
60
59
|
|
|
61
60
|
// Add Config
|
|
62
61
|
await manager._setConfigsFromMeta(rootDid);
|
|
@@ -13,6 +13,7 @@ const {
|
|
|
13
13
|
ensureMeta,
|
|
14
14
|
checkStructVersion,
|
|
15
15
|
checkVersionCompatibility,
|
|
16
|
+
getBlockletStatus,
|
|
16
17
|
} = require('../../../util/blocklet');
|
|
17
18
|
const { resolveDownload, resolveDiffDownload, downloadFromUpload } = require('../../downloader/resolve-download');
|
|
18
19
|
|
|
@@ -39,9 +40,10 @@ const installComponentFromUpload = async ({
|
|
|
39
40
|
// download
|
|
40
41
|
const { tarFile } = await downloadFromUpload(file, { downloadDir: path.join(manager.dataDirs.tmp, 'download') });
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
const appStatus = getBlockletStatus(oldBlocklet);
|
|
44
|
+
if (isInProgress(appStatus)) {
|
|
45
|
+
logger.error(`Can not deploy blocklet when it is ${fromBlockletStatus(appStatus)}`);
|
|
46
|
+
throw new Error(`Can not deploy blocklet when it is ${fromBlockletStatus(appStatus)}`);
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
let meta;
|
|
@@ -105,6 +107,8 @@ const installComponentFromUpload = async ({
|
|
|
105
107
|
const action = 'upgrade';
|
|
106
108
|
await manager._rollbackCache.backup({ did: newBlocklet.meta.did, action, oldBlocklet });
|
|
107
109
|
|
|
110
|
+
const componentDids = [newChild.meta.did, ...newChildren.map((x) => x.meta.did)];
|
|
111
|
+
|
|
108
112
|
await manager._downloadAndInstall({
|
|
109
113
|
blocklet: newBlocklet,
|
|
110
114
|
oldBlocklet,
|
|
@@ -112,7 +116,7 @@ const installComponentFromUpload = async ({
|
|
|
112
116
|
throwOnError: true,
|
|
113
117
|
postAction: action,
|
|
114
118
|
skipCheckStatusBeforeDownload: true,
|
|
115
|
-
|
|
119
|
+
componentDids,
|
|
116
120
|
});
|
|
117
121
|
return manager.getBlocklet(newBlocklet.meta.did);
|
|
118
122
|
};
|
|
@@ -127,8 +127,10 @@ const installComponentFromUrl = async ({
|
|
|
127
127
|
throw err;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
const componentDids = [newChild.meta.did, ...newChildren.map((x) => x.meta.did)];
|
|
131
|
+
|
|
130
132
|
// new blocklet
|
|
131
|
-
const newBlocklet = await states.blocklet.setBlockletStatus(rootDid, BlockletStatus.waiting);
|
|
133
|
+
const newBlocklet = await states.blocklet.setBlockletStatus(rootDid, BlockletStatus.waiting, { componentDids });
|
|
132
134
|
|
|
133
135
|
newBlocklet.children = blocklet.children;
|
|
134
136
|
await validateBlocklet(newBlocklet);
|
|
@@ -138,7 +140,7 @@ const installComponentFromUrl = async ({
|
|
|
138
140
|
const downloadParams = {
|
|
139
141
|
oldBlocklet: { ...oldBlocklet },
|
|
140
142
|
blocklet: { ...newBlocklet },
|
|
141
|
-
|
|
143
|
+
componentDids,
|
|
142
144
|
context,
|
|
143
145
|
postAction: action,
|
|
144
146
|
};
|
|
@@ -73,8 +73,8 @@ const check = async ({ did, states }) => {
|
|
|
73
73
|
};
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
-
const upgrade = async ({ updateId,
|
|
77
|
-
if (!
|
|
76
|
+
const upgrade = async ({ updateId, componentDids, context, states, manager }) => {
|
|
77
|
+
if (!componentDids?.length) {
|
|
78
78
|
throw new Error('At least one component needs to be selected');
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -87,7 +87,7 @@ const upgrade = async ({ updateId, selectedComponentDids, context, states, manag
|
|
|
87
87
|
let dynamicComponents = [];
|
|
88
88
|
const children = cloneDeep(oldBlocklet.children).map((oldComponent) => {
|
|
89
89
|
const newComponent = sessionData.children.find((x) => x.meta.did === oldComponent.meta.did);
|
|
90
|
-
if (newComponent &&
|
|
90
|
+
if (newComponent && componentDids.includes(newComponent.meta.did)) {
|
|
91
91
|
dynamicComponents.push(...(newComponent._dynamicComponents || []));
|
|
92
92
|
delete newComponent._dynamicComponents;
|
|
93
93
|
return newComponent;
|
|
@@ -97,8 +97,8 @@ const upgrade = async ({ updateId, selectedComponentDids, context, states, manag
|
|
|
97
97
|
dynamicComponents = filterDuplicateComponents(dynamicComponents, children);
|
|
98
98
|
children.push(...dynamicComponents);
|
|
99
99
|
|
|
100
|
-
//
|
|
101
|
-
|
|
100
|
+
// componentDids
|
|
101
|
+
componentDids.push(...dynamicComponents.map((x) => x.meta.did));
|
|
102
102
|
|
|
103
103
|
checkVersionCompatibility(children);
|
|
104
104
|
|
|
@@ -108,7 +108,7 @@ const upgrade = async ({ updateId, selectedComponentDids, context, states, manag
|
|
|
108
108
|
});
|
|
109
109
|
|
|
110
110
|
// new blocklet
|
|
111
|
-
const newBlocklet = await states.blocklet.setBlockletStatus(did, BlockletStatus.waiting);
|
|
111
|
+
const newBlocklet = await states.blocklet.setBlockletStatus(did, BlockletStatus.waiting, { componentDids });
|
|
112
112
|
|
|
113
113
|
newBlocklet.children = children;
|
|
114
114
|
await validateBlocklet(newBlocklet);
|
|
@@ -128,7 +128,7 @@ const upgrade = async ({ updateId, selectedComponentDids, context, states, manag
|
|
|
128
128
|
id: did,
|
|
129
129
|
oldBlocklet: { ...oldBlocklet },
|
|
130
130
|
blocklet: { ...newBlocklet },
|
|
131
|
-
|
|
131
|
+
componentDids: componentDids || [],
|
|
132
132
|
context,
|
|
133
133
|
postAction: action,
|
|
134
134
|
},
|
|
@@ -27,10 +27,10 @@ class BlockletPm2Events extends EventEmitter {
|
|
|
27
27
|
if (actualPm2Home !== expectedPm2Home) {
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
|
-
const { BLOCKLET_DID: blockletDid } = details.process || {};
|
|
31
|
-
logger.debug('listen pm2 event', { name, blockletDid });
|
|
30
|
+
const { BLOCKLET_DID: blockletDid, BLOCKLET_COMPONENT_DID: componentDid } = details.process || {};
|
|
31
|
+
logger.debug('listen pm2 event', { name, blockletDid, componentDid });
|
|
32
32
|
if (blockletDid) {
|
|
33
|
-
this.emit(name, { blockletDid });
|
|
33
|
+
this.emit(name, { blockletDid, componentDid });
|
|
34
34
|
}
|
|
35
35
|
})
|
|
36
36
|
.error((error) => {
|
|
@@ -78,14 +78,14 @@ async function runScripts({
|
|
|
78
78
|
return true;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
function doBackup({ dbDir, backupDir, printInfo, printSuccess }) {
|
|
82
82
|
printInfo('Backing up before migration...');
|
|
83
83
|
fs.emptyDirSync(backupDir);
|
|
84
84
|
fs.copySync(dbDir, backupDir);
|
|
85
85
|
printSuccess('Backup success');
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
function doRestore({ dbDir, backupDir, printInfo, printSuccess }) {
|
|
89
89
|
printInfo('Restoring when migration failed...');
|
|
90
90
|
fs.emptyDirSync(dbDir);
|
|
91
91
|
fs.copySync(backupDir, dbDir);
|
|
@@ -28,7 +28,7 @@ class BlockletBackup extends BaseBackup {
|
|
|
28
28
|
* @return {Promise<import('@abtnode/client').BlockletState>}
|
|
29
29
|
* @memberof BlockletBackup
|
|
30
30
|
*/
|
|
31
|
-
|
|
31
|
+
cleanData() {
|
|
32
32
|
const clone = cloneDeep(this.blocklet);
|
|
33
33
|
|
|
34
34
|
/** @type {import('@abtnode/client').ComponentState[]} */
|
|
@@ -8,7 +8,7 @@ const { BaseRestore } = require('./base');
|
|
|
8
8
|
class BlockletExtrasRestore extends BaseRestore {
|
|
9
9
|
filename = 'blocklet-extras.json';
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
import(params) {
|
|
12
12
|
const extras = this.cleanExtras(this.getExtras(), params);
|
|
13
13
|
removeSync(join(this.restoreDir, this.filename));
|
|
14
14
|
outputJsonSync(join(this.restoreDir, this.filename), extras);
|
|
@@ -8,7 +8,7 @@ const { BaseRestore } = require('./base');
|
|
|
8
8
|
class BlockletRestore extends BaseRestore {
|
|
9
9
|
filename = 'blocklet.json';
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
import(params) {
|
|
12
12
|
const blocklet = this.decrypt(this.getBlocklet(), params);
|
|
13
13
|
removeSync(join(this.restoreDir, this.filename));
|
|
14
14
|
outputJsonSync(join(this.restoreDir, this.filename), blocklet);
|
|
@@ -61,7 +61,7 @@ class DiskRestore extends BaseRestore {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
initialize() {
|
|
65
65
|
this.serverDir = process.env.ABT_NODE_DATA_DIR;
|
|
66
66
|
this.restoreDir = getBackupDirs(this.serverDir, this.input.appDid).restoreDir;
|
|
67
67
|
if (existsSync(this.restoreDir)) {
|
|
@@ -82,7 +82,7 @@ class SpacesRestore extends BaseRestore {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
initialize() {
|
|
86
86
|
this.serverDir = process.env.ABT_NODE_DATA_DIR;
|
|
87
87
|
this.restoreDir = join(this.serverDir, 'tmp/restore', this.input.appDid);
|
|
88
88
|
if (existsSync(this.restoreDir)) {
|
package/lib/cert.js
CHANGED
|
@@ -4,7 +4,7 @@ const logger = require('@abtnode/logger')('@abtnode/core:cert');
|
|
|
4
4
|
const { EVENTS } = require('@abtnode/constant');
|
|
5
5
|
const { BlockletEvents } = require('@blocklet/constant');
|
|
6
6
|
|
|
7
|
-
const onCertExpired =
|
|
7
|
+
const onCertExpired = (cert, states) => {
|
|
8
8
|
logger.info('send certificate expire notification', { domain: cert.domain });
|
|
9
9
|
states.notification.create({
|
|
10
10
|
title: 'SSL Certificate Expired',
|
|
@@ -120,7 +120,7 @@ class Cert extends EventEmitter {
|
|
|
120
120
|
* did?:string // blocklet.meta.did
|
|
121
121
|
* }}
|
|
122
122
|
*/
|
|
123
|
-
|
|
123
|
+
issue({ domain, did }) {
|
|
124
124
|
logger.info(`generate certificate for ${domain}`);
|
|
125
125
|
|
|
126
126
|
if (did) {
|
|
@@ -137,7 +137,7 @@ class Cert extends EventEmitter {
|
|
|
137
137
|
return result;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
update(data) {
|
|
141
141
|
return this.manager.update(data.id, { name: data.name, public: data.public });
|
|
142
142
|
}
|
|
143
143
|
|
|
@@ -149,11 +149,11 @@ class Cert extends EventEmitter {
|
|
|
149
149
|
return {};
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
|
|
152
|
+
addWithoutValidations(data) {
|
|
153
153
|
return this.manager.addWithoutValidations(data);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
updateWithoutValidations(id, data) {
|
|
157
157
|
return this.manager.updateWithoutValidations(id, data);
|
|
158
158
|
}
|
|
159
159
|
|
|
@@ -7,7 +7,7 @@ const getCron = () => ({
|
|
|
7
7
|
name: 'rotate-pm2-logs',
|
|
8
8
|
time: '0 0 * * *', // default : every day at midnight
|
|
9
9
|
options: { runOnInit: false },
|
|
10
|
-
fn:
|
|
10
|
+
fn: () => {
|
|
11
11
|
console.info(`Log rotator started on ${new Date().toISOString()}`);
|
|
12
12
|
const child = spawn('node', [path.join(__dirname, './script.js')], {
|
|
13
13
|
detached: true,
|
package/lib/event.js
CHANGED
|
@@ -3,7 +3,13 @@ const cloneDeep = require('lodash/cloneDeep');
|
|
|
3
3
|
const { EventEmitter } = require('events');
|
|
4
4
|
const { wipeSensitiveData } = require('@blocklet/meta/lib/util');
|
|
5
5
|
const logger = require('@abtnode/logger')('@abtnode/core:event');
|
|
6
|
-
const {
|
|
6
|
+
const {
|
|
7
|
+
BLOCKLET_MODES,
|
|
8
|
+
BlockletStatus,
|
|
9
|
+
BlockletSource,
|
|
10
|
+
BlockletEvents,
|
|
11
|
+
BlockletInternalEvents,
|
|
12
|
+
} = require('@blocklet/constant');
|
|
7
13
|
const { EVENTS } = require('@abtnode/constant');
|
|
8
14
|
const { NodeMonitSender } = require('./monitor/node-monit-sender');
|
|
9
15
|
const handleInstanceInStore = require('./util/public-to-store');
|
|
@@ -375,6 +381,10 @@ module.exports = ({
|
|
|
375
381
|
listen(blockletManager, eventName, handleBlockletEvent);
|
|
376
382
|
});
|
|
377
383
|
|
|
384
|
+
[BlockletInternalEvents.componentsUpdated, BlockletInternalEvents.appConfigChanged].forEach((eventName) => {
|
|
385
|
+
listen(blockletManager, eventName, onEvent);
|
|
386
|
+
});
|
|
387
|
+
|
|
378
388
|
listen(notificationState, EVENTS.NOTIFICATION_CREATE, onEvent);
|
|
379
389
|
|
|
380
390
|
listen(nodeState, BlockletEvents.purchaseChange, onEvent);
|
package/lib/index.js
CHANGED
|
@@ -16,6 +16,7 @@ const getRouterHelpers = require('./router/helper');
|
|
|
16
16
|
const TeamManager = require('./team/manager');
|
|
17
17
|
const NodeAPI = require('./api/node');
|
|
18
18
|
const TeamAPI = require('./api/team');
|
|
19
|
+
const { getLauncherSession, isLauncherSessionConsumed, setupAppOwner } = require('./util/launcher');
|
|
19
20
|
const WebHook = require('./webhook');
|
|
20
21
|
const states = require('./states');
|
|
21
22
|
const Cert = require('./cert');
|
|
@@ -250,7 +251,6 @@ function ABTNode(options) {
|
|
|
250
251
|
devBlocklet: blockletManager.dev.bind(blockletManager),
|
|
251
252
|
checkComponentsForUpdates: blockletManager.checkComponentsForUpdates.bind(blockletManager),
|
|
252
253
|
upgradeComponents: blockletManager.upgradeComponents.bind(blockletManager),
|
|
253
|
-
getBlockletMetaFromUrl: getMetaFromUrl.bind(blockletManager),
|
|
254
254
|
getBlockletForLauncher: blockletManager.getBlockletForLauncher.bind(blockletManager),
|
|
255
255
|
resetBlocklet: blockletManager.reset.bind(blockletManager),
|
|
256
256
|
deleteBlockletProcess: blockletManager.deleteProcess.bind(blockletManager),
|
|
@@ -268,7 +268,6 @@ function ABTNode(options) {
|
|
|
268
268
|
// For diagnose purpose
|
|
269
269
|
syncBlockletStatus: blockletManager.status.bind(blockletManager),
|
|
270
270
|
ensureBlockletIntegrity: blockletManager.ensureBlocklet.bind(blockletManager),
|
|
271
|
-
updateBlockletStatus: states.blocklet.setBlockletStatus.bind(states.blocklet),
|
|
272
271
|
|
|
273
272
|
getBlocklets: blockletManager.list.bind(blockletManager),
|
|
274
273
|
getBlockletsFromBackup: blockletManager.listBackups.bind(blockletManager),
|
|
@@ -277,6 +276,7 @@ function ABTNode(options) {
|
|
|
277
276
|
hasBlocklet: blockletManager.hasBlocklet.bind(blockletManager),
|
|
278
277
|
updateAllBlockletEnvironment: blockletManager.updateAllBlockletEnvironment.bind(blockletManager),
|
|
279
278
|
setBlockletInitialized: blockletManager.setInitialized.bind(blockletManager),
|
|
279
|
+
setBlockletOwner: blockletManager.updateOwner.bind(blockletManager),
|
|
280
280
|
updateBlockletOwner: blockletManager.updateOwner.bind(blockletManager),
|
|
281
281
|
getBlockletRuntimeHistory: blockletManager.getRuntimeHistory.bind(blockletManager),
|
|
282
282
|
|
|
@@ -462,6 +462,12 @@ function ABTNode(options) {
|
|
|
462
462
|
|
|
463
463
|
// for exporting blocklet data dir
|
|
464
464
|
createBlockletDataArchive: createDataArchive,
|
|
465
|
+
|
|
466
|
+
// public utils used in launch workflow
|
|
467
|
+
getBlockletMetaFromUrl: getMetaFromUrl,
|
|
468
|
+
getLauncherSession,
|
|
469
|
+
isLauncherSessionConsumed,
|
|
470
|
+
setupAppOwner,
|
|
465
471
|
};
|
|
466
472
|
|
|
467
473
|
const events = createEvents({
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* eslint-disable no-await-in-loop */
|
|
2
|
+
/* eslint-disable no-continue */
|
|
3
|
+
|
|
4
|
+
module.exports = async ({ states, printInfo }) => {
|
|
5
|
+
printInfo('Try to update component status...');
|
|
6
|
+
|
|
7
|
+
const apps = await states.blocklet.find({});
|
|
8
|
+
|
|
9
|
+
for (const app of apps || []) {
|
|
10
|
+
const appStatus = app.status;
|
|
11
|
+
let shouldUpdate = false;
|
|
12
|
+
for (const component of app.children || []) {
|
|
13
|
+
shouldUpdate = true;
|
|
14
|
+
component.status = appStatus;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (shouldUpdate) {
|
|
18
|
+
await states.blocklet.update({ id: app.id }, { $set: { children: app.children } });
|
|
19
|
+
printInfo(`Blocklet in blocklet.db updated: ${app.meta?.title}. status: ${appStatus}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
package/lib/migrations/index.js
CHANGED
|
@@ -78,7 +78,7 @@ const getMigrationScripts = (scriptsDir) => {
|
|
|
78
78
|
return sorted;
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
-
const doBackup =
|
|
81
|
+
const doBackup = ({ dataDir, configFile, printInfo, printSuccess }) => {
|
|
82
82
|
printInfo('Backing up state db and config before migration...');
|
|
83
83
|
|
|
84
84
|
const backupDir = path.join(dataDir, 'migration', Date.now().toString());
|
|
@@ -96,7 +96,7 @@ const doBackup = async ({ dataDir, configFile, printInfo, printSuccess }) => {
|
|
|
96
96
|
return backupDir;
|
|
97
97
|
};
|
|
98
98
|
|
|
99
|
-
const doRestore =
|
|
99
|
+
const doRestore = ({ dataDir, configFile, backupPath, printInfo, printSuccess }) => {
|
|
100
100
|
printInfo('Restoring when migration failed...');
|
|
101
101
|
|
|
102
102
|
const dbBackup = path.join(backupPath, BACKUP_FILE_DB);
|
|
@@ -309,7 +309,7 @@ const runDataMigrations = async ({
|
|
|
309
309
|
}
|
|
310
310
|
};
|
|
311
311
|
|
|
312
|
-
const closeDatabaseConnections =
|
|
312
|
+
const closeDatabaseConnections = ({
|
|
313
313
|
dataDir,
|
|
314
314
|
blocklets = [],
|
|
315
315
|
printInfo = console.info, // eslint-disable-line
|
|
@@ -116,7 +116,7 @@ class BlockletRuntimeMonitor extends EventEmitter {
|
|
|
116
116
|
await forEachBlocklet(
|
|
117
117
|
blocklet,
|
|
118
118
|
async (component, { id: componentId, ancestors }) => {
|
|
119
|
-
if (component.meta.group !== BlockletGroup.gateway) {
|
|
119
|
+
if (component.meta.group !== BlockletGroup.gateway && component.status === BlockletStatus.running) {
|
|
120
120
|
const processId = getComponentProcessId(component, ancestors);
|
|
121
121
|
try {
|
|
122
122
|
const runtimeInfo = await getRuntimeInfo(processId);
|
|
@@ -130,8 +130,13 @@ class BlockletRuntimeMonitor extends EventEmitter {
|
|
|
130
130
|
appCpu += runtimeInfo.cpuUsage || 0;
|
|
131
131
|
appMem += runtimeInfo.memoryUsage || 0;
|
|
132
132
|
} catch (err) {
|
|
133
|
-
|
|
133
|
+
// component status in db may not sync with pm2 when server has just started
|
|
134
|
+
if (err.code !== 'BLOCKLET_PROCESS_404') {
|
|
135
|
+
this.logger.error('failed to get blocklet runtime info', { processId, error: err });
|
|
136
|
+
}
|
|
134
137
|
}
|
|
138
|
+
} else {
|
|
139
|
+
delete this.data[blockletDid][componentId];
|
|
135
140
|
}
|
|
136
141
|
},
|
|
137
142
|
{ parallel: true }
|
package/lib/processes/updater.js
CHANGED
|
@@ -109,7 +109,7 @@ const verifyBlockletServer = async (version) => {
|
|
|
109
109
|
};
|
|
110
110
|
|
|
111
111
|
// Restart Blocklet Server
|
|
112
|
-
const restartBlockletServer =
|
|
112
|
+
const restartBlockletServer = (dataDir) => {
|
|
113
113
|
// We put this in the event loop because it will terminate the current node process
|
|
114
114
|
// But we need to wait for the session state to transition from restarting to cleanup
|
|
115
115
|
process.nextTick(async () => {
|
package/lib/router/helper.js
CHANGED
|
@@ -168,7 +168,7 @@ const ensureServiceRule = async (sites) => {
|
|
|
168
168
|
return site;
|
|
169
169
|
});
|
|
170
170
|
};
|
|
171
|
-
const ensureRootRule =
|
|
171
|
+
const ensureRootRule = (sites) => {
|
|
172
172
|
return sites.map((site) => {
|
|
173
173
|
if (!isBasicSite(site.domain) && !site.rules.some((x) => x.from.pathPrefix === '/')) {
|
|
174
174
|
site.rules.push({
|
|
@@ -388,7 +388,7 @@ const ensureCorsForWebWallet = async (sites) => {
|
|
|
388
388
|
* @param {Array<import('@abtnode/client').BlockletState>} blocklets
|
|
389
389
|
* @return {Promise<any>}
|
|
390
390
|
*/
|
|
391
|
-
const ensureCorsForDidSpace =
|
|
391
|
+
const ensureCorsForDidSpace = (sites = [], blocklets) => {
|
|
392
392
|
return sites.map((site) => {
|
|
393
393
|
const blocklet = blocklets.find((x) => x.meta.did === site.blockletDid);
|
|
394
394
|
if (blocklet) {
|
|
@@ -404,7 +404,7 @@ const ensureCorsForDidSpace = async (sites = [], blocklets) => {
|
|
|
404
404
|
});
|
|
405
405
|
};
|
|
406
406
|
|
|
407
|
-
const filterSitesForRemovedBlocklets =
|
|
407
|
+
const filterSitesForRemovedBlocklets = (sites = [], blocklets) => {
|
|
408
408
|
return sites.filter((site) => {
|
|
409
409
|
if (!site.domain.endsWith(BLOCKLET_SITE_GROUP_SUFFIX)) {
|
|
410
410
|
return true;
|
|
@@ -420,7 +420,7 @@ const filterSitesForRemovedBlocklets = async (sites = [], blocklets) => {
|
|
|
420
420
|
*
|
|
421
421
|
* @returns {boolean} if routing changed
|
|
422
422
|
*/
|
|
423
|
-
const ensureBlockletWellknownRules =
|
|
423
|
+
const ensureBlockletWellknownRules = (sites, blocklets) => {
|
|
424
424
|
/**
|
|
425
425
|
* 1. component blocklet 不允许有相同多的 wellknown
|
|
426
426
|
* 1. wellknown 可以访问的路由:
|
|
@@ -488,7 +488,7 @@ const ensureBlockletWellknownRules = async (sites, blocklets) => {
|
|
|
488
488
|
.filter(Boolean);
|
|
489
489
|
};
|
|
490
490
|
|
|
491
|
-
const ensureBlockletCache =
|
|
491
|
+
const ensureBlockletCache = (sites = [], blocklets) => {
|
|
492
492
|
return sites
|
|
493
493
|
.map((site) => {
|
|
494
494
|
if (!site.domain.endsWith(BLOCKLET_SITE_GROUP_SUFFIX)) {
|
package/lib/states/audit-log.js
CHANGED
package/lib/states/backup.js
CHANGED
|
@@ -35,7 +35,7 @@ class BackupState extends BaseState {
|
|
|
35
35
|
/**
|
|
36
36
|
* @param {Pick<import('@abtnode/models').BackupState, 'appPid' | 'userDid' | 'strategy' | 'sourceUrl' | 'target'>} backup
|
|
37
37
|
*/
|
|
38
|
-
|
|
38
|
+
start(backup) {
|
|
39
39
|
const { error, value } = validateBackupStart.validate(backup, {
|
|
40
40
|
stripUnknown: true,
|
|
41
41
|
allowUnknown: true,
|
|
@@ -52,7 +52,7 @@ class BackupState extends BaseState {
|
|
|
52
52
|
* @param {string} id
|
|
53
53
|
* @param {Pick<import('@abtnode/models').BackupState, 'targetUrl'>} successBackupInfo
|
|
54
54
|
*/
|
|
55
|
-
|
|
55
|
+
success(id, successBackupInfo) {
|
|
56
56
|
const { error, value } = validateBackupSuccess.validate(successBackupInfo, {
|
|
57
57
|
stripUnknown: true,
|
|
58
58
|
allowUnknown: true,
|
|
@@ -78,7 +78,7 @@ class BackupState extends BaseState {
|
|
|
78
78
|
* @param {string} id
|
|
79
79
|
* @param {Pick<import('@abtnode/models').BackupState, 'message'>} errorBackupInfo
|
|
80
80
|
*/
|
|
81
|
-
|
|
81
|
+
fail(id, errorBackupInfo) {
|
|
82
82
|
const { error, value } = validateBackupFail.validate(errorBackupInfo, {
|
|
83
83
|
stripUnknown: true,
|
|
84
84
|
allowUnknown: true,
|
|
@@ -104,6 +104,7 @@ class BackupState extends BaseState {
|
|
|
104
104
|
* @param {import('@abtnode/models').BackupState} backup
|
|
105
105
|
* @return {Promise<import('@abtnode/models').BackupState>}
|
|
106
106
|
*/
|
|
107
|
+
// eslint-disable-next-line require-await
|
|
107
108
|
async create(backup) {
|
|
108
109
|
const { error, value } = validateBackup.validate(backup, {
|
|
109
110
|
allowUnknown: true,
|
|
@@ -121,7 +122,7 @@ class BackupState extends BaseState {
|
|
|
121
122
|
* @param {{ did: string }} { did }
|
|
122
123
|
* @return {Promise<Array<import('@abtnode/models').BackupState>>}
|
|
123
124
|
*/
|
|
124
|
-
|
|
125
|
+
getBlockletBackups({ did }) {
|
|
125
126
|
return this.find({ appPid: did }, {}, { updatedAt: -1 });
|
|
126
127
|
}
|
|
127
128
|
}
|
|
@@ -207,10 +207,20 @@ class BlockletExtrasState extends BaseState {
|
|
|
207
207
|
return super.upsert({ did }, { $set: entity });
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
|
|
210
|
+
getMeta(did) {
|
|
211
211
|
return super.findOne({ did }, { did: 1, controller: 1, meta: 1 });
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
+
async isLauncherSessionConsumed(sessionId) {
|
|
215
|
+
const count = await super.count({ 'controller.sessionId': sessionId });
|
|
216
|
+
return count > 0;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
async isLauncherNftConsumed(nftId) {
|
|
220
|
+
const count = await super.count({ 'controller.nftId': nftId });
|
|
221
|
+
return count > 0;
|
|
222
|
+
}
|
|
223
|
+
|
|
214
224
|
encryptSecurityData({ data, _rootDid } = {}) {
|
|
215
225
|
if (!data) {
|
|
216
226
|
return data;
|