@underpostnet/underpost 2.8.5 → 2.8.6

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.
Files changed (60) hide show
  1. package/.github/workflows/ghpkg.yml +1 -1
  2. package/.github/workflows/npmpkg.yml +1 -1
  3. package/.github/workflows/pwa-microservices-template.page.yml +1 -1
  4. package/.vscode/settings.json +4 -0
  5. package/CHANGELOG.md +24 -0
  6. package/bin/build.js +29 -4
  7. package/bin/deploy.js +70 -74
  8. package/bin/hwt.js +0 -10
  9. package/bin/index.js +54 -23
  10. package/bin/util.js +0 -7
  11. package/bin/vs.js +1 -0
  12. package/conf.js +0 -2
  13. package/docker-compose.yml +1 -1
  14. package/manifests/kind-config-dev.yaml +12 -0
  15. package/manifests/mongodb/kustomization.yaml +2 -2
  16. package/manifests/mongodb-4.4/kustomization.yaml +7 -0
  17. package/manifests/mongodb-4.4/service-deployment.yaml +63 -0
  18. package/package.json +9 -7
  19. package/src/cli/cluster.js +99 -51
  20. package/src/cli/cron.js +1 -1
  21. package/src/cli/db.js +102 -38
  22. package/src/cli/deploy.js +76 -35
  23. package/src/cli/fs.js +149 -0
  24. package/src/cli/image.js +50 -27
  25. package/src/cli/repository.js +21 -0
  26. package/src/cli/script.js +25 -1
  27. package/src/cli/test.js +39 -4
  28. package/src/client/components/core/CalendarCore.js +12 -1
  29. package/src/client/components/core/CommonJs.js +52 -1
  30. package/src/client/components/core/CssCore.js +2 -4
  31. package/src/client/components/core/Docs.js +1 -2
  32. package/src/client/components/core/Input.js +4 -2
  33. package/src/client/components/core/LoadingAnimation.js +8 -1
  34. package/src/client/components/core/Modal.js +30 -6
  35. package/src/client/components/core/Panel.js +8 -6
  36. package/src/client/components/core/PanelForm.js +23 -7
  37. package/src/client/services/core/core.service.js +15 -10
  38. package/src/client/ssr/Render.js +4 -1
  39. package/src/client/ssr/body/CacheControl.js +2 -3
  40. package/src/client/sw/default.sw.js +3 -3
  41. package/src/db/mongo/MongooseDB.js +17 -1
  42. package/src/index.js +9 -1
  43. package/src/server/backup.js +3 -3
  44. package/src/server/client-build.js +32 -23
  45. package/src/server/client-formatted.js +2 -1
  46. package/src/server/conf.js +17 -15
  47. package/src/server/dns.js +39 -46
  48. package/src/server/downloader.js +0 -8
  49. package/src/server/runtime.js +16 -1
  50. package/test/api.test.js +0 -8
  51. package/manifests/core/kustomization.yaml +0 -11
  52. package/manifests/core/underpost-engine-backup-access.yaml +0 -16
  53. package/manifests/core/underpost-engine-backup-pv-pvc.yaml +0 -22
  54. package/manifests/core/underpost-engine-headless-service.yaml +0 -10
  55. package/manifests/core/underpost-engine-mongodb-backup-cronjob.yaml +0 -40
  56. package/manifests/core/underpost-engine-mongodb-configmap.yaml +0 -26
  57. package/manifests/core/underpost-engine-statefulset.yaml +0 -91
  58. package/manifests/valkey/underpost-engine-valkey-service.yaml +0 -17
  59. package/manifests/valkey/underpost-engine-valkey-statefulset.yaml +0 -39
  60. /package/manifests/{core/underpost-engine-pv-pvc.yaml → mongodb-4.4/pv-pvc.yaml} +0 -0
