underpost 2.8.62 → 2.8.65

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 (50) hide show
  1. package/Dockerfile +9 -10
  2. package/bin/build.js +2 -2
  3. package/bin/deploy.js +40 -2
  4. package/bin/index.js +39 -18
  5. package/docker-compose.yml +1 -1
  6. package/package.json +2 -9
  7. package/src/api/default/default.service.js +1 -1
  8. package/src/api/user/user.service.js +14 -11
  9. package/src/cli/cluster.js +45 -2
  10. package/src/cli/cron.js +39 -8
  11. package/src/cli/db.js +18 -8
  12. package/src/cli/deploy.js +173 -80
  13. package/src/cli/fs.js +7 -6
  14. package/src/cli/image.js +39 -101
  15. package/src/cli/monitor.js +182 -0
  16. package/src/cli/repository.js +5 -2
  17. package/src/client/components/core/Account.js +28 -24
  18. package/src/client/components/core/Blockchain.js +1 -1
  19. package/src/client/components/core/CalendarCore.js +14 -84
  20. package/src/client/components/core/CommonJs.js +2 -1
  21. package/src/client/components/core/Css.js +0 -1
  22. package/src/client/components/core/CssCore.js +10 -2
  23. package/src/client/components/core/Docs.js +1 -1
  24. package/src/client/components/core/EventsUI.js +3 -3
  25. package/src/client/components/core/FileExplorer.js +86 -78
  26. package/src/client/components/core/LoadingAnimation.js +1 -17
  27. package/src/client/components/core/LogIn.js +3 -3
  28. package/src/client/components/core/LogOut.js +1 -1
  29. package/src/client/components/core/Modal.js +12 -7
  30. package/src/client/components/core/Panel.js +19 -61
  31. package/src/client/components/core/PanelForm.js +13 -22
  32. package/src/client/components/core/Recover.js +3 -3
  33. package/src/client/components/core/RichText.js +1 -11
  34. package/src/client/components/core/Router.js +3 -1
  35. package/src/client/components/core/SignUp.js +2 -2
  36. package/src/client/components/default/RoutesDefault.js +3 -2
  37. package/src/client/services/default/default.management.js +45 -38
  38. package/src/client/ssr/Render.js +2 -0
  39. package/src/index.js +18 -2
  40. package/src/mailer/MailerProvider.js +3 -0
  41. package/src/runtime/lampp/Dockerfile +65 -0
  42. package/src/server/conf.js +89 -1
  43. package/src/server/dns.js +9 -1
  44. package/src/server/json-schema.js +77 -0
  45. package/src/server/network.js +7 -122
  46. package/src/server/peer.js +2 -2
  47. package/src/server/proxy.js +4 -4
  48. package/src/server/runtime.js +22 -11
  49. package/src/server/start.js +123 -0
  50. package/src/server/valkey.js +25 -11
package/Dockerfile CHANGED
@@ -1,11 +1,11 @@
1
1
  ARG BASE_DEBIAN=buster
2
2
 
3
+ # USER root
4
+
3
5
  FROM debian:${BASE_DEBIAN}
4
6
 
5
7
  ENV DEBIAN_FRONTEND=noninteractive
6
8
 
7
- WORKDIR /home/dd
8
-
9
9
  # Set root password to root, format is 'user:password'.
10
10
  RUN echo 'root:root' | chpasswd
11
11
 
@@ -25,9 +25,6 @@ RUN mkdir -p /var/run/sshd
25
25
  # Allow root login via password
26
26
  RUN sed -ri 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
27
27
 
28
- # copy supervisor config file to start openssh-server
29
- COPY supervisord-openssh-server.conf /etc/supervisor/conf.d/supervisord-openssh-server.conf
30
-
31
28
  # install open ssl git and others tools
32
29
  RUN apt-get install -yq --no-install-recommends libssl-dev curl wget git gnupg
33
30
 
@@ -37,12 +34,14 @@ RUN apt-get install -y nodejs build-essential
37
34
  RUN node --version
38
35
  RUN npm --version
39
36
 
40
- RUN npm install -g underpost
41
-
42
- VOLUME [ "/home/dd/engine/logs" ]
37
+ WORKDIR /home/dd
43
38
 
