underpost 2.8.852 → 2.8.853

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/README.md CHANGED
@@ -49,12 +49,13 @@ template
49
49
 
50
50
 
51
51
 
52
+
52
53
 
53
54
 
54
55
  <!-- badges -->
55
56
 
56
57
 
57
- [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/2.8.852)](https://socket.dev/npm/package/underpost/overview/2.8.852) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
58
+ [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/2.8.853)](https://socket.dev/npm/package/underpost/overview/2.8.853) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
58
59
 
59
60
 
60
61
  <!-- end-badges -->
@@ -86,6 +87,7 @@ template
86
87
 
87
88
 
88
89
 
90
+
89
91
 
90
92
 
91
93
  </div>
@@ -132,7 +134,7 @@ Run dev client server
132
134
  npm run dev
133
135
  ```
134
136
  <!-- -->
135
- ## underpost ci/cd cli v2.8.852
137
+ ## underpost ci/cd cli v2.8.853
136
138
 
137
139
  ### Usage: `underpost [options] [command]`
138
140
  ```
@@ -157,6 +159,7 @@ Commands:
157
159
  dockerfile-pull-base-images [options] Pulls required Underpost Dockerfile base images and optionally loads them into clusters.
158
160
  install Quickly imports Underpost npm dependencies by copying them.
159
161
  db [options] <deploy-list> Manages database operations, including import, export, and collection management.
162
+ metadata [options] [deploy-id] [host] [path] Manages cluster metadata operations, including import and export.
160
163
  script [options] <operator> <script-name> [script-value] Supports a variety of built-in Underpost global scripts, their preset lifecycle events, and arbitrary custom scripts.
161
164
  cron [options] [deploy-list] [job-list] Manages cron jobs, including initialization, execution, and configuration updates.
162
165
  fs [options] [path] Manages file storage, defaulting to file upload operations.
package/bin/deploy.js CHANGED
@@ -1015,43 +1015,6 @@ EOF`);
1015
1015
  break;
1016
1016
  }
1017
1017
 
1018
- case 'update-instances': {
1019
- shellExec(`node bin deploy dd production --sync --build-manifest --info-router --dashboard-update`);
1020
- shellExec(`node bin cron --dashboard-update --init`);
1021
- const deployId = 'dd-core';
1022
- const host = 'www.nexodev.org';
1023
- const path = '/';
1024
-
1025
- {
1026
- const outputPath = './engine-private/instances';
1027
- if (fs.existsSync(outputPath)) fs.mkdirSync(outputPath, { recursive: true });
1028
- const collection = 'instances';
1029
- if (process.argv.includes('export'))
1030
- shellExec(
1031
- `node bin db --export --collections ${collection} --out-path ${outputPath} --hosts ${host} --paths '${path}' ${deployId}`,
1032
- );
1033
- if (process.argv.includes('import'))
1034
- shellExec(
1035
- `node bin db --import --drop --preserveUUID --out-path ${outputPath} --hosts ${host} --paths '${path}' ${deployId}`,
1036
- );
1037
- }
1038
- {
1039
- const outputPath = './engine-private/crons';
1040
- if (fs.existsSync(outputPath)) fs.mkdirSync(outputPath, { recursive: true });
1041
- const collection = 'crons';
1042
- if (process.argv.includes('export'))
1043
- shellExec(
1044
- `node bin db --export --collections ${collection} --out-path ${outputPath} --hosts ${host} --paths '${path}' ${deployId}`,
1045
- );
1046
- if (process.argv.includes('import'))
1047
- shellExec(
1048
- `node bin db --import --drop --preserveUUID --out-path ${outputPath} --hosts ${host} --paths '${path}' ${deployId}`,
1049
- );
1050
- }
1051
-
1052
- break;
1053
- }
1054
-
1055
1018
  case 'cli-docs': {
1056
1019
  buildCliDoc(program, process.argv[3], process.argv[4]);
1057
1020
  break;
package/cli.md CHANGED
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v2.8.852
1
+ ## underpost ci/cd cli v2.8.853
2
2
 
3
3
  ### Usage: `underpost [options] [command]`
4
4
  ```
@@ -23,6 +23,7 @@ Commands:
23
23
  dockerfile-pull-base-images [options] Pulls required Underpost Dockerfile base images and optionally loads them into clusters.
24
24
  install Quickly imports Underpost npm dependencies by copying them.
25
25
  db [options] <deploy-list> Manages database operations, including import, export, and collection management.
26
+ metadata [options] [deploy-id] [host] [path] Manages cluster metadata operations, including import and export.
26
27
  script [options] <operator> <script-name> [script-value] Supports a variety of built-in Underpost global scripts, their preset lifecycle events, and arbitrary custom scripts.
27
28
  cron [options] [deploy-list] [job-list] Manages cron jobs, including initialization, execution, and configuration updates.
28
29
  fs [options] [path] Manages file storage, defaulting to file upload operations.
@@ -288,8 +289,6 @@ Options:
288
289
  --build-manifest Builds Kubernetes YAML manifests, including
289
290
  deployments, services, proxies, and
290
291
  secrets.
291
- --dashboard-update Updates dashboard instance data with the
292
- current router configuration.
293
292
  --replicas <replicas> Sets a custom number of replicas for
294
293
  deployments.
295
294
  --versions <deployment-versions> A comma-separated list of custom deployment
@@ -302,9 +301,6 @@ Options:
302
301
  --kubeadm Enables the kubeadm context for deployment
303
302
  operations.
304
303
  --restore-hosts Restores default `/etc/hosts` entries.
305
- --rebuild-clients-bundle Inside the container, rebuilds client
306
- bundles (only static public or storage
307
- client files).
308
304
  -h, --help display help for command
309
305
 
310
306
  ```
@@ -427,6 +423,27 @@ Options:
427
423
  ```
428
424
 
429
425
 
426
+ ### `metadata` :
427
+ ```
428
+ Usage: underpost metadata [options] [deploy-id] [host] [path]
429
+
430
+ Manages cluster metadata operations, including import and export.
431
+
432
+ Arguments:
433
+ deploy-id The deployment ID to manage metadata.
434
+ host The host to manage metadata.
435
+ path The path to manage metadata.
436
+
437
+ Options:
438
+ --import Imports from local storage.
439
+ --export Exports to local storage.
440
+ --crons Apply to cron data collection
441
+ --instances Apply to instance data collection
442
+ -h, --help display help for command
443
+
444
+ ```
445
+
446
+
430
447
  ### `script` :
431
448
  ```
432
449
  Usage: underpost script [options] <operator> <script-name> [script-value]
@@ -461,19 +478,16 @@ Manages cron jobs, including initialization, execution, and configuration
461
478
  updates.
462
479
 
463
480
  Arguments:
464
- deploy-list A comma-separated list of deployment IDs (e.g.,
465
- "default-a,default-b").
466
- job-list A comma-separated list of job IDs. Options: callback,
467
- updateDashboardData. Defaults to all available jobs.
481
+ deploy-list A comma-separated list of deployment IDs (e.g.,
482
+ "default-a,default-b").
483
+ job-list A comma-separated list of job IDs. Options: callback. Defaults
484
+ to all available jobs.
468
485
 
469
486
  Options:
470
- --itc Executes cron jobs within the container execution
471
- context.
472
- --init Initializes cron jobs for the default deployment ID.
473
- --git Uploads cron job configurations to GitHub.
474
- --dashboard-update Updates dashboard cron data with the current job
475
- configurations.
476
- -h, --help display help for command
487
+ --itc Executes cron jobs within the container execution context.
488
+ --init Initializes cron jobs for the default deployment ID.
489
+ --git Uploads cron job configurations to GitHub.
490
+ -h, --help display help for command
477
491
 
478
492
  ```
479
493
 
@@ -574,7 +588,7 @@ Options:
574
588
  Runs a script from the specified path.
575
589
 
576
590
  Arguments:
577
- runner-id The runner ID to run. Options: spark-template, rmi, kill, secret, gpu-env, tf-gpu-test, dev-cluster, cyberia-ide, engine-ide, template-deploy, ssh-deploy, ide, monitor, db-client, cluster, deploy, tf-vae-test, deploy-job.
591
+ runner-id The runner ID to run. Options: spark-template, rmi, kill, secret, gpu-env, tf-gpu-test, dev-cluster, ssh-cluster-info, cyberia-ide, engine-ide, template-deploy, ssh-deploy, ide, monitor, db-client, cluster, deploy, tf-vae-test, deploy-job.
578
592
  path The absolute or relative directory path where the script is located.
579
593
 
580
594
  Options:
@@ -58,7 +58,7 @@ services:
58
58
  cpus: '0.25'
59
59
  memory: 20M
60
60
  labels: # labels in Compose file instead of Dockerfile
61
- engine.version: '2.8.852'
61
+ engine.version: '2.8.853'
62
62
  networks:
63
63
  - load-balancer
64
64
 
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-template-development-blue
20
- image: localhost/rockylinux9-underpost:v2.8.852
20
+ image: localhost/rockylinux9-underpost:v2.8.853
21
21
  # resources:
22
22
  # requests:
23
23
  # memory: "124Ki"
@@ -100,7 +100,7 @@ spec:
100
100
  spec:
101
101
  containers:
102
102
  - name: dd-template-development-green
103
- image: localhost/rockylinux9-underpost:v2.8.852
103
+ image: localhost/rockylinux9-underpost:v2.8.853
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ REMOTE_USER=$(node bin config get --plain DEFAULT_SSH_USER)
5
+ REMOTE_HOST=$(node bin config get --plain DEFAULT_SSH_HOST)
6
+ SSH_KEY=$(node bin config get --plain DEFAULT_SSH_KEY_PATH)
7
+
8
+ chmod 600 "$SSH_KEY"
9
+
10
+ ssh -i "$SSH_KEY" -o BatchMode=yes "${REMOTE_USER}@${REMOTE_HOST}" sh <<EOF
11
+ cd /home/dd/engine
12
+ node bin deploy dd production --info-traffic
13
+ kubectl get pods -A
14
+ EOF
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "underpost",
5
- "version": "2.8.852",
5
+ "version": "2.8.853",
6
6
  "description": "pwa api rest template",
7
7
  "scripts": {
8
8
  "start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
package/src/cli/cron.js CHANGED
@@ -50,7 +50,7 @@ class UnderpostCron {
50
50
  callback: async function (
51
51
  deployList = 'default',
52
52
  jobList = Object.keys(UnderpostCron.JOB),
53
- options = { itc: false, init: false, git: false, dashboardUpdate: false },
53
+ options = { itc: false, init: false, git: false },
54
54
  ) {
55
55
  if (options.init === true) {
56
56
  UnderpostCron.NETWORK = [];
@@ -61,7 +61,7 @@ class UnderpostCron {
61
61
  for (const job of Object.keys(confCronConfig.jobs)) {
62
62
  const name = `${jobDeployId}-${job}`;
63
63
  let deployId;
64
- if (!options.dashboardUpdate) shellExec(Cmd.delete(name));
64
+ shellExec(Cmd.delete(name));
65
65
  switch (job) {
66
66
  case 'dns':
67
67
  deployId = jobDeployId;
@@ -71,8 +71,7 @@ class UnderpostCron {
71
71
  deployId = deployList;
72
72
  break;
73
73
  }
74
- if (!options.dashboardUpdate)
75
- shellExec(Cmd.cron(deployId, job, name, confCronConfig.jobs[job].expression, options));
74
+ shellExec(Cmd.cron(deployId, job, name, confCronConfig.jobs[job].expression, options));
76
75
  UnderpostCron.NETWORK.push({
77
76
  deployId,
78
77
  jobId: job,
@@ -80,7 +79,6 @@ class UnderpostCron {
80
79
  });
81
80
  }
82
81
  }
83
- if (options.dashboardUpdate === true) await UnderpostCron.API.updateDashboardData();
84
82
  if (fs.existsSync(`./tmp/await-deploy`)) fs.remove(`./tmp/await-deploy`);
85
83
  return;
86
84
  }
@@ -89,32 +87,6 @@ class UnderpostCron {
89
87
  if (UnderpostCron.JOB[jobId]) await UnderpostCron.JOB[jobId].callback(deployList, options);
90
88
  }
91
89
  },
92
- async updateDashboardData() {
93
- try {
94
- const deployId = process.env.DEFAULT_DEPLOY_ID;
95
- const host = process.env.DEFAULT_DEPLOY_HOST;
96
- const path = process.env.DEFAULT_DEPLOY_PATH;
97
- const confServerPath = `./engine-private/conf/${deployId}/conf.server.json`;
98
- const confServer = JSON.parse(fs.readFileSync(confServerPath, 'utf8'));
99
- const { db } = confServer[host][path];
100
-
101
- await DataBaseProvider.load({ apis: ['cron'], host, path, db });
102
-
103
- /** @type {import('../api/cron/cron.model.js').CronModel} */
104
- const Cron = DataBaseProvider.instance[`${host}${path}`].mongoose.models.Cron;
105
-
106
- await Cron.deleteMany();
107
-
108
- for (const cronInstance of UnderpostCron.NETWORK) {
109
- logger.info('save', cronInstance);
110
- await new Cron(cronInstance).save();
111
- }
112
-
113
- await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
114
- } catch (error) {
115
- logger.error(error, error.stack);
116
- }
117
- },
118
90
  };
119
91
  }
120
92
 
package/src/cli/db.js CHANGED
@@ -3,6 +3,7 @@ import { loggerFactory } from '../server/logger.js';
3
3
  import { shellExec } from '../server/process.js';
4
4
  import fs from 'fs-extra';
5
5
  import UnderpostDeploy from './deploy.js';
6
+ import UnderpostCron from './cron.js';
6
7
 
7
8
  const logger = loggerFactory(import.meta);
8
9
 
@@ -216,6 +217,129 @@ class UnderpostDB {
216
217
  }
217
218
  }
218
219
  },
220
+ async updateDashboardData(
221
+ deployId = process.env.DEFAULT_DEPLOY_ID,
222
+ host = process.env.DEFAULT_DEPLOY_HOST,
223
+ path = process.env.DEFAULT_DEPLOY_PATH,
224
+ ) {
225
+ try {
226
+ deployId = deployId ?? process.env.DEFAULT_DEPLOY_ID;
227
+ host = host ?? process.env.DEFAULT_DEPLOY_HOST;
228
+ path = path ?? process.env.DEFAULT_DEPLOY_PATH;
229
+
230
+ const { db } = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'))[host][
231
+ path
232
+ ];
233
+
234
+ await DataBaseProvider.load({ apis: ['instance'], host, path, db });
235
+
236
+ /** @type {import('../api/instance/instance.model.js').InstanceModel} */
237
+ const Instance = DataBaseProvider.instance[`${host}${path}`].mongoose.models.Instance;
238
+
239
+ await Instance.deleteMany();
240
+
241
+ for (const _deployId of deployList.split(',')) {
242
+ const deployId = _deployId.trim();
243
+ if (!deployId) continue;
244
+ const confServer = loadReplicas(
245
+ JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
246
+ 'proxy',
247
+ );
248
+ const router = await UnderpostDeploy.API.routerFactory(deployId, env);
249
+ const pathPortAssignmentData = pathPortAssignmentFactory(router, confServer);
250
+
251
+ for (const host of Object.keys(confServer)) {
252
+ for (const { path, port } of pathPortAssignmentData[host]) {
253
+ if (!confServer[host][path]) continue;
254
+
255
+ const { client, runtime, apis } = confServer[host][path];
256
+
257
+ const body = {
258
+ deployId,
259
+ host,
260
+ path,
261
+ port,
262
+ client,
263
+ runtime,
264
+ apis,
265
+ };
266
+
267
+ logger.info('save', body);
268
+
269
+ await new Instance(body).save();
270
+ }
271
+ }
272
+ }
273
+
274
+ await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
275
+ } catch (error) {
276
+ logger.error(error, error.stack);
277
+ }
278
+
279
+ try {
280
+ const confServerPath = `./engine-private/conf/${deployId}/conf.server.json`;
281
+ const confServer = JSON.parse(fs.readFileSync(confServerPath, 'utf8'));
282
+ const { db } = confServer[host][path];
283
+
284
+ await DataBaseProvider.load({ apis: ['cron'], host, path, db });
285
+
286
+ /** @type {import('../api/cron/cron.model.js').CronModel} */
287
+ const Cron = DataBaseProvider.instance[`${host}${path}`].mongoose.models.Cron;
288
+
289
+ await Cron.deleteMany();
290
+
291
+ for (const cronInstance of UnderpostCron.NETWORK) {
292
+ logger.info('save', cronInstance);
293
+ await new Cron(cronInstance).save();
294
+ }
295
+
296
+ await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
297
+ } catch (error) {
298
+ logger.error(error, error.stack);
299
+ }
300
+ },
301
+ clusterMetadataBackupCallback(
302
+ deployId = process.env.DEFAULT_DEPLOY_ID,
303
+ host = process.env.DEFAULT_DEPLOY_HOST,
304
+ path = process.env.DEFAULT_DEPLOY_PATH,
305
+ options = {
306
+ import: false,
307
+ export: false,
308
+ instances: false,
309
+ crons: false,
310
+ },
311
+ ) {
312
+ deployId = deployId ?? process.env.DEFAULT_DEPLOY_ID;
313
+ host = host ?? process.env.DEFAULT_DEPLOY_HOST;
314
+ path = path ?? process.env.DEFAULT_DEPLOY_PATH;
315
+
316
+ if (options.instances === true) {
317
+ const outputPath = './engine-private/instances';
318
+ if (fs.existsSync(outputPath)) fs.mkdirSync(outputPath, { recursive: true });
319
+ const collection = 'instances';
320
+ if (options.export === true)
321
+ shellExec(
322
+ `node bin db --export --collections ${collection} --out-path ${outputPath} --hosts ${host} --paths '${path}' ${deployId}`,
323
+ );
324
+ if (options.import === true)
325
+ shellExec(
326
+ `node bin db --import --drop --preserveUUID --out-path ${outputPath} --hosts ${host} --paths '${path}' ${deployId}`,
327
+ );
328
+ }
329
+ if (options.crons === true) {
330
+ const outputPath = './engine-private/crons';
331
+ if (fs.existsSync(outputPath)) fs.mkdirSync(outputPath, { recursive: true });
332
+ const collection = 'crons';
333
+ if (options.export === true)
334
+ shellExec(
335
+ `node bin db --export --collections ${collection} --out-path ${outputPath} --hosts ${host} --paths '${path}' ${deployId}`,
336
+ );
337
+ if (options.import === true)
338
+ shellExec(
339
+ `node bin db --import --drop --preserveUUID --out-path ${outputPath} --hosts ${host} --paths '${path}' ${deployId}`,
340
+ );
341
+ }
342
+ },
219
343
  };
