@abtnode/core 1.15.17 → 1.16.0-beta-8ee536d7

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 +1680 -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 +576 -500
  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 +195 -138
  70. package/lib/states/blocklet.js +371 -110
  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
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.15.17",
6
+ "version": "1.16.0-beta-8ee536d7",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,59 +19,77 @@
19
19
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "@abtnode/constant": "1.15.17",
23
- "@abtnode/cron": "1.15.17",
24
- "@abtnode/logger": "1.15.17",
25
- "@abtnode/queue": "1.15.17",
26
- "@abtnode/rbac": "1.15.17",
27
- "@abtnode/router-provider": "1.15.17",
28
- "@abtnode/static-server": "1.15.17",
29
- "@abtnode/timemachine": "1.15.17",
30
- "@abtnode/util": "1.15.17",
31
- "@arcblock/did": "^1.13.61",
32
- "@arcblock/event-hub": "1.13.61",
22
+ "@abtnode/auth": "1.16.0-beta-8ee536d7",
23
+ "@abtnode/certificate-manager": "1.16.0-beta-8ee536d7",
24
+ "@abtnode/constant": "1.16.0-beta-8ee536d7",
25
+ "@abtnode/cron": "1.16.0-beta-8ee536d7",
26
+ "@abtnode/db": "1.16.0-beta-8ee536d7",
27
+ "@abtnode/logger": "1.16.0-beta-8ee536d7",
28
+ "@abtnode/queue": "1.16.0-beta-8ee536d7",
29
+ "@abtnode/rbac": "1.16.0-beta-8ee536d7",
30
+ "@abtnode/router-provider": "1.16.0-beta-8ee536d7",
31
+ "@abtnode/static-server": "1.16.0-beta-8ee536d7",
32
+ "@abtnode/timemachine": "1.16.0-beta-8ee536d7",
33
+ "@abtnode/util": "1.16.0-beta-8ee536d7",
34
+ "@arcblock/did": "1.18.62",
35
+ "@arcblock/did-motif": "^1.1.10",
36
+ "@arcblock/did-util": "1.18.62",
37
+ "@arcblock/event-hub": "1.18.62",
38
+ "@arcblock/jwt": "^1.18.62",
33
39
  "@arcblock/pm2-events": "^0.0.5",
34
- "@arcblock/vc": "^1.13.61",
35
- "@blocklet/meta": "1.15.17",
40
+ "@arcblock/vc": "1.18.62",
41
+ "@blocklet/constant": "1.16.0-beta-8ee536d7",
42
+ "@blocklet/meta": "1.16.0-beta-8ee536d7",
43
+ "@blocklet/sdk": "1.16.0-beta-8ee536d7",
44
+ "@did-space/client": "^0.2.33",
36
45
  "@fidm/x509": "^1.2.1",
37
- "@nedb/core": "^1.2.2",
38
- "@nedb/multi": "^1.2.2",
39
- "@ocap/mcrypto": "^1.13.61",
40
- "@ocap/util": "^1.13.61",
41
- "@ocap/wallet": "^1.13.61",
42
- "@slack/webhook": "^5.0.3",
43
- "axios": "^0.21.4",
46
+ "@ocap/client": "1.18.62",
47
+ "@ocap/mcrypto": "1.18.62",
48
+ "@ocap/util": "1.18.62",
49
+ "@ocap/wallet": "1.18.62",
50
+ "@slack/webhook": "^5.0.4",
51
+ "archiver": "^5.3.1",
52
+ "axios": "^0.27.2",
44
53
  "axon": "^2.0.3",
45
- "chalk": "^4.0.0",
54
+ "chalk": "^4.1.2",
55
+ "dayjs": "^1.11.7",
46
56
  "deep-diff": "^1.0.2",
47
- "detect-port": "^1.3.0",
57
+ "detect-port": "^1.5.1",
58
+ "escape-string-regexp": "^4.0.0",
59
+ "fast-glob": "^3.2.12",
48
60
  "flat": "^5.0.2",
