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 +8 -0
- package/docker-compose.yml +1 -1
- package/package.json +1 -1
- package/src/cli/deploy.js +8 -27
- package/src/cli/image.js +37 -39
- package/src/cli/monitor.js +68 -0
- package/src/client/components/core/Docs.js +1 -1
- package/src/index.js +9 -1
- package/src/server/conf.js +45 -1
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();
|
package/docker-compose.yml
CHANGED
package/package.json
CHANGED
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
|
|
145
|
-
|
|
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
|
|
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
|
-
|
|
74
|
-
default:
|
|
75
|
-
{
|
|
72
|
+
switch (deployId) {
|
|
73
|
+
default:
|
|
76
74
|
{
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
83
|
+
`,
|
|
84
|
+
),
|
|
85
|
+
'utf8',
|
|
86
|
+
);
|
|
87
|
+
}
|
|
89
88
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
96
|
+
` port: 6379,
|
|
98
97
|
host: 'service-valkey.default.svc.cluster.local',`,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
),
|
|
99
|
+
'utf8',
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
102
|
}
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
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(`
|
|
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.
|
|
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;
|
package/src/server/conf.js
CHANGED
|
@@ -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
|
};
|