@abtnode/core 1.5.13 → 1.15.17
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/blocklet/extras.js +1 -1
- package/lib/blocklet/hooks.js +4 -1
- package/lib/blocklet/manager/disk.js +30 -8
- package/lib/blocklet/migration.js +95 -47
- package/lib/blocklet/registry.js +5 -5
- package/lib/event.js +2 -2
- package/lib/migrations/1.5.15-site.js +184 -0
- package/lib/router/helper.js +124 -92
- package/lib/router/index.js +10 -2
- package/lib/router/manager.js +7 -7
- package/lib/states/site.js +1 -1
- package/lib/team/manager.js +1 -1
- package/lib/util/default-node-config.js +6 -6
- package/lib/util/index.js +29 -14
- package/lib/util/ready.js +5 -5
- package/lib/util/upgrade.js +4 -4
- package/lib/validators/router.js +13 -7
- package/lib/webhook/index.js +2 -2
- package/lib/webhook/sender/slack/index.js +1 -1
- package/package.json +18 -18
package/lib/blocklet/extras.js
CHANGED
|
@@ -26,7 +26,7 @@ const mergeConfigs = (oldConfigs, newConfigs = []) => {
|
|
|
26
26
|
// newConfig 为用户传的,也可以是从环境变量中去读的
|
|
27
27
|
const uniqConfigs = uniqBy(newConfigs, (x) => x.key || x.name);
|
|
28
28
|
|
|
29
|
-
// `BLOCKLET_*` and `ABT_NODE_*` vars can only be set by
|
|
29
|
+
// `BLOCKLET_*` and `ABT_NODE_*` vars can only be set by Blocklet Server Daemon with only a few exceptions.
|
|
30
30
|
const newConfig = uniqConfigs.filter((x) => {
|
|
31
31
|
const key = x.key || x.name;
|
|
32
32
|
|
package/lib/blocklet/hooks.js
CHANGED
|
@@ -5,10 +5,13 @@ const camelCase = require('lodash/camelCase');
|
|
|
5
5
|
// eslint-disable-next-line global-require
|
|
6
6
|
const logger = require('@abtnode/logger')(`${require('../../package.json').name}:blocklet:hooks`);
|
|
7
7
|
|
|
8
|
+
const { getSafeEnv } = require('../util');
|
|
9
|
+
|
|
8
10
|
const runAsync = ({ appDir, env, hook, progress = false }) => {
|
|
11
|
+
const safeEnv = getSafeEnv(env);
|
|
9
12
|
const child = childProcess.exec(hook, {
|
|
10
13
|
cwd: appDir,
|
|
11
|
-
env:
|
|
14
|
+
env: safeEnv,
|
|
12
15
|
stdio: 'inherit',
|
|
13
16
|
});
|
|
14
17
|
|
|
@@ -221,12 +221,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
221
221
|
async start({ did, checkHealthImmediately = false, throwOnError }, context) {
|
|
222
222
|
logger.info('start blocklet', { did });
|
|
223
223
|
const blocklet = await this.ensureBlocklet(did);
|
|
224
|
-
try {
|
|
225
|
-
await runMigrationScripts({ blocklet });
|
|
226
|
-
} catch (error) {
|
|
227
|
-
logger.error('Failed to migrate blocklet', { did, error });
|
|
228
|
-
throw error;
|
|
229
|
-
}
|
|
230
224
|
|
|
231
225
|
try {
|
|
232
226
|
// check required config
|
|
@@ -961,7 +955,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
961
955
|
return a.from.pathPrefix.length < b.from.pathPrefix ? 1 : -1;
|
|
962
956
|
});
|
|
963
957
|
const nodeIp = await getAccessibleExternalNodeIp(nodeInfo);
|
|
964
|
-
return getBlockletInterfaces({ blocklet, context, nodeInfo,
|
|
958
|
+
return getBlockletInterfaces({ blocklet, context, nodeInfo, routingRules, nodeIp });
|
|
965
959
|
}
|
|
966
960
|
|
|
967
961
|
async attachRuntimeInfo({ did, nodeInfo, diskInfo = true, context, cachedBlocklet }) {
|
|
@@ -1432,7 +1426,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1432
1426
|
|
|
1433
1427
|
// download
|
|
1434
1428
|
await this._downloadBlocklet(blocklet);
|
|
1435
|
-
|
|
1436
1429
|
return this._installBlocklet({
|
|
1437
1430
|
did: meta.did,
|
|
1438
1431
|
context,
|
|
@@ -1644,6 +1637,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1644
1637
|
|
|
1645
1638
|
const oldBlocklet = await this.state.getBlocklet(did);
|
|
1646
1639
|
|
|
1640
|
+
// NOTE: 目前的版本移除了降级通道,所以不需要考虑降级通道的情况
|
|
1647
1641
|
const action = semver.gt(oldBlocklet.meta.version, version) ? 'downgrade' : 'upgrade';
|
|
1648
1642
|
logger.info(`${action} blocklet`, { did, version });
|
|
1649
1643
|
|
|
@@ -1915,6 +1909,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1915
1909
|
const { meta, source, deployedFrom, children } = newBlocklet;
|
|
1916
1910
|
const { did, version, name } = meta;
|
|
1917
1911
|
|
|
1912
|
+
const oldVersion = oldBlocklet.meta.version;
|
|
1918
1913
|
const action = semver.gt(oldBlocklet.meta.version, version) ? 'downgrade' : 'upgrade';
|
|
1919
1914
|
try {
|
|
1920
1915
|
// delete old process
|
|
@@ -1960,6 +1955,33 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1960
1955
|
});
|
|
1961
1956
|
await forEachBlocklet(blocklet, postInstall, { parallel: true });
|
|
1962
1957
|
|
|
1958
|
+
// run migrations
|
|
1959
|
+
const runMigration = (b) => {
|
|
1960
|
+
// BUG: 本身的定义是在执行 upgrade 操作时进行 migration,但是父 blocklet upgrade 时,子 blocklet 可能不需要 upgrade,就会导致子 blocklet 多走了一遍 migration 流程
|
|
1961
|
+
if (b.meta.did === did) {
|
|
1962
|
+
return runMigrationScripts({
|
|
1963
|
+
blocklet: b,
|
|
1964
|
+
oldVersion,
|
|
1965
|
+
newVersion: version,
|
|
1966
|
+
env: getRuntimeEnvironments(b, nodeEnvironments),
|
|
1967
|
+
appDir: b.env.appDir,
|
|
1968
|
+
did: b.meta.did,
|
|
1969
|
+
notification: this.notification,
|
|
1970
|
+
context,
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
1973
|
+
return Promise.resolve();
|
|
1974
|
+
};
|
|
1975
|
+
logger.info('start migration');
|
|
1976
|
+
|
|
1977
|
+
try {
|
|
1978
|
+
await forEachBlocklet(blocklet, runMigration, { parallel: true });
|
|
1979
|
+
} catch (error) {
|
|
1980
|
+
logger.error('Failed to migrate blocklet', { did, error });
|
|
1981
|
+
throw error;
|
|
1982
|
+
}
|
|
1983
|
+
logger.info('end migration');
|
|
1984
|
+
|
|
1963
1985
|
logger.info('updated blocklet for upgrading', { did, version, source, name });
|
|
1964
1986
|
|
|
1965
1987
|
// start new process
|
|
@@ -1,10 +1,68 @@
|
|
|
1
1
|
/* eslint-disable no-await-in-loop */
|
|
2
|
+
const childProcess = require('child_process');
|
|
2
3
|
const fs = require('fs-extra');
|
|
3
4
|
const path = require('path');
|
|
4
5
|
const semver = require('semver');
|
|
6
|
+
|
|
5
7
|
const { getMigrationScripts: getScripts } = require('../migrations');
|
|
8
|
+
const { getSafeEnv } = require('../util');
|
|
9
|
+
const { name } = require('../../package.json');
|
|
10
|
+
const logger = require('@abtnode/logger')(`${name}:blocklet:migration`); // eslint-disable-line
|
|
11
|
+
|
|
12
|
+
const _runScript = ({ appDir, env, migrationScript, progress = false }) => {
|
|
13
|
+
const safeEnv = getSafeEnv(env);
|
|
14
|
+
|
|
15
|
+
const child = childProcess.exec(`node ${migrationScript}`, {
|
|
16
|
+
cwd: appDir,
|
|
17
|
+
env: safeEnv,
|
|
18
|
+
stdio: 'inherit',
|
|
19
|
+
});
|
|
20
|
+
let hasUnhandledRejection = false;
|
|
21
|
+
|
|
22
|
+
if (progress) {
|
|
23
|
+
child.stdout.pipe(process.stdout);
|
|
24
|
+
child.stderr.pipe(process.stderr);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
const errorMessages = [];
|
|
29
|
+
|
|
30
|
+
child.stderr.on('data', (err) => {
|
|
31
|
+
// Check if has unhandledRejection in childProcess
|
|
32
|
+
// https://stackoverflow.com/questions/32784649/gracefully-handle-errors-in-child-processes-in-nodejs
|
|
33
|
+
if (err.includes('UnhandledPromiseRejectionWarning')) {
|
|
34
|
+
hasUnhandledRejection = true;
|
|
35
|
+
}
|
|
36
|
+
errorMessages.push(err);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
child.on('exit', (code) => {
|
|
40
|
+
if (errorMessages.length > 0) {
|
|
41
|
+
if (code !== 0 || hasUnhandledRejection) {
|
|
42
|
+
return reject(new Error(errorMessages.join('\r\n')));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!progress) {
|
|
46
|
+
errorMessages.forEach((message) => process.stderr.write(message));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
6
49
|
|
|
7
|
-
|
|
50
|
+
return resolve();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
async function runScripts({
|
|
56
|
+
dbDir,
|
|
57
|
+
backupDir,
|
|
58
|
+
scriptsDir,
|
|
59
|
+
printInfo,
|
|
60
|
+
printSuccess,
|
|
61
|
+
printError,
|
|
62
|
+
appDir,
|
|
63
|
+
env,
|
|
64
|
+
oldVersion,
|
|
65
|
+
}) {
|
|
8
66
|
let scripts = [];
|
|
9
67
|
try {
|
|
10
68
|
scripts = await getScripts(scriptsDir);
|
|
@@ -14,16 +72,7 @@ async function runScripts({ CONFIG_FILE, DB_DIR, BAK_DIR, scriptsDir, printInfo,
|
|
|
14
72
|
throw err;
|
|
15
73
|
}
|
|
16
74
|
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
config = fs.readJsonSync(CONFIG_FILE);
|
|
20
|
-
} catch {
|
|
21
|
-
config = {
|
|
22
|
-
version: '0.0.0',
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const pendingScripts = scripts.filter((x) => semver.gt(x.version, config.version));
|
|
75
|
+
const pendingScripts = scripts.filter((x) => semver.gt(x.version, oldVersion));
|
|
27
76
|
|
|
28
77
|
if (!pendingScripts.length) {
|
|
29
78
|
return true;
|
|
@@ -31,25 +80,23 @@ async function runScripts({ CONFIG_FILE, DB_DIR, BAK_DIR, scriptsDir, printInfo,
|
|
|
31
80
|
|
|
32
81
|
printInfo('pending scripts', pendingScripts);
|
|
33
82
|
try {
|
|
34
|
-
await doBackup({
|
|
83
|
+
await doBackup({ dbDir, backupDir, printInfo, printSuccess, printError });
|
|
35
84
|
} catch (err) {
|
|
36
85
|
printError(`Failed to backup state db due to ${err.message}, abort!`);
|
|
37
86
|
throw err;
|
|
38
87
|
}
|
|
39
88
|
|
|
40
89
|
for (let i = 0; i < pendingScripts.length; i++) {
|
|
41
|
-
const {
|
|
90
|
+
const { script: scriptPath } = pendingScripts[i];
|
|
42
91
|
try {
|
|
43
|
-
// eslint-disable-next-line
|
|
44
|
-
const scriptFn = require(path.join(folder, scriptPath));
|
|
45
92
|
printInfo(`Migration script started: ${scriptPath}`);
|
|
46
|
-
await
|
|
93
|
+
await _runScript({ appDir, env, migrationScript: path.join(scriptsDir, scriptPath) });
|
|
47
94
|
printInfo(`Migration script executed: ${scriptPath}`);
|
|
48
95
|
} catch (migrationErr) {
|
|
49
96
|
printError(`Failed to execute migration script: ${scriptPath}, error: ${migrationErr.message}`);
|
|
50
97
|
|
|
51
98
|
try {
|
|
52
|
-
await doRestore({
|
|
99
|
+
await doRestore({ dbDir, backupDir, printInfo, printSuccess, printError });
|
|
53
100
|
} catch (restoreErr) {
|
|
54
101
|
printError(`Failed to restore state db due to: ${restoreErr.message}`);
|
|
55
102
|
}
|
|
@@ -58,51 +105,52 @@ async function runScripts({ CONFIG_FILE, DB_DIR, BAK_DIR, scriptsDir, printInfo,
|
|
|
58
105
|
}
|
|
59
106
|
}
|
|
60
107
|
|
|
61
|
-
fs.writeJsonSync(CONFIG_FILE, {
|
|
62
|
-
version: pendingScripts[pendingScripts.length - 1].version,
|
|
63
|
-
});
|
|
64
|
-
|
|
65
108
|
return true;
|
|
66
109
|
}
|
|
67
110
|
|
|
68
|
-
async function doBackup({
|
|
111
|
+
async function doBackup({ dbDir, backupDir, printInfo, printSuccess }) {
|
|
69
112
|
printInfo('Backing up before migration...');
|
|
70
|
-
fs.emptyDirSync(
|
|
71
|
-
fs.copySync(
|
|
113
|
+
fs.emptyDirSync(backupDir);
|
|
114
|
+
fs.copySync(dbDir, backupDir);
|
|
72
115
|
printSuccess('Backup success');
|
|
73
116
|
}
|
|
74
117
|
|
|
75
|
-
async function doRestore({
|
|
118
|
+
async function doRestore({ dbDir, backupDir, printInfo, printSuccess }) {
|
|
76
119
|
printInfo('Restoring when migration failed...');
|
|
77
|
-
fs.emptyDirSync(
|
|
78
|
-
fs.copySync(
|
|
120
|
+
fs.emptyDirSync(dbDir);
|
|
121
|
+
fs.copySync(backupDir, dbDir);
|
|
79
122
|
printSuccess('Restore succeed');
|
|
80
123
|
}
|
|
81
124
|
|
|
82
125
|
module.exports = async ({
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
126
|
+
appDir,
|
|
127
|
+
env,
|
|
128
|
+
oldVersion,
|
|
129
|
+
newVersion,
|
|
130
|
+
printInfo = logger.info,
|
|
131
|
+
printSuccess = logger.info,
|
|
132
|
+
printError = logger.error,
|
|
87
133
|
}) => {
|
|
88
|
-
const
|
|
89
|
-
const baseDir = blocklet.environmentObj.BLOCKLET_DATA_DIR;
|
|
90
|
-
const appDir = blocklet.environmentObj.BLOCKLET_APP_DIR;
|
|
134
|
+
const baseDir = env.BLOCKLET_DATA_DIR;
|
|
91
135
|
|
|
92
136
|
const scriptsDir = path.join(appDir, 'migration');
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const CONFIG_FILE = path.join(baseDir, 'config.json');
|
|
137
|
+
const dbDir = path.join(baseDir, 'db');
|
|
138
|
+
const backupDir = path.join(baseDir, 'db-bak');
|
|
96
139
|
|
|
97
140
|
fs.ensureDirSync(scriptsDir);
|
|
98
|
-
fs.ensureDirSync(
|
|
99
|
-
fs.ensureDirSync(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
141
|
+
fs.ensureDirSync(dbDir);
|
|
142
|
+
fs.ensureDirSync(backupDir);
|
|
143
|
+
|
|
144
|
+
await runScripts({
|
|
145
|
+
dbDir,
|
|
146
|
+
backupDir,
|
|
147
|
+
scriptsDir,
|
|
148
|
+
printError,
|
|
149
|
+
printInfo,
|
|
150
|
+
printSuccess,
|
|
151
|
+
appDir,
|
|
152
|
+
env,
|
|
153
|
+
oldVersion,
|
|
154
|
+
newVersion,
|
|
155
|
+
});
|
|
108
156
|
};
|
package/lib/blocklet/registry.js
CHANGED
|
@@ -3,7 +3,7 @@ const { BlockletGroup } = require('@blocklet/meta/lib/constants');
|
|
|
3
3
|
const joinURL = require('url-join');
|
|
4
4
|
const get = require('lodash/get');
|
|
5
5
|
const pick = require('lodash/pick');
|
|
6
|
-
const {
|
|
6
|
+
const { BLOCKLET_STORE_API_PREFIX } = require('@abtnode/constant');
|
|
7
7
|
|
|
8
8
|
const { name } = require('../../package.json');
|
|
9
9
|
|
|
@@ -63,7 +63,7 @@ class BlockletRegistry {
|
|
|
63
63
|
|
|
64
64
|
const url = joinURL(
|
|
65
65
|
registryUrl || defaultRegistryUrl,
|
|
66
|
-
|
|
66
|
+
BLOCKLET_STORE_API_PREFIX,
|
|
67
67
|
`/blocklets/${did}/blocklet.json?__t__=${Date.now()}`
|
|
68
68
|
);
|
|
69
69
|
|
|
@@ -109,7 +109,7 @@ class BlockletRegistry {
|
|
|
109
109
|
|
|
110
110
|
async refreshBlocklets(context) {
|
|
111
111
|
const registryUrl = await states.node.getBlockletRegistry();
|
|
112
|
-
const url = joinURL(registryUrl,
|
|
112
|
+
const url = joinURL(registryUrl, BLOCKLET_STORE_API_PREFIX, '/blocklets.json');
|
|
113
113
|
try {
|
|
114
114
|
let res = await request.get(url, {
|
|
115
115
|
validateStatus: (status) => (status >= 200 && status < 300) || status === 304,
|
|
@@ -153,7 +153,7 @@ class BlockletRegistry {
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
BlockletRegistry.validateRegistryURL = async (registry) => {
|
|
156
|
-
const url = joinURL(registry,
|
|
156
|
+
const url = joinURL(registry, BLOCKLET_STORE_API_PREFIX, `/blocklets.json?__t__=${Date.now()}`);
|
|
157
157
|
try {
|
|
158
158
|
const res = await request.get(url);
|
|
159
159
|
if (Array.isArray(res.data)) {
|
|
@@ -170,7 +170,7 @@ BlockletRegistry.validateRegistryURL = async (registry) => {
|
|
|
170
170
|
|
|
171
171
|
BlockletRegistry.getRegistryMeta = async (registry) => {
|
|
172
172
|
try {
|
|
173
|
-
const url = joinURL(registry,
|
|
173
|
+
const url = joinURL(registry, BLOCKLET_STORE_API_PREFIX, `/registry.json?__t__=${Date.now()}`);
|
|
174
174
|
const { data } = await request.get(url);
|
|
175
175
|
|
|
176
176
|
if (!data) {
|
package/lib/event.js
CHANGED
|
@@ -128,8 +128,8 @@ module.exports = ({
|
|
|
128
128
|
const handleCLIEvent = (eventName) => {
|
|
129
129
|
const [, status] = eventName.split('.');
|
|
130
130
|
onEvent(eventName, {
|
|
131
|
-
title: `
|
|
132
|
-
description: `
|
|
131
|
+
title: `Blocklet Server ${status}`,
|
|
132
|
+
description: `Blocklet Server is ${status} successfully`,
|
|
133
133
|
entityType: 'node',
|
|
134
134
|
status: 'success',
|
|
135
135
|
});
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/* eslint-disable no-continue */
|
|
2
|
+
/* eslint-disable no-await-in-loop */
|
|
3
|
+
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
4
|
+
|
|
5
|
+
const findBlocklet = (site, blocklets) => {
|
|
6
|
+
// prefix = /
|
|
7
|
+
const rootRule = site.rules.find((x) => x.from.pathPrefix === '/' && x.to.type === 'blocklet');
|
|
8
|
+
if (rootRule) {
|
|
9
|
+
const blocklet = blocklets.find((x) => x.meta.did === rootRule.to.did);
|
|
10
|
+
if (blocklet) {
|
|
11
|
+
return blocklet;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
for (const rule of site.rules) {
|
|
16
|
+
if (rule.to.type === 'blocklet') {
|
|
17
|
+
const blocklet = blocklets.find((x) => x.meta.did === rule.to.did);
|
|
18
|
+
if (blocklet) {
|
|
19
|
+
return blocklet;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return null;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const mergeSite = (newSite, oldSite) => {
|
|
28
|
+
const { domain, domainAliases = [], isProtected, rules, corsAllowedOrigins } = oldSite;
|
|
29
|
+
|
|
30
|
+
// merge domain
|
|
31
|
+
const domains = [
|
|
32
|
+
{
|
|
33
|
+
value: domain,
|
|
34
|
+
isProtected,
|
|
35
|
+
},
|
|
36
|
+
...(domainAliases || []).map((x) => (typeof x === 'string' ? { value: x, isProtected: false } : x)),
|
|
37
|
+
];
|
|
38
|
+
domains.forEach((x) => {
|
|
39
|
+
if (!newSite.domainAliases.some((y) => y.value === x.value)) {
|
|
40
|
+
newSite.domainAliases.push(x);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// merge cors
|
|
45
|
+
(corsAllowedOrigins || []).forEach((x) => {
|
|
46
|
+
if (!newSite.corsAllowedOrigins.includes(x)) {
|
|
47
|
+
newSite.corsAllowedOrigins.push(x);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// merge rules
|
|
52
|
+
(rules || []).forEach((x) => {
|
|
53
|
+
if (!newSite.rules.some((y) => normalizePathPrefix(y.from.pathPrefix) === normalizePathPrefix(x.from.pathPrefix))) {
|
|
54
|
+
newSite.rules.push(x);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
module.exports = async ({ states, node, printInfo }) => {
|
|
60
|
+
printInfo('Migrate site to 2.0 version for router...\n');
|
|
61
|
+
|
|
62
|
+
const sites = await states.site.getSites();
|
|
63
|
+
const blocklets = await states.blocklet.getBlocklets();
|
|
64
|
+
printInfo(`Find blocklets: ${blocklets.length}`);
|
|
65
|
+
|
|
66
|
+
// blocklet site which ends with 888-888-888-888.ip.abtnet.io
|
|
67
|
+
const blockletSystemSites = [];
|
|
68
|
+
|
|
69
|
+
// custom site added by user
|
|
70
|
+
const customSites = [];
|
|
71
|
+
|
|
72
|
+
sites.forEach((site) => {
|
|
73
|
+
const { domain } = site;
|
|
74
|
+
|
|
75
|
+
// filter 3 default basic site
|
|
76
|
+
if (domain === '' || domain === '127.0.0.1' || domain === '*') {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const blocklet = findBlocklet(site, blocklets);
|
|
81
|
+
|
|
82
|
+
if (domain.endsWith('888-888-888-888.ip.abtnet.io')) {
|
|
83
|
+
blockletSystemSites.push({
|
|
84
|
+
site,
|
|
85
|
+
blocklet,
|
|
86
|
+
});
|
|
87
|
+
} else {
|
|
88
|
+
customSites.push({
|
|
89
|
+
site,
|
|
90
|
+
blocklet,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
printInfo(
|
|
96
|
+
`Find sites: ${sites.length}; blockletSystemSites: ${blockletSystemSites.length}; customSites: ${customSites.length}\n`
|
|
97
|
+
);
|
|
98
|
+
printInfo(`blockletSystemSites: ${blockletSystemSites.map((x) => x.site.domain).join(', ')}\n`);
|
|
99
|
+
printInfo(`customSites: ${customSites.map((x) => x.site.domain).join(', ')}\n`);
|
|
100
|
+
|
|
101
|
+
// generate new blocklet site for every installed blocklet
|
|
102
|
+
const newBlockletSites = {}; // <blockletDid>: <site>
|
|
103
|
+
for (const blocklet of blocklets) {
|
|
104
|
+
const domain = `${blocklet.meta.did}.blocklet-domain-group`;
|
|
105
|
+
newBlockletSites[blocklet.meta.did] = {
|
|
106
|
+
domain,
|
|
107
|
+
domainAliases: [],
|
|
108
|
+
isProtected: true,
|
|
109
|
+
rules: [],
|
|
110
|
+
corsAllowedOrigins: [],
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
printInfo(
|
|
114
|
+
`newBlockletSites: ${Object.values(newBlockletSites)
|
|
115
|
+
.map((x) => x.domain)
|
|
116
|
+
.join(', ')}\n`
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
printInfo('\n');
|
|
120
|
+
printInfo('Start merge blockletSystemSites to new sites');
|
|
121
|
+
for (const { site: oldSite, blocklet } of blockletSystemSites) {
|
|
122
|
+
// merge blockletSystemSite to new blocklet site
|
|
123
|
+
if (blocklet) {
|
|
124
|
+
const newSite = newBlockletSites[blocklet.meta.did];
|
|
125
|
+
mergeSite(newSite, oldSite);
|
|
126
|
+
printInfo(`Merge site from ${oldSite.domain} to ${newSite.domain}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
printInfo('\n');
|
|
131
|
+
printInfo('Start merge customSites to new sites');
|
|
132
|
+
for (const { site: oldSite, blocklet } of customSites) {
|
|
133
|
+
// reserve custom site which not belong to any blocklet
|
|
134
|
+
if (!blocklet) {
|
|
135
|
+
printInfo(`Skip merge custom site: ${oldSite.domain}`);
|
|
136
|
+
oldSite.skip = true;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
// merge custom site to new blocklet site
|
|
140
|
+
const newSite = newBlockletSites[blocklet.meta.did];
|
|
141
|
+
mergeSite(newSite, oldSite);
|
|
142
|
+
printInfo(`Merge site from ${oldSite.domain} to ${newSite.domain}`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
printInfo('\n');
|
|
146
|
+
printInfo('Start delete blockletSystemSites from db');
|
|
147
|
+
for (const { site: oldSite } of blockletSystemSites) {
|
|
148
|
+
if (oldSite.skip) {
|
|
149
|
+
printInfo(`Skip delete site from db: ${oldSite.domain}`);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// delete each blockletSystemSite
|
|
153
|
+
await states.site.remove({ _id: oldSite.id });
|
|
154
|
+
printInfo(`Delete site from db: ${oldSite.domain}`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
printInfo('\n');
|
|
158
|
+
printInfo('Start delete customSites from db');
|
|
159
|
+
for (const { site: oldSite } of customSites) {
|
|
160
|
+
if (oldSite.skip) {
|
|
161
|
+
printInfo(`Skip delete site from db: ${oldSite.domain}`);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
// delete custom site which bind to a blocklet
|
|
165
|
+
await states.site.remove({ _id: oldSite.id });
|
|
166
|
+
printInfo(`Delete site from db: ${oldSite.domain}`);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// add new blocklet site to db
|
|
170
|
+
printInfo('\n');
|
|
171
|
+
printInfo('Start add new sites to db');
|
|
172
|
+
for (const site of Object.values(newBlockletSites)) {
|
|
173
|
+
await states.site.add(site);
|
|
174
|
+
printInfo(`Add site to db: ${site.domain}`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
await node.takeRoutingSnapshot({
|
|
178
|
+
message: 'Migrate site to 2.0 version for router',
|
|
179
|
+
dryRun: false,
|
|
180
|
+
handleRouting: false,
|
|
181
|
+
});
|
|
182
|
+
printInfo('\n');
|
|
183
|
+
printInfo('Take routing snapshot');
|
|
184
|
+
};
|