44
39
  EXPOSE 22
45
40
 
46
- EXPOSE 4000-4004
41
+ EXPOSE 80
42
+
43
+ EXPOSE 443
44
+
45
+ EXPOSE 3000-3100
47
46
 
48
- CMD [ "underpost", "new", "service" ]
47
+ EXPOSE 4000-4100
package/bin/build.js CHANGED
@@ -47,7 +47,7 @@ if (process.argv.includes('conf')) {
47
47
  if (!fs.existsSync(`../${privateRepoName}`)) {
48
48
  shellExec(`cd .. && underpost clone ${privateGitUri}`, { silent: true });
49
49
  } else {
50
- shellExec(`cd ../${privateRepoName} && underpost pull . ${privateGitUri}`);
50
+ shellExec(`cd ../${privateRepoName} && git checkout . && git clean -f -d && underpost pull . ${privateGitUri}`);
51
51
  }
52
52
  const toPath = `../${privateRepoName}/conf/${_confName}`;
53
53
  fs.removeSync(toPath);
@@ -176,7 +176,7 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
176
176
  if (!fs.existsSync(`${basePath}/images`)) fs.mkdirSync(`${basePath}/images`);
177
177
 
178
178
  const env = process.argv.includes('development') ? 'development' : 'production';
179
- const deploymentsFiles = ['Dockerfile', 'proxy.yaml', 'deployment.yaml', 'secret.yaml'];
179
+ const deploymentsFiles = ['proxy.yaml', 'deployment.yaml', 'secret.yaml'];
180
180
  // remove engine-private of .dockerignore for local testing
181
181
  for (const file of deploymentsFiles) {
182
182
  if (fs.existsSync(`./manifests/deployment/${confName}-${env}/${file}`)) {
package/bin/deploy.js CHANGED
@@ -33,8 +33,9 @@ import { MongooseDB } from '../src/db/mongo/MongooseDB.js';
33
33
  import { Lampp } from '../src/runtime/lampp/Lampp.js';
34
34
  import { DefaultConf } from '../conf.js';
35
35
  import { JSONweb } from '../src/server/client-formatted.js';
36
- import ejs from 'easy-json-schema';
36
+
37
37
  import { Xampp } from '../src/runtime/xampp/Xampp.js';
38
+ import { ejs } from '../src/server/json-schema.js';
38
39
 
39
40
  const logger = loggerFactory(import.meta);
40
41
 
@@ -673,8 +674,8 @@ try {
673
674
  }
674
675
 
675
676
  case 'version-build': {
676
- const newVersion = process.argv[3];
677
677
  const originPackageJson = JSON.parse(fs.readFileSync(`package.json`, 'utf8'));
678
+ const newVersion = process.argv[3] ?? originPackageJson.version;
678
679
  const { version } = originPackageJson;
679
680
  originPackageJson.version = newVersion;
680
681
  fs.writeFileSync(`package.json`, JSON.stringify(originPackageJson, null, 4), 'utf8');
@@ -1048,6 +1049,43 @@ ${shellExec(`git log | grep Author: | sort -u`, { stdout: true }).split(`\n`).jo
1048
1049
  break;
1049
1050
  }
1050
1051
 
1052
+ case 'update-instances': {
1053
+ shellExec(`node bin deploy dd production --sync --build-manifest --info-router --dashboard-update`);
1054
+ shellExec(`node bin cron --dashboard-update --init`);
1055
+ const deployId = 'dd-core';
1056
+ const host = 'www.nexodev.org';
1057
+ const path = '/';
1058
+
1059
+ {
1060
+ const outputPath = './engine-private/instances';
1061
+ if (fs.existsSync(outputPath)) fs.mkdirSync(outputPath, { recursive: true });
1062
+ const collection = 'instances';
1063
+ if (process.argv.includes('export'))
1064
+ shellExec(
1065
+ `node bin db --export --collections ${collection} --out-path ${outputPath} --hosts ${host} --paths '${path}' ${deployId}`,
1066
+ );
1067
+ if (process.argv.includes('import'))
1068
+ shellExec(
1069
+ `node bin db --import --drop --preserveUUID --out-path ${outputPath} --hosts ${host} --paths '${path}' ${deployId}`,
1070
+ );
1071
+ }
1072
+ {
1073
+ const outputPath = './engine-private/crons';
1074
+ if (fs.existsSync(outputPath)) fs.mkdirSync(outputPath, { recursive: true });
1075
+ const collection = 'crons';
1076
+ if (process.argv.includes('export'))
1077
+ shellExec(
1078
+ `node bin db --export --collections ${collection} --out-path ${outputPath} --hosts ${host} --paths '${path}' ${deployId}`,
1079
+ );
1080
+ if (process.argv.includes('import'))
1081
+ shellExec(
1082
+ `node bin db --import --drop --preserveUUID --out-path ${outputPath} --hosts ${host} --paths '${path}' ${deployId}`,
1083
+ );
1084
+ }
1085
+
1086
+ break;
1087
+ }
1088
+
1051
1089
  default:
1052
1090
  break;
1053
1091
  }
package/bin/index.js CHANGED
@@ -22,6 +22,15 @@ program
22
22
  .description('Create a new project')
23
23
  .action(Underpost.repo.new);
24
24
 
25
+ program
26
+ .command('start')
27
+ .argument('<deploy-id>', 'Deploy configuration id')
28
+ .argument('[env]', 'Optional environment, for default is development')
29
+ .option('--run', 'Run app servers and monitor health server')
30
+ .option('--build', 'Build app client')
31
+ .action(Underpost.start.callback)
32
+ .description('Start up server, build pipelines, or services');
33
+
25
34
  program
26
35
  .command('clone')
27
36
  .argument(`<uri>`, 'e.g. username/repository')
@@ -91,6 +100,8 @@ program
91
100
  .option('--ns-use <ns-name>', 'Switches current context to namespace')
92
101
  .option('--dev', 'init with dev cluster')
93
102
  .option('--list-pods', 'Display list pods information')
103
+ .option('--info-capacity', 'display current total machine capacity info')
104
+ .option('--info-capacity-pod', 'display current machine capacity pod info')
94
105
  .action(Underpost.cluster.init)
95
106
  .description('Manage cluster, for default initialization base kind cluster');
96
107
 
@@ -105,7 +116,10 @@ program
105
116
  .option('--info-util', 'Display kubectl util management commands')
106
117
  .option('--cert', 'Reset tls/ssl certificate secrets')
107
118
  .option('--build-manifest', 'Build kind yaml manifests: deployments, services, proxy and secrets')
108
- .option('--version', 'Set custom version')
119
+ .option('--dashboard-update', 'Update dashboard instance data with current router config')
120
+ .option('--replicas <replicas>', 'Set custom number of replicas')
121
+ .option('--versions <deployment-versions>', 'Comma separated custom deployment versions')
122
+ .option('--traffic <traffic-versions>', 'Comma separated custom deployment traffic')
109
123
  .description('Manage deployment, for default deploy development pods')
110
124
  .action(Underpost.deploy.callback);
111
125
 
@@ -124,24 +138,17 @@ program
124
138
  if (args[1].init) return Underpost.secret[args[0]].init();
125
139
  });
126
140
 
127
- program
128
- .command('dockerfile-node-script')
129
- .argument('<deploy-id>', 'Deploy configuration id')
130
- .argument('[env]', 'Optional environment, for default is development')
131
- .option('--run', 'Run custom entry point script')
132
- .option('--build', 'Build custom image container scripts')
133
- .description('Dockerfile custom node build script')
134
- .action(Underpost.image.dockerfile.script);
135
-
136
141
  program
137
142
  .command('dockerfile-image-build')
138
- .argument('<deploy-id>', 'Deploy configuration id')
139
- .argument('[env]', 'Optional environment, for default is development')
140
- .argument('[path]', 'Absolute or relative directory, for default is current')
141
- .option('--image-archive', 'Only load tar image from ./images')
142
- .option('--podman-save', 'Save image from podman to ./images')
143
- .option('--image-name <image-name>', 'Set custom image name')
144
- .option('--image-version <image-version>', 'Set custom image version')
143
+ .option('--path [path]', 'Dockerfile path')
144
+ .option('--image-name [image-name]', 'Set image name')
145
+ .option('--image-path [image-path]', 'Set tar image path')
146
+ .option('--dockerfile-name [dockerfile-name]', 'set Dockerfile name')
147
+ .option('--podman-save', 'Export tar file from podman')
148
+ .option('--kind-load', 'Import tar image to Kind cluster')
149
+ .option('--secrets', 'Dockerfile env secrets')
150
+ .option('--secrets-path [secrets-path]', 'Dockerfile custom path env secrets')
151
+ .option('--no-cache', 'Build without using cache')
145
152
  .description('Build image from Dockerfile')
146
153
  .action(Underpost.image.dockerfile.build);
147
154
 
@@ -163,11 +170,13 @@ program
163
170
  .option('--import', 'Import container backups from repositories')
164
171
  .option('--export', 'Export container backups to repositories')
165
172
  .option('--pod-name <pod-name>', 'Optional pod context')
166
- .option('--collection <collection>', 'Collection')
173
+ .option('--collections <collections>', 'Comma separated collections')
167
174
  .option('--out-path <out-path>', 'Custom out path backup')
168
175
  .option('--drop', 'Drop databases')
169
176
  .option('--preserveUUID', 'Preserve Ids')
170
177
  .option('--git', 'Upload to github')
178
+ .option('--hosts <hosts>', 'Comma separated hosts')
179
+ .option('--paths <paths>', 'Comma separated paths')
171
180
  .option('--ns <ns-name>', 'Optional name space context')
172
181
  .description('Manage databases')
173
182
  .action(Underpost.db.callback);
@@ -193,6 +202,7 @@ program
193
202
  .option('--itc', 'Inside container execution context')
194
203
  .option('--init', 'Init cron jobs for cron job default deploy id')
195
204
  .option('--git', 'Upload to github')
205
+ .option('--dashboard-update', 'Update dashboard cron data with current jobs config')
196
206
  .description('Cron jobs management')
197
207
  .action(Underpost.cron.callback);
198
208
 
@@ -220,4 +230,15 @@ program
220
230
  .option('--kind-type <kind-type>')
221
231
  .action(Underpost.test.callback);
222
232
 
233
+ program
234
+ .command('monitor')
235
+ .argument('<deploy-id>', 'Deploy configuration id')
236
+ .argument('[env]', 'Optional environment, for default is development')
237
+ .option('--ms-interval <ms-interval>', 'Custom ms interval delta time')
238
+ .option('--now', 'Exec immediately monitor script')
239
+ .option('--single', 'Disable recurrence')
240
+ .option('--type <type>', 'Set custom monitor type')
241
+ .description('Monitor health server management')
242
+ .action(Underpost.monitor.callback);
243
+
223
244
  program.parse();
@@ -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.62'
61
+ engine.version: '2.8.65'
62
62
  networks:
63
63
  - load-balancer
64
64
 
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.62",
5
+ "version": "2.8.65",
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",
@@ -69,7 +69,6 @@
69
69
  "cors": "^2.8.5",
70
70
  "d3": "^7.9.0",
71
71
  "dotenv": "^16.3.1",
72
- "easy-json-schema": "^0.0.2-beta",
73
72
  "easymde": "^2.18.0",
74
73
  "env-cmd": "^10.1.0",
75
74
  "express": "^4.18.2",
@@ -119,13 +118,7 @@
119
118
  "vanilla-jsoneditor": "^2.3.2",
120
119
  "winston": "^3.11.0"
121
120
  },
