@abtnode/core 1.15.17 → 1.16.0-beta-b16cb035

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.
Files changed (119) hide show
  1. package/lib/api/node.js +67 -69
  2. package/lib/api/team.js +386 -55
  3. package/lib/blocklet/downloader/blocklet-downloader.js +226 -0
  4. package/lib/blocklet/downloader/bundle-downloader.js +272 -0
  5. package/lib/blocklet/downloader/constants.js +3 -0
  6. package/lib/blocklet/downloader/resolve-download.js +199 -0
  7. package/lib/blocklet/extras.js +83 -26
  8. package/lib/blocklet/hooks.js +18 -65
  9. package/lib/blocklet/manager/base.js +10 -16
  10. package/lib/blocklet/manager/disk.js +1679 -1566
  11. package/lib/blocklet/manager/helper/install-application-from-backup.js +177 -0
  12. package/lib/blocklet/manager/helper/install-application-from-dev.js +94 -0
  13. package/lib/blocklet/manager/helper/install-application-from-general.js +188 -0
  14. package/lib/blocklet/manager/helper/install-component-from-dev.js +84 -0
  15. package/lib/blocklet/manager/helper/install-component-from-upload.js +181 -0
  16. package/lib/blocklet/manager/helper/install-component-from-url.js +173 -0
  17. package/lib/blocklet/manager/helper/migrate-application-to-struct-v2.js +450 -0
  18. package/lib/blocklet/manager/helper/rollback-cache.js +41 -0
  19. package/lib/blocklet/manager/helper/upgrade-components.js +152 -0
  20. package/lib/blocklet/migration.js +30 -52
  21. package/lib/blocklet/storage/backup/audit-log.js +27 -0
  22. package/lib/blocklet/storage/backup/base.js +62 -0
  23. package/lib/blocklet/storage/backup/blocklet-extras.js +92 -0
  24. package/lib/blocklet/storage/backup/blocklet.js +70 -0
  25. package/lib/blocklet/storage/backup/blocklets.js +74 -0
  26. package/lib/blocklet/storage/backup/data.js +19 -0
  27. package/lib/blocklet/storage/backup/logs.js +24 -0
  28. package/lib/blocklet/storage/backup/routing-rule.js +19 -0
  29. package/lib/blocklet/storage/backup/spaces.js +240 -0
  30. package/lib/blocklet/storage/restore/base.js +67 -0
  31. package/lib/blocklet/storage/restore/blocklet-extras.js +86 -0
  32. package/lib/blocklet/storage/restore/blocklet.js +56 -0
  33. package/lib/blocklet/storage/restore/blocklets.js +43 -0
  34. package/lib/blocklet/storage/restore/logs.js +21 -0
  35. package/lib/blocklet/storage/restore/spaces.js +156 -0
  36. package/lib/blocklet/storage/utils/hash.js +51 -0
  37. package/lib/blocklet/storage/utils/zip.js +43 -0
  38. package/lib/cert.js +206 -0
  39. package/lib/event.js +237 -64
  40. package/lib/index.js +191 -83
  41. package/lib/migrations/1.0.21-update-config.js +1 -1
  42. package/lib/migrations/1.0.22-max-memory.js +1 -1
  43. package/lib/migrations/1.0.25.js +1 -1
  44. package/lib/migrations/1.0.32-update-config.js +1 -1
  45. package/lib/migrations/1.0.33-blocklets.js +1 -1
  46. package/lib/migrations/1.5.20-registry.js +15 -0
  47. package/lib/migrations/1.6.17-blocklet-children.js +48 -0
  48. package/lib/migrations/1.6.21-rename-ip-echo-domain.js +35 -0
  49. package/lib/migrations/1.6.4-security.js +59 -0
  50. package/lib/migrations/1.6.5-security.js +60 -0
  51. package/lib/migrations/1.6.9-update-node-info-and-certificate.js +38 -0
  52. package/lib/migrations/1.7.1-blocklet-setup.js +18 -0
  53. package/lib/migrations/1.7.12-blocklet-meta.js +51 -0
  54. package/lib/migrations/1.7.15-blocklet-bundle-source.js +42 -0
  55. package/lib/migrations/1.7.20-blocklet-component.js +41 -0
  56. package/lib/migrations/1.8.33-blocklet-mem-limit.js +20 -0
  57. package/lib/migrations/README.md +1 -1
  58. package/lib/migrations/index.js +6 -2
  59. package/lib/monitor/blocklet-runtime-monitor.js +200 -0
  60. package/lib/monitor/get-history-list.js +37 -0
  61. package/lib/monitor/node-runtime-monitor.js +228 -0
  62. package/lib/router/helper.js +572 -497
  63. package/lib/router/index.js +85 -21
  64. package/lib/router/manager.js +146 -187
  65. package/lib/states/README.md +36 -1
  66. package/lib/states/access-key.js +39 -17
  67. package/lib/states/audit-log.js +462 -0
  68. package/lib/states/base.js +4 -213
  69. package/lib/states/blocklet-extras.js +194 -138
  70. package/lib/states/blocklet.js +361 -104
  71. package/lib/states/cache.js +8 -6
  72. package/lib/states/challenge.js +5 -5
  73. package/lib/states/index.js +19 -36
  74. package/lib/states/migration.js +4 -4
  75. package/lib/states/node.js +135 -46
  76. package/lib/states/notification.js +22 -35
  77. package/lib/states/session.js +17 -9
  78. package/lib/states/site.js +50 -25
  79. package/lib/states/user.js +74 -20
  80. package/lib/states/webhook.js +10 -6
  81. package/lib/team/manager.js +124 -7
  82. package/lib/util/blocklet.js +1223 -246
  83. package/lib/util/chain.js +1 -1
  84. package/lib/util/default-node-config.js +5 -23
  85. package/lib/util/disk-monitor.js +13 -10
  86. package/lib/util/domain-status.js +84 -15
  87. package/lib/util/get-accessible-external-node-ip.js +2 -2
  88. package/lib/util/get-domain-for-blocklet.js +13 -0
  89. package/lib/util/get-meta-from-url.js +33 -0
  90. package/lib/util/index.js +207 -272
  91. package/lib/util/ip.js +6 -0
  92. package/lib/util/maintain.js +233 -0
  93. package/lib/util/public-to-store.js +85 -0
  94. package/lib/util/ready.js +1 -1
  95. package/lib/util/requirement.js +28 -9
  96. package/lib/util/reset-node.js +22 -7
  97. package/lib/util/router.js +13 -0
  98. package/lib/util/rpc.js +16 -0
  99. package/lib/util/store.js +179 -0
  100. package/lib/util/sysinfo.js +44 -0
  101. package/lib/util/ua.js +54 -0
  102. package/lib/validators/blocklet-extra.js +24 -0
  103. package/lib/validators/node.js +25 -12
  104. package/lib/validators/permission.js +16 -1
  105. package/lib/validators/role.js +17 -3
  106. package/lib/validators/router.js +40 -20
  107. package/lib/validators/trusted-passport.js +1 -0
  108. package/lib/validators/util.js +22 -5
  109. package/lib/webhook/index.js +45 -35
  110. package/lib/webhook/sender/index.js +5 -0
  111. package/lib/webhook/sender/slack/index.js +1 -1
  112. package/lib/webhook/sender/wallet/index.js +48 -0
  113. package/package.json +54 -36
  114. package/lib/blocklet/registry.js +0 -205
  115. package/lib/states/https-cert.js +0 -67
  116. package/lib/util/get-ip-dns-domain-for-blocklet.js +0 -19
  117. package/lib/util/service.js +0 -66
  118. package/lib/util/upgrade.js +0 -178
  119. /package/lib/{queue.js → util/queue.js} +0 -0
