underpost 2.8.622 → 2.8.635

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/bin/index.js CHANGED
@@ -220,4 +220,12 @@ program
220
220
  .option('--kind-type <kind-type>')
221
221
  .action(Underpost.test.callback);
222
222
 
223
+ program
224
+ .command('monitor')
225
+ .argument('<deploy-id>', 'Deploy configuration id')
226
+ .argument('[env]', 'Optional environment, for default is development')
227
+ .description('Monitor health server management')
228
+ .option('--itc', 'Inside container execution context')
229
+ .action(Underpost.monitor.callback);
230
+
223
231
  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.622'
61
+ engine.version: '2.8.635'
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.622",
5
+ "version": "2.8.635",
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/deploy.js CHANGED
@@ -3,8 +3,10 @@ import {
3
3
  buildPortProxyRouter,
4
4
  buildProxyRouter,
5
5
  Config,
6
+ deployRangePortFactory,
6
7
  getDataDeploy,
7
8
  loadReplicas,
9
+ pathPortAssignmentFactory,
8
10
  } from '../server/conf.js';
9
11
  import { loggerFactory } from '../server/logger.js';
10
12
  import { shellExec } from '../server/process.js';
@@ -36,15 +38,13 @@ class UnderpostDeploy {
36
38
  for (const _deployId of deployList.split(',')) {
37
39
  const deployId = _deployId.trim();
38
40
  if (!deployId) continue;
39
-
40
- const router = await UnderpostDeploy.API.routerFactory(deployId, env);
41
- const ports = Object.values(router).map((p) => parseInt(p.split(':')[2]));
42
- const fromPort = Math.min(...ports);
43
- const toPort = Math.max(...ports);
44
41
  const confServer = loadReplicas(
45
42
  JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
46
43
  'proxy',
47
44
  );
45
+ const router = await UnderpostDeploy.API.routerFactory(deployId, env);
46
+ const pathPortAssignmentData = pathPortAssignmentFactory(router, confServer);
47
+ const { fromPort, toPort } = deployRangePortFactory(router);
48
48
 
49
49
  fs.mkdirSync(`./engine-private/conf/${deployId}/build/${env}`, { recursive: true });
50
50
  if (env === 'development') fs.mkdirSync(`./manifests/deployment/${deployId}-${env}`, { recursive: true });
@@ -141,27 +141,8 @@ spec:
141
141
  kind: ClusterIssuer
142
142
  secretName: ${host}`;
143
143
 
144
- const pathPortConditions = [];
145
- for (const path of Object.keys(confServer[host])) {
146
- const { peer } = confServer[host][path];
147
- if (!router[`${host}${path === '/' ? '' : path}`]) continue;
148
- const port = parseInt(router[`${host}${path === '/' ? '' : path}`].split(':')[2]);
149
- // logger.info('', { host, port, path });
150
- pathPortConditions.push({
151
- port,
152
- path,
153
- });
154
-
155
- if (peer) {
156
- // logger.info('', { host, port: port + 1, path: '/peer' });
157
- pathPortConditions.push({
158
- port: port + 1,
159
- path: '/peer',
160
- });
161
- }
162
- }
163
-
164
- // logger.info('', { host, pathPortConditions });
144
+ const pathPortAssignment = pathPortAssignmentData[host];
145
+ // logger.info('', { host, pathPortAssignment });
165
146
  proxyYaml += `
166
147
  ---
167
148
  apiVersion: projectcontour.io/v1
@@ -178,7 +159,7 @@ spec:
178
159
  secretName: ${host}`
179
160
  }
180
161
  routes:`;
181
- for (const conditionObj of pathPortConditions) {
162
+ for (const conditionObj of pathPortAssignment) {
182
163
  const { path, port } = conditionObj;
183
164
  proxyYaml += `
184
165
  - conditions:
package/src/cli/image.js CHANGED
@@ -2,10 +2,10 @@ import fs from 'fs-extra';
2
2
  import Underpost from '../index.js';
3
3
  import { shellCd, shellExec } from '../server/process.js';
4
4
  import dotenv from 'dotenv';
5
- import { getNpmRootPath } from '../server/conf.js';
5
+ import { awaitDeployMonitor, getNpmRootPath } from '../server/conf.js';
6
6
  import { timer } from '../client/components/core/CommonJs.js';
7
- import UnderpostRootEnv from './env.js';
8
7
  import { loggerFactory } from '../server/logger.js';
8
+ import UnderpostMonitor from './monitor.js';
9
9
 
10
10
  dotenv.config();
11
11
 
@@ -69,59 +69,57 @@ class UnderpostImage {
69
69
  for (const itcScript of itcScripts)
70
70
  if (itcScript.match(deployId)) shellExec(`node ./engine-private/itc-scripts/${itcScript}`);
71
71
  }
72
- }
73
- switch (deployId) {
74
- default:
75
- {
72
+ switch (deployId) {
73
+ default:
76
74
  {
77
- const originPath = `./src/db/mongo/MongooseDB.js`;
78
- fs.writeFileSync(
79
- originPath,
80
- fs.readFileSync(originPath, 'utf8').replaceAll(
81
- `connect: async (host, name) => {`,
82
- `connect: async (host, name) => {
75
+ {
76
+ const originPath = `./src/db/mongo/MongooseDB.js`;
77
+ fs.writeFileSync(
78
+ originPath,
79
+ fs.readFileSync(originPath, 'utf8').replaceAll(
80
+ `connect: async (host, name) => {`,
81
+ `connect: async (host, name) => {
83
82
  host = 'mongodb://mongodb-0.mongodb-service:27017';
84
- `,
85
- ),
86
- 'utf8',
87
- );
88
- }
83
+ `,
84
+ ),
85
+ 'utf8',
86
+ );
87
+ }
89
88
 
90
- {
91
- const originPath = `./src/server/valkey.js`;
92
- fs.writeFileSync(
93
- originPath,
94
- fs.readFileSync(originPath, 'utf8').replaceAll(
95
- ` // port: 6379,
89
+ {
90
+ const originPath = `./src/server/valkey.js`;
91
+ fs.writeFileSync(
92
+ originPath,
93
+ fs.readFileSync(originPath, 'utf8').replaceAll(
94
+ ` // port: 6379,
96
95
  // host: 'service-valkey.default.svc.cluster.local',`,
97
- ` port: 6379,
96
+ ` port: 6379,
98
97
  host: 'service-valkey.default.svc.cluster.local',`,
99
- ),
100
- 'utf8',
101
- );
98
+ ),
99
+ 'utf8',
100
+ );
101
+ }
102
102
  }
103
- }
104
- break;
103
+ break;
104
+ }
105
+ shellExec(`node bin/deploy conf ${deployId} ${env}`);
106
+ shellExec(`node bin/deploy build-full-client ${deployId}`);
105
107
  }
106
- shellExec(`node bin/deploy conf ${deployId} ${env}`);
107
- shellExec(`node bin/deploy build-full-client ${deployId}`);
108
108
  if (options.run === true) {
109
109
  const runCmd = env === 'production' ? 'run prod-img' : 'run dev-img';
110
110
  if (fs.existsSync(`./engine-private/replica`)) {
111
111
  const replicas = await fs.readdir(`./engine-private/replica`);
112
112
  for (const replica of replicas) {
113
+ if (!replica.match(deployId)) continue;
113
114
  shellExec(`node bin/deploy conf ${replica} ${env}`);
114
115
  shellExec(`npm ${runCmd} deploy deploy-id:${replica}`, { async: true });
115
- fs.writeFileSync(`./tmp/await-deploy`, '', 'utf8');
116
- const monitor = async () => {
117
- await timer(1000);
118
- if (fs.existsSync(`./tmp/await-deploy`)) return await monitor();
119
- };
120
- await monitor();
116
+ await awaitDeployMonitor(true);
121
117
  }
122
- shellExec(`node bin/deploy conf ${deployId} ${env}`);
123
118
  }
124
- shellExec(`npm ${runCmd} deploy deploy-id:${deployId}`);
119
+ shellExec(`node bin/deploy conf ${deployId} ${env}`);
120
+ shellExec(`npm ${runCmd} deploy deploy-id:${deployId}`, { async: true });
121
+ await awaitDeployMonitor(true);
122
+ await UnderpostMonitor.API.callback(deployId, env, { itc: true });
125
123
  }
126
124
  },
127
125
  },
@@ -0,0 +1,68 @@
1
+ import { loadReplicas, pathPortAssignmentFactory } from '../server/conf.js';
2
+ import { loggerFactory } from '../server/logger.js';
3
+ import UnderpostDeploy from './deploy.js';
4
+ import axios from 'axios';
5
+ import UnderpostRootEnv from './env.js';
6
+ import fs from 'fs-extra';
7
+ import { timer } from '../client/components/core/CommonJs.js';
8
+
9
+ const logger = loggerFactory(import.meta);
10
+
11
+ class UnderpostMonitor {
12
+ static API = {
13
+ async callback(deployId, env = 'development', options = { itc: false }) {
14
+ const router = await UnderpostDeploy.API.routerFactory(deployId, env);
15
+
16
+ const confServer = loadReplicas(
17
+ JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
18
+ 'proxy',
19
+ );
20
+
21
+ const pathPortAssignmentData = pathPortAssignmentFactory(router, confServer);
22
+
23
+ logger.info('', pathPortAssignmentData);
24
+
25
+ if (options.itc === true) {
26
+ const errorPayloads = [];
27
+ const maxAttempts = Object.keys(pathPortAssignmentData)
28
+ .map((host) => pathPortAssignmentData[host].length)
29
+ .reduce((accumulator, value) => accumulator + value, 0);
30
+
31
+ const monitor = async () => {
32
+ await timer(30000);
33
+ if (UnderpostRootEnv.API.get('running-job')) return await monitor();
34
+ for (const host of Object.keys(pathPortAssignmentData)) {
35
+ for (const instance of pathPortAssignmentData[host]) {
36
+ const { port, path } = instance;
37
+ if (path.match('peer') || path.match('socket')) continue;
38
+ const urlTest = `http://localhost:${port}${path}`;
39
+ logger.info('Test instance', urlTest);
40
+ await axios.get(urlTest, { timeout: 10000 }).catch((error) => {
41
+ // console.log(error);
42
+ const errorPayload = {
43
+ urlTest,
44
+ host,
45
+ port,
46
+ path,
47
+ name: error.name,
48
+ status: error.status,
49
+ code: error.code,
50
+ errors: error.errors,
51
+ };
52
+ if (errorPayload.status !== 404) {
53
+ errorPayloads.push(errorPayload);
54
+ if (errorPayloads.length >= maxAttempts) throw new Error(JSON.stringify(errorPayloads, null, 4));
55
+ logger.error('Error accumulator', errorPayloads.length);
56
+ }
57
+ });
58
+ }
59
+ }
60
+ await monitor();
61
+ };
62
+ await monitor();
63
+ }
64
+ },
65
+ };
66
+ }
67
+
68
+ export default UnderpostMonitor;
@@ -79,7 +79,7 @@ const Docs = {
79
79
  icon: html`<i class="fa-brands fa-osi"></i>`,
80
80
  text: 'Source Docs',
81
81
  url: function () {
82
- return `${getProxyPath()}docs/engine/${window.renderPayload.version}`;
82
+ return `${getProxyPath()}docs/engine/${window.renderPayload.version.replace('v', '')}`;
83
83
  },
84
84
  },
85
85
  {
package/src/index.js CHANGED
@@ -11,6 +11,7 @@ import UnderpostDeploy from './cli/deploy.js';
11
11
  import UnderpostRootEnv from './cli/env.js';
12
12
  import UnderpostFileStorage from './cli/fs.js';
13
13
  import UnderpostImage from './cli/image.js';
14
+ import UnderpostMonitor from './cli/monitor.js';
14
15
  import UnderpostRepository from './cli/repository.js';
15
16
  import UnderpostScript from './cli/script.js';
16
17
  import UnderpostSecret from './cli/secrets.js';
@@ -28,7 +29,7 @@ class Underpost {
28
29
  * @type {String}
29
30
  * @memberof Underpost
30
31
  */
31
- static version = 'v2.8.622';
32
+ static version = 'v2.8.635';
32
33
  /**
33
34
  * Repository cli API
34
35
  * @static
@@ -106,6 +107,13 @@ class Underpost {
106
107
  * @memberof UnderpostFileStorage
107
108
  */
108
109
  static fs = UnderpostFileStorage.API;
110
+ /**
111
+ * Monitor cli API
112
+ * @static
113
+ * @type {UnderpostMonitor.API}
114
+ * @memberof UnderpostMonitor
115
+ */
116
+ static monitor = UnderpostMonitor.API;
109
117
  }
110
118
 
111
119
  const up = Underpost;
@@ -499,6 +499,40 @@ const buildProxyRouter = () => {
499
499
  return proxyRouter;
500
500
  };
501
501
 
502
+ const pathPortAssignmentFactory = (router, confServer) => {
503
+ const pathPortAssignmentData = {};
504
+ for (const host of Object.keys(confServer)) {
505
+ const pathPortAssignment = [];
506
+ for (const path of Object.keys(confServer[host])) {
507
+ const { peer } = confServer[host][path];
508
+ if (!router[`${host}${path === '/' ? '' : path}`]) continue;
509
+ const port = parseInt(router[`${host}${path === '/' ? '' : path}`].split(':')[2]);
510
+ // logger.info('', { host, port, path });
511
+ pathPortAssignment.push({
512
+ port,
513
+ path,
514
+ });
515
+
516
+ if (peer) {
517
+ // logger.info('', { host, port: port + 1, path: '/peer' });
518
+ pathPortAssignment.push({
519
+ port: port + 1,
520
+ path: '/peer',
521
+ });
522
+ }
523
+ }
524
+ pathPortAssignmentData[host] = pathPortAssignment;
525
+ }
526
+ return pathPortAssignmentData;
527
+ };
528
+
529
+ const deployRangePortFactory = (router) => {
530
+ const ports = Object.values(router).map((p) => parseInt(p.split(':')[2]));
531
+ const fromPort = Math.min(...ports);
532
+ const toPort = Math.max(...ports);
533
+ return { ports, fromPort, toPort };
534
+ };
535
+
502
536
  const buildKindPorts = (from, to) =>
503
537
  range(parseInt(from), parseInt(to))
504
538
  .map(
@@ -729,7 +763,7 @@ const validateTemplatePath = (absolutePath = '') => {
729
763
  return true;
730
764
  };
731
765
 
732
- const deployTest = async (dataDeploy) => {
766
+ const deployTest = async (dataDeploy = [{ deployId: 'default' }]) => {
733
767
  const failed = [];
734
768
  for (const deploy of dataDeploy) {
735
769
  const deployServerConfPath = fs.existsSync(`./engine-private/replica/${deploy.deployId}/conf.server.json`)
@@ -773,6 +807,12 @@ const deployTest = async (dataDeploy) => {
773
807
  return { failed };
774
808
  };
775
809
 
810
+ const awaitDeployMonitor = async (init = false, deltaMs = 1000) => {
811
+ if (init) fs.writeFileSync(`./tmp/await-deploy`, '', 'utf8');
812
+ await timer(deltaMs);
813
+ if (fs.existsSync(`./tmp/await-deploy`)) return await awaitDeployMonitor();
814
+ };
815
+
776
816
  const getDeployGroupId = () => {
777
817
  const deployGroupIndexArg = process.argv.findIndex((a) => a.match(`deploy-group:`));
778
818
  if (deployGroupIndexArg > -1) return process.argv[deployGroupIndexArg].split(':')[1].trim();
@@ -1122,4 +1162,8 @@ export {
1122
1162
  getNpmRootPath,
1123
1163
  getUnderpostRootPath,
1124
1164
  writeEnv,
1165
+ deployTest,
1166
+ pathPortAssignmentFactory,
1167
+ deployRangePortFactory,
1168
+ awaitDeployMonitor,
1125
1169
  };