@underpostnet/underpost 2.8.4 → 2.8.5
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 +13 -46
- package/.github/workflows/npmpkg.yml +67 -0
- package/.github/workflows/publish.yml +5 -5
- package/.github/workflows/pwa-microservices-template.page.yml +3 -2
- package/.github/workflows/pwa-microservices-template.test.yml +2 -2
- package/.vscode/settings.json +6 -1
- package/CHANGELOG.md +16 -0
- package/Dockerfile +6 -27
- package/bin/build.js +52 -169
- package/bin/deploy.js +6 -27
- package/bin/file.js +29 -15
- package/bin/index.js +158 -30
- package/bin/util.js +0 -8
- package/docker-compose.yml +1 -1
- package/manifests/mongodb/backup-access.yaml +16 -0
- package/manifests/mongodb/backup-cronjob.yaml +42 -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 +21 -5
- package/src/api/core/core.service.js +1 -1
- package/src/cli/cluster.js +154 -0
- package/src/cli/cron.js +90 -0
- package/src/cli/db.js +148 -0
- package/src/cli/deploy.js +277 -0
- package/src/cli/env.js +52 -0
- package/src/cli/image.js +125 -0
- package/src/cli/repository.js +104 -0
- package/src/cli/script.js +29 -0
- package/src/cli/secrets.js +37 -0
- package/src/cli/test.js +83 -0
- package/src/client/components/core/Auth.js +22 -4
- package/src/client/components/core/CommonJs.js +82 -1
- package/src/client/components/core/Css.js +1 -0
- package/src/client/components/core/Input.js +1 -1
- package/src/client/components/core/Modal.js +0 -1
- 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/ssr/body/CacheControl.js +2 -2
- package/src/index.js +77 -26
- package/src/server/backup.js +49 -93
- package/src/server/client-build.js +1 -10
- package/src/server/client-formatted.js +5 -3
- package/src/server/conf.js +68 -187
- package/src/server/dns.js +48 -65
- package/src/server/logger.js +7 -7
- package/src/server/network.js +17 -7
- package/src/server/runtime.js +8 -22
- 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/src/server/dns.js
CHANGED
|
@@ -17,10 +17,8 @@ dotenv.config();
|
|
|
17
17
|
|
|
18
18
|
const logger = loggerFactory(import.meta);
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
callback: () => null,
|
|
23
|
-
InitIpDaemon: async function ({ deployId }) {
|
|
20
|
+
class Dns {
|
|
21
|
+
static callback = async function (deployList) {
|
|
24
22
|
// NAT-VPS modem/router device configuration:
|
|
25
23
|
// LAN --> [NAT-VPS] --> WAN
|
|
26
24
|
// enabled DMZ Host to proxy IP 80-443 (79-444) sometimes router block first port
|
|
@@ -30,56 +28,55 @@ const Dns = {
|
|
|
30
28
|
// LAN server or device's local servers port -> 3000-3100 (2999-3101)
|
|
31
29
|
// DNS Records: [ANAME](Address Dynamic) -> [A](ipv4) host | [AAAA](ipv6) host -> [public-ip]
|
|
32
30
|
// Forward the router's TCP/UDP ports to the LAN device's IP address
|
|
33
|
-
|
|
31
|
+
for (const _deployId of deployList.split(',')) {
|
|
32
|
+
const deployId = _deployId.trim();
|
|
34
33
|
const privateCronConfPath = `./engine-private/conf/${deployId}/conf.cron.json`;
|
|
35
|
-
|
|
36
34
|
const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json';
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (testIp && typeof testIp === 'string' && validator.isIP(testIp) && Dns.ip !== testIp) {
|
|
51
|
-
logger.info(`New ip`, testIp);
|
|
52
|
-
for (const recordType of Object.keys(confCronData.records)) {
|
|
53
|
-
switch (recordType) {
|
|
54
|
-
case 'A':
|
|
55
|
-
for (const dnsProvider of confCronData.records[recordType]) {
|
|
56
|
-
if (typeof Dns.services.updateIp[dnsProvider.dns] === 'function')
|
|
57
|
-
await Dns.services.updateIp[dnsProvider.dns]({ ...dnsProvider, ip: testIp });
|
|
58
|
-
}
|
|
59
|
-
break;
|
|
35
|
+
const confCronData = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
|
|
36
|
+
|
|
37
|
+
let testIp;
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
testIp = await ip.public.ipv4();
|
|
41
|
+
} catch (error) {
|
|
42
|
+
logger.error(error, { testIp, stack: error.stack });
|
|
43
|
+
}
|
|
44
|
+
const ipFileName = `${deployId}.ip`;
|
|
45
|
+
const currentIp = fs.existsSync(`./engine-private/deploy/${ipFileName}`)
|
|
46
|
+
? fs.readFileSync(`./engine-private/deploy/${ipFileName}`, 'utf8')
|
|
47
|
+
: undefined;
|
|
60
48
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
49
|
+
if (testIp && typeof testIp === 'string' && validator.isIP(testIp) && currentIp !== testIp) {
|
|
50
|
+
logger.info(`new ip`, testIp);
|
|
51
|
+
for (const recordType of Object.keys(confCronData.records)) {
|
|
52
|
+
switch (recordType) {
|
|
53
|
+
case 'A':
|
|
54
|
+
for (const dnsProvider of confCronData.records[recordType]) {
|
|
55
|
+
if (typeof Dns.services.updateIp[dnsProvider.dns] === 'function')
|
|
56
|
+
await Dns.services.updateIp[dnsProvider.dns]({ ...dnsProvider, ip: testIp });
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
|
|
60
|
+
default:
|
|
61
|
+
break;
|
|
64
62
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const ipUrlTest = `https://${process.env.DEFAULT_DEPLOY_HOST}`;
|
|
66
|
+
const response = await axios.get(ipUrlTest);
|
|
67
|
+
const verifyIp = response.request.socket.remoteAddress;
|
|
68
|
+
logger.info(ipUrlTest + ' IP', verifyIp);
|
|
69
|
+
if (verifyIp === testIp) {
|
|
70
|
+
fs.writeFileSync(`./engine-private/deploy/${ipFileName}`, testIp, 'utf8');
|
|
71
|
+
} else logger.error('ip not updated');
|
|
72
|
+
} catch (error) {
|
|
73
|
+
logger.error(error), 'ip not updated';
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
},
|
|
82
|
-
services: {
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
static services = {
|
|
83
80
|
updateIp: {
|
|
84
81
|
dondominio: (options) => {
|
|
85
82
|
const { user, api_key, host, dns, ip } = options;
|
|
@@ -100,21 +97,7 @@ const Dns = {
|
|
|
100
97
|
});
|
|
101
98
|
},
|
|
102
99
|
},
|
|
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
|
-
};
|
|
100
|
+
};
|
|
101
|
+
}
|
|
119
102
|
|
|
120
|
-
export
|
|
103
|
+
export default Dns;
|
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 = [];
|
package/src/server/runtime.js
CHANGED
|
@@ -15,7 +15,7 @@ import { getCapVariableName, newInstance } from '../client/components/core/Commo
|
|
|
15
15
|
import { Xampp } from '../runtime/xampp/Xampp.js';
|
|
16
16
|
import { MailerProvider } from '../mailer/MailerProvider.js';
|
|
17
17
|
import { DataBaseProvider } from '../db/DataBaseProvider.js';
|
|
18
|
-
import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
18
|
+
// import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
19
19
|
import { createPeerServer } from './peer.js';
|
|
20
20
|
import { Lampp } from '../runtime/lampp/Lampp.js';
|
|
21
21
|
import { getDeployId } from './conf.js';
|
|
@@ -31,20 +31,6 @@ const buildRuntime = async () => {
|
|
|
31
31
|
const collectDefaultMetrics = promClient.collectDefaultMetrics;
|
|
32
32
|
collectDefaultMetrics();
|
|
33
33
|
|
|
34
|
-
if (fs.existsSync(`/root/.bashrc`) && !fs.readFileSync(`/root/.bashrc`, 'utf8').match(`underpost-engine`)) {
|
|
35
|
-
fs.writeFileSync(
|
|
36
|
-
`/root/.bashrc`,
|
|
37
|
-
`${fs.readFileSync(`/root/.bashrc`, 'utf8')}
|
|
38
|
-
` +
|
|
39
|
-
`export NVM_DIR="$HOME/.nvm"
|
|
40
|
-
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
|
41
|
-
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm underpost-engine bash_completion
|
|
42
|
-
|
|
43
|
-
export PATH=$PATH:/opt/lampp/bin`,
|
|
44
|
-
'utf8',
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
34
|
const promCounterOption = {
|
|
49
35
|
name: `${deployId.replaceAll('-', '_')}_http_requests_total`,
|
|
50
36
|
help: 'Total number of HTTP requests',
|
|
@@ -54,7 +40,6 @@ export PATH=$PATH:/opt/lampp/bin`,
|
|
|
54
40
|
// logger.info('promCounterOption', promCounterOption);
|
|
55
41
|
|
|
56
42
|
const requestCounter = new promClient.Counter(promCounterOption);
|
|
57
|
-
|
|
58
43
|
const ipInstance = ''; // await ip.public.ipv4();
|
|
59
44
|
const initPort = parseInt(process.env.PORT) + 1;
|
|
60
45
|
let currentPort = initPort;
|
|
@@ -101,12 +86,13 @@ export PATH=$PATH:/opt/lampp/bin`,
|
|
|
101
86
|
apis,
|
|
102
87
|
};
|
|
103
88
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
89
|
+
const redirectTarget = redirect
|
|
90
|
+
? redirect[redirect.length - 1] === '/'
|
|
91
|
+
? redirect.slice(0, -1)
|
|
92
|
+
: redirect
|
|
93
|
+
: undefined;
|
|
94
|
+
|
|
95
|
+
// if (redirect) logger.info('redirect', new URL(redirect));
|
|
110
96
|
|
|
111
97
|
switch (runtime) {
|
|
112
98
|
case 'lampp':
|
package/src/dns.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// https://nodejs.org/api
|
|
4
|
-
// https://expressjs.com/en/4x/api.html
|
|
5
|
-
|
|
6
|
-
import dotenv from 'dotenv';
|
|
7
|
-
import { loggerFactory } from './server/logger.js';
|
|
8
|
-
import { Dns } from './server/dns.js';
|
|
9
|
-
import { ProcessController } from './server/process.js';
|
|
10
|
-
import { Config } from './server/conf.js';
|
|
11
|
-
|
|
12
|
-
dotenv.config();
|
|
13
|
-
|
|
14
|
-
await Config.build();
|
|
15
|
-
|
|
16
|
-
const logger = loggerFactory(import.meta);
|
|
17
|
-
|
|
18
|
-
await logger.setUpInfo();
|
|
19
|
-
|
|
20
|
-
await Dns.InitIpDaemon();
|
|
21
|
-
|
|
22
|
-
ProcessController.init(logger);
|
package/src/server/project.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { loadConf, newProject, repoClone, repoCommit, repoPull, repoPush } from './conf.js';
|
|
2
|
-
|
|
3
|
-
class Project {
|
|
4
|
-
constructor(repositoryName, version) {
|
|
5
|
-
return newProject(repositoryName, version);
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
static clone(gitUri = 'underpostnet/pwa-microservices-template') {
|
|
9
|
-
return repoClone(gitUri);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
static useEnv(deployId = 'default', env = 'production') {
|
|
13
|
-
return loadConf(deployId, env);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
static pull(repoPath = './', gitUri = 'underpostnet/pwa-microservices-template') {
|
|
17
|
-
return repoPull(repoPath, gitUri);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
static commit(
|
|
21
|
-
repoPath = './',
|
|
22
|
-
commitType = 'feat',
|
|
23
|
-
subModule = '',
|
|
24
|
-
message = '',
|
|
25
|
-
options = {
|
|
26
|
-
copy: false,
|
|
27
|
-
info: false,
|
|
28
|
-
empty: false,
|
|
29
|
-
},
|
|
30
|
-
) {
|
|
31
|
-
return repoCommit(repoPath, commitType, subModule, message, options);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
static push(repoPath = './', gitUri = 'underpostnet/pwa-microservices-template') {
|
|
35
|
-
return repoPush(repoPath, gitUri);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export default Project;
|
package/startup.cjs
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
const shell = require('shelljs');
|
|
2
|
-
|
|
3
|
-
// /usr/bin/supervisord -n
|
|
4
|
-
// /usr/sbin/sshd -D
|
|
5
|
-
|
|
6
|
-
shell.exec(`/usr/bin/supervisord -n`, { async: true });
|
|
7
|
-
|
|
8
|
-
// shell.exec(`sudo /opt/lampp/lampp start`, { async: true });
|
|
9
|
-
|
|
10
|
-
// shell.exec(`/usr/bin/mongod -f /etc/mongod.conf`, { async: true });
|
|
11
|
-
|
|
12
|
-
shell.exec(`underpost new app`);
|
|
File without changes
|
|
File without changes
|