@@ -0,0 +1,181 @@
1
+ const path = require('path');
2
+
3
+ const logger = require('@abtnode/logger')('@abtnode/core:install-component-upload');
4
+ const getComponentProcessId = require('@blocklet/meta/lib/get-component-process-id');
5
+
6
+ const { BlockletSource, BlockletGroup, fromBlockletStatus } = require('@blocklet/constant');
7
+ const { isInProgress } = require('../../../util');
8
+ const {
9
+ parseComponents,
10
+ filterDuplicateComponents,
11
+ getDiffFiles,
12
+ getBundleDir,
13
+ ensureMeta,
14
+ checkStructVersion,
15
+ checkVersionCompatibility,
16
+ } = require('../../../util/blocklet');
17
+ const { resolveDownload, resolveDiffDownload, downloadFromUpload } = require('../../downloader/resolve-download');
18
+
19
+ const installComponentFromUpload = async ({
20
+ rootDid,
21
+ mountPoint,
22
+ file,
23
+ did,
24
+ diffVersion,
25
+ deleteSet,
26
+ context = {},
27
+ manager,
28
+ states,
29
+ }) => {
30
+ logger.info('install component', { from: 'upload file' });
31
+
32
+ const oldBlocklet = await manager._getBlockletForInstallation(rootDid);
33
+ if (!oldBlocklet) {
34
+ throw new Error('Root blocklet does not exist');
35
+ }
36
+
37
+ checkStructVersion(oldBlocklet);
38
+
39
+ // download
40
+ const { tarFile } = await downloadFromUpload(file, { downloadDir: path.join(manager.dataDirs.tmp, 'download') });
41
+
42
+ if (isInProgress(oldBlocklet.status)) {
43
+ logger.error(`Can not deploy blocklet when it is ${fromBlockletStatus(oldBlocklet.status)}`);
44
+ throw new Error(`Can not deploy blocklet when it is ${fromBlockletStatus(oldBlocklet.status)}`);
45
+ }
46
+
47
+ let meta;
48
+ // diff upload
49
+ if (did && diffVersion) {
50
+ const oldChild = oldBlocklet.children.find((x) => x.meta.did === did);
51
+ if (!oldChild) {
52
+ throw new Error(`Blocklet ${did} not found when diff deploying`);
53
+ }
54
+ if (oldChild.meta.version !== diffVersion) {
55
+ logger.error('Diff deploy: Blocklet version changed', {
56
+ preVersion: diffVersion,
57
+ changedVersion: oldChild.meta.version,
58
+ name: oldChild.meta.name,
59
+ did: oldChild.meta.did,
60
+ });
61
+ throw new Error('Blocklet version changed when diff deploying');
62
+ }
63
+
64
+ meta = (await resolveDiffDownload(tarFile, manager.installDir, { deleteSet, meta: oldChild.meta })).meta;
65
+ } else {
66
+ // full deploy
67
+ meta = (await resolveDownload(tarFile, manager.installDir)).meta;
68
+ }
69
+
70
+ if (meta.did === rootDid) {
71
+ // should not be here
72
+ throw new Error('Cannot add self as a component');
73
+ }
74
+
75
+ if (meta.group === BlockletGroup.gateway) {
76
+ throw new Error('Cannot add gateway component');
77
+ }
78
+
79
+ const newBlocklet = await states.blocklet.getBlocklet(rootDid);
80
+
81
+ const newChild = {
82
+ meta: ensureMeta(meta),
83
+ mountPoint,
84
+ source: BlockletSource.upload,
85
+ deployedFrom: `Upload by ${context.user.fullName}`,
86
+ bundleSource: null,
87
+ };
88
+ const index = newBlocklet.children.findIndex((child) => child.meta.did === meta.did);
89
+ if (index >= 0) {
90
+ // if upgrade, do not update mountPoint and title
91
+ newChild.mountPoint = newBlocklet.children[index].mountPoint;
92
+ newChild.meta.title = newBlocklet.children[index].meta.title;
93
+ newBlocklet.children.splice(index, 1, newChild);
94
+ } else {
95
+ newBlocklet.children.push(newChild);
96
+ }
97
+
98
+ const { dynamicComponents } = await parseComponents(newChild);
99
+ const newChildren = filterDuplicateComponents(dynamicComponents, newBlocklet.children);
100
+
101
+ newBlocklet.children.push(...newChildren);
102
+
103
+ checkVersionCompatibility(newBlocklet.children);
104
+
105
+ // backup rollback data
106
+ const action = 'upgrade';
107
+ await manager._rollbackCache.backup({ did: newBlocklet.meta.did, action, oldBlocklet });
108
+
109
+ await manager._downloadAndInstall({
110
+ blocklet: newBlocklet,
111
+ oldBlocklet,
112
+ context: { ...context, forceStartProcessIds: [getComponentProcessId(newChild, [newBlocklet])] },
113
+ throwOnError: true,
114
+ postAction: action,
115
+ skipCheckStatusBeforeDownload: true,
116
+ selectedComponentDids: newChildren.map((x) => x.meta.did),
117
+ });
118
+ return manager.getBlocklet(newBlocklet.meta.did);
119
+ };
120
+
121
+ const diff = async ({ did, hashFiles: clientFiles, rootDid: inputRootDid, states, manager }) => {
122
+ if (!did) {
123
+ throw new Error('did is empty');
124
+ }
125
+
126
+ if (!clientFiles || !clientFiles.length) {
127
+ throw new Error('hashFiles is empty');
128
+ }
129
+
130
+ const rootDid = inputRootDid || did;
131
+ const childDid = inputRootDid ? did : '';
132
+
133
+ if (childDid === rootDid) {
134
+ throw new Error('Cannot add self as a component');
135
+ }
136
+
137
+ logger.info('Get blocklet diff', { rootDid, childDid, clientFilesNumber: clientFiles.length });
138
+
139
+ const rootBlocklet = await states.blocklet.getBlocklet(rootDid);
140
+ if (childDid && !rootBlocklet) {
141
+ throw new Error('Root blocklet does not exist');
142
+ }
143
+
144
+ const state = childDid ? await (rootBlocklet.children || []).find((x) => x.meta.did === childDid) : rootBlocklet;
145
+
146
+ if (!state) {
147
+ return {
148
+ hasBlocklet: false,
149
+ };
150
+ }
151
+
152
+ if (state.source === BlockletSource.local) {
153
+ throw new Error(`Blocklet ${state.meta.name} is already deployed from local, can not deployed from remote.`);
154
+ }
155
+
156
+ const { version } = state.meta;
157
+ const bundleDir = getBundleDir(manager.installDir, state.meta);
158
+ const { addSet, changeSet, deleteSet } = await getDiffFiles(clientFiles, bundleDir);
159
+
160
+ logger.info('Diff files', {
161
+ name: state.meta.name,
162
+ did: state.meta.did,
163
+ version: state.meta.version,
164
+ addNum: addSet.length,
165
+ changeNum: changeSet.length,
166
+ deleteNum: deleteSet.length,
167
+ });
168
+
169
+ return {
170
+ hasBlocklet: true,
171
+ version,
172
+ addSet,
173
+ changeSet,
174
+ deleteSet,
175
+ };
176
+ };
177
+
178
+ module.exports = {
179
+ installComponentFromUpload,
180
+ diff,
181
+ };
@@ -0,0 +1,173 @@
1
+ const capitalize = require('lodash/capitalize');
2
+ const { sign } = require('@arcblock/jwt');
3
+
4
+ const logger = require('@abtnode/logger')('@abtnode/core:install-component-url');
5
+
6
+ const { isFreeBlocklet, isComponentBlocklet } = require('@blocklet/meta/lib/util');
7
+ const { titleSchema } = require('@blocklet/meta/lib/schema');
8
+ const hasReservedKey = require('@blocklet/meta/lib/has-reserved-key');
9
+
10
+ const { BlockletStatus, BlockletEvents, BlockletGroup } = require('@blocklet/constant');
11
+ const {
12
+ getBlockletMetaFromUrl,
13
+ parseComponents,
14
+ filterDuplicateComponents,
15
+ ensureMeta,
16
+ checkStructVersion,
17
+ checkVersionCompatibility,
18
+ validateBlocklet,
19
+ } = require('../../../util/blocklet');
20
+ const StoreUtil = require('../../../util/store');
21
+ const { formatName } = require('../../../util/get-domain-for-blocklet');
22
+
23
+ const installComponentFromUrl = async ({
24
+ rootDid,
25
+ mountPoint,
26
+ url,
27
+ context,
28
+ title,
29
+ configs,
30
+ downloadTokenList,
31
+ sync,
32
+ manager,
33
+ states,
34
+ }) => {
35
+ const blocklet = await states.blocklet.getBlocklet(rootDid);
36
+ if (!blocklet) {
37
+ throw new Error('Root blocklet does not exist');
38
+ }
39
+
40
+ checkStructVersion(blocklet);
41
+
42
+ const { inStore } = await StoreUtil.parseSourceUrl(url);
43
+
44
+ const meta = await getBlockletMetaFromUrl(url);
45
+
46
+ if (meta.group === BlockletGroup.gateway) {
47
+ throw new Error('Cannot add gateway component');
48
+ }
49
+
50
+ // 如果是一个付费的blocklet,并且url来源为Store, 需要携带token才能下载成功
51
+ if (!isFreeBlocklet(meta) && inStore) {
52
+ const info = await states.node.read();
53
+
54
+ // eslint-disable-next-line no-param-reassign
55
+ context = {
56
+ ...context,
57
+ headers: {
58
+ 'x-server-did': info.did,
59
+ 'x-server-public-key': info.pk,
60
+ 'x-server-signature': sign(info.did, info.sk, {
61
+ exp: (Date.now() + 5 * 60 * 1000) / 1000,
62
+ }),
63
+ },
64
+ downloadTokenList: downloadTokenList || [],
65
+ };
66
+ }
67
+
68
+ if (!isComponentBlocklet(meta)) {
69
+ throw new Error('The blocklet cannot be a component');
70
+ }
71
+
72
+ if (title) {
73
+ meta.title = await titleSchema.validateAsync(title);
74
+ }
75
+
76
+ const newChildMeta = ensureMeta(meta);
77
+
78
+ // children
79
+ const newChild = {
80
+ meta: newChildMeta,
81
+ mountPoint: mountPoint || formatName(newChildMeta.name),
82
+ bundleSource: { url },
83
+ };
84
+
85
+ const { dynamicComponents } = await parseComponents(newChild);
86
+
87
+ const index = blocklet.children.findIndex((child) => child.meta.did === meta.did);
88
+ if (index >= 0) {
89
+ // if upgrade, do not update mountPoint and title
90
+ newChild.mountPoint = blocklet.children[index].mountPoint;
91
+ newChild.meta.title = blocklet.children[index].meta.title;
92
+ blocklet.children.splice(index, 1, newChild);
93
+ } else {
94
+ dynamicComponents.unshift(newChild);
95
+ }
96
+
97
+ const newChildren = filterDuplicateComponents(dynamicComponents, blocklet.children);
98
+
99
+ blocklet.children.push(...newChildren);
100
+
101
+ checkVersionCompatibility(blocklet.children);
102
+
103
+ const oldBlocklet = await manager._getBlockletForInstallation(rootDid);
104
+ const action = 'upgrade';
105
+ try {
106
+ // add component to db
107
+ await states.blocklet.addChildren(rootDid, newChildren);
108
+
109
+ // update configs
110
+ if (Array.isArray(configs)) {
111
+ if (hasReservedKey(configs)) {
112
+ throw new Error('Component key of environments can not start with `ABT_NODE_` or `BLOCKLET_`');
113
+ }
114
+
115
+ await states.blockletExtras.setConfigs([blocklet.meta.did, newChild.meta.did], configs);
116
+ }
117
+ } catch (err) {
118
+ logger.error('Add component failed', err);
119
+ await manager._rollback(action, rootDid, oldBlocklet);
120
+ throw err;
121
+ }
122
+
123
+ // new blocklet
124
+ const newBlocklet = await states.blocklet.setBlockletStatus(rootDid, BlockletStatus.waiting);
125
+
126
+ newBlocklet.children = blocklet.children;
127
+ await validateBlocklet(newBlocklet);
128
+
129
+ manager.emit(BlockletEvents.statusChange, newBlocklet);
130
+
131
+ const downloadParams = {
132
+ oldBlocklet: { ...oldBlocklet },
133
+ blocklet: { ...newBlocklet },
134
+ selectedComponentDids: [newChild.meta.did, ...newChildren.map((x) => x.meta.did)],
135
+ context,
136
+ postAction: action,
137
+ };
138
+
139
+ // backup rollback data
140
+ await manager._rollbackCache.backup({ did: rootDid, action, oldBlocklet });
141
+
142
+ if (sync) {
143
+ await manager._downloadAndInstall({ ...downloadParams, throwOnError: true });
144
+ return states.blocklet.getBlocklet(rootDid);
145
+ }
146
+
147
+ // add to queue
148
+ const ticket = manager.installQueue.push(
149
+ {
150
+ entity: 'blocklet',
151
+ action: 'download',
152
+ id: rootDid,
153
+ ...downloadParams,
154
+ },
155
+ rootDid
156
+ );
157
+
158
+ ticket.on('failed', async (err) => {
159
+ logger.error('queue failed', { entity: 'blocklet', action, did: rootDid, error: err });
160
+ await manager._rollback(action, rootDid, oldBlocklet);
161
+ manager.emit(`blocklet.${action}.failed`, { did: rootDid, err });
162
+ manager._createNotification(rootDid, {
163
+ title: `Blocklet ${capitalize(action)} Failed`,
164
+ description: `Blocklet ${rootDid} ${action} failed with error: ${err.message || 'queue exception'}`,
165
+ entityType: 'blocklet',
166
+ entityId: rootDid,
167
+ severity: 'error',
168
+ });
169
+ });
170
+ return newBlocklet;
171
+ };
172
+
173
+ module.exports = { installComponentFromUrl };