220
344
  }
221
345
 
package/src/cli/deploy.js CHANGED
@@ -242,12 +242,10 @@ spec:
242
242
  cert: false,
243
243
  versions: '',
244
244
  traffic: '',
245
- dashboardUpdate: false,
246
245
  replicas: '',
247
246
  restoreHosts: false,
248
247
  disableUpdateDeployment: false,
249
248
  infoTraffic: false,
250
- rebuildClientsBundle: false,
251
249
  },
252
250
  ) {
253
251
  if (options.infoUtil === true)
@@ -311,18 +309,20 @@ Password: <Your Key>
311
309
  deployId,
312
310
  env,
313
311
  traffic: UnderpostDeploy.API.getCurrentTraffic(deployId),
312
+ router: await UnderpostDeploy.API.routerFactory(deployId, env),
313
+ pods: await UnderpostDeploy.API.get(deployId),
314
314
  });
315
315
  }
316
316
  return;
317
317
  }
318
- if (options.rebuildClientsBundle === true) await UnderpostDeploy.API.rebuildClientsBundle(deployList);
319
318
  if (!(options.versions && typeof options.versions === 'string')) options.versions = 'blue,green';
320
319
  if (!options.replicas) options.replicas = 1;
321
320
  if (options.sync) UnderpostDeploy.API.sync(deployList, options);