49
- "fs-extra": "^10.0.0",
61
+ "fs-extra": "^11.1.0",
50
62
  "get-port": "^5.1.1",
63
+ "hasha": "^5.2.2",
51
64
  "is-base64": "^1.1.0",
52
65
  "is-ip": "^3.1.0",
53
66
  "is-url": "^1.2.4",
54
- "joi": "^17.4.0",
55
- "js-yaml": "^3.14.0",
67
+ "joi": "17.7.0",
68
+ "js-yaml": "^4.1.0",
56
69
  "lodash": "^4.17.21",
57
70
  "lru-cache": "^6.0.0",
58
- "pm2": "^4.2.3",
59
- "semver": "^7.3.2",
60
- "shelljs": "^0.8.4",
61
- "slugify": "^1.4.6",
62
- "ssri": "^8.0.0",
71
+ "node-stream-zip": "^1.15.0",
72
+ "p-limit": "^3.1.0",
73
+ "p-retry": "4.6.1",
74
+ "pm2": "^5.2.0",
75
+ "semver": "^7.3.8",
76
+ "shelljs": "^0.8.5",
77
+ "ssri": "^8.0.1",
63
78
  "stream-throttle": "^0.1.3",
64
79
  "stream-to-promise": "^3.0.0",
65
- "tar": "^6.1.0",
80
+ "systeminformation": "^5.12.6",
81
+ "tar": "^6.1.11",
82
+ "ua-parser-js": "^1.0.2",
66
83
  "unzipper": "^0.10.11",
67
84
  "url-join": "^4.0.1",
68
- "uuid": "7.0.3"
85
+ "uuid": "7.0.3",
86
+ "valid-url": "^1.0.9"
69
87
  },
70
88
  "devDependencies": {
71
89
  "compression": "^1.7.4",
72
90
  "expand-tilde": "^2.0.2",
73
- "express": "^4.17.1",
74
- "jest": "^27.3.1"
91
+ "express": "^4.18.2",
92
+ "jest": "^27.5.1"
75
93
  },
76
- "gitHead": "22715c3ea74d0230f3413162a17f491614b6735a"
94
+ "gitHead": "57d0c45be311a5fbc1c0fffa2814b62c1a3ee34c"
77
95
  }