@@ -0,0 +1,63 @@
1
+ apiVersion: apps/v1
2
+ kind: Deployment
3
+ metadata:
4
+ name: mongodb-deployment
5
+ namespace: default
6
+ spec:
7
+ selector:
8
+ matchLabels:
9
+ app: mongodb
10
+ replicas: 1
11
+ template:
12
+ metadata:
13
+ labels:
14
+ app: mongodb
15
+ spec:
16
+ hostname: mongo
17
+ containers:
18
+ - name: mongodb
19
+ image: docker.io/library/mongo:4.4
20
+ command: ['mongod', '--replSet', 'rs0', '--bind_ip_all']
21
+ # -- bash
22
+ # mongo
23
+ # use admin
24
+ # rs.initiate()
25
+ ports:
26
+ - containerPort: 27017
27
+
28
+ volumeMounts:
29
+ - name: mongo-persistent-storage
30
+ mountPath: /data/db
31
+
32
+ # resources:
33
+ # requests:
34
+ # memory: '500Mi'
35
+ # cpu: '500m'
36
+ volumes:
37
+ - name: mongo-persistent-storage
38
+ persistentVolumeClaim:
39
+ claimName: mongodb-pvc
40
+
41
+ ---
42
+ apiVersion: v1
43
+ kind: Service
44
+ metadata:
45
+ name: mongodb-service
46
+ namespace: default
47
+ spec:
48
+ clusterIP: None
49
+ selector:
50
+ app: mongodb
51
+ ports:
52
+ - protocol: TCP
53
+ port: 27017
54
+ # targetPort: 27017
55
+ # type: ClusterIP
56
+
57
+ # rs.initiate();
58
+ # use admin;
59
+ # rs.initiate({ _id: "rs0", members: [ { _id: 0, host: "127.0.0.1:27017" } ] })
60
+ # db.createUser({user: "your_user",pwd: "your_password", roles: [{role: "userAdminAnyDatabase", db: "admin" },{ role: "readWriteAnyDatabase", db: "admin" }]});
61
+ # cfg = rs.conf();
62
+ # cfg.members[0].host = "127.0.0.1:27027";
63
+ # rs.reconfig(cfg);
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "@underpostnet/underpost",
5
- "version": "2.8.5",
5
+ "version": "2.8.6",
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",
@@ -10,6 +10,7 @@
10
10
  "pm2": "env-cmd -f .env.production pm2 start src/server.js --node-args=\"--max-old-space-size=8192\" --name engine",
11
11
  "dev": "env-cmd -f .env.development node src/client.dev default",
12
12
  "dev-img": "env-cmd -f .env.development node src/server",
13
+ "prod-img": "env-cmd -f .env.production node src/server",
13
14
  "dev-api": "env-cmd -f .env.development nodemon --watch src --ignore src/client src/api",
14
15
  "dev-client": "env-cmd -f .env.development node src/client.dev",
15
16
  "proxy": "node src/proxy proxy",
@@ -56,9 +57,11 @@
56
57
  "ag-grid-community": "31.0.0",
57
58
  "axios": "^1.5.1",
58
59
  "chai": "^5.1.0",
60
+ "clean-jsdoc-theme": "^4.3.0",
59
61
  "cli-progress": "^3.12.0",
60
62
  "cli-spinners": "^3.0.0",
61
63
  "clipboardy": "^4.0.0",
64
+ "cloudinary": "^2.5.1",
62
65
  "color": "^4.2.3",
63
66
  "colors": "^1.4.0",
64
67
  "commander": "^12.1.0",
@@ -66,6 +69,7 @@
66
69
  "cors": "^2.8.5",
67
70
  "d3": "^7.9.0",
68
71
  "dotenv": "^16.3.1",
72
+ "easy-json-schema": "^0.0.2-beta",
69
73
  "easymde": "^2.18.0",
70
74
  "env-cmd": "^10.1.0",
71
75
  "express": "^4.18.2",
@@ -86,6 +90,7 @@
86
90
  "log-update": "^6.0.0",
87
91
  "mariadb": "^3.2.2",
88
92
  "marked": "^12.0.2",
93
+ "mocha": "^10.8.2",
89
94
  "mongoose": "^8.9.5",
