underpost 2.8.44 → 2.8.46

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 (45) hide show
  1. package/.github/workflows/ghpkg.yml +13 -46
  2. package/.github/workflows/npmpkg.yml +67 -0
  3. package/.github/workflows/publish.yml +5 -5
  4. package/.github/workflows/pwa-microservices-template.page.yml +3 -2
  5. package/.github/workflows/pwa-microservices-template.test.yml +2 -2
  6. package/.vscode/settings.json +2 -0
  7. package/CHANGELOG.md +16 -0
  8. package/Dockerfile +3 -24
  9. package/bin/build.js +37 -0
  10. package/bin/deploy.js +1 -14
  11. package/bin/file.js +19 -13
  12. package/bin/index.js +117 -39
  13. package/docker-compose.yml +1 -1
  14. package/manifests/mongodb/backup-access.yaml +16 -0
  15. package/manifests/mongodb/backup-cronjob.yaml +40 -0
  16. package/manifests/mongodb/backup-pv-pvc.yaml +22 -0
  17. package/manifests/mongodb/configmap.yaml +26 -0
  18. package/manifests/mongodb/headless-service.yaml +10 -0
  19. package/manifests/mongodb/kustomization.yaml +11 -0
  20. package/manifests/mongodb/pv-pvc.yaml +23 -0
  21. package/manifests/mongodb/statefulset.yaml +125 -0
  22. package/manifests/valkey/kustomization.yaml +2 -2
  23. package/manifests/valkey/service.yaml +17 -0
  24. package/manifests/valkey/statefulset.yaml +39 -0
  25. package/package.json +25 -5
  26. package/src/cli/cluster.js +154 -0
  27. package/src/cli/db.js +98 -0
  28. package/src/cli/env.js +52 -0
  29. package/src/cli/image.js +118 -0
  30. package/src/cli/repository.js +108 -0
  31. package/src/cli/script.js +29 -0
  32. package/src/cli/secrets.js +37 -0
  33. package/src/cli/test.js +32 -0
  34. package/src/client/components/core/Auth.js +22 -4
  35. package/src/client/components/core/CommonJs.js +73 -1
  36. package/src/client/components/core/Input.js +1 -1
  37. package/src/client/components/core/Scroll.js +1 -0
  38. package/src/client/components/core/Translate.js +4 -0
  39. package/src/index.js +61 -24
  40. package/src/server/conf.js +6 -208
  41. package/src/server/logger.js +3 -3
  42. package/src/server/network.js +2 -2
  43. package/startup.cjs +0 -12
  44. /package/manifests/deployment/{mongo-express.yaml → mongo-express/deployment.yaml} +0 -0
  45. /package/manifests/deployment/{phpmyadmin.yaml → phpmyadmin/deployment.yaml} +0 -0
