underpost 2.8.86 → 2.8.87
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/.env.development +6 -1
- package/.env.production +6 -1
- package/.env.test +6 -1
- package/README.md +22 -2
- package/bin/build.js +1 -0
- package/bin/deploy.js +32 -20
- package/bin/file.js +5 -2
- package/bin/util.js +1 -56
- package/cli.md +10 -5
- package/conf.js +3 -3
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/mongo-express/deployment.yaml +12 -12
- package/manifests/maas/nvim.sh +91 -0
- package/package.json +3 -11
- package/src/api/file/file.service.js +28 -8
- package/src/api/user/user.router.js +31 -5
- package/src/api/user/user.service.js +3 -4
- package/src/cli/cluster.js +4 -23
- package/src/cli/db.js +0 -19
- package/src/cli/deploy.js +21 -29
- package/src/cli/fs.js +1 -0
- package/src/cli/index.js +4 -1
- package/src/cli/repository.js +4 -2
- package/src/cli/run.js +17 -2
- package/src/client/components/core/CssCore.js +12 -0
- package/src/client/components/core/FullScreen.js +19 -28
- package/src/client/components/core/Input.js +1 -0
- package/src/client/components/core/Modal.js +25 -39
- package/src/client/components/core/ObjectLayerEngine.js +229 -4
- package/src/client/components/core/ObjectLayerEngineModal.js +441 -0
- package/src/client/components/core/ToggleSwitch.js +15 -1
- package/src/client/public/default/assets/mailer/api-user-default-avatar.png +0 -0
- package/src/index.js +1 -1
- package/src/server/client-build-docs.js +1 -1
- package/src/server/client-build.js +4 -12
- package/src/server/client-icons.js +6 -78
- package/src/server/conf.js +83 -138
- package/src/server/proxy.js +1 -1
- package/src/server/runtime.js +1 -2
- package/src/server/start.js +2 -2
- package/test/api.test.js +3 -2
- package/bin/cyberia0.js +0 -78
|
@@ -4,6 +4,7 @@ import { loggerFactory } from '../../server/logger.js';
|
|
|
4
4
|
import { UserController } from './user.controller.js';
|
|
5
5
|
import express from 'express';
|
|
6
6
|
import { DataBaseProvider } from '../../db/DataBaseProvider.js';
|
|
7
|
+
import { FileFactory } from '../file/file.service.js';
|
|
7
8
|
|
|
8
9
|
const logger = loggerFactory(import.meta);
|
|
9
10
|
|
|
@@ -11,9 +12,10 @@ const UserRouter = (options) => {
|
|
|
11
12
|
const router = express.Router();
|
|
12
13
|
|
|
13
14
|
(async () => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
// admin user seed
|
|
16
|
+
try {
|
|
17
|
+
const models = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models;
|
|
18
|
+
if (models.User) {
|
|
17
19
|
const adminUser = await models.User.findOne({ role: 'admin' });
|
|
18
20
|
if (!adminUser) {
|
|
19
21
|
const defaultPassword = process.env.DEFAULT_ADMIN_PASSWORD || 'changethis';
|
|
@@ -29,10 +31,13 @@ const UserRouter = (options) => {
|
|
|
29
31
|
});
|
|
30
32
|
logger.warn('Default admin user created. Please change the default password immediately!', result._doc);
|
|
31
33
|
}
|
|
32
|
-
} catch (error) {
|
|
33
|
-
logger.error('Error checking/creating admin user:', error);
|
|
34
34
|
}
|
|
35
|
+
} catch (error) {
|
|
36
|
+
logger.error('Error checking/creating admin user');
|
|
37
|
+
console.log(error);
|
|
35
38
|
}
|
|
39
|
+
|
|
40
|
+
// default user avatar seed
|
|
36
41
|
options.png = {
|
|
37
42
|
buffer: {
|
|
38
43
|
'invalid-token': fs.readFileSync(`./src/client/public/default/assets/mailer/api-user-invalid-token.png`),
|
|
@@ -43,6 +48,27 @@ const UserRouter = (options) => {
|
|
|
43
48
|
res.set('Content-Type', 'image/png');
|
|
44
49
|
},
|
|
45
50
|
};
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const models = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models;
|
|
54
|
+
const name = 'api-user-default-avatar.png';
|
|
55
|
+
const imageFile = await models.File.findOne({ name });
|
|
56
|
+
let _id;
|
|
57
|
+
if (imageFile) {
|
|
58
|
+
_id = imageFile._id;
|
|
59
|
+
} else {
|
|
60
|
+
const file = await new models.File(
|
|
61
|
+
FileFactory.create(fs.readFileSync(`./src/client/public/default/assets/mailer/${name}`), name),
|
|
62
|
+
).save();
|
|
63
|
+
_id = file._id;
|
|
64
|
+
}
|
|
65
|
+
options.getDefaultProfileImageId = async () => {
|
|
66
|
+
return _id;
|
|
67
|
+
};
|
|
68
|
+
} catch (error) {
|
|
69
|
+
logger.error('Error checking/creating default profile image');
|
|
70
|
+
console.log(error);
|
|
71
|
+
}
|
|
46
72
|
})();
|
|
47
73
|
|
|
48
74
|
router.post(`/mailer/:id`, authMiddleware, async (req, res) => {
|
|
@@ -9,7 +9,6 @@ import { DataBaseProvider } from '../../db/DataBaseProvider.js';
|
|
|
9
9
|
import { FileFactory } from '../file/file.service.js';
|
|
10
10
|
import { UserDto } from './user.model.js';
|
|
11
11
|
import { selectDtoFactory, ValkeyAPI } from '../../server/valkey.js';
|
|
12
|
-
import { getDefaultProfileImageId } from '../../server/client-icons.js';
|
|
13
12
|
|
|
14
13
|
const logger = loggerFactory(import.meta);
|
|
15
14
|
|
|
@@ -129,7 +128,7 @@ const UserService = {
|
|
|
129
128
|
if (!user.profileImageId)
|
|
130
129
|
await User.findByIdAndUpdate(
|
|
131
130
|
user._id,
|
|
132
|
-
{ profileImageId: await getDefaultProfileImageId(File) },
|
|
131
|
+
{ profileImageId: await options.getDefaultProfileImageId(File) },
|
|
133
132
|
{
|
|
134
133
|
runValidators: true,
|
|
135
134
|
},
|
|
@@ -212,7 +211,7 @@ const UserService = {
|
|
|
212
211
|
if (validatePassword.status === 'error') throw new Error(validatePassword.message);
|
|
213
212
|
req.body.password = await hashPassword(req.body.password);
|
|
214
213
|
req.body.role = req.body.role === 'guest' ? 'guest' : 'user';
|
|
215
|
-
req.body.profileImageId = await getDefaultProfileImageId(File);
|
|
214
|
+
req.body.profileImageId = await options.getDefaultProfileImageId(File);
|
|
216
215
|
const { _id } = await new User(req.body).save();
|
|
217
216
|
if (_id) {
|
|
218
217
|
const user = await User.findOne({ _id }).select(UserDto.select.get());
|
|
@@ -313,7 +312,7 @@ const UserService = {
|
|
|
313
312
|
if (!file && !(await ValkeyAPI.getValkeyObject(options, req.auth.user.email))) {
|
|
314
313
|
await User.findByIdAndUpdate(
|
|
315
314
|
user._id,
|
|
316
|
-
{ profileImageId: await getDefaultProfileImageId(File) },
|
|
315
|
+
{ profileImageId: await options.getDefaultProfileImageId(File) },
|
|
317
316
|
{
|
|
318
317
|
runValidators: true,
|
|
319
318
|
},
|
package/src/cli/cluster.js
CHANGED
|
@@ -410,21 +410,10 @@ EOF
|
|
|
410
410
|
const successInstance = await UnderpostTest.API.statusMonitor('mongodb-0', 'Running', 'pods', 1000, 60 * 10);
|
|
411
411
|
|
|
412
412
|
if (successInstance) {
|
|
413
|
-
if (!options.mongoDbHost) options.mongoDbHost = 'mongodb-service';
|
|
413
|
+
if (!options.mongoDbHost) options.mongoDbHost = 'mongodb-0.mongodb-service';
|
|
414
414
|
const mongoConfig = {
|
|
415
415
|
_id: 'rs0',
|
|
416
|
-
members:
|
|
417
|
-
{
|
|
418
|
-
_id: 0,
|
|
419
|
-
host: `${options.mongoDbHost === 'mongodb-service' ? 'mongodb-0.' : ''}${options.mongoDbHost}:27017`,
|
|
420
|
-
priority: 1,
|
|
421
|
-
},
|
|
422
|
-
// {
|
|
423
|
-
// _id: 1,
|
|
424
|
-
// host: `${options.mongoDbHost === 'mongodb-service' ? 'mongodb-1.' : ''}${options.mongoDbHost}:27017`,
|
|
425
|
-
// priority: 1,
|
|
426
|
-
// },
|
|
427
|
-
],
|
|
416
|
+
members: options.mongoDbHost.split(',').map((host, index) => ({ _id: index, host: `${host}:27017` })),
|
|
428
417
|
};
|
|
429
418
|
|
|
430
419
|
shellExec(
|
|
@@ -683,17 +672,9 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`,
|
|
|
683
672
|
}
|
|
684
673
|
},
|
|
685
674
|
|
|
686
|
-
|
|
687
|
-
* @method getResourcesCapacity
|
|
688
|
-
* @description Retrieves and returns the allocatable CPU and memory resources
|
|
689
|
-
* of the Kubernetes node.
|
|
690
|
-
* @param {boolean} [isKubeadmOrK3s=false] - If true, assumes a kubeadm or k3s-managed node;
|
|
691
|
-
* otherwise, assumes a Kind worker node.
|
|
692
|
-
* @returns {object} An object containing CPU and memory resources with values and units.
|
|
693
|
-
*/
|
|
694
|
-
getResourcesCapacity(isKubeadmOrK3s = false) {
|
|
675
|
+
getResourcesCapacity(node) {
|
|
695
676
|
const resources = {};
|
|
696
|
-
const nodeName =
|
|
677
|
+
const nodeName = node ?? os.hostname();
|
|
697
678
|
const info = shellExec(`kubectl describe node ${nodeName} | grep -E '(Allocatable:|Capacity:)' -A 6`, {
|
|
698
679
|
stdout: true,
|
|
699
680
|
silent: true,
|
package/src/cli/db.js
CHANGED
|
@@ -177,25 +177,6 @@ class UnderpostDB {
|
|
|
177
177
|
}`,
|
|
178
178
|
);
|
|
179
179
|
}
|
|
180
|
-
if (false) {
|
|
181
|
-
const containerBaseBackupPath = '/backup';
|
|
182
|
-
let timeFolder = shellExec(
|
|
183
|
-
`sudo kubectl exec -i ${podName} -- sh -c "cd ${containerBaseBackupPath} && ls -a"`,
|
|
184
|
-
{
|
|
185
|
-
stdout: true,
|
|
186
|
-
disableLog: false,
|
|
187
|
-
silent: true,
|
|
188
|
-
},
|
|
189
|
-
).split(`\n`);
|
|
190
|
-
timeFolder = timeFolder[timeFolder.length - 2];
|
|
191
|
-
if (timeFolder === '..') {
|
|
192
|
-
logger.warn(`Cannot backup available`, { timeFolder });
|
|
193
|
-
} else {
|
|
194
|
-
shellExec(
|
|
195
|
-
`sudo kubectl cp ${nameSpace}/${podName}:${containerBaseBackupPath}/${timeFolder}/${dbName} ${_toNewBsonPath}`,
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
180
|
}
|
|
200
181
|
break;
|
|
201
182
|
}
|
package/src/cli/deploy.js
CHANGED
|
@@ -22,13 +22,13 @@ const logger = loggerFactory(import.meta);
|
|
|
22
22
|
class UnderpostDeploy {
|
|
23
23
|
static NETWORK = {};
|
|
24
24
|
static API = {
|
|
25
|
-
sync(deployList, { versions, replicas,
|
|
25
|
+
sync(deployList, { versions, replicas, node }) {
|
|
26
26
|
const deployGroupId = 'dd.router';
|
|
27
27
|
fs.writeFileSync(`./engine-private/deploy/${deployGroupId}`, deployList, 'utf8');
|
|
28
28
|
const totalPods = deployList.split(',').length * versions.split(',').length * parseInt(replicas);
|
|
29
29
|
const limitFactor = 0.8;
|
|
30
30
|
const reserveFactor = 0.05;
|
|
31
|
-
const resources = UnderpostCluster.API.getResourcesCapacity(
|
|
31
|
+
const resources = UnderpostCluster.API.getResourcesCapacity(node);
|
|
32
32
|
const memory = parseInt(resources.memory.value / totalPods);
|
|
33
33
|
const cpu = parseInt(resources.cpu.value / totalPods);
|
|
34
34
|
UnderpostRootEnv.API.set(
|
|
@@ -49,7 +49,7 @@ class UnderpostDeploy {
|
|
|
49
49
|
const initEnvObj = dotenv.parse(fs.readFileSync(initEnvPath, 'utf8'));
|
|
50
50
|
process.env.PORT = initEnvObj.PORT;
|
|
51
51
|
process.env.NODE_ENV = env;
|
|
52
|
-
await Config.build(
|
|
52
|
+
await Config.build('proxy', deployList);
|
|
53
53
|
return buildPortProxyRouter(env === 'development' ? 80 : 443, buildProxyRouter());
|
|
54
54
|
},
|
|
55
55
|
deploymentYamlServiceFactory({ deployId, env, port, deploymentVersions }) {
|
|
@@ -243,9 +243,11 @@ spec:
|
|
|
243
243
|
versions: '',
|
|
244
244
|
traffic: '',
|
|
245
245
|
replicas: '',
|
|
246
|
+
node: '',
|
|
246
247
|
restoreHosts: false,
|
|
247
248
|
disableUpdateDeployment: false,
|
|
248
249
|
infoTraffic: false,
|
|
250
|
+
etcHosts: false,
|
|
249
251
|
},
|
|
250
252
|
) {
|
|
251
253
|
if (options.infoUtil === true)
|
|
@@ -325,14 +327,10 @@ Password: <Your Key>
|
|
|
325
327
|
}
|
|
326
328
|
UnderpostDeploy.API.configMap(env);
|
|
327
329
|
let renderHosts = '';
|
|
328
|
-
let
|
|
329
|
-
const etcHost = (
|
|
330
|
-
concat,
|
|
331
|
-
) => `127.0.0.1 ${concat} localhost localhost.localdomain localhost4 localhost4.localdomain4
|
|
332
|
-
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6`;
|
|
330
|
+
let etcHosts = [];
|
|
333
331
|
if (options.restoreHosts === true) {
|
|
334
|
-
|
|
335
|
-
|
|
332
|
+
const factoryResult = UnderpostDeploy.API.etcHostFactory(etcHosts);
|
|
333
|
+
renderHosts = factoryResult.renderHosts;
|
|
336
334
|
logger.info(renderHosts);
|
|
337
335
|
return;
|
|
338
336
|
}
|
|
@@ -361,7 +359,7 @@ Password: <Your Key>
|
|
|
361
359
|
for (const host of Object.keys(confServer)) {
|
|
362
360
|
shellExec(`sudo kubectl delete HTTPProxy ${host}`);
|
|
363
361
|
if (env === 'production' && options.cert === true) shellExec(`sudo kubectl delete Certificate ${host}`);
|
|
364
|
-
if (!options.remove === true && env === 'development')
|
|
362
|
+
if (!options.remove === true && env === 'development') etcHosts.push(host);
|
|
365
363
|
}
|
|
366
364
|
|
|
367
365
|
const manifestsPath =
|
|
@@ -376,24 +374,9 @@ Password: <Your Key>
|
|
|
376
374
|
shellExec(`sudo kubectl apply -f ./${manifestsPath}/secret.yaml`);
|
|
377
375
|
}
|
|
378
376
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
switch (env) {
|
|
383
|
-
case 'development':
|
|
384
|
-
renderHosts = etcHost(concatHots);
|
|
385
|
-
fs.writeFileSync(`/etc/hosts`, renderHosts, 'utf8');
|
|
386
|
-
|
|
387
|
-
break;
|
|
388
|
-
|
|
389
|
-
default:
|
|
390
|
-
break;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
break;
|
|
394
|
-
|
|
395
|
-
default:
|
|
396
|
-
break;
|
|
377
|
+
if (options.etcHosts === true) {
|
|
378
|
+
const factoryResult = UnderpostDeploy.API.etcHostFactory(etcHosts);
|
|
379
|
+
renderHosts = factoryResult.renderHosts;
|
|
397
380
|
}
|
|
398
381
|
if (renderHosts)
|
|
399
382
|
logger.info(
|
|
@@ -487,6 +470,15 @@ Password: <Your Key>
|
|
|
487
470
|
);
|
|
488
471
|
shellExec(`sudo kubectl apply -f ./engine-private/conf/${deployId}/build/${env}/proxy.yaml`);
|
|
489
472
|
},
|
|
473
|
+
etcHostFactory(hosts = []) {
|
|
474
|
+
const renderHosts = `127.0.0.1 ${hosts.join(
|
|
475
|
+
' ',
|
|
476
|
+
)} localhost localhost.localdomain localhost4 localhost4.localdomain4
|
|
477
|
+
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6`;
|
|
478
|
+
|
|
479
|
+
fs.writeFileSync(`/etc/hosts`, renderHosts, 'utf8');
|
|
480
|
+
return { renderHosts };
|
|
481
|
+
},
|
|
490
482
|
};
|
|
491
483
|
}
|
|
492
484
|
|
package/src/cli/fs.js
CHANGED
|
@@ -61,6 +61,7 @@ class UnderpostFileStorage {
|
|
|
61
61
|
await UnderpostFileStorage.API.pull(_path, options);
|
|
62
62
|
} else logger.warn(`Pull path already exists`, _path);
|
|
63
63
|
}
|
|
64
|
+
shellExec(`cd ${path} && git init && git add . && git commit -m "Base pull state"`);
|
|
64
65
|
} else {
|
|
65
66
|
const files =
|
|
66
67
|
options.git === true
|
package/src/cli/index.js
CHANGED
|
@@ -22,7 +22,8 @@ program.name('underpost').description(`underpost ci/cd cli ${Underpost.version}`
|
|
|
22
22
|
// 'new' command: Create a new project
|
|
23
23
|
program
|
|
24
24
|
.command('new')
|
|
25
|
-
.argument('<app-name>', 'The name of the application to create.')
|
|
25
|
+
.argument('<app-name>', 'The name or deploy-id of the application to create.')
|
|
26
|
+
.option('--deploy-id', 'Crete deploy ID conf env files')
|
|
26
27
|
.option('--dev', 'Sets the development cli context')
|
|
27
28
|
.description('Initializes a new Underpost project with a predefined structure.')
|
|
28
29
|
.action(Underpost.repo.new);
|
|
@@ -157,6 +158,7 @@ program
|
|
|
157
158
|
.option('--expose', 'Exposes services matching the provided deployment ID list.')
|
|
158
159
|
.option('--info-util', 'Displays useful `kubectl` utility management commands.')
|
|
159
160
|
.option('--cert', 'Resets TLS/SSL certificate secrets for deployments.')
|
|
161
|
+
.option('--node <node>', 'Sets optional node for deployment operations.')
|
|
160
162
|
.option(
|
|
161
163
|
'--build-manifest',
|
|
162
164
|
'Builds Kubernetes YAML manifests, including deployments, services, proxies, and secrets.',
|
|
@@ -167,6 +169,7 @@ program
|
|
|
167
169
|
.option('--disable-update-deployment', 'Disables updates to deployments.')
|
|
168
170
|
.option('--info-traffic', 'Retrieves traffic configuration from current resource deployments.')
|
|
169
171
|
.option('--kubeadm', 'Enables the kubeadm context for deployment operations.')
|
|
172
|
+
.option('--etc-hosts', 'Enables the etc-hosts context for deployment operations.')
|
|
170
173
|
.option('--restore-hosts', 'Restores default `/etc/hosts` entries.')
|
|
171
174
|
.description('Manages application deployments, defaulting to deploying development pods.')
|
|
172
175
|
.action(Underpost.deploy.callback);
|
package/src/cli/repository.js
CHANGED
|
@@ -5,6 +5,7 @@ import { actionInitLog, loggerFactory } from '../server/logger.js';
|
|
|
5
5
|
import fs from 'fs-extra';
|
|
6
6
|
import { getNpmRootPath } from '../server/conf.js';
|
|
7
7
|
import UnderpostStartUp from '../server/start.js';
|
|
8
|
+
import { Config } from '../server/conf.js';
|
|
8
9
|
|
|
9
10
|
dotenv.config();
|
|
10
11
|
|
|
@@ -80,15 +81,16 @@ class UnderpostRepository {
|
|
|
80
81
|
);
|
|
81
82
|
},
|
|
82
83
|
|
|
83
|
-
new(repositoryName, options = { dev: false }) {
|
|
84
|
+
new(repositoryName, options = { dev: false, deployId: false }) {
|
|
84
85
|
return new Promise(async (resolve, reject) => {
|
|
85
86
|
try {
|
|
86
87
|
await logger.setUpInfo();
|
|
88
|
+
actionInitLog();
|
|
87
89
|
if (repositoryName === 'service')
|
|
88
90
|
return resolve(
|
|
89
91
|
await UnderpostStartUp.API.listenPortController(UnderpostStartUp.API.listenServerFactory(), ':'),
|
|
90
92
|
);
|
|
91
|
-
|
|
93
|
+
if (options.deployId === true) return Config.deployIdFactory(repositoryName);
|
|
92
94
|
const npmRoot = getNpmRootPath();
|
|
93
95
|
const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
|
|
94
96
|
const destFolder = `./${repositoryName}`;
|
package/src/cli/run.js
CHANGED
|
@@ -72,12 +72,19 @@ class UnderpostRun {
|
|
|
72
72
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
73
73
|
shellExec(`${baseCommand} cluster${options.dev ? ' --dev' : ''} --reset`);
|
|
74
74
|
shellExec(`${baseCommand} cluster${options.dev ? ' --dev' : ''}`);
|
|
75
|
+
const mongoHosts = ['mongodb-0.mongodb-service'];
|
|
75
76
|
shellExec(
|
|
76
|
-
`${baseCommand} cluster${options.dev ? ' --dev' : ''} --mongodb --mongo-db-host ${
|
|
77
|
+
`${baseCommand} cluster${options.dev ? ' --dev' : ''} --mongodb --mongo-db-host ${mongoHosts.join(
|
|
78
|
+
',',
|
|
79
|
+
)} --pull-image`,
|
|
77
80
|
);
|
|
78
81
|
shellExec(`${baseCommand} cluster${options.dev ? ' --dev' : ''} --valkey --pull-image`);
|
|
79
82
|
shellExec(`${baseCommand} deploy --expose mongo`, { async: true });
|
|
80
83
|
shellExec(`${baseCommand} deploy --expose valkey`, { async: true });
|
|
84
|
+
{
|
|
85
|
+
const hostListenResult = UnderpostDeploy.API.etcHostFactory(mongoHosts);
|
|
86
|
+
logger.info(hostListenResult.renderHosts);
|
|
87
|
+
}
|
|
81
88
|
},
|
|
82
89
|
'ssh-cluster-info': (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
83
90
|
const { underpostRoot } = options;
|
|
@@ -141,6 +148,14 @@ class UnderpostRun {
|
|
|
141
148
|
let [deployId, subConf] = path.split(',');
|
|
142
149
|
shellExec(`npm run dev-api ${deployId} ${subConf}`);
|
|
143
150
|
},
|
|
151
|
+
'router-sync': (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
152
|
+
const baseCommand = options.dev || true ? 'node bin' : 'underpost';
|
|
153
|
+
const defaultPaht = ['dd', 'kind-control-plane'];
|
|
154
|
+
let [deployId, node] = path ? path.split(',') : defaultPaht;
|
|
155
|
+
deployId = deployId ?? defaultPaht[0];
|
|
156
|
+
node = node ?? defaultPaht[1];
|
|
157
|
+
shellExec(`${baseCommand} deploy --sync --node ${node} --build-manifest --info-router ${deployId} production`);
|
|
158
|
+
},
|
|
144
159
|
monitor: (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
145
160
|
const pid = getTerminalPid();
|
|
146
161
|
logger.info('monitor pid', pid);
|
|
@@ -298,7 +313,7 @@ class UnderpostRun {
|
|
|
298
313
|
|
|
299
314
|
UnderpostDeploy.API.switchTraffic(deployId, env, targetTraffic);
|
|
300
315
|
|
|
301
|
-
shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${currentTraffic}`);
|
|
316
|
+
// shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${currentTraffic}`);
|
|
302
317
|
},
|
|
303
318
|
'tf-vae-test': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
304
319
|
const { underpostRoot } = options;
|
|
@@ -524,6 +524,12 @@ const CssCoreDark = {
|
|
|
524
524
|
}
|
|
525
525
|
.btn-input-extension:hover {
|
|
526
526
|
}
|
|
527
|
+
.section-mp-border {
|
|
528
|
+
border: 2px solid #313131;
|
|
529
|
+
border-radius: 5px;
|
|
530
|
+
padding: 5px;
|
|
531
|
+
margin: 5px;
|
|
532
|
+
}
|
|
527
533
|
</style>
|
|
528
534
|
${scrollBarDarkRender()} ${borderChar(1, 'black', ['.main-body-btn-container'])}
|
|
529
535
|
`,
|
|
@@ -848,6 +854,12 @@ const CssCoreLight = {
|
|
|
848
854
|
}
|
|
849
855
|
.btn-input-extension:hover {
|
|
850
856
|
}
|
|
857
|
+
.section-mp-border {
|
|
858
|
+
border: 2px solid #bbb;
|
|
859
|
+
border-radius: 5px;
|
|
860
|
+
padding: 5px;
|
|
861
|
+
margin: 5px;
|
|
862
|
+
}
|
|
851
863
|
</style>
|
|
852
864
|
${scrollBarLightRender()} ${borderChar(1, 'white', ['.main-body-btn-container'])}
|
|
853
865
|
`,
|
|
@@ -9,35 +9,26 @@ const FullScreen = {
|
|
|
9
9
|
Responsive.Event['full-screen-settings'] = () => {
|
|
10
10
|
let fullScreenMode = checkFullScreen();
|
|
11
11
|
if ((fullScreenSwitch && !fullScreenMode) || (!fullScreenSwitch && fullScreenMode))
|
|
12
|
-
if (s('.fullscreen
|
|
12
|
+
if (s('.fullscreen')) ToggleSwitch.Tokens[`fullscreen`].click();
|
|
13
13
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
},
|
|
33
|
-
checked: () => {
|
|
34
|
-
fullScreenSwitch = true;
|
|
35
|
-
if (!checkFullScreen()) fullScreenIn();
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
})}
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
14
|
+
return html`<div class="in section-mp">
|
|
15
|
+
${await ToggleSwitch.Render({
|
|
16
|
+
wrapper: true,
|
|
17
|
+
wrapperLabel: html`<i class="fa-solid fa-expand"></i> ${Translate.Render('fullscreen')}`,
|
|
18
|
+
id: 'fullscreen',
|
|
19
|
+
disabledOnClick: true,
|
|
20
|
+
checked: fullScreenSwitch,
|
|
21
|
+
on: {
|
|
22
|
+
unchecked: () => {
|
|
23
|
+
fullScreenSwitch = false;
|
|
24
|
+
if (checkFullScreen()) fullScreenOut();
|
|
25
|
+
},
|
|
26
|
+
checked: () => {
|
|
27
|
+
fullScreenSwitch = true;
|
|
28
|
+
if (!checkFullScreen()) fullScreenIn();
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
})}
|
|
41
32
|
</div>`;
|
|
42
33
|
},
|
|
43
34
|
};
|
|
@@ -65,6 +65,7 @@ const Input = {
|
|
|
65
65
|
type="${options?.type ? options.type : 'text'}"
|
|
66
66
|
class="${options.inputClass ? options.inputClass : 'in wfa'} ${id}"
|
|
67
67
|
${options?.min !== undefined ? `min="${options.min}"` : ''}
|
|
68
|
+
${options?.max !== undefined ? `max="${options.max}"` : ''}
|
|
68
69
|
placeholder${options?.placeholder ? `="${options.placeholder}"` : ''}
|
|
69
70
|
${options?.value !== undefined ? `value="${options.value}"` : ''}
|
|
70
71
|
${options?.autocomplete ? `autocomplete="${options.autocomplete}"` : ''}
|
|
@@ -51,6 +51,7 @@ const Modal = {
|
|
|
51
51
|
RouterInstance: {},
|
|
52
52
|
disableTools: [],
|
|
53
53
|
observer: false,
|
|
54
|
+
disableBoxShadow: false,
|
|
54
55
|
},
|
|
55
56
|
) {
|
|
56
57
|
if (options.heightBottomBar === undefined) options.heightBottomBar = 50;
|
|
@@ -89,6 +90,11 @@ const Modal = {
|
|
|
89
90
|
onHome: {},
|
|
90
91
|
homeModals: options.homeModals ? options.homeModals : [],
|
|
91
92
|
query: options.query ? `${window.location.search}` : undefined,
|
|
93
|
+
getTop: () => window.innerHeight - (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar),
|
|
94
|
+
getHeight: () =>
|
|
95
|
+
window.innerHeight -
|
|
96
|
+
(options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
|
|
97
|
+
(options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar),
|
|
92
98
|
};
|
|
93
99
|
|
|
94
100
|
if (idModal !== 'main-body' && options.mode !== 'view') {
|
|
@@ -117,12 +123,7 @@ const Modal = {
|
|
|
117
123
|
|
|
118
124
|
Responsive.Event[`view-${idModal}`] = () => {
|
|
119
125
|
if (!this.Data[idModal]) return delete Responsive.Event[`view-${idModal}`];
|
|
120
|
-
if (this.Data[idModal].slideMenu)
|
|
121
|
-
s(`.${idModal}`).style.height = `${
|
|
122
|
-
window.innerHeight -
|
|
123
|
-
(options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
|
|
124
|
-
(options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
|
|
125
|
-
}px`;
|
|
126
|
+
if (this.Data[idModal].slideMenu) s(`.${idModal}`).style.height = `${this.Data[idModal].getHeight()}px`;
|
|
126
127
|
};
|
|
127
128
|
Responsive.Event[`view-${idModal}`]();
|
|
128
129
|
|
|
@@ -207,11 +208,7 @@ const Modal = {
|
|
|
207
208
|
const { barConfig } = options;
|
|
208
209
|
options.style = {
|
|
209
210
|
position: 'absolute',
|
|
210
|
-
height: `${
|
|
211
|
-
window.innerHeight -
|
|
212
|
-
(options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
|
|
213
|
-
(options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
|
|
214
|
-
}px`,
|
|
211
|
+
height: `${Modal.Data[idModal].getHeight()}px`,
|
|
215
212
|
width: `${slideMenuWidth}px`,
|
|
216
213
|
// 'overflow-x': 'hidden',
|
|
217
214
|
// overflow: 'visible', // required for tooltip
|
|
@@ -239,11 +236,7 @@ const Modal = {
|
|
|
239
236
|
if (this.Data[_idModal].slideMenu && this.Data[_idModal].slideMenu.id === idModal)
|
|
240
237
|
this.Data[_idModal].slideMenu.callBack();
|
|
241
238
|
}
|
|
242
|
-
s(`.${idModal}`).style.height = `${
|
|
243
|
-
window.innerHeight -
|
|
244
|
-
(options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
|
|
245
|
-
(options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
|
|
246
|
-
}px`;
|
|
239
|
+
s(`.${idModal}`).style.height = `${Modal.Data[idModal].getHeight()}px`;
|
|
247
240
|
if (s(`.main-body-top`)) {
|
|
248
241
|
if (Modal.mobileModal()) {
|
|
249
242
|
if (s(`.btn-menu-${idModal}`).classList.contains('hide') && collapseSlideMenuWidth !== slideMenuWidth)
|
|
@@ -753,9 +746,12 @@ const Modal = {
|
|
|
753
746
|
s(`.main-btn-${results[currentKeyBoardSearchBoxIndex].routerId}`).click();
|
|
754
747
|
Modal.removeModal(searchBoxHistoryId);
|
|
755
748
|
};
|
|
756
|
-
|
|
749
|
+
let boxHistoryDelayRender = 0;
|
|
757
750
|
const searchBoxHistoryOpen = async () => {
|
|
758
|
-
if (
|
|
751
|
+
if (boxHistoryDelayRender) return;
|
|
752
|
+
boxHistoryDelayRender = 1000;
|
|
753
|
+
setTimeout(() => (boxHistoryDelayRender = 0));
|
|
754
|
+
if (!s(`.${searchBoxHistoryId}`)) {
|
|
759
755
|
const { barConfig } = await Themes[Css.currentTheme]();
|
|
760
756
|
barConfig.buttons.maximize.disabled = true;
|
|
761
757
|
barConfig.buttons.minimize.disabled = true;
|
|
@@ -763,7 +759,7 @@ const Modal = {
|
|
|
763
759
|
barConfig.buttons.menu.disabled = true;
|
|
764
760
|
barConfig.buttons.close.disabled = false;
|
|
765
761
|
await Modal.Render({
|
|
766
|
-
id,
|
|
762
|
+
id: searchBoxHistoryId,
|
|
767
763
|
barConfig,
|
|
768
764
|
title: html`<div class="search-box-recent-title">
|
|
769
765
|
${renderViewTitle({
|
|
@@ -964,6 +960,7 @@ const Modal = {
|
|
|
964
960
|
heightBottomBar: originHeightBottomBar,
|
|
965
961
|
barMode: options.barMode,
|
|
966
962
|
observer: true,
|
|
963
|
+
disableBoxShadow: true,
|
|
967
964
|
});
|
|
968
965
|
const maxWidthInputSearchBox = 450;
|
|
969
966
|
const paddingInputSearchBox = 5;
|
|
@@ -985,12 +982,7 @@ const Modal = {
|
|
|
985
982
|
s(`.top-bar-search-box`).style.top = `${
|
|
986
983
|
(originHeightTopBar - s(`.top-bar-search-box`).clientHeight) / 2
|
|
987
984
|
}px`;
|
|
988
|
-
if (this.Data[id].slideMenu)
|
|
989
|
-
s(`.${id}`).style.height = `${
|
|
990
|
-
window.innerHeight -
|
|
991
|
-
(options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
|
|
992
|
-
(options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
|
|
993
|
-
}px`;
|
|
985
|
+
if (this.Data[id].slideMenu) s(`.${id}`).style.height = `${Modal.Data[id].getHeight()}px`;
|
|
994
986
|
};
|
|
995
987
|
Responsive.Event[`view-${id}`]();
|
|
996
988
|
Keyboard.instanceMultiPressKey({
|
|
@@ -1119,9 +1111,7 @@ const Modal = {
|
|
|
1119
1111
|
if (!this.Data[id] || !s(`.${id}`)) return delete Responsive.Event[`view-${id}`];
|
|
1120
1112
|
// <div class="in fll right-offset-menu-bottom-bar" style="height: 100%"></div>
|
|
1121
1113
|
// s(`.right-offset-menu-bottom-bar`).style.width = `${window.innerWidth - slideMenuWidth}px`;
|
|
1122
|
-
s(`.${id}`).style.top = `${
|
|
1123
|
-
window.innerHeight - (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
|
|
1124
|
-
}px`;
|
|
1114
|
+
s(`.${id}`).style.top = `${Modal.Data[id].getTop()}px`;
|
|
1125
1115
|
};
|
|
1126
1116
|
Responsive.Event[`view-${id}`]();
|
|
1127
1117
|
}
|
|
@@ -1293,11 +1283,7 @@ const Modal = {
|
|
|
1293
1283
|
s(`.main-body-btn-ui-close`).classList.contains('hide') &&
|
|
1294
1284
|
s(`.btn-restore-${id}`).style.display !== 'none'
|
|
1295
1285
|
? `${window.innerHeight}px`
|
|
1296
|
-
: `${
|
|
1297
|
-
window.innerHeight -
|
|
1298
|
-
(options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
|
|
1299
|
-
(options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
|
|
1300
|
-
}px`;
|
|
1286
|
+
: `${Modal.Data[id].getHeight()}px`;
|
|
1301
1287
|
|
|
1302
1288
|
if (
|
|
1303
1289
|
s(`.main-body-btn-ui-close`).classList.contains('hide') &&
|
|
@@ -1405,7 +1391,11 @@ const Modal = {
|
|
|
1405
1391
|
}
|
|
1406
1392
|
</style>
|
|
1407
1393
|
${renderStyleTag(`style-${idModal}`, `.${idModal}`, options)}
|
|
1408
|
-
<div
|
|
1394
|
+
<div
|
|
1395
|
+
class="fix ${options && options.class ? options.class : ''} modal ${options.disableBoxShadow
|
|
1396
|
+
? ''
|
|
1397
|
+
: 'box-shadow'} ${idModal}"
|
|
1398
|
+
>
|
|
1409
1399
|
<div class="abs modal-handle-${idModal}"></div>
|
|
1410
1400
|
<div class="in modal-html-${idModal}">
|
|
1411
1401
|
<div class="stq bar-default-modal bar-default-modal-${idModal}">
|
|
@@ -1918,11 +1908,7 @@ const Modal = {
|
|
|
1918
1908
|
if (s(`.btn-restore-${idModal}`) && s(`.btn-restore-${idModal}`).style.display !== 'none') {
|
|
1919
1909
|
s(`.${idModal}`).style.height = s(`.main-body-btn-ui-close`).classList.contains('hide')
|
|
1920
1910
|
? `${window.innerHeight}px`
|
|
1921
|
-
: `${
|
|
1922
|
-
window.innerHeight -
|
|
1923
|
-
(options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
|
|
1924
|
-
(options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
|
|
1925
|
-
}px`;
|
|
1911
|
+
: `${Modal.Data[idModal].getHeight()}px`;
|
|
1926
1912
|
}
|
|
1927
1913
|
s(`.${idModal}`).style.top = s(`.main-body-btn-ui-close`).classList.contains('hide')
|
|
1928
1914
|
? `0px`
|