122
- "devDependencies": {
123
- "clean-jsdoc-theme": "^4.3.0",
124
- "easy-json-schema": "^0.0.2-beta",
125
- "mocha": "^10.8.2",
126
- "plantuml": "^0.0.2",
127
- "swagger-autogen": "^2.23.7"
128
- },
121
+ "devDependencies": {},
129
122
  "publishConfig": {
130
123
  "provenance": true,
131
124
  "access": "public",
@@ -24,7 +24,7 @@ const DefaultService = {
24
24
  /** @type {import('./default.model.js').DefaultModel} */
25
25
  const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Default;
26
26
  if (req.params.id) return await Default.findByIdAndDelete(req.params.id);
27
- else return await await Default.deleteMany();
27
+ else return await Default.deleteMany();
28
28
  },
29
29
  };
30
30
 
@@ -225,8 +225,8 @@ const UserService = {
225
225
  } else throw new Error('invalid email or password');
226
226
 
227
227
  case 'guest': {
228
- const user = await ValkeyAPI.valkeyObjectFactory('user', options);
229
- await ValkeyAPI.setValkeyObject(user.email, user);
228
+ const user = await ValkeyAPI.valkeyObjectFactory(options, 'user');
229
+ await ValkeyAPI.setValkeyObject(options, user.email, user);
230
230
  return {
231
231
  token: hashJWT({ user: UserDto.auth.payload(user) }),
232
232
  user: selectDtoFactory(user, UserDto.select.get()),
@@ -325,15 +325,18 @@ const UserService = {
325
325
  return await User.find().select(UserDto.select.getAll());
326
326
 
327
327
  case 'auth': {
328
- const user = (await ValkeyAPI.getValkeyObject(req.auth.user.email))
329
- ? await ValkeyAPI.getValkeyObject(req.auth.user.email)
330
- : await User.findOne({
331
- _id: req.auth.user._id,
332
- });
328
+ let user;
329
+ if (req.auth.user._id.match('guest')) {
330
+ user = await ValkeyAPI.getValkeyObject(options, req.auth.user.email);
331
+ if (!user) throw new Error('guest user expired');
332
+ } else
333
+ user = await User.findOne({
334
+ _id: req.auth.user._id,
335
+ });
333
336
 
334
337
  const file = await File.findOne({ _id: user.profileImageId });
335
338
 
336
- if (!file && !(await ValkeyAPI.getValkeyObject(req.auth.user.email))) {
339
+ if (!file && !(await ValkeyAPI.getValkeyObject(options, req.auth.user.email))) {
337
340
  await User.findByIdAndUpdate(
338
341
  user._id,
339
342
  { profileImageId: await getDefaultProfileImageId(File) },
@@ -342,8 +345,8 @@ const UserService = {
342
345
  },
343
346
  );
344
347
  }
345
- return (await ValkeyAPI.getValkeyObject(req.auth.user.email))
346
- ? selectDtoFactory(await ValkeyAPI.getValkeyObject(req.auth.user.email), UserDto.select.get())
348
+ return (await ValkeyAPI.getValkeyObject(options, req.auth.user.email))
349
+ ? selectDtoFactory(await ValkeyAPI.getValkeyObject(options, req.auth.user.email), UserDto.select.get())
347
350
  : await User.findOne({
348
351
  _id: req.auth.user._id,
349
352
  }).select(UserDto.select.get());
@@ -378,7 +381,7 @@ const UserService = {
378
381
  switch (user.role) {
379
382
  case 'admin': {
380
383
  if (req.params.id) return await User.findByIdAndDelete(req.params.id);
381
- else return await await User.deleteMany();
384
+ else return await User.deleteMany();
382
385
  }
383
386
  default:
384
387
  if (req.auth.user._id !== req.params.id) throw new Error(`Invalid token user id`);
@@ -1,5 +1,4 @@
1
- import { timer } from '../client/components/core/CommonJs.js';
2
- import { cliSpinner, getNpmRootPath } from '../server/conf.js';
1
+ import { getNpmRootPath } from '../server/conf.js';
3
2
  import { loggerFactory } from '../server/logger.js';
4
3
  import { shellExec } from '../server/process.js';
5
4
  import UnderpostDeploy from './deploy.js';
@@ -23,10 +22,14 @@ class UnderpostCluster {
23
22
  reset: false,
24
23
  dev: false,
25
24
  nsUse: '',
25
+ infoCapacity: false,
26
+ infoCapacityPod: false,
26
27
  },
27
28
  ) {
28
29
  const npmRoot = getNpmRootPath();
29
30
  const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
31
+ if (options.infoCapacityPod === true) return logger.info('', UnderpostDeploy.API.resourcesFactory());
32
+ if (options.infoCapacity === true) return logger.info('', UnderpostCluster.API.getResourcesCapacity());
30
33
  if (options.reset === true) return await UnderpostCluster.API.reset();
31
34
  if (options.listPods === true) return console.table(UnderpostDeploy.API.get(podName ?? undefined));
32
35
 
@@ -197,6 +200,46 @@ class UnderpostCluster {
197
200
  );
198
201
  shellExec(`sudo podman system reset -f`);
199
202
  },
203
+ getResourcesCapacity() {
204
+ const resources = {};
205
+ const info = false
206
+ ? `Capacity:
207
+ cpu: 8
208
+ ephemeral-storage: 153131976Ki
209
+ hugepages-1Gi: 0
210
+ hugepages-2Mi: 0
211
+ memory: 11914720Ki
212
+ pods: 110
213
+ Allocatable:
214
+ cpu: 8
215
+ ephemeral-storage: 153131976Ki
216
+ hugepages-1Gi: 0
217
+ hugepages-2Mi: 0
218
+ memory: 11914720Ki
219
+ pods: `
220
+ : shellExec(`kubectl describe node kind-worker | grep -E '(Allocatable:|Capacity:)' -A 6`, {
221
+ stdout: true,
222
+ silent: true,
223
+ });
224
+ info
225
+ .split('Allocatable:')[1]
226
+ .split('\n')
227
+ .filter((row) => row.match('cpu') || row.match('memory'))
228
+ .map((row) => {
229
+ if (row.match('cpu'))
230
+ resources.cpu = {
231
+ value: parseInt(row.split(':')[1].trim()) * 1000,
232
+ unit: 'm',
233
+ };
234
+ if (row.match('memory'))
235
+ resources.memory = {
236
+ value: parseInt(row.split(':')[1].split('Ki')[0].trim()),
237
+ unit: 'Ki',
238
+ };
239
+ });
240
+
241
+ return resources;
242
+ },
200
243
  };
201
244
  }
202
245
  export default UnderpostCluster;
package/src/cli/cron.js CHANGED
@@ -4,20 +4,24 @@
4
4
  * @namespace UnderpostCron
5
5
  */
6
6
 
7
- import Underpost from '../index.js';
7
+ import { DataBaseProvider } from '../db/DataBaseProvider.js';
8
8
  import BackUp from '../server/backup.js';
9
9
  import { Cmd } from '../server/conf.js';
10
10
  import Dns from '../server/dns.js';
11
- import { netWorkCron, saveRuntimeCron } from '../server/network.js';
11
+ import { loggerFactory } from '../server/logger.js';
12
+
12
13
  import { shellExec } from '../server/process.js';
13
14
  import fs from 'fs-extra';
14
15
 
16
+ const logger = loggerFactory(import.meta);
17
+
15
18
  /**
16
19
  * UnderpostCron main module methods
17
20
  * @class
18
21
  * @memberof UnderpostCron
19
22
  */
20
23
  class UnderpostCron {
24
+ static NETWORK = [];
21
25
  static JOB = {
22
26
  /**
23
27
  * DNS cli API
@@ -46,10 +50,10 @@ class UnderpostCron {
46
50
  callback: async function (
47
51
  deployList = 'default',
48
52
  jobList = Object.keys(UnderpostCron.JOB),
49
- options = { itc: false, init: false, git: false },
53
+ options = { itc: false, init: false, git: false, dashboardUpdate: false },
50
54
  ) {
51
55
  if (options.init === true) {
52
- await Underpost.test.setUpInfo();
56
+ UnderpostCron.NETWORK = [];
53
57
  const jobDeployId = fs.readFileSync('./engine-private/deploy/dd.cron', 'utf8').trim();
54
58
  deployList = fs.readFileSync('./engine-private/deploy/dd.router', 'utf8').trim();
55
59
  const confCronConfig = JSON.parse(fs.readFileSync(`./engine-private/conf/${jobDeployId}/conf.cron.json`));
@@ -57,7 +61,7 @@ class UnderpostCron {
57
61
  for (const job of Object.keys(confCronConfig.jobs)) {
58
62
  const name = `${jobDeployId}-${job}`;
59
63
  let deployId;
60
- shellExec(Cmd.delete(name));
64
+ if (!options.dashboardUpdate) shellExec(Cmd.delete(name));
61
65
  switch (job) {
62
66
  case 'dns':
63
67
  deployId = jobDeployId;
@@ -67,15 +71,16 @@ class UnderpostCron {
67
71
  deployId = deployList;
68
72
  break;
69
73
  }
70
- shellExec(Cmd.cron(deployId, job, name, confCronConfig.jobs[job].expression, options));
71
- netWorkCron.push({
74
+ if (!options.dashboardUpdate)
75
+ shellExec(Cmd.cron(deployId, job, name, confCronConfig.jobs[job].expression, options));
76
+ UnderpostCron.NETWORK.push({
72
77
  deployId,
73
78
  jobId: job,
74
79
  expression: confCronConfig.jobs[job].expression,
75
80
  });
76
81
  }
77
82
  }
78
- await saveRuntimeCron();
83
+ if (options.dashboardUpdate === true) await UnderpostCron.API.updateDashboardData();
79
84
  if (fs.existsSync(`./tmp/await-deploy`)) fs.remove(`./tmp/await-deploy`);
80
85
  return;
81
86
  }
@@ -84,6 +89,32 @@ class UnderpostCron {
84
89
  if (UnderpostCron.JOB[jobId]) await UnderpostCron.JOB[jobId].callback(deployList, options);
85
90
  }
86
91
  },
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
+ },
87
118
  };
88
119
  }
89
120
 
package/src/cli/db.js CHANGED
@@ -15,11 +15,13 @@ class UnderpostDB {
15
15
  export: false,
16
16
  podName: false,
17
17
  ns: false,
18
- collection: '',
18
+ collections: '',
19
19
  outPath: '',
20
20
  drop: false,
21
21
  preserveUUID: false,
22
22
  git: false,
23
+ hosts: '',
24
+ paths: '',
23
25
  },
24
26
  ) {
25
27
  const newBackupTimestamp = new Date().getTime();
@@ -39,20 +41,28 @@ class UnderpostDB {
39
41
  if (!dbs[provider]) dbs[provider] = {};
40
42
 
41
43
  if (!(name in dbs[provider]))
42
- dbs[provider][name] = { user, password, hostFolder: host + path.replaceAll('/', '-') };
44
+ dbs[provider][name] = { user, password, hostFolder: host + path.replaceAll('/', '-'), host, path };
43
45
  }
44
46
  }
45
47
  }
46
48
 
47
- if (!fs.existsSync(`../${repoName}`)) {
48
- shellExec(`cd .. && underpost clone ${process.env.GITHUB_USERNAME}/${repoName}`);
49
- } else {
50
- shellExec(`cd ../${repoName} && underpost pull . ${process.env.GITHUB_USERNAME}/${repoName}`);
49
+ if (options.git === true) {
50
+ if (!fs.existsSync(`../${repoName}`)) {
51
+ shellExec(`cd .. && underpost clone ${process.env.GITHUB_USERNAME}/${repoName}`);
52
+ } else {
53
+ shellExec(`cd ../${repoName} && git checkout . && git clean -f -d`);
54
+ shellExec(`cd ../${repoName} && underpost pull . ${process.env.GITHUB_USERNAME}/${repoName}`);
55
+ }
51
56
  }
52
57
 
53
58
  for (const provider of Object.keys(dbs)) {
54
59
  for (const dbName of Object.keys(dbs[provider])) {
55
- const { hostFolder, user, password } = dbs[provider][dbName];
60
+ const { hostFolder, user, password, host, path } = dbs[provider][dbName];
61
+ if (
62
+ (options.hosts && !options.hosts.split(',').includes(host)) ||
63
+ (options.paths && !options.paths.split(',').includes(path))
64
+ )
65
+ continue;
56
66
  if (hostFolder) {
57
67
  logger.info('', { hostFolder, provider, dbName });
58
68
 
@@ -153,7 +163,7 @@ class UnderpostDB {
153
163
  const podName = podNameData.NAME;
154
164
  shellExec(`sudo kubectl exec -i ${podName} -- sh -c "rm -rf /${dbName}"`);
155
165
  if (options.collections)
156
- for (const collection of options.collections)
166
+ for (const collection of options.collections.split(','))
157
167
  shellExec(
158
168
  `sudo kubectl exec -i ${podName} -- sh -c "mongodump -d ${dbName} --collection ${collection} -o /"`,
159
169
  );