@@ -0,0 +1,16 @@
1
+ apiVersion: v1
2
+ kind: Pod
3
+ metadata:
4
+ name: backup-access
5
+ spec:
6
+ containers:
7
+ - name: busybox
8
+ image: busybox
9
+ command: ['sh', '-c', 'sleep 3600']
10
+ volumeMounts:
11
+ - name: backup-storage
12
+ mountPath: /backup
13
+ volumes:
14
+ - name: backup-storage
15
+ persistentVolumeClaim:
16
+ claimName: backup-pvc
@@ -0,0 +1,40 @@
1
+ apiVersion: batch/v1
2
+ kind: CronJob
3
+ metadata:
4
+ name: mongodb-backup
5
+ spec:
6
+ schedule: '*/5 * * * *' # Runs backup every five minutes
7
+ jobTemplate:
8
+ spec:
9
+ template:
10
+ spec:
11
+ containers:
12
+ - name: mongodump
13
+ image: docker.io/library/mongo:latest
14
+ command:
15
+ - sh
16
+ - -c
17
+ - |
18
+ # Perform backup
19
+ mongodump -u $MONGO_INITDB_ROOT_USERNAME -p $MONGO_INITDB_ROOT_PASSWORD --host=mongodb-service --port=27017 --out=/backup/$(date +\%Y-\%m-\%dT\%H-\%M-\%S)
20
+ # Remove backups older than 7 days
21
+ find /backup -type d -mtime +7 -exec rm -rf {} +
22
+ volumeMounts:
23
+ - name: backup-storage
24
+ mountPath: /backup
25
+ env:
26
+ - name: MONGO_INITDB_ROOT_USERNAME
27
+ valueFrom:
28
+ secretKeyRef:
29
+ name: mongodb-secret
30
+ key: username
31
+ - name: MONGO_INITDB_ROOT_PASSWORD
32
+ valueFrom:
33
+ secretKeyRef:
34
+ name: mongodb-secret
35
+ key: password
36
+ restartPolicy: Never
37
+ volumes:
38
+ - name: backup-storage
39
+ persistentVolumeClaim:
40
+ claimName: backup-pvc
@@ -0,0 +1,22 @@
1
+ apiVersion: v1
2
+ kind: PersistentVolume
3
+ metadata:
4
+ name: backup-pv
5
+ spec:
6
+ capacity:
7
+ storage: 5Gi
8
+ accessModes:
9
+ - ReadWriteOnce
10
+ hostPath:
11
+ path: /mnt/backup
12
+ ---
13
+ apiVersion: v1
14
+ kind: PersistentVolumeClaim
15
+ metadata:
16
+ name: backup-pvc
17
+ spec:
18
+ accessModes:
19
+ - ReadWriteOnce
20
+ resources:
21
+ requests:
22
+ storage: 5Gi
@@ -0,0 +1,26 @@
1
+ # origin conf: /etc/mongod.conf
2
+ apiVersion: v1
3
+ kind: ConfigMap
4
+ metadata:
5
+ name: mongodb-config-file
6
+ namespace: default
7
+ data:
8
+ mongod.conf: |
9
+ storage:
10
+ dbPath: /data/db
11
+ systemLog:
12
+ destination: file
13
+ logAppend: true
14
+ path: /var/log/mongodb/mongod.log
15
+ replication:
16
+ replSetName: rs0
17
+ net:
18
+ bindIp: 127.0.0.1
19
+ port: 27017
20
+ processManagement:
21
+ fork: true
22
+ setParameter:
23
+ enableLocalhostAuthBypass: false
24
+ security:
25
+ authorization: enabled
26
+ keyFile: /etc/mongodb-keyfile
@@ -0,0 +1,10 @@
1
+ apiVersion: v1
2
+ kind: Service
3
+ metadata:
4
+ name: mongodb-service
5
+ spec:
6
+ clusterIP: None
7
+ selector:
8
+ app: mongodb
9
+ ports:
10
+ - port: 27017
@@ -0,0 +1,11 @@
1
+ ---
2
+ # kubectl apply -k core/.
3
+ apiVersion: kustomize.config.k8s.io/v1beta1
4
+ kind: Kustomization
5
+ resources:
6
+ - pv-pvc.yaml
7
+ - headless-service.yaml
8
+ - statefulset.yaml
9
+ - backup-pv-pvc.yaml
10
+ - backup-cronjob.yaml
11
+ - backup-access.yaml
@@ -0,0 +1,23 @@
1
+ apiVersion: v1
2
+ kind: PersistentVolume
3
+ metadata:
4
+ name: mongodb-pv
5
+ spec:
6
+ capacity:
7
+ storage: 5Gi
8
+ accessModes:
9
+ - ReadWriteOnce
10
+ hostPath:
11
+ path: /data/mongodb
12
+ ---
13
+ apiVersion: v1
14
+ kind: PersistentVolumeClaim
15
+ metadata:
16
+ name: mongodb-pvc
17
+ spec:
18
+ storageClassName: ''
19
+ accessModes:
20
+ - ReadWriteOnce
21
+ resources:
22
+ requests:
23
+ storage: 5Gi
@@ -0,0 +1,125 @@
1
+ apiVersion: apps/v1
2
+ kind: StatefulSet
3
+ metadata:
4
+ name: mongodb # Specifies the name of the statefulset
5
+ spec:
6
+ serviceName: 'mongodb-service' # Specifies the service to use
7
+ replicas: 2
8
+ selector:
9
+ matchLabels:
10
+ app: mongodb
11
+ template:
12
+ metadata:
13
+ labels:
14
+ app: mongodb
15
+ spec:
16
+ containers:
17
+ - name: mongodb
18
+ image: docker.io/library/mongo:latest
19
+ command:
20
+ - mongod
21
+ - '--replSet'
22
+ - 'rs0'
23
+ # - '--config'
24
+ # - '-f'
25
+ # - '/etc/mongod.conf'
26
+ # - '--auth'
27
+ # - '--clusterAuthMode'
28
+ # - 'keyFile'
29
+ # - '--keyFile'
30
+ # - '/etc/mongodb-keyfile'
31
+ # - '--interleave'
32
+ # - 'all'
33
+ # - '--wiredTigerCacheSizeGB'
34
+ # - '0.25'
35
+ # - '--setParameter'
36
+ # - 'authenticationMechanisms=SCRAM-SHA-1'
37
+ # - '--fork'
38
+ - '--logpath'
39
+ - '/var/log/mongodb/mongod.log'
40
+ - '--bind_ip_all'
41
+ # command: ['sh', '-c']
42
+ # args:
43
+ # - |
44
+ # mongod --replSet rs0 --bind_ip_all &
45
+ # sleep 1000
46
+ # if mongosh --host mongodb-0.mongodb-service:27017 --eval "rs.status()" | grep -q "not yet initialized"; then
47
+ # mongosh --host mongodb-0.mongodb-service:27017 <<EOF
48
+ # use admin;
49
+ # rs.initiate({
50
+ # _id: "rs0",
51
+ # members: [
52
+ # { _id: 0, host: "mongodb-0.mongodb-service:27017", priority: 1 },
53
+ # { _id: 1, host: "mongodb-1.mongodb-service:27017", priority: 1 }
54
+ # ]
55
+ # });
56
+ # db.getSiblingDB("admin").createUser({
57
+ # user: process.env.MONGO_INITDB_ROOT_USERNAME,
58
+ # pwd: process.env.MONGO_INITDB_ROOT_PASSWORD,
59
+ # roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
60
+ # });
61
+ # use default;
62
+ # db.createUser(
63
+ # {
64
+ # user: process.env.MONGO_INITDB_ROOT_USERNAME,
65
+ # pwd: process.env.MONGO_INITDB_ROOT_PASSWORD,
66
+ # roles: [
67
+ # { role: "read", db: "test" },
68
+ # { role: "readWrite", db: "default" }
69
+ # ]
70
+ # }
71
+ # );
72
+ # EOF
73
+ # fi
74
+ # wait
75
+ ports:
76
+ - containerPort: 27017
77
+ volumeMounts:
78
+ - name: mongodb-storage
79
+ mountPath: /data/db
80
+ - name: keyfile
81
+ mountPath: /etc/mongodb-keyfile
82
+ readOnly: true
83
+ # - name: mongodb-configuration-file
84
+ # mountPath: /etc/mongod.conf
85
+ # subPath: mongod.conf
86
+ # readOnly: true
87
+ # - name: mongodb-config
88
+ # mountPath: /config
89
+ env:
90
+ - name: MONGO_INITDB_ROOT_USERNAME
91
+ valueFrom:
92
+ secretKeyRef:
93
+ name: mongodb-secret
94
+ key: username
95
+ - name: MONGO_INITDB_ROOT_PASSWORD
96
+ valueFrom:
97
+ secretKeyRef:
98
+ name: mongodb-secret
99
+ key: password
100
+ resources:
101
+ requests:
102
+ cpu: '100m'
103
+ memory: '256Mi'
104
+ limits:
105
+ cpu: '500m'
106
+ memory: '512Mi'
107
+ volumes:
108
+ - name: keyfile
109
+ secret:
110
+ secretName: mongodb-keyfile
111
+ defaultMode: 0400
112
+ # - name: mongodb-configuration-file
113
+ # configMap:
114
+ # name: mongodb-config-file
115
+ # - name: mongodb-config
116
+ # configMap:
117
+ # name: mongodb-config
118
+ volumeClaimTemplates:
119
+ - metadata:
120
+ name: mongodb-storage
121
+ spec:
122
+ accessModes: ['ReadWriteOnce']
123
+ resources:
124
+ requests:
125
+ storage: 5Gi
@@ -3,5 +3,5 @@
3
3
  apiVersion: kustomize.config.k8s.io/v1beta1