322
321
  if (options.buildManifest === true) await UnderpostDeploy.API.buildManifest(deployList, env, options);
323
- if (options.infoRouter === true) logger.info('router', await UnderpostDeploy.API.routerFactory(deployList, env));
324
- if (options.dashboardUpdate === true) await UnderpostDeploy.API.updateDashboardData(deployList, env, options);
325
- if (options.infoRouter === true) return;
322
+ if (options.infoRouter === true) {
323
+ logger.info('router', await UnderpostDeploy.API.routerFactory(deployList, env));
324
+ return;
325
+ }
326
326
  shellExec(`kubectl delete configmap underpost-config`);
327
327
  shellExec(
328
328
  `kubectl create configmap underpost-config --from-file=/home/dd/engine/engine-private/conf/dd-cron/.env.${env}`,
@@ -435,23 +435,6 @@ Password: <Your Key>
435
435
 
436
436
  return result;
437
437
  },
438
- rebuildClientsBundle(deployList) {
439
- for (const _deployId of deployList.split(',')) {
440
- const deployId = _deployId.trim();
441
- const repoName = `engine-${deployId.split('-')[1]}`;
442
-
443
- shellExec(`underpost script set ${deployId}-client-build '
444
- cd /home/dd/engine &&
445
- git checkout . &&
446
- underpost pull . underpostnet/${repoName} &&
447
- underpost pull ./engine-private underpostnet/${repoName}-private &&
448
- underpost env ${deployId} production &&
449
- node bin/deploy build-full-client ${deployId}
450
- '`);
451
-
452
- shellExec(`node bin script run ${deployId}-client-build --itc --pod-name ${deployId}`);
453
- }
454
- },
455
438
  resourcesFactory() {
456
439
  return {
457
440
  requests: {
@@ -465,60 +448,6 @@ node bin/deploy build-full-client ${deployId}
465
448
  totalPods: UnderpostRootEnv.API.get('total-pods'),
466
449
  };
467
450
  },
468
- async updateDashboardData(deployList, env, options) {
469
- try {
470
- const deployId = process.env.DEFAULT_DEPLOY_ID;
471
- const host = process.env.DEFAULT_DEPLOY_HOST;
472
- const path = process.env.DEFAULT_DEPLOY_PATH;
473
- const { db } = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'))[host][
474
- path
475
- ];
476
-
477
- await DataBaseProvider.load({ apis: ['instance'], host, path, db });
478
-
479
- /** @type {import('../api/instance/instance.model.js').InstanceModel} */
480
- const Instance = DataBaseProvider.instance[`${host}${path}`].mongoose.models.Instance;
481
-
482
- await Instance.deleteMany();
483
-
484
- for (const _deployId of deployList.split(',')) {
485
- const deployId = _deployId.trim();
486
- if (!deployId) continue;
487
- const confServer = loadReplicas(
488
- JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
489
- 'proxy',
490
- );
491
- const router = await UnderpostDeploy.API.routerFactory(deployId, env);
492
- const pathPortAssignmentData = pathPortAssignmentFactory(router, confServer);
493
-
494
- for (const host of Object.keys(confServer)) {
495
- for (const { path, port } of pathPortAssignmentData[host]) {
496
- if (!confServer[host][path]) continue;
497
-
498
- const { client, runtime, apis } = confServer[host][path];
499
-
500
- const body = {
501
- deployId,
502
- host,
503
- path,
504
- port,
505
- client,
506
- runtime,
507
- apis,
508
- };
509
-
510
- logger.info('save', body);
511
-
512
- await new Instance(body).save();
513
- }
514
- }
515
- }
516
-
517
- await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
518
- } catch (error) {
519
- logger.error(error, error.stack);
520
- }
521
- },
522
451
  existsContainerFile({ podName, path }) {
523
452
  return JSON.parse(
524
453
  shellExec(`kubectl exec ${podName} -- test -f ${path} && echo "true" || echo "false"`, {
package/src/cli/index.js CHANGED
@@ -155,7 +155,6 @@ program
155
155
  '--build-manifest',
156
156
  'Builds Kubernetes YAML manifests, including deployments, services, proxies, and secrets.',
157
157
  )
158
- .option('--dashboard-update', 'Updates dashboard instance data with the current router configuration.')
159
158
  .option('--replicas <replicas>', 'Sets a custom number of replicas for deployments.')
160
159
  .option('--versions <deployment-versions>', 'A comma-separated list of custom deployment versions.')
161
160
  .option('--traffic <traffic-versions>', 'A comma-separated list of custom deployment traffic weights.')
@@ -163,10 +162,6 @@ program
163
162
  .option('--info-traffic', 'Retrieves traffic configuration from current resource deployments.')
164
163
  .option('--kubeadm', 'Enables the kubeadm context for deployment operations.')
165
164
  .option('--restore-hosts', 'Restores default `/etc/hosts` entries.')
166
- .option(
167
- '--rebuild-clients-bundle',
168
- 'Inside the container, rebuilds client bundles (only static public or storage client files).',
169
- )
170
165
  .description('Manages application deployments, defaulting to deploying development pods.')
171
166
  .action(Underpost.deploy.callback);
172
167
 
@@ -240,6 +235,18 @@ program
240
235
  .description('Manages database operations, including import, export, and collection management.')
241
236
  .action(Underpost.db.callback);
242
237
 
238
+ program
239
+ .command('metadata')
240
+ .argument('[deploy-id]', 'The deployment ID to manage metadata.')
241
+ .argument('[host]', 'The host to manage metadata.')
242
+ .argument('[path]', 'The path to manage metadata.')
243
+ .option('--import', 'Imports from local storage.')
244
+ .option('--export', 'Exports to local storage.')
245
+ .option('--crons', 'Apply to cron data collection')
246
+ .option('--instances', 'Apply to instance data collection')
247
+ .description('Manages cluster metadata operations, including import and export.')
248
+ .action(Underpost.db.clusterMetadataBackupCallback);
249
+
243
250
  // 'script' command: Execute scripts
244
251
  program
245
252
  .command('script')
@@ -268,7 +275,6 @@ program
268
275
  .option('--itc', 'Executes cron jobs within the container execution context.')
269
276
  .option('--init', 'Initializes cron jobs for the default deployment ID.')
270
277
  .option('--git', 'Uploads cron job configurations to GitHub.')
271
- .option('--dashboard-update', 'Updates dashboard cron data with the current job configurations.')
272
278
  .description('Manages cron jobs, including initialization, execution, and configuration updates.')
273
279
  .action(Underpost.cron.callback);
274
280
 
package/src/cli/run.js CHANGED
@@ -76,6 +76,11 @@ class UnderpostRun {
76
76
  shellExec(`${baseCommand} deploy --expose mongo`, { async: true });
77
77
  shellExec(`${baseCommand} deploy --expose valkey`, { async: true });
78
78
  },
79
+ 'ssh-cluster-info': (path, options = UnderpostRun.DEFAULT_OPTION) => {
80
+ const { underpostRoot } = options;
81
+ shellExec(`chmod +x ${underpostRoot}/manifests/maas/ssh-cluster-info.sh`);
82
+ shellExec(`${underpostRoot}/manifests/maas/ssh-cluster-info.sh`);
83
+ },
79
84
  'cyberia-ide': (path, options = UnderpostRun.DEFAULT_OPTION) => {
80
85
  const baseCommand = options.dev ? 'node bin' : 'underpost';
81
86
  shellExec(`${baseCommand} run ide /home/dd/cyberia-server`);
@@ -10,7 +10,7 @@ import { Modal } from './Modal.js';
10
10
  import { NotificationManager } from './NotificationManager.js';
11
11
  import { Translate } from './Translate.js';
12
12
  import { Validator } from './Validator.js';
13
- import { append, htmls, s } from './VanillaJs.js';
13
+ import { append, getProxyPath, htmls, s } from './VanillaJs.js';
14
14
 
15
15
  const Account = {
16
16
  UpdateEvent: {},
@@ -80,9 +80,10 @@ const Recover = {
80
80
  }
81
81
  switch (mode) {
82
82
  case 'recover-verify-email': {
83
- body.proxyPath = getProxyPath();
84
- body.hostname = `${location.hostname}`;
85
- const result = await UserService.post({ id: 'recover-verify-email', body });
83
+ const result = await UserService.post({
84
+ id: 'recover-verify-email',
85
+ body: { ...body, proxyPath: getProxyPath(), hostname: `${location.hostname}` },
86
+ });
86
87
  NotificationManager.Push({
87
88
  html:
88
89
  result.status === 'error' ? result.message : Translate.Render(`${result.status}-recover-verify-email`),
package/src/index.js CHANGED
@@ -35,7 +35,7 @@ class Underpost {
35
35
  * @type {String}
36
36
  * @memberof Underpost
37
37
  */
38
- static version = 'v2.8.852';
38
+ static version = 'v2.8.853';
39
39
  /**
40
40
  * Repository cli API
41
41
  * @static