underpost 2.8.47 → 2.8.51
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 +1 -1
- package/bin/build.js +32 -191
- package/bin/deploy.js +9 -28
- package/bin/index.js +19 -5
- package/bin/util.js +0 -8
- package/docker-compose.yml +1 -1
- package/manifests/mongodb/backup-cronjob.yaml +14 -12
- package/package.json +1 -1
- package/src/api/core/core.service.js +1 -1
- package/src/cli/cron.js +90 -0
- package/src/cli/deploy.js +183 -1
- package/src/cli/image.js +22 -3
- package/src/cli/repository.js +5 -13
- package/src/cli/test.js +7 -4
- package/src/client/components/core/CommonJs.js +9 -0
- package/src/client/components/core/Css.js +1 -0
- package/src/client/components/core/Modal.js +0 -1
- package/src/client/components/core/VanillaJs.js +0 -9
- package/src/client/components/core/Worker.js +34 -31
- package/src/index.js +9 -1
- package/src/server/backup.js +49 -93
- package/src/server/conf.js +58 -24
- package/src/server/dns.js +48 -65
- package/src/server/network.js +7 -4
- package/src/dns.js +0 -22
package/Dockerfile
CHANGED
package/bin/build.js
CHANGED
|
@@ -3,7 +3,7 @@ import { loggerFactory } from '../src/server/logger.js';
|
|
|
3
3
|
import { shellExec } from '../src/server/process.js';
|
|
4
4
|
import dotenv from 'dotenv';
|
|
5
5
|
import { getCapVariableName } from '../src/client/components/core/CommonJs.js';
|
|
6
|
-
import {
|
|
6
|
+
import { getPathsSSR } from '../src/server/conf.js';
|
|
7
7
|
|
|
8
8
|
const baseConfPath = './engine-private/conf/dd-cron/.env.production';
|
|
9
9
|
if (fs.existsSync(baseConfPath)) dotenv.config({ path: baseConfPath, override: true });
|
|
@@ -20,21 +20,13 @@ const logger = loggerFactory(import.meta);
|
|
|
20
20
|
const confName = process.argv[2];
|
|
21
21
|
const basePath = '../pwa-microservices-template';
|
|
22
22
|
const repoName = `engine-${confName.split('dd-')[1]}`;
|
|
23
|
-
const privateRepoName = `${repoName}-private`;
|
|
24
|
-
const privateRepoNameBackUp = `${repoName}-cron-backups`;
|
|
25
|
-
const gitPrivateUrl = `https://${process.env.GITHUB_TOKEN}@github.com/underpostnet/${privateRepoName}.git`;
|
|
26
|
-
const gitPrivateBackUpUrl = `https://${process.env.GITHUB_TOKEN}@github.com/underpostnet/${privateRepoNameBackUp}.git`;
|
|
27
23
|
|
|
28
24
|
logger.info('', {
|
|
29
25
|
confName,
|
|
30
26
|
repoName,
|
|
31
|
-
privateRepoName,
|
|
32
|
-
privateRepoNameBackUp,
|
|
33
27
|
basePath,
|
|
34
28
|
});
|
|
35
29
|
|
|
36
|
-
if (process.argv.includes('info')) process.exit(0);
|
|
37
|
-
|
|
38
30
|
if (process.argv.includes('clean')) {
|
|
39
31
|
if (fs.existsSync(`${basePath}/images`)) fs.copySync(`${basePath}/images`, `./images`);
|
|
40
32
|
shellExec(`cd ${basePath} && git checkout .`);
|
|
@@ -42,173 +34,40 @@ if (process.argv.includes('clean')) {
|
|
|
42
34
|
process.exit(0);
|
|
43
35
|
}
|
|
44
36
|
|
|
45
|
-
if (process.argv.includes('proxy')) {
|
|
46
|
-
const env = process.argv.includes('development') ? 'development' : 'production';
|
|
47
|
-
process.env.NODE_ENV = env;
|
|
48
|
-
process.env.PORT = process.env.NODE_ENV === 'development' ? 4000 : 3000;
|
|
49
|
-
process.argv[2] = 'proxy';
|
|
50
|
-
process.argv[3] = fs.readFileSync('./engine-private/deploy/dd-router', 'utf8').trim();
|
|
51
|
-
|
|
52
|
-
await Config.build();
|
|
53
|
-
process.env.NODE_ENV = 'production';
|
|
54
|
-
const router = buildPortProxyRouter(443, buildProxyRouter());
|
|
55
|
-
const confServer = JSON.parse(fs.readFileSync(`./engine-private/conf/${confName}/conf.server.json`, 'utf8'));
|
|
56
|
-
const confHosts = Object.keys(confServer);
|
|
57
|
-
|
|
58
|
-
for (const host of Object.keys(router)) {
|
|
59
|
-
if (!confHosts.find((_host) => host.match(_host))) {
|
|
60
|
-
delete router[host];
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const ports = Object.values(router).map((p) => p.split(':')[2]);
|
|
65
|
-
|
|
66
|
-
const fromPort = ports[0];
|
|
67
|
-
const toPort = ports[ports.length - 1];
|
|
68
|
-
|
|
69
|
-
logger.info('port range', { fromPort, toPort, router });
|
|
70
|
-
|
|
71
|
-
const deploymentYamlFilePath = `./engine-private/conf/${confName}/build/${env}/deployment.yaml`;
|
|
72
|
-
|
|
73
|
-
const deploymentYamlParts = fs.readFileSync(deploymentYamlFilePath, 'utf8').split('ports:');
|
|
74
|
-
deploymentYamlParts[1] =
|
|
75
|
-
buildKindPorts(fromPort, toPort) +
|
|
76
|
-
` type: LoadBalancer
|
|
77
|
-
`;
|
|
78
|
-
|
|
79
|
-
fs.writeFileSync(
|
|
80
|
-
deploymentYamlFilePath,
|
|
81
|
-
deploymentYamlParts.join(`ports:
|
|
82
|
-
`),
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
let proxyYaml = '';
|
|
86
|
-
let secretYaml = '';
|
|
87
|
-
|
|
88
|
-
for (const host of Object.keys(confServer)) {
|
|
89
|
-
if (env === 'production')
|
|
90
|
-
secretYaml += `
|
|
91
|
-
---
|
|
92
|
-
apiVersion: cert-manager.io/v1
|
|
93
|
-
kind: Certificate
|
|
94
|
-
metadata:
|
|
95
|
-
name: ${host}
|
|
96
|
-
spec:
|
|
97
|
-
commonName: ${host}
|
|
98
|
-
dnsNames:
|
|
99
|
-
- ${host}
|
|
100
|
-
issuerRef:
|
|
101
|
-
name: letsencrypt-prod
|
|
102
|
-
kind: ClusterIssuer
|
|
103
|
-
secretName: ${host}`;
|
|
104
|
-
|
|
105
|
-
const pathPortConditions = [];
|
|
106
|
-
for (const path of Object.keys(confServer[host])) {
|
|
107
|
-
const { peer } = confServer[host][path];
|
|
108
|
-
const port = parseInt(router[`${host}${path === '/' ? '' : path}`].split(':')[2]);
|
|
109
|
-
// logger.info('', { host, port, path });
|
|
110
|
-
pathPortConditions.push({
|
|
111
|
-
port,
|
|
112
|
-
path,
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
if (peer) {
|
|
116
|
-
// logger.info('', { host, port: port + 1, path: '/peer' });
|
|
117
|
-
pathPortConditions.push({
|
|
118
|
-
port: port + 1,
|
|
119
|
-
path: '/peer',
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
// logger.info('', { host, pathPortConditions });
|
|
124
|
-
proxyYaml += `
|
|
125
|
-
---
|
|
126
|
-
apiVersion: projectcontour.io/v1
|
|
127
|
-
kind: HTTPProxy
|
|
128
|
-
metadata:
|
|
129
|
-
name: ${host}
|
|
130
|
-
spec:
|
|
131
|
-
virtualhost:
|
|
132
|
-
fqdn: ${host}${
|
|
133
|
-
env === 'development'
|
|
134
|
-
? ''
|
|
135
|
-
: `
|
|
136
|
-
tls:
|
|
137
|
-
secretName: ${host}`
|
|
138
|
-
}
|
|
139
|
-
routes:`;
|
|
140
|
-
for (const conditionObj of pathPortConditions) {
|
|
141
|
-
const { path, port } = conditionObj;
|
|
142
|
-
proxyYaml += `
|
|
143
|
-
- conditions:
|
|
144
|
-
- prefix: ${path}
|
|
145
|
-
enableWebsockets: true
|
|
146
|
-
services:
|
|
147
|
-
- name: ${confName}-${env}-service
|
|
148
|
-
port: ${port}`;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
const yamlPath = `./engine-private/conf/${confName}/build/${env}/proxy.yaml`;
|
|
152
|
-
fs.writeFileSync(yamlPath, proxyYaml, 'utf8');
|
|
153
|
-
if (env === 'production') {
|
|
154
|
-
const yamlPath = `./engine-private/conf/${confName}/build/${env}/secret.yaml`;
|
|
155
|
-
fs.writeFileSync(yamlPath, secretYaml, 'utf8');
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
process.exit(0);
|
|
159
|
-
}
|
|
160
37
|
if (process.argv.includes('conf')) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
` &&
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
shellExec(`cd ../${privateRepoNameBackUp} && git pull`);
|
|
184
|
-
}
|
|
185
|
-
const serverConf = JSON.parse(fs.readFileSync(`./engine-private/conf/${confName}/conf.server.json`, 'utf8'));
|
|
186
|
-
for (const host of Object.keys(serverConf)) {
|
|
187
|
-
for (let path of Object.keys(serverConf[host])) {
|
|
188
|
-
path = path.replaceAll('/', '-');
|
|
189
|
-
const toPath = `../${privateRepoNameBackUp}/${host}${path}`;
|
|
190
|
-
const fromPath = `./engine-private/cron-backups/${host}${path}`;
|
|
191
|
-
if (fs.existsSync(fromPath)) {
|
|
192
|
-
if (fs.existsSync(toPath)) fs.removeSync(toPath);
|
|
193
|
-
logger.info('Build', { fromPath, toPath });
|
|
194
|
-
fs.copySync(fromPath, toPath);
|
|
195
|
-
}
|
|
38
|
+
for (const _confName of (confName === 'dd'
|
|
39
|
+
? fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8')
|
|
40
|
+
: confName
|
|
41
|
+
).split(',')) {
|
|
42
|
+
const _repoName = `engine-${_confName.split('dd-')[1]}`;
|
|
43
|
+
const privateRepoName = `${_repoName}-private`;
|
|
44
|
+
const privateGitUri = `${process.env.GITHUB_USERNAME}/${privateRepoName}`;
|
|
45
|
+
|
|
46
|
+
if (!fs.existsSync(`../${privateRepoName}`)) {
|
|
47
|
+
shellExec(`cd .. && underpost clone ${privateGitUri}`, { silent: true });
|
|
48
|
+
} else {
|
|
49
|
+
shellExec(`cd ../${privateRepoName} && underpost pull . ${privateGitUri}`);
|
|
50
|
+
}
|
|
51
|
+
const toPath = `../${privateRepoName}/conf/${_confName}`;
|
|
52
|
+
fs.removeSync(toPath);
|
|
53
|
+
fs.mkdirSync(toPath, { recursive: true });
|
|
54
|
+
fs.copySync(`./engine-private/conf/${_confName}`, toPath);
|
|
55
|
+
if (fs.existsSync(`./engine-private/replica`)) {
|
|
56
|
+
const replicas = await fs.readdir(`./engine-private/replica`);
|
|
57
|
+
for (const replica of replicas)
|
|
58
|
+
if (replica.match(_confName))
|
|
59
|
+
fs.copySync(`./engine-private/replica/${replica}`, `../${privateRepoName}/replica/${replica}`);
|
|
196
60
|
}
|
|
61
|
+
shellExec(
|
|
62
|
+
`cd ../${privateRepoName}` +
|
|
63
|
+
` && git add .` +
|
|
64
|
+
` && underpost cmt . ci engine-core-conf 'Update ${_confName} conf'` +
|
|
65
|
+
` && underpost push . ${privateGitUri}`,
|
|
66
|
+
);
|
|
197
67
|
}
|
|
198
|
-
shellExec(
|
|
199
|
-
`cd ../${privateRepoNameBackUp}` +
|
|
200
|
-
` && git add .` +
|
|
201
|
-
` && git commit -m "ci(engine-core-cron-backups): ⚙️ Update ${confName} cron backups"` +
|
|
202
|
-
` && git push`,
|
|
203
|
-
);
|
|
204
68
|
process.exit(0);
|
|
205
69
|
}
|
|
206
70
|
|
|
207
|
-
if (process.argv.includes('test')) {
|
|
208
|
-
fs.mkdirSync(`${basePath}/engine-private/conf`, { recursive: true });
|
|
209
|
-
fs.copySync(`./engine-private/conf/${confName}`, `${basePath}/engine-private/conf/${confName}`);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
71
|
const { DefaultConf } = await import(`../conf.${confName}.js`);
|
|
213
72
|
|
|
214
73
|
{
|
|
@@ -294,27 +153,9 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
|
|
|
294
153
|
const env = process.argv.includes('development') ? 'development' : 'production';
|
|
295
154
|
const deploymentsFiles = ['Dockerfile', 'proxy.yaml', 'deployment.yaml', 'secret.yaml'];
|
|
296
155
|
// remove engine-private of .dockerignore for local testing
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (!fs.existsSync(`./manifests/deployment/${confName}-${env}`))
|
|
302
|
-
fs.mkdirSync(`./manifests/deployment/${confName}-${env}`);
|
|
303
|
-
|
|
304
|
-
for (const file of deploymentsFiles) {
|
|
305
|
-
if (fs.existsSync(`./engine-private/conf/${confName}/build/${env}/${file}`)) {
|
|
306
|
-
fs.copyFileSync(`./engine-private/conf/${confName}/build/${env}/${file}`, `${basePath}/${file}`);
|
|
307
|
-
fs.copyFileSync(
|
|
308
|
-
`./engine-private/conf/${confName}/build/${env}/${file}`,
|
|
309
|
-
`./manifests/deployment/${confName}-${env}/${file}`,
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
} else {
|
|
314
|
-
for (const file of deploymentsFiles) {
|
|
315
|
-
if (fs.existsSync(`./manifests/deployment/${confName}-${env}/${file}`)) {
|
|
316
|
-
fs.copyFileSync(`./manifests/deployment/${confName}-${env}/${file}`, `${basePath}/${file}`);
|
|
317
|
-
}
|
|
156
|
+
for (const file of deploymentsFiles) {
|
|
157
|
+
if (fs.existsSync(`./manifests/deployment/${confName}-${env}/${file}`)) {
|
|
158
|
+
fs.copyFileSync(`./manifests/deployment/${confName}-${env}/${file}`, `${basePath}/${file}`);
|
|
318
159
|
}
|
|
319
160
|
}
|
|
320
161
|
}
|
package/bin/deploy.js
CHANGED
|
@@ -141,28 +141,7 @@ try {
|
|
|
141
141
|
loadConf(process.argv[3], process.argv[4]);
|
|
142
142
|
break;
|
|
143
143
|
}
|
|
144
|
-
case 'run':
|
|
145
|
-
{
|
|
146
|
-
if (process.argv.includes('replicas')) {
|
|
147
|
-
const deployGroupId = getDeployGroupId();
|
|
148
|
-
const dataDeploy = getDataDeploy({
|
|
149
|
-
deployId: process.argv[3],
|
|
150
|
-
buildSingleReplica: true,
|
|
151
|
-
deployGroupId,
|
|
152
|
-
});
|
|
153
|
-
if (fs.existsSync(`./tmp/await-deploy`)) fs.remove(`./tmp/await-deploy`);
|
|
154
|
-
await deployRun(dataDeploy);
|
|
155
|
-
} else {
|
|
156
|
-
loadConf(process.argv[3]);
|
|
157
|
-
shellExec(`npm start ${process.argv.includes('maintenance') ? 'maintenance' : ''}`);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
break;
|
|
161
144
|
|
|
162
|
-
case 'remove-await-deploy': {
|
|
163
|
-
if (fs.existsSync(`./tmp/await-deploy`)) fs.remove(`./tmp/await-deploy`);
|
|
164
|
-
break;
|
|
165
|
-
}
|
|
166
145
|
case 'new-nodejs-app':
|
|
167
146
|
{
|
|
168
147
|
const deployId = process.argv[3];
|
|
@@ -229,6 +208,7 @@ try {
|
|
|
229
208
|
break;
|
|
230
209
|
case 'build-full-client':
|
|
231
210
|
{
|
|
211
|
+
dotenv.config({ override: true });
|
|
232
212
|
if (!process.argv[3]) process.argv[3] = 'default';
|
|
233
213
|
const { deployId, folder } = loadConf(process.argv[3]);
|
|
234
214
|
|
|
@@ -254,7 +234,7 @@ try {
|
|
|
254
234
|
serverConf[host][path].replicas.map((replica) => buildReplicaId({ deployId, replica })),
|
|
255
235
|
);
|
|
256
236
|
|
|
257
|
-
shellExec(Cmd.replica(deployId, host, path));
|
|
237
|
+
// shellExec(Cmd.replica(deployId, host, path));
|
|
258
238
|
}
|
|
259
239
|
}
|
|
260
240
|
}
|
|
@@ -263,7 +243,7 @@ try {
|
|
|
263
243
|
await buildClient();
|
|
264
244
|
|
|
265
245
|
for (const replicaDeployId of deployIdSingleReplicas) {
|
|
266
|
-
shellExec(Cmd.conf(replicaDeployId));
|
|
246
|
+
shellExec(Cmd.conf(replicaDeployId, process.env.NODE_ENV));
|
|
267
247
|
shellExec(Cmd.build(replicaDeployId));
|
|
268
248
|
}
|
|
269
249
|
}
|
|
@@ -456,12 +436,13 @@ try {
|
|
|
456
436
|
case 'run-macro':
|
|
457
437
|
{
|
|
458
438
|
if (fs.existsSync(`./tmp/await-deploy`)) fs.remove(`./tmp/await-deploy`);
|
|
459
|
-
const dataDeploy = getDataDeploy({
|
|
439
|
+
const dataDeploy = getDataDeploy({
|
|
440
|
+
deployGroupId: process.argv[3],
|
|
441
|
+
buildSingleReplica: true,
|
|
442
|
+
deployIdConcat: ['dd-proxy', 'dd-cron'],
|
|
443
|
+
});
|
|
460
444
|
if (!process.argv[4]) await setUpProxyMaintenanceServer({ deployGroupId: process.argv[3] });
|
|
461
|
-
await deployRun(
|
|
462
|
-
process.argv[4] ? dataDeploy.filter((d) => d.deployId.match(process.argv[4])) : dataDeploy,
|
|
463
|
-
true,
|
|
464
|
-
);
|
|
445
|
+
await deployRun(process.argv[4] ? dataDeploy.filter((d) => d.deployId.match(process.argv[4])) : dataDeploy);
|
|
465
446
|
}
|
|
466
447
|
break;
|
|
467
448
|
|
package/bin/index.js
CHANGED
|
@@ -8,8 +8,8 @@ import { getNpmRootPath, loadConf } from '../src/server/conf.js';
|
|
|
8
8
|
import fs from 'fs-extra';
|
|
9
9
|
import { commitData } from '../src/client/components/core/CommonJs.js';
|
|
10
10
|
import UnderpostScript from '../src/cli/script.js';
|
|
11
|
-
import { shellExec } from '../src/server/process.js';
|
|
12
11
|
import UnderpostDB from '../src/cli/db.js';
|
|
12
|
+
import UnderpostCron from '../src/cli/cron.js';
|
|
13
13
|
|
|
14
14
|
const npmRoot = getNpmRootPath();
|
|
15
15
|
const underpostRoot = `${npmRoot}/underpost/.env`;
|
|
@@ -63,7 +63,7 @@ program
|
|
|
63
63
|
|
|
64
64
|
program
|
|
65
65
|
.command('env')
|
|
66
|
-
.argument('<deploy-id>',
|
|
66
|
+
.argument('<deploy-id>', `deploy configuration id, if 'clean' restore default`)
|
|
67
67
|
.argument('[env]', 'Optional environment, for default is production')
|
|
68
68
|
.description('Set environment variables files and conf related to <deploy-id>')
|
|
69
69
|
.action(loadConf);
|
|
@@ -99,9 +99,12 @@ program
|
|
|
99
99
|
|
|
100
100
|
program
|
|
101
101
|
.command('deploy')
|
|
102
|
-
.argument('<deploy-list>', 'Deploy id list, e.g. default-a,
|
|
102
|
+
.argument('<deploy-list>', 'Deploy id list, e.g. default-a,default-b')
|
|
103
103
|
.argument('[env]', 'Optional environment, for default is development')
|
|
104
104
|
.option('--remove', 'Delete deployments and services')
|
|
105
|
+
.option('--sync', 'Sync deployments env, ports, and replicas')
|
|
106
|
+
.option('--info-router', 'Display router structure')
|
|
107
|
+
.option('--build-manifest', 'Build kind yaml manifests: deployments, services, proxy and secrets')
|
|
105
108
|
.description('Manage deployment, for default deploy development pods')
|
|
106
109
|
.action(Underpost.deploy.callback);
|
|
107
110
|
|
|
@@ -124,6 +127,7 @@ program
|
|
|
124
127
|
.command('dockerfile-node-script')
|
|
125
128
|
.argument('<deploy-id>', 'Deploy configuration id')
|
|
126
129
|
.argument('[env]', 'Optional environment, for default is development')
|
|
130
|
+
.option('--run', 'Run custom entry point script')
|
|
127
131
|
.description('Dockerfile custom node build script')
|
|
128
132
|
.action(Underpost.image.dockerfile.script);
|
|
129
133
|
|
|
@@ -150,7 +154,7 @@ program
|
|
|
150
154
|
|
|
151
155
|
program
|
|
152
156
|
.command('db')
|
|
153
|
-
.argument('<deploy-list>', 'Deploy id list, e.g. default-a,
|
|
157
|
+
.argument('<deploy-list>', 'Deploy id list, e.g. default-a,default-b')
|
|
154
158
|
.option('--import', 'Import container backups from repositories')
|
|
155
159
|
.option('--export', 'Export container backups to repositories')
|
|
156
160
|
.description('Manage databases')
|
|
@@ -166,12 +170,22 @@ program
|
|
|
166
170
|
)
|
|
167
171
|
.action((...args) => Underpost.script[args[0]](args[1], args[2]));
|
|
168
172
|
|
|
173
|
+
program
|
|
174
|
+
.command('cron')
|
|
175
|
+
.argument('[deploy-list]', 'Deploy id list, e.g. default-a,default-b')
|
|
176
|
+
.argument('[job-list]', `Deploy id list, e.g. ${Object.keys(UnderpostCron.JOB)}, for default all available jobs`)
|
|
177
|
+
.option('--disable-kind-cluster', 'Disable kind cluster configuration')
|
|
178
|
+
.option('--init', 'Init cron jobs for cron job default deploy id')
|
|
179
|
+
.description('Cron jobs management')
|
|
180
|
+
.action(Underpost.cron.callback);
|
|
181
|
+
|
|
169
182
|
program
|
|
170
183
|
.command('test')
|
|
171
|
-
.argument('[deploy-list]', 'Deploy id list, e.g. default-a,
|
|
184
|
+
.argument('[deploy-list]', 'Deploy id list, e.g. default-a,default-b')
|
|
172
185
|
.description('Manage Test, for default run current underpost default test')
|
|
173
186
|
.option('--inside-container', 'Inside container execution context')
|
|
174
187
|
.option('--sh', 'Copy to clipboard, container entrypoint shell command')
|
|
188
|
+
.option('--logs', 'Display container logs')
|
|
175
189
|
.action(Underpost.test.callback);
|
|
176
190
|
|
|
177
191
|
program.parse();
|
package/bin/util.js
CHANGED
|
@@ -112,14 +112,6 @@ try {
|
|
|
112
112
|
fs.writeFileSync('b64-image', `data:image/jpg;base64,${fs.readFileSync(process.argv[3]).toString('base64')}`);
|
|
113
113
|
break;
|
|
114
114
|
|
|
115
|
-
case 'clean-env': {
|
|
116
|
-
shellExec(`git checkout package.json`);
|
|
117
|
-
shellExec(`git checkout .env.production`);
|
|
118
|
-
shellExec(`git checkout .env.development`);
|
|
119
|
-
shellExec(`git checkout .env.test`);
|
|
120
|
-
shellExec(`git checkout jsdoc.json`);
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
115
|
case 'get-keys': {
|
|
124
116
|
const sentence = fs.existsSync('./_')
|
|
125
117
|
? fs.readFileSync('./_', 'utf8')
|
package/docker-compose.yml
CHANGED
|
@@ -16,25 +16,27 @@ spec:
|
|
|
16
16
|
- -c
|
|
17
17
|
- |
|
|
18
18
|
# Perform backup
|
|
19
|
-
mongodump
|
|
19
|
+
mongodump --host=mongodb-service --port=27017 --out=/backup/$(date +\%Y-\%m-\%dT\%H-\%M-\%S)
|
|
20
20
|
# Remove backups older than 7 days
|
|
21
21
|
find /backup -type d -mtime +7 -exec rm -rf {} +
|
|
22
22
|
volumeMounts:
|
|
23
23
|
- name: backup-storage
|
|
24
24
|
mountPath: /backup
|
|
25
|
-
env:
|
|
26
|
-
- name: MONGO_INITDB_ROOT_USERNAME
|
|
27
|
-
valueFrom:
|
|
28
|
-
secretKeyRef:
|
|
29
|
-
name: mongodb-secret
|
|
30
|
-
key: username
|
|
31
|
-
- name: MONGO_INITDB_ROOT_PASSWORD
|
|
32
|
-
valueFrom:
|
|
33
|
-
secretKeyRef:
|
|
34
|
-
name: mongodb-secret
|
|
35
|
-
key: password
|
|
36
25
|
restartPolicy: Never
|
|
37
26
|
volumes:
|
|
38
27
|
- name: backup-storage
|
|
39
28
|
persistentVolumeClaim:
|
|
40
29
|
claimName: backup-pvc
|
|
30
|
+
# mongodump -u $MONGO_INITDB_ROOT_USERNAME -p $MONGO_INITDB_ROOT_PASSWORD --host=mongodb-service --port=27017 --out=/backup/$(date +\%Y-\%m-\%dT\%H-\%M-\%S)
|
|
31
|
+
|
|
32
|
+
# env:
|
|
33
|
+
# - name: MONGO_INITDB_ROOT_USERNAME
|
|
34
|
+
# valueFrom:
|
|
35
|
+
# secretKeyRef:
|
|
36
|
+
# name: mongodb-secret
|
|
37
|
+
# key: username
|
|
38
|
+
# - name: MONGO_INITDB_ROOT_PASSWORD
|
|
39
|
+
# valueFrom:
|
|
40
|
+
# secretKeyRef:
|
|
41
|
+
# name: mongodb-secret
|
|
42
|
+
# key: password
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@ const CoreService = {
|
|
|
9
9
|
/** @type {import('./core.model.js').CoreModel} */
|
|
10
10
|
const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Core;
|
|
11
11
|
if (req.path.startsWith('/sh')) {
|
|
12
|
-
if (req.body.
|
|
12
|
+
if (req.body.stdout) return shellExec(req.body.sh, { stdout: true });
|
|
13
13
|
shellExec(req.body.sh, { async: true });
|
|
14
14
|
return 'Command "' + req.body.sh + '" running';
|
|
15
15
|
}
|
package/src/cli/cron.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UnderpostCron CLI index module
|
|
3
|
+
* @module src/cli/cron.js
|
|
4
|
+
* @namespace UnderpostCron
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Underpost from '../index.js';
|
|
8
|
+
import BackUp from '../server/backup.js';
|
|
9
|
+
import { Cmd } from '../server/conf.js';
|
|
10
|
+
import Dns from '../server/dns.js';
|
|
11
|
+
import { netWorkCron, saveRuntimeCron } from '../server/network.js';
|
|
12
|
+
import { shellExec } from '../server/process.js';
|
|
13
|
+
import fs from 'fs-extra';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* UnderpostCron main module methods
|
|
17
|
+
* @class
|
|
18
|
+
* @memberof UnderpostCron
|
|
19
|
+
*/
|
|
20
|
+
class UnderpostCron {
|
|
21
|
+
static JOB = {
|
|
22
|
+
/**
|
|
23
|
+
* DNS cli API
|
|
24
|
+
* @static
|
|
25
|
+
* @type {Dns}
|
|
26
|
+
* @memberof UnderpostCron
|
|
27
|
+
*/
|
|
28
|
+
dns: Dns,
|
|
29
|
+
/**
|
|
30
|
+
* BackUp cli API
|
|
31
|
+
* @static
|
|
32
|
+
* @type {BackUp}
|
|
33
|
+
* @memberof UnderpostCron
|
|
34
|
+
*/
|
|
35
|
+
backup: BackUp,
|
|
36
|
+
};
|
|
37
|
+
static API = {
|
|
38
|
+
/**
|
|
39
|
+
* Run the cron jobs
|
|
40
|
+
* @static
|
|
41
|
+
* @param {String} deployList - Comma separated deploy ids
|
|
42
|
+
* @param {String} jobList - Comma separated job ids
|
|
43
|
+
* @return {void}
|
|
44
|
+
* @memberof UnderpostCron
|
|
45
|
+
*/
|
|
46
|
+
callback: async function (
|
|
47
|
+
deployList = 'default',
|
|
48
|
+
jobList = Object.keys(UnderpostCron.JOB),
|
|
49
|
+
options = { disableKindCluster: false, init: false },
|
|
50
|
+
) {
|
|
51
|
+
if (options.init === true) {
|
|
52
|
+
await Underpost.test.setUpInfo();
|
|
53
|
+
const jobDeployId = fs.readFileSync('./engine-private/deploy/dd.cron', 'utf8').trim();
|
|
54
|
+
deployList = fs.readFileSync('./engine-private/deploy/dd.router', 'utf8').trim();
|
|
55
|
+
const confCronConfig = JSON.parse(fs.readFileSync(`./engine-private/conf/${jobDeployId}/conf.cron.json`));
|
|
56
|
+
if (confCronConfig.jobs && Object.keys(confCronConfig.jobs).length > 0) {
|
|
57
|
+
for (const job of Object.keys(confCronConfig.jobs)) {
|
|
58
|
+
const name = `${jobDeployId}-${job}`;
|
|
59
|
+
let deployId;
|
|
60
|
+
shellExec(Cmd.delete(name));
|
|
61
|
+
switch (job) {
|
|
62
|
+
case 'dns':
|
|
63
|
+
deployId = jobDeployId;
|
|
64
|
+
break;
|
|
65
|
+
|
|
66
|
+
default:
|
|
67
|
+
deployId = deployList;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
shellExec(Cmd.cron(deployId, job, name, confCronConfig.jobs[job].expression, options));
|
|
71
|
+
netWorkCron.push({
|
|
72
|
+
deployId,
|
|
73
|
+
jobId: job,
|
|
74
|
+
expression: confCronConfig.jobs[job].expression,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
await saveRuntimeCron();
|
|
79
|
+
if (fs.existsSync(`./tmp/await-deploy`)) fs.remove(`./tmp/await-deploy`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
for (const _jobId of jobList.split(',')) {
|
|
83
|
+
const jobId = _jobId.trim();
|
|
84
|
+
if (UnderpostCron.JOB[jobId]) await UnderpostCron.JOB[jobId].callback(deployList, options);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export default UnderpostCron;
|