4
4
  kind: Kustomization
5
5
  resources:
6
- - underpost-engine-valkey-service.yaml
7
- - underpost-engine-valkey-statefulset.yaml
6
+ - service.yaml
7
+ - statefulset.yaml
@@ -0,0 +1,17 @@
1
+ ---
2
+ apiVersion: v1
3
+ kind: Service
4
+ metadata:
5
+ name: service-valkey
6
+ namespace: default
7
+ spec:
8
+ ports:
9
+ - port: 6379
10
+ targetPort: 6379
11
+ selector:
12
+ app: service-valkey
13
+ ipFamilyPolicy: PreferDualStack
14
+ ipFamilies:
15
+ - IPv4
16
+ # - IPv6
17
+ type: ClusterIP
@@ -0,0 +1,39 @@
1
+ ---
2
+ apiVersion: apps/v1
3
+ kind: StatefulSet
4
+ metadata:
5
+ name: service-valkey
6
+ namespace: default
7
+ spec:
8
+ serviceName: service-valkey
9
+ replicas: 1
10
+ selector:
11
+ matchLabels:
12
+ app: service-valkey
13
+ template:
14
+ metadata:
15
+ labels:
16
+ app: service-valkey
17
+ spec:
18
+ containers:
19
+ - name: service-valkey
20
+ image: docker.io/valkey/valkey:latest
21
+ env:
22
+ - name: TZ
23
+ value: Europe/Zurich
24
+ ports:
25
+ - containerPort: 6379
26
+ startupProbe:
27
+ tcpSocket:
28
+ port: 6379
29
+ failureThreshold: 30
30
+ periodSeconds: 5
31
+ timeoutSeconds: 5
32
+ livenessProbe:
33
+ tcpSocket:
34
+ port: 6379
35
+ failureThreshold: 2
36
+ periodSeconds: 30
37
+ timeoutSeconds: 5
38
+ restartPolicy: Always
39
+ automountServiceAccountToken: false
package/package.json CHANGED
@@ -2,20 +2,27 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "underpost",
5
- "version": "2.8.44",
5
+ "version": "2.8.46",
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",
9
- "build": "node bin/deploy build-full-client",
9
+ "test": "env-cmd -f .env.test c8 mocha",
10
+ "pm2": "env-cmd -f .env.production pm2 start src/server.js --node-args=\"--max-old-space-size=8192\" --name engine",
10
11
  "dev": "env-cmd -f .env.development node src/client.dev default",
