underpost 2.8.44 → 2.8.451
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/.vscode/settings.json +2 -0
- package/CHANGELOG.md +16 -0
- package/Dockerfile +3 -24
- package/bin/build.js +31 -0
- package/bin/file.js +15 -13
- package/bin/index.js +100 -40
- package/docker-compose.yml +1 -1
- package/manifests/mongodb/backup-access.yaml +16 -0
- package/manifests/mongodb/backup-cronjob.yaml +40 -0
- package/manifests/mongodb/backup-pv-pvc.yaml +22 -0
- package/manifests/mongodb/configmap.yaml +26 -0
- package/manifests/mongodb/headless-service.yaml +10 -0
- package/manifests/mongodb/kustomization.yaml +11 -0
- package/manifests/mongodb/pv-pvc.yaml +23 -0
- package/manifests/mongodb/statefulset.yaml +125 -0
- package/manifests/valkey/kustomization.yaml +2 -2
- package/manifests/valkey/service.yaml +17 -0
- package/manifests/valkey/statefulset.yaml +39 -0
- package/package.json +9 -3
- package/src/cli/cluster.js +154 -0
- package/src/cli/env.js +52 -0
- package/src/cli/image.js +118 -0
- package/src/cli/repository.js +108 -0
- package/src/cli/script.js +29 -0
- package/src/cli/secrets.js +37 -0
- package/src/cli/test.js +32 -0
- package/src/client/components/core/CommonJs.js +73 -1
- package/src/client/components/core/Input.js +1 -1
- package/src/client/components/core/Scroll.js +1 -0
- package/src/index.js +53 -24
- package/src/server/conf.js +6 -208
- package/src/server/logger.js +2 -3
- package/src/server/network.js +1 -1
- package/startup.cjs +0 -12
- /package/manifests/deployment/{mongo-express.yaml → mongo-express/deployment.yaml} +0 -0
- /package/manifests/deployment/{phpmyadmin.yaml → phpmyadmin/deployment.yaml} +0 -0
|
@@ -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,26 @@
|
|
|
2
2
|
"type": "module",
|
|
3
3
|
"main": "src/index.js",
|
|
4
4
|
"name": "underpost",
|
|
5
|
-
"version": "2.8.
|
|
5
|
+
"version": "2.8.451",
|
|
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
|
-
"
|
|
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",
|
|
15
19
|
"install": "npm run install-global && npm run install-test",
|
|
16
20
|
"docker:start": "docker-compose up",
|
|
17
21
|
"prettier": "prettier --write .",
|
|
18
|
-
"
|
|
22
|
+
"fix": "npm audit fix --force && npm audit",
|
|
23
|
+
"changelog": "auto-changelog",
|
|
24
|
+
"build": "node bin/deploy build-full-client"
|
|
19
25
|
},
|
|
20
26
|
"bin": {
|
|
21
27
|
"underpost": "bin/index.js"
|
|
@@ -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-0 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
|
+
`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/env.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { getNpmRootPath, writeEnv } from '../server/conf.js';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import { loggerFactory } from '../server/logger.js';
|
|
4
|
+
import dotenv from 'dotenv';
|
|
5
|
+
|
|
6
|
+
dotenv.config();
|
|
7
|
+
|
|
8
|
+
const logger = loggerFactory(import.meta);
|
|
9
|
+
|
|
10
|
+
class UnderpostRootEnv {
|
|
11
|
+
static API = {
|
|
12
|
+
set(key, value) {
|
|
13
|
+
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
14
|
+
const envPath = `${exeRootPath}/.env`;
|
|
15
|
+
let env = {};
|
|
16
|
+
if (fs.existsSync(envPath)) env = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
|
17
|
+
env[key] = value;
|
|
18
|
+
writeEnv(envPath, env);
|
|
19
|
+
},
|
|
20
|
+
delete(key) {
|
|
21
|
+
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
22
|
+
const envPath = `${exeRootPath}/.env`;
|
|
23
|
+
let env = {};
|
|
24
|
+
if (fs.existsSync(envPath)) env = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
|
25
|
+
delete env[key];
|
|
26
|
+
writeEnv(envPath, env);
|
|
27
|
+
},
|
|
28
|
+
get(key) {
|
|
29
|
+
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
30
|
+
const envPath = `${exeRootPath}/.env`;
|
|
31
|
+
if (!fs.existsSync(envPath)) return logger.error(`Unable to find underpost root environment`);
|
|
32
|
+
const env = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
|
33
|
+
logger.info('underpost root', { [key]: env[key] });
|
|
34
|
+
return env[key];
|
|
35
|
+
},
|
|
36
|
+
list() {
|
|
37
|
+
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
38
|
+
const envPath = `${exeRootPath}/.env`;
|
|
39
|
+
if (!fs.existsSync(envPath)) return logger.error(`Unable to find underpost root environment`);
|
|
40
|
+
const env = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
|
41
|
+
logger.info('underpost root', env);
|
|
42
|
+
return env;
|
|
43
|
+
},
|
|
44
|
+
clean() {
|
|
45
|
+
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
46
|
+
const envPath = `${exeRootPath}/.env`;
|
|
47
|
+
fs.removeSync(envPath);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default UnderpostRootEnv;
|
package/src/cli/image.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import Underpost from '../index.js';
|
|
3
|
+
import { shellExec } from '../server/process.js';
|
|
4
|
+
import { MariaDB } from '../db/mariadb/MariaDB.js';
|
|
5
|
+
import dotenv from 'dotenv';
|
|
6
|
+
import { getNpmRootPath } from '../server/conf.js';
|
|
7
|
+
|
|
8
|
+
dotenv.config();
|
|
9
|
+
|
|
10
|
+
class UnderpostImage {
|
|
11
|
+
static API = {
|
|
12
|
+
dockerfile: {
|
|
13
|
+
pullBaseImages() {
|
|
14
|
+
shellExec(`sudo podman pull docker.io/library/debian:buster`);
|
|
15
|
+
},
|
|
16
|
+
build(deployId = 'default', env = 'development', path = '.', imageArchive = false) {
|
|
17
|
+
const imgName = `${deployId}-${env}:${Underpost.version}`;
|
|
18
|
+
const podManImg = `localhost/${imgName}`;
|
|
19
|
+
const imagesStoragePath = `./images`;
|
|
20
|
+
const tarFile = `${imagesStoragePath}/${imgName.replace(':', '_')}.tar`;
|
|
21
|
+
|
|
22
|
+
let secrets = '';
|
|
23
|
+
let secretDockerInput = '';
|
|
24
|
+
|
|
25
|
+
const envObj = dotenv.parse(fs.readFileSync(`${getNpmRootPath()}/underpost/.env`, 'utf8'));
|
|
26
|
+
|
|
27
|
+
for (const key of Object.keys(envObj)) {
|
|
28
|
+
continue;
|
|
29
|
+
secrets += ` && export ${key}="${envObj[key]}" `; // $(cat gitlab-token.txt)
|
|
30
|
+
secretDockerInput += ` --secret id=${key},env=${key} \ `;
|
|
31
|
+
}
|
|
32
|
+
// --rm --no-cache
|
|
33
|
+
if (imageArchive !== true) {
|
|
34
|
+
fs.copyFile(`${getNpmRootPath()}/underpost/.env`, `${path}/.env.underpost`);
|
|
35
|
+
shellExec(
|
|
36
|
+
`cd ${path}${secrets}&& sudo podman build -f ./Dockerfile -t ${imgName} --pull=never --cap-add=CAP_AUDIT_WRITE${secretDockerInput}`,
|
|
37
|
+
);
|
|
38
|
+
fs.removeSync(`${path}/.env.underpost`);
|
|
39
|
+
shellExec(`cd ${path} && podman save -o ${tarFile} ${podManImg}`);
|
|
40
|
+
}
|
|
41
|
+
shellExec(`cd ${path} && sudo kind load image-archive ${tarFile}`);
|
|
42
|
+
},
|
|
43
|
+
async script(deployId = 'default', env = 'development') {
|
|
44
|
+
switch (deployId) {
|
|
45
|
+
case 'dd-lampp':
|
|
46
|
+
{
|
|
47
|
+
const lamppPublicPath = '/xampp/htdocs/online';
|
|
48
|
+
if (process.argv.includes('test')) {
|
|
49
|
+
const { MARIADB_HOST, MARIADB_USER, MARIADB_PASSWORD, DD_LAMPP_TEST_DB_0 } = process.env;
|
|
50
|
+
|
|
51
|
+
await MariaDB.query({
|
|
52
|
+
host: MARIADB_HOST,
|
|
53
|
+
user: MARIADB_USER,
|
|
54
|
+
password: MARIADB_PASSWORD,
|
|
55
|
+
query: `SHOW TABLES FROM ${DD_LAMPP_TEST_DB_0}`,
|
|
56
|
+
});
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
shellExec(`sudo mkdir -p ${lamppPublicPath}`);
|
|
60
|
+
|
|
61
|
+
{
|
|
62
|
+
shellExec(
|
|
63
|
+
`cd ${lamppPublicPath} && git clone https://${process.env.GITHUB_TOKEN}@github.com/${process.env.DD_LAMPP_REPO_0}`,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
shellExec(`cd ${lamppPublicPath} && sudo ${process.env.DD_LAMPP_SCRIPT_0}`);
|
|
67
|
+
|
|
68
|
+
shellExec(
|
|
69
|
+
`sudo sed -i -e "s@define( 'DB_HOST', 'localhost' );@define( 'DB_HOST', '${process.env.MARIADB_HOST}' );@g" ${lamppPublicPath}/${process.env.DD_LAMPP_REPO_0_FOLDER}/wp-config.php`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
{
|
|
73
|
+
shellExec(
|
|
74
|
+
`cd ${lamppPublicPath} && git clone https://${process.env.GITHUB_TOKEN}@github.com/${process.env.DD_LAMPP_REPO_1}`,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
break;
|
|
79
|
+
|
|
80
|
+
default:
|
|
81
|
+
{
|
|
82
|
+
{
|
|
83
|
+
const originPath = `./src/db/mongo/MongooseDB.js`;
|
|
84
|
+
fs.writeFileSync(
|
|
85
|
+
originPath,
|
|
86
|
+
fs.readFileSync(originPath, 'utf8').replaceAll(
|
|
87
|
+
`connect: async (host, name) => {`,
|
|
88
|
+
`connect: async (host, name) => {
|
|
89
|
+
host = 'mongodb://mongodb-0.mongodb-service:27017';
|
|
90
|
+
`,
|
|
91
|
+
),
|
|
92
|
+
'utf8',
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
{
|
|
97
|
+
const originPath = `./src/server/valkey.js`;
|
|
98
|
+
fs.writeFileSync(
|
|
99
|
+
originPath,
|
|
100
|
+
fs.readFileSync(originPath, 'utf8').replaceAll(
|
|
101
|
+
` // port: 6379,
|
|
102
|
+
// host: 'service-valkey.default.svc.cluster.local',`,
|
|
103
|
+
` port: 6379,
|
|
104
|
+
host: 'service-valkey.default.svc.cluster.local',`,
|
|
105
|
+
),
|
|
106
|
+
'utf8',
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
shellExec(`node bin/deploy conf ${deployId} ${env}`);
|
|
113
|
+
shellExec(`node bin/deploy build-full-client ${deployId}`);
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export default UnderpostImage;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { commitData } from '../client/components/core/CommonJs.js';
|
|
2
|
+
import dotenv from 'dotenv';
|
|
3
|
+
import { pbcopy, shellExec } from '../server/process.js';
|
|
4
|
+
import { actionInitLog, loggerFactory } from '../server/logger.js';
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
import { getNpmRootPath } from '../server/conf.js';
|
|
7
|
+
|
|
8
|
+
dotenv.config();
|
|
9
|
+
|
|
10
|
+
const logger = loggerFactory(import.meta);
|
|
11
|
+
|
|
12
|
+
class UnderpostRepository {
|
|
13
|
+
static API = {
|
|
14
|
+
clone(gitUri = 'underpostnet/pwa-microservices-template') {
|
|
15
|
+
const repoName = gitUri.split('/').pop();
|
|
16
|
+
if (fs.existsSync(`./${repoName}`)) fs.removeSync(`./${repoName}`);
|
|
17
|
+
return shellExec(
|
|
18
|
+
`git clone https://${process.env.GITHUB_TOKEN ? `${process.env.GITHUB_TOKEN}@` : ''}github.com/${gitUri}.git`,
|
|
19
|
+
{
|
|
20
|
+
disableLog: true,
|
|
21
|
+
},
|
|
22
|
+
);
|
|
23
|
+
if (process.env.GITHUB_TOKEN) {
|
|
24
|
+
shellExec(
|
|
25
|
+
`git clone https://${
|
|
26
|
+
process.env.GITHUB_TOKEN ? `${process.env.GITHUB_TOKEN}@` : ''
|
|
27
|
+
}github.com/${gitUri}-private.git`,
|
|
28
|
+
);
|
|
29
|
+
fs.moveSync(`./${repoName}-private`, `./${repoName}/engine-private`, {
|
|
30
|
+
overwrite: true,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
pull(repoPath = './', gitUri = 'underpostnet/pwa-microservices-template') {
|
|
35
|
+
shellExec(
|
|
36
|
+
`cd ${repoPath} && git pull https://${
|
|
37
|
+
process.env.GITHUB_TOKEN ? `${process.env.GITHUB_TOKEN}@` : ''
|
|
38
|
+
}github.com/${gitUri}.git`,
|
|
39
|
+
{
|
|
40
|
+
disableLog: true,
|
|
41
|
+
},
|
|
42
|
+
);
|
|
43
|
+
},
|
|
44
|
+
commit(
|
|
45
|
+
repoPath = './',
|
|
46
|
+
commitType = 'feat',
|
|
47
|
+
subModule = '',
|
|
48
|
+
message = '',
|
|
49
|
+
options = {
|
|
50
|
+
copy: false,
|
|
51
|
+
info: false,
|
|
52
|
+
empty: false,
|
|
53
|
+
},
|
|
54
|
+
) {
|
|
55
|
+
if (options.info) return logger.info('', commitData);
|
|
56
|
+
const _message = `${commitType}${subModule ? `(${subModule})` : ''}${process.argv.includes('!') ? '!' : ''}: ${
|
|
57
|
+
commitData[commitType].emoji
|
|
58
|
+
} ${message ? message : commitData[commitType].description}`;
|
|
59
|
+
if (options.copy) return pbcopy(_message);
|
|
60
|
+
shellExec(`cd ${repoPath} && git commit ${options?.empty ? `--allow-empty ` : ''}-m "${_message}"`);
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
push(repoPath = './', gitUri = 'underpostnet/pwa-microservices-template', options = { f: false }) {
|
|
64
|
+
shellExec(
|
|
65
|
+
`cd ${repoPath} && git push https://${process.env.GITHUB_TOKEN}@github.com/${gitUri}.git${
|
|
66
|
+
options?.f === true ? ' --force' : ''
|
|
67
|
+
}`,
|
|
68
|
+
{
|
|
69
|
+
disableLog: true,
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
logger.info(
|
|
73
|
+
'commit url',
|
|
74
|
+
`http://github.com/${gitUri}/commit/${shellExec(`cd ${repoPath} && git rev-parse --verify HEAD`, {
|
|
75
|
+
stdout: true,
|
|
76
|
+
}).trim()}`,
|
|
77
|
+
);
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
new(repositoryName) {
|
|
81
|
+
return new Promise(async (resolve, reject) => {
|
|
82
|
+
try {
|
|
83
|
+
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
84
|
+
// const exeRootPath = '/home/dd/pwa-microservices-template';
|
|
85
|
+
actionInitLog();
|
|
86
|
+
await logger.setUpInfo();
|
|
87
|
+
const destFolder = `${process.cwd()}/${repositoryName}`;
|
|
88
|
+
logger.info('Note: This process may take several minutes to complete');
|
|
89
|
+
logger.info('build app', { destFolder });
|
|
90
|
+
fs.mkdirSync(destFolder, { recursive: true });
|
|
91
|
+
fs.copySync(exeRootPath, destFolder);
|
|
92
|
+
if (fs.existsSync(`${destFolder}/node_modules`)) fs.removeSync(`${destFolder}/node_modules`);
|
|
93
|
+
fs.writeFileSync(`${destFolder}/.gitignore`, fs.readFileSync(`${exeRootPath}/.dockerignore`, 'utf8'), 'utf8');
|
|
94
|
+
shellExec(`cd ${destFolder} && git init && git add . && git commit -m "Base template implementation"`);
|
|
95
|
+
shellExec(`cd ${destFolder} && npm install`);
|
|
96
|
+
shellExec(`cd ${destFolder} && npm run build`);
|
|
97
|
+
shellExec(`cd ${destFolder} && npm run dev`);
|
|
98
|
+
return resolve();
|
|
99
|
+
} catch (error) {
|
|
100
|
+
logger.error(error, error.stack);
|
|
101
|
+
return reject(error.message);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export default UnderpostRepository;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getNpmRootPath } 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 UnderpostScript {
|
|
9
|
+
static API = {
|
|
10
|
+
set(key, value) {
|
|
11
|
+
const npmRoot = `${getNpmRootPath()}/underpost`;
|
|
12
|
+
const packageJson = JSON.parse(fs.readFileSync(`${npmRoot}/package.json`, 'utf8'));
|
|
13
|
+
packageJson.scripts[key] = value;
|
|
14
|
+
fs.writeFileSync(`${npmRoot}/package.json`, JSON.stringify(packageJson, null, 4));
|
|
15
|
+
},
|
|
16
|
+
run(key) {
|
|
17
|
+
const npmRoot = `${getNpmRootPath()}/underpost`;
|
|
18
|
+
shellExec(`cd ${npmRoot} && npm run ${key}`);
|
|
19
|
+
},
|
|
20
|
+
get(key) {
|
|
21
|
+
const npmRoot = `${getNpmRootPath()}/underpost`;
|
|
22
|
+
const packageJson = JSON.parse(fs.readFileSync(`${npmRoot}/package.json`, 'utf8'));
|
|
23
|
+
logger.info('[get] ' + key, packageJson.scripts[key]);
|
|
24
|
+
return packageJson.scripts[key];
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default UnderpostScript;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
import { shellExec } from '../server/process.js';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import UnderpostRootEnv from './env.js';
|
|
5
|
+
|
|
6
|
+
class UnderpostSecret {
|
|
7
|
+
static API = {
|
|
8
|
+
docker: {
|
|
9
|
+
init() {
|
|
10
|
+
shellExec(`docker swarm init`);
|
|
11
|
+
},
|
|
12
|
+
createFromEnvFile(envPath) {
|
|
13
|
+
const envObj = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
|
14
|
+
for (const key of Object.keys(envObj)) {
|
|
15
|
+
UnderpostSecret.API.docker.set(key, envObj[key]);
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
set(key, value) {
|
|
19
|
+
shellExec(`docker secret rm ${key}`);
|
|
20
|
+
shellExec(`echo "${value}" | docker secret create ${key} -`);
|
|
21
|
+
},
|
|
22
|
+
list() {
|
|
23
|
+
shellExec(`docker secret ls`);
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
underpost: {
|
|
27
|
+
createFromEnvFile(envPath) {
|
|
28
|
+
const envObj = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
|
29
|
+
for (const key of Object.keys(envObj)) {
|
|
30
|
+
UnderpostRootEnv.API.set(key, envObj[key]);
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default UnderpostSecret;
|
package/src/cli/test.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getNpmRootPath } from '../server/conf.js';
|
|
2
|
+
import { actionInitLog, loggerFactory } from '../server/logger.js';
|
|
3
|
+
import { shellExec } from '../server/process.js';
|
|
4
|
+
|
|
5
|
+
const logger = loggerFactory(import.meta);
|
|
6
|
+
|
|
7
|
+
class UnderpostTest {
|
|
8
|
+
static API = {
|
|
9
|
+
/**
|
|
10
|
+
* Logs information about the current process environment to the console.
|
|
11
|
+
*
|
|
12
|
+
* This function is used to log details about
|
|
13
|
+
* the execution context, such as command-line arguments,
|
|
14
|
+
* environment variables, the process's administrative privileges,
|
|
15
|
+
* and the maximum available heap space size.
|
|
16
|
+
*
|
|
17
|
+
* @static
|
|
18
|
+
* @method setUpInfo
|
|
19
|
+
* @returns {Promise<void>}
|
|
20
|
+
* @memberof Underpost
|
|
21
|
+
*/
|
|
22
|
+
async setUpInfo() {
|
|
23
|
+
return await setUpInfo(logger);
|
|
24
|
+
},
|
|
25
|
+
run() {
|
|
26
|
+
actionInitLog();
|
|
27
|
+
shellExec(`cd ${getNpmRootPath()}/underpost && npm run test`);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default UnderpostTest;
|