underpost 2.8.79 → 2.8.84

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 (53) hide show
  1. package/.github/workflows/ghpkg.yml +22 -20
  2. package/.github/workflows/npmpkg.yml +15 -10
  3. package/.github/workflows/pwa-microservices-template.page.yml +12 -3
  4. package/.github/workflows/pwa-microservices-template.test.yml +20 -17
  5. package/.vscode/extensions.json +2 -3
  6. package/.vscode/settings.json +2 -42
  7. package/Dockerfile +14 -33
  8. package/README.md +43 -25
  9. package/bin/db.js +1 -0
  10. package/bin/deploy.js +104 -797
  11. package/bin/file.js +18 -1
  12. package/bin/vs.js +18 -3
  13. package/cli.md +367 -207
  14. package/conf.js +4 -0
  15. package/docker-compose.yml +1 -1
  16. package/manifests/deployment/dd-template-development/deployment.yaml +167 -0
  17. package/manifests/deployment/dd-template-development/proxy.yaml +46 -0
  18. package/manifests/deployment/tensorflow/tf-gpu-test.yaml +65 -0
  19. package/manifests/lxd/lxd-admin-profile.yaml +1 -0
  20. package/manifests/lxd/lxd-preseed.yaml +9 -37
  21. package/manifests/lxd/underpost-setup.sh +98 -81
  22. package/manifests/maas/device-scan.sh +43 -0
  23. package/manifests/maas/gpu-diag.sh +19 -0
  24. package/manifests/maas/lxd-preseed.yaml +32 -0
  25. package/manifests/maas/maas-setup.sh +120 -0
  26. package/manifests/maas/nat-iptables.sh +26 -0
  27. package/manifests/maas/snap-clean.sh +26 -0
  28. package/manifests/mariadb/statefulset.yaml +2 -1
  29. package/manifests/mariadb/storage-class.yaml +10 -0
  30. package/manifests/mongodb-4.4/service-deployment.yaml +2 -2
  31. package/manifests/valkey/service.yaml +3 -9
  32. package/manifests/valkey/statefulset.yaml +10 -12
  33. package/package.json +1 -1
  34. package/src/cli/baremetal.js +1280 -0
  35. package/src/cli/cloud-init.js +537 -0
  36. package/src/cli/cluster.js +506 -243
  37. package/src/cli/deploy.js +41 -3
  38. package/src/cli/env.js +2 -2
  39. package/src/cli/image.js +57 -9
  40. package/src/cli/index.js +271 -232
  41. package/src/cli/lxd.js +314 -81
  42. package/src/cli/repository.js +7 -4
  43. package/src/cli/run.js +262 -0
  44. package/src/cli/test.js +1 -1
  45. package/src/index.js +28 -1
  46. package/src/runtime/lampp/Dockerfile +41 -47
  47. package/src/server/conf.js +61 -0
  48. package/src/server/logger.js +3 -3
  49. package/src/server/process.js +16 -19
  50. package/src/server/runtime.js +1 -6
  51. package/src/server/ssl.js +1 -12
  52. package/src/server/valkey.js +3 -3
  53. package/supervisord-openssh-server.conf +0 -5