12
+ "dev-img": "env-cmd -f .env.development node src/server",
11
13
  "dev-api": "env-cmd -f .env.development nodemon --watch src --ignore src/client src/api",
14
+ "dev-client": "env-cmd -f .env.development node src/client.dev",
15
+ "proxy": "node src/proxy proxy",
12
16
  "docs": "jsdoc -c jsdoc.json",
13
17
  "install-global": "npm install -g pm2 && npm install -g jsdoc && npm install -g prettier && npm install -g env-cmd && npm install -g yarn && npm install -g auto-changelog",
14
18
  "install-test": "npm install -g mocha && npm install -g c8 && npm install -g nyc && npm install -g coveralls",
19
+ "install-underpost": "cp -a $(npm root -g)/underpost/node_modules ./node_modules && npm install --only=dev --ignore-scripts",
15
20
  "install": "npm run install-global && npm run install-test",
16
21
  "docker:start": "docker-compose up",
17
22
  "prettier": "prettier --write .",
18
- "test": "env-cmd -f .env.test c8 mocha"
23
+ "fix": "npm audit fix --force && npm audit",
24
+ "changelog": "auto-changelog",
25
+ "build": "node bin/deploy build-full-client"
19
26
  },
20
27
  "bin": {
21
28
  "underpost": "bin/index.js"
@@ -25,6 +32,14 @@
25
32
  "url": "git+https://github.com/underpostnet/pwa-microservices-template.git"
26
33
  },
