@abtnode/core 1.6.16 → 1.6.20
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/blocklet/hooks.js +16 -63
- package/lib/blocklet/manager/disk.js +425 -151
- package/lib/blocklet/migration.js +16 -52
- package/lib/event.js +3 -2
- package/lib/index.js +2 -1
- package/lib/migrations/1.6.17-blocklet-children.js +48 -0
- package/lib/router/helper.js +11 -9
- package/lib/router/manager.js +45 -41
- package/lib/states/blocklet-extras.js +39 -3
- package/lib/states/blocklet.js +84 -12
- package/lib/states/node.js +17 -2
- package/lib/util/blocklet.js +284 -68
- package/lib/util/get-domain-for-blocklet.js +2 -2
- package/lib/util/upgrade.js +8 -4
- package/package.json +23 -23
package/lib/util/blocklet.js
CHANGED
|
@@ -6,9 +6,11 @@ const os = require('os');
|
|
|
6
6
|
const tar = require('tar');
|
|
7
7
|
const get = require('lodash/get');
|
|
8
8
|
const intersection = require('lodash/intersection');
|
|
9
|
+
const intersectionBy = require('lodash/intersectionBy');
|
|
9
10
|
const streamToPromise = require('stream-to-promise');
|
|
10
11
|
const { Throttle } = require('stream-throttle');
|
|
11
12
|
const ssri = require('ssri');
|
|
13
|
+
const diff = require('deep-diff');
|
|
12
14
|
|
|
13
15
|
const { toHex } = require('@ocap/util');
|
|
14
16
|
const logger = require('@abtnode/logger')('@abtnode/core:util:blocklet');
|
|
@@ -17,7 +19,10 @@ const sleep = require('@abtnode/util/lib/sleep');
|
|
|
17
19
|
const ensureEndpointHealthy = require('@abtnode/util/lib/ensure-endpoint-healthy');
|
|
18
20
|
const CustomError = require('@abtnode/util/lib/custom-error');
|
|
19
21
|
const getFolderSize = require('@abtnode/util/lib/get-folder-size');
|
|
22
|
+
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
23
|
+
const hashFiles = require('@abtnode/util/lib/hash-files');
|
|
20
24
|
const { BLOCKLET_MAX_MEM_LIMIT_IN_MB } = require('@abtnode/constant');
|
|
25
|
+
|
|
21
26
|
const {
|
|
22
27
|
BlockletStatus,
|
|
23
28
|
BlockletSource,
|
|
@@ -29,6 +34,7 @@ const {
|
|
|
29
34
|
BLOCKLET_DEFAULT_PORT_NAME,
|
|
30
35
|
BLOCKLET_INTERFACE_TYPE_WEB,
|
|
31
36
|
BLOCKLET_CONFIGURABLE_KEY,
|
|
37
|
+
BLOCKLET_DYNAMIC_PATH_PREFIX,
|
|
32
38
|
fromBlockletStatus,
|
|
33
39
|
} = require('@blocklet/meta/lib/constants');
|
|
34
40
|
const verifyMultiSig = require('@blocklet/meta/lib/verify-multi-sig');
|
|
@@ -61,8 +67,6 @@ const getBlockletEngineNameByPlatform = (blockletMeta) => getBlockletEngine(bloc
|
|
|
61
67
|
|
|
62
68
|
const noop = () => {};
|
|
63
69
|
|
|
64
|
-
const asyncFs = fs.promises;
|
|
65
|
-
|
|
66
70
|
const statusMap = {
|
|
67
71
|
online: BlockletStatus.running,
|
|
68
72
|
launching: BlockletStatus.starting,
|
|
@@ -80,8 +84,6 @@ const PRIVATE_NODE_ENVS = [
|
|
|
80
84
|
'ABT_NODE_TOKEN_SECRET',
|
|
81
85
|
'ABT_NODE_SK',
|
|
82
86
|
'ABT_NODE_SESSION_SECRET',
|
|
83
|
-
'ABT_NODE_NAME',
|
|
84
|
-
'ABT_NODE_DESCRIPTION',
|
|
85
87
|
'ABT_NODE_BASE_URL',
|
|
86
88
|
'ABT_NODE_LOG_LEVEL',
|
|
87
89
|
'ABT_NODE_LOG_DIR',
|
|
@@ -120,19 +122,9 @@ const getBlockletDirs = (blocklet, { rootBlocklet, dataDirs, ensure = false } =
|
|
|
120
122
|
logsDir = path.join(dataDirs.logs, rootBlocklet.meta.name);
|
|
121
123
|
}
|
|
122
124
|
|
|
123
|
-
if (ensure) {
|
|
124
|
-
try {
|
|
125
|
-
fs.mkdirSync(dataDir, { recursive: true });
|
|
126
|
-
fs.mkdirSync(logsDir, { recursive: true });
|
|
127
|
-
fs.mkdirSync(cacheDir, { recursive: true });
|
|
128
|
-
} catch (err) {
|
|
129
|
-
logger.error('make blocklet dir failed', { error: err });
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
125
|
// get app dirs
|
|
134
126
|
|
|
135
|
-
const {
|
|
127
|
+
const { main, group } = blocklet.meta;
|
|
136
128
|
|
|
137
129
|
const startFromDevEntry =
|
|
138
130
|
blocklet.mode === BLOCKLET_MODES.DEVELOPMENT && blocklet.meta.scripts && blocklet.meta.scripts.dev;
|
|
@@ -147,13 +139,24 @@ const getBlockletDirs = (blocklet, { rootBlocklet, dataDirs, ensure = false } =
|
|
|
147
139
|
if (blocklet.source === BlockletSource.local) {
|
|
148
140
|
appDir = blocklet.deployedFrom;
|
|
149
141
|
} else {
|
|
150
|
-
appDir =
|
|
142
|
+
appDir = getBundleDir(dataDirs.blocklets, blocklet.meta);
|
|
151
143
|
}
|
|
152
144
|
|
|
153
145
|
if (!appDir) {
|
|
154
146
|
throw new Error('Can not determine blocklet directory, maybe invalid deployment from local blocklets');
|
|
155
147
|
}
|
|
156
148
|
|
|
149
|
+
if (ensure) {
|
|
150
|
+
try {
|
|
151
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
152
|
+
fs.mkdirSync(logsDir, { recursive: true });
|
|
153
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
154
|
+
fs.mkdirSync(appDir, { recursive: true }); // prevent getDiskInfo failed from custom blocklet
|
|
155
|
+
} catch (err) {
|
|
156
|
+
logger.error('make blocklet dir failed', { error: err });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
157
160
|
mainDir = appDir;
|
|
158
161
|
|
|
159
162
|
if (!startFromDevEntry && !isBeforeInstalled(rootBlocklet.status)) {
|
|
@@ -249,7 +252,7 @@ const getRootSystemEnvironments = (blocklet, nodeInfo) => {
|
|
|
249
252
|
const appDescription = description || result.description;
|
|
250
253
|
|
|
251
254
|
// FIXME: we should use https here when possible, eg, when did-gateway is available
|
|
252
|
-
const appUrl = `http://${getDidDomainForBlocklet({
|
|
255
|
+
const appUrl = `http://${getDidDomainForBlocklet({ name, daemonDid: nodeInfo.did, didDomain: nodeInfo.didDomain })}`;
|
|
253
256
|
|
|
254
257
|
return {
|
|
255
258
|
BLOCKLET_DID: did,
|
|
@@ -437,11 +440,13 @@ const startBlockletProcess = async (blocklet, { preStart = noop, nodeEnvironment
|
|
|
437
440
|
const options = {
|
|
438
441
|
namespace: 'blocklets',
|
|
439
442
|
name: appId,
|
|
440
|
-
|
|
443
|
+
cwd: appCwd,
|
|
441
444
|
time: true,
|
|
442
445
|
output: path.join(logsDir, 'output.log'),
|
|
443
446
|
error: path.join(logsDir, 'error.log'),
|
|
444
|
-
|
|
447
|
+
wait_ready: process.env.NODE_ENV !== 'test',
|
|
448
|
+
listen_timeout: 5000,
|
|
449
|
+
max_memory_restart: `${maxMemoryRestart}M`,
|
|
445
450
|
max_restarts: b.mode === BLOCKLET_MODES.DEVELOPMENT ? 0 : 3,
|
|
446
451
|
env: {
|
|
447
452
|
...env,
|
|
@@ -469,17 +474,17 @@ const startBlockletProcess = async (blocklet, { preStart = noop, nodeEnvironment
|
|
|
469
474
|
const engine = getEngine(blockletEngineInfo.interpreter);
|
|
470
475
|
options.interpreter = engine.interpreter === 'node' ? '' : engine.interpreter;
|
|
471
476
|
options.interpreterArgs = engine.args || '';
|
|
472
|
-
|
|
473
477
|
options.script = blockletEngineInfo.script || appMain;
|
|
474
|
-
|
|
475
|
-
logger.debug('start.blocklet.engine.info', { blockletEngineInfo });
|
|
476
|
-
logger.debug('start.blocklet.max_memory_restart', { maxMemoryRestart });
|
|
477
478
|
}
|
|
478
479
|
|
|
479
480
|
await pm2.startAsync(options);
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
481
|
+
|
|
482
|
+
const status = await getProcessState(appId);
|
|
483
|
+
if (status === BlockletStatus.error) {
|
|
484
|
+
throw new Error(`${appId} is not running within 5 seconds`);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
logger.info('blocklet started', { appId, status });
|
|
483
488
|
},
|
|
484
489
|
{ parallel: true }
|
|
485
490
|
);
|
|
@@ -542,6 +547,10 @@ const getBlockletStatusFromProcess = async (blocklet) => {
|
|
|
542
547
|
|
|
543
548
|
const list = await Promise.all(tasks);
|
|
544
549
|
|
|
550
|
+
if (!list.length) {
|
|
551
|
+
return blocklet.status;
|
|
552
|
+
}
|
|
553
|
+
|
|
545
554
|
return getRootBlockletStatus(list);
|
|
546
555
|
};
|
|
547
556
|
|
|
@@ -620,26 +629,76 @@ const reloadProcess = (appId) =>
|
|
|
620
629
|
});
|
|
621
630
|
});
|
|
622
631
|
|
|
623
|
-
const
|
|
624
|
-
const
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
632
|
+
const findWebInterface = (blocklet) => {
|
|
633
|
+
const meta = blocklet.meta || blocklet || {};
|
|
634
|
+
const { interfaces = [] } = meta;
|
|
635
|
+
|
|
636
|
+
if (!Array.isArray(interfaces)) {
|
|
637
|
+
return null;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
return interfaces.find((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB);
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* this function has side effect on children
|
|
645
|
+
*/
|
|
646
|
+
const parseChildren = async (src, { children, dynamic } = {}) => {
|
|
647
|
+
const configs = Array.isArray(src) ? src : src.children || [];
|
|
648
|
+
|
|
649
|
+
if (children) {
|
|
650
|
+
children.forEach((x) => {
|
|
651
|
+
x.dynamic = !!dynamic;
|
|
652
|
+
});
|
|
653
|
+
mergeMeta(configs, children);
|
|
654
|
+
return children;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
if (!configs || !configs.length) {
|
|
658
|
+
return [];
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
const results = [];
|
|
662
|
+
|
|
663
|
+
for (const config of configs) {
|
|
664
|
+
const mountPoint = config.mountPoint || config.mountPoints[0].root.prefix;
|
|
665
|
+
if (!mountPoint) {
|
|
666
|
+
throw new Error(`MountPoint does not found in child ${config.name}`);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
const m = await getBlockletMetaFromUrl(config.resolved);
|
|
670
|
+
if (m.name !== config.name) {
|
|
671
|
+
logger.error('Resolved child blocklet name does not match in the configuration', {
|
|
672
|
+
expected: config.name,
|
|
673
|
+
resolved: m.name,
|
|
674
|
+
});
|
|
675
|
+
throw new Error(
|
|
676
|
+
`Child blocklet name does not match in the configuration. expected: ${config.name}, resolved: ${m.name}`
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
validateBlockletMeta(m, { ensureDist: true });
|
|
680
|
+
|
|
681
|
+
const webInterface = findWebInterface(m);
|
|
682
|
+
if (!webInterface) {
|
|
683
|
+
throw new Error(`Web interface does not found in child ${config.name}`);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
const rule = webInterface.prefix;
|
|
687
|
+
if (rule !== BLOCKLET_DYNAMIC_PATH_PREFIX && normalizePathPrefix(rule) !== normalizePathPrefix(mountPoint)) {
|
|
688
|
+
throw new Error(`Prefix does not match in child ${config.name}. expected: ${rule}, resolved: ${mountPoint}`);
|
|
639
689
|
}
|
|
690
|
+
|
|
691
|
+
results.push({
|
|
692
|
+
mountPoint,
|
|
693
|
+
meta: m,
|
|
694
|
+
dynamic: !!dynamic,
|
|
695
|
+
sourceUrl: config.resolved,
|
|
696
|
+
});
|
|
640
697
|
}
|
|
641
698
|
|
|
642
|
-
|
|
699
|
+
mergeMeta(configs, results);
|
|
700
|
+
|
|
701
|
+
return results;
|
|
643
702
|
};
|
|
644
703
|
|
|
645
704
|
const validateBlocklet = (blocklet) =>
|
|
@@ -737,7 +796,7 @@ const verifyIntegrity = async ({ file, integrity: expected }) => {
|
|
|
737
796
|
return true;
|
|
738
797
|
};
|
|
739
798
|
|
|
740
|
-
const pruneBlockletBundle = async (blocklets, installDir) => {
|
|
799
|
+
const pruneBlockletBundle = async ({ blocklets, installDir, blockletSettings }) => {
|
|
741
800
|
for (const blocklet of blocklets) {
|
|
742
801
|
if (
|
|
743
802
|
[
|
|
@@ -755,53 +814,104 @@ const pruneBlockletBundle = async (blocklets, installDir) => {
|
|
|
755
814
|
}
|
|
756
815
|
}
|
|
757
816
|
|
|
758
|
-
// blockletMap: { <name/version>: true }
|
|
759
|
-
const blockletMap =
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
817
|
+
// blockletMap: { <[scope/]name/version>: true }
|
|
818
|
+
const blockletMap = {};
|
|
819
|
+
for (const blocklet of blocklets) {
|
|
820
|
+
blockletMap[`${blocklet.meta.name}/${blocklet.meta.version}`] = true;
|
|
821
|
+
for (const child of blocklet.children || []) {
|
|
822
|
+
blockletMap[`${child.meta.name}/${child.meta.version}`] = true;
|
|
763
823
|
}
|
|
764
|
-
|
|
765
|
-
|
|
824
|
+
}
|
|
825
|
+
for (const setting of blockletSettings) {
|
|
826
|
+
for (const child of setting.children || []) {
|
|
827
|
+
blockletMap[`${child.meta.name}/${child.meta.version}`] = true;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
766
830
|
|
|
767
|
-
// appDirs: [{ key: <name/version>, dir: appDir }]
|
|
831
|
+
// appDirs: [{ key: <[scope/]name/version>, dir: appDir }]
|
|
768
832
|
const appDirs = [];
|
|
769
833
|
|
|
770
834
|
// fill appDirs
|
|
771
835
|
try {
|
|
772
|
-
|
|
773
|
-
|
|
836
|
+
// @return root/scope/bundle/version
|
|
837
|
+
const getNextLevel = (level, name) => {
|
|
838
|
+
if (level === 'root') {
|
|
839
|
+
if (name.startsWith('@')) {
|
|
840
|
+
return 'scope';
|
|
841
|
+
}
|
|
842
|
+
return 'bundle';
|
|
843
|
+
}
|
|
844
|
+
if (level === 'scope') {
|
|
845
|
+
return 'bundle';
|
|
846
|
+
}
|
|
847
|
+
if (level === 'bundle') {
|
|
848
|
+
return 'version';
|
|
849
|
+
}
|
|
850
|
+
throw new Error(`Invalid level ${level}`);
|
|
851
|
+
};
|
|
852
|
+
|
|
853
|
+
const fillAppDirs = async (dir, level = 'root') => {
|
|
854
|
+
if (level === 'version') {
|
|
855
|
+
if (!fs.existsSync(path.join(dir, 'blocklet.yml'))) {
|
|
856
|
+
logger.error('blocklet.yml does not exist in blocklet bundle dir', { dir });
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
|
|
774
860
|
appDirs.push({
|
|
775
861
|
key: path.relative(installDir, dir),
|
|
776
862
|
dir,
|
|
777
863
|
});
|
|
864
|
+
|
|
778
865
|
return;
|
|
779
866
|
}
|
|
867
|
+
|
|
780
868
|
const nextDirs = [];
|
|
781
|
-
for (const x of await
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
return;
|
|
869
|
+
for (const x of await fs.promises.readdir(dir)) {
|
|
870
|
+
if (!fs.lstatSync(path.join(dir, x)).isDirectory()) {
|
|
871
|
+
logger.error('pruneBlockletBundle: invalid file in bundle storage', { dir, file: x });
|
|
872
|
+
// eslint-disable-next-line no-continue
|
|
873
|
+
continue;
|
|
787
874
|
}
|
|
788
|
-
nextDirs.push(
|
|
875
|
+
nextDirs.push(x);
|
|
789
876
|
}
|
|
790
877
|
|
|
791
878
|
for (const x of nextDirs) {
|
|
792
|
-
await fillAppDirs(x);
|
|
879
|
+
await fillAppDirs(path.join(dir, x), getNextLevel(level, x));
|
|
793
880
|
}
|
|
794
881
|
};
|
|
795
|
-
await fillAppDirs(installDir);
|
|
882
|
+
await fillAppDirs(installDir, 'root');
|
|
796
883
|
} catch (error) {
|
|
797
884
|
logger.error('fill app dirs failed', { error });
|
|
798
885
|
}
|
|
799
886
|
|
|
887
|
+
const ensureBundleDirRemoved = async (dir) => {
|
|
888
|
+
const relativeDir = path.relative(installDir, dir);
|
|
889
|
+
const arr = relativeDir.split('/').filter(Boolean);
|
|
890
|
+
const { length } = arr;
|
|
891
|
+
const bundleName = arr[length - 2];
|
|
892
|
+
const scopeName = length > 2 ? arr[length - 3] : '';
|
|
893
|
+
const bundleDir = path.join(installDir, scopeName, bundleName);
|
|
894
|
+
const isEmpty = (await fs.promises.readdir(bundleDir)).length === 0;
|
|
895
|
+
if (isEmpty) {
|
|
896
|
+
logger.info('Remove bundle folder', { bundleDir });
|
|
897
|
+
await fs.remove(bundleDir);
|
|
898
|
+
}
|
|
899
|
+
if (scopeName) {
|
|
900
|
+
const scopeDir = path.join(installDir, scopeName);
|
|
901
|
+
const isScopeEmpty = (await fs.promises.readdir(scopeDir)).length === 0;
|
|
902
|
+
if (isScopeEmpty) {
|
|
903
|
+
logger.info('Remove scope folder', { scopeDir });
|
|
904
|
+
await fs.remove(scopeDir);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
};
|
|
908
|
+
|
|
800
909
|
// remove trash
|
|
801
910
|
for (const app of appDirs) {
|
|
802
911
|
if (!blockletMap[app.key]) {
|
|
803
|
-
logger.info('Remove
|
|
912
|
+
logger.info('Remove app folder', { dir: app.dir });
|
|
804
913
|
await fs.remove(app.dir);
|
|
914
|
+
await ensureBundleDirRemoved(app.dir);
|
|
805
915
|
}
|
|
806
916
|
}
|
|
807
917
|
|
|
@@ -839,15 +949,25 @@ const getRuntimeInfo = async (appId) => {
|
|
|
839
949
|
};
|
|
840
950
|
};
|
|
841
951
|
|
|
842
|
-
|
|
952
|
+
/**
|
|
953
|
+
* merge services
|
|
954
|
+
* from meta.children[].mountPoints[].services
|
|
955
|
+
* to childrenMeta[].interfaces[].services
|
|
956
|
+
*
|
|
957
|
+
* @param {array<child>|object{children:array}} source e.g. [<config>] or { children: [<config>] }
|
|
958
|
+
* @param {array<meta|{meta}>} childrenMeta e.g. [<meta>] or [{ meta: <meta> }]
|
|
959
|
+
*/
|
|
960
|
+
|
|
961
|
+
const mergeMeta = (source, childrenMeta = []) => {
|
|
843
962
|
// configMap
|
|
844
963
|
const configMap = {};
|
|
845
|
-
(
|
|
964
|
+
(Array.isArray(source) ? source : source.children || []).forEach((x) => {
|
|
846
965
|
configMap[x.name] = x;
|
|
847
966
|
});
|
|
848
967
|
|
|
849
968
|
// merge service from config to child meta
|
|
850
|
-
childrenMeta.forEach((
|
|
969
|
+
childrenMeta.forEach((child) => {
|
|
970
|
+
const childMeta = child.meta || child;
|
|
851
971
|
const config = configMap[childMeta.name];
|
|
852
972
|
if (!config) {
|
|
853
973
|
return;
|
|
@@ -907,10 +1027,100 @@ const getUpdateMetaList = (oldMetas = [], newMetas = []) => {
|
|
|
907
1027
|
return newMetas.filter(({ version, did }) => did && version !== oldMap[did]);
|
|
908
1028
|
};
|
|
909
1029
|
|
|
1030
|
+
const getSourceFromInstallParams = (params) => {
|
|
1031
|
+
if (params.url) {
|
|
1032
|
+
return BlockletSource.url;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
if (params.file) {
|
|
1036
|
+
return BlockletSource.upload;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
if (params.did) {
|
|
1040
|
+
return BlockletSource.registry;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
if (params.title && params.description) {
|
|
1044
|
+
return BlockletSource.custom;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
throw new Error('Can only install blocklet from store/url/upload/custom');
|
|
1048
|
+
};
|
|
1049
|
+
|
|
1050
|
+
const checkDuplicateComponents = (dynamicComponents, staticComponents) => {
|
|
1051
|
+
const duplicates = intersectionBy(dynamicComponents, staticComponents, 'meta.did');
|
|
1052
|
+
if (duplicates.length) {
|
|
1053
|
+
throw new Error(
|
|
1054
|
+
`Cannot add duplicate component${duplicates.length > 1 ? 's' : ''}: ${duplicates
|
|
1055
|
+
.map((x) => x.meta.title || x.meta.name)
|
|
1056
|
+
.join(', ')}`
|
|
1057
|
+
);
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1061
|
+
const getDiffFiles = async (inputFiles, sourceDir) => {
|
|
1062
|
+
if (!fs.existsSync(sourceDir)) {
|
|
1063
|
+
throw new Error(`${sourceDir} does not exist`);
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
const files = inputFiles.reduce((obj, item) => {
|
|
1067
|
+
obj[item.file] = item.hash;
|
|
1068
|
+
return obj;
|
|
1069
|
+
}, {});
|
|
1070
|
+
|
|
1071
|
+
const { files: sourceFiles } = await hashFiles(sourceDir, {
|
|
1072
|
+
filter: (x) => x.indexOf('node_modules') === -1,
|
|
1073
|
+
concurrentHash: 1,
|
|
1074
|
+
});
|
|
1075
|
+
|
|
1076
|
+
const addSet = [];
|
|
1077
|
+
const changeSet = [];
|
|
1078
|
+
const deleteSet = [];
|
|
1079
|
+
|
|
1080
|
+
const diffFiles = diff(sourceFiles, files);
|
|
1081
|
+
if (diffFiles) {
|
|
1082
|
+
diffFiles.forEach((item) => {
|
|
1083
|
+
if (item.kind === 'D') {
|
|
1084
|
+
deleteSet.push(item.path[0]);
|
|
1085
|
+
}
|
|
1086
|
+
if (item.kind === 'E') {
|
|
1087
|
+
changeSet.push(item.path[0]);
|
|
1088
|
+
}
|
|
1089
|
+
if (item.kind === 'N') {
|
|
1090
|
+
addSet.push(item.path[0]);
|
|
1091
|
+
}
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
return {
|
|
1096
|
+
addSet,
|
|
1097
|
+
changeSet,
|
|
1098
|
+
deleteSet,
|
|
1099
|
+
};
|
|
1100
|
+
};
|
|
1101
|
+
|
|
1102
|
+
const getBundleDir = (installDir, bundle) => path.join(installDir, bundle.name, bundle.version);
|
|
1103
|
+
|
|
1104
|
+
const needBlockletDownload = (blocklet, oldBlocklet) => {
|
|
1105
|
+
if ([BlockletSource.upload, BlockletSource.local, BlockletSource.custom].includes(blocklet.source)) {
|
|
1106
|
+
return false;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
if (!get(oldBlocklet, 'meta.dist.integrity')) {
|
|
1110
|
+
return true;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
if (get(oldBlocklet, 'meta.dist.integrity') === get(blocklet, 'meta.dist.integrity')) {
|
|
1114
|
+
return false;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
return true;
|
|
1118
|
+
};
|
|
1119
|
+
|
|
910
1120
|
module.exports = {
|
|
911
1121
|
forEachBlocklet,
|
|
912
1122
|
getBlockletMetaFromUrl,
|
|
913
|
-
|
|
1123
|
+
parseChildren,
|
|
914
1124
|
getBlockletDirs,
|
|
915
1125
|
getRootSystemEnvironments,
|
|
916
1126
|
getSystemEnvironments,
|
|
@@ -936,4 +1146,10 @@ module.exports = {
|
|
|
936
1146
|
mergeMeta,
|
|
937
1147
|
fixAndVerifyBlockletMeta,
|
|
938
1148
|
getUpdateMetaList,
|
|
1149
|
+
getSourceFromInstallParams,
|
|
1150
|
+
findWebInterface,
|
|
1151
|
+
checkDuplicateComponents,
|
|
1152
|
+
getDiffFiles,
|
|
1153
|
+
getBundleDir,
|
|
1154
|
+
needBlockletDownload,
|
|
939
1155
|
};
|
|
@@ -16,8 +16,8 @@ const getIpDnsDomainForBlocklet = (blocklet, blockletInterface) => {
|
|
|
16
16
|
}${iName}-${SLOT_FOR_IP_DNS_SITE}.${DEFAULT_IP_DNS_DOMAIN_SUFFIX}`;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
const getDidDomainForBlocklet = ({
|
|
20
|
-
return `${
|
|
19
|
+
const getDidDomainForBlocklet = ({ name, daemonDid, didDomain }) => {
|
|
20
|
+
return `${formatName(name)}-${daemonDid.toLowerCase()}.${didDomain}`;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
module.exports = { getIpDnsDomainForBlocklet, getDidDomainForBlocklet };
|
package/lib/util/upgrade.js
CHANGED
|
@@ -27,9 +27,6 @@ const waitUpdaterRpc = async (message) =>
|
|
|
27
27
|
const checkNewVersion = async (params, context) => {
|
|
28
28
|
try {
|
|
29
29
|
const info = await states.node.read();
|
|
30
|
-
if (!info.autoUpgrade) {
|
|
31
|
-
return '';
|
|
32
|
-
}
|
|
33
30
|
|
|
34
31
|
if (!process.env.ABT_NODE_PACKAGE_NAME) {
|
|
35
32
|
logger.error('ABT_NODE_PACKAGE_NAME name was not found in environment');
|
|
@@ -176,7 +173,14 @@ const getCron = () => ({
|
|
|
176
173
|
name: 'check-update',
|
|
177
174
|
time: '0 0 8 * * *', // check every day
|
|
178
175
|
// time: '0 */5 * * * *', // check every 5 minutes
|
|
179
|
-
fn:
|
|
176
|
+
fn: async () => {
|
|
177
|
+
const info = await states.node.read();
|
|
178
|
+
if (!info.autoUpgrade) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
checkNewVersion();
|
|
183
|
+
},
|
|
180
184
|
options: { runOnInit: false },
|
|
181
185
|
});
|
|
182
186
|
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.6.
|
|
6
|
+
"version": "1.6.20",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,30 +19,30 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/certificate-manager": "1.6.
|
|
23
|
-
"@abtnode/constant": "1.6.
|
|
24
|
-
"@abtnode/cron": "1.6.
|
|
25
|
-
"@abtnode/db": "1.6.
|
|
26
|
-
"@abtnode/logger": "1.6.
|
|
27
|
-
"@abtnode/queue": "1.6.
|
|
28
|
-
"@abtnode/rbac": "1.6.
|
|
29
|
-
"@abtnode/router-provider": "1.6.
|
|
30
|
-
"@abtnode/static-server": "1.6.
|
|
31
|
-
"@abtnode/timemachine": "1.6.
|
|
32
|
-
"@abtnode/util": "1.6.
|
|
33
|
-
"@arcblock/did": "^1.14.
|
|
34
|
-
"@arcblock/event-hub": "1.14.
|
|
22
|
+
"@abtnode/certificate-manager": "1.6.20",
|
|
23
|
+
"@abtnode/constant": "1.6.20",
|
|
24
|
+
"@abtnode/cron": "1.6.20",
|
|
25
|
+
"@abtnode/db": "1.6.20",
|
|
26
|
+
"@abtnode/logger": "1.6.20",
|
|
27
|
+
"@abtnode/queue": "1.6.20",
|
|
28
|
+
"@abtnode/rbac": "1.6.20",
|
|
29
|
+
"@abtnode/router-provider": "1.6.20",
|
|
30
|
+
"@abtnode/static-server": "1.6.20",
|
|
31
|
+
"@abtnode/timemachine": "1.6.20",
|
|
32
|
+
"@abtnode/util": "1.6.20",
|
|
33
|
+
"@arcblock/did": "^1.14.13",
|
|
34
|
+
"@arcblock/event-hub": "1.14.13",
|
|
35
35
|
"@arcblock/pm2-events": "^0.0.5",
|
|
36
|
-
"@arcblock/vc": "^1.14.
|
|
37
|
-
"@blocklet/meta": "1.6.
|
|
36
|
+
"@arcblock/vc": "^1.14.13",
|
|
37
|
+
"@blocklet/meta": "1.6.20",
|
|
38
38
|
"@fidm/x509": "^1.2.1",
|
|
39
39
|
"@nedb/core": "^1.2.2",
|
|
40
40
|
"@nedb/multi": "^1.2.2",
|
|
41
|
-
"@ocap/mcrypto": "^1.14.
|
|
42
|
-
"@ocap/util": "^1.14.
|
|
43
|
-
"@ocap/wallet": "^1.14.
|
|
41
|
+
"@ocap/mcrypto": "^1.14.13",
|
|
42
|
+
"@ocap/util": "^1.14.13",
|
|
43
|
+
"@ocap/wallet": "^1.14.13",
|
|
44
44
|
"@slack/webhook": "^5.0.3",
|
|
45
|
-
"axios": "^0.
|
|
45
|
+
"axios": "^0.25.0",
|
|
46
46
|
"axon": "^2.0.3",
|
|
47
47
|
"chalk": "^4.0.0",
|
|
48
48
|
"deep-diff": "^1.0.2",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"is-base64": "^1.1.0",
|
|
54
54
|
"is-ip": "^3.1.0",
|
|
55
55
|
"is-url": "^1.2.4",
|
|
56
|
-
"joi": "^17.
|
|
56
|
+
"joi": "^17.6.0",
|
|
57
57
|
"js-yaml": "^3.14.0",
|
|
58
58
|
"lodash": "^4.17.21",
|
|
59
59
|
"lru-cache": "^6.0.0",
|
|
60
|
-
"pm2": "^
|
|
60
|
+
"pm2": "^5.1.2",
|
|
61
61
|
"semver": "^7.3.2",
|
|
62
62
|
"shelljs": "^0.8.4",
|
|
63
63
|
"slugify": "^1.4.6",
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"express": "^4.17.1",
|
|
76
76
|
"jest": "^27.4.5"
|
|
77
77
|
},
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "e695a9fa4e2cbf7fcef554be3309090c37919d94"
|
|
79
79
|
}
|