@abtnode/core 1.8.65-beta-5405baf2 → 1.8.65-beta-bfcc12ce
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.js +1 -0
- package/lib/blocklet/downloader/blocklet-downloader.js +33 -12
- package/lib/blocklet/manager/disk.js +293 -217
- package/lib/blocklet/manager/helper/install-from-backup.js +13 -4
- package/lib/blocklet/manager/helper/rollback-cache.js +41 -0
- package/lib/blocklet/storage/backup/blocklet-extras.js +4 -0
- package/lib/blocklet/storage/backup/blocklets.js +23 -29
- package/lib/blocklet/storage/backup/data.js +2 -2
- package/lib/blocklet/storage/backup/logs.js +3 -2
- package/lib/blocklet/storage/backup/spaces.js +3 -14
- package/lib/blocklet/storage/restore/blocklet-extras.js +8 -3
- package/lib/blocklet/storage/restore/blocklets.js +29 -11
- package/lib/blocklet/storage/restore/logs.js +21 -0
- package/lib/blocklet/storage/restore/spaces.js +6 -1
- package/lib/blocklet/storage/utils/hash.js +51 -0
- package/lib/blocklet/storage/utils/zip.js +43 -0
- package/lib/router/helper.js +82 -9
- package/lib/router/index.js +8 -1
- package/lib/states/blocklet.js +5 -2
- package/lib/util/blocklet.js +10 -7
- package/lib/validators/router.js +7 -1
- package/package.json +27 -25
|
@@ -129,6 +129,7 @@ const { SpacesRestore } = require('../storage/restore/spaces');
|
|
|
129
129
|
const installFromBackup = require('./helper/install-from-backup');
|
|
130
130
|
const { resolveDownload, resolveDiffDownload } = require('../downloader/resolve-download');
|
|
131
131
|
const BlockletDownloader = require('../downloader/blocklet-downloader');
|
|
132
|
+
const RollbackCache = require('./helper/rollback-cache');
|
|
132
133
|
|
|
133
134
|
const {
|
|
134
135
|
isInProgress,
|
|
@@ -218,6 +219,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
218
219
|
cache: states.cache,
|
|
219
220
|
});
|
|
220
221
|
|
|
222
|
+
this._rollbackCache = new RollbackCache({ dir: this.dataDirs.tmp });
|
|
223
|
+
|
|
221
224
|
if (daemon) {
|
|
222
225
|
blockletPm2Events.on('online', (data) => this._syncPm2Status('online', data.blockletDid));
|
|
223
226
|
blockletPm2Events.on('stop', (data) => this._syncPm2Status('stop', data.blockletDid));
|
|
@@ -255,6 +258,10 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
255
258
|
async install(params, context = {}) {
|
|
256
259
|
logger.debug('install blocklet', { params, context });
|
|
257
260
|
|
|
261
|
+
if (!params.controller && context?.user?.controller) {
|
|
262
|
+
params.controller = context.user.controller;
|
|
263
|
+
}
|
|
264
|
+
|
|
258
265
|
const info = await states.node.read();
|
|
259
266
|
|
|
260
267
|
context.headers = Object.assign(context?.headers || {}, {
|
|
@@ -444,6 +451,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
444
451
|
|
|
445
452
|
async start({ did, throwOnError, checkHealthImmediately = false, e2eMode = false }, context) {
|
|
446
453
|
logger.info('start blocklet', { did });
|
|
454
|
+
// should check blocklet integrity
|
|
447
455
|
const blocklet = await this.ensureBlocklet(did, { e2eMode });
|
|
448
456
|
|
|
449
457
|
try {
|
|
@@ -557,7 +565,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
557
565
|
async stop({ did, updateStatus = true, silent = false }, context) {
|
|
558
566
|
logger.info('stop blocklet', { did });
|
|
559
567
|
|
|
560
|
-
const blocklet = await this.
|
|
568
|
+
const blocklet = await this.getBlocklet(did);
|
|
561
569
|
const { processId } = blocklet.env;
|
|
562
570
|
|
|
563
571
|
if (updateStatus) {
|
|
@@ -655,7 +663,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
655
663
|
|
|
656
664
|
// eslint-disable-next-line no-unused-vars
|
|
657
665
|
async reload({ did }, context) {
|
|
658
|
-
const blocklet = await this.
|
|
666
|
+
const blocklet = await this.getBlocklet(did);
|
|
659
667
|
|
|
660
668
|
await states.blocklet.setBlockletStatus(did, BlockletStatus.stopping);
|
|
661
669
|
await reloadBlockletProcess(blocklet);
|
|
@@ -671,13 +679,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
671
679
|
logger.info('delete blocklet', { did, keepData });
|
|
672
680
|
|
|
673
681
|
try {
|
|
674
|
-
const blocklet = await this.
|
|
682
|
+
const blocklet = await this.getBlocklet(did);
|
|
675
683
|
if (isDeletableBlocklet(blocklet) === false) {
|
|
676
684
|
throw new Error('Blocklet is protected from accidental deletion');
|
|
677
685
|
}
|
|
678
686
|
|
|
679
687
|
const nodeEnvironments = await states.node.getEnvironments();
|
|
680
|
-
|
|
681
688
|
await deleteBlockletProcess(blocklet, {
|
|
682
689
|
preDelete: (b, { ancestors }) =>
|
|
683
690
|
hooks.preUninstall(b.env.processId, {
|
|
@@ -700,31 +707,27 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
700
707
|
severity: 'success',
|
|
701
708
|
});
|
|
702
709
|
return doc;
|
|
703
|
-
} catch (
|
|
710
|
+
} catch (error) {
|
|
704
711
|
// If we installed a corrupted blocklet accidentally, just cleanup the disk and state db
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
const doc = await this._deleteBlocklet({ did, keepData, keepLogsDir, keepConfigs }, context);
|
|
708
|
-
|
|
709
|
-
this._createNotification(doc.meta.did, {
|
|
710
|
-
title: 'Blocklet Deleted',
|
|
711
|
-
description: `Blocklet ${doc.meta.name}@${doc.meta.version} is deleted.`,
|
|
712
|
-
entityType: 'blocklet',
|
|
713
|
-
entityId: doc.meta.did,
|
|
714
|
-
severity: 'success',
|
|
715
|
-
});
|
|
712
|
+
logger.error('blocklet delete failed, will delete again', { did, error });
|
|
713
|
+
const doc = await this._deleteBlocklet({ did, keepData, keepLogsDir, keepConfigs }, context);
|
|
716
714
|
|
|
717
|
-
|
|
718
|
-
|
|
715
|
+
this._createNotification(doc.meta.did, {
|
|
716
|
+
title: 'Blocklet Deleted',
|
|
717
|
+
description: `Blocklet ${doc.meta.name}@${doc.meta.version} is deleted.`,
|
|
718
|
+
entityType: 'blocklet',
|
|
719
|
+
entityId: doc.meta.did,
|
|
720
|
+
severity: 'success',
|
|
721
|
+
});
|
|
719
722
|
|
|
720
|
-
|
|
723
|
+
return doc;
|
|
721
724
|
}
|
|
722
725
|
}
|
|
723
726
|
|
|
724
727
|
async reset({ did, childDid }, context = {}) {
|
|
725
728
|
logger.info('reset blocklet', { did, childDid });
|
|
726
729
|
|
|
727
|
-
const blocklet = await this.
|
|
730
|
+
const blocklet = await this.getBlocklet(did);
|
|
728
731
|
|
|
729
732
|
if (isInProgress(blocklet.status || blocklet.status === BlockletStatus.running)) {
|
|
730
733
|
throw new Error('Cannot reset when blocklet is in progress');
|
|
@@ -774,7 +777,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
774
777
|
async deleteComponent({ did, rootDid, keepData, keepState }, context) {
|
|
775
778
|
logger.info('delete blocklet component', { did, rootDid, keepData });
|
|
776
779
|
|
|
777
|
-
const blocklet = await this.
|
|
780
|
+
const blocklet = await this.getBlocklet(rootDid);
|
|
778
781
|
const child = blocklet.children.find((x) => x.meta.did === did);
|
|
779
782
|
if (!child) {
|
|
780
783
|
throw new Error('Component does not exist');
|
|
@@ -828,7 +831,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
828
831
|
await states.blockletExtras.delConfigs([blocklet.meta.did, child.meta.did]);
|
|
829
832
|
}
|
|
830
833
|
|
|
831
|
-
const newBlocklet = await this.
|
|
834
|
+
const newBlocklet = await this.getBlocklet(rootDid);
|
|
832
835
|
this.emit(BlockletEvents.upgraded, { blocklet: newBlocklet, context: { ...context, createAuditLog: false } }); // trigger router refresh
|
|
833
836
|
|
|
834
837
|
this._createNotification(newBlocklet.meta.did, {
|
|
@@ -843,12 +846,13 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
843
846
|
return newBlocklet;
|
|
844
847
|
}
|
|
845
848
|
|
|
849
|
+
// eslint-disable-next-line no-unused-vars
|
|
846
850
|
async cancelDownload({ did: inputDid }, context) {
|
|
847
851
|
try {
|
|
848
852
|
await statusLock.acquire();
|
|
849
853
|
const blocklet = await states.blocklet.getBlocklet(inputDid);
|
|
850
854
|
if (!blocklet) {
|
|
851
|
-
throw new Error(
|
|
855
|
+
throw new Error(`Can not cancel download for non-exist blocklet in database. did: ${inputDid}`);
|
|
852
856
|
}
|
|
853
857
|
|
|
854
858
|
const { name, did, version } = blocklet.meta;
|
|
@@ -858,15 +862,35 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
858
862
|
}
|
|
859
863
|
|
|
860
864
|
const job = await this.installQueue.get(did);
|
|
861
|
-
if (job) {
|
|
862
|
-
const { postAction, oldBlocklet } = job;
|
|
863
|
-
await this._rollback(postAction, did, oldBlocklet);
|
|
864
|
-
}
|
|
865
865
|
|
|
866
|
+
// cancel job
|
|
866
867
|
if (blocklet.status === BlockletStatus.downloading) {
|
|
867
|
-
|
|
868
|
+
try {
|
|
869
|
+
await this.blockletDownloader.cancelDownload(blocklet.meta.did);
|
|
870
|
+
} catch (error) {
|
|
871
|
+
logger.error('failed to exec blockletDownloader.download', { did: blocklet.meta.did, error });
|
|
872
|
+
}
|
|
868
873
|
} else if (blocklet.status === BlockletStatus.waiting) {
|
|
869
|
-
|
|
874
|
+
try {
|
|
875
|
+
await this.installQueue.cancel(blocklet.meta.did);
|
|
876
|
+
} catch (error) {
|
|
877
|
+
logger.error('failed to cancel waiting', { did: blocklet.meta.did, error });
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// rollback
|
|
882
|
+
if (job) {
|
|
883
|
+
const { postAction, oldBlocklet } = job;
|
|
884
|
+
await this._rollback(postAction, did, oldBlocklet);
|
|
885
|
+
} else {
|
|
886
|
+
const data = await this._rollbackCache.restore({ did });
|
|
887
|
+
if (data) {
|
|
888
|
+
const { action, oldBlocklet } = data;
|
|
889
|
+
await this._rollback(action, did, oldBlocklet);
|
|
890
|
+
await this._rollbackCache.remove({ did });
|
|
891
|
+
} else {
|
|
892
|
+
throw new Error(`Cannot find rollback data in queue or backup file of blocklet ${inputDid}`);
|
|
893
|
+
}
|
|
870
894
|
}
|
|
871
895
|
|
|
872
896
|
logger.info('cancel download blocklet', { did, name, version, status: fromBlockletStatus(blocklet.status) });
|
|
@@ -874,14 +898,25 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
874
898
|
statusLock.release();
|
|
875
899
|
return blocklet;
|
|
876
900
|
} catch (error) {
|
|
877
|
-
|
|
901
|
+
try {
|
|
902
|
+
// fallback blocklet status to error
|
|
903
|
+
const blocklet = await states.blocklet.getBlocklet(inputDid);
|
|
904
|
+
if (blocklet) {
|
|
905
|
+
await states.blocklet.setBlockletStatus(blocklet.meta.did, BlockletStatus.error);
|
|
906
|
+
}
|
|
907
|
+
statusLock.release();
|
|
908
|
+
} catch (err) {
|
|
909
|
+
statusLock.release();
|
|
910
|
+
logger.error('Failed to fallback blocklet status to error on cancelDownload', { error });
|
|
911
|
+
}
|
|
912
|
+
|
|
878
913
|
throw error;
|
|
879
914
|
}
|
|
880
915
|
}
|
|
881
916
|
|
|
882
917
|
// eslint-disable-next-line no-unused-vars
|
|
883
918
|
async deleteProcess({ did }, context) {
|
|
884
|
-
const blocklet = await this.
|
|
919
|
+
const blocklet = await this.getBlocklet(did);
|
|
885
920
|
|
|
886
921
|
logger.info('delete blocklet process', { did });
|
|
887
922
|
|
|
@@ -904,17 +939,17 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
904
939
|
|
|
905
940
|
if (!attachRuntimeInfo) {
|
|
906
941
|
try {
|
|
907
|
-
const blocklet = await this.
|
|
942
|
+
const blocklet = await this.getBlocklet(did, { throwOnNotExist: false });
|
|
908
943
|
return blocklet;
|
|
909
944
|
} catch (e) {
|
|
910
945
|
logger.error('get blocklet detail error', { error: e });
|
|
911
|
-
return
|
|
946
|
+
return states.blocklet.getBlocklet(did);
|
|
912
947
|
}
|
|
913
948
|
}
|
|
914
949
|
|
|
915
950
|
const nodeInfo = await states.node.read();
|
|
916
951
|
|
|
917
|
-
return this.
|
|
952
|
+
return this._attachRuntimeInfo({ did, nodeInfo, diskInfo: true, context });
|
|
918
953
|
}
|
|
919
954
|
|
|
920
955
|
async attachBlockletListRuntimeInfo({ blocklets, useCache }, context) {
|
|
@@ -929,7 +964,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
929
964
|
const cachedBlocklet =
|
|
930
965
|
useCache && this.cachedBlocklets ? this.cachedBlocklets.find((y) => y.meta.did === x.meta.did) : null;
|
|
931
966
|
|
|
932
|
-
return this.
|
|
967
|
+
return this._attachRuntimeInfo({
|
|
933
968
|
did: x.meta.did,
|
|
934
969
|
nodeInfo,
|
|
935
970
|
diskInfo: false,
|
|
@@ -977,7 +1012,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
977
1012
|
const [rootDid, ...childDids] = dids;
|
|
978
1013
|
logger.info('config blocklet', { dids });
|
|
979
1014
|
|
|
980
|
-
let blocklet = await this.
|
|
1015
|
+
let blocklet = await this.getBlocklet(rootDid);
|
|
981
1016
|
for (const childDid of childDids) {
|
|
982
1017
|
blocklet = blocklet.children.find((x) => x.meta.did === childDid);
|
|
983
1018
|
if (!blocklet) {
|
|
@@ -1035,20 +1070,20 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1035
1070
|
await this.updateBlockletEnvironment(rootDid);
|
|
1036
1071
|
|
|
1037
1072
|
// response
|
|
1038
|
-
const newState = await this.
|
|
1073
|
+
const newState = await this.getBlocklet(rootDid);
|
|
1039
1074
|
this.emit(BlockletEvents.updated, newState);
|
|
1040
1075
|
return newState;
|
|
1041
1076
|
}
|
|
1042
1077
|
|
|
1043
1078
|
async configPublicToStore({ did, publicToStore = false }) {
|
|
1044
|
-
const blocklet = await this.
|
|
1079
|
+
const blocklet = await this.getBlocklet(did);
|
|
1045
1080
|
// publicToStore 由用户传入
|
|
1046
1081
|
// handleInstanceInStore 方法写在前面,保证向 store 操作成功后才会更改 blocklet 中的 publicToStore值
|
|
1047
1082
|
// handleInstanceInStore 中会校验修改 publicToStore字段 的条件,不符合则会抛错,就不会执行下面更新 publicToStore 的逻辑
|
|
1048
1083
|
await handleInstanceInStore(blocklet, { publicToStore });
|
|
1049
1084
|
await states.blockletExtras.setSettings(did, { publicToStore });
|
|
1050
1085
|
|
|
1051
|
-
const newState = await this.
|
|
1086
|
+
const newState = await this.getBlocklet(did);
|
|
1052
1087
|
return newState;
|
|
1053
1088
|
}
|
|
1054
1089
|
|
|
@@ -1058,7 +1093,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1058
1093
|
}
|
|
1059
1094
|
await states.blockletExtras.setSettings(did, { navigations });
|
|
1060
1095
|
|
|
1061
|
-
const newState = await this.
|
|
1096
|
+
const newState = await this.getBlocklet(did);
|
|
1062
1097
|
this.emit(BlockletEvents.updated, newState);
|
|
1063
1098
|
return newState;
|
|
1064
1099
|
}
|
|
@@ -1110,7 +1145,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1110
1145
|
await states.blockletExtras.setConfigs(dids, configs);
|
|
1111
1146
|
}
|
|
1112
1147
|
|
|
1113
|
-
const blocklet = await this.
|
|
1148
|
+
const blocklet = await this.getBlocklet(rootDid);
|
|
1114
1149
|
|
|
1115
1150
|
this.emit(BlockletEvents.updated, { meta: { did: blocklet.meta.did } });
|
|
1116
1151
|
|
|
@@ -1158,7 +1193,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1158
1193
|
// trigger dashboard frontend refresh
|
|
1159
1194
|
this.emit(BlockletEvents.updated, blocklet);
|
|
1160
1195
|
|
|
1161
|
-
return this.
|
|
1196
|
+
return this.getBlocklet(rootDid);
|
|
1162
1197
|
}
|
|
1163
1198
|
|
|
1164
1199
|
async updateComponentMountPoint({ did, rootDid: inputRootDid, mountPoint }, context) {
|
|
@@ -1194,7 +1229,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1194
1229
|
|
|
1195
1230
|
this.emit(BlockletEvents.upgraded, { blocklet, context: { ...context, createAuditLog: false } }); // trigger router refresh
|
|
1196
1231
|
|
|
1197
|
-
return this.
|
|
1232
|
+
return this.getBlocklet(rootDid);
|
|
1198
1233
|
}
|
|
1199
1234
|
|
|
1200
1235
|
/**
|
|
@@ -1429,6 +1464,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1429
1464
|
|
|
1430
1465
|
this.emit(BlockletEvents.statusChange, newBlocklet);
|
|
1431
1466
|
|
|
1467
|
+
// backup rollback data
|
|
1468
|
+
await this._rollbackCache.backup({ did, action, oldBlocklet });
|
|
1469
|
+
|
|
1432
1470
|
// add to queue
|
|
1433
1471
|
const ticket = this.installQueue.push(
|
|
1434
1472
|
{
|
|
@@ -1540,6 +1578,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1540
1578
|
|
|
1541
1579
|
// Add Config
|
|
1542
1580
|
await this._setConfigsFromMeta(did);
|
|
1581
|
+
|
|
1582
|
+
// should ensure blocklet integrity
|
|
1543
1583
|
let blocklet = await this.ensureBlocklet(did);
|
|
1544
1584
|
|
|
1545
1585
|
// pre install
|
|
@@ -1547,14 +1587,14 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1547
1587
|
|
|
1548
1588
|
// Add environments
|
|
1549
1589
|
await this.updateBlockletEnvironment(did);
|
|
1550
|
-
blocklet = await this.
|
|
1590
|
+
blocklet = await this.getBlocklet(did);
|
|
1551
1591
|
|
|
1552
1592
|
// post install
|
|
1553
1593
|
await this._runPostInstallHook(blocklet);
|
|
1554
1594
|
|
|
1555
1595
|
await states.blocklet.setBlockletStatus(did, BlockletStatus.installed);
|
|
1556
1596
|
|
|
1557
|
-
blocklet = await this.
|
|
1597
|
+
blocklet = await this.getBlocklet(did);
|
|
1558
1598
|
|
|
1559
1599
|
await fs.writeFile(path.join(blocklet.env.dataDir, 'logo.svg'), createDidLogo(blocklet.meta.did));
|
|
1560
1600
|
|
|
@@ -1607,6 +1647,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1607
1647
|
|
|
1608
1648
|
// Add Config
|
|
1609
1649
|
await this._setConfigsFromMeta(rootDid);
|
|
1650
|
+
|
|
1651
|
+
// should ensure blocklet integrity
|
|
1610
1652
|
let blocklet = await this.ensureBlocklet(rootDid);
|
|
1611
1653
|
|
|
1612
1654
|
// pre install
|
|
@@ -1614,14 +1656,14 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1614
1656
|
|
|
1615
1657
|
// Add environments
|
|
1616
1658
|
await this.updateBlockletEnvironment(rootDid);
|
|
1617
|
-
blocklet = await this.
|
|
1659
|
+
blocklet = await this.getBlocklet(rootDid);
|
|
1618
1660
|
|
|
1619
1661
|
// post install
|
|
1620
1662
|
await this._runPostInstallHook(blocklet);
|
|
1621
1663
|
|
|
1622
1664
|
logger.info('add blocklet component for dev', { did, version, meta });
|
|
1623
1665
|
|
|
1624
|
-
blocklet = await this.
|
|
1666
|
+
blocklet = await this.getBlocklet(rootDid);
|
|
1625
1667
|
|
|
1626
1668
|
return blocklet;
|
|
1627
1669
|
}
|
|
@@ -1645,7 +1687,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1645
1687
|
}
|
|
1646
1688
|
|
|
1647
1689
|
async ensureBlocklet(did, opts = {}) {
|
|
1648
|
-
return getBlocklet({ ...opts, states, dataDirs: this.dataDirs, did });
|
|
1690
|
+
return getBlocklet({ ...opts, states, dataDirs: this.dataDirs, did, ensureIntegrity: true });
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
async getBlocklet(did, opts = {}) {
|
|
1694
|
+
return getBlocklet({ ...opts, states, dataDirs: this.dataDirs, did, ensureIntegrity: false });
|
|
1649
1695
|
}
|
|
1650
1696
|
|
|
1651
1697
|
async hasBlocklet({ did }) {
|
|
@@ -1663,7 +1709,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1663
1709
|
|
|
1664
1710
|
this.emit(BlockletEvents.updated, { meta: { did: blocklet.meta.did } });
|
|
1665
1711
|
|
|
1666
|
-
return this.
|
|
1712
|
+
return this.getBlocklet(did);
|
|
1667
1713
|
}
|
|
1668
1714
|
|
|
1669
1715
|
async status(did, { forceSync = false } = {}) {
|
|
@@ -1680,7 +1726,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1680
1726
|
return res;
|
|
1681
1727
|
};
|
|
1682
1728
|
|
|
1683
|
-
const blocklet = await this.
|
|
1729
|
+
const blocklet = await this.getBlocklet(did);
|
|
1684
1730
|
|
|
1685
1731
|
let shouldUpdateStatus = forceSync || shouldUpdateBlockletStatus(blocklet.status);
|
|
1686
1732
|
if (isInProgress(blocklet.status)) {
|
|
@@ -1709,80 +1755,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1709
1755
|
}
|
|
1710
1756
|
}
|
|
1711
1757
|
|
|
1712
|
-
async attachRuntimeInfo({ did, nodeInfo, diskInfo = true, context, cachedBlocklet }) {
|
|
1713
|
-
if (!did) {
|
|
1714
|
-
throw new Error('did should not be empty');
|
|
1715
|
-
}
|
|
1716
|
-
|
|
1717
|
-
try {
|
|
1718
|
-
const blocklet = await this.ensureBlocklet(did, { throwOnNotExist: false });
|
|
1719
|
-
|
|
1720
|
-
if (!blocklet) {
|
|
1721
|
-
return null;
|
|
1722
|
-
}
|
|
1723
|
-
|
|
1724
|
-
const fromCache = !!cachedBlocklet;
|
|
1725
|
-
|
|
1726
|
-
// if from cached data, only use cache data of runtime info (engine, diskInfo, runtimeInfo...)
|
|
1727
|
-
if (fromCache) {
|
|
1728
|
-
const cached = {};
|
|
1729
|
-
forEachBlockletSync(cachedBlocklet, (component, { id }) => {
|
|
1730
|
-
cached[id] = component;
|
|
1731
|
-
});
|
|
1732
|
-
|
|
1733
|
-
Object.assign(blocklet, pick(cachedBlocklet, ['appRuntimeInfo', 'diskInfo']));
|
|
1734
|
-
|
|
1735
|
-
forEachBlockletSync(blocklet, (component, { id }) => {
|
|
1736
|
-
if (cached[id]) {
|
|
1737
|
-
Object.assign(component, pick(cached[id], ['runtimeInfo']));
|
|
1738
|
-
}
|
|
1739
|
-
});
|
|
1740
|
-
}
|
|
1741
|
-
|
|
1742
|
-
// 处理 domainAliases#value SLOT_FOR_IP_DNS_SITE
|
|
1743
|
-
if (blocklet?.site?.domainAliases?.length) {
|
|
1744
|
-
const nodeIp = await getAccessibleExternalNodeIp(nodeInfo);
|
|
1745
|
-
blocklet.site.domainAliases = blocklet.site.domainAliases.map((x) => ({
|
|
1746
|
-
...x,
|
|
1747
|
-
value: util.replaceDomainSlot({ domain: x.value, context, nodeIp }),
|
|
1748
|
-
}));
|
|
1749
|
-
}
|
|
1750
|
-
|
|
1751
|
-
// app runtime info, app status
|
|
1752
|
-
blocklet.appRuntimeInfo = this.runtimeMonitor.getRuntimeInfo(blocklet.meta.did);
|
|
1753
|
-
|
|
1754
|
-
if (!fromCache) {
|
|
1755
|
-
// app disk info, component runtime info, component status, component engine
|
|
1756
|
-
await forEachBlocklet(blocklet, async (component, { level }) => {
|
|
1757
|
-
component.engine = getEngine(getBlockletEngineNameByPlatform(component.meta)).describe();
|
|
1758
|
-
|
|
1759
|
-
if (level === 0) {
|
|
1760
|
-
component.diskInfo = await getDiskInfo(component, {
|
|
1761
|
-
useFakeDiskInfo: !diskInfo,
|
|
1762
|
-
});
|
|
1763
|
-
}
|
|
1764
|
-
|
|
1765
|
-
component.runtimeInfo = this.runtimeMonitor.getRuntimeInfo(blocklet.meta.did, component.env.id);
|
|
1766
|
-
|
|
1767
|
-
if (component.runtimeInfo?.status && shouldUpdateBlockletStatus(component.status)) {
|
|
1768
|
-
component.status = statusMap[component.runtimeInfo.status];
|
|
1769
|
-
}
|
|
1770
|
-
});
|
|
1771
|
-
}
|
|
1772
|
-
|
|
1773
|
-
return blocklet;
|
|
1774
|
-
} catch (err) {
|
|
1775
|
-
const simpleState = await states.blocklet.getBlocklet(did);
|
|
1776
|
-
logger.error('failed to get blocklet info', {
|
|
1777
|
-
did,
|
|
1778
|
-
name: get(simpleState, 'meta.name'),
|
|
1779
|
-
status: get(simpleState, 'status'),
|
|
1780
|
-
error: err,
|
|
1781
|
-
});
|
|
1782
|
-
return simpleState;
|
|
1783
|
-
}
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
1758
|
async refreshListCache() {
|
|
1787
1759
|
this.list({ useCache: false }).catch((err) => {
|
|
1788
1760
|
logger.error('refresh blocklet list failed', { error: err });
|
|
@@ -1792,7 +1764,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1792
1764
|
async onJob(job) {
|
|
1793
1765
|
if (job.entity === 'blocklet') {
|
|
1794
1766
|
if (job.action === 'download') {
|
|
1795
|
-
await this.
|
|
1767
|
+
await this.downloadAndInstall(job);
|
|
1796
1768
|
}
|
|
1797
1769
|
if (job.action === 'restart') {
|
|
1798
1770
|
await this.onRestart(job);
|
|
@@ -1817,33 +1789,35 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1817
1789
|
* @return {*}
|
|
1818
1790
|
* @memberof BlockletManager
|
|
1819
1791
|
*/
|
|
1820
|
-
async
|
|
1821
|
-
const { blocklet, context, postAction, oldBlocklet, throwOnError } = params;
|
|
1792
|
+
async downloadAndInstall(params) {
|
|
1793
|
+
const { blocklet, context, postAction, oldBlocklet, throwOnError, skipCheckStatusBeforeDownload } = params;
|
|
1822
1794
|
const { meta } = blocklet;
|
|
1823
1795
|
const { name, did, version } = meta;
|
|
1824
1796
|
|
|
1825
1797
|
// check status
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
if (!b0) {
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1798
|
+
if (!skipCheckStatusBeforeDownload) {
|
|
1799
|
+
try {
|
|
1800
|
+
await statusLock.acquire();
|
|
1801
|
+
|
|
1802
|
+
const b0 = await states.blocklet.getBlocklet(did);
|
|
1803
|
+
if (!b0 || ![BlockletStatus.waiting].includes(b0.status)) {
|
|
1804
|
+
if (!b0) {
|
|
1805
|
+
throw new Error('blocklet does not exist before downloading');
|
|
1806
|
+
} else {
|
|
1807
|
+
throw new Error(`blocklet status is invalid before downloading: ${fromBlockletStatus(b0.status)}`);
|
|
1808
|
+
}
|
|
1835
1809
|
}
|
|
1810
|
+
statusLock.release();
|
|
1811
|
+
} catch (error) {
|
|
1812
|
+
statusLock.release();
|
|
1813
|
+
logger.error('Check blocklet status failed before downloading', {
|
|
1814
|
+
name,
|
|
1815
|
+
did,
|
|
1816
|
+
error,
|
|
1817
|
+
});
|
|
1818
|
+
await this._rollback(postAction, did, oldBlocklet);
|
|
1819
|
+
return;
|
|
1836
1820
|
}
|
|
1837
|
-
statusLock.release();
|
|
1838
|
-
} catch (error) {
|
|
1839
|
-
statusLock.release();
|
|
1840
|
-
logger.error('Check blocklet status failed before downloading', {
|
|
1841
|
-
name,
|
|
1842
|
-
did,
|
|
1843
|
-
error,
|
|
1844
|
-
});
|
|
1845
|
-
await this._rollback(postAction, did, oldBlocklet);
|
|
1846
|
-
return;
|
|
1847
1821
|
}
|
|
1848
1822
|
|
|
1849
1823
|
// download bundle
|
|
@@ -1853,8 +1827,16 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1853
1827
|
if (isCancelled) {
|
|
1854
1828
|
logger.info('Download was canceled', { name, did, version });
|
|
1855
1829
|
|
|
1856
|
-
|
|
1857
|
-
|
|
1830
|
+
// rollback on download cancelled
|
|
1831
|
+
await statusLock.acquire();
|
|
1832
|
+
try {
|
|
1833
|
+
if ((await states.blocklet.getBlockletStatus(did)) === BlockletStatus.downloading) {
|
|
1834
|
+
await this._rollback(postAction, did, oldBlocklet);
|
|
1835
|
+
}
|
|
1836
|
+
statusLock.release();
|
|
1837
|
+
} catch (error) {
|
|
1838
|
+
statusLock.release();
|
|
1839
|
+
logger.error('Rollback blocklet failed on download canceled', { postAction, name, did, version, error });
|
|
1858
1840
|
}
|
|
1859
1841
|
return;
|
|
1860
1842
|
}
|
|
@@ -1875,10 +1857,16 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1875
1857
|
severity: 'error',
|
|
1876
1858
|
});
|
|
1877
1859
|
|
|
1860
|
+
// rollback on download failed
|
|
1861
|
+
await statusLock.acquire();
|
|
1878
1862
|
try {
|
|
1879
|
-
await
|
|
1880
|
-
|
|
1881
|
-
|
|
1863
|
+
if ((await states.blocklet.getBlockletStatus(did)) === BlockletStatus.downloading) {
|
|
1864
|
+
await this._rollback(postAction, did, oldBlocklet);
|
|
1865
|
+
}
|
|
1866
|
+
statusLock.release();
|
|
1867
|
+
} catch (error) {
|
|
1868
|
+
statusLock.release();
|
|
1869
|
+
logger.error('Rollback blocklet failed on download failed', { postAction, name, did, version, error });
|
|
1882
1870
|
}
|
|
1883
1871
|
|
|
1884
1872
|
if (throwOnError) {
|
|
@@ -1981,7 +1969,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1981
1969
|
|
|
1982
1970
|
async onCheckIfStarted(jobInfo, { throwOnError } = {}) {
|
|
1983
1971
|
const { did, context, minConsecutiveTime = 5000, timeout } = jobInfo;
|
|
1984
|
-
const blocklet = await this.
|
|
1972
|
+
const blocklet = await this.getBlocklet(did);
|
|
1985
1973
|
|
|
1986
1974
|
const { meta } = blocklet;
|
|
1987
1975
|
const { name } = meta;
|
|
@@ -2022,7 +2010,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2022
2010
|
}
|
|
2023
2011
|
|
|
2024
2012
|
async updateBlockletEnvironment(did) {
|
|
2025
|
-
const blockletWithEnv = await this.
|
|
2013
|
+
const blockletWithEnv = await this.getBlocklet(did);
|
|
2026
2014
|
const blocklet = await states.blocklet.getBlocklet(did);
|
|
2027
2015
|
const nodeInfo = await states.node.read();
|
|
2028
2016
|
|
|
@@ -2406,13 +2394,20 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2406
2394
|
newBlocklet.deployedFrom = `Upload by ${context.user.fullName}`;
|
|
2407
2395
|
newBlocklet.children = await this._getChildrenForInstallation(meta);
|
|
2408
2396
|
await validateBlocklet(newBlocklet);
|
|
2409
|
-
await this._downloadBlocklet(newBlocklet);
|
|
2410
2397
|
|
|
2411
|
-
|
|
2398
|
+
// backup rollback data
|
|
2399
|
+
const action = 'upgrade';
|
|
2400
|
+
await this._rollbackCache.backup({ did: newBlocklet.meta.did, action, oldBlocklet });
|
|
2401
|
+
|
|
2402
|
+
await this.downloadAndInstall({
|
|
2403
|
+
blocklet: newBlocklet,
|
|
2412
2404
|
oldBlocklet,
|
|
2413
|
-
newBlocklet,
|
|
2414
2405
|
context: { ...context, forceStartProcessIds: [getComponentProcessId(newBlocklet)] },
|
|
2406
|
+
throwOnError: true,
|
|
2407
|
+
postAction: action,
|
|
2408
|
+
skipCheckStatusBeforeDownload: true,
|
|
2415
2409
|
});
|
|
2410
|
+
return this.getBlocklet(newBlocklet.meta.did);
|
|
2416
2411
|
}
|
|
2417
2412
|
|
|
2418
2413
|
// full deploy
|
|
@@ -2432,14 +2427,20 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2432
2427
|
newBlocklet.deployedFrom = `Upload by ${context.user.fullName}`;
|
|
2433
2428
|
newBlocklet.children = await this._getChildrenForInstallation(meta);
|
|
2434
2429
|
|
|
2435
|
-
|
|
2436
|
-
|
|
2430
|
+
// backup rollback data
|
|
2431
|
+
const action = 'upgrade';
|
|
2432
|
+
await this._rollbackCache.backup({ did: newBlocklet.meta.did, action, oldBlocklet });
|
|
2437
2433
|
|
|
2438
|
-
|
|
2434
|
+
await validateBlocklet(newBlocklet);
|
|
2435
|
+
await this.downloadAndInstall({
|
|
2436
|
+
blocklet: newBlocklet,
|
|
2439
2437
|
oldBlocklet,
|
|
2440
|
-
newBlocklet,
|
|
2441
2438
|
context: { ...context, forceStartProcessIds: [getComponentProcessId(newBlocklet)] },
|
|
2439
|
+
throwOnError: true,
|
|
2440
|
+
postAction: action,
|
|
2441
|
+
skipCheckStatusBeforeDownload: true,
|
|
2442
2442
|
});
|
|
2443
|
+
return this.getBlocklet(newBlocklet.meta.did);
|
|
2443
2444
|
}
|
|
2444
2445
|
|
|
2445
2446
|
// full deploy - install
|
|
@@ -2453,25 +2454,31 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2453
2454
|
children,
|
|
2454
2455
|
});
|
|
2455
2456
|
|
|
2457
|
+
const action = 'install';
|
|
2458
|
+
const oldState = { extraState: oldExtraState };
|
|
2456
2459
|
try {
|
|
2457
2460
|
await this._setConfigsFromMeta(meta.did);
|
|
2458
2461
|
await validateBlocklet(blocklet);
|
|
2459
2462
|
|
|
2460
2463
|
// check duplicate appSk
|
|
2461
2464
|
await checkDuplicateAppSk({ did: meta.did, states });
|
|
2462
|
-
|
|
2463
|
-
// download
|
|
2464
|
-
await this._downloadBlocklet(blocklet);
|
|
2465
|
-
|
|
2466
|
-
return this._installBlocklet({
|
|
2467
|
-
did: meta.did,
|
|
2468
|
-
context,
|
|
2469
|
-
oldBlocklet: { extraState: oldExtraState },
|
|
2470
|
-
});
|
|
2471
2465
|
} catch (error) {
|
|
2472
|
-
await this._rollback(
|
|
2466
|
+
await this._rollback(action, meta.did, oldState);
|
|
2473
2467
|
throw error;
|
|
2474
2468
|
}
|
|
2469
|
+
|
|
2470
|
+
// backup rollback data
|
|
2471
|
+
await this._rollbackCache.backup({ did: meta.did, action, oldBlocklet: oldState });
|
|
2472
|
+
|
|
2473
|
+
await this.downloadAndInstall({
|
|
2474
|
+
blocklet,
|
|
2475
|
+
oldBlocklet: oldState,
|
|
2476
|
+
context,
|
|
2477
|
+
throwOnError: true,
|
|
2478
|
+
postAction: action,
|
|
2479
|
+
skipCheckStatusBeforeDownload: true,
|
|
2480
|
+
});
|
|
2481
|
+
return this.getBlocklet(meta.did);
|
|
2475
2482
|
}
|
|
2476
2483
|
|
|
2477
2484
|
async _installComponentFromUpload({
|
|
@@ -2552,34 +2559,19 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2552
2559
|
|
|
2553
2560
|
await this._upsertDynamicNavigation(newBlocklet.meta.did, newChild, { skipNavigation });
|
|
2554
2561
|
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
await
|
|
2562
|
+
// backup rollback data
|
|
2563
|
+
const action = 'upgrade';
|
|
2564
|
+
await this._rollbackCache.backup({ did: newBlocklet.meta.did, action, oldBlocklet });
|
|
2558
2565
|
|
|
2559
|
-
|
|
2566
|
+
await this.downloadAndInstall({
|
|
2567
|
+
blocklet: newBlocklet,
|
|
2560
2568
|
oldBlocklet,
|
|
2561
|
-
newBlocklet,
|
|
2562
2569
|
context: { ...context, forceStartProcessIds: [getComponentProcessId(newChild, [newBlocklet])] },
|
|
2570
|
+
throwOnError: true,
|
|
2571
|
+
postAction: action,
|
|
2572
|
+
skipCheckStatusBeforeDownload: true,
|
|
2563
2573
|
});
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
/**
|
|
2567
|
-
* add to download job queue
|
|
2568
|
-
* @param {string} did blocklet did
|
|
2569
|
-
* @param {object} blocklet object
|
|
2570
|
-
*/
|
|
2571
|
-
async download(did, blocklet) {
|
|
2572
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.waiting);
|
|
2573
|
-
this.installQueue.push(
|
|
2574
|
-
{
|
|
2575
|
-
entity: 'blocklet',
|
|
2576
|
-
action: 'download',
|
|
2577
|
-
id: did,
|
|
2578
|
-
blocklet: { ...blocklet },
|
|
2579
|
-
postAction: 'install',
|
|
2580
|
-
},
|
|
2581
|
-
did
|
|
2582
|
-
);
|
|
2574
|
+
return this.getBlocklet(newBlocklet.meta.did);
|
|
2583
2575
|
}
|
|
2584
2576
|
|
|
2585
2577
|
async prune() {
|
|
@@ -2650,6 +2642,80 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2650
2642
|
];
|
|
2651
2643
|
}
|
|
2652
2644
|
|
|
2645
|
+
async _attachRuntimeInfo({ did, nodeInfo, diskInfo = true, context, cachedBlocklet }) {
|
|
2646
|
+
if (!did) {
|
|
2647
|
+
throw new Error('did should not be empty');
|
|
2648
|
+
}
|
|
2649
|
+
|
|
2650
|
+
try {
|
|
2651
|
+
const blocklet = await this.getBlocklet(did, { throwOnNotExist: false });
|
|
2652
|
+
|
|
2653
|
+
if (!blocklet) {
|
|
2654
|
+
return null;
|
|
2655
|
+
}
|
|
2656
|
+
|
|
2657
|
+
const fromCache = !!cachedBlocklet;
|
|
2658
|
+
|
|
2659
|
+
// if from cached data, only use cache data of runtime info (engine, diskInfo, runtimeInfo...)
|
|
2660
|
+
if (fromCache) {
|
|
2661
|
+
const cached = {};
|
|
2662
|
+
forEachBlockletSync(cachedBlocklet, (component, { id }) => {
|
|
2663
|
+
cached[id] = component;
|
|
2664
|
+
});
|
|
2665
|
+
|
|
2666
|
+
Object.assign(blocklet, pick(cachedBlocklet, ['appRuntimeInfo', 'diskInfo']));
|
|
2667
|
+
|
|
2668
|
+
forEachBlockletSync(blocklet, (component, { id }) => {
|
|
2669
|
+
if (cached[id]) {
|
|
2670
|
+
Object.assign(component, pick(cached[id], ['runtimeInfo']));
|
|
2671
|
+
}
|
|
2672
|
+
});
|
|
2673
|
+
}
|
|
2674
|
+
|
|
2675
|
+
// 处理 domainAliases#value SLOT_FOR_IP_DNS_SITE
|
|
2676
|
+
if (blocklet?.site?.domainAliases?.length) {
|
|
2677
|
+
const nodeIp = await getAccessibleExternalNodeIp(nodeInfo);
|
|
2678
|
+
blocklet.site.domainAliases = blocklet.site.domainAliases.map((x) => ({
|
|
2679
|
+
...x,
|
|
2680
|
+
value: util.replaceDomainSlot({ domain: x.value, context, nodeIp }),
|
|
2681
|
+
}));
|
|
2682
|
+
}
|
|
2683
|
+
|
|
2684
|
+
// app runtime info, app status
|
|
2685
|
+
blocklet.appRuntimeInfo = this.runtimeMonitor.getRuntimeInfo(blocklet.meta.did);
|
|
2686
|
+
|
|
2687
|
+
if (!fromCache) {
|
|
2688
|
+
// app disk info, component runtime info, component status, component engine
|
|
2689
|
+
await forEachBlocklet(blocklet, async (component, { level }) => {
|
|
2690
|
+
component.engine = getEngine(getBlockletEngineNameByPlatform(component.meta)).describe();
|
|
2691
|
+
|
|
2692
|
+
if (level === 0) {
|
|
2693
|
+
component.diskInfo = await getDiskInfo(component, {
|
|
2694
|
+
useFakeDiskInfo: !diskInfo,
|
|
2695
|
+
});
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
component.runtimeInfo = this.runtimeMonitor.getRuntimeInfo(blocklet.meta.did, component.env.id);
|
|
2699
|
+
|
|
2700
|
+
if (component.runtimeInfo?.status && shouldUpdateBlockletStatus(component.status)) {
|
|
2701
|
+
component.status = statusMap[component.runtimeInfo.status];
|
|
2702
|
+
}
|
|
2703
|
+
});
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
return blocklet;
|
|
2707
|
+
} catch (err) {
|
|
2708
|
+
const simpleState = await states.blocklet.getBlocklet(did);
|
|
2709
|
+
logger.error('failed to get blocklet info', {
|
|
2710
|
+
did,
|
|
2711
|
+
name: get(simpleState, 'meta.name'),
|
|
2712
|
+
status: get(simpleState, 'status'),
|
|
2713
|
+
error: err,
|
|
2714
|
+
});
|
|
2715
|
+
return simpleState;
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
|
|
2653
2719
|
async _syncBlockletStatus() {
|
|
2654
2720
|
const run = async (blocklet) => {
|
|
2655
2721
|
try {
|
|
@@ -2728,6 +2794,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2728
2794
|
const blocklet1 = await states.blocklet.setBlockletStatus(did, BlockletStatus.waiting);
|
|
2729
2795
|
this.emit(BlockletEvents.added, blocklet1);
|
|
2730
2796
|
|
|
2797
|
+
const action = 'install';
|
|
2798
|
+
const oldBlocklet = {
|
|
2799
|
+
extraState: oldExtraState,
|
|
2800
|
+
};
|
|
2801
|
+
|
|
2731
2802
|
/** @type {{
|
|
2732
2803
|
* blocklet: any;
|
|
2733
2804
|
* oldBlocklet: {
|
|
@@ -2739,16 +2810,16 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2739
2810
|
* }} */
|
|
2740
2811
|
const downloadParams = {
|
|
2741
2812
|
blocklet: { ...blocklet1 },
|
|
2742
|
-
oldBlocklet: {
|
|
2743
|
-
children: children.filter((x) => x.dynamic), // let downloader skip re-downloading dynamic blocklet
|
|
2744
|
-
extraState: oldExtraState,
|
|
2745
|
-
},
|
|
2746
2813
|
context,
|
|
2747
|
-
postAction:
|
|
2814
|
+
postAction: action,
|
|
2815
|
+
oldBlocklet,
|
|
2748
2816
|
};
|
|
2749
2817
|
|
|
2818
|
+
// backup rollback data
|
|
2819
|
+
await this._rollbackCache.backup({ did, action, oldBlocklet });
|
|
2820
|
+
|
|
2750
2821
|
if (sync) {
|
|
2751
|
-
await this.
|
|
2822
|
+
await this.downloadAndInstall({ ...downloadParams, throwOnError: true });
|
|
2752
2823
|
return states.blocklet.getBlocklet(did);
|
|
2753
2824
|
}
|
|
2754
2825
|
|
|
@@ -2859,8 +2930,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2859
2930
|
postAction: action,
|
|
2860
2931
|
};
|
|
2861
2932
|
|
|
2933
|
+
// backup rollback data
|
|
2934
|
+
await this._rollbackCache.backup({ did, action, oldBlocklet });
|
|
2935
|
+
|
|
2862
2936
|
if (sync) {
|
|
2863
|
-
await this.
|
|
2937
|
+
await this.downloadAndInstall({ ...downloadParams, throwOnError: true });
|
|
2864
2938
|
return states.blocklet.getBlocklet(did);
|
|
2865
2939
|
}
|
|
2866
2940
|
const ticket = this.installQueue.push(
|
|
@@ -2898,6 +2972,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2898
2972
|
*/
|
|
2899
2973
|
async _installBlocklet({ did, oldBlocklet, context }) {
|
|
2900
2974
|
try {
|
|
2975
|
+
// should ensure blocklet integrity
|
|
2901
2976
|
let blocklet = await this.ensureBlocklet(did);
|
|
2902
2977
|
const { meta, source, deployedFrom } = blocklet;
|
|
2903
2978
|
|
|
@@ -2914,13 +2989,13 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2914
2989
|
|
|
2915
2990
|
// Add environments
|
|
2916
2991
|
await this.updateBlockletEnvironment(meta.did);
|
|
2917
|
-
blocklet = await this.
|
|
2992
|
+
blocklet = await this.getBlocklet(did);
|
|
2918
2993
|
|
|
2919
2994
|
// post install
|
|
2920
2995
|
await this._runPostInstallHook(blocklet, context);
|
|
2921
2996
|
|
|
2922
2997
|
await states.blocklet.setBlockletStatus(did, BlockletStatus.installed);
|
|
2923
|
-
blocklet = await this.
|
|
2998
|
+
blocklet = await this.getBlocklet(did);
|
|
2924
2999
|
logger.info('blocklet installed', { source, did: meta.did });
|
|
2925
3000
|
|
|
2926
3001
|
await fs.writeFile(path.join(blocklet.env.dataDir, 'logo.svg'), createDidLogo(blocklet.meta.did));
|
|
@@ -2956,6 +3031,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2956
3031
|
entityId: did,
|
|
2957
3032
|
severity: 'success',
|
|
2958
3033
|
});
|
|
3034
|
+
|
|
3035
|
+
await this._rollbackCache.remove({ did: blocklet.meta.did });
|
|
2959
3036
|
return blocklet;
|
|
2960
3037
|
} catch (err) {
|
|
2961
3038
|
const { meta } = await states.blocklet.getBlocklet(did);
|
|
@@ -3005,6 +3082,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
3005
3082
|
await states.blocklet.upgradeBlocklet({ meta, source, deployedFrom, children });
|
|
3006
3083
|
await this._setConfigsFromMeta(did);
|
|
3007
3084
|
|
|
3085
|
+
// should ensure blocklet integrity
|
|
3008
3086
|
let blocklet = await this.ensureBlocklet(did);
|
|
3009
3087
|
|
|
3010
3088
|
// pre install
|
|
@@ -3012,7 +3090,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
3012
3090
|
|
|
3013
3091
|
// Add environments
|
|
3014
3092
|
await this.updateBlockletEnvironment(did);
|
|
3015
|
-
blocklet = await this.
|
|
3093
|
+
blocklet = await this.getBlocklet(did);
|
|
3016
3094
|
|
|
3017
3095
|
// post install
|
|
3018
3096
|
await this._runPostInstallHook(blocklet, context);
|
|
@@ -3052,7 +3130,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
3052
3130
|
logger.info('started blocklet for upgrading', { did, version });
|
|
3053
3131
|
}
|
|
3054
3132
|
|
|
3055
|
-
blocklet = await this.
|
|
3133
|
+
blocklet = await this.getBlocklet(did, context);
|
|
3056
3134
|
|
|
3057
3135
|
await fs.writeFile(path.join(blocklet.env.dataDir, 'logo.svg'), createDidLogo(blocklet.meta.did));
|
|
3058
3136
|
|
|
@@ -3081,6 +3159,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
3081
3159
|
// Update dynamic component meta in blocklet settings
|
|
3082
3160
|
await this._ensureDynamicChildrenInSettings(blocklet);
|
|
3083
3161
|
|
|
3162
|
+
await this._rollbackCache.remove({ did: blocklet.meta.did });
|
|
3163
|
+
|
|
3084
3164
|
return blocklet;
|
|
3085
3165
|
} catch (err) {
|
|
3086
3166
|
const b = await this._rollback(action, did, oldBlocklet);
|
|
@@ -3144,9 +3224,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
3144
3224
|
});
|
|
3145
3225
|
this.emit(BlockletEvents.statusChange, blocklet1);
|
|
3146
3226
|
},
|
|
3147
|
-
postDownload: async () => {
|
|
3148
|
-
|
|
3149
|
-
|
|
3227
|
+
postDownload: async ({ isCancelled }) => {
|
|
3228
|
+
if (!isCancelled) {
|
|
3229
|
+
// since preferences only exist in blocklet bundle, we need to populate then after downloaded
|
|
3230
|
+
await this._setConfigsFromMeta(did);
|
|
3231
|
+
}
|
|
3150
3232
|
},
|
|
3151
3233
|
});
|
|
3152
3234
|
}
|
|
@@ -3164,12 +3246,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
3164
3246
|
}
|
|
3165
3247
|
}
|
|
3166
3248
|
|
|
3167
|
-
// eslint-disable-next-line no-unused-vars
|
|
3168
|
-
async _cancelWaiting(blockletMeta, context) {
|
|
3169
|
-
const { did } = blockletMeta;
|
|
3170
|
-
return this.installQueue.cancel(did);
|
|
3171
|
-
}
|
|
3172
|
-
|
|
3173
3249
|
/**
|
|
3174
3250
|
* @param {string} action install, upgrade, downgrade
|
|
3175
3251
|
* @param {string} did
|
|
@@ -3283,7 +3359,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
3283
3359
|
}
|
|
3284
3360
|
|
|
3285
3361
|
async _setConfigsFromMeta(did, childDid) {
|
|
3286
|
-
const blocklet = await getBlocklet({ states, dataDirs: this.dataDirs, did
|
|
3362
|
+
const blocklet = await getBlocklet({ states, dataDirs: this.dataDirs, did });
|
|
3287
3363
|
|
|
3288
3364
|
if (!childDid) {
|
|
3289
3365
|
await forEachBlocklet(blocklet, async (b, { ancestors }) => {
|
|
@@ -3337,7 +3413,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
3337
3413
|
}
|
|
3338
3414
|
|
|
3339
3415
|
async _getBlockletForInstallation(did) {
|
|
3340
|
-
const blocklet = await states.blocklet.getBlocklet(did);
|
|
3416
|
+
const blocklet = await states.blocklet.getBlocklet(did, { decryptSk: false });
|
|
3341
3417
|
if (!blocklet) {
|
|
3342
3418
|
return null;
|
|
3343
3419
|
}
|
|
@@ -3563,7 +3639,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
3563
3639
|
|
|
3564
3640
|
this.emit(BlockletEvents.appDidChanged, blocklet);
|
|
3565
3641
|
|
|
3566
|
-
const blockletWithEnv = await this.
|
|
3642
|
+
const blockletWithEnv = await this.getBlocklet(blocklet.meta.did);
|
|
3567
3643
|
const appSystemEnvironments = getAppOverwrittenEnvironments(blockletWithEnv, nodeInfo);
|
|
3568
3644
|
|
|
3569
3645
|
await didDocument.updateBlockletDocument({
|