@@ -1,205 +0,0 @@
1
- const isBase64 = require('is-base64');
2
- const { BlockletGroup } = require('@blocklet/meta/lib/constants');
3
- const joinURL = require('url-join');
4
- const get = require('lodash/get');
5
- const pick = require('lodash/pick');
6
- const { BLOCKLET_STORE_API_PREFIX } = require('@abtnode/constant');
7
-
8
- const { name } = require('../../package.json');
9
-
10
- const logger = require('@abtnode/logger')(`${name}:blocklet:registry`); // eslint-disable-line
11
-
12
- const request = require('../util/request');
13
-
14
- const states = require('../states');
15
- const isRequirementsSatisfied = require('../util/requirement');
16
- const { fixAndVerifyBlockletMeta } = require('../util/blocklet');
17
- const { translate } = require('../locales');
18
-
19
- const DEFAULT_REFRESH_INTERVAL = 1 * 60 * 1000;
20
- const MAX_REFRESH_INTERVAL = 1 * 60 * 1000;
21
-
22
- class BlockletRegistry {
23
- constructor() {
24
- this.blocklets = [];
25
- this.cacheId = '';
26
- }
27
-
28
- getCron(refreshInterval = DEFAULT_REFRESH_INTERVAL) {
29
- const interval = Math.min(Math.max(Number(refreshInterval), DEFAULT_REFRESH_INTERVAL), MAX_REFRESH_INTERVAL); // Should between 20 ~ 60 seconds
30
- return {
31
- name: 'refetch-blocklet-registry',
32
- time: `*/${Math.round(interval / 1000)} * * * * *`,
33
- fn: this._init.bind(this),
34
- };
35
- }
36
-
37
- async listBlocklets(input, context) {
38
- const registryUrl = await states.node.getBlockletRegistry();
39
-
40
- if (input && input.registryUrl && registryUrl !== input.registryUrl) {
41
- this.blocklets = [];
42
- this.cacheId = '';
43
- }
44
-
45
- if (this.blocklets.length > 0) {
46
- return this.blocklets.filter((x) => isRequirementsSatisfied(x.requirements, false));
47
- }
48
- return this.refreshBlocklets(context);
49
- }
50
-
51
- async hasBlocklet(id) {
52
- const list = await this.listBlocklets();
53
- return list.some((x) => x.did === id || x.name === id);
54
- }
55
-
56
- getBlocklet(id, registryUrl) {
57
- return this.getBlockletMeta({ did: id, registryUrl });
58
- }
59
-
60
- // eslint-disable-next-line no-unused-vars
61
- async getBlockletMeta({ did, registryUrl }, context) {
62
- const defaultRegistryUrl = await states.node.getBlockletRegistry();
63
-
64
- const url = joinURL(
65
- registryUrl || defaultRegistryUrl,
66
- BLOCKLET_STORE_API_PREFIX,
67
- `/blocklets/${did}/blocklet.json?__t__=${Date.now()}`
68
- );
69
-
70
- const { data } = await request.get(url);
71
- try {
72
- return fixAndVerifyBlockletMeta(data, did);
73
- } catch (err) {
74
- logger.error('failed to get blocklet meta', { did, data, error: err });
75
- throw err;
76
- }
77
- }
78
-
79
- async resolveTarballURL({ did, tarball = '', registryUrl = '' }) {
80
- if (!tarball) {
81
- return '';
82
- }
83
-
84
- if (tarball.startsWith('file://')) {
85
- return decodeURIComponent(tarball);
86
- }
87
-
88
- if (tarball.startsWith('http://') || tarball.startsWith('https://')) {
89
- return tarball;
90
- }
91
-
92
- const defaultRegistryUrl = await states.node.getBlockletRegistry();
93
- return joinURL(registryUrl || defaultRegistryUrl, 'api', 'blocklets', did, tarball);
94
- }
95
-
96
- clearCache() {
97
- this.cacheId = '';
98
- this.blocklets = [];
99
- }
100
-
101
- async _init() {
102
- states.node.onReady(async () => {
103
- this.refreshBlocklets().catch(
104
- (error) => logger.error('refresh blocklets failed on initialize the registry', { error })
105
- // eslint-disable-next-line function-paren-newline
106
- );
107
- });
108
- }
109
-
110
- async refreshBlocklets(context) {
111
- const registryUrl = await states.node.getBlockletRegistry();
112
- const url = joinURL(registryUrl, BLOCKLET_STORE_API_PREFIX, '/blocklets.json');
113
- try {
114
- let res = await request.get(url, {
115
- validateStatus: (status) => (status >= 200 && status < 300) || status === 304,
116
- headers: {
117
- 'If-None-Match': this.cacheId,
118
- },
119
- });
120
-
121
- if (res.status === 304 && this.blocklets.length > 0) {
122
- logger.debug('use cached data', { etag: res.headers.etag, registryUrl });
123
- return this.blocklets;
124
- }
125
-
126
- if (res.status === 304) {
127
- res = await request.get(url, {
128
- headers: {
129
- 'Cache-Control': 'no-store',
130
- },
131
- });
132
-
133
- logger.debug('re-fetch from registry', { status: res.status });
134
- }
135
-
136
- if (!Array.isArray(res.data)) {
137
- logger.error('Blocklet list fetch failed, response data is not a list', { url, data: res.data });
138
- throw new Error('Blocklet list fetch failed');
139
- }
140
-
141
- const blocklets = res.data.filter((x) => BlockletGroup[x.group]);
142
- logger.debug('blocklets loaded', { url, blocklets: blocklets.map((x) => ({ did: x.did, name: x.name })) });
143
- this.cacheId = res.headers.etag;
144
- this.blocklets = blocklets;
145
- } catch (error) {
146
- logger.error('refresh blocklet registry failed', { error, registryUrl });
147
- this.cacheId = '';
148
- throw new Error(translate(get(context, 'query.locale', 'en'), 'registry.getListError', { registryUrl }));
149
- }
150
-
151
- return this.blocklets;
152
- }
153
- }
154
-
155
- BlockletRegistry.validateRegistryURL = async (registry) => {
156
- const url = joinURL(registry, BLOCKLET_STORE_API_PREFIX, `/blocklets.json?__t__=${Date.now()}`);
157
- try {
158
- const res = await request.get(url);
159
- if (Array.isArray(res.data)) {
160
- return res.data;
161
- }
162
-
163
- logger.error('Blocklet list fetch failed ', { url, data: res.data });
164
- throw new Error('blocklet list fetch failed');
165
- } catch (error) {
166
- logger.error('Blocklet registry refresh failed', { url, error });
167
- throw new Error(`Invalid Blocklet Registry URL ${registry}: ${error.message}`);
168
- }
169
- };
170
-
171
- BlockletRegistry.getRegistryMeta = async (registry) => {
172
- try {
173
- const url = joinURL(registry, BLOCKLET_STORE_API_PREFIX, `/registry.json?__t__=${Date.now()}`);
174
- const { data } = await request.get(url);
175
-
176
- if (!data) {
177
- return {};
178
- }
179
-
180
- const requiredFields = ['name', 'description', 'maintainer'];
181
-
182
- const missingFields = requiredFields.filter((x) => !data[x]);
183
- if (missingFields.length > 0) {
184
- throw new Error(`the registry missing required information: ${missingFields.join(', ')}`);
185
- }
186
-
187
- const result = pick(data, ['id', 'name', 'description', 'maintainer', 'cdnUrl', 'chainHost']);
188
- const { logoUrl } = data;
189
- if (logoUrl) {
190
- if (logoUrl.startsWith('http') === true) {
191
- result.logoUrl = logoUrl;
192
- } else if (isBase64(logoUrl, { allowMime: true })) {
193
- result.logoUrl = logoUrl;
194
- } else {
195
- result.logoUrl = joinURL(registry, logoUrl);
196
- }
197
- }
198
-
199
- return result;
200
- } catch (err) {
201
- throw new Error(`Can not get meta info for registry [${registry}]: ${err.message}`);
202
- }
203
- };
204
-
205
- module.exports = BlockletRegistry;
@@ -1,67 +0,0 @@
1
- /* eslint-disable no-underscore-dangle */
2
-
3
- const logger = require('@abtnode/logger')('@abtnode/core:https-cert');
4
- const BaseState = require('./base');
5
- const { getHttpsCertInfo } = require('../util');
6
-
7
- const attachHttpsCertInfo = (certificates = []) => {
8
- if (!certificates) {
9
- return null;
10
- }
11
-
12
- if (Array.isArray(certificates)) {
13
- return certificates.map((cert) => {
14
- const info = cert.certificate ? getHttpsCertInfo(cert.certificate) : {};
15
- return { ...cert, ...info };
16
- });
17
- }
18
-
19
- const info = certificates.certificate ? getHttpsCertInfo(certificates.certificate) : {};
20
- return { ...certificates, ...info };
21
- };
22
-
23
- class HttpsCert extends BaseState {
24
- constructor(baseDir, options = {}) {
25
- super(baseDir, { filename: 'https_cert.db', ...options });
26
-
27
- this.db.ensureIndex({ fieldName: 'domain', unique: true }, (error) => {
28
- if (error) {
29
- logger.error('ensure unique index failed', { error });
30
- }
31
- });
32
- }
33
-
34
- async upsert(entity) {
35
- const updateResult = await this.asyncDB.update(
36
- { domain: entity.domain },
37
- { $set: entity },
38
- {
39
- upsert: true,
40
- }
41
- );
42
-
43
- logger.debug('upsert result', { updateResult });
44
-
45
- const newEntity = await this.findOne({ domain: entity.domain });
46
-
47
- return HttpsCert.renameIdFiledName(newEntity);
48
- }
49
-
50
- async find(condition, projection) {
51
- const dbEntity = await this.asyncDB.find(condition, { privateKey: 0, ...(projection || {}) });
52
-
53
- return attachHttpsCertInfo(HttpsCert.renameIdFiledName(dbEntity));
54
- }
55
-
56
- async findOne(condition, projection) {
57
- const dbEntity = await this.asyncDB.findOne(condition, { privateKey: 0, ...(projection || {}) });
58
-
59
- return attachHttpsCertInfo(HttpsCert.renameIdFiledName(dbEntity));
60
- }
61
-
62
- async remove(...args) {
63
- return this.asyncDB.remove(...args);
64
- }
65
- }
66
-
67
- module.exports = HttpsCert;
@@ -1,19 +0,0 @@
1
- const slugify = require('slugify');
2
- const { DEFAULT_IP_DNS_DOMAIN_SUFFIX } = require('@abtnode/constant');
3
-
4
- const SLOT_FOR_IP_DNS_SITE = '888-888-888-888';
5
-
6
- const formatName = (name) => slugify(name.replace(/^[@./-]/, '').replace(/[@./]/g, '-'));
7
-
8
- const hiddenInterfaceNames = ['public', 'publicUrl'];
9
-
10
- const getIpDnsDomainForBlocklet = (blocklet, blockletInterface) => {
11
- const nameSuffix = blocklet.meta.did.slice(-3).toLowerCase();
12
- const iName = hiddenInterfaceNames.includes(blockletInterface.name) ? '' : blockletInterface.name.toLowerCase();
13
-
14
- return `${formatName(blocklet.meta.name)}-${nameSuffix}${
15
- iName ? '-' : ''
16
- }${iName}-${SLOT_FOR_IP_DNS_SITE}.${DEFAULT_IP_DNS_DOMAIN_SUFFIX}`;
17
- };
18
-
19
- module.exports = getIpDnsDomainForBlocklet;
@@ -1,66 +0,0 @@
1
- const fs = require('fs-extra');
2
- const { NODE_SERVICES } = require('@abtnode/constant');
3
-
4
- const servicesNames = Object.values(NODE_SERVICES);
5
-
6
- const getServices = ({ stringifySchema = false } = {}) =>
7
- servicesNames
8
- .map((x) => {
9
- const service = {};
10
-
11
- // Read service meta
12
- try {
13
- const packageFile = require.resolve(`${x}/package.json`);
14
- const { name, description, version } = fs.readJSONSync(packageFile);
15
- service.name = name;
16
- service.description = description || name;
17
- service.version = version;
18
- } catch (err) {
19
- return null;
20
- }
21
-
22
- // Read service config: optional
23
- try {
24
- const schemaFile = require.resolve(`${x}/api/schema.json`);
25
- service.schema = fs.readJSONSync(schemaFile);
26
- } catch (err) {
27
- service.schema = {};
28
- }
29
-
30
- if (stringifySchema) {
31
- service.schema = JSON.stringify(service.schema);
32
- }
33
-
34
- return service;
35
- })
36
- .filter((x) => x.name && x.version);
37
-
38
- const getServicesFromBlockletInterface = (
39
- interfaceMeta,
40
- { logError, services = getServices(), stringifyConfig = true } = {}
41
- ) => {
42
- const list = interfaceMeta.services || [];
43
- return list
44
- .map((s) => {
45
- const service = services.find((t) => t.name === s.name);
46
-
47
- if (!service) {
48
- if (typeof logError === 'function') {
49
- logError('Service in blocklet meta was not found in node');
50
- }
51
- return null;
52
- }
53
-
54
- const { name, version, description } = service;
55
-
56
- const config = stringifyConfig ? JSON.stringify(s.config) : s.config;
57
-
58
- return { name, version, description, config };
59
- })
60
- .filter(Boolean);
61
- };
62
-
63
- module.exports = {
64
- getServices,
65
- getServicesFromBlockletInterface,
66
- };
@@ -1,178 +0,0 @@
1
- /* eslint-disable no-param-reassign */
2
- const axon = require('axon');
3
- const semver = require('semver');
4
- const sleep = require('@abtnode/util/lib/sleep');
5
- const { NODE_PACKAGE_NAME, NODE_MODES, NODE_UPGRADE_PROGRESS } = require('@abtnode/constant');
6
- const listNpmPackageVersion = require('@abtnode/util/lib/list-npm-package-version');
7
- const Lock = require('@abtnode/util/lib/lock');
8
- const logger = require('@abtnode/logger')('@abtnode/core:upgrade');
9
-
10
- const states = require('../states');
11
-
12
- const lock = new Lock('node-upgrade-lock');
13
-
14
- // Connect to updater and send RPC call
15
- const sock = axon.socket('req');
16
- sock.connect(Number(process.env.ABT_NODE_UPDATER_PORT), '127.0.0.1');
17
- const waitUpdaterRpc = async (message) =>
18
- new Promise((resolve) => {
19
- logger.info('send command to updater process', message);
20
- sock.send(JSON.stringify(message), (result) => {
21
- logger.info('receive response from updater process', result);
22
- resolve(result);
23
- });
24
- });
25
-
26
- // eslint-disable-next-line no-unused-vars
27
- const checkNewVersion = async (params, context) => {
28
- try {
29
- const info = await states.node.read();
30
- if (!info.autoUpgrade) {
31
- return '';
32
- }
33
-
34
- const versions = await listNpmPackageVersion(NODE_PACKAGE_NAME);
35
- if (Array.isArray(versions) && versions.length) {
36
- const latestVersion = versions[0].version;
37
- if (semver.gt(latestVersion, info.version)) {
38
- // if (semver.gte(latestVersion, info.version)) {
39
- logger.info('New version found for Blocklet Server', {
40
- latestVersion,
41
- currentVersion: info.version,
42
- nextVersion: info.nextVersion,
43
- });
44
- await states.node.updateNodeInfo({ nextVersion: latestVersion });
45
- await states.notification.create({
46
- title: 'Blocklet Server upgrade available',
47
- description: 'A new and improved version of blocklet server is now available',
48
- entityType: 'node',
49
- severity: 'info',
50
- sticky: true,
51
- action: '/settings/basic',
52
- });
53
-
54
- return latestVersion;
55
- }
56
- }
57
-
58
- return '';
59
- } catch (err) {
60
- logger.error('Failed to check new version for Blocklet Server', { error: err });
61
- }
62
-
63
- return '';
64
- };
65
-
66
- // eslint-disable-next-line no-unused-vars
67
- const startUpgrade = async (params, context) => {
68
- const info = await states.node.read();
69
-
70
- if (!info.nextVersion) {
71
- throw new Error('Do nothing since there is no next version to upgrade');
72
- }
73
-
74
- const from = info.version;
75
- const to = info.nextVersion;
76
-
77
- // 0. ensure we have an upgrading session, we need a session to recover from crash
78
- let sessionId = info.upgradeSessionId;
79
- if (!sessionId) {
80
- const result = await states.session.start({ from, to, stage: NODE_UPGRADE_PROGRESS.SETUP, startedAt: Date.now() });
81
- sessionId = result.id;
82
- logger.info('generate new session for upgrade', { from, to, sessionId });
83
- await states.node.updateNodeInfo({ upgradeSessionId: sessionId });
84
- }
85
- const session = await states.session.read(sessionId);
86
- if (!session) {
87
- throw new Error(`Upgrade aborted due to invalid session: ${sessionId}`);
88
- }
89
-
90
- process.nextTick(async () => {
91
- await doUpgrade(session);
92
- });
93
-
94
- return sessionId;
95
- };
96
-
97
- // TODO: error handling and rollback support
98
- const doUpgrade = async (session) => {
99
- await lock.acquire();
100
-
101
- const sessionId = session.id;
102
- const info = await states.node.read();
103
- const from = info.version;
104
- const to = info.nextVersion;
105
-
106
- const goNextState = async (stage) => {
107
- session = await states.session.update(sessionId, { stage });
108
- // Emit events so client will keep up
109
- states.node.emit('node.upgrade.progress', session);
110
- };
111
-
112
- // 1. enter maintenance mode
113
- if (session.stage === NODE_UPGRADE_PROGRESS.SETUP) {
114
- logger.info('enter maintenance mode for upgrading', { from, to, sessionId });
115
- await states.node.enterMode(NODE_MODES.MAINTENANCE);
116
- await goNextState(NODE_UPGRADE_PROGRESS.INSTALLING);
117
- }
118
-
119
- // 2. install specified version
120
- if (session.stage === NODE_UPGRADE_PROGRESS.INSTALLING) {
121
- await waitUpdaterRpc({ command: 'install', version: to });
122
- logger.info('new version installed for upgrading', { from, to, sessionId });
123
- await goNextState(NODE_UPGRADE_PROGRESS.RESTARTING);
124
- }
125
-
126
- // 3. restarting update version in node config and state
127
- if (session.stage === NODE_UPGRADE_PROGRESS.RESTARTING) {
128
- logger.info('daemon restarted for upgrading', { from, to, sessionId });
129
- await sleep(3000);
130
- await goNextState(NODE_UPGRADE_PROGRESS.CLEANUP);
131
- await sleep(3000);
132
- await waitUpdaterRpc({ command: 'restart', dataDir: process.env.ABT_NODE_DATA_DIR });
133
- await lock.release();
134
- return; // we should abort here and resume after restart
135
- }
136
-
137
- // 4. reset node.nextVersion/upgradeSessionId and exit maintenance mode
138
- if (session.stage === NODE_UPGRADE_PROGRESS.CLEANUP) {
139
- logger.info('cleanup for upgrading', { from, to, sessionId });
140
- await goNextState(NODE_UPGRADE_PROGRESS.COMPLETE);
141
- await sleep(5000);
142
- await states.node.updateNodeInfo({ nextVersion: '', version: to, upgradeSessionId: '' });
143
- try {
144
- await states.node.exitMode(NODE_MODES.MAINTENANCE);
145
- } catch (error) {
146
- logger.error('Failed to exit maintenance mode', { error });
147
- }
148
- }
149
- await lock.release();
150
- };
151
-
152
- const isUpgrading = async () => {
153
- const info = await states.node.read();
154
- if (!info.nextVersion) {
155
- return false;
156
- }
157
-
158
- if (!info.upgradeSessionId) {
159
- return false;
160
- }
161
-
162
- const session = await states.session.read(info.upgradeSessionId);
163
- if (!session) {
164
- return false;
165
- }
166
-
167
- return session;
168
- };
169
-
170
- const getCron = () => ({
171
- name: 'check-update',
172
- time: '0 0 8 * * *', // check every day
173
- // time: '0 */5 * * * *', // check every 5 minutes
174
- fn: checkNewVersion,
175
- options: { runOnInit: false },
176
- });
177
-
178
- module.exports = { getCron, checkNewVersion, doUpgrade, startUpgrade, isUpgrading };
File without changes