27
34
  "keywords": [
35
+ "pwa",
36
+ "microservices",
37
+ "template",
38
+ "builder",
39
+ "pwa",
40
+ "microservices",
41
+ "template",
42
+ "builder",
28
43
  "engine",
29
44
  "server",
30
45
  "proxy",
@@ -99,12 +114,17 @@
99
114
  "uglify-js": "^3.17.4",
100
115
  "validator": "^13.11.0",
101
116
  "vanilla-jsoneditor": "^2.3.2",
102
- "winston": "^3.11.0"
117
+ "winston": "^3.11.0",
118
+ "clean-jsdoc-theme": "^4.3.0",
119
+ "easy-json-schema": "^0.0.2-beta",
120
+ "mocha": "^10.8.2",
121
+ "plantuml": "^0.0.2",
122
+ "swagger-autogen": "^2.23.7"
103
123
  },
104
124
  "devDependencies": {
105
125
  "clean-jsdoc-theme": "^4.3.0",
106
126
  "easy-json-schema": "^0.0.2-beta",
107
- "mocha": "^10.4.0",
127
+ "mocha": "^10.8.2",
108
128
  "plantuml": "^0.0.2",
109
129
  "swagger-autogen": "^2.23.7"
110
130
  },
@@ -0,0 +1,154 @@
1
+ import { timer } from '../client/components/core/CommonJs.js';
2
+ import { cliSpinner } from '../server/conf.js';
3
+ import { loggerFactory } from '../server/logger.js';
4
+ import { shellExec } from '../server/process.js';
5
+
6
+ const logger = loggerFactory(import.meta);
7
+
8
+ class UnderpostCluster {
9
+ static API = {
10
+ async init(options = { valkey: false, mariadb: false, valkey: false, full: false, info: false, nsUse: '' }) {
11
+ if (options.nsUse) {
12
+ shellExec(`kubectl config set-context --current --namespace=${options.nsUse}`);
13
+ return;
14
+ }
15
+ if (options.info) {
16
+ shellExec(`kubectl config get-contexts`); // config env persisente for manage multiple clusters
17
+ shellExec(`kubectl config get-clusters`);
18
+ shellExec(`kubectl get nodes -o wide`); // set of nodes of a cluster
19
+ shellExec(`kubectl config view | grep namespace`);
20
+ shellExec(`kubectl get ns -o wide`); // A namespace can have pods of different nodes
21
+ shellExec(`kubectl get pvc --all-namespaces -o wide`); // PersistentVolumeClaim -> request storage service
22
+ shellExec(`kubectl get pv --all-namespaces -o wide`); // PersistentVolume -> real storage
23
+ shellExec(`kubectl get cronjob --all-namespaces -o wide`);
24
+ shellExec(`kubectl get svc --all-namespaces -o wide`); // proxy dns gate way -> deployments, statefulsets, pods
25
+ shellExec(`kubectl get statefulsets --all-namespaces -o wide`); // set pods with data/volume persistence
26
+ shellExec(`kubectl get deployments --all-namespaces -o wide`); // set pods
27
+ shellExec(`kubectl get configmap --all-namespaces -o wide`);
28
+ shellExec(`kubectl get pods --all-namespaces -o wide`);
29
+ shellExec(
30
+ `kubectl get pod --all-namespaces -o="custom-columns=NAME:.metadata.name,INIT-CONTAINERS:.spec.initContainers[*].name,CONTAINERS:.spec.containers[*].name"`,
31
+ );
32
+ shellExec(
33
+ `kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\\n"}{.metadata.name}{":\\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}'`,
34
+ );
35
+ console.log();
36
+ logger.info('contour -------------------------------------------------');
37
+ for (const _k of ['Cluster', 'HTTPProxy', 'ClusterIssuer', 'Certificate']) {
38
+ shellExec(`kubectl get ${_k} --all-namespaces -o wide`);
39
+ }
40
+ logger.info('----------------------------------------------------------------');
41
+ shellExec(`kubectl get secrets --all-namespaces -o wide`);
42
+ shellExec(`docker secret ls`);
43
+ return;
44
+ }
45
+ const testClusterInit = shellExec(`kubectl get pods --all-namespaces -o wide`, {
46
+ disableLogging: true,
47
+ silent: true,
48
+ stdout: true,
49
+ });
50
+ if (!(testClusterInit.match('kube-system') && testClusterInit.match('kube-proxy'))) {
51
+ shellExec(`containerd config default > /etc/containerd/config.toml`);
52
+ shellExec(`sed -i -e "s/SystemdCgroup = false/SystemdCgroup = true/g" /etc/containerd/config.toml`);
53
+ // shellExec(`cp /etc/kubernetes/admin.conf ~/.kube/config`);
54
+ shellExec(`sudo systemctl restart kubelet`);
55
+ shellExec(`sudo service docker restart`);
56
+ shellExec(`cd ./manifests && kind create cluster --config kind-config.yaml`);
57
+ shellExec(`sudo chown $(id -u):$(id -g) $HOME/.kube/config**`);
58
+ } else logger.warn('Cluster already initialized');
59
+
60
+ if (options.full || options.valkey) {
61
+ shellExec(`kubectl delete statefulset service-valkey`);
62
+ shellExec(`kubectl apply -k ./manifests/valkey`);
63
+ }
64
+ if (options.full || options.mariadb) {
65
+ shellExec(
66
+ `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
+ );
68
+ shellExec(
69
+ `sudo kubectl create secret generic github-secret --from-literal=GITHUB_TOKEN=${process.env.GITHUB_TOKEN}`,
70
+ );
71
+ shellExec(`kubectl delete statefulset mariadb-statefulset`);
72
+ shellExec(`kubectl apply -k ./manifests/mariadb`);
73
+ }
74
+ if (options.full || options.mongodb) {
75
+ shellExec(
76
+ `sudo kubectl create secret generic mongodb-keyfile --from-file=/home/dd/engine/engine-private/mongodb-keyfile`,
77
+ );
78
+ shellExec(
79
+ `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
+ );
81
+ 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
+ });
103
+
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
+ };
111
+
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
+ );
118
+ }
119
+
120
+ if (options.full || options.contour)
121
+ shellExec(`kubectl apply -f https://projectcontour.io/quickstart/contour.yaml`);
122
+ },
123
+ reset() {
124
+ shellExec(`kind get clusters | xargs -t -n1 kind delete cluster --name`);
125
+ shellExec(`sudo kubeadm reset -f`);
126
+ shellExec('sudo rm -f /etc/cni/net.d/10-flannel.conflist');
127
+ shellExec('sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X');
128
+ shellExec('sudo rm -f $HOME/.kube/config');
129
+ shellExec('sudo rm -rf /root/.local/share/Trash/files/*');
130
+ shellExec('sudo docker system prune -a -f');
131
+ shellExec('sudo service docker stop');
132
+ shellExec(`sudo rm -rf /var/lib/containers/storage/*`);
133
+ shellExec(`sudo rm -rf /var/lib/docker/volumes/*`);
134
+ shellExec(`sudo rm -rf /var/lib/docker~/*`);
135
+ shellExec(`sudo rm -rf /home/containers/storage/*`);
136
+ shellExec(`sudo rm -rf /home/docker/*`);
137
+ shellExec('sudo mv /var/lib/docker /var/lib/docker~');
138
+ shellExec('sudo mkdir /home/docker');
139
+ shellExec('sudo chmod 0711 /home/docker');
140
+ shellExec('sudo ln -s /home/docker /var/lib/docker');
141
+ shellExec(`sudo podman system prune -a -f`);
142
+ shellExec(`sudo podman system prune --all --volumes --force`);
143
+ shellExec(`sudo podman system prune --external --force`);
144
+ shellExec(`sudo podman system prune --all --volumes --force`);
145
+ shellExec(`sudo mkdir -p /home/containers/storage`);
146
+ shellExec('sudo chmod 0711 /home/containers/storage');
147
+ shellExec(
148
+ `sudo sed -i -e "s@/var/lib/containers/storage@/home/containers/storage@g" /etc/containers/storage.conf`,
149
+ );
150
+ shellExec(`sudo podman system reset -f`);
151
+ },
152
+ };
153
+ }
154
+ export default UnderpostCluster;
package/src/cli/db.js ADDED
@@ -0,0 +1,98 @@
1
+ import { mergeFile } from '../server/conf.js';
2
+ import { loggerFactory } from '../server/logger.js';
3
+ import { shellExec } from '../server/process.js';
4
+ import fs from 'fs-extra';
5
+
6
+ const logger = loggerFactory(import.meta);
7
+
8
+ class UnderpostDB {
9
+ static API = {
10
+ async import(options = { import: 'default' }) {
11
+ for (const _deployId of options.import.split(',')) {
12
+ const deployId = _deployId.trim();
13
+ if (!deployId) continue;
14
+ const dbs = {};
15
+ const repoName = `engine-${deployId.split('dd-')[1]}-cron-backups`;
16
+
17
+ const confServer = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'));
18
+ for (const host of Object.keys(confServer)) {
19
+ for (const path of Object.keys(confServer[host])) {
20
+ const { db } = confServer[host][path];
21
+ if (db) {
22
+ const { provider, name, user, password } = db;
23
+ if (!dbs[provider]) dbs[provider] = {};
24
+
25
+ if (!(name in dbs[provider]))
26
+ dbs[provider][name] = { user, password, hostFolder: host + path.replaceAll('/', '-') };
27
+ }
28
+ }
29
+ }
30
+
31
+ if (!fs.existsSync(`../${repoName}`)) {
32
+ shellExec(`cd .. && underpost clone ${process.env.GITHUB_USERNAME}/${repoName}`);
33
+ } else {
34
+ shellExec(`cd ../${repoName} && underpost pull . ${process.env.GITHUB_USERNAME}/${repoName}`);
35
+ }
36
+
37
+ for (const provider of Object.keys(dbs)) {
38
+ for (const dbName of Object.keys(dbs[provider])) {
39
+ const { hostFolder, user, password } = dbs[provider][dbName];
40
+ if (hostFolder) {
41
+ logger.info('import', { hostFolder, provider, dbName });
42
+
43
+ const backUpPath = `../${repoName}/${hostFolder}`;
44
+ const times = await fs.readdir(backUpPath);
45
+ const currentBackupTimestamp = Math.max(...times.map((t) => parseInt(t)));
46
+ dbs[provider][dbName].currentBackupTimestamp = currentBackupTimestamp;
47
+
48
+ const _fromPartsParts = `../${repoName}/${hostFolder}/${currentBackupTimestamp}/${dbName}-parths.json`;
49
+ const _toSqlPath = `../${repoName}/${hostFolder}/${currentBackupTimestamp}/${dbName}.sql`;
50
+ const _toBsonPath = `../${repoName}/${hostFolder}/${currentBackupTimestamp}/${dbName}`;
51
+
52
+ if (fs.existsSync(_fromPartsParts) && !fs.existsSync(_toSqlPath)) {
53
+ const names = JSON.parse(fs.readFileSync(_fromPartsParts, 'utf8')).map((_path) => {
54
+ return `../${repoName}/${hostFolder}/${currentBackupTimestamp}/${_path.split('/').pop()}`;
55
+ });
56
+ logger.info('merge Back Up paths', {
57
+ _fromPartsParts,
58
+ _toSqlPath,
59
+ names,
60
+ });
61
+ await mergeFile(names, _toSqlPath);
62
+ }
63
+
64
+ switch (provider) {
65
+ case 'mariadb': {
66
+ const podName = `mariadb-statefulset-0`;
67
+ const nameSpace = 'default';
68
+ const serviceName = 'mariadb';
69
+ shellExec(`sudo kubectl cp ${_toSqlPath} ${nameSpace}/${podName}:/${dbName}.sql`);
70
+ const cmd = `mariadb -u ${user} -p${password} ${dbName} < /${dbName}.sql`;
71
+ shellExec(
72
+ `kubectl exec -i ${podName} -- ${serviceName} -p${password} -e 'CREATE DATABASE ${dbName};'`,
73
+ );
74
+ shellExec(`sudo kubectl exec -i ${podName} -- sh -c "${cmd}"`);
75
+ break;
76
+ }
77
+
78
+ case 'mongoose': {
79
+ const podName = `mongodb-0`;
80
+ const nameSpace = 'default';
81
+ shellExec(`sudo kubectl cp ${_toBsonPath} ${nameSpace}/${podName}:/${dbName}`);
82
+ const cmd = `mongorestore -d ${dbName} /${dbName}`;
83
+ shellExec(`sudo kubectl exec -i ${podName} -- sh -c "${cmd}"`);
84
+ break;
85
+ }
86
+
87
+ default:
88
+ break;
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ },
95
+ };
96
+ }
97
+
98
+ export default UnderpostDB;