underpost 2.8.55 → 2.8.61
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/.github/workflows/ghpkg.yml +1 -1
- package/.github/workflows/npmpkg.yml +1 -1
- package/.github/workflows/pwa-microservices-template.page.yml +1 -1
- package/.vscode/settings.json +3 -0
- package/bin/build.js +9 -0
- package/bin/index.js +31 -6
- package/bin/vs.js +1 -0
- package/docker-compose.yml +1 -1
- package/manifests/kind-config-dev.yaml +12 -0
- package/manifests/mongodb/kustomization.yaml +2 -2
- package/manifests/mongodb-4.4/service-deployment.yaml +4 -4
- package/package.json +8 -7
- package/src/cli/cluster.js +56 -30
- package/src/cli/cron.js +1 -1
- package/src/cli/db.js +102 -38
- package/src/cli/deploy.js +27 -6
- package/src/cli/fs.js +149 -0
- package/src/cli/image.js +36 -4
- package/src/cli/repository.js +21 -0
- package/src/cli/test.js +17 -6
- package/src/client/components/core/CalendarCore.js +12 -1
- package/src/client/components/core/CommonJs.js +52 -1
- package/src/client/components/core/CssCore.js +2 -4
- package/src/client/components/core/Docs.js +1 -2
- package/src/client/components/core/Input.js +4 -2
- package/src/client/components/core/LoadingAnimation.js +8 -1
- package/src/client/components/core/Modal.js +30 -6
- package/src/client/components/core/Panel.js +8 -6
- package/src/client/components/core/PanelForm.js +23 -7
- package/src/client/services/core/core.service.js +15 -10
- package/src/client/ssr/Render.js +4 -1
- package/src/client/ssr/body/CacheControl.js +2 -3
- package/src/client/sw/default.sw.js +3 -3
- package/src/index.js +9 -1
- package/src/server/backup.js +2 -2
- package/src/server/client-build.js +32 -23
- package/src/server/client-formatted.js +2 -1
- package/src/server/conf.js +1 -1
- package/src/server/dns.js +2 -2
- package/src/server/runtime.js +16 -1
- package/manifests/valkey/underpost-engine-valkey-service.yaml +0 -17
- package/manifests/valkey/underpost-engine-valkey-statefulset.yaml +0 -39
|
@@ -43,7 +43,7 @@ jobs:
|
|
|
43
43
|
run: |
|
|
44
44
|
npm install -g underpost
|
|
45
45
|
underpost config set GITHUB_TOKEN ${{ secrets.GIT_AUTH_TOKEN }}
|
|
46
|
-
|
|
46
|
+
npm install
|
|
47
47
|
node ./bin/deploy rename-package @underpostnet/underpost
|
|
48
48
|
node ./bin/deploy set-repo underpostnet/pwa-microservices-template-ghpkg
|
|
49
49
|
|
|
@@ -43,7 +43,7 @@ jobs:
|
|
|
43
43
|
- name: Build the site
|
|
44
44
|
run: |
|
|
45
45
|
npm install -g underpost
|
|
46
|
-
|
|
46
|
+
npm install
|
|
47
47
|
node bin/deploy update-default-conf ghpkg
|
|
48
48
|
env-cmd -f .env.production node bin/deploy build-full-client github-pages underpostnet.github.io /pwa-microservices-template-ghpkg
|
|
49
49
|
# git lfs install
|
package/.vscode/settings.json
CHANGED
package/bin/build.js
CHANGED
|
@@ -155,6 +155,15 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
|
|
|
155
155
|
`${basePath}/.github/workflows/engine.${confName.split('dd-')[1]}.ci.yml`,
|
|
156
156
|
);
|
|
157
157
|
|
|
158
|
+
switch (confName) {
|
|
159
|
+
case 'dd-cyberia':
|
|
160
|
+
fs.copyFileSync(`./bin/cyberia.js`, `${basePath}/bin/cyberia.js`);
|
|
161
|
+
break;
|
|
162
|
+
|
|
163
|
+
default:
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
|
|
158
167
|
const packageJson = JSON.parse(fs.readFileSync(`${basePath}/package.json`, 'utf8'));
|
|
159
168
|
packageJson.name = repoName;
|
|
160
169
|
fs.writeFileSync(
|
package/bin/index.js
CHANGED
|
@@ -6,9 +6,6 @@ import Underpost from '../src/index.js';
|
|
|
6
6
|
import { getUnderpostRootPath, loadConf } from '../src/server/conf.js';
|
|
7
7
|
import fs from 'fs-extra';
|
|
8
8
|
import { commitData } from '../src/client/components/core/CommonJs.js';
|
|
9
|
-
import UnderpostScript from '../src/cli/script.js';
|
|
10
|
-
import UnderpostDB from '../src/cli/db.js';
|
|
11
|
-
import UnderpostCron from '../src/cli/cron.js';
|
|
12
9
|
|
|
13
10
|
const underpostRootPath = getUnderpostRootPath();
|
|
14
11
|
fs.existsSync(`${underpostRootPath}/.env`)
|
|
@@ -85,12 +82,14 @@ program
|
|
|
85
82
|
.option('--reset', `Delete all clusters and prune all data and caches`)
|
|
86
83
|
.option('--mariadb', 'Init with mariadb statefulset')
|
|
87
84
|
.option('--mongodb', 'Init with mongodb statefulset')
|
|
85
|
+
.option('--mongodb4', 'Init with mongodb 4.4 service')
|
|
88
86
|
.option('--valkey', 'Init with valkey service')
|
|
89
87
|
.option('--contour', 'Init with project contour base HTTPProxy and envoy')
|
|
90
88
|
.option('--cert-manager', 'Init with letsencrypt-prod ClusterIssuer')
|
|
91
89
|
.option('--info', 'Get all kinds objects deployed')
|
|
92
90
|
.option('--full', 'Init with all statefulsets and services available')
|
|
93
91
|
.option('--ns-use <ns-name>', 'Switches current context to namespace')
|
|
92
|
+
.option('--dev', 'init with dev cluster')
|
|
94
93
|
.option('--list-pods', 'Display list pods information')
|
|
95
94
|
.action(Underpost.cluster.init)
|
|
96
95
|
.description('Manage cluster, for default initialization base kind cluster');
|
|
@@ -104,7 +103,9 @@ program
|
|
|
104
103
|
.option('--info-router', 'Display router structure')
|
|
105
104
|
.option('--expose', 'Expose service match deploy-list')
|
|
106
105
|
.option('--info-util', 'Display kubectl util management commands')
|
|
106
|
+
.option('--cert', 'Reset tls/ssl certificate secrets')
|
|
107
107
|
.option('--build-manifest', 'Build kind yaml manifests: deployments, services, proxy and secrets')
|
|
108
|
+
.option('--version', 'Set custom version')
|
|
108
109
|
.description('Manage deployment, for default deploy development pods')
|
|
109
110
|
.action(Underpost.deploy.callback);
|
|
110
111
|
|
|
@@ -128,6 +129,7 @@ program
|
|
|
128
129
|
.argument('<deploy-id>', 'Deploy configuration id')
|
|
129
130
|
.argument('[env]', 'Optional environment, for default is development')
|
|
130
131
|
.option('--run', 'Run custom entry point script')
|
|
132
|
+
.option('--build', 'Build custom image container scripts')
|
|
131
133
|
.description('Dockerfile custom node build script')
|
|
132
134
|
.action(Underpost.image.dockerfile.script);
|
|
133
135
|
|
|
@@ -138,6 +140,8 @@ program
|
|
|
138
140
|
.argument('[path]', 'Absolute or relative directory, for default is current')
|
|
139
141
|
.option('--image-archive', 'Only load tar image from ./images')
|
|
140
142
|
.option('--podman-save', 'Save image from podman to ./images')
|
|
143
|
+
.option('--image-name <image-name>', 'Set custom image name')
|
|
144
|
+
.option('--image-version <image-version>', 'Set custom image version')
|
|
141
145
|
.description('Build image from Dockerfile')
|
|
142
146
|
.action(Underpost.image.dockerfile.build);
|
|
143
147
|
|
|
@@ -158,12 +162,19 @@ program
|
|
|
158
162
|
.argument('<deploy-list>', 'Deploy id list, e.g. default-a,default-b')
|
|
159
163
|
.option('--import', 'Import container backups from repositories')
|
|
160
164
|
.option('--export', 'Export container backups to repositories')
|
|
165
|
+
.option('--pod-name <pod-name>', 'Optional pod context')
|
|
166
|
+
.option('--collection <collection>', 'Collection')
|
|
167
|
+
.option('--out-path <out-path>', 'Custom out path backup')
|
|
168
|
+
.option('--drop', 'Drop databases')
|
|
169
|
+
.option('--preserveUUID', 'Preserve Ids')
|
|
170
|
+
.option('--git', 'Upload to github')
|
|
171
|
+
.option('--ns <ns-name>', 'Optional name space context')
|
|
161
172
|
.description('Manage databases')
|
|
162
|
-
.action(
|
|
173
|
+
.action(Underpost.db.callback);
|
|
163
174
|
|
|
164
175
|
program
|
|
165
176
|
.command('script')
|
|
166
|
-
.argument('operator', `Options: ${Object.keys(
|
|
177
|
+
.argument('operator', `Options: ${Object.keys(Underpost.script)}`)
|
|
167
178
|
.argument('<script-name>', 'Script name')
|
|
168
179
|
.argument('[script-value]', 'Literal command, or path')
|
|
169
180
|
.option('--itc', 'Inside container execution context')
|
|
@@ -178,12 +189,25 @@ program
|
|
|
178
189
|
program
|
|
179
190
|
.command('cron')
|
|
180
191
|
.argument('[deploy-list]', 'Deploy id list, e.g. default-a,default-b')
|
|
181
|
-
.argument('[job-list]', `Deploy id list, e.g. ${Object.keys(
|
|
192
|
+
.argument('[job-list]', `Deploy id list, e.g. ${Object.keys(Underpost.cron)}, for default all available jobs`)
|
|
182
193
|
.option('--itc', 'Inside container execution context')
|
|
183
194
|
.option('--init', 'Init cron jobs for cron job default deploy id')
|
|
195
|
+
.option('--git', 'Upload to github')
|
|
184
196
|
.description('Cron jobs management')
|
|
185
197
|
.action(Underpost.cron.callback);
|
|
186
198
|
|
|
199
|
+
program
|
|
200
|
+
.command('fs')
|
|
201
|
+
.argument('[path]', 'Absolute or relative directory')
|
|
202
|
+
.option('--rm', 'Remove file')
|
|
203
|
+
.option('--git', 'Current git changes')
|
|
204
|
+
.option('--recursive', 'Upload files recursively')
|
|
205
|
+
.option('--deploy-id <deploy-id>', 'Deploy configuration id')
|
|
206
|
+
.option('--pull', 'Download file')
|
|
207
|
+
.option('--force', 'Force action')
|
|
208
|
+
.description('File storage management, for default upload file')
|
|
209
|
+
.action(Underpost.fs.callback);
|
|
210
|
+
|
|
187
211
|
program
|
|
188
212
|
.command('test')
|
|
189
213
|
.argument('[deploy-list]', 'Deploy id list, e.g. default-a,default-b')
|
|
@@ -193,6 +217,7 @@ program
|
|
|
193
217
|
.option('--logs', 'Display container logs')
|
|
194
218
|
.option('--pod-name <pod-name>')
|
|
195
219
|
.option('--pod-status <pod-status>')
|
|
220
|
+
.option('--kind-type <kind-type>')
|
|
196
221
|
.action(Underpost.test.callback);
|
|
197
222
|
|
|
198
223
|
program.parse();
|
package/bin/vs.js
CHANGED
|
@@ -20,6 +20,7 @@ switch (process.argv[2]) {
|
|
|
20
20
|
logger.info('Open new vs windows', 'Ctrl Shift N');
|
|
21
21
|
logger.info('Close current vs windows', 'Ctrl Shift W');
|
|
22
22
|
logger.info('Preview md', 'Ctrl shift V');
|
|
23
|
+
logger.info('Open git changes', 'Ctrl G + G');
|
|
23
24
|
logger.warn('Terminal shortcut configure with command pallette', 'Ctl shift T');
|
|
24
25
|
break;
|
|
25
26
|
}
|
package/docker-compose.yml
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
kind: Cluster
|
|
2
|
+
apiVersion: kind.x-k8s.io/v1alpha4
|
|
3
|
+
nodes:
|
|
4
|
+
- role: control-plane
|
|
5
|
+
- role: worker
|
|
6
|
+
# extraPortMappings:
|
|
7
|
+
# - containerPort: 80
|
|
8
|
+
# hostPort: 80
|
|
9
|
+
# listenAddress: '0.0.0.0'
|
|
10
|
+
# - containerPort: 443
|
|
11
|
+
# hostPort: 443
|
|
12
|
+
# listenAddress: '0.0.0.0'
|
|
@@ -29,10 +29,10 @@ spec:
|
|
|
29
29
|
- name: mongo-persistent-storage
|
|
30
30
|
mountPath: /data/db
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
# resources:
|
|
33
|
+
# requests:
|
|
34
|
+
# memory: '500Mi'
|
|
35
|
+
# cpu: '500m'
|
|
36
36
|
volumes:
|
|
37
37
|
- name: mongo-persistent-storage
|
|
38
38
|
persistentVolumeClaim:
|
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.61",
|
|
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",
|
|
@@ -57,9 +57,11 @@
|
|
|
57
57
|
"ag-grid-community": "31.0.0",
|
|
58
58
|
"axios": "^1.5.1",
|
|
59
59
|
"chai": "^5.1.0",
|
|
60
|
+
"clean-jsdoc-theme": "^4.3.0",
|
|
60
61
|
"cli-progress": "^3.12.0",
|
|
61
62
|
"cli-spinners": "^3.0.0",
|
|
62
63
|
"clipboardy": "^4.0.0",
|
|
64
|
+
"cloudinary": "^2.5.1",
|
|
63
65
|
"color": "^4.2.3",
|
|
64
66
|
"colors": "^1.4.0",
|
|
65
67
|
"commander": "^12.1.0",
|
|
@@ -67,6 +69,7 @@
|
|
|
67
69
|
"cors": "^2.8.5",
|
|
68
70
|
"d3": "^7.9.0",
|
|
69
71
|
"dotenv": "^16.3.1",
|
|
72
|
+
"easy-json-schema": "^0.0.2-beta",
|
|
70
73
|
"easymde": "^2.18.0",
|
|
71
74
|
"env-cmd": "^10.1.0",
|
|
72
75
|
"express": "^4.18.2",
|
|
@@ -87,6 +90,7 @@
|
|
|
87
90
|
"log-update": "^6.0.0",
|
|
88
91
|
"mariadb": "^3.2.2",
|
|
89
92
|
"marked": "^12.0.2",
|
|
93
|
+
"mocha": "^10.8.2",
|
|
90
94
|
"mongoose": "^8.9.5",
|
|
91
95
|
"morgan": "^1.10.0",
|
|
92
96
|
"nodemailer": "^6.9.9",
|
|
@@ -95,6 +99,7 @@
|
|
|
95
99
|
"peer": "^1.0.2",
|
|
96
100
|
"peerjs": "^1.5.2",
|
|
97
101
|
"pixi.js": "7.4.2",
|
|
102
|
+
"plantuml": "^0.0.2",
|
|
98
103
|
"prom-client": "^15.1.2",
|
|
99
104
|
"public-ip": "^6.0.1",
|
|
100
105
|
"read": "^2.1.0",
|
|
@@ -106,17 +111,13 @@
|
|
|
106
111
|
"socket.io": "^4.8.0",
|
|
107
112
|
"sortablejs": "^1.15.0",
|
|
108
113
|
"split-file": "^2.3.0",
|
|
114
|
+
"swagger-autogen": "^2.23.7",
|
|
109
115
|
"swagger-ui-express": "^5.0.0",
|
|
110
116
|
"systeminformation": "^5.23.7",
|
|
111
117
|
"uglify-js": "^3.17.4",
|
|
112
118
|
"validator": "^13.11.0",
|
|
113
119
|
"vanilla-jsoneditor": "^2.3.2",
|
|
114
|
-
"winston": "^3.11.0"
|
|
115
|
-
"clean-jsdoc-theme": "^4.3.0",
|
|
116
|
-
"easy-json-schema": "^0.0.2-beta",
|
|
117
|
-
"mocha": "^10.8.2",
|
|
118
|
-
"plantuml": "^0.0.2",
|
|
119
|
-
"swagger-autogen": "^2.23.7"
|
|
120
|
+
"winston": "^3.11.0"
|
|
120
121
|
},
|
|
121
122
|
"devDependencies": {
|
|
122
123
|
"clean-jsdoc-theme": "^4.3.0",
|
package/src/cli/cluster.js
CHANGED
|
@@ -12,7 +12,8 @@ class UnderpostCluster {
|
|
|
12
12
|
async init(
|
|
13
13
|
podName,
|
|
14
14
|
options = {
|
|
15
|
-
|
|
15
|
+
mongodb: false,
|
|
16
|
+
mongodb4: false,
|
|
16
17
|
mariadb: false,
|
|
17
18
|
valkey: false,
|
|
18
19
|
full: false,
|
|
@@ -20,19 +21,20 @@ class UnderpostCluster {
|
|
|
20
21
|
certManager: false,
|
|
21
22
|
listPods: false,
|
|
22
23
|
reset: false,
|
|
24
|
+
dev: false,
|
|
23
25
|
nsUse: '',
|
|
24
26
|
},
|
|
25
27
|
) {
|
|
26
28
|
const npmRoot = getNpmRootPath();
|
|
27
|
-
const underpostRoot = `${npmRoot}/underpost`;
|
|
29
|
+
const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
|
|
28
30
|
if (options.reset === true) return await UnderpostCluster.API.reset();
|
|
29
31
|
if (options.listPods === true) return console.table(UnderpostDeploy.API.get(podName ?? undefined));
|
|
30
32
|
|
|
31
|
-
if (options.nsUse) {
|
|
33
|
+
if (options.nsUse && typeof options.nsUse === 'string') {
|
|
32
34
|
shellExec(`kubectl config set-context --current --namespace=${options.nsUse}`);
|
|
33
35
|
return;
|
|
34
36
|
}
|
|
35
|
-
if (options.info) {
|
|
37
|
+
if (options.info === true) {
|
|
36
38
|
shellExec(`kubectl config get-contexts`); // config env persisente for manage multiple clusters
|
|
37
39
|
shellExec(`kubectl config get-clusters`);
|
|
38
40
|
shellExec(`kubectl get nodes -o wide`); // set of nodes of a cluster
|
|
@@ -63,12 +65,8 @@ class UnderpostCluster {
|
|
|
63
65
|
shellExec(`kubectl get crd --all-namespaces -o wide`);
|
|
64
66
|
return;
|
|
65
67
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
silent: true,
|
|
69
|
-
stdout: true,
|
|
70
|
-
});
|
|
71
|
-
if (!(testClusterInit.match('kube-system') && testClusterInit.match('kube-proxy'))) {
|
|
68
|
+
|
|
69
|
+
if (!UnderpostDeploy.API.get('kube-apiserver-kind-control-plane')[0]) {
|
|
72
70
|
shellExec(`containerd config default > /etc/containerd/config.toml`);
|
|
73
71
|
shellExec(`sed -i -e "s/SystemdCgroup = false/SystemdCgroup = true/g" /etc/containerd/config.toml`);
|
|
74
72
|
// shellExec(`cp /etc/kubernetes/admin.conf ~/.kube/config`);
|
|
@@ -76,15 +74,19 @@ class UnderpostCluster {
|
|
|
76
74
|
shellExec(`sudo service docker restart`);
|
|
77
75
|
shellExec(`sudo systemctl enable --now containerd.service`);
|
|
78
76
|
shellExec(`sudo systemctl restart containerd`);
|
|
79
|
-
shellExec(
|
|
77
|
+
shellExec(
|
|
78
|
+
`cd ${underpostRoot}/manifests && kind create cluster --config kind-config${
|
|
79
|
+
options?.dev === true ? '-dev' : ''
|
|
80
|
+
}.yaml`,
|
|
81
|
+
);
|
|
80
82
|
shellExec(`sudo chown $(id -u):$(id -g) $HOME/.kube/config**`);
|
|
81
83
|
} else logger.warn('Cluster already initialized');
|
|
82
84
|
|
|
83
|
-
if (options.full || options.valkey) {
|
|
85
|
+
if (options.full === true || options.valkey === true) {
|
|
84
86
|
shellExec(`kubectl delete statefulset service-valkey`);
|
|
85
87
|
shellExec(`kubectl apply -k ${underpostRoot}/manifests/valkey`);
|
|
86
88
|
}
|
|
87
|
-
if (options.full || options.mariadb) {
|
|
89
|
+
if (options.full === true || options.mariadb === true) {
|
|
88
90
|
shellExec(
|
|
89
91
|
`sudo kubectl create secret generic mariadb-secret --from-file=username=/home/dd/engine/engine-private/mariadb-username --from-file=password=/home/dd/engine/engine-private/mariadb-password`,
|
|
90
92
|
);
|
|
@@ -94,7 +96,29 @@ class UnderpostCluster {
|
|
|
94
96
|
shellExec(`kubectl delete statefulset mariadb-statefulset`);
|
|
95
97
|
shellExec(`kubectl apply -k ${underpostRoot}/manifests/mariadb`);
|
|
96
98
|
}
|
|
97
|
-
if (options.
|
|
99
|
+
if (options.mongodb4 === true) {
|
|
100
|
+
shellExec(`kubectl apply -k ${underpostRoot}/manifests/mongodb-4.4`);
|
|
101
|
+
|
|
102
|
+
const deploymentName = 'mongodb-deployment';
|
|
103
|
+
|
|
104
|
+
const successInstance = await UnderpostTest.API.statusMonitor(deploymentName);
|
|
105
|
+
|
|
106
|
+
if (successInstance) {
|
|
107
|
+
const mongoConfig = {
|
|
108
|
+
_id: 'rs0',
|
|
109
|
+
members: [{ _id: 0, host: '127.0.0.1:27017' }],
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const [pod] = UnderpostDeploy.API.get(deploymentName);
|
|
113
|
+
|
|
114
|
+
shellExec(
|
|
115
|
+
`sudo kubectl exec -i ${pod.NAME} -- mongo --quiet \
|
|
116
|
+
--eval 'rs.initiate(${JSON.stringify(mongoConfig)})'`,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// await UnderpostTest.API.statusMonitor('mongodb-1');
|
|
121
|
+
} else if (options.full === true || options.mongodb === true) {
|
|
98
122
|
shellExec(
|
|
99
123
|
`sudo kubectl create secret generic mongodb-keyfile --from-file=/home/dd/engine/engine-private/mongodb-keyfile`,
|
|
100
124
|
);
|
|
@@ -104,28 +128,30 @@ class UnderpostCluster {
|
|
|
104
128
|
shellExec(`kubectl delete statefulset mongodb`);
|
|
105
129
|
shellExec(`kubectl apply -k ${underpostRoot}/manifests/mongodb`);
|
|
106
130
|
|
|
107
|
-
await UnderpostTest.API.
|
|
131
|
+
const successInstance = await UnderpostTest.API.statusMonitor('mongodb-1');
|
|
108
132
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
133
|
+
if (successInstance) {
|
|
134
|
+
const mongoConfig = {
|
|
135
|
+
_id: 'rs0',
|
|
136
|
+
members: [
|
|
137
|
+
{ _id: 0, host: 'mongodb-0.mongodb-service:27017', priority: 1 },
|
|
138
|
+
{ _id: 1, host: 'mongodb-1.mongodb-service:27017', priority: 1 },
|
|
139
|
+
],
|
|
140
|
+
};
|
|
116
141
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
142
|
+
shellExec(
|
|
143
|
+
`sudo kubectl exec -i mongodb-0 -- mongosh --quiet --json=relaxed \
|
|
144
|
+
--eval 'use admin' \
|
|
145
|
+
--eval 'rs.initiate(${JSON.stringify(mongoConfig)})' \
|
|
146
|
+
--eval 'rs.status()'`,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
123
149
|
}
|
|
124
150
|
|
|
125
|
-
if (options.full || options.contour)
|
|
151
|
+
if (options.full === true || options.contour === true)
|
|
126
152
|
shellExec(`kubectl apply -f https://projectcontour.io/quickstart/contour.yaml`);
|
|
127
153
|
|
|
128
|
-
if (options.full || options.certManager) {
|
|
154
|
+
if (options.full === true || options.certManager === true) {
|
|
129
155
|
if (!UnderpostDeploy.API.get('cert-manager').find((p) => p.STATUS === 'Running')) {
|
|
130
156
|
shellExec(`helm repo add jetstack https://charts.jetstack.io --force-update`);
|
|
131
157
|
shellExec(
|
package/src/cli/cron.js
CHANGED
|
@@ -46,7 +46,7 @@ class UnderpostCron {
|
|
|
46
46
|
callback: async function (
|
|
47
47
|
deployList = 'default',
|
|
48
48
|
jobList = Object.keys(UnderpostCron.JOB),
|
|
49
|
-
options = { itc: false, init: false },
|
|
49
|
+
options = { itc: false, init: false, git: false },
|
|
50
50
|
) {
|
|
51
51
|
if (options.init === true) {
|
|
52
52
|
await Underpost.test.setUpInfo();
|
package/src/cli/db.js
CHANGED
|
@@ -2,14 +2,28 @@ import { mergeFile, splitFileFactory } from '../server/conf.js';
|
|
|
2
2
|
import { loggerFactory } from '../server/logger.js';
|
|
3
3
|
import { shellExec } from '../server/process.js';
|
|
4
4
|
import fs from 'fs-extra';
|
|
5
|
+
import UnderpostDeploy from './deploy.js';
|
|
5
6
|
|
|
6
7
|
const logger = loggerFactory(import.meta);
|
|
7
8
|
|
|
8
9
|
class UnderpostDB {
|
|
9
10
|
static API = {
|
|
10
|
-
async callback(
|
|
11
|
+
async callback(
|
|
12
|
+
deployList = 'default',
|
|
13
|
+
options = {
|
|
14
|
+
import: false,
|
|
15
|
+
export: false,
|
|
16
|
+
podName: false,
|
|
17
|
+
ns: false,
|
|
18
|
+
collection: '',
|
|
19
|
+
outPath: '',
|
|
20
|
+
drop: false,
|
|
21
|
+
preserveUUID: false,
|
|
22
|
+
git: false,
|
|
23
|
+
},
|
|
24
|
+
) {
|
|
11
25
|
const newBackupTimestamp = new Date().getTime();
|
|
12
|
-
const nameSpace = 'default';
|
|
26
|
+
const nameSpace = options.ns && typeof options.ns === 'string' ? options.ns : 'default';
|
|
13
27
|
for (const _deployId of deployList.split(',')) {
|
|
14
28
|
const deployId = _deployId.trim();
|
|
15
29
|
if (!deployId) continue;
|
|
@@ -43,10 +57,12 @@ class UnderpostDB {
|
|
|
43
57
|
logger.info('', { hostFolder, provider, dbName });
|
|
44
58
|
|
|
45
59
|
const backUpPath = `../${repoName}/${hostFolder}`;
|
|
60
|
+
if (!fs.existsSync(backUpPath)) fs.mkdirSync(backUpPath, { recursive: true });
|
|
61
|
+
shellExec(`cd ${backUpPath} && find . -type d -empty -delete`); // delete empty folders
|
|
46
62
|
const times = await fs.readdir(backUpPath);
|
|
47
|
-
const currentBackupTimestamp = Math.max(...times.map((t) => parseInt(t)));
|
|
63
|
+
const currentBackupTimestamp = Math.max(...times.map((t) => parseInt(t)).filter((t) => !isNaN(t)));
|
|
48
64
|
dbs[provider][dbName].currentBackupTimestamp = currentBackupTimestamp;
|
|
49
|
-
const removeBackupTimestamp = Math.min(...times.map((t) => parseInt(t)));
|
|
65
|
+
const removeBackupTimestamp = Math.min(...times.map((t) => parseInt(t)).filter((t) => !isNaN(t)));
|
|
50
66
|
|
|
51
67
|
const sqlContainerPath = `/home/${dbName}.sql`;
|
|
52
68
|
const _fromPartsParts = `../${repoName}/${hostFolder}/${currentBackupTimestamp}/${dbName}-parths.json`;
|
|
@@ -68,57 +84,105 @@ class UnderpostDB {
|
|
|
68
84
|
}
|
|
69
85
|
|
|
70
86
|
if (options.export === true && times.length >= 5) {
|
|
87
|
+
logger.info('remove', `../${repoName}/${hostFolder}/${removeBackupTimestamp}`);
|
|
71
88
|
fs.removeSync(`../${repoName}/${hostFolder}/${removeBackupTimestamp}`);
|
|
89
|
+
logger.info('create', `../${repoName}/${hostFolder}/${newBackupTimestamp}`);
|
|
72
90
|
fs.mkdirSync(`../${repoName}/${hostFolder}/${newBackupTimestamp}`, { recursive: true });
|
|
73
91
|
}
|
|
74
92
|
|
|
75
93
|
switch (provider) {
|
|
76
94
|
case 'mariadb': {
|
|
77
|
-
const
|
|
95
|
+
const podNames =
|
|
96
|
+
options.podName && typeof options.podName === 'string'
|
|
97
|
+
? options.podName.split(',')
|
|
98
|
+
: UnderpostDeploy.API.get('mariadb'); // `mariadb-statefulset-0`;
|
|
78
99
|
const serviceName = 'mariadb';
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
`kubectl
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
100
|
+
for (const podNameData of [podNames[0]]) {
|
|
101
|
+
const podName = podNameData.NAME;
|
|
102
|
+
if (options.import === true) {
|
|
103
|
+
shellExec(`sudo kubectl exec -i ${podName} -- sh -c "rm -rf /${dbName}.sql"`);
|
|
104
|
+
shellExec(`sudo kubectl cp ${_toSqlPath} ${nameSpace}/${podName}:/${dbName}.sql`);
|
|
105
|
+
const cmd = `mariadb -u ${user} -p${password} ${dbName} < /${dbName}.sql`;
|
|
106
|
+
shellExec(
|
|
107
|
+
`kubectl exec -i ${podName} -- ${serviceName} -p${password} -e 'CREATE DATABASE ${dbName};'`,
|
|
108
|
+
);
|
|
109
|
+
shellExec(`sudo kubectl exec -i ${podName} -- sh -c "${cmd}"`);
|
|
110
|
+
}
|
|
111
|
+
if (options.export === true) {
|
|
112
|
+
shellExec(`sudo kubectl exec -i ${podName} -- sh -c "rm -rf ${sqlContainerPath}"`);
|
|
113
|
+
const cmd = `mariadb-dump --user=${user} --password=${password} --lock-tables ${dbName} > ${sqlContainerPath}`;
|
|
114
|
+
shellExec(`sudo kubectl exec -i ${podName} -- sh -c "${cmd}"`);
|
|
115
|
+
shellExec(
|
|
116
|
+
`sudo kubectl cp ${nameSpace}/${podName}:${sqlContainerPath} ${
|
|
117
|
+
options.outPath ? options.outPath : _toNewSqlPath
|
|
118
|
+
}`,
|
|
119
|
+
);
|
|
120
|
+
await splitFileFactory(dbName, options.outPath ? options.outPath : _toNewSqlPath);
|
|
121
|
+
}
|
|
92
122
|
}
|
|
93
123
|
break;
|
|
94
124
|
}
|
|
95
125
|
|
|
96
126
|
case 'mongoose': {
|
|
97
127
|
if (options.import === true) {
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
128
|
+
const podNames =
|
|
129
|
+
options.podName && typeof options.podName === 'string'
|
|
130
|
+
? options.podName.split(',')
|
|
131
|
+
: UnderpostDeploy.API.get('mongo');
|
|
132
|
+
// `mongodb-0`;
|
|
133
|
+
for (const podNameData of [podNames[0]]) {
|
|
134
|
+
const podName = podNameData.NAME;
|
|
135
|
+
shellExec(`sudo kubectl exec -i ${podName} -- sh -c "rm -rf /${dbName}"`);
|
|
136
|
+
shellExec(
|
|
137
|
+
`sudo kubectl cp ${
|
|
138
|
+
options.outPath ? options.outPath : _toBsonPath
|
|
139
|
+
} ${nameSpace}/${podName}:/${dbName}`,
|
|
140
|
+
);
|
|
141
|
+
const cmd = `mongorestore -d ${dbName} /${dbName}${options.drop ? ' --drop' : ''}${
|
|
142
|
+
options.preserveUUID ? ' --preserveUUID' : ''
|
|
143
|
+
}`;
|
|
144
|
+
shellExec(`sudo kubectl exec -i ${podName} -- sh -c "${cmd}"`);
|
|
145
|
+
}
|
|
102
146
|
}
|
|
103
147
|
if (options.export === true) {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
} else {
|
|
148
|
+
const podNames =
|
|
149
|
+
options.podName && typeof options.podName === 'string'
|
|
150
|
+
? options.podName.split(',')
|
|
151
|
+
: UnderpostDeploy.API.get('mongo'); // `backup-access`;
|
|
152
|
+
for (const podNameData of [podNames[0]]) {
|
|
153
|
+
const podName = podNameData.NAME;
|
|
154
|
+
shellExec(`sudo kubectl exec -i ${podName} -- sh -c "rm -rf /${dbName}"`);
|
|
155
|
+
if (options.collections)
|
|
156
|
+
for (const collection of options.collections)
|
|
157
|
+
shellExec(
|
|
158
|
+
`sudo kubectl exec -i ${podName} -- sh -c "mongodump -d ${dbName} --collection ${collection} -o /${dbName}"`,
|
|
159
|
+
);
|
|
160
|
+
else shellExec(`sudo kubectl exec -i ${podName} -- sh -c "mongodump -d ${dbName} -o /${dbName}"`);
|
|
118
161
|
shellExec(
|
|
119
|
-
`sudo kubectl cp ${nameSpace}/${podName}
|
|
162
|
+
`sudo kubectl cp ${nameSpace}/${podName}:/${dbName} ${
|
|
163
|
+
options.outPath ? options.outPath : _toNewBsonPath
|
|
164
|
+
}`,
|
|
120
165
|
);
|
|
121
166
|
}
|
|
167
|
+
if (false) {
|
|
168
|
+
const containerBaseBackupPath = '/backup';
|
|
169
|
+
let timeFolder = shellExec(
|
|
170
|
+
`sudo kubectl exec -i ${podName} -- sh -c "cd ${containerBaseBackupPath} && ls -a"`,
|
|
171
|
+
{
|
|
172
|
+
stdout: true,
|
|
173
|
+
disableLog: false,
|
|
174
|
+
silent: true,
|
|
175
|
+
},
|
|
176
|
+
).split(`\n`);
|
|
177
|
+
timeFolder = timeFolder[timeFolder.length - 2];
|
|
178
|
+
if (timeFolder === '..') {
|
|
179
|
+
logger.warn(`Cannot backup available`, { timeFolder });
|
|
180
|
+
} else {
|
|
181
|
+
shellExec(
|
|
182
|
+
`sudo kubectl cp ${nameSpace}/${podName}:${containerBaseBackupPath}/${timeFolder}/${dbName} ${_toNewBsonPath}`,
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
122
186
|
}
|
|
123
187
|
break;
|
|
124
188
|
}
|
|
@@ -129,7 +193,7 @@ class UnderpostDB {
|
|
|
129
193
|
}
|
|
130
194
|
}
|
|
131
195
|
}
|
|
132
|
-
if (options.export === true) {
|
|
196
|
+
if (options.export === true && options.git === true) {
|
|
133
197
|
shellExec(`cd ../${repoName} && git add .`);
|
|
134
198
|
shellExec(
|
|
135
199
|
`underpost cmt ../${repoName} backup '' '${new Date(newBackupTimestamp).toLocaleDateString()} ${new Date(
|