90
95
  "morgan": "^1.10.0",
91
96
  "nodemailer": "^6.9.9",
@@ -94,6 +99,7 @@
94
99
  "peer": "^1.0.2",
95
100
  "peerjs": "^1.5.2",
96
101
  "pixi.js": "7.4.2",
102
+ "plantuml": "^0.0.2",
97
103
  "prom-client": "^15.1.2",
98
104
  "public-ip": "^6.0.1",
99
105
  "read": "^2.1.0",
@@ -105,17 +111,13 @@
105
111
  "socket.io": "^4.8.0",
106
112
  "sortablejs": "^1.15.0",
107
113
  "split-file": "^2.3.0",
114
+ "swagger-autogen": "^2.23.7",
108
115
  "swagger-ui-express": "^5.0.0",
109
116
  "systeminformation": "^5.23.7",
110
117
  "uglify-js": "^3.17.4",
111
118
  "validator": "^13.11.0",
112
119
  "vanilla-jsoneditor": "^2.3.2",
113
- "winston": "^3.11.0",
114
- "clean-jsdoc-theme": "^4.3.0",
115
- "easy-json-schema": "^0.0.2-beta",
116
- "mocha": "^10.8.2",
117
- "plantuml": "^0.0.2",
118
- "swagger-autogen": "^2.23.7"
120
+ "winston": "^3.11.0"
119
121
  },
