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/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
|
-
|
|
41
|
-
|
|
42
|
-
VOLUME [ "/home/dd/engine/logs" ]
|
|
37
|
+
WORKDIR /home/dd
|
|
43
38
|
|
|
44
39
|
EXPOSE 22
|
|
45
40
|
|
|
46
|
-
EXPOSE
|
|
41
|
+
EXPOSE 80
|
|
42
|
+
|
|
43
|
+
EXPOSE 443
|
|
44
|
+
|
|
45
|
+
EXPOSE 3000-3100
|
|
47
46
|
|
|
48
|
-
|
|
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 = ['
|
|
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
|
-
|
|
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('--
|
|
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
|
-
.
|
|
139
|
-
.
|
|
140
|
-
.
|
|
141
|
-
.option('--
|
|
142
|
-
.option('--podman-save', '
|
|
143
|
-
.option('--
|
|
144
|
-
.option('--
|
|
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('--
|
|
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();
|
package/docker-compose.yml
CHANGED
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.
|
|
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
|
|
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'
|
|
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
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
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
|
|
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`);
|
package/src/cli/cluster.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
71
|
-
|
|
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
|
|
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
|
-
|
|
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 (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
);
|