@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
@@ -1,68 +1,27 @@
1
1
  /* eslint-disable no-await-in-loop */
2
- const childProcess = require('child_process');
3
2
  const fs = require('fs-extra');
4
3
  const path = require('path');
5
4
  const semver = require('semver');
5
+ const runScript = require('@abtnode/util/lib/run-script');
6
6
 
7
7
  const { getMigrationScripts: getScripts } = require('../migrations');
8
8
  const { getSafeEnv } = require('../util');
9
9
  const { name } = require('../../package.json');
10
10
  const logger = require('@abtnode/logger')(`${name}:blocklet:migration`); // eslint-disable-line
11
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
- }
49
-
50
- return resolve();
51
- });
52
- });
53
- };
54
-
55
12
  async function runScripts({
13
+ blocklet,
14
+ appDir,
15
+ env,
16
+ oldVersion,
56
17
  dbDir,
57
18
  backupDir,
58
19
  scriptsDir,
59
20
  printInfo,
60
21
  printSuccess,
61
22
  printError,
62
- appDir,
63
- env,
64
- oldVersion,
65
23
  }) {
24
+ // 获取所有待执行的脚本
66
25
  let scripts = [];
67
26
  try {
68
27
  scripts = await getScripts(scriptsDir);
@@ -79,25 +38,36 @@ async function runScripts({
79
38
  }
80
39
 
81
40
  printInfo('pending scripts', pendingScripts);
41
+ // 执行脚本前需要对数据库文件做一次备份
82
42
  try {
83
43
  await doBackup({ dbDir, backupDir, printInfo, printSuccess, printError });
84
44
  } catch (err) {
85
45
  printError(`Failed to backup state db due to ${err.message}, abort!`);
46
+ // 备份失败时,需要移除备份目录
47
+ fs.removeSync(backupDir);
86
48
  throw err;
87
49
  }
88
50
 
51
+ // 按照顺序依次执行 migration 脚本
89
52
  for (let i = 0; i < pendingScripts.length; i++) {
90
53
  const { script: scriptPath } = pendingScripts[i];
91
54
  try {
92
55
  printInfo(`Migration script started: ${scriptPath}`);
93
- await _runScript({ appDir, env, migrationScript: path.join(scriptsDir, scriptPath) });
56
+ await runScript(`node ${path.join(scriptsDir, scriptPath)}`, [blocklet.env.processId, 'migration'].join(':'), {
57
+ cwd: appDir,
58
+ env: getSafeEnv(env),
59
+ silent: false,
60
+ });
94
61
  printInfo(`Migration script executed: ${scriptPath}`);
95
62
  } catch (migrationErr) {
96
63
  printError(`Failed to execute migration script: ${scriptPath}, error: ${migrationErr.message}`);
97
64
 
98
65
  try {
99
66
  await doRestore({ dbDir, backupDir, printInfo, printSuccess, printError });
67
+ // 恢复备份成功时,需要移除备份目录
68
+ fs.removeSync(backupDir);
100
69
  } catch (restoreErr) {
70
+ // 如果恢复备份失败,则保留备份目录,恢复数据
101
71
  printError(`Failed to restore state db due to: ${restoreErr.message}`);
102
72
  }
103
73
 
@@ -123,6 +93,7 @@ async function doRestore({ dbDir, backupDir, printInfo, printSuccess }) {
123
93
  }
124
94
 
125
95
  module.exports = async ({
96
+ blocklet,
126
97
  appDir,
127
98
  env,
128
99
  oldVersion,
@@ -131,6 +102,10 @@ module.exports = async ({
131
102
  printSuccess = logger.info,
132
103
  printError = logger.error,
133
104
  }) => {
105
+ if (!oldVersion) {
106
+ return;
107
+ }
108
+
134
109
  const baseDir = env.BLOCKLET_DATA_DIR;
135
110
 
136
111
  const scriptsDir = path.join(appDir, 'migration');
@@ -142,15 +117,18 @@ module.exports = async ({
142
117
  fs.ensureDirSync(backupDir);
143
118
 
144
119
  await runScripts({
120
+ blocklet,
121
+ appDir,
122
+ env,
123
+ oldVersion,
124
+ newVersion,
145
125
  dbDir,
146
126
  backupDir,
147
127
  scriptsDir,
148
128
  printError,
149
129
  printInfo,
150
130
  printSuccess,
151
- appDir,
152
- env,
153
- oldVersion,
154
- newVersion,
155
131
  });
132
+
133
+ fs.removeSync(backupDir);
156
134
  };
@@ -0,0 +1,27 @@
1
+ const { removeSync, outputJsonSync } = require('fs-extra');
2
+ const { join } = require('path');
3
+ const states = require('../../../states');
4
+ const { BaseBackup } = require('./base');
5
+
6
+ /**
7
+ *
8
+ *
9
+ * @class AuditLogBackup
10
+ */
11
+ class AuditLogBackup extends BaseBackup {
12
+ filename = 'audit-log.json';
13
+
14
+ async export() {
15
+ /**
16
+ * @type {import('@abtnode/client').AuditLog}
17
+ */
18
+ const auditLogs = await states.auditLog.find({
19
+ scope: this.blocklet.meta.did,
20
+ });
21
+
22
+ removeSync(join(this.backupDir, this.filename));
23
+ outputJsonSync(join(this.backupDir, this.filename), auditLogs);
24
+ }
25
+ }
26
+
27
+ module.exports = { AuditLogBackup };
@@ -0,0 +1,62 @@
1
+ class BaseBackup {
2
+ /**
3
+ * @type {import('./spaces').SpaceBackupInput}
4
+ * @memberof BaseBackup
5
+ */
6
+ input;
7
+
8
+ /**
9
+ * @description blocklet state 对象
10
+ * @type {import('@abtnode/client').BlockletState}
11
+ * @memberof BaseBackup
12
+ */
13
+ blocklet;
14
+
15
+ /**
16
+ * @description 当前 blocklet 的数据目录
17
+ * @type {string}
18
+ * @memberof BaseBackup
19
+ */
20
+ backupDir;
21
+
22
+ /**
23
+ *
24
+ * @description spaces 的 endpoint
25
+ * @type {import('./spaces').SecurityContext}
26
+ * @memberof BaseBackup
27
+ */
28
+ securityContext;
29
+
30
+ /**
31
+ *
32
+ * @description server 的数据目录
33
+ * @type {string}
34
+ * @memberof BaseBackup
35
+ */
36
+ serverDir;
37
+
38
+ constructor(input) {
39
+ this.input = input;
40
+ }
41
+
42
+ /**
43
+ *
44
+ *
45
+ * @param {import('./spaces').SpacesBackup} spacesBackup
46
+ * @memberof BaseBackup
47
+ */
48
+ ensureParams(spacesBackup) {
49
+ this.blocklet = spacesBackup.blocklet;
50
+ this.serverDir = spacesBackup.serverDir;
51
+ this.backupDir = spacesBackup.backupDir;
52
+ this.securityContext = spacesBackup.securityContext;
53
+ }
54
+
55
+ async export() {
56
+ throw new Error('not implemented');
57
+ }
58
+ }
59
+
60
+ module.exports = {
61
+ BaseBackup,
62
+ };
@@ -0,0 +1,92 @@
1
+ const { removeSync, readFileSync, outputJsonSync } = require('fs-extra');
2
+ const { isEmpty, cloneDeep } = require('lodash');
3
+ const { join } = require('path');
4
+ const security = require('@abtnode/util/lib/security');
5
+
6
+ const states = require('../../../states');
7
+ const { BaseBackup } = require('./base');
8
+
9
+ class BlockletExtrasBackup extends BaseBackup {
10
+ filename = 'blocklet-extras.json';
11
+
12
+ async export() {
13
+ const blockletExtra = await this.getBlockletExtra();
14
+ removeSync(join(this.backupDir, this.filename));
15
+ outputJsonSync(join(this.backupDir, this.filename), blockletExtra);
16
+ }
17
+
18
+ /**
19
+ *
20
+ * @description
21
+ * @return {Promise<import('@abtnode/client').BlockletState>}
22
+ * @memberof BlockletExtrasBackup
23
+ */
24
+ async getBlockletExtra() {
25
+ /**
26
+ * @type {import('@abtnode/client').BlockletState}
27
+ */
28
+ const blockletExtra = await states.blockletExtras.findOne({
29
+ did: this.blocklet.meta.did,
30
+ });
31
+ if (isEmpty(blockletExtra)) {
32
+ throw new Error('blockletExtra cannot be empty');
33
+ }
34
+
35
+ return this.cleanData(blockletExtra);
36
+ }
37
+
38
+ /**
39
+ *
40
+ * @description 清理数据并加密
41
+ * @param {import('@abtnode/client').BlockletState} raw
42
+ * @return {Promise<any>}
43
+ * @memberof BlockletExtrasBackup
44
+ */
45
+ async cleanData(raw) {
46
+ const blockletExtra = cloneDeep(raw);
47
+
48
+ const queue = [blockletExtra];
49
+ while (queue.length) {
50
+ const current = queue.pop();
51
+
52
+ // 删除父 blocklet 的某些数据
53
+ if (current._id) {
54
+ delete current._id;
55
+ delete current.createdAt;
56
+ delete current.updatedAt;
57
+ }
58
+
59
+ // 加解密
60
+ this.encrypt(current.configs);
61
+
62
+ if (current?.children) {
63
+ queue.push(...current.children);
64
+ }
65
+ }
66
+
67
+ return blockletExtra;
68
+ }
69
+
70
+ /**
71
+ *
72
+ * @description 清理数据并加密
73
+ * @param {import('@abtnode/client').ConfigEntry[]} configs
74
+ * @return {void}
75
+ * @memberof BlockletExtrasBackup
76
+ */
77
+ encrypt(configs) {
78
+ if (isEmpty(configs)) {
79
+ return;
80
+ }
81
+
82
+ const dk = readFileSync(join(this.serverDir, '.sock'));
83
+ for (const config of configs) {
84
+ if (config.secure) {
85
+ const decrypted = security.decrypt(config.value, this.blocklet.meta.did, dk);
86
+ config.value = this.securityContext.encrypt(decrypted);
87
+ }
88
+ }
89
+ }
90
+ }
91
+
92
+ module.exports = { BlockletExtrasBackup };
@@ -0,0 +1,70 @@
1
+ const { removeSync, outputJsonSync } = require('fs-extra');
2
+ const { cloneDeep } = require('lodash');
3
+ const { join } = require('path');
4
+ const { BaseBackup } = require('./base');
5
+
6
+ class BlockletBackup extends BaseBackup {
7
+ filename = 'blocklet.json';
8
+
9
+ async export() {
10
+ const blocklet = await this.cleanData();
11
+ removeSync(join(this.backupDir, this.filename));
12
+ outputJsonSync(join(this.backupDir, this.filename), blocklet);
13
+ }
14
+
15
+ /**
16
+ * @description 清理数据
17
+ * @see blocklet.db 中需要删除哪些字段呢? https://github.com/ArcBlock/blocklet-server/issues/6120#issuecomment-1383798348
18
+ * @return {Promise<import('@abtnode/client').BlockletState>}
19
+ * @memberof BlockletBackup
20
+ */
21
+ async cleanData() {
22
+ const clone = cloneDeep(this.blocklet);
23
+
24
+ /** @type {import('@abtnode/client').ComponentState[]} */
25
+ const queue = [clone];
26
+
27
+ // 广度优先遍历
28
+ while (queue.length) {
29
+ const current = queue.pop();
30
+
31
+ // 父组件才需要删除的属性
32
+ if (current._id) {
33
+ delete current._id;
34
+ delete current.createdAt;
35
+ delete current.startedAt;
36
+ delete current.installedAt;
37
+ }
38
+
39
+ // 子组件和父组件都需要删除的属性
40
+ delete current.status;
41
+ delete current.ports;
42
+ delete current.environments;
43
+
44
+ if (current.children) {
45
+ queue.push(...current.children);
46
+ }
47
+ }
48
+
49
+ return this.encrypt(clone);
50
+ }
51
+
52
+ /**
53
+ *
54
+ * @description 清理数据并加密
55
+ * @param {import('@abtnode/client').BlockletState} info
56
+ * @memberof BlockletExtrasBackup
57
+ */
58
+ encrypt(info) {
59
+ if (Array.isArray(info.migratedFrom)) {
60
+ info.migratedFrom = info.migratedFrom.map((x) => {
61
+ x.appSk = this.securityContext.encrypt(x.appSk);
62
+ return x;
63
+ });
64
+ }
65
+
66
+ return info;
67
+ }
68
+ }
69
+
70
+ module.exports = { BlockletBackup };
@@ -0,0 +1,74 @@
1
+ const { join } = require('path');
2
+ const validUrl = require('valid-url');
3
+ const { BaseBackup } = require('./base');
4
+ const { dirToZip } = require('../utils/zip');
5
+ const { compareAndMove } = require('../utils/hash');
6
+
7
+ class BlockletsBackup extends BaseBackup {
8
+ /**
9
+ *
10
+ * @returns {Promise<void>}
11
+ * @memberof BlockletsBackup
12
+ */
13
+ async export() {
14
+ const blockletMetas = this.getBlockletMetas(this.blocklet);
15
+ const serverBlockletsDir = join(this.serverDir, 'blocklets');
16
+
17
+ const blockletMetasFromLocal = blockletMetas.filter(
18
+ (b) => !validUrl.isHttpUri(b.tarball) && !validUrl.isHttpsUri(b.tarball)
19
+ );
20
+
21
+ const dirs = [];
22
+ for (const blockletMeta of blockletMetasFromLocal) {
23
+ const sourceDir = join(serverBlockletsDir, blockletMeta.name, blockletMeta.version);
24
+ const zipPath = join(this.backupDir, 'blocklets', blockletMeta.name, `${blockletMeta.version}.zip`);
25
+ dirs.push({ sourceDir, zipPath });
26
+ }
27
+
28
+ await this.dirsToZip(dirs);
29
+ }
30
+
31
+ /**
32
+ *
33
+ *
34
+ * @param {import('@abtnode/client').BlockletState} blocklet
35
+ * @returns {Array<{name: string, version: string, tarball: string}>}
36
+ * @memberof BlockletsBackup
37
+ */
38
+ getBlockletMetas(blocklet) {
39
+ if (!blocklet?.meta?.bundleName || !blocklet?.meta?.version) {
40
+ return [];
41
+ }
42
+
43
+ const metas = [];
44
+ metas.push({
45
+ name: blocklet.meta.bundleName,
46
+ version: blocklet.meta.version,
47
+ tarball: blocklet?.meta?.dist?.tarball,
48
+ });
49
+
50
+ for (const child of blocklet.children) {
51
+ metas.push(...this.getBlockletMetas(child));
52
+ }
53
+
54
+ return metas;
55
+ }
56
+
57
+ /**
58
+ * @param {Array<{sourceDir: string, zipPath: string}>} dirs: /some/folder/to/compress
59
+ * @param {String} zipPath: /path/to/created.zip
60
+ * @returns {Promise}
61
+ * @memberof BlockletsBackup
62
+ */
63
+ async dirsToZip(dirs) {
64
+ await Promise.all(
65
+ dirs.map(async (dir) => {
66
+ const tempZipPath = `${dir.zipPath}.bak`;
67
+ await dirToZip(dir.sourceDir, tempZipPath);
68
+ await compareAndMove(dir.zipPath, tempZipPath);
69
+ })
70
+ );
71
+ }
72
+ }
73
+
74
+ module.exports = { BlockletsBackup };
@@ -0,0 +1,19 @@
1
+ const { copy } = require('fs-extra');
2
+ const { join } = require('path');
3
+ const { BaseBackup } = require('./base');
4
+
5
+ class DataBackup extends BaseBackup {
6
+ /**
7
+ *
8
+ * @returns {Promise<void>}
9
+ * @memberof BlockletsBackup
10
+ */
11
+ async export() {
12
+ const blockletDataDir = join(this.serverDir, 'data', this.blocklet.meta.name);
13
+ const blockletBackupDataDir = join(this.backupDir, 'data');
14
+
15
+ await copy(blockletDataDir, blockletBackupDataDir, { overwrite: true });
16
+ }
17
+ }
18
+
19
+ module.exports = { DataBackup };
@@ -0,0 +1,24 @@
1
+ const { ensureDirSync, copy, statSync } = require('fs-extra');
2
+ const { join } = require('path');
3
+ const { BaseBackup } = require('./base');
4
+
5
+ // note: 可以不需要备份
6
+ class LogsBackup extends BaseBackup {
7
+ async export() {
8
+ const sourceLogsDir = join(this.serverDir, 'logs', this.blocklet.meta.name);
9
+ ensureDirSync(sourceLogsDir);
10
+
11
+ const targetLogsDir = join(this.backupDir, 'logs');
12
+
13
+ await copy(sourceLogsDir, targetLogsDir, {
14
+ overwrite: true,
15
+ filter: (src) => {
16
+ return !statSync(src).isSymbolicLink();
17
+ },
18
+ });
19
+ }
20
+ }
21
+
22
+ module.exports = {
23
+ LogsBackup,
24
+ };
@@ -0,0 +1,19 @@
1
+ const { removeSync, outputJsonSync } = require('fs-extra');
2
+ const { join } = require('path');
3
+ const states = require('../../../states');
4
+ const { BaseBackup } = require('./base');
5
+
6
+ class RoutingRuleBackup extends BaseBackup {
7
+ filename = 'routing_rule.json';
8
+
9
+ async export() {
10
+ const routingRule = await states.site.findOne({
11
+ domain: `${this.blocklet.meta.did}.blocklet-domain-group`,
12
+ });
13
+
14
+ removeSync(join(this.backupDir, this.filename));
15
+ outputJsonSync(join(this.backupDir, this.filename), routingRule);
16
+ }
17
+ }
18
+
19
+ module.exports = { RoutingRuleBackup };