underpost 2.8.867 → 2.8.871
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/README.md +50 -36
- package/bin/build.js +1 -0
- package/bin/deploy.js +4 -0
- package/bin/util.js +1 -56
- package/cli.md +88 -86
- package/conf.js +1 -1
- 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 +1 -10
- package/src/api/file/file.service.js +28 -8
- package/src/api/user/user.router.js +24 -0
- package/src/api/user/user.service.js +3 -4
- package/src/cli/cluster.js +2 -13
- package/src/cli/cron.js +0 -1
- package/src/cli/db.js +0 -19
- package/src/cli/deploy.js +17 -26
- package/src/cli/fs.js +1 -0
- package/src/cli/index.js +1 -0
- package/src/cli/run.js +9 -2
- package/src/client/components/core/CalendarCore.js +1 -1
- package/src/client/components/core/CssCore.js +12 -0
- package/src/client/components/core/Docs.js +2 -2
- 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 +41 -24
- package/src/client/components/core/ObjectLayerEngine.js +229 -4
- package/src/client/components/core/ObjectLayerEngineModal.js +441 -0
- package/src/client/components/core/Panel.js +4 -1
- package/src/client/components/core/PanelForm.js +1 -1
- package/src/client/components/core/Router.js +29 -25
- package/src/client/components/core/ToggleSwitch.js +15 -1
- package/src/client/components/core/VanillaJs.js +12 -13
- 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.js +3 -11
- package/src/server/client-icons.js +6 -78
- package/src/server/conf.js +4 -56
- package/src/server/process.js +2 -1
|
@@ -17,7 +17,7 @@ spec:
|
|
|
17
17
|
spec:
|
|
18
18
|
containers:
|
|
19
19
|
- name: dd-default-development-blue
|
|
20
|
-
image: localhost/rockylinux9-underpost:v2.8.
|
|
20
|
+
image: localhost/rockylinux9-underpost:v2.8.871
|
|
21
21
|
# resources:
|
|
22
22
|
# requests:
|
|
23
23
|
# memory: "124Ki"
|
|
@@ -100,7 +100,7 @@ spec:
|
|
|
100
100
|
spec:
|
|
101
101
|
containers:
|
|
102
102
|
- name: dd-default-development-green
|
|
103
|
-
image: localhost/rockylinux9-underpost:v2.8.
|
|
103
|
+
image: localhost/rockylinux9-underpost:v2.8.871
|
|
104
104
|
# resources:
|
|
105
105
|
# requests:
|
|
106
106
|
# memory: "124Ki"
|
|
@@ -20,16 +20,16 @@ spec:
|
|
|
20
20
|
ports:
|
|
21
21
|
- containerPort: 8081
|
|
22
22
|
env:
|
|
23
|
-
- name: ME_CONFIG_MONGODB_ADMINUSERNAME
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- name: ME_CONFIG_MONGODB_ADMINPASSWORD
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
# - name: ME_CONFIG_MONGODB_ADMINUSERNAME
|
|
24
|
+
# valueFrom:
|
|
25
|
+
# secretKeyRef:
|
|
26
|
+
# name: mongodb-secret
|
|
27
|
+
# key: username
|
|
28
|
+
# - name: ME_CONFIG_MONGODB_ADMINPASSWORD
|
|
29
|
+
# valueFrom:
|
|
30
|
+
# secretKeyRef:
|
|
31
|
+
# name: mongodb-secret
|
|
32
|
+
# key: password
|
|
33
33
|
- name: ME_CONFIG_BASICAUTH_USERNAME
|
|
34
34
|
valueFrom:
|
|
35
35
|
secretKeyRef:
|
|
@@ -42,8 +42,8 @@ spec:
|
|
|
42
42
|
key: password
|
|
43
43
|
- name: ME_CONFIG_MONGODB_SERVER
|
|
44
44
|
value: 'mongodb-0.mongodb-service'
|
|
45
|
-
- name: ME_CONFIG_MONGODB_ENABLE_ADMIN
|
|
46
|
-
|
|
45
|
+
# - name: ME_CONFIG_MONGODB_ENABLE_ADMIN
|
|
46
|
+
# value: 'true'
|
|
47
47
|
- name: ME_CONFIG_MONGODB_PORT
|
|
48
48
|
value: '27017'
|
|
49
49
|
---
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
sudo dnf install -y neovim
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
sudo rm -rf ~/.config/nvim
|
|
8
|
+
sudo rm -rf ~/.local/share/nvim
|
|
9
|
+
|
|
10
|
+
mkdir -p ~/.config/nvim
|
|
11
|
+
mkdir -p ~/.local/share/nvim/site/autoload
|
|
12
|
+
|
|
13
|
+
# Install vim-plug for Neovim
|
|
14
|
+
curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \
|
|
15
|
+
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
|
|
16
|
+
|
|
17
|
+
# Create an init.vim with nvim-tree.lua + web-devicons + gruvbox (theme)
|
|
18
|
+
cat > ~/.config/nvim/init.vim <<'EOF'
|
|
19
|
+
" Minimal init.vim to use nvim-tree.lua + gruvbox theme via vim-plug
|
|
20
|
+
|
|
21
|
+
" --- vim-plug manager
|
|
22
|
+
call plug#begin('~/.local/share/nvim/plugged')
|
|
23
|
+
|
|
24
|
+
" file explorer (nvim-tree)
|
|
25
|
+
Plug 'nvim-tree/nvim-tree.lua'
|
|
26
|
+
Plug 'nvim-tree/nvim-web-devicons' " optional: file icons
|
|
27
|
+
|
|
28
|
+
" colorscheme
|
|
29
|
+
Plug 'morhetz/gruvbox'
|
|
30
|
+
|
|
31
|
+
" sensible defaults, optional
|
|
32
|
+
Plug 'tpope/vim-sensible'
|
|
33
|
+
|
|
34
|
+
call plug#end()
|
|
35
|
+
|
|
36
|
+
" --- UI settings
|
|
37
|
+
syntax on
|
|
38
|
+
filetype plugin indent on
|
|
39
|
+
set number
|
|
40
|
+
set relativenumber
|
|
41
|
+
if has('termguicolors')
|
|
42
|
+
set termguicolors
|
|
43
|
+
endif
|
|
44
|
+
set background=dark
|
|
45
|
+
|
|
46
|
+
" gruvbox options (optional)
|
|
47
|
+
let g:gruvbox_contrast_dark = 'soft'
|
|
48
|
+
colorscheme gruvbox
|
|
49
|
+
|
|
50
|
+
" --- nvim-tree configuration (Lua block)
|
|
51
|
+
lua << 'LUA'
|
|
52
|
+
-- safe require
|
|
53
|
+
local ok, tree = pcall(require, "nvim-tree")
|
|
54
|
+
if not ok then
|
|
55
|
+
return
|
|
56
|
+
end
|
|
57
|
+
tree.setup{
|
|
58
|
+
view = {
|
|
59
|
+
width = 30,
|
|
60
|
+
side = "left",
|
|
61
|
+
preserve_window_proportions = true,
|
|
62
|
+
},
|
|
63
|
+
renderer = {
|
|
64
|
+
indent_markers = { enable = true },
|
|
65
|
+
},
|
|
66
|
+
actions = {
|
|
67
|
+
open_file = {
|
|
68
|
+
quit_on_open = false,
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
LUA
|
|
73
|
+
|
|
74
|
+
" --- mappings: Ctrl-n toggles nvim-tree
|
|
75
|
+
nnoremap <C-n> :NvimTreeToggle<CR>
|
|
76
|
+
|
|
77
|
+
" Open nvim-tree on startup when opening nvim with no file args
|
|
78
|
+
autocmd StdinReadPre * let s:std_in=1
|
|
79
|
+
autocmd VimEnter * if argc() == 0 && !exists('s:std_in') | NvimTreeToggle | wincmd p | endif
|
|
80
|
+
EOF
|
|
81
|
+
|
|
82
|
+
# Fix permissions in case something was left owned by root (happens if you used sudo on these paths before)
|
|
83
|
+
sudo chown -R "$USER":"$USER" ~/.config/nvim ~/.local/share/nvim 2>/dev/null || true
|
|
84
|
+
|
|
85
|
+
# Install plugins automatically (non-interactive)
|
|
86
|
+
nvim +PlugInstall +qall
|
|
87
|
+
|
|
88
|
+
echo
|
|
89
|
+
echo "Done. Plugins installed."
|
|
90
|
+
echo "Run 'nvim' and press Ctrl-n to toggle the file tree."
|
|
91
|
+
echo "If colorscheme is not correct, ensure your terminal supports truecolor and TERM is xterm-256color."
|
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.871",
|
|
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",
|
|
@@ -58,11 +58,8 @@
|
|
|
58
58
|
"axios": "^1.5.1",
|
|
59
59
|
"chai": "^5.1.0",
|
|
60
60
|
"clean-jsdoc-theme": "^4.3.0",
|
|
61
|
-
"cli-progress": "^3.12.0",
|
|
62
|
-
"cli-spinners": "^3.0.0",
|
|
63
61
|
"clipboardy": "^4.0.0",
|
|
64
62
|
"cloudinary": "^2.5.1",
|
|
65
|
-
"color": "^4.2.3",
|
|
66
63
|
"colors": "^1.4.0",
|
|
67
64
|
"commander": "^12.1.0",
|
|
68
65
|
"compression": "^1.7.4",
|
|
@@ -74,7 +71,6 @@
|
|
|
74
71
|
"express": "^4.18.2",
|
|
75
72
|
"express-fileupload": "^1.4.3",
|
|
76
73
|
"favicons": "^7.2.0",
|
|
77
|
-
"font-awesome-assets": "^0.0.9",
|
|
78
74
|
"fs-extra": "^11.1.1",
|
|
79
75
|
"fullcalendar": "^6.1.15",
|
|
80
76
|
"html-minifier-terser": "^7.2.0",
|
|
@@ -82,11 +78,8 @@
|
|
|
82
78
|
"ignore-walk": "^6.0.4",
|
|
83
79
|
"iovalkey": "^0.2.1",
|
|
84
80
|
"jimp": "^0.22.12",
|
|
85
|
-
"joystick-controller": "^1.0.15",
|
|
86
81
|
"json-colorizer": "^2.2.2",
|
|
87
82
|
"jsonwebtoken": "^9.0.2",
|
|
88
|
-
"keyword-extractor": "^0.0.28",
|
|
89
|
-
"log-update": "^6.0.0",
|
|
90
83
|
"mariadb": "^3.2.2",
|
|
91
84
|
"marked": "^12.0.2",
|
|
92
85
|
"mocha": "^10.8.2",
|
|
@@ -97,7 +90,6 @@
|
|
|
97
90
|
"pathfinding": "^0.4.18",
|
|
98
91
|
"peer": "^1.0.2",
|
|
99
92
|
"peerjs": "^1.5.2",
|
|
100
|
-
"pixi.js": "7.4.2",
|
|
101
93
|
"prom-client": "^15.1.2",
|
|
102
94
|
"public-ip": "^6.0.1",
|
|
103
95
|
"read": "^2.1.0",
|
|
@@ -116,7 +108,6 @@
|
|
|
116
108
|
"vanilla-jsoneditor": "^2.3.2",
|
|
117
109
|
"winston": "^3.11.0"
|
|
118
110
|
},
|
|
119
|
-
"devDependencies": {},
|
|
120
111
|
"publishConfig": {
|
|
121
112
|
"provenance": true,
|
|
122
113
|
"access": "public",
|
|
@@ -5,14 +5,18 @@ import crypto from 'crypto';
|
|
|
5
5
|
const logger = loggerFactory(import.meta);
|
|
6
6
|
|
|
7
7
|
const FileFactory = {
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
if (
|
|
11
|
-
if (Array.isArray(req.files.file)) for (const file of req.files.file) results.push(await new File(file).save());
|
|
8
|
+
filesExtract: (req) => {
|
|
9
|
+
const files = [];
|
|
10
|
+
if (Array.isArray(req.files.file)) for (const file of req.files.file) files.push(file);
|
|
12
11
|
else if (Object.keys(req.files).length > 0)
|
|
13
|
-
for (const keyFile of Object.keys(req.files))
|
|
12
|
+
for (const keyFile of Object.keys(req.files)) files.push(req.files[keyFile]);
|
|
13
|
+
return files;
|
|
14
|
+
},
|
|
15
|
+
upload: async function (req, File) {
|
|
16
|
+
const results = FileFactory.filesExtract(req);
|
|
14
17
|
let index = -1;
|
|
15
|
-
for (
|
|
18
|
+
for (let file of results) {
|
|
19
|
+
file = await new File(file).save();
|
|
16
20
|
index++;
|
|
17
21
|
const [result] = await File.find({
|
|
18
22
|
_id: file._id,
|
|
@@ -25,7 +29,23 @@ const FileFactory = {
|
|
|
25
29
|
return Buffer.from(raw, 'utf8').toString('hex');
|
|
26
30
|
// reverse hexValue.toString()
|
|
27
31
|
},
|
|
28
|
-
|
|
32
|
+
getMymeTypeFromPath: (path) => {
|
|
33
|
+
switch (path.split('.').pop()) {
|
|
34
|
+
case 'png':
|
|
35
|
+
return 'image/png';
|
|
36
|
+
case 'jpg':
|
|
37
|
+
return 'image/jpeg';
|
|
38
|
+
case 'jpeg':
|
|
39
|
+
return 'image/jpeg';
|
|
40
|
+
case 'gif':
|
|
41
|
+
return 'image/gif';
|
|
42
|
+
case 'svg':
|
|
43
|
+
return 'image/svg+xml';
|
|
44
|
+
default:
|
|
45
|
+
return 'application/octet-stream';
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
create: (data = Buffer.from([]), name = '') => {
|
|
29
49
|
return {
|
|
30
50
|
name: name,
|
|
31
51
|
data: data,
|
|
@@ -33,7 +53,7 @@ const FileFactory = {
|
|
|
33
53
|
encoding: '7bit',
|
|
34
54
|
tempFilePath: '',
|
|
35
55
|
truncated: false,
|
|
36
|
-
mimetype:
|
|
56
|
+
mimetype: FileFactory.getMymeTypeFromPath(name),
|
|
37
57
|
md5: crypto.createHash('md5').update(data).digest('hex'),
|
|
38
58
|
cid: undefined,
|
|
39
59
|
};
|
|
@@ -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,6 +12,7 @@ const UserRouter = (options) => {
|
|
|
11
12
|
const router = express.Router();
|
|
12
13
|
|
|
13
14
|
(async () => {
|
|
15
|
+
// admin user seed
|
|
14
16
|
try {
|
|
15
17
|
const models = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models;
|
|
16
18
|
if (models.User) {
|
|
@@ -35,6 +37,7 @@ const UserRouter = (options) => {
|
|
|
35
37
|
console.log(error);
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
// default user avatar seed
|
|
38
41
|
options.png = {
|
|
39
42
|
buffer: {
|
|
40
43
|
'invalid-token': fs.readFileSync(`./src/client/public/default/assets/mailer/api-user-invalid-token.png`),
|
|
@@ -45,6 +48,27 @@ const UserRouter = (options) => {
|
|
|
45
48
|
res.set('Content-Type', 'image/png');
|
|
46
49
|
},
|
|
47
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
|
+
}
|
|
48
72
|
})();
|
|
49
73
|
|
|
50
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(
|
package/src/cli/cron.js
CHANGED
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
|
@@ -247,6 +247,7 @@ spec:
|
|
|
247
247
|
restoreHosts: false,
|
|
248
248
|
disableUpdateDeployment: false,
|
|
249
249
|
infoTraffic: false,
|
|
250
|
+
etcHosts: false,
|
|
250
251
|
},
|
|
251
252
|
) {
|
|
252
253
|
if (options.infoUtil === true)
|
|
@@ -326,14 +327,10 @@ Password: <Your Key>
|
|
|
326
327
|
}
|
|
327
328
|
UnderpostDeploy.API.configMap(env);
|
|
328
329
|
let renderHosts = '';
|
|
329
|
-
let
|
|
330
|
-
const etcHost = (
|
|
331
|
-
concat,
|
|
332
|
-
) => `127.0.0.1 ${concat} localhost localhost.localdomain localhost4 localhost4.localdomain4
|
|
333
|
-
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6`;
|
|
330
|
+
let etcHosts = [];
|
|
334
331
|
if (options.restoreHosts === true) {
|
|
335
|
-
|
|
336
|
-
|
|
332
|
+
const factoryResult = UnderpostDeploy.API.etcHostFactory(etcHosts);
|
|
333
|
+
renderHosts = factoryResult.renderHosts;
|
|
337
334
|
logger.info(renderHosts);
|
|
338
335
|
return;
|
|
339
336
|
}
|
|
@@ -362,7 +359,7 @@ Password: <Your Key>
|
|
|
362
359
|
for (const host of Object.keys(confServer)) {
|
|
363
360
|
shellExec(`sudo kubectl delete HTTPProxy ${host}`);
|
|
364
361
|
if (env === 'production' && options.cert === true) shellExec(`sudo kubectl delete Certificate ${host}`);
|
|
365
|
-
if (!options.remove === true && env === 'development')
|
|
362
|
+
if (!options.remove === true && env === 'development') etcHosts.push(host);
|
|
366
363
|
}
|
|
367
364
|
|
|
368
365
|
const manifestsPath =
|
|
@@ -377,24 +374,9 @@ Password: <Your Key>
|
|
|
377
374
|
shellExec(`sudo kubectl apply -f ./${manifestsPath}/secret.yaml`);
|
|
378
375
|
}
|
|
379
376
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
switch (env) {
|
|
384
|
-
case 'development':
|
|
385
|
-
renderHosts = etcHost(concatHots);
|
|
386
|
-
fs.writeFileSync(`/etc/hosts`, renderHosts, 'utf8');
|
|
387
|
-
|
|
388
|
-
break;
|
|
389
|
-
|
|
390
|
-
default:
|
|
391
|
-
break;
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
break;
|
|
395
|
-
|
|
396
|
-
default:
|
|
397
|
-
break;
|
|
377
|
+
if (options.etcHosts === true) {
|
|
378
|
+
const factoryResult = UnderpostDeploy.API.etcHostFactory(etcHosts);
|
|
379
|
+
renderHosts = factoryResult.renderHosts;
|
|
398
380
|
}
|
|
399
381
|
if (renderHosts)
|
|
400
382
|
logger.info(
|
|
@@ -488,6 +470,15 @@ Password: <Your Key>
|
|
|
488
470
|
);
|
|
489
471
|
shellExec(`sudo kubectl apply -f ./engine-private/conf/${deployId}/build/${env}/proxy.yaml`);
|
|
490
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
|
+
},
|
|
491
482
|
};
|
|
492
483
|
}
|
|
493
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
|
@@ -169,6 +169,7 @@ program
|
|
|
169
169
|
.option('--disable-update-deployment', 'Disables updates to deployments.')
|
|
170
170
|
.option('--info-traffic', 'Retrieves traffic configuration from current resource deployments.')
|
|
171
171
|
.option('--kubeadm', 'Enables the kubeadm context for deployment operations.')
|
|
172
|
+
.option('--etc-hosts', 'Enables the etc-hosts context for deployment operations.')
|
|
172
173
|
.option('--restore-hosts', 'Restores default `/etc/hosts` entries.')
|
|
173
174
|
.description('Manages application deployments, defaulting to deploying development pods.')
|
|
174
175
|
.action(Underpost.deploy.callback);
|
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;
|
|
@@ -306,7 +313,7 @@ class UnderpostRun {
|
|
|
306
313
|
|
|
307
314
|
UnderpostDeploy.API.switchTraffic(deployId, env, targetTraffic);
|
|
308
315
|
|
|
309
|
-
shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${currentTraffic}`);
|
|
316
|
+
// shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${currentTraffic}`);
|
|
310
317
|
},
|
|
311
318
|
'tf-vae-test': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
312
319
|
const { underpostRoot } = options;
|
|
@@ -346,7 +346,7 @@ const CalendarCore = {
|
|
|
346
346
|
status,
|
|
347
347
|
});
|
|
348
348
|
|
|
349
|
-
setQueryPath({ path: options.route, queryPath: '' });
|
|
349
|
+
setQueryPath({ path: options.route, queryPath: '', replace: true });
|
|
350
350
|
await CalendarCore.Data[options.idModal].updatePanel();
|
|
351
351
|
|
|
352
352
|
return { status };
|
|
@@ -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
|
`,
|
|
@@ -4,7 +4,7 @@ import { rgbToHex } from './CommonJs.js';
|
|
|
4
4
|
import { Css, darkTheme, dynamicCol, renderCssAttr, simpleIconsRender, ThemeEvents, Themes } from './Css.js';
|
|
5
5
|
import { DropDown } from './DropDown.js';
|
|
6
6
|
import { buildBadgeToolTipMenuOption, Modal, renderMenuLabel, renderViewTitle } from './Modal.js';
|
|
7
|
-
import { listenQueryPathInstance, setQueryPath } from './Router.js';
|
|
7
|
+
import { listenQueryPathInstance, setQueryPath, closeModalRouteChangeEvent } from './Router.js';
|
|
8
8
|
import { Translate } from './Translate.js';
|
|
9
9
|
import { getProxyPath, getQueryParams, htmls, s, sa } from './VanillaJs.js';
|
|
10
10
|
import Sortable from 'sortablejs';
|
|
@@ -51,7 +51,7 @@ const Docs = {
|
|
|
51
51
|
};
|
|
52
52
|
Modal.Data[ModalId].onObserverListener[ModalId]();
|
|
53
53
|
Modal.Data[ModalId].onCloseListener[ModalId] = () => {
|
|
54
|
-
|
|
54
|
+
closeModalRouteChangeEvent({ closedId: ModalId });
|
|
55
55
|
};
|
|
56
56
|
},
|
|
57
57
|
Data: [
|
|
@@ -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}"` : ''}
|