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.
- package/Dockerfile +9 -10
- package/bin/build.js +2 -2
- package/bin/deploy.js +40 -2
- package/bin/index.js +39 -18
- package/docker-compose.yml +1 -1
- package/package.json +2 -9
- package/src/api/default/default.service.js +1 -1
- package/src/api/user/user.service.js +14 -11
- package/src/cli/cluster.js +45 -2
- package/src/cli/cron.js +39 -8
- package/src/cli/db.js +18 -8
- package/src/cli/deploy.js +173 -80
- package/src/cli/fs.js +7 -6
- package/src/cli/image.js +39 -101
- package/src/cli/monitor.js +182 -0
- package/src/cli/repository.js +5 -2
- package/src/client/components/core/Account.js +28 -24
- package/src/client/components/core/Blockchain.js +1 -1
- package/src/client/components/core/CalendarCore.js +14 -84
- package/src/client/components/core/CommonJs.js +2 -1
- package/src/client/components/core/Css.js +0 -1
- package/src/client/components/core/CssCore.js +10 -2
- package/src/client/components/core/Docs.js +1 -1
- package/src/client/components/core/EventsUI.js +3 -3
- package/src/client/components/core/FileExplorer.js +86 -78
- package/src/client/components/core/LoadingAnimation.js +1 -17
- package/src/client/components/core/LogIn.js +3 -3
- package/src/client/components/core/LogOut.js +1 -1
- package/src/client/components/core/Modal.js +12 -7
- package/src/client/components/core/Panel.js +19 -61
- package/src/client/components/core/PanelForm.js +13 -22
- package/src/client/components/core/Recover.js +3 -3
- package/src/client/components/core/RichText.js +1 -11
- package/src/client/components/core/Router.js +3 -1
- package/src/client/components/core/SignUp.js +2 -2
- package/src/client/components/default/RoutesDefault.js +3 -2
- package/src/client/services/default/default.management.js +45 -38
- package/src/client/ssr/Render.js +2 -0
- package/src/index.js +18 -2
- package/src/mailer/MailerProvider.js +3 -0
- package/src/runtime/lampp/Dockerfile +65 -0
- package/src/server/conf.js +89 -1
- package/src/server/dns.js +9 -1
- package/src/server/json-schema.js +77 -0
- package/src/server/network.js +7 -122
- package/src/server/peer.js +2 -2
- package/src/server/proxy.js +4 -4
- package/src/server/runtime.js +22 -11
- package/src/server/start.js +123 -0
- package/src/server/valkey.js +25 -11
package/src/cli/deploy.js
CHANGED
|
@@ -3,22 +3,41 @@ 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';
|
|
11
13
|
import fs from 'fs-extra';
|
|
12
14
|
import dotenv from 'dotenv';
|
|
13
|
-
import
|
|
15
|
+
import { DataBaseProvider } from '../db/DataBaseProvider.js';
|
|
16
|
+
import UnderpostRootEnv from './env.js';
|
|
17
|
+
import UnderpostCluster from './cluster.js';
|
|
14
18
|
|
|
15
19
|
const logger = loggerFactory(import.meta);
|
|
16
20
|
|
|
17
21
|
class UnderpostDeploy {
|
|
22
|
+
static NETWORK = {};
|
|
18
23
|
static API = {
|
|
19
|
-
sync(deployList) {
|
|
24
|
+
sync(deployList, { versions, replicas }) {
|
|
20
25
|
const deployGroupId = 'dd.tmp';
|
|
21
26
|
fs.writeFileSync(`./engine-private/deploy/${deployGroupId}`, deployList, 'utf8');
|
|
27
|
+
const totalPods = deployList.split(',').length * versions.split(',').length * parseInt(replicas);
|
|
28
|
+
const limitFactor = 0.95;
|
|
29
|
+
const reserveFactor = 0.35;
|
|
30
|
+
const resources = UnderpostCluster.API.getResourcesCapacity();
|
|
31
|
+
const memory = parseInt(resources.memory.value / totalPods);
|
|
32
|
+
const cpu = parseInt(resources.cpu.value / totalPods);
|
|
33
|
+
UnderpostRootEnv.API.set(
|
|
34
|
+
'resources.requests.memory',
|
|
35
|
+
`${parseInt(memory * reserveFactor)}${resources.memory.unit}`,
|
|
36
|
+
);
|
|
37
|
+
UnderpostRootEnv.API.set('resources.requests.cpu', `${parseInt(cpu * reserveFactor)}${resources.cpu.unit}`);
|
|
38
|
+
UnderpostRootEnv.API.set('resources.limits.memory', `${parseInt(memory * limitFactor)}${resources.memory.unit}`);
|
|
39
|
+
UnderpostRootEnv.API.set('resources.limits.cpu', `${parseInt(cpu * limitFactor)}${resources.cpu.unit}`);
|
|
40
|
+
UnderpostRootEnv.API.set('total-pods', totalPods);
|
|
22
41
|
return getDataDeploy({
|
|
23
42
|
buildSingleReplica: true,
|
|
24
43
|
deployGroupId,
|
|
@@ -32,59 +51,51 @@ class UnderpostDeploy {
|
|
|
32
51
|
await Config.build(undefined, 'proxy', deployList);
|
|
33
52
|
return buildPortProxyRouter(env === 'development' ? 80 : 443, buildProxyRouter());
|
|
34
53
|
},
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
fs.mkdirSync(`./engine-private/conf/${deployId}/build/${env}`, { recursive: true });
|
|
50
|
-
if (env === 'development') fs.mkdirSync(`./manifests/deployment/${deployId}-${env}`, { recursive: true });
|
|
51
|
-
|
|
52
|
-
logger.info('port range', { deployId, fromPort, toPort });
|
|
53
|
-
// const customImg = `underpost-engine:${version && typeof version === 'string' ? version : Underpost.version}`;
|
|
54
|
-
const deploymentYamlParts = `apiVersion: apps/v1
|
|
54
|
+
deploymentYamlServiceFactory({ deployId, env, port, deploymentVersions }) {
|
|
55
|
+
return deploymentVersions
|
|
56
|
+
.map(
|
|
57
|
+
(version, i) => ` - name: ${deployId}-${env}-${version}-service
|
|
58
|
+
port: ${port}
|
|
59
|
+
weight: ${i === 0 ? 100 : 0}
|
|
60
|
+
`,
|
|
61
|
+
)
|
|
62
|
+
.join('');
|
|
63
|
+
},
|
|
64
|
+
deploymentYamlPartsFactory({ deployId, env, suffix, resources, replicas }) {
|
|
65
|
+
return `apiVersion: apps/v1
|
|
55
66
|
kind: Deployment
|
|
56
67
|
metadata:
|
|
57
|
-
name: ${deployId}-${env}
|
|
68
|
+
name: ${deployId}-${env}-${suffix}
|
|
58
69
|
labels:
|
|
59
|
-
app: ${deployId}-${env}
|
|
70
|
+
app: ${deployId}-${env}-${suffix}
|
|
60
71
|
spec:
|
|
61
|
-
replicas:
|
|
72
|
+
replicas: ${replicas}
|
|
62
73
|
selector:
|
|
63
74
|
matchLabels:
|
|
64
|
-
app: ${deployId}-${env}
|
|
75
|
+
app: ${deployId}-${env}-${suffix}
|
|
65
76
|
template:
|
|
66
77
|
metadata:
|
|
67
78
|
labels:
|
|
68
|
-
app: ${deployId}-${env}
|
|
79
|
+
app: ${deployId}-${env}-${suffix}
|
|
69
80
|
spec:
|
|
70
81
|
containers:
|
|
71
|
-
- name: ${deployId}-${env}
|
|
82
|
+
- name: ${deployId}-${env}-${suffix}
|
|
72
83
|
image: localhost/debian:underpost
|
|
84
|
+
resources:
|
|
85
|
+
requests:
|
|
86
|
+
memory: "${resources.requests.memory}"
|
|
87
|
+
cpu: "${resources.requests.cpu}"
|
|
88
|
+
limits:
|
|
89
|
+
memory: "${resources.limits.memory}"
|
|
90
|
+
cpu: "${resources.limits.cpu}"
|
|
73
91
|
command:
|
|
74
92
|
- /bin/sh
|
|
75
93
|
- -c
|
|
76
94
|
- >
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
command:
|
|
82
|
-
- /bin/sh
|
|
83
|
-
- -c
|
|
84
|
-
- >
|
|
85
|
-
sleep 20 &&
|
|
86
|
-
npm install -g underpost
|
|
87
|
-
underpost secret underpost --create-from-file /etc/config/.env.${env}
|
|
95
|
+
npm install -g npm@11.2.0 &&
|
|
96
|
+
npm install -g underpost &&
|
|
97
|
+
underpost secret underpost --create-from-file /etc/config/.env.${env} &&
|
|
98
|
+
underpost start --build --run ${deployId} ${env}
|
|
88
99
|
volumeMounts:
|
|
89
100
|
- name: config-volume
|
|
90
101
|
mountPath: /etc/config
|
|
@@ -92,27 +103,50 @@ spec:
|
|
|
92
103
|
- name: config-volume
|
|
93
104
|
configMap:
|
|
94
105
|
name: underpost-config
|
|
95
|
-
# image: localhost/${deployId}-${env}:${version && typeof version === 'string' ? version : Underpost.version}
|
|
96
106
|
---
|
|
97
107
|
apiVersion: v1
|
|
98
108
|
kind: Service
|
|
99
109
|
metadata:
|
|
100
|
-
name: ${deployId}-${env}-service
|
|
110
|
+
name: ${deployId}-${env}-${suffix}-service
|
|
101
111
|
spec:
|
|
102
112
|
selector:
|
|
103
|
-
app: ${deployId}-${env}
|
|
113
|
+
app: ${deployId}-${env}-${suffix}
|
|
104
114
|
ports:
|
|
105
|
-
type: LoadBalancer
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
115
|
+
{{ports}} type: LoadBalancer`;
|
|
116
|
+
},
|
|
117
|
+
async buildManifest(deployList, env, options) {
|
|
118
|
+
const resources = UnderpostDeploy.API.resourcesFactory();
|
|
119
|
+
const replicas = options.replicas;
|
|
110
120
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
121
|
+
for (const _deployId of deployList.split(',')) {
|
|
122
|
+
const deployId = _deployId.trim();
|
|
123
|
+
if (!deployId) continue;
|
|
124
|
+
const confServer = loadReplicas(
|
|
125
|
+
JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
|
|
126
|
+
'proxy',
|
|
115
127
|
);
|
|
128
|
+
const router = await UnderpostDeploy.API.routerFactory(deployId, env);
|
|
129
|
+
const pathPortAssignmentData = pathPortAssignmentFactory(router, confServer);
|
|
130
|
+
const { fromPort, toPort } = deployRangePortFactory(router);
|
|
131
|
+
const deploymentVersions = options.versions.split(',');
|
|
132
|
+
fs.mkdirSync(`./engine-private/conf/${deployId}/build/${env}`, { recursive: true });
|
|
133
|
+
if (env === 'development') fs.mkdirSync(`./manifests/deployment/${deployId}-${env}`, { recursive: true });
|
|
134
|
+
|
|
135
|
+
logger.info('port range', { deployId, fromPort, toPort });
|
|
136
|
+
|
|
137
|
+
let deploymentYamlParts = '';
|
|
138
|
+
for (const deploymentVersion of deploymentVersions) {
|
|
139
|
+
deploymentYamlParts += `---
|
|
140
|
+
${UnderpostDeploy.API.deploymentYamlPartsFactory({
|
|
141
|
+
deployId,
|
|
142
|
+
env,
|
|
143
|
+
suffix: deploymentVersion,
|
|
144
|
+
resources,
|
|
145
|
+
replicas,
|
|
146
|
+
}).replace('{{ports}}', buildKindPorts(fromPort, toPort))}
|
|
147
|
+
`;
|
|
148
|
+
}
|
|
149
|
+
fs.writeFileSync(`./engine-private/conf/${deployId}/build/${env}/deployment.yaml`, deploymentYamlParts, 'utf8');
|
|
116
150
|
|
|
117
151
|
let proxyYaml = '';
|
|
118
152
|
let secretYaml = '';
|
|
@@ -134,27 +168,8 @@ spec:
|
|
|
134
168
|
kind: ClusterIssuer
|
|
135
169
|
secretName: ${host}`;
|
|
136
170
|
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
const { peer } = confServer[host][path];
|
|
140
|
-
if (!router[`${host}${path === '/' ? '' : path}`]) continue;
|
|
141
|
-
const port = parseInt(router[`${host}${path === '/' ? '' : path}`].split(':')[2]);
|
|
142
|
-
// logger.info('', { host, port, path });
|
|
143
|
-
pathPortConditions.push({
|
|
144
|
-
port,
|
|
145
|
-
path,
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
if (peer) {
|
|
149
|
-
// logger.info('', { host, port: port + 1, path: '/peer' });
|
|
150
|
-
pathPortConditions.push({
|
|
151
|
-
port: port + 1,
|
|
152
|
-
path: '/peer',
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// logger.info('', { host, pathPortConditions });
|
|
171
|
+
const pathPortAssignment = pathPortAssignmentData[host];
|
|
172
|
+
// logger.info('', { host, pathPortAssignment });
|
|
158
173
|
proxyYaml += `
|
|
159
174
|
---
|
|
160
175
|
apiVersion: projectcontour.io/v1
|
|
@@ -171,15 +186,20 @@ spec:
|
|
|
171
186
|
secretName: ${host}`
|
|
172
187
|
}
|
|
173
188
|
routes:`;
|
|
174
|
-
for (const conditionObj of
|
|
189
|
+
for (const conditionObj of pathPortAssignment) {
|
|
175
190
|
const { path, port } = conditionObj;
|
|
176
191
|
proxyYaml += `
|
|
177
192
|
- conditions:
|
|
178
193
|
- prefix: ${path}
|
|
179
194
|
enableWebsockets: true
|
|
180
195
|
services:
|
|
181
|
-
|
|
182
|
-
|
|
196
|
+
${UnderpostDeploy.API.deploymentYamlServiceFactory({
|
|
197
|
+
deployId,
|
|
198
|
+
env,
|
|
199
|
+
port,
|
|
200
|
+
deploymentVersions:
|
|
201
|
+
options.traffic && typeof options.traffic === 'string' ? options.traffic.split(',') : ['blue'],
|
|
202
|
+
})}`;
|
|
183
203
|
}
|
|
184
204
|
}
|
|
185
205
|
const yamlPath = `./engine-private/conf/${deployId}/build/${env}/proxy.yaml`;
|
|
@@ -211,7 +231,10 @@ spec:
|
|
|
211
231
|
infoUtil: false,
|
|
212
232
|
expose: false,
|
|
213
233
|
cert: false,
|
|
214
|
-
|
|
234
|
+
versions: '',
|
|
235
|
+
traffic: '',
|
|
236
|
+
dashboardUpdate: false,
|
|
237
|
+
replicas: '',
|
|
215
238
|
},
|
|
216
239
|
) {
|
|
217
240
|
if (options.infoUtil === true)
|
|
@@ -222,10 +245,13 @@ kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
|
|
|
222
245
|
`);
|
|
223
246
|
if (deployList === 'dd' && fs.existsSync(`./engine-private/deploy/dd.router`))
|
|
224
247
|
deployList = fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8');
|
|
225
|
-
if (options.
|
|
226
|
-
if (options.
|
|
227
|
-
if (options.
|
|
228
|
-
|
|
248
|
+
if (!(options.versions && typeof options.versions === 'string')) options.versions = 'blue,green';
|
|
249
|
+
if (!options.replicas) options.replicas = 2;
|
|
250
|
+
if (options.sync) UnderpostDeploy.API.sync(deployList, options);
|
|
251
|
+
if (options.buildManifest === true) await UnderpostDeploy.API.buildManifest(deployList, env, options);
|
|
252
|
+
if (options.infoRouter === true) logger.info('router', await UnderpostDeploy.API.routerFactory(deployList, env));
|
|
253
|
+
if (options.dashboardUpdate === true) await UnderpostDeploy.API.updateDashboardData(deployList, env, options);
|
|
254
|
+
if (options.infoRouter === true) return;
|
|
229
255
|
shellExec(`kubectl delete configmap underpost-config`);
|
|
230
256
|
shellExec(
|
|
231
257
|
`kubectl create configmap underpost-config --from-file=/home/dd/engine/engine-private/conf/dd-cron/.env.${env}`,
|
|
@@ -328,6 +354,73 @@ kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
|
|
|
328
354
|
|
|
329
355
|
return result;
|
|
330
356
|
},
|
|
357
|
+
resourcesFactory() {
|
|
358
|
+
return {
|
|
359
|
+
requests: {
|
|
360
|
+
memory: UnderpostRootEnv.API.get('resources.requests.memory'),
|
|
361
|
+
cpu: UnderpostRootEnv.API.get('resources.requests.cpu'),
|
|
362
|
+
},
|
|
363
|
+
limits: {
|
|
364
|
+
memory: UnderpostRootEnv.API.get('resources.limits.memory'),
|
|
365
|
+
cpu: UnderpostRootEnv.API.get('resources.limits.cpu'),
|
|
366
|
+
},
|
|
367
|
+
totalPods: UnderpostRootEnv.API.get('total-pods'),
|
|
368
|
+
};
|
|
369
|
+
},
|
|
370
|
+
async updateDashboardData(deployList, env, options) {
|
|
371
|
+
try {
|
|
372
|
+
const deployId = process.env.DEFAULT_DEPLOY_ID;
|
|
373
|
+
const host = process.env.DEFAULT_DEPLOY_HOST;
|
|
374
|
+
const path = process.env.DEFAULT_DEPLOY_PATH;
|
|
375
|
+
const { db } = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'))[host][
|
|
376
|
+
path
|
|
377
|
+
];
|
|
378
|
+
|
|
379
|
+
await DataBaseProvider.load({ apis: ['instance'], host, path, db });
|
|
380
|
+
|
|
381
|
+
/** @type {import('../api/instance/instance.model.js').InstanceModel} */
|
|
382
|
+
const Instance = DataBaseProvider.instance[`${host}${path}`].mongoose.models.Instance;
|
|
383
|
+
|
|
384
|
+
await Instance.deleteMany();
|
|
385
|
+
|
|
386
|
+
for (const _deployId of deployList.split(',')) {
|
|
387
|
+
const deployId = _deployId.trim();
|
|
388
|
+
if (!deployId) continue;
|
|
389
|
+
const confServer = loadReplicas(
|
|
390
|
+
JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
|
|
391
|
+
'proxy',
|
|
392
|
+
);
|
|
393
|
+
const router = await UnderpostDeploy.API.routerFactory(deployId, env);
|
|
394
|
+
const pathPortAssignmentData = pathPortAssignmentFactory(router, confServer);
|
|
395
|
+
|
|
396
|
+
for (const host of Object.keys(confServer)) {
|
|
397
|
+
for (const { path, port } of pathPortAssignmentData[host]) {
|
|
398
|
+
if (!confServer[host][path]) continue;
|
|
399
|
+
|
|
400
|
+
const { client, runtime, apis } = confServer[host][path];
|
|
401
|
+
|
|
402
|
+
const body = {
|
|
403
|
+
deployId,
|
|
404
|
+
host,
|
|
405
|
+
path,
|
|
406
|
+
port,
|
|
407
|
+
client,
|
|
408
|
+
runtime,
|
|
409
|
+
apis,
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
logger.info('save', body);
|
|
413
|
+
|
|
414
|
+
await new Instance(body).save();
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
|
|
420
|
+
} catch (error) {
|
|
421
|
+
logger.error(error, error.stack);
|
|
422
|
+
}
|
|
423
|
+
},
|
|
331
424
|
};
|
|
332
425
|
}
|
|
333
426
|
|
package/src/cli/fs.js
CHANGED
|
@@ -38,7 +38,7 @@ class UnderpostFileStorage {
|
|
|
38
38
|
options = { rm: false, recursive: false, deployId: '', force: false, pull: false, git: false },
|
|
39
39
|
) {
|
|
40
40
|
const { storage, storageConf } = UnderpostFileStorage.API.getStorageConf(options);
|
|
41
|
-
const deleteFiles = UnderpostRepository.API.getDeleteFiles(path);
|
|
41
|
+
const deleteFiles = options.pull === true ? [] : UnderpostRepository.API.getDeleteFiles(path);
|
|
42
42
|
for (const relativePath of deleteFiles) {
|
|
43
43
|
const _path = path + '/' + relativePath;
|
|
44
44
|
if (_path in storage) {
|
|
@@ -46,10 +46,6 @@ class UnderpostFileStorage {
|
|
|
46
46
|
delete storage[_path];
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
const files =
|
|
50
|
-
options.git === true
|
|
51
|
-
? UnderpostRepository.API.getChangedFiles(path)
|
|
52
|
-
: await fs.readdir(path, { recursive: true });
|
|
53
49
|
if (options.pull === true) {
|
|
54
50
|
for (const _path of Object.keys(storage)) {
|
|
55
51
|
if (!fs.existsSync(_path) || options.force === true) {
|
|
@@ -57,7 +53,11 @@ class UnderpostFileStorage {
|
|
|
57
53
|
await UnderpostFileStorage.API.pull(_path, options);
|
|
58
54
|
} else logger.warn(`Pull path already exists`, _path);
|
|
59
55
|
}
|
|
60
|
-
} else
|
|
56
|
+
} else {
|
|
57
|
+
const files =
|
|
58
|
+
options.git === true
|
|
59
|
+
? UnderpostRepository.API.getChangedFiles(path)
|
|
60
|
+
: await fs.readdir(path, { recursive: true });
|
|
61
61
|
for (const relativePath of files) {
|
|
62
62
|
const _path = path + '/' + relativePath;
|
|
63
63
|
if (fs.statSync(_path).isDirectory()) {
|
|
@@ -68,6 +68,7 @@ class UnderpostFileStorage {
|
|
|
68
68
|
if (storage) storage[_path] = {};
|
|
69
69
|
} else logger.warn('File already exists', _path);
|
|
70
70
|
}
|
|
71
|
+
}
|
|
71
72
|
UnderpostFileStorage.API.writeStorageConf(storage, storageConf);
|
|
72
73
|
if (options.git === true) {
|
|
73
74
|
shellExec(`cd ${path} && git add .`);
|
package/src/cli/image.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
|
-
import Underpost from '../index.js';
|
|
3
2
|
import { shellCd, shellExec } from '../server/process.js';
|
|
4
3
|
import dotenv from 'dotenv';
|
|
5
|
-
import { getNpmRootPath } from '../server/conf.js';
|
|
6
|
-
import { timer } from '../client/components/core/CommonJs.js';
|
|
7
|
-
import UnderpostRootEnv from './env.js';
|
|
4
|
+
import { awaitDeployMonitor, getNpmRootPath } from '../server/conf.js';
|
|
8
5
|
import { loggerFactory } from '../server/logger.js';
|
|
6
|
+
import UnderpostMonitor from './monitor.js';
|
|
9
7
|
|
|
10
8
|
dotenv.config();
|
|
11
9
|
|
|
@@ -18,109 +16,49 @@ class UnderpostImage {
|
|
|
18
16
|
shellExec(`sudo podman pull docker.io/library/debian:buster`);
|
|
19
17
|
},
|
|
20
18
|
build(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
options = {
|
|
20
|
+
path: '',
|
|
21
|
+
imageName: '',
|
|
22
|
+
imagePath: '',
|
|
23
|
+
dockerfileName: '',
|
|
24
|
+
podmanSave: false,
|
|
25
|
+
kindLoad: false,
|
|
26
|
+
secrets: false,
|
|
27
|
+
secretsPath: '',
|
|
28
|
+
noCache: false,
|
|
29
|
+
},
|
|
25
30
|
) {
|
|
26
|
-
const
|
|
27
|
-
options
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
if (!fs.existsSync(`${path}${imagesStoragePath}`))
|
|
34
|
-
fs.mkdirSync(`${path}${imagesStoragePath}`, { recursive: true });
|
|
35
|
-
const tarFile = `.${imagesStoragePath}/${imgName.replace(':', '_')}.tar`;
|
|
36
|
-
|
|
37
|
-
let secrets = ' ';
|
|
31
|
+
const { path, imageName, imagePath, dockerfileName, podmanSave, secrets, secretsPath, kindLoad, noCache } =
|
|
32
|
+
options;
|
|
33
|
+
const podManImg = `localhost/${imageName}`;
|
|
34
|
+
if (imagePath && typeof imagePath === 'string' && !fs.existsSync(imagePath))
|
|
35
|
+
fs.mkdirSync(imagePath, { recursive: true });
|
|
36
|
+
const tarFile = `${imagePath}/${imageName.replace(':', '_')}.tar`;
|
|
37
|
+
let secretsInput = ' ';
|
|
38
38
|
let secretDockerInput = '';
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
let cache = '';
|
|
40
|
+
if (secrets === true) {
|
|
41
|
+
const envObj = dotenv.parse(
|
|
42
|
+
fs.readFileSync(
|
|
43
|
+
secretsPath && typeof secretsPath === 'string' ? secretsPath : `${getNpmRootPath()}/underpost/.env`,
|
|
44
|
+
'utf8',
|
|
45
|
+
),
|
|
46
|
+
);
|
|
47
|
+
for (const key of Object.keys(envObj)) {
|
|
48
|
+
secretsInput += ` && export ${key}="${envObj[key]}" `; // $(cat gitlab-token.txt)
|
|
49
|
+
secretDockerInput += ` --secret id=${key},env=${key} \ `;
|
|
50
|
+
}
|
|
46
51
|
}
|
|
47
|
-
|
|
48
|
-
if (
|
|
52
|
+
if (noCache === true) cache += ' --rm --no-cache';
|
|
53
|
+
if (path && typeof path === 'string')
|
|
49
54
|
shellExec(
|
|
50
|
-
`cd ${path}${
|
|
55
|
+
`cd ${path}${secretsInput}&& sudo podman build -f ./${
|
|
56
|
+
dockerfileName && typeof dockerfileName === 'string' ? dockerfileName : 'Dockerfile'
|
|
57
|
+
} -t ${imageName} --pull=never --cap-add=CAP_AUDIT_WRITE${cache}${secretDockerInput}`,
|
|
51
58
|
);
|
|
52
|
-
}
|
|
53
|
-
if (options.imageArchive !== true || options.podmanSave === true)
|
|
54
|
-
shellExec(`cd ${path} && podman save -o ${tarFile} ${podManImg}`);
|
|
55
|
-
shellExec(`cd ${path} && sudo kind load image-archive ${tarFile}`);
|
|
56
|
-
},
|
|
57
|
-
async script(deployId = 'default', env = 'development', options = { run: false, build: false }) {
|
|
58
|
-
if (options.build === true) {
|
|
59
|
-
const buildBasePath = `/home/dd`;
|
|
60
|
-
const repoName = `engine-${deployId.split('-')[1]}`;
|
|
61
|
-
shellExec(`cd ${buildBasePath} && underpost clone underpostnet/${repoName}`);
|
|
62
|
-
shellExec(`cd ${buildBasePath} && sudo mv ./${repoName} ./engine`);
|
|
63
|
-
shellExec(`cd ${buildBasePath}/engine && underpost clone underpostnet/${repoName}-private`);
|
|
64
|
-
shellExec(`cd ${buildBasePath}/engine && sudo mv ./${repoName}-private ./engine-private`);
|
|
65
|
-
shellCd(`${buildBasePath}/engine`);
|
|
66
|
-
shellExec(`underpost install`);
|
|
67
|
-
const itcScripts = fs.readdir('./engine-private/itc-scripts');
|
|
68
|
-
for (const itcScript of itcScripts)
|
|
69
|
-
if (itcScript.match(deployId)) shellExec(`node ./engine-private/itc-scripts/${itcScript}`);
|
|
70
|
-
}
|
|
71
|
-
switch (deployId) {
|
|
72
|
-
default:
|
|
73
|
-
{
|
|
74
|
-
{
|
|
75
|
-
const originPath = `./src/db/mongo/MongooseDB.js`;
|
|
76
|
-
fs.writeFileSync(
|
|
77
|
-
originPath,
|
|
78
|
-
fs.readFileSync(originPath, 'utf8').replaceAll(
|
|
79
|
-
`connect: async (host, name) => {`,
|
|
80
|
-
`connect: async (host, name) => {
|
|
81
|
-
host = 'mongodb://mongodb-0.mongodb-service:27017';
|
|
82
|
-
`,
|
|
83
|
-
),
|
|
84
|
-
'utf8',
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
59
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
fs.writeFileSync(
|
|
91
|
-
originPath,
|
|
92
|
-
fs.readFileSync(originPath, 'utf8').replaceAll(
|
|
93
|
-
` // port: 6379,
|
|
94
|
-
// host: 'service-valkey.default.svc.cluster.local',`,
|
|
95
|
-
` port: 6379,
|
|
96
|
-
host: 'service-valkey.default.svc.cluster.local',`,
|
|
97
|
-
),
|
|
98
|
-
'utf8',
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
shellExec(`node bin/deploy conf ${deployId} ${env}`);
|
|
105
|
-
shellExec(`node bin/deploy build-full-client ${deployId}`);
|
|
106
|
-
if (options.run === true) {
|
|
107
|
-
const runCmd = env === 'production' ? 'run prod-img' : 'run dev-img';
|
|
108
|
-
if (fs.existsSync(`./engine-private/replica`)) {
|
|
109
|
-
const replicas = await fs.readdir(`./engine-private/replica`);
|
|
110
|
-
for (const replica of replicas) {
|
|
111
|
-
shellExec(`node bin/deploy conf ${replica} ${env}`);
|
|
112
|
-
shellExec(`npm ${runCmd} deploy deploy-id:${replica}`, { async: true });
|
|
113
|
-
fs.writeFileSync(`./tmp/await-deploy`, '', 'utf8');
|
|
114
|
-
const monitor = async () => {
|
|
115
|
-
await timer(1000);
|
|
116
|
-
if (fs.existsSync(`./tmp/await-deploy`)) return await monitor();
|
|
117
|
-
};
|
|
118
|
-
await monitor();
|
|
119
|
-
}
|
|
120
|
-
shellExec(`node bin/deploy conf ${deployId} ${env}`);
|
|
121
|
-
}
|
|
122
|
-
shellExec(`npm ${runCmd} deploy deploy-id:${deployId}`);
|
|
123
|
-
}
|
|
60
|
+
if (podmanSave === true) shellExec(`podman save -o ${tarFile} ${podManImg}`);
|
|
61
|
+
if (kindLoad === true) shellExec(`sudo kind load image-archive ${tarFile}`);
|
|
124
62
|
},
|
|
125
63
|
},
|
|
126
64
|
};
|