underpost 3.2.8 → 3.2.10
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/.github/workflows/npmpkg.ci.yml +1 -0
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/.github/workflows/release.cd.yml +1 -0
- package/.vscode/settings.json +10 -5
- package/CHANGELOG.md +223 -2
- package/CLI-HELP.md +36 -7
- package/README.md +38 -9
- package/bin/build.js +27 -11
- package/bin/deploy.js +20 -21
- package/bin/file.js +32 -13
- package/bin/index.js +2 -1
- package/bin/vs.js +1 -1
- package/bump.config.js +26 -0
- package/conf.js +20 -4
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -2
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +2 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +4 -2
- package/manifests/kind-config-dev.yaml +8 -0
- package/manifests/mongodb/pv-pvc.yaml +44 -8
- package/manifests/mongodb/statefulset.yaml +55 -68
- package/package.json +40 -25
- package/scripts/k3s-node-setup.sh +30 -11
- package/scripts/nat-iptables.sh +103 -18
- package/src/api/core/core.router.js +19 -14
- package/src/api/core/core.service.js +5 -5
- package/src/api/default/default.router.js +22 -18
- package/src/api/default/default.service.js +5 -5
- package/src/api/document/document.router.js +28 -23
- package/src/api/document/document.service.js +100 -23
- package/src/api/file/file.router.js +19 -13
- package/src/api/file/file.service.js +9 -7
- package/src/api/test/test.router.js +17 -12
- package/src/api/types.js +24 -0
- package/src/api/user/guest.service.js +5 -4
- package/src/api/user/user.router.js +297 -288
- package/src/api/user/user.service.js +100 -35
- package/src/cli/baremetal.js +20 -11
- package/src/cli/cluster.js +243 -55
- package/src/cli/db.js +106 -62
- package/src/cli/deploy.js +297 -154
- package/src/cli/fs.js +19 -3
- package/src/cli/index.js +37 -9
- package/src/cli/ipfs.js +4 -6
- package/src/cli/kubectl.js +4 -1
- package/src/cli/lxd.js +217 -135
- package/src/cli/release.js +289 -131
- package/src/cli/repository.js +91 -34
- package/src/cli/run.js +297 -56
- package/src/cli/test.js +9 -3
- package/src/client/Default.index.js +9 -3
- package/src/client/components/core/Auth.js +19 -5
- package/src/client/components/core/Docs.js +6 -34
- package/src/client/components/core/FileExplorer.js +6 -6
- package/src/client/components/core/Modal.js +65 -2
- package/src/client/components/core/PanelForm.js +56 -52
- package/src/client/components/core/Recover.js +4 -4
- package/src/client/components/core/Worker.js +170 -350
- package/src/client/services/default/default.management.js +20 -25
- package/src/client/services/user/guest.service.js +10 -3
- package/src/client/sw/core.sw.js +174 -112
- package/src/db/DataBaseProvider.js +120 -20
- package/src/db/mongo/MongoBootstrap.js +587 -0
- package/src/db/mongo/MongooseDB.js +126 -22
- package/src/index.js +1 -1
- package/src/runtime/express/Express.js +2 -2
- package/src/runtime/wp/Wp.js +8 -5
- package/src/server/auth.js +2 -2
- package/src/server/client-build-docs.js +1 -1
- package/src/server/client-build.js +94 -129
- package/src/server/conf.js +20 -65
- package/src/server/data-query.js +32 -20
- package/src/server/dns.js +22 -0
- package/src/server/process.js +180 -19
- package/src/server/runtime.js +1 -1
- package/src/server/start.js +26 -7
- package/src/server/valkey.js +9 -2
- package/src/ws/IoInterface.js +16 -16
- package/src/ws/core/channels/core.ws.chat.js +11 -11
- package/src/ws/core/channels/core.ws.mailer.js +29 -29
- package/src/ws/core/channels/core.ws.stream.js +19 -19
- package/src/ws/core/core.ws.connection.js +8 -8
- package/src/ws/core/core.ws.server.js +6 -5
- package/src/ws/default/channels/default.ws.main.js +10 -10
- package/src/ws/default/default.ws.connection.js +4 -4
- package/src/ws/default/default.ws.server.js +4 -3
- package/typedoc.json +10 -1
- package/src/client/ssr/email/DefaultRecoverEmail.js +0 -21
- package/src/client/ssr/email/DefaultVerifyEmail.js +0 -17
- /package/src/client/ssr/{offline → views}/Maintenance.js +0 -0
- /package/src/client/ssr/{offline → views}/NoNetworkConnection.js +0 -0
- /package/src/client/ssr/{pages → views}/Test.js +0 -0
package/src/cli/db.js
CHANGED
|
@@ -10,8 +10,9 @@ import { mergeFile, splitFileFactory, loadConfServerJson, resolveConfSecrets } f
|
|
|
10
10
|
import { loggerFactory } from '../server/logger.js';
|
|
11
11
|
import { shellExec } from '../server/process.js';
|
|
12
12
|
import fs from 'fs-extra';
|
|
13
|
-
import {
|
|
13
|
+
import { DataBaseProviderService } from '../db/DataBaseProvider.js';
|
|
14
14
|
import { loadReplicas, pathPortAssignmentFactory, loadCronDeployEnv } from '../server/conf.js';
|
|
15
|
+
import { MongoBootstrap } from '../db/mongo/MongoBootstrap.js';
|
|
15
16
|
import Underpost from '../index.js';
|
|
16
17
|
import { timer } from '../client/components/core/CommonJs.js';
|
|
17
18
|
const logger = loggerFactory(import.meta);
|
|
@@ -229,9 +230,12 @@ class UnderpostDB {
|
|
|
229
230
|
* @param {string} params.bsonPath - BSON directory path.
|
|
230
231
|
* @param {boolean} params.drop - Whether to drop existing database.
|
|
231
232
|
* @param {boolean} params.preserveUUID - Whether to preserve UUIDs.
|
|
233
|
+
* @param {string} [params.user=''] - MongoDB username for authenticated restore.
|
|
234
|
+
* @param {string} [params.password=''] - MongoDB password for authenticated restore.
|
|
235
|
+
* @param {string} [params.authDatabase='admin'] - Auth database for restore command.
|
|
232
236
|
* @return {boolean} Success status.
|
|
233
237
|
*/
|
|
234
|
-
_importMongoDB({ pod, namespace, dbName, bsonPath, drop, preserveUUID }) {
|
|
238
|
+
_importMongoDB({ pod, namespace, dbName, bsonPath, drop, preserveUUID, user = '', password = '', authDatabase = 'admin' }) {
|
|
235
239
|
try {
|
|
236
240
|
const podName = pod.NAME;
|
|
237
241
|
const containerBsonPath = `/${dbName}`;
|
|
@@ -268,9 +272,10 @@ class UnderpostDB {
|
|
|
268
272
|
}
|
|
269
273
|
|
|
270
274
|
// Restore database
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
275
|
+
const authFlags = user && password
|
|
276
|
+
? ` --username ${JSON.stringify(user)} --password ${JSON.stringify(password)} --authenticationDatabase ${JSON.stringify(authDatabase)}`
|
|
277
|
+
: '';
|
|
278
|
+
const restoreCmd = `mongorestore -d ${dbName} ${containerBsonPath}${drop ? ' --drop' : ''}${preserveUUID ? ' --preserveUUID' : ''}${authFlags}`;
|
|
274
279
|
Underpost.kubectl.exec({ podName, namespace, command: restoreCmd });
|
|
275
280
|
|
|
276
281
|
logger.info('Successfully imported MongoDB database', { podName, dbName });
|
|
@@ -291,9 +296,12 @@ class UnderpostDB {
|
|
|
291
296
|
* @param {string} params.dbName - Database name.
|
|
292
297
|
* @param {string} params.outputPath - Output directory path.
|
|
293
298
|
* @param {string} [params.collections=''] - Comma-separated collection list.
|
|
299
|
+
* @param {string} [params.user=''] - MongoDB username for authenticated dump.
|
|
300
|
+
* @param {string} [params.password=''] - MongoDB password for authenticated dump.
|
|
301
|
+
* @param {string} [params.authDatabase='admin'] - Auth database for dump command.
|
|
294
302
|
* @return {boolean} Success status.
|
|
295
303
|
*/
|
|
296
|
-
_exportMongoDB({ pod, namespace, dbName, outputPath, collections = '' }) {
|
|
304
|
+
_exportMongoDB({ pod, namespace, dbName, outputPath, collections = '', user = '', password = '', authDatabase = 'admin' }) {
|
|
297
305
|
try {
|
|
298
306
|
const podName = pod.NAME;
|
|
299
307
|
const containerBsonPath = `/${dbName}`;
|
|
@@ -308,14 +316,18 @@ class UnderpostDB {
|
|
|
308
316
|
});
|
|
309
317
|
|
|
310
318
|
// Dump database or specific collections
|
|
319
|
+
const authFlags = user && password
|
|
320
|
+
? ` --username ${JSON.stringify(user)} --password ${JSON.stringify(password)} --authenticationDatabase ${JSON.stringify(authDatabase)}`
|
|
321
|
+
: '';
|
|
322
|
+
|
|
311
323
|
if (collections) {
|
|
312
324
|
const collectionList = collections.split(',').map((c) => c.trim());
|
|
313
325
|
for (const collection of collectionList) {
|
|
314
|
-
const dumpCmd = `mongodump -d ${dbName} --collection ${collection} -o
|
|
326
|
+
const dumpCmd = `mongodump -d ${dbName} --collection ${collection} -o /${authFlags}`;
|
|
315
327
|
Underpost.kubectl.exec({ podName, namespace, command: dumpCmd });
|
|
316
328
|
}
|
|
317
329
|
} else {
|
|
318
|
-
const dumpCmd = `mongodump -d ${dbName} -o
|
|
330
|
+
const dumpCmd = `mongodump -d ${dbName} -o /${authFlags}`;
|
|
319
331
|
Underpost.kubectl.exec({ podName, namespace, command: dumpCmd });
|
|
320
332
|
}
|
|
321
333
|
|
|
@@ -347,9 +359,12 @@ class UnderpostDB {
|
|
|
347
359
|
* @param {string} params.podName - Pod name.
|
|
348
360
|
* @param {string} params.namespace - Namespace.
|
|
349
361
|
* @param {string} params.dbName - Database name.
|
|
362
|
+
* @param {string} [params.user=''] - MongoDB username for authenticated stats query.
|
|
363
|
+
* @param {string} [params.password=''] - MongoDB password for authenticated stats query.
|
|
364
|
+
* @param {string} [params.authDatabase='admin'] - Auth database for stats query.
|
|
350
365
|
* @return {Object|null} Collection statistics or null on error.
|
|
351
366
|
*/
|
|
352
|
-
_getMongoStats({ podName, namespace, dbName }) {
|
|
367
|
+
_getMongoStats({ podName, namespace, dbName, user = '', password = '', authDatabase = 'admin' }) {
|
|
353
368
|
try {
|
|
354
369
|
logger.info('Getting MongoDB collection statistics', { podName, dbName });
|
|
355
370
|
|
|
@@ -357,8 +372,11 @@ class UnderpostDB {
|
|
|
357
372
|
const script = `db.getSiblingDB('${dbName}').getCollectionNames().map(function(c) { return { collection: c, count: db.getSiblingDB('${dbName}')[c].countDocuments() }; })`;
|
|
358
373
|
|
|
359
374
|
// Execute the script
|
|
360
|
-
const
|
|
361
|
-
|
|
375
|
+
const authFlags = user && password
|
|
376
|
+
? ` --authenticationDatabase ${JSON.stringify(authDatabase)} -u ${JSON.stringify(user)} -p ${JSON.stringify(password)}`
|
|
377
|
+
: '';
|
|
378
|
+
const command = `sudo kubectl exec -n ${namespace} -i ${podName} -- mongosh --quiet${authFlags} --eval "${script}"`;
|
|
379
|
+
const output = shellExec(command, { stdout: true, silent: true, silentOnError: true });
|
|
362
380
|
|
|
363
381
|
if (!output || output.trim() === '') {
|
|
364
382
|
logger.warn('No collections found or empty output');
|
|
@@ -415,7 +433,7 @@ class UnderpostDB {
|
|
|
415
433
|
logger.info('Getting MariaDB table statistics', { podName, dbName });
|
|
416
434
|
|
|
417
435
|
const command = `sudo kubectl exec -n ${namespace} -i ${podName} -- mariadb -u ${user} -p${password} ${dbName} -e "SELECT TABLE_NAME as 'table', TABLE_ROWS as 'count' FROM information_schema.TABLES WHERE TABLE_SCHEMA = '${dbName}' ORDER BY TABLE_NAME;" --skip-column-names --batch`;
|
|
418
|
-
const output = shellExec(command, { stdout: true, silent: true, disableLog: true });
|
|
436
|
+
const output = shellExec(command, { stdout: true, silent: true, disableLog: true, silentOnError: true });
|
|
419
437
|
|
|
420
438
|
if (!output || output.trim() === '') {
|
|
421
439
|
logger.warn('No tables found or empty output');
|
|
@@ -475,47 +493,7 @@ class UnderpostDB {
|
|
|
475
493
|
console.log('='.repeat(70) + '\n');
|
|
476
494
|
},
|
|
477
495
|
|
|
478
|
-
/**
|
|
479
|
-
* Gets MongoDB primary pod name from replica set status.
|
|
480
|
-
* @method getMongoPrimaryPodName
|
|
481
|
-
* @memberof UnderpostDB
|
|
482
|
-
* @param {Object} [options={}] - Options for getting primary pod.
|
|
483
|
-
* @param {string} [options.namespace='default'] - Kubernetes namespace.
|
|
484
|
-
* @param {string} [options.podName='mongodb-0'] - Initial pod name to query replica set status.
|
|
485
|
-
* @return {string|null} Primary pod name or null if not found.
|
|
486
|
-
*/
|
|
487
|
-
getMongoPrimaryPodName(options = { namespace: 'default', podName: 'mongodb-0' }) {
|
|
488
|
-
const { namespace = 'default', podName = 'mongodb-0' } = options;
|
|
489
|
-
|
|
490
|
-
try {
|
|
491
|
-
logger.info('Checking for MongoDB primary pod', { namespace, checkingPod: podName });
|
|
492
|
-
|
|
493
|
-
const command = `sudo kubectl exec -n ${namespace} -i ${podName} -- mongosh --quiet --eval 'rs.status().members.filter(m => m.stateStr=="PRIMARY").map(m=>m.name)'`;
|
|
494
|
-
const output = shellExec(command, { stdout: true, silent: true });
|
|
495
|
-
|
|
496
|
-
if (!output || output.trim() === '') {
|
|
497
|
-
logger.warn('No primary pod found in replica set');
|
|
498
|
-
return null;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
// Parse the output to get the primary pod name
|
|
502
|
-
// Output format: [ 'mongodb-0:27017' ] or [ 'mongodb-1.mongodb-service:27017' ] or similar
|
|
503
|
-
const match = output.match(/['"]([^'"]+)['"]/);
|
|
504
|
-
if (match && match[1]) {
|
|
505
|
-
let primaryName = match[1].split(':')[0]; // Extract pod name without port
|
|
506
|
-
// Remove service suffix if present (e.g., "mongodb-1.mongodb-service" -> "mongodb-1")
|
|
507
|
-
primaryName = primaryName.split('.')[0];
|
|
508
|
-
logger.info('Found MongoDB primary pod', { primaryPod: primaryName });
|
|
509
|
-
return primaryName;
|
|
510
|
-
}
|
|
511
496
|
|
|
512
|
-
logger.warn('Could not parse primary pod from replica set status', { output });
|
|
513
|
-
return null;
|
|
514
|
-
} catch (error) {
|
|
515
|
-
logger.error('Failed to get MongoDB primary pod', { error: error.message });
|
|
516
|
-
return null;
|
|
517
|
-
}
|
|
518
|
-
},
|
|
519
497
|
|
|
520
498
|
/**
|
|
521
499
|
* Main callback: Initiates database backup workflow.
|
|
@@ -626,7 +604,13 @@ class UnderpostDB {
|
|
|
626
604
|
});
|
|
627
605
|
|
|
628
606
|
if (options.primaryPodEnsure) {
|
|
629
|
-
const primaryPodName =
|
|
607
|
+
const primaryPodName = MongoBootstrap.getPrimaryPodName({
|
|
608
|
+
namespace,
|
|
609
|
+
podName: options.primaryPodEnsure,
|
|
610
|
+
username: process.env.MONGODB_USERNAME || process.env.DB_USER || '',
|
|
611
|
+
password: process.env.MONGODB_PASSWORD || process.env.DB_PASSWORD || '',
|
|
612
|
+
authDatabase: process.env.MONGODB_AUTH_DB || 'admin',
|
|
613
|
+
});
|
|
630
614
|
if (!primaryPodName) {
|
|
631
615
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
632
616
|
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
@@ -813,7 +797,13 @@ class UnderpostDB {
|
|
|
813
797
|
podsToProcess = [];
|
|
814
798
|
} else {
|
|
815
799
|
const firstPod = targetPods[0].NAME;
|
|
816
|
-
const primaryPodName =
|
|
800
|
+
const primaryPodName = MongoBootstrap.getPrimaryPodName({
|
|
801
|
+
namespace,
|
|
802
|
+
podName: firstPod,
|
|
803
|
+
username: user,
|
|
804
|
+
password,
|
|
805
|
+
authDatabase: 'admin',
|
|
806
|
+
});
|
|
817
807
|
|
|
818
808
|
if (primaryPodName) {
|
|
819
809
|
const primaryPod = targetPods.find((p) => p.NAME === primaryPodName);
|
|
@@ -839,6 +829,8 @@ class UnderpostDB {
|
|
|
839
829
|
pods: podsToProcess.map((p) => p.NAME),
|
|
840
830
|
});
|
|
841
831
|
|
|
832
|
+
let exportSucceeded = false;
|
|
833
|
+
|
|
842
834
|
// Process each pod
|
|
843
835
|
for (const pod of podsToProcess) {
|
|
844
836
|
logger.info('Processing pod', { podName: pod.NAME, node: pod.NODE, status: pod.STATUS });
|
|
@@ -871,7 +863,7 @@ class UnderpostDB {
|
|
|
871
863
|
|
|
872
864
|
if (options.export === true) {
|
|
873
865
|
const outputPath = options.outPath || toNewSqlPath;
|
|
874
|
-
await Underpost.db._exportMariaDB({
|
|
866
|
+
const success = await Underpost.db._exportMariaDB({
|
|
875
867
|
pod,
|
|
876
868
|
namespace,
|
|
877
869
|
dbName,
|
|
@@ -879,6 +871,7 @@ class UnderpostDB {
|
|
|
879
871
|
password,
|
|
880
872
|
outputPath,
|
|
881
873
|
});
|
|
874
|
+
exportSucceeded = exportSucceeded || success;
|
|
882
875
|
}
|
|
883
876
|
break;
|
|
884
877
|
}
|
|
@@ -889,6 +882,9 @@ class UnderpostDB {
|
|
|
889
882
|
podName: pod.NAME,
|
|
890
883
|
namespace,
|
|
891
884
|
dbName,
|
|
885
|
+
user,
|
|
886
|
+
password,
|
|
887
|
+
authDatabase: 'admin',
|
|
892
888
|
});
|
|
893
889
|
if (stats) {
|
|
894
890
|
Underpost.db._displayStats({ provider, dbName, stats });
|
|
@@ -904,18 +900,25 @@ class UnderpostDB {
|
|
|
904
900
|
bsonPath,
|
|
905
901
|
drop: options.drop,
|
|
906
902
|
preserveUUID: options.preserveUUID,
|
|
903
|
+
user,
|
|
904
|
+
password,
|
|
905
|
+
authDatabase: 'admin',
|
|
907
906
|
});
|
|
908
907
|
}
|
|
909
908
|
|
|
910
909
|
if (options.export === true) {
|
|
911
910
|
const outputPath = options.outPath || toNewBsonPath;
|
|
912
|
-
Underpost.db._exportMongoDB({
|
|
911
|
+
const success = Underpost.db._exportMongoDB({
|
|
913
912
|
pod,
|
|
914
913
|
namespace,
|
|
915
914
|
dbName,
|
|
916
915
|
outputPath,
|
|
917
916
|
collections: options.collections,
|
|
917
|
+
user,
|
|
918
|
+
password,
|
|
919
|
+
authDatabase: 'admin',
|
|
918
920
|
});
|
|
921
|
+
exportSucceeded = exportSucceeded || success;
|
|
919
922
|
}
|
|
920
923
|
break;
|
|
921
924
|
}
|
|
@@ -926,6 +929,10 @@ class UnderpostDB {
|
|
|
926
929
|
}
|
|
927
930
|
}
|
|
928
931
|
|
|
932
|
+
if (options.export === true && exportSucceeded === true) {
|
|
933
|
+
Underpost.db._enforceBackupRetention(`../${repoName}/${hostFolder}`);
|
|
934
|
+
}
|
|
935
|
+
|
|
929
936
|
// Mark this host+path combination as processed
|
|
930
937
|
processedHostPaths.add(hostPathKey);
|
|
931
938
|
}
|
|
@@ -948,6 +955,43 @@ class UnderpostDB {
|
|
|
948
955
|
throw error;
|
|
949
956
|
}
|
|
950
957
|
},
|
|
958
|
+
/**
|
|
959
|
+
* Helper: Removes old timestamp backup folders and keeps only the newest ones.
|
|
960
|
+
* @method _enforceBackupRetention
|
|
961
|
+
* @memberof UnderpostDB
|
|
962
|
+
* @param {string} backupDir - Path to host-folder backup directory.
|
|
963
|
+
* @param {number} [maxRetention=MAX_BACKUP_RETENTION] - Maximum folders to keep.
|
|
964
|
+
* @return {number} Number of removed backup folders.
|
|
965
|
+
*/
|
|
966
|
+
_enforceBackupRetention(backupDir, maxRetention = MAX_BACKUP_RETENTION) {
|
|
967
|
+
try {
|
|
968
|
+
if (!fs.existsSync(backupDir)) return 0;
|
|
969
|
+
|
|
970
|
+
const timestamps = fs
|
|
971
|
+
.readdirSync(backupDir)
|
|
972
|
+
.filter((entry) => /^\d+$/.test(entry))
|
|
973
|
+
.sort((a, b) => parseInt(b, 10) - parseInt(a, 10));
|
|
974
|
+
|
|
975
|
+
if (timestamps.length <= maxRetention) return 0;
|
|
976
|
+
|
|
977
|
+
const staleTimestamps = timestamps.slice(maxRetention);
|
|
978
|
+
staleTimestamps.forEach((timestamp) => {
|
|
979
|
+
fs.removeSync(`${backupDir}/${timestamp}`);
|
|
980
|
+
});
|
|
981
|
+
|
|
982
|
+
logger.info('Pruned old backup timestamp folders', {
|
|
983
|
+
backupDir,
|
|
984
|
+
kept: maxRetention,
|
|
985
|
+
removed: staleTimestamps.length,
|
|
986
|
+
removedTimestamps: staleTimestamps,
|
|
987
|
+
});
|
|
988
|
+
|
|
989
|
+
return staleTimestamps.length;
|
|
990
|
+
} catch (error) {
|
|
991
|
+
logger.error('Failed to enforce backup retention', { backupDir, maxRetention, error: error.message });
|
|
992
|
+
return 0;
|
|
993
|
+
}
|
|
994
|
+
},
|
|
951
995
|
|
|
952
996
|
/**
|
|
953
997
|
* Creates cluster metadata for the specified deployment.
|
|
@@ -999,7 +1043,7 @@ class UnderpostDB {
|
|
|
999
1043
|
const retryDelay = 3000;
|
|
1000
1044
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
1001
1045
|
try {
|
|
1002
|
-
await
|
|
1046
|
+
await DataBaseProviderService.load({ apis: ['instance', 'cron'], host, path, db });
|
|
1003
1047
|
break;
|
|
1004
1048
|
} catch (err) {
|
|
1005
1049
|
if (attempt === maxRetries) {
|
|
@@ -1013,7 +1057,7 @@ class UnderpostDB {
|
|
|
1013
1057
|
|
|
1014
1058
|
try {
|
|
1015
1059
|
/** @type {import('../api/instance/instance.model.js').InstanceModel} */
|
|
1016
|
-
const Instance =
|
|
1060
|
+
const Instance = DataBaseProviderService.getModel('instance', { host, path });
|
|
1017
1061
|
|
|
1018
1062
|
await Instance.deleteMany();
|
|
1019
1063
|
logger.info('Cleared existing instance metadata');
|
|
@@ -1114,10 +1158,10 @@ class UnderpostDB {
|
|
|
1114
1158
|
|
|
1115
1159
|
const confCron = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
|
|
1116
1160
|
|
|
1117
|
-
await
|
|
1161
|
+
await DataBaseProviderService.load({ apis: ['cron'], host, path, db });
|
|
1118
1162
|
|
|
1119
1163
|
/** @type {import('../api/cron/cron.model.js').CronModel} */
|
|
1120
|
-
const Cron =
|
|
1164
|
+
const Cron = DataBaseProviderService.getModel('cron', { host, path });
|
|
1121
1165
|
|
|
1122
1166
|
await Cron.deleteMany();
|
|
1123
1167
|
logger.info('Cleared existing cron metadata');
|
|
@@ -1136,7 +1180,7 @@ class UnderpostDB {
|
|
|
1136
1180
|
logger.error('Failed to create cron metadata', { error: error.message });
|
|
1137
1181
|
}
|
|
1138
1182
|
|
|
1139
|
-
await
|
|
1183
|
+
await DataBaseProviderService.getProvider({ host, path }, 'mongoose').close();
|
|
1140
1184
|
logger.info('Cluster metadata creation completed');
|
|
1141
1185
|
} catch (error) {
|
|
1142
1186
|
logger.error('Cluster metadata creation failed', { error: error.message });
|
|
@@ -1229,7 +1273,7 @@ class UnderpostDB {
|
|
|
1229
1273
|
let dbProvider;
|
|
1230
1274
|
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
1231
1275
|
try {
|
|
1232
|
-
dbProvider = await
|
|
1276
|
+
dbProvider = await DataBaseProviderService.load({ apis, host, path, db });
|
|
1233
1277
|
break;
|
|
1234
1278
|
} catch (err) {
|
|
1235
1279
|
if (attempt === 3) throw err;
|