package/src/cli/run.js ADDED
@@ -0,0 +1,262 @@
1
+ import { daemonProcess, getTerminalPid, openTerminal, pbcopy, shellCd, shellExec } from '../server/process.js';
2
+ import read from 'read';
3
+ import { getNpmRootPath } from '../server/conf.js';
4
+ import { loggerFactory } from '../server/logger.js';
5
+ import UnderpostTest from './test.js';
6
+ import fs from 'fs-extra';
7
+ import { range, setPad, timer } from '../client/components/core/CommonJs.js';
8
+ import UnderpostDeploy from './deploy.js';
9
+
10
+ const logger = loggerFactory(import.meta);
11
+
12
+ class UnderpostRun {
13
+ static DEFAULT_OPTION = {
14
+ dev: false,
15
+ podName: '',
16
+ volumeHostPath: '',
17
+ volumeMountPath: '',
18
+ imageName: '',
19
+ containerName: '',
20
+ namespace: '',
21
+ };
22
+ static RUNNERS = {
23
+ 'spark-template': (path, options = UnderpostRun.DEFAULT_OPTION) => {
24
+ const dir = '/home/dd/spark-template';
25
+ shellExec(`sudo rm -rf ${dir}`);
26
+ shellCd('/home/dd');
27
+
28
+ // pbcopy(`cd /home/dd && sbt new underpostnet/spark-template.g8`);
29
+ // await read({ prompt: 'Command copy to clipboard, press enter to continue.\n' });
30
+ shellExec(`cd /home/dd && sbt new underpostnet/spark-template.g8 '--name=spark-template'`);
31
+
32
+ shellCd(dir);
33
+
34
+ shellExec(`git init && git add . && git commit -m "Base implementation"`);
35
+ shellExec(`chmod +x ./replace_params.sh`);
36
+ shellExec(`chmod +x ./build.sh`);
37
+
38
+ shellExec(`./replace_params.sh`);
39
+ shellExec(`./build.sh`);
40
+
41
+ shellCd('/home/dd/engine');
42
+ },
43
+ rmi: (path, options = UnderpostRun.DEFAULT_OPTION) => {
44
+ shellExec(`podman rmi $(podman images -qa) --force`);
45
+ },
46
+ kill: (path, options = UnderpostRun.DEFAULT_OPTION) => {
47
+ shellExec(`sudo kill -9 $(lsof -t -i:${path})`);
48
+ },
49
+ secret: (path, options = UnderpostRun.DEFAULT_OPTION) => {
50
+ shellExec(
51
+ `underpost secret underpost --create-from-file ${
52
+ path ? path : `/home/dd/engine/engine-private/conf/dd-cron/.env.production`
53
+ }`,
54
+ );
55
+ },
56
+ 'gpu-env': (path, options = UnderpostRun.DEFAULT_OPTION) => {
57
+ shellExec(
58
+ `node bin cluster --dev --reset && node bin cluster --dev --dedicated-gpu --kubeadm && kubectl get pods --all-namespaces -o wide -w`,
59
+ );
60
+ },
61
+ 'tf-gpu-test': (path, options = UnderpostRun.DEFAULT_OPTION) => {
62
+ const { underpostRoot } = options;
63
+ shellExec(`kubectl delete configmap tf-gpu-test-script`);
64
+ shellExec(`kubectl delete pod tf-gpu-test-pod`);
65
+ shellExec(`kubectl apply -f ${underpostRoot}/manifests/deployment/tensorflow/tf-gpu-test.yaml`);
66
+ },
67
+ ide: (path, options = UnderpostRun.DEFAULT_OPTION) => {
68
+ const { underpostRoot } = options;
69
+ shellExec(`node ${underpostRoot}/bin/vs ${path}`);
70
+ },
71
+ monitor: (path, options = UnderpostRun.DEFAULT_OPTION) => {
72
+ const pid = getTerminalPid();
73
+ logger.info('monitor pid', pid);
74
+ const checkPath = '/await';
75
+ const _monitor = async () => {
76
+ const result = UnderpostDeploy.API.existsContainerFile({ podName: path, path: checkPath });
77
+ logger.info('monitor', result);
78
+ if (result === true) {
79
+ switch (path) {
80
+ case 'tf-vae-test':
81
+ {
82
+ const nameSpace = 'default';
83
+ const podName = path;
84
+ const basePath = '/home/dd';
85
+ const scriptPath = '/site/en/tutorials/generative/cvae.py';
86
+ // shellExec(
87
+ // `sudo kubectl cp ${nameSpace}/${podName}:${basePath}/docs${scriptPath} ${basePath}/lab/src/${scriptPath
88
+ // .split('/')
89
+ // .pop()}`,
90
+ // );
91
+ // const file = fs.readFileSync(`${basePath}/lab/src/${scriptPath.split('/').pop()}`, 'utf8');
92
+ // fs.writeFileSync(
93
+ // `${basePath}/lab/src/${scriptPath.split('/').pop()}`,
94
+ // file.replace(
95
+ // `import time`,
96
+ // `import time
97
+ // print('=== SCRIPT UPDATE TEST ===')`,
98
+ // ),
99
+ // 'utf8',
100
+ // );
101
+ shellExec(
102
+ `sudo kubectl cp ${basePath}/lab/src/${scriptPath
103
+ .split('/')
104
+ .pop()} ${nameSpace}/${podName}:${basePath}/docs${scriptPath}`,
105
+ );
106
+ // shellExec(`sudo kubectl exec -i ${podName} -- sh -c "ipython ${basePath}/docs${scriptPath}"`);
107
+ shellExec(`sudo kubectl exec -i ${podName} -- sh -c "rm -rf ${checkPath}"`);
108
+
109
+ {
110
+ const checkPath = `/latent_space_plot.png`;
111
+ const outsPaths = [];
112
+ logger.info('monitor', checkPath);
113
+ while (!UnderpostDeploy.API.existsContainerFile({ podName, path: `/home/dd/docs${checkPath}` }))
114
+ await timer(1000);
115
+
116
+ {
117
+ const toPath = `${basePath}/lab${checkPath}`;
118
+ outsPaths.push(toPath);
119
+ shellExec(`sudo kubectl cp ${nameSpace}/${podName}:${basePath}/docs${checkPath} ${toPath}`);
120
+ }
121
+
122
+ for (let i of range(1, 10)) {
123
+ i = `/image_at_epoch_${setPad(i, '0', 4)}.png`;
124
+ const toPath = `${basePath}/lab/${i}`;
125
+ outsPaths.push(toPath);
126
+ shellExec(`sudo kubectl cp ${nameSpace}/${podName}:${basePath}/docs${i} ${toPath}`);
127
+ }
128
+ openTerminal(`firefox ${outsPaths.join(' ')}`, { single: true });
129
+ }
130
+ shellExec(`sudo kill -9 ${pid}`);
131
+ }
132
+ break;
133
+
134
+ default:
135
+ break;
136
+ }
137
+ return;
138
+ }
139
+ await timer(1000);
140
+ _monitor();
141
+ };
142
+ _monitor();
143
+ },
144
+ 'tf-vae-test': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
145
+ const { underpostRoot } = options;
146
+ const podName = 'tf-vae-test';
147
+ await UnderpostRun.RUNNERS['deploy-job']('', {
148
+ podName,
149
+ // volumeMountPath: '/custom_images',
150
+ // volumeHostPath: '/home/dd/engine/src/client/public/cyberia/assets/skin',
151
+ on: {
152
+ init: async () => {
153
+ openTerminal(`node bin run --dev monitor ${podName}`);
154
+ },
155
+ },
156
+ args: [
157
+ `pip install --upgrade \
158
+ nbconvert \
159
+ tensorflow-probability==0.23.0 \
160
+ imageio \
161
+ git+https://github.com/tensorflow/docs \
162
+ matplotlib \
163
+ "numpy<1.25,>=1.21"`,
164
+ 'mkdir -p /home/dd',
165
+ 'cd /home/dd',
166
+ 'git clone https://github.com/tensorflow/docs.git',
167
+ 'cd docs',
168
+ 'jupyter nbconvert --to python site/en/tutorials/generative/cvae.ipynb',
169
+ `echo '' > /await`,
170
+ `echo '=== WAITING SCRIPT LAUNCH ==='`,
171
+ `while [ -f /await ]; do sleep 1; done`,
172
+ `echo '=== FINISHED ==='`,
173
+ daemonProcess(`ipython site/en/tutorials/generative/cvae.py`),
174
+ ],
175
+ });
176
+ },
177
+ 'deploy-job': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
178
+ const podName = options.podName || 'deploy-job';
179
+ const volumeName = `${podName}-volume`;
180
+ const args = (options.args ? options.args : path ? [`python ${path}`] : []).filter((c) => c.trim());
181
+ const imageName = options.imageName || 'nvcr.io/nvidia/tensorflow:24.04-tf2-py3';
182
+ const containerName = options.containerName || `${podName}-container`;
183
+ const gpuEnable = imageName.match('nvidia');
184
+ const runtimeClassName = gpuEnable ? 'nvidia' : '';
185
+ const namespace = options.namespace || 'default';
186
+ const volumeMountPath = options.volumeMountPath || path;
187
+ const volumeHostPath = options.volumeHostPath || path;
188
+ const enableVolumeMount = volumeHostPath && volumeMountPath;
189
+
190
+ const cmd = `kubectl apply -f - <<EOF
191
+ apiVersion: v1
192
+ kind: Pod
193
+ metadata:
194
+ name: ${podName}
195
+ namespace: ${namespace}
196
+ spec:
197
+ restartPolicy: Never
198
+ ${runtimeClassName ? ` runtimeClassName: ${runtimeClassName}` : ''}
199
+ containers:
200
+ - name: ${containerName}
201
+ image: ${imageName}
202
+ imagePullPolicy: IfNotPresent
203
+ tty: true
204
+ stdin: true
205
+ command: ${JSON.stringify(options.command ? options.command : ['/bin/bash', '-c'])}
206
+ ${
207
+ args.length > 0
208
+ ? ` args:
209
+ - |
210
+ ${args.map((arg) => ` ${arg}`).join('\n')}`
211
+ : ''
212
+ }
213
+ ${
214
+ gpuEnable
215
+ ? ` resources:
216
+ limits:
217
+ nvidia.com/gpu: '1'
218
+ env:
219
+ - name: NVIDIA_VISIBLE_DEVICES
220
+ value: all`
221
+ : ''
222
+ }
223
+ ${
224
+ enableVolumeMount
225
+ ? `
226
+ volumeMounts:
227
+ - name: ${volumeName}
228
+ mountPath: ${volumeMountPath}
229
+ volumes:
230
+ - name: ${volumeName}
231
+ hostPath:
232
+ path: ${volumeHostPath}
233
+ type: ${fs.statSync(volumeHostPath).isDirectory() ? 'Directory' : 'File'}`
234
+ : ''
235
+ }
236
+ EOF`;
237
+ shellExec(`kubectl delete pod ${podName}`);
238
+ console.log(cmd);
239
+ shellExec(cmd, { disableLog: true });
240
+ const successInstance = await UnderpostTest.API.statusMonitor(podName);
241
+ if (successInstance) {
242
+ options.on?.init ? await options.on.init() : null;
243
+ shellExec(`kubectl logs -f ${podName}`);
244
+ }
245
+ },
246
+ };
247
+ static API = {
248
+ async callback(runner, path, options = UnderpostRun.DEFAULT_OPTION) {
249
+ const npmRoot = getNpmRootPath();
250
+ const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
251
+ if (options.command) options.command = options.command.split(',');
252
+ if (options.args) options.args = options.args.split(',');
253
+ options.underpostRoot = underpostRoot;
254
+ options.npmRoot = npmRoot;
255
+ logger.info('callback', { path, options });
256
+ const result = await UnderpostRun.RUNNERS[runner](path, options);
257
+ return result;
258
+ },
259
+ };
260
+ }
261
+
262
+ export default UnderpostRun;
package/src/cli/test.js CHANGED
@@ -94,7 +94,7 @@ class UnderpostTest {
94
94
  const _monitor = async () => {
95
95
  await timer(deltaMs);
96
96
  const pods = UnderpostDeploy.API.get(podName, kindType);
97
- const result = pods.find((p) => p.STATUS === status);
97
+ let result = pods.find((p) => p.STATUS === status || (status === 'Running' && p.STATUS === 'Completed'));
98
98
  logger.info(
99
99
  `Testing pod ${podName}... ${result ? 1 : 0}/1 - elapsed time ${deltaMs * (index + 1)}s - attempt ${
100
100
  index + 1
package/src/index.js CHANGED
@@ -4,6 +4,8 @@
4
4
  * @namespace Underpost
5
5
  */
6
6
 
7
+ import UnderpostBaremetal from './cli/baremetal.js';
8
+ import UnderpostCloudInit from './cli/cloud-init.js';
7
9
  import UnderpostCluster from './cli/cluster.js';
8
10
  import UnderpostCron from './cli/cron.js';
9
11
  import UnderpostDB from './cli/db.js';
@@ -14,6 +16,7 @@ import UnderpostImage from './cli/image.js';
14
16
  import UnderpostLxd from './cli/lxd.js';
15
17
  import UnderpostMonitor from './cli/monitor.js';
16
18
  import UnderpostRepository from './cli/repository.js';
19
+ import UnderpostRun from './cli/run.js';
17
20
  import UnderpostScript from './cli/script.js';
18
21
  import UnderpostSecret from './cli/secrets.js';
19
22
  import UnderpostTest from './cli/test.js';
@@ -31,7 +34,7 @@ class Underpost {
31
34
  * @type {String}
32
35
  * @memberof Underpost
33
36
  */
34
- static version = 'v2.8.79';
37
+ static version = 'v2.8.84';
35
38
  /**
36
39
  * Repository cli API
37
40
  * @static
@@ -130,6 +133,30 @@ class Underpost {
130
133
  * @memberof Underpost
131
134
  */
132
135
  static lxd = UnderpostLxd.API;
136
+
137
+ /**
138
+ * Cloud Init cli API
139
+ * @static
140
+ * @type {UnderpostCloudInit.API}
141
+ * @memberof Underpost
142
+ */
143
+ static cloudInit = UnderpostCloudInit.API;
144
+
145
+ /**
146
+ * Run cli API
147
+ * @static
148
+ * @type {UnderpostRun.API}
149
+ * @memberof Underpost
150
+ */
151
+ static run = UnderpostRun.API;
152
+
153
+ /**
154
+ * Baremetal cli API
155
+ * @static
156
+ * @type {UnderpostBaremetal.API}
157
+ * @memberof Underpost
158
+ */
159
+ static baremetal = UnderpostBaremetal.API;
133
160
  }
134
161
 
135
162
  const up = Underpost;
@@ -1,65 +1,59 @@
1
- ARG BASE_DEBIAN=buster
2
-
3
- # USER root
4
-
5
- FROM debian:${BASE_DEBIAN}
6
-
7
- ENV DEBIAN_FRONTEND=noninteractive
8
-
9
- # Set root password to root, format is 'user:password'.
10
- RUN echo 'root:root' | chpasswd
11
-
12
- RUN apt-get update --fix-missing
13
- RUN apt-get upgrade -y
14
- # install sudo
15
- RUN apt-get -y install sudo
16
- # net-tools provides netstat commands
17
- RUN apt-get -y install curl net-tools
18
- RUN apt-get -yq install openssh-server supervisor
19
- # Few handy utilities which are nice to have
20
- RUN apt-get -y install nano vim less --no-install-recommends
21
- RUN apt-get clean
22
-
23
- # install ssh
24
- RUN mkdir -p /var/run/sshd
25
- # Allow root login via password
26
- RUN sed -ri 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
27
-
28
- # install open ssl git and others tools
29
- RUN apt-get install -yq --no-install-recommends libssl-dev curl wget git gnupg
30
-
31
- # install lampp
1
+ FROM rockylinux:9
2
+
3
+ RUN dnf install -y --allowerasing bzip2
4
+
5
+ RUN dnf update -y
6
+ RUN dnf install -y epel-release
7
+ RUN dnf install -y --allowerasing sudo
8
+ RUN dnf install -y --allowerasing curl
9
+ RUN dnf install -y --allowerasing net-tools
10
+ RUN dnf install -y --allowerasing openssh-server
11
+ RUN dnf install -y --allowerasing nano
12
+ RUN dnf install -y --allowerasing vim-enhanced
13
+ RUN dnf install -y --allowerasing less
14
+ RUN dnf install -y --allowerasing openssl-devel
15
+ RUN dnf install -y --allowerasing wget
16
+ RUN dnf install -y --allowerasing git
17
+ RUN dnf install -y --allowerasing gnupg2
18
+ RUN dnf clean all
19
+
20
+ # Install LAMPP (XAMPP)
21
+ # Download the XAMPP installer for Linux
32
22
  RUN curl -Lo xampp-linux-installer.run https://sourceforge.net/projects/xampp/files/XAMPP%20Linux/7.4.33/xampp-linux-x64-7.4.33-0-installer.run?from_af=true
33
23
  RUN chmod +x xampp-linux-installer.run
34
- RUN bash -c './xampp-linux-installer.run'
24
+ # Run the XAMPP installer in silent mode
25
+ RUN bash -c './xampp-linux-installer.run --mode unattended'
26
+ # Create a symbolic link for easy access to lampp command
35
27
  RUN ln -sf /opt/lampp/lampp /usr/bin/lampp
36
- # Enable XAMPP web interface(remove security checks)
37
- RUN sed -i.bak s'/Require local/Require all granted/g' /opt/lampp/etc/extra/httpd-xampp.conf
28
+
29
+ # Configure XAMPP
30
+ # Enable XAMPP web interface (remove security checks)
31
+ RUN sed -i.bak 's/Require local/Require all granted/g' /opt/lampp/etc/extra/httpd-xampp.conf
38
32
  # Enable error display in php
39
- RUN sed -i.bak s'/display_errors=Off/display_errors=On/g' /opt/lampp/etc/php.ini
40
- # Enable includes of several configuration files
41
- RUN mkdir /opt/lampp/apache2/conf.d
33
+ RUN sed -i.bak 's/display_errors=Off/display_errors=On/g' /opt/lampp/etc/php.ini
34
+ # Enable includes of several configuration files for Apache
35
+ RUN mkdir -p /opt/lampp/apache2/conf.d
42
36
  RUN echo "IncludeOptional /opt/lampp/apache2/conf.d/*.conf" >>/opt/lampp/etc/httpd.conf
43
- # Create a /www folder and a symbolic link to it in /opt/lampp/htdocs. It'll be accessible via http://localhost:[port]/www/
44
- # This is convenient because it doesn't interfere with xampp, phpmyadmin or other tools in /opt/lampp/htdocs
45
- # /opt/lampp/etc/httpd.conf
37
+ # Create a /www folder and a symbolic link to it in /opt/lampp/htdocs
38
+ # This is convenient because it doesn't interfere with xampp, phpmyadmin or other tools
46
39
  RUN mkdir /www
47
40
  RUN ln -s /www /opt/lampp/htdocs
48
41
 
49
- # install nodejs https://github.com/nodesource/distributions/blob/master/README.md#deb
50
- RUN curl -fsSL https://deb.nodesource.com/setup_23.x | bash -
51
- RUN apt-get install -y nodejs build-essential
42
+ # Install Node.js
43
+ RUN curl -fsSL https://rpm.nodesource.com/setup_23.x | bash -
44
+ RUN dnf install nodejs -y
45
+ RUN dnf clean all
46
+
47
+ # Verify Node.js and npm versions
52
48
  RUN node --version
53
49
  RUN npm --version
54
50
 
51
+ # Set working directory
55
52
  WORKDIR /home/dd
56
53
 
54
+ # Expose necessary ports
57
55
  EXPOSE 22
58
-
59
56
  EXPOSE 80
60
-
61
57
  EXPOSE 443
62
-
63
58
  EXPOSE 3000-3100
64
-
65
59
  EXPOSE 4000-4100
@@ -1171,6 +1171,66 @@ const writeEnv = (envPath, envObj) =>
1171
1171
  'utf8',
1172
1172
  );
1173
1173
 
1174
+ const buildCliDoc = (program, oldVersion, newVersion) => {
1175
+ let md = shellExec(`node bin help`, { silent: true, stdout: true }).split('Options:');
1176
+ const baseOptions =
1177
+ `## ${md[0].split(`\n`)[2]}
1178
+
1179
+ ### Usage: ` +
1180
+ '`' +
1181
+ md[0].split(`\n`)[0].split('Usage: ')[1] +
1182
+ '`' +
1183
+ `
1184
+ ` +
1185
+ '```\n Options:' +
1186
+ md[1] +
1187
+ ' \n```';
1188
+ md =
1189
+ baseOptions +
1190
+ `
1191
+
1192
+ ## Commands:
1193
+ `;
1194
+ program.commands.map((o) => {
1195
+ md +=
1196
+ `
1197
+
1198
+ ` +
1199
+ '### `' +
1200
+ o._name +
1201
+ '` :' +
1202
+ `
1203
+ ` +
1204
+ '```\n ' +
1205
+ shellExec(`node bin help ${o._name}`, { silent: true, stdout: true }) +
1206
+ ' \n```' +
1207
+ `
1208
+ `;
1209
+ });
1210
+ md = md.replaceAll(oldVersion, newVersion);
1211
+ fs.writeFileSync(`./src/client/public/nexodev/docs/references/Command Line Interface.md`, md, 'utf8');
1212
+ fs.writeFileSync(`./cli.md`, md, 'utf8');
1213
+ const readmeSplit = `pwa-microservices-template</a>`;
1214
+ const readme = fs.readFileSync(`./README.md`, 'utf8').split(readmeSplit);
1215
+ fs.writeFileSync(
1216
+ './README.md',
1217
+ (
1218
+ readme[0] +
1219
+ readmeSplit +
1220
+ `
1221
+
1222
+ ` +
1223
+ baseOptions +
1224
+ `
1225
+
1226
+ <a target="_top" href="https://github.com/underpostnet/pwa-microservices-template/blob/master/cli.md">See complete CLI Docs here.</a>
1227
+
1228
+ `
1229
+ ).replaceAll(oldVersion, newVersion),
1230
+ 'utf8',
1231
+ );
1232
+ };
1233
+
1174
1234
  export {
1175
1235
  Cmd,
1176
1236
  Config,
@@ -1214,4 +1274,5 @@ export {
1214
1274
  deployRangePortFactory,
1215
1275
  awaitDeployMonitor,
1216
1276
  rebuildConfFactory,
1277
+ buildCliDoc,
1217
1278
  };
@@ -176,7 +176,7 @@ const loggerMiddleware = (meta = { url: '' }) => {
176
176
  );
177
177
  };
178
178
 
179
- const underpostASCI = () => `
179
+ const underpostASCII = () => `
180
180
 
181
181
  ██╗░░░██╗███╗░░██╗██████╗░███████╗██████╗░██████╗░░█████╗░░██████╗████████╗
182
182
  ██║░░░██║████╗░██║██╔══██╗██╔════╝██╔══██╗██╔══██╗██╔══██╗██╔════╝╚══██╔══╝
@@ -188,10 +188,10 @@ const underpostASCI = () => `
188
188
 
189
189
  const actionInitLog = () =>
190
190
  console.log(
191
- underpostASCI() +
191
+ underpostASCII() +
192
192
  `
193
193
  https://www.nexodev.org/docs
194
194
  `,
195
195
  );
196
196
 
197
- export { loggerFactory, loggerMiddleware, setUpInfo, underpostASCI, actionInitLog };
197
+ export { loggerFactory, loggerMiddleware, setUpInfo, underpostASCII, actionInitLog };
@@ -10,8 +10,6 @@ dotenv.config();
10
10
 
11
11
  const logger = loggerFactory(import.meta);
12
12
 
13
- // process.exit();
14
-
15
13
  const getRootDirectory = () => process.cwd().replace(/\\/g, '/');
16
14
 
17
15
  const ProcessController = {
@@ -63,27 +61,26 @@ const shellCd = (cd, options = { disableLog: false }) => {
63
61
  return shell.cd(cd);
64
62
  };
65
63
 
66
- function pbcopy(data) {
67
- switch (process.platform) {
68
- case 'linux':
69
- {
70
- // sudo dnf install xclip
71
- // sudo apt update
72
- // sudo apt install xclip
73
- // paste: xclip -o
74
- // copy:
75
- // shellExec(`echo "${data}" | xclip -sel clip`, { async: true });
76
- }
64
+ const openTerminal = (cmd, options = { single: false }) => {
65
+ if (options.single === true) {
66
+ shellExec(`setsid gnome-terminal -- bash -ic "${cmd}; exec bash" >/dev/null 2>&1 &`);
67
+ return;
68
+ }
69
+ shellExec(`gnome-terminal -- bash -c "${cmd}; exec bash" & disown`, {
70
+ async: true,
71
+ stdout: true,
72
+ });
73
+ };
77
74
 
78
- break;
75
+ const daemonProcess = (cmd) => `exec bash -c '${cmd}; exec tail -f /dev/null'`;
79
76
 
80
- default:
81
- break;
82
- }
77
+ // list all terminals: pgrep gnome-terminal
78
+ // list last terminal: pgrep -n gnome-terminal
79
+ const getTerminalPid = () => JSON.parse(shellExec(`pgrep -n gnome-terminal`, { stdout: true, silent: true }));
83
80
 
81
+ function pbcopy(data) {
84
82
  clipboard.writeSync(data || '🦄');
85
-
86
83
  logger.info(`copied to clipboard`, clipboard.readSync());
87
84
  }
88
85
 
89
- export { ProcessController, getRootDirectory, shellExec, shellCd, pbcopy };
86
+ export { ProcessController, getRootDirectory, shellExec, shellCd, pbcopy, openTerminal, getTerminalPid, daemonProcess };
@@ -251,11 +251,6 @@ const buildRuntime = async () => {
251
251
  return next();
252
252
  });
253
253
 
254
- // https://github.com/prometheus/prometheus/blob/main/documentation/examples/prometheus.yml
255
- // https://github.com/grafana/grafana/tree/main/conf
256
- // https://medium.com/@diego.coder/monitoreo-de-aplicaciones-con-node-js-grafana-y-prometheus-afd2b33e3f91
257
- // for grafana prometheus server: host.docker.internal:9090
258
-
259
254
  app.use((req, res, next) => {
260
255
  requestCounter.inc({
261
256
  instance: `${host}:${port}${path}`,
@@ -366,7 +361,7 @@ const buildRuntime = async () => {
366
361
  if (db && apis) await DataBaseProvider.load({ apis, host, path, db });
367
362
 
368
363
  // valkey server
369
- await createValkeyConnection({ host, path }, valkey);
364
+ if (valkey) await createValkeyConnection({ host, path }, valkey);
370
365
 
371
366
  if (mailer) {
372
367
  const mailerSsrConf = confSSR[getCapVariableName(client)];
package/src/server/ssl.js CHANGED
@@ -106,15 +106,4 @@ const sslRedirectMiddleware = (req, res, port, proxyRouter) => {
106
106
  return res.status(302).redirect(sslRedirectUrl);
107
107
  };
108
108
 
109
- const installCertbot = () => {
110
- switch (process.platform) {
111
- case 'win32':
112
- break;
113
- case 'linux':
114
- break;
115
- default:
116
- break;
117
- }
118
- };
119
-
120
- export { buildSSL, buildSecureContext, validateSecureContext, createSslServer, sslRedirectMiddleware, installCertbot };
109
+ export { buildSSL, buildSecureContext, validateSecureContext, createSslServer, sslRedirectMiddleware };
@@ -34,14 +34,14 @@ const selectDtoFactory = (payload, select) => {
34
34
  const valkeyClientFactory = async (options) => {
35
35
  const valkey = new Valkey({
36
36
  // port: 6379,
37
- // host: 'service-valkey.default.svc.cluster.local',
37
+ // host: 'valkey-service.default.svc.cluster.local',
38
38
  port: options?.port ? options.port : undefined,
39
- host: options?.port ? options.host : undefined,
39
+ host: options?.host ? options.host : undefined,
40
40
  retryStrategy: (attempt) => {
41
41
  if (attempt === 1) {
42
42
  valkey.disconnect();
43
43
  valkeyEnabled = false;
44
- logger.warn('Valkey service not enabled', { valkeyEnabled });
44
+ logger.warn('Valkey service not enabled', { ...options, valkeyEnabled });
45
45
  return;
46
46
  }
47
47
  return 1000; // 1 second interval attempt
@@ -1,5 +0,0 @@
1
- [program:openssh-server]
2
- command=/usr/sbin/sshd -D
3
- numprocs=1
4
- autostart=true
5
- autorestart=true