@underpostnet/underpost 2.8.4 → 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.
- package/.github/workflows/ghpkg.yml +12 -45
- package/.github/workflows/npmpkg.yml +67 -0
- package/.github/workflows/publish.yml +5 -5
- package/.github/workflows/pwa-microservices-template.page.yml +2 -1
- package/.github/workflows/pwa-microservices-template.test.yml +2 -2
- package/.vscode/settings.json +10 -1
- package/CHANGELOG.md +40 -0
- package/Dockerfile +6 -27
- package/bin/build.js +73 -165
- package/bin/deploy.js +76 -101
- package/bin/file.js +29 -15
- package/bin/hwt.js +0 -10
- package/bin/index.js +191 -32
- package/bin/util.js +0 -15
- package/bin/vs.js +1 -0
- package/conf.js +0 -2
- package/docker-compose.yml +1 -1
- package/manifests/kind-config-dev.yaml +12 -0
- package/manifests/{core/underpost-engine-mongodb-backup-cronjob.yaml → mongodb/backup-cronjob.yaml} +14 -12
- package/manifests/mongodb/kustomization.yaml +11 -0
- package/manifests/mongodb/pv-pvc.yaml +23 -0
- package/manifests/{core/underpost-engine-statefulset.yaml → mongodb/statefulset.yaml} +34 -0
- package/manifests/mongodb-4.4/kustomization.yaml +7 -0
- package/manifests/mongodb-4.4/service-deployment.yaml +63 -0
- package/manifests/valkey/kustomization.yaml +2 -2
- package/package.json +22 -4
- package/src/api/core/core.service.js +1 -1
- package/src/cli/cluster.js +202 -0
- package/src/cli/cron.js +90 -0
- package/src/cli/db.js +212 -0
- package/src/cli/deploy.js +318 -0
- package/src/cli/env.js +52 -0
- package/src/cli/fs.js +149 -0
- package/src/cli/image.js +148 -0
- package/src/cli/repository.js +125 -0
- package/src/cli/script.js +53 -0
- package/src/cli/secrets.js +37 -0
- package/src/cli/test.js +118 -0
- package/src/client/components/core/Auth.js +22 -4
- package/src/client/components/core/CalendarCore.js +12 -1
- package/src/client/components/core/CommonJs.js +134 -2
- package/src/client/components/core/Css.js +1 -0
- 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 +5 -3
- package/src/client/components/core/LoadingAnimation.js +8 -1
- package/src/client/components/core/Modal.js +30 -7
- package/src/client/components/core/Panel.js +8 -6
- package/src/client/components/core/PanelForm.js +23 -7
- package/src/client/components/core/Scroll.js +1 -0
- package/src/client/components/core/Translate.js +4 -0
- package/src/client/components/core/VanillaJs.js +0 -9
- package/src/client/components/core/Worker.js +34 -31
- 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/db/mongo/MongooseDB.js +17 -1
- package/src/index.js +85 -26
- package/src/server/backup.js +49 -93
- package/src/server/client-build.js +33 -33
- package/src/server/client-formatted.js +6 -3
- package/src/server/conf.js +82 -199
- package/src/server/dns.js +29 -53
- package/src/server/downloader.js +0 -8
- package/src/server/logger.js +7 -7
- package/src/server/network.js +17 -7
- package/src/server/runtime.js +24 -23
- package/test/api.test.js +0 -8
- package/manifests/core/kustomization.yaml +0 -11
- package/src/dns.js +0 -22
- package/src/server/project.js +0 -39
- 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
- /package/manifests/{core/underpost-engine-backup-access.yaml → mongodb/backup-access.yaml} +0 -0
- /package/manifests/{core/underpost-engine-backup-pv-pvc.yaml → mongodb/backup-pv-pvc.yaml} +0 -0
- /package/manifests/{core/underpost-engine-mongodb-configmap.yaml → mongodb/configmap.yaml} +0 -0
- /package/manifests/{core/underpost-engine-headless-service.yaml → mongodb/headless-service.yaml} +0 -0
- /package/manifests/{core/underpost-engine-pv-pvc.yaml → mongodb-4.4/pv-pvc.yaml} +0 -0
- /package/manifests/valkey/{underpost-engine-valkey-service.yaml → service.yaml} +0 -0
- /package/manifests/valkey/{underpost-engine-valkey-statefulset.yaml → statefulset.yaml} +0 -0
package/src/server/conf.js
CHANGED
|
@@ -13,23 +13,14 @@ import cliProgress from 'cli-progress';
|
|
|
13
13
|
import cliSpinners from 'cli-spinners';
|
|
14
14
|
import logUpdate from 'log-update';
|
|
15
15
|
import colors from 'colors';
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
16
|
+
import { loggerFactory } from './logger.js';
|
|
17
|
+
import { shellExec } from './process.js';
|
|
18
18
|
import { DefaultConf } from '../../conf.js';
|
|
19
19
|
import read from 'read';
|
|
20
20
|
import splitFile from 'split-file';
|
|
21
21
|
import axios from 'axios';
|
|
22
|
-
import https from 'https';
|
|
23
22
|
import { ssrFactory } from './client-formatted.js';
|
|
24
23
|
|
|
25
|
-
// axios.defaults.baseURL = BASE_URL;
|
|
26
|
-
|
|
27
|
-
// const httpsAgent = new https.Agent({
|
|
28
|
-
// rejectUnauthorized: false,
|
|
29
|
-
// });
|
|
30
|
-
|
|
31
|
-
// axios.defaults.httpsAgent = httpsAgent;
|
|
32
|
-
|
|
33
24
|
colors.enable();
|
|
34
25
|
|
|
35
26
|
dotenv.config();
|
|
@@ -40,21 +31,26 @@ const logger = loggerFactory(import.meta);
|
|
|
40
31
|
|
|
41
32
|
const Config = {
|
|
42
33
|
default: DefaultConf,
|
|
43
|
-
build: async function (options = { folder: '' }) {
|
|
34
|
+
build: async function (options = { folder: '' }, deployContext, deployList, subConf) {
|
|
35
|
+
if (!deployContext) deployContext = process.argv[2];
|
|
44
36
|
if (!fs.existsSync(`./tmp`)) fs.mkdirSync(`./tmp`, { recursive: true });
|
|
45
37
|
fs.writeFileSync(`./tmp/await-deploy`, '', 'utf8');
|
|
46
|
-
if (fs.existsSync(`./engine-private/conf/${
|
|
47
|
-
|
|
38
|
+
if (fs.existsSync(`./engine-private/conf/${deployContext}`))
|
|
39
|
+
return loadConf(deployContext, process.env.NODE_ENV, subConf);
|
|
40
|
+
if (fs.existsSync(`./engine-private/replica/${deployContext}`))
|
|
41
|
+
return loadConf(deployContext, process.env.NODE_ENV, subConf);
|
|
48
42
|
|
|
49
|
-
if (
|
|
43
|
+
if (deployContext === 'deploy') return;
|
|
50
44
|
|
|
51
|
-
if (
|
|
45
|
+
if (deployContext === 'proxy') {
|
|
46
|
+
if (!deployList) deployList = process.argv[3];
|
|
47
|
+
if (!subConf) subConf = process.argv[4];
|
|
52
48
|
this.default.server = {};
|
|
53
|
-
for (const deployId of
|
|
49
|
+
for (const deployId of deployList.split(',')) {
|
|
54
50
|
let confPath = `./engine-private/conf/${deployId}/conf.server.json`;
|
|
55
51
|
const privateConfDevPath = fs.existsSync(`./engine-private/replica/${deployId}/conf.server.json`)
|
|
56
52
|
? `./engine-private/replica/${deployId}/conf.server.json`
|
|
57
|
-
: `./engine-private/conf/${deployId}/conf.server.dev.${
|
|
53
|
+
: `./engine-private/conf/${deployId}/conf.server.dev.${subConf}.json`;
|
|
58
54
|
const confDevPath = fs.existsSync(privateConfDevPath)
|
|
59
55
|
? privateConfDevPath
|
|
60
56
|
: `./engine-private/conf/${deployId}/conf.server.dev.json`;
|
|
@@ -62,7 +58,7 @@ const Config = {
|
|
|
62
58
|
if (process.env.NODE_ENV === 'development' && fs.existsSync(confDevPath)) confPath = confDevPath;
|
|
63
59
|
const serverConf = JSON.parse(fs.readFileSync(confPath, 'utf8'));
|
|
64
60
|
|
|
65
|
-
for (const host of Object.keys(loadReplicas(serverConf))) {
|
|
61
|
+
for (const host of Object.keys(loadReplicas(serverConf, deployContext, subConf))) {
|
|
66
62
|
if (serverConf[host]['/'])
|
|
67
63
|
this.default.server[host] = {
|
|
68
64
|
...this.default.server[host],
|
|
@@ -92,7 +88,15 @@ const Config = {
|
|
|
92
88
|
},
|
|
93
89
|
};
|
|
94
90
|
|
|
95
|
-
const loadConf = (deployId, envInput) => {
|
|
91
|
+
const loadConf = (deployId, envInput, subConf) => {
|
|
92
|
+
if (deployId === 'clean') {
|
|
93
|
+
shellExec(`git checkout package.json`);
|
|
94
|
+
shellExec(`git checkout .env.production`);
|
|
95
|
+
shellExec(`git checkout .env.development`);
|
|
96
|
+
shellExec(`git checkout .env.test`);
|
|
97
|
+
shellExec(`git checkout jsdoc.json`);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
96
100
|
const folder = fs.existsSync(`./engine-private/replica/${deployId}`)
|
|
97
101
|
? `./engine-private/replica/${deployId}`
|
|
98
102
|
: `./engine-private/conf/${deployId}`;
|
|
@@ -109,7 +113,8 @@ const loadConf = (deployId, envInput) => {
|
|
|
109
113
|
? fs.readFileSync(`${folder}/conf.${typeConf}.json`, 'utf8')
|
|
110
114
|
: JSON.stringify(Config.default[typeConf]);
|
|
111
115
|
if (process.env.NODE_ENV === 'development' && typeConf === 'server') {
|
|
112
|
-
|
|
116
|
+
if (!subConf) subConf = process.argv[3];
|
|
117
|
+
const devConfPath = `${folder}/conf.${typeConf}.dev${subConf ? `.${subConf}` : ''}.json`;
|
|
113
118
|
if (fs.existsSync(devConfPath)) srcConf = fs.readFileSync(devConfPath, 'utf8');
|
|
114
119
|
}
|
|
115
120
|
if (typeConf === 'server') srcConf = JSON.stringify(loadReplicas(JSON.parse(srcConf)), null, 4);
|
|
@@ -127,19 +132,25 @@ const loadConf = (deployId, envInput) => {
|
|
|
127
132
|
...env,
|
|
128
133
|
};
|
|
129
134
|
}
|
|
130
|
-
|
|
135
|
+
const originPackageJson = JSON.parse(fs.readFileSync(`./package.json`, 'utf8'));
|
|
136
|
+
const packageJson = JSON.parse(fs.readFileSync(`${folder}/package.json`, 'utf8'));
|
|
137
|
+
originPackageJson.scripts.start = packageJson.scripts.start;
|
|
138
|
+
packageJson.scripts = originPackageJson.scripts;
|
|
139
|
+
fs.writeFileSync(`./package.json`, JSON.stringify(packageJson, null, 4), 'utf8');
|
|
131
140
|
return { folder, deployId };
|
|
132
141
|
};
|
|
133
142
|
|
|
134
|
-
const loadReplicas = (confServer) => {
|
|
143
|
+
const loadReplicas = (confServer, deployContext, subConf) => {
|
|
144
|
+
if (!deployContext) deployContext = process.argv[2];
|
|
145
|
+
if (!subConf) subConf = process.argv[3];
|
|
135
146
|
for (const host of Object.keys(confServer)) {
|
|
136
147
|
for (const path of Object.keys(confServer[host])) {
|
|
137
148
|
const { replicas, singleReplica } = confServer[host][path];
|
|
138
149
|
if (
|
|
139
150
|
replicas &&
|
|
140
|
-
(
|
|
151
|
+
(deployContext === 'proxy' ||
|
|
141
152
|
!singleReplica ||
|
|
142
|
-
(singleReplica && process.env.NODE_ENV === 'development' && !
|
|
153
|
+
(singleReplica && process.env.NODE_ENV === 'development' && !subConf))
|
|
143
154
|
)
|
|
144
155
|
for (const replicaPath of replicas) {
|
|
145
156
|
confServer[host][replicaPath] = newInstance(confServer[host][path]);
|
|
@@ -509,21 +520,25 @@ const buildPortProxyRouter = (port, proxyRouter) => {
|
|
|
509
520
|
// build router
|
|
510
521
|
Object.keys(hosts).map((hostKey) => {
|
|
511
522
|
let { host, path, target, proxy, peer } = hosts[hostKey];
|
|
512
|
-
if (process.env.NODE_ENV === 'development') host = `localhost`;
|
|
523
|
+
if (process.argv.includes('localhost') && process.env.NODE_ENV === 'development') host = `localhost`;
|
|
513
524
|
|
|
514
525
|
if (!proxy.includes(port)) return;
|
|
515
526
|
const absoluteHost = [80, 443].includes(port)
|
|
516
527
|
? `${host}${path === '/' ? '' : path}`
|
|
517
528
|
: `${host}:${port}${path === '/' ? '' : path}`;
|
|
518
529
|
|
|
519
|
-
if (
|
|
530
|
+
if (process.argv.includes('localhost')) {
|
|
531
|
+
if (!(absoluteHost in router)) router[absoluteHost] = target;
|
|
532
|
+
} else router[absoluteHost] = target;
|
|
520
533
|
}); // order router
|
|
521
534
|
|
|
522
535
|
if (Object.keys(router).length === 0) return router;
|
|
523
536
|
|
|
537
|
+
const reOrderRouter = {};
|
|
524
538
|
for (const absoluteHostKey of orderArrayFromAttrInt(Object.keys(router), 'length'))
|
|
525
|
-
|
|
526
|
-
|
|
539
|
+
reOrderRouter[absoluteHostKey] = router[absoluteHostKey];
|
|
540
|
+
|
|
541
|
+
return reOrderRouter;
|
|
527
542
|
};
|
|
528
543
|
|
|
529
544
|
const cliBar = async (time = 5000) => {
|
|
@@ -574,9 +589,25 @@ const cliSpinner = async (time = 5000, message0, message1, color, type = 'dots')
|
|
|
574
589
|
const buildReplicaId = ({ deployId, replica }) => `${deployId}-${replica.slice(1)}`;
|
|
575
590
|
|
|
576
591
|
const getDataDeploy = (
|
|
577
|
-
options = {
|
|
592
|
+
options = {
|
|
593
|
+
buildSingleReplica: false,
|
|
594
|
+
deployGroupId: '',
|
|
595
|
+
deployId: '',
|
|
596
|
+
disableSyncEnvPort: false,
|
|
597
|
+
deployIdConcat: [],
|
|
598
|
+
},
|
|
578
599
|
) => {
|
|
579
|
-
let dataDeploy =
|
|
600
|
+
let dataDeploy =
|
|
601
|
+
options.deployGroupId === 'dd'
|
|
602
|
+
? fs.readFileSync(`./engine-private/deploy/${options.deployGroupId}.router`, 'utf8')
|
|
603
|
+
: fs.readFileSync(`./engine-private/deploy/${options.deployGroupId}`, 'utf8');
|
|
604
|
+
|
|
605
|
+
dataDeploy = dataDeploy
|
|
606
|
+
.split(',')
|
|
607
|
+
.map((deployId) => deployId.trim())
|
|
608
|
+
.filter((deployId) => deployId);
|
|
609
|
+
|
|
610
|
+
if (options.deployIdConcat) dataDeploy = dataDeploy.concat(options.deployIdConcat);
|
|
580
611
|
|
|
581
612
|
if (options.deployId) dataDeploy = dataDeploy.filter((d) => d === options.deployId);
|
|
582
613
|
|
|
@@ -811,7 +842,7 @@ const deployRun = async (dataDeploy, currentAttempt = 1) => {
|
|
|
811
842
|
if (failed.length > 0) {
|
|
812
843
|
for (const deploy of failed) logger.error(deploy.deployId, Cmd.run(deploy.deployId));
|
|
813
844
|
if (currentAttempt === maxAttempts) return logger.error(`max deploy attempts exceeded`);
|
|
814
|
-
|
|
845
|
+
await read({ prompt: 'Press enter to retry failed processes\n' });
|
|
815
846
|
currentAttempt++;
|
|
816
847
|
await deployRun(failed, currentAttempt);
|
|
817
848
|
} else logger.info(`Deploy process successfully`);
|
|
@@ -957,15 +988,15 @@ const getPathsSSR = (conf) => {
|
|
|
957
988
|
|
|
958
989
|
const Cmd = {
|
|
959
990
|
delete: (deployId) => `pm2 delete ${deployId}`,
|
|
960
|
-
run: (
|
|
991
|
+
run: () => `npm start`,
|
|
961
992
|
build: (deployId) => `node bin/deploy build-full-client ${deployId}${process.argv.includes('l') ? ' l' : ''}`,
|
|
962
993
|
conf: (deployId, env) => `node bin/deploy conf ${deployId} ${env ? env : 'production'}`,
|
|
963
994
|
replica: (deployId, host, path) => `node bin/deploy build-single-replica ${deployId} ${host} ${path}`,
|
|
964
995
|
syncPorts: (deployGroupId) => `node bin/deploy sync-env-port ${deployGroupId}`,
|
|
965
|
-
cron: (
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
996
|
+
cron: (deployList, jobList, name, expression, options) =>
|
|
997
|
+
`pm2 start ./bin/index.js --no-autorestart --instances 1 --cron "${expression}" --name ${name} -- cron ${
|
|
998
|
+
options?.itc ? `--itc ` : ''
|
|
999
|
+
}${options?.git ? `--git ` : ''}${deployList} ${jobList}`,
|
|
969
1000
|
};
|
|
970
1001
|
|
|
971
1002
|
const fixDependencies = async () => {
|
|
@@ -1032,170 +1063,26 @@ const setUpProxyMaintenanceServer = ({ deployGroupId }) => {
|
|
|
1032
1063
|
shellExec(`node bin/deploy valkey-service`);
|
|
1033
1064
|
const proxyDeployId = fs.readFileSync(`./engine-private/deploy/${deployGroupId}.proxy`, 'utf8').trim();
|
|
1034
1065
|
shellExec(`node bin/deploy conf ${proxyDeployId} production`);
|
|
1035
|
-
shellExec(`
|
|
1036
|
-
};
|
|
1037
|
-
|
|
1038
|
-
const repoClone = (gitUri = 'underpostnet/pwa-microservices-template') => {
|
|
1039
|
-
const repoName = gitUri.split('/').pop();
|
|
1040
|
-
if (fs.existsSync(`./${repoName}`)) fs.removeSync(`./${repoName}`);
|
|
1041
|
-
shellExec(
|
|
1042
|
-
`git clone https://${process.env.GITHUB_TOKEN ? `${process.env.GITHUB_TOKEN}@` : ''}github.com/${gitUri}.git`,
|
|
1043
|
-
);
|
|
1044
|
-
if (process.env.GITHUB_TOKEN) {
|
|
1045
|
-
shellExec(
|
|
1046
|
-
`git clone https://${
|
|
1047
|
-
process.env.GITHUB_TOKEN ? `${process.env.GITHUB_TOKEN}@` : ''
|
|
1048
|
-
}github.com/${gitUri}-private.git`,
|
|
1049
|
-
);
|
|
1050
|
-
fs.moveSync(`./${repoName}-private`, `./${repoName}/engine-private`, {
|
|
1051
|
-
overwrite: true,
|
|
1052
|
-
});
|
|
1053
|
-
}
|
|
1054
|
-
};
|
|
1055
|
-
|
|
1056
|
-
const repoPull = (repoPath = './', gitUri = 'underpostnet/pwa-microservices-template') => {
|
|
1057
|
-
shellExec(`cd ${repoPath} && git pull https://${process.env.GITHUB_TOKEN}@github.com/${gitUri}.git`, {
|
|
1058
|
-
disableLog: true,
|
|
1059
|
-
});
|
|
1060
|
-
};
|
|
1061
|
-
|
|
1062
|
-
const commitData = {
|
|
1063
|
-
feat: {
|
|
1064
|
-
description: 'A new feature',
|
|
1065
|
-
title: 'Features',
|
|
1066
|
-
emoji: '✨',
|
|
1067
|
-
},
|
|
1068
|
-
fix: {
|
|
1069
|
-
description: 'A bug fix',
|
|
1070
|
-
title: 'Bug Fixes',
|
|
1071
|
-
emoji: '🐛',
|
|
1072
|
-
},
|
|
1073
|
-
docs: {
|
|
1074
|
-
description: 'Documentation only changes',
|
|
1075
|
-
title: 'Documentation',
|
|
1076
|
-
emoji: '📚',
|
|
1077
|
-
},
|
|
1078
|
-
style: {
|
|
1079
|
-
description:
|
|
1080
|
-
'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
|
|
1081
|
-
title: 'Styles',
|
|
1082
|
-
emoji: '💎',
|
|
1083
|
-
},
|
|
1084
|
-
refactor: {
|
|
1085
|
-
description: 'A code change that neither fixes a bug nor adds a feature',
|
|
1086
|
-
title: 'Code Refactoring',
|
|
1087
|
-
emoji: '📦',
|
|
1088
|
-
},
|
|
1089
|
-
perf: {
|
|
1090
|
-
description: 'A code change that improves performance',
|
|
1091
|
-
title: 'Performance Improvements',
|
|
1092
|
-
emoji: '⚡️',
|
|
1093
|
-
},
|
|
1094
|
-
cd: {
|
|
1095
|
-
description:
|
|
1096
|
-
'Changes to our Continuous Delivery configuration files and scripts (example scopes: Jenkins, Spinnaker, ArgoCD)',
|
|
1097
|
-
title: 'Continuous Delivery',
|
|
1098
|
-
emoji: '🚀',
|
|
1099
|
-
},
|
|
1100
|
-
test: {
|
|
1101
|
-
description: 'Adding missing tests or correcting existing tests',
|
|
1102
|
-
title: 'Tests',
|
|
1103
|
-
emoji: '🚨',
|
|
1104
|
-
},
|
|
1105
|
-
build: {
|
|
1106
|
-
description: 'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)',
|
|
1107
|
-
title: 'Builds',
|
|
1108
|
-
emoji: '🛠',
|
|
1109
|
-
},
|
|
1110
|
-
ci: {
|
|
1111
|
-
description:
|
|
1112
|
-
'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)',
|
|
1113
|
-
title: 'Continuous Integrations',
|
|
1114
|
-
emoji: '⚙️',
|
|
1115
|
-
},
|
|
1116
|
-
chore: {
|
|
1117
|
-
description: "Other changes that don't modify src or test files",
|
|
1118
|
-
title: 'Chores',
|
|
1119
|
-
emoji: '♻️',
|
|
1120
|
-
},
|
|
1121
|
-
revert: {
|
|
1122
|
-
description: 'Reverts a previous commit',
|
|
1123
|
-
title: 'Reverts',
|
|
1124
|
-
emoji: '🗑',
|
|
1125
|
-
},
|
|
1126
|
-
backup: {
|
|
1127
|
-
description: 'Changes related to backups, including creation, restoration, and maintenance.',
|
|
1128
|
-
title: 'Backups',
|
|
1129
|
-
emoji: '💾',
|
|
1130
|
-
},
|
|
1131
|
-
};
|
|
1132
|
-
|
|
1133
|
-
const repoCommit = (
|
|
1134
|
-
repoPath = './',
|
|
1135
|
-
commitType = 'feat',
|
|
1136
|
-
subModule = '',
|
|
1137
|
-
message = '',
|
|
1138
|
-
options = {
|
|
1139
|
-
copy: false,
|
|
1140
|
-
info: false,
|
|
1141
|
-
empty: false,
|
|
1142
|
-
},
|
|
1143
|
-
) => {
|
|
1144
|
-
if (options.info) return logger.info('', commitData);
|
|
1145
|
-
const _message = `${commitType}${subModule ? `(${subModule})` : ''}${process.argv.includes('!') ? '!' : ''}: ${
|
|
1146
|
-
commitData[commitType].emoji
|
|
1147
|
-
} ${message ? message : commitData[commitType].description}`;
|
|
1148
|
-
if (options.copy) return pbcopy(_message);
|
|
1149
|
-
shellExec(`cd ${repoPath} && git commit ${options?.empty ? `--allow-empty ` : ''}-m "${_message}"`);
|
|
1150
|
-
};
|
|
1151
|
-
|
|
1152
|
-
const repoPush = (repoPath = './', gitUri = 'underpostnet/pwa-microservices-template') => {
|
|
1153
|
-
shellExec(`cd ${repoPath} && git push https://${process.env.GITHUB_TOKEN}@github.com/${gitUri}.git`, {
|
|
1154
|
-
disableLog: true,
|
|
1155
|
-
});
|
|
1156
|
-
logger.info(
|
|
1157
|
-
'commit url',
|
|
1158
|
-
`http://github.com/${gitUri}/commit/${shellExec(`cd ${repoPath} && git rev-parse --verify HEAD`, {
|
|
1159
|
-
stdout: true,
|
|
1160
|
-
}).trim()}`,
|
|
1161
|
-
);
|
|
1066
|
+
shellExec(`npm start ${proxyDeployId} maintenance`);
|
|
1162
1067
|
};
|
|
1163
1068
|
|
|
1164
1069
|
const getNpmRootPath = () =>
|
|
1165
1070
|
shellExec(`npm root -g`, {
|
|
1166
1071
|
stdout: true,
|
|
1072
|
+
disableLog: true,
|
|
1073
|
+
silent: true,
|
|
1167
1074
|
}).trim();
|
|
1168
1075
|
|
|
1169
|
-
const
|
|
1170
|
-
return new Promise(async (resolve, reject) => {
|
|
1171
|
-
try {
|
|
1172
|
-
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
1173
|
-
// const exeRootPath = '/home/dd/pwa-microservices-template';
|
|
1174
|
-
actionInitLog(version);
|
|
1175
|
-
await logger.setUpInfo();
|
|
1176
|
-
const destFolder = `${process.cwd()}/${repositoryName}`;
|
|
1177
|
-
logger.info('Note: This process may take several minutes to complete');
|
|
1178
|
-
logger.info('build app', { destFolder });
|
|
1179
|
-
fs.mkdirSync(destFolder, { recursive: true });
|
|
1180
|
-
fs.copySync(exeRootPath, destFolder);
|
|
1181
|
-
if (fs.existsSync(`${destFolder}/node_modules`)) fs.removeSync(`${destFolder}/node_modules`);
|
|
1182
|
-
fs.writeFileSync(`${destFolder}/.gitignore`, fs.readFileSync(`${exeRootPath}/.dockerignore`, 'utf8'), 'utf8');
|
|
1183
|
-
shellExec(`cd ${destFolder} && git init && git add . && git commit -m "Base template implementation"`);
|
|
1184
|
-
shellExec(`cd ${destFolder} && npm install`);
|
|
1185
|
-
shellExec(`cd ${destFolder} && npm run build`);
|
|
1186
|
-
shellExec(`cd ${destFolder} && npm run dev`);
|
|
1187
|
-
return resolve();
|
|
1188
|
-
} catch (error) {
|
|
1189
|
-
logger.error(error, error.stack);
|
|
1190
|
-
return reject(error.message);
|
|
1191
|
-
}
|
|
1192
|
-
});
|
|
1193
|
-
};
|
|
1076
|
+
const getUnderpostRootPath = () => `${getNpmRootPath()}/underpost`;
|
|
1194
1077
|
|
|
1195
|
-
const
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1078
|
+
const writeEnv = (envPath, envObj) =>
|
|
1079
|
+
fs.writeFileSync(
|
|
1080
|
+
envPath,
|
|
1081
|
+
Object.keys(envObj)
|
|
1082
|
+
.map((key) => `${key}=${envObj[key]}`)
|
|
1083
|
+
.join(`\n`),
|
|
1084
|
+
'utf8',
|
|
1085
|
+
);
|
|
1199
1086
|
|
|
1200
1087
|
export {
|
|
1201
1088
|
Cmd,
|
|
@@ -1232,11 +1119,7 @@ export {
|
|
|
1232
1119
|
buildKindPorts,
|
|
1233
1120
|
buildPortProxyRouter,
|
|
1234
1121
|
splitFileFactory,
|
|
1235
|
-
repoClone,
|
|
1236
|
-
repoPull,
|
|
1237
|
-
repoCommit,
|
|
1238
|
-
repoPush,
|
|
1239
|
-
newProject,
|
|
1240
|
-
runTest,
|
|
1241
1122
|
getNpmRootPath,
|
|
1123
|
+
getUnderpostRootPath,
|
|
1124
|
+
writeEnv,
|
|
1242
1125
|
};
|
package/src/server/dns.js
CHANGED
|
@@ -1,28 +1,19 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import dotenv from 'dotenv';
|
|
3
3
|
import fs from 'fs';
|
|
4
|
-
import https from 'https';
|
|
5
4
|
import validator from 'validator';
|
|
6
5
|
import { ip } from './network.js';
|
|
7
6
|
import { loggerFactory } from './logger.js';
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
const httpsAgent = new https.Agent({
|
|
11
|
-
rejectUnauthorized: false,
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
axios.defaults.httpsAgent = httpsAgent;
|
|
7
|
+
import UnderpostRootEnv from '../cli/env.js';
|
|
15
8
|
|
|
16
9
|
dotenv.config();
|
|
17
10
|
|
|
18
11
|
const logger = loggerFactory(import.meta);
|
|
19
12
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// NAT-VPS modem/router device configuration:
|
|
25
|
-
// LAN --> [NAT-VPS] --> WAN
|
|
13
|
+
class Dns {
|
|
14
|
+
static callback = async function (deployList) {
|
|
15
|
+
// Network topology configuration:
|
|
16
|
+
// LAN -> [NAT-VPS](modem/router device) -> WAN
|
|
26
17
|
// enabled DMZ Host to proxy IP 80-443 (79-444) sometimes router block first port
|
|
27
18
|
// disabled local red DHCP
|
|
28
19
|
// verify inet ip proxy server address
|
|
@@ -30,25 +21,24 @@ const Dns = {
|
|
|
30
21
|
// LAN server or device's local servers port -> 3000-3100 (2999-3101)
|
|
31
22
|
// DNS Records: [ANAME](Address Dynamic) -> [A](ipv4) host | [AAAA](ipv6) host -> [public-ip]
|
|
32
23
|
// Forward the router's TCP/UDP ports to the LAN device's IP address
|
|
24
|
+
for (const _deployId of deployList.split(',')) {
|
|
25
|
+
const deployId = _deployId.trim();
|
|
26
|
+
const privateCronConfPath = `./engine-private/conf/${deployId}/conf.cron.json`;
|
|
27
|
+
const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json';
|
|
28
|
+
const confCronData = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
|
|
33
29
|
|
|
34
|
-
const privateCronConfPath = `./engine-private/conf/${deployId}/conf.cron.json`;
|
|
35
|
-
|
|
36
|
-
const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json';
|
|
37
|
-
let confCronData = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
|
|
38
|
-
if (confCronData.ipDaemon.disabled) return;
|
|
39
|
-
Dns.ip = confCronData.ipDaemon.ip;
|
|
40
|
-
logger.info(`Current ip`, Dns.ip);
|
|
41
|
-
const callback = async () => {
|
|
42
|
-
logger.info('init dns ip callback');
|
|
43
|
-
await logger.setUpInfo();
|
|
44
30
|
let testIp;
|
|
31
|
+
|
|
45
32
|
try {
|
|
46
33
|
testIp = await ip.public.ipv4();
|
|
47
34
|
} catch (error) {
|
|
48
35
|
logger.error(error, { testIp, stack: error.stack });
|
|
49
36
|
}
|
|
50
|
-
|
|
51
|
-
|
|
37
|
+
|
|
38
|
+
const currentIp = UnderpostRootEnv.API.get('ip');
|
|
39
|
+
|
|
40
|
+
if (testIp && typeof testIp === 'string' && validator.isIP(testIp) && currentIp !== testIp) {
|
|
41
|
+
logger.info(`new ip`, testIp);
|
|
52
42
|
for (const recordType of Object.keys(confCronData.records)) {
|
|
53
43
|
switch (recordType) {
|
|
54
44
|
case 'A':
|
|
@@ -66,20 +56,20 @@ const Dns = {
|
|
|
66
56
|
const ipUrlTest = `https://${process.env.DEFAULT_DEPLOY_HOST}`;
|
|
67
57
|
const response = await axios.get(ipUrlTest);
|
|
68
58
|
const verifyIp = response.request.socket.remoteAddress;
|
|
69
|
-
logger.info(ipUrlTest + '
|
|
59
|
+
logger.info(ipUrlTest + ' verify ip', verifyIp);
|
|
70
60
|
if (verifyIp === testIp) {
|
|
71
|
-
|
|
72
|
-
|
|
61
|
+
logger.info('ip updated successfully', testIp);
|
|
62
|
+
UnderpostRootEnv.API.set('ip', testIp);
|
|
63
|
+
} else logger.error('ip not updated', testIp);
|
|
73
64
|
} catch (error) {
|
|
74
|
-
logger.error(error
|
|
65
|
+
logger.error(error, error.stack);
|
|
66
|
+
logger.error('ip not updated', testIp);
|
|
75
67
|
}
|
|
76
68
|
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
},
|
|
82
|
-
services: {
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
static services = {
|
|
83
73
|
updateIp: {
|
|
84
74
|
dondominio: (options) => {
|
|
85
75
|
const { user, api_key, host, dns, ip } = options;
|
|
@@ -100,21 +90,7 @@ const Dns = {
|
|
|
100
90
|
});
|
|
101
91
|
},
|
|
102
92
|
},
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
Dns.ip = ip;
|
|
106
|
-
confCronData.ipDaemon.ip = ip;
|
|
107
|
-
fs.writeFileSync(confCronPath, JSON.stringify(confCronData, null, 4), 'utf8');
|
|
108
|
-
shellExec(
|
|
109
|
-
`cd ./engine-private` +
|
|
110
|
-
` && git pull ${Dns.repoUrl}` +
|
|
111
|
-
` && git add . && git commit -m "update ip ${new Date().toLocaleDateString()}"` +
|
|
112
|
-
` && git push ${Dns.repoUrl}`,
|
|
113
|
-
{
|
|
114
|
-
disableLog: true,
|
|
115
|
-
},
|
|
116
|
-
);
|
|
117
|
-
},
|
|
118
|
-
};
|
|
93
|
+
};
|
|
94
|
+
}
|
|
119
95
|
|
|
120
|
-
export
|
|
96
|
+
export default Dns;
|
package/src/server/downloader.js
CHANGED
|
@@ -2,16 +2,8 @@ import axios from 'axios';
|
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import { loggerFactory } from './logger.js';
|
|
4
4
|
import dotenv from 'dotenv';
|
|
5
|
-
import https from 'https';
|
|
6
|
-
|
|
7
5
|
dotenv.config();
|
|
8
6
|
|
|
9
|
-
const httpsAgent = new https.Agent({
|
|
10
|
-
rejectUnauthorized: false,
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
axios.defaults.httpsAgent = httpsAgent;
|
|
14
|
-
|
|
15
7
|
const logger = loggerFactory(import.meta);
|
|
16
8
|
|
|
17
9
|
const Downloader = (url, fullPath, options = { method: 'get', responseType: 'stream' }) =>
|
package/src/server/logger.js
CHANGED
|
@@ -84,8 +84,8 @@ const format = (meta) =>
|
|
|
84
84
|
* @memberof Logger
|
|
85
85
|
*/
|
|
86
86
|
const setUpInfo = async (logger = new winston.Logger()) => {
|
|
87
|
-
logger.info('npm_package_version', process.env.npm_package_version);
|
|
88
87
|
logger.info('argv', process.argv);
|
|
88
|
+
logger.info('cwd', process.cwd());
|
|
89
89
|
logger.info('platform', process.platform);
|
|
90
90
|
logger.info('env', process.env.NODE_ENV);
|
|
91
91
|
logger.info('--max-old-space-size', {
|
|
@@ -112,10 +112,10 @@ const loggerFactory = (meta = { url: '' }) => {
|
|
|
112
112
|
// Allow the use the terminal to print the messages
|
|
113
113
|
new winston.transports.Console(),
|
|
114
114
|
// Allow to print all the error level messages inside the error.log file
|
|
115
|
-
new winston.transports.File({
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}),
|
|
115
|
+
// new winston.transports.File({
|
|
116
|
+
// filename: `logs/${meta}/error.log`,
|
|
117
|
+
// level: 'error',
|
|
118
|
+
// }),
|
|
119
119
|
// Allow to print all the error message inside the all.log file
|
|
120
120
|
// (also the error log that are also printed inside the error.log(
|
|
121
121
|
new winston.transports.File({ filename: `logs/${meta}/all.log` }),
|
|
@@ -186,11 +186,11 @@ const underpostASCI = () => `
|
|
|
186
186
|
░╚═════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚═╝░░░░░░╚════╝░╚═════╝░░░░╚═╝░░░
|
|
187
187
|
`;
|
|
188
188
|
|
|
189
|
-
const actionInitLog = (
|
|
189
|
+
const actionInitLog = () =>
|
|
190
190
|
console.log(
|
|
191
191
|
underpostASCI() +
|
|
192
192
|
`
|
|
193
|
-
|
|
193
|
+
https://www.nexodev.org/docs
|
|
194
194
|
`,
|
|
195
195
|
);
|
|
196
196
|
|
package/src/server/network.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
|
|
3
3
|
import { publicIp, publicIpv4, publicIpv6 } from 'public-ip';
|
|
4
|
-
import { loggerFactory } from './logger.js';
|
|
4
|
+
import { actionInitLog, loggerFactory } from './logger.js';
|
|
5
5
|
import { DataBaseProvider } from '../db/DataBaseProvider.js';
|
|
6
6
|
import { getDeployId } from './conf.js';
|
|
7
7
|
|
|
@@ -39,8 +39,8 @@ const saveRuntimeRouter = async () => {
|
|
|
39
39
|
const host = process.env.DEFAULT_DEPLOY_HOST;
|
|
40
40
|
const path = process.env.DEFAULT_DEPLOY_PATH;
|
|
41
41
|
const confServerPath = `./engine-private/conf/${deployId}/conf.server.json`;
|
|
42
|
-
if (!deployId || !host || !path) {
|
|
43
|
-
logger.warn('default deploy instance not found');
|
|
42
|
+
if (!deployId || !host || !path || !fs.existsSync(confServerPath)) {
|
|
43
|
+
// logger.warn('default deploy instance not found');
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
46
|
const confServer = JSON.parse(fs.readFileSync(confServerPath, 'utf8'));
|
|
@@ -77,7 +77,7 @@ const saveRuntimeRouter = async () => {
|
|
|
77
77
|
|
|
78
78
|
if (closeConn) await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
|
|
79
79
|
} catch (error) {
|
|
80
|
-
logger.error(error);
|
|
80
|
+
logger.error(error, error.stack);
|
|
81
81
|
}
|
|
82
82
|
};
|
|
83
83
|
|
|
@@ -114,20 +114,30 @@ const saveRuntimeCron = async () => {
|
|
|
114
114
|
|
|
115
115
|
if (closeConn) await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
|
|
116
116
|
} catch (error) {
|
|
117
|
-
logger.error(error);
|
|
117
|
+
logger.error(error, error.stack);
|
|
118
118
|
}
|
|
119
119
|
};
|
|
120
120
|
|
|
121
121
|
const listenServerFactory = (logic = async () => {}) => {
|
|
122
122
|
return {
|
|
123
|
-
listen: async (...args) => (
|
|
123
|
+
listen: async (...args) => (
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
const message = 'Listen server factory timeout';
|
|
126
|
+
logger.error(message);
|
|
127
|
+
throw new Error(message);
|
|
128
|
+
}, 80000000), // ~ 55 days
|
|
129
|
+
(logic ? await logic(...args) : undefined, args[1]())
|
|
130
|
+
),
|
|
124
131
|
};
|
|
125
132
|
};
|
|
126
133
|
|
|
127
134
|
const listenPortController = async (server, port, metadata) =>
|
|
128
135
|
new Promise((resolve) => {
|
|
129
136
|
try {
|
|
130
|
-
if (
|
|
137
|
+
if (port === ':') {
|
|
138
|
+
server.listen(port, actionInitLog);
|
|
139
|
+
return resolve(true);
|
|
140
|
+
}
|
|
131
141
|
|
|
132
142
|
const { host, path, client, runtime, meta } = metadata;
|
|
133
143
|
const error = [];
|