120
122
  "devDependencies": {
121
123
  "clean-jsdoc-theme": "^4.3.0",
@@ -1,18 +1,40 @@
1
1
  import { timer } from '../client/components/core/CommonJs.js';
2
- import { cliSpinner } from '../server/conf.js';
2
+ import { cliSpinner, getNpmRootPath } from '../server/conf.js';
3
3
  import { loggerFactory } from '../server/logger.js';
4
4
  import { shellExec } from '../server/process.js';
5
+ import UnderpostDeploy from './deploy.js';
6
+ import UnderpostTest from './test.js';
5
7
 
6
8
  const logger = loggerFactory(import.meta);
7
9
 
8
10
  class UnderpostCluster {
9
11
  static API = {
10
- async init(options = { valkey: false, mariadb: false, valkey: false, full: false, info: false, nsUse: '' }) {
11
- if (options.nsUse) {
12
+ async init(
13
+ podName,
14
+ options = {
15
+ mongodb: false,
16
+ mongodb4: false,
17
+ mariadb: false,
18
+ valkey: false,
19
+ full: false,
20
+ info: false,
21
+ certManager: false,
22
+ listPods: false,
23
+ reset: false,
24
+ dev: false,
25
+ nsUse: '',
26
+ },
27
+ ) {
28
+ const npmRoot = getNpmRootPath();
29
+ const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
30
+ if (options.reset === true) return await UnderpostCluster.API.reset();
31
+ if (options.listPods === true) return console.table(UnderpostDeploy.API.get(podName ?? undefined));
32
+
33
+ if (options.nsUse && typeof options.nsUse === 'string') {
12
34
  shellExec(`kubectl config set-context --current --namespace=${options.nsUse}`);
13
35
  return;
14
36
  }
15
- if (options.info) {
37
+ if (options.info === true) {
16
38
  shellExec(`kubectl config get-contexts`); // config env persisente for manage multiple clusters
17
39
  shellExec(`kubectl config get-clusters`);
18
40
  shellExec(`kubectl get nodes -o wide`); // set of nodes of a cluster
@@ -40,28 +62,31 @@ class UnderpostCluster {
40
62
  logger.info('----------------------------------------------------------------');
41
63
  shellExec(`kubectl get secrets --all-namespaces -o wide`);
42
64
  shellExec(`docker secret ls`);
65
+ shellExec(`kubectl get crd --all-namespaces -o wide`);
43
66
  return;
44
67
  }
45
- const testClusterInit = shellExec(`kubectl get pods --all-namespaces -o wide`, {
46
- disableLog: true,
47
- silent: true,
48
- stdout: true,
49
- });
50
- if (!(testClusterInit.match('kube-system') && testClusterInit.match('kube-proxy'))) {
68
+
69
+ if (!UnderpostDeploy.API.get('kube-apiserver-kind-control-plane')[0]) {
51
70
  shellExec(`containerd config default > /etc/containerd/config.toml`);
52
71
  shellExec(`sed -i -e "s/SystemdCgroup = false/SystemdCgroup = true/g" /etc/containerd/config.toml`);
53
72
  // shellExec(`cp /etc/kubernetes/admin.conf ~/.kube/config`);
54
73
  shellExec(`sudo systemctl restart kubelet`);
55
74
  shellExec(`sudo service docker restart`);
56
- shellExec(`cd ./manifests && kind create cluster --config kind-config.yaml`);
75
+ shellExec(`sudo systemctl enable --now containerd.service`);
76
+ shellExec(`sudo systemctl restart containerd`);
77
+ shellExec(
78
+ `cd ${underpostRoot}/manifests && kind create cluster --config kind-config${
79
+ options?.dev === true ? '-dev' : ''
80
+ }.yaml`,
81
+ );
57
82
  shellExec(`sudo chown $(id -u):$(id -g) $HOME/.kube/config**`);
58
83
  } else logger.warn('Cluster already initialized');
59
84
 
60
- if (options.full || options.valkey) {
85
+ if (options.full === true || options.valkey === true) {
61
86
  shellExec(`kubectl delete statefulset service-valkey`);
62
- shellExec(`kubectl apply -k ./manifests/valkey`);
87
+ shellExec(`kubectl apply -k ${underpostRoot}/manifests/valkey`);
63
88
  }
64
- if (options.full || options.mariadb) {
89
+ if (options.full === true || options.mariadb === true) {
65
90
  shellExec(
66
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`,
67
92
  );
@@ -69,9 +94,31 @@ class UnderpostCluster {
69
94
  `sudo kubectl create secret generic github-secret --from-literal=GITHUB_TOKEN=${process.env.GITHUB_TOKEN}`,
70
95
  );
71
96
  shellExec(`kubectl delete statefulset mariadb-statefulset`);
72
- shellExec(`kubectl apply -k ./manifests/mariadb`);
97
+ shellExec(`kubectl apply -k ${underpostRoot}/manifests/mariadb`);
73
98
  }
74
- if (options.full || options.mongodb) {
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) {
75
122
  shellExec(
76
123
  `sudo kubectl create secret generic mongodb-keyfile --from-file=/home/dd/engine/engine-private/mongodb-keyfile`,
77
124
  );
@@ -79,46 +126,47 @@ class UnderpostCluster {
79
126
  `sudo kubectl create secret generic mongodb-secret --from-file=username=/home/dd/engine/engine-private/mongodb-username --from-file=password=/home/dd/engine/engine-private/mongodb-password`,
80
127
  );
81
128
  shellExec(`kubectl delete statefulset mongodb`);
82
- shellExec(`kubectl apply -k ./manifests/mongodb`);
83
-
84
- await new Promise(async (resolve) => {
85
- cliSpinner(3000, `[cluster.js] `, ` Load mongodb instance`, 'yellow', 'material');
86
- await timer(3000);
87
-
88
- const monitor = async () => {
89
- cliSpinner(1000, `[cluster.js] `, ` Load mongodb instance`, 'yellow', 'material');
90
- await timer(1000);
91
- if (
92
- shellExec(`kubectl get pods --all-namespaces -o wide`, {
93
- silent: true,
94
- stdout: true,
95
- disableLog: true,
96
- }).match(`mongodb-1 1/1 Running`)
97
- )
98
- return resolve();
99
- return monitor();
100
- };
101
- await monitor();
102
- });
129
+ shellExec(`kubectl apply -k ${underpostRoot}/manifests/mongodb`);
103
130
 
104
- const mongoConfig = {
105
- _id: 'rs0',
106
- members: [
107
- { _id: 0, host: 'mongodb-0.mongodb-service:27017', priority: 1 },
108
- { _id: 1, host: 'mongodb-1.mongodb-service:27017', priority: 1 },
109
- ],
110
- };
131
+ const successInstance = await UnderpostTest.API.statusMonitor('mongodb-1');
111
132
 
112
- shellExec(
113
- `sudo kubectl exec -i mongodb-0 -- mongosh --quiet --json=relaxed \
114
- --eval 'use admin' \
115
- --eval 'rs.initiate(${JSON.stringify(mongoConfig)})' \
116
- --eval 'rs.status()'`,
117
- );
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
+ };
141
+
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
+ }
118
149
  }
119
150
 
120
- if (options.full || options.contour)
151
+ if (options.full === true || options.contour === true)
121
152
  shellExec(`kubectl apply -f https://projectcontour.io/quickstart/contour.yaml`);
153
+
154
+ if (options.full === true || options.certManager === true) {
155
+ if (!UnderpostDeploy.API.get('cert-manager').find((p) => p.STATUS === 'Running')) {
156
+ shellExec(`helm repo add jetstack https://charts.jetstack.io --force-update`);
157
+ shellExec(
158
+ `helm install cert-manager jetstack/cert-manager \
159
+ --namespace cert-manager \
160
+ --create-namespace \
161
+ --version v1.17.0 \
162
+ --set crds.enabled=true`,
163
+ );
164
+ }
165
+
166
+ const letsEncName = 'letsencrypt-prod';
167
+ shellExec(`sudo kubectl delete ClusterIssuer ${letsEncName}`);
168
+ shellExec(`sudo kubectl apply -f ${underpostRoot}/manifests/${letsEncName}.yaml`);
169
+ }
122
170
  },
123
171
  reset() {
124
172
  shellExec(`kind get clusters | xargs -t -n1 kind delete cluster --name`);
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 = { disableKindCluster: 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(deployList = 'default', options = { import: false, export: false }) {
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 podName = `mariadb-statefulset-0`;
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
- if (options.import === true) {
80
- shellExec(`sudo kubectl cp ${_toSqlPath} ${nameSpace}/${podName}:/${dbName}.sql`);
81
- const cmd = `mariadb -u ${user} -p${password} ${dbName} < /${dbName}.sql`;
82
- shellExec(
83
- `kubectl exec -i ${podName} -- ${serviceName} -p${password} -e 'CREATE DATABASE ${dbName};'`,
84
- );
85
- shellExec(`sudo kubectl exec -i ${podName} -- sh -c "${cmd}"`);
86
- }
87
- if (options.export === true) {
88
- const cmd = `mariadb-dump --user=${user} --password=${password} --lock-tables ${dbName} > ${sqlContainerPath}`;
89
- shellExec(`sudo kubectl exec -i ${podName} -- sh -c "${cmd}"`);
90
- shellExec(`sudo kubectl cp ${nameSpace}/${podName}:${sqlContainerPath} ${_toNewSqlPath}`);
91
- await splitFileFactory(dbName, _toNewSqlPath);
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 podName = `mongodb-0`;
99
- shellExec(`sudo kubectl cp ${_toBsonPath} ${nameSpace}/${podName}:/${dbName}`);
100
- const cmd = `mongorestore -d ${dbName} /${dbName}`;
101
- shellExec(`sudo kubectl exec -i ${podName} -- sh -c "${cmd}"`);
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 podName = `backup-access`;
105
- const containerBaseBackupPath = '/backup';
106
- let timeFolder = shellExec(
107
- `sudo kubectl exec -i ${podName} -- sh -c "cd ${containerBaseBackupPath} && ls -a"`,
108
- {
109
- stdout: true,
110
- disableLog: false,
111
- silent: true,
112
- },
113
- ).split(`\n`);
114
- timeFolder = timeFolder[timeFolder.length - 2];
115
- if (timeFolder === '..') {
116
- logger.warn(`Cannot backup available`, { timeFolder });
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}:${containerBaseBackupPath}/${timeFolder}/${dbName} ${_toNewBsonPath}`,
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(