underpost 2.8.839 → 2.8.843

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/.env.development CHANGED
@@ -1,3 +1,4 @@
1
+ DEPLOY_ID=dd-template
1
2
  NODE_ENV=development
2
3
  PORT=4000
3
4
  JWT_SECRET=test
package/.env.production CHANGED
@@ -1,3 +1,4 @@
1
+ DEPLOY_ID=dd-template
1
2
  NODE_ENV=production
2
3
  PORT=3000
3
4
  JWT_SECRET=test
package/.env.test CHANGED
@@ -1,3 +1,4 @@
1
+ DEPLOY_ID=dd-template
1
2
  NODE_ENV=test
2
3
  PORT=5000
3
4
  JWT_SECRET=test
package/README.md CHANGED
@@ -26,10 +26,14 @@ template
26
26
 
27
27
 
28
28
 
29
+
30
+
31
+
32
+
29
33
  <!-- badges -->
30
34
 
31
35
 
32
- [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/2.8.839)](https://socket.dev/npm/package/underpost/overview/2.8.839) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
36
+ [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/2.8.843)](https://socket.dev/npm/package/underpost/overview/2.8.843) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
33
37
 
34
38
 
35
39
  <!-- end-badges -->
@@ -38,6 +42,10 @@ template
38
42
 
39
43
 
40
44
 
45
+
46
+
47
+
48
+
41
49
  </div>
42
50
 
43
51
  <div align="center">
@@ -82,7 +90,7 @@ Run dev client server
82
90
  npm run dev
83
91
  ```
84
92
  <!-- -->
85
- ## underpost ci/cd cli v2.8.839
93
+ ## underpost ci/cd cli v2.8.843
86
94
 
87
95
  ### Usage: `underpost [options] [command]`
88
96
  ```
package/bin/build.js CHANGED
@@ -183,4 +183,5 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
183
183
  fs.copyFileSync(`./manifests/deployment/${confName}-${env}/${file}`, `${basePath}/${file}`);
184
184
  }
185
185
  }
186
+ fs.copyFileSync(`./.github/workflows/deploy.${confName}.yml`, `${basePath}/.github/workflows/deploy.${confName}.yml`);
186
187
  }
package/bin/deploy.js CHANGED
@@ -1110,18 +1110,6 @@ EOF`);
1110
1110
  break;
1111
1111
  }
1112
1112
 
1113
- case 'monitor': {
1114
- shellExec(
1115
- `node bin monitor ${process.argv[6] === 'sync' ? '--sync ' : ''}--type ${process.argv[3]} ${process.argv[4]} ${
1116
- process.argv[5]
1117
- }`,
1118
- {
1119
- async: true,
1120
- },
1121
- );
1122
- break;
1123
- }
1124
-
1125
1113
  case 'postgresql': {
1126
1114
  if (process.argv.includes('install')) {
1127
1115
  shellExec(`sudo dnf install -y postgresql-server postgresql`);
package/bin/file.js CHANGED
@@ -86,6 +86,9 @@ try {
86
86
  '.github/workflows/engine.lampp.ci.yml',
87
87
  '.github/workflows/engine.core.ci.yml',
88
88
  '.github/workflows/engine.cyberia.ci.yml',
89
+ '.github/workflows/deploy.dd-core.yml',
90
+ '.github/workflows/deploy.dd-cyberia.yml',
91
+ '.github/workflows/deploy.dd-lampp.yml',
89
92
  './manifests/deployment/dd-lampp-development',
90
93
  './manifests/deployment/dd-cyberia-development',
91
94
  './manifests/deployment/dd-core-development',
package/cli.md CHANGED
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v2.8.839
1
+ ## underpost ci/cd cli v2.8.843
2
2
 
3
3
  ### Usage: `underpost [options] [command]`
4
4
  ```
@@ -554,7 +554,7 @@ Options:
554
554
  Runs a script from the specified path.
555
555
 
556
556
  Arguments:
557
- runner-id The runner ID to run. Options: spark-template, gpu-env, tf-gpu-test, ide, monitor, tf-vae-test, deploy-job.
557
+ runner-id The runner ID to run. Options: spark-template, rmi, kill, secret, gpu-env, tf-gpu-test, ide, monitor, db-client, cluster, deploy, tf-vae-test, deploy-job.
558
558
  path The absolute or relative directory path where the script is located.
559
559
 
560
560
  Options:
@@ -564,6 +564,7 @@ Options:
564
564
  --pod-name <pod-name> Optional: Specifies the pod name for test execution.
565
565
  --volume-host-path <volume-host-path> Optional: Specifies the volume host path for test execution.
566
566
  --volume-mount-path <volume-mount-path> Optional: Specifies the volume mount path for test execution.
567
+ --volume-type <volume-type> Optional: Specifies the volume type for test execution.
567
568
  --image-name <image-name> Optional: Specifies the image name for test execution.
568
569
  --container-name <container-name> Optional: Specifies the container name for test execution.
569
570
  --namespace <namespace> Optional: Specifies the namespace for test execution.
@@ -58,7 +58,7 @@ services:
58
58
  cpus: '0.25'
59
59
  memory: 20M
60
60
  labels: # labels in Compose file instead of Dockerfile
61
- engine.version: '2.8.839'
61
+ engine.version: '2.8.843'
62
62
  networks:
63
63
  - load-balancer
64
64
 
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-template-development-blue
20
- image: localhost/rockylinux9-underpost:v2.8.839
20
+ image: localhost/rockylinux9-underpost:v2.8.843
21
21
  # resources:
22
22
  # requests:
23
23
  # memory: "124Ki"
@@ -100,7 +100,7 @@ spec:
100
100
  spec:
101
101
  containers:
102
102
  - name: dd-template-development-green
103
- image: localhost/rockylinux9-underpost:v2.8.839
103
+ image: localhost/rockylinux9-underpost:v2.8.843
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "underpost",
5
- "version": "2.8.839",
5
+ "version": "2.8.843",
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",
@@ -11,7 +11,7 @@
11
11
  "dev": "env-cmd -f .env.development node src/client.dev default",
12
12
  "dev-img": "env-cmd -f .env.development node src/server",
13
13
  "prod-img": "env-cmd -f .env.production node src/server",
14
- "monitor": "pm2 start bin/deploy.js --name monitor -- monitor",
14
+ "monitor": "pm2 start src/monitor.js --name monitor -- dd production",
15
15
  "dev-api": "env-cmd -f .env.development nodemon --watch src --ignore src/client src/api",
16
16
  "dev-client": "env-cmd -f .env.development node src/client.dev",
17
17
  "proxy": "node src/proxy proxy",
@@ -260,12 +260,12 @@ class UnderpostCluster {
260
260
 
261
261
  if (options.full === true || options.valkey === true) {
262
262
  if (options.pullImage === true) {
263
- shellExec(`docker pull valkey/valkey:latest`);
264
- shellExec(`sudo podman pull valkey/valkey:latest`);
265
- if (!options.kubeadm && !options.k3s)
263
+ // shellExec(`sudo podman pull valkey/valkey:latest`);
264
+ if (!options.kubeadm && !options.k3s) {
266
265
  // Only load if not kubeadm/k3s (Kind needs it)
266
+ shellExec(`docker pull valkey/valkey:latest`);
267
267
  shellExec(`sudo kind load docker-image valkey/valkey:latest`);
268
- else if (options.kubeadm || options.k3s)
268
+ } else if (options.kubeadm || options.k3s)
269
269
  // For kubeadm/k3s, ensure it's available for containerd
270
270
  shellExec(`sudo crictl pull valkey/valkey:latest`);
271
271
  }
@@ -279,12 +279,12 @@ class UnderpostCluster {
279
279
  shellExec(`kubectl delete statefulset mariadb-statefulset --ignore-not-found`);
280
280
 
281
281
  if (options.pullImage === true) {
282
- shellExec(`docker pull mariadb:latest`);
283
- shellExec(`sudo podman pull mariadb:latest`);
284
- if (!options.kubeadm && !options.k3s)
282
+ // shellExec(`sudo podman pull mariadb:latest`);
283
+ if (!options.kubeadm && !options.k3s) {
285
284
  // Only load if not kubeadm/k3s (Kind needs it)
285
+ shellExec(`docker pull mariadb:latest`);
286
286
  shellExec(`sudo kind load docker-image mariadb:latest`);
287
- else if (options.kubeadm || options.k3s)
287
+ } else if (options.kubeadm || options.k3s)
288
288
  // For kubeadm/k3s, ensure it's available for containerd
289
289
  shellExec(`sudo crictl pull mariadb:latest`);
290
290
  }
@@ -304,11 +304,11 @@ class UnderpostCluster {
304
304
  }
305
305
  if (options.full === true || options.postgresql === true) {
306
306
  if (options.pullImage === true) {
307
- shellExec(`docker pull postgres:latest`);
308
- if (!options.kubeadm && !options.k3s)
307
+ if (!options.kubeadm && !options.k3s) {
309
308
  // Only load if not kubeadm/k3s (Kind needs it)
309
+ shellExec(`docker pull postgres:latest`);
310
310
  shellExec(`sudo kind load docker-image postgres:latest`);
311
- else if (options.kubeadm || options.k3s)
311
+ } else if (options.kubeadm || options.k3s)
312
312
  // For kubeadm/k3s, ensure it's available for containerd
313
313
  shellExec(`sudo crictl pull postgres:latest`);
314
314
  }
@@ -319,11 +319,11 @@ class UnderpostCluster {
319
319
  }
320
320
  if (options.mongodb4 === true) {
321
321
  if (options.pullImage === true) {
322
- shellExec(`docker pull mongo:4.4`);
323
- if (!options.kubeadm && !options.k3s)
322
+ if (!options.kubeadm && !options.k3s) {
324
323
  // Only load if not kubeadm/k3s (Kind needs it)
324
+ shellExec(`docker pull mongo:4.4`);
325
325
  shellExec(`sudo kind load docker-image mongo:4.4`);
326
- else if (options.kubeadm || options.k3s)
326
+ } else if (options.kubeadm || options.k3s)
327
327
  // For kubeadm/k3s, ensure it's available for containerd
328
328
  shellExec(`sudo crictl pull mongo:4.4`);
329
329
  }
@@ -348,11 +348,11 @@ class UnderpostCluster {
348
348
  }
349
349
  } else if (options.full === true || options.mongodb === true) {
350
350
  if (options.pullImage === true) {
351
- shellExec(`docker pull mongo:latest`);
352
- if (!options.kubeadm && !options.k3s)
351
+ if (!options.kubeadm && !options.k3s) {
353
352
  // Only load if not kubeadm/k3s (Kind needs it)
353
+ shellExec(`docker pull mongo:latest`);
354
354
  shellExec(`sudo kind load docker-image mongo:latest`);
355
- else if (options.kubeadm || options.k3s)
355
+ } else if (options.kubeadm || options.k3s)
356
356
  // For kubeadm/k3s, ensure it's available for containerd
357
357
  shellExec(`sudo crictl pull mongo:latest`);
358
358
  }
@@ -368,7 +368,7 @@ class UnderpostCluster {
368
368
  shellExec(`kubectl apply -f ${underpostRoot}/manifests/mongodb/storage-class.yaml`);
369
369
  shellExec(`kubectl apply -k ${underpostRoot}/manifests/mongodb`);
370
370
 
371
- const successInstance = await UnderpostTest.API.statusMonitor('mongodb-1');
371
+ const successInstance = await UnderpostTest.API.statusMonitor('mongodb-1', 'Running', 'pods', 1000, 60 * 10);
372
372
 
373
373
  if (successInstance) {
374
374
  const mongoConfig = {
@@ -425,7 +425,7 @@ class UnderpostCluster {
425
425
  * @param {string} underpostRoot - The root directory of the underpost project.
426
426
  */
427
427
  config(options = { underpostRoot: '.' }) {
428
- const underpostRoot = options;
428
+ const { underpostRoot } = options;
429
429
  console.log('Applying host configuration: SELinux, Docker, Containerd, and Sysctl settings.');
430
430
  // Disable SELinux (permissive mode)
431
431
  shellExec(`sudo setenforce 0`);
@@ -460,10 +460,13 @@ class UnderpostCluster {
460
460
  `/etc/sysctl.d/99-k8s-ipforward.conf`,
461
461
  `/etc/sysctl.d/99-k8s.conf`,
462
462
  ])
463
- shellExec(`echo 'net.bridge.bridge-nf-call-iptables = 1
463
+ shellExec(
464
+ `echo 'net.bridge.bridge-nf-call-iptables = 1
464
465
  net.bridge.bridge-nf-call-ip6tables = 1
465
466
  net.bridge.bridge-nf-call-arptables = 1
466
- net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
467
+ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`,
468
+ { silent: true },
469
+ );
467
470
  // shellExec(`sudo sysctl --system`); // Apply sysctl changes immediately
468
471
  // Apply NAT iptables rules.
469
472
  shellExec(`${underpostRoot}/manifests/maas/nat-iptables.sh`, { silent: true });
package/src/cli/deploy.js CHANGED
@@ -528,6 +528,25 @@ node bin/deploy build-full-client ${deployId}
528
528
  }).trim(),
529
529
  );
530
530
  },
531
+ checkDeploymentReadyStatus(deployId, env, traffic) {
532
+ const cmd = `underpost config get container-status`;
533
+ const pods = UnderpostDeploy.API.get(`${deployId}-${env}-${traffic}`);
534
+ const readyPods = [];
535
+ const notReadyPods = [];
536
+ for (const pod of pods) {
537
+ const { NAME } = pod;
538
+ if (
539
+ shellExec(`sudo kubectl exec -i ${NAME} -- sh -c "${cmd}"`, { stdout: true }).match(
540
+ `${deployId}-${env}-running-deployment`,
541
+ )
542
+ ) {
543
+ readyPods.push(pod);
544
+ } else {
545
+ notReadyPods.push(pod);
546
+ }
547
+ }
548
+ return { ready: notReadyPods.length === 0, notReadyPods, readyPods };
549
+ },
531
550
  };
532
551
  }
533
552
 
package/src/cli/index.js CHANGED
@@ -86,7 +86,13 @@ program
86
86
  .argument('<deploy-id>', `The deployment configuration ID. Use 'clean' to restore default environment settings.`)
87
87
  .argument('[env]', 'Optional: The environment to set (e.g., "production", "development"). Defaults to "production".')
88
88
  .description('Sets environment variables and configurations related to a specific deployment ID.')
89
- .action(loadConf);
89
+ .action((...args) => {
90
+ if (args[0] === 'current') {
91
+ console.log(process.env.DEPLOY_ID);
92
+ return;
93
+ }
94
+ loadConf(...args);
95
+ });
90
96
 
91
97
  // 'config' command: Manage Underpost configurations
92
98
  program
@@ -326,6 +332,7 @@ program
326
332
  .option('--pod-name <pod-name>', 'Optional: Specifies the pod name for test execution.')
327
333
  .option('--volume-host-path <volume-host-path>', 'Optional: Specifies the volume host path for test execution.')
328
334
  .option('--volume-mount-path <volume-mount-path>', 'Optional: Specifies the volume mount path for test execution.')
335
+ .option('--volume-type <volume-type>', 'Optional: Specifies the volume type for test execution.')
329
336
  .option('--image-name <image-name>', 'Optional: Specifies the image name for test execution.')
330
337
  .option('--container-name <container-name>', 'Optional: Specifies the container name for test execution.')
331
338
  .option('--namespace <namespace>', 'Optional: Specifies the namespace for test execution.')
@@ -173,19 +173,15 @@ class UnderpostMonitor {
173
173
  monitorTrafficName = undefined;
174
174
  monitorPodName = undefined;
175
175
  }
176
- const cmd = `underpost config get container-status`;
177
176
  const checkDeploymentReadyStatus = () => {
178
- const pods = UnderpostDeploy.API.get(`${deployId}-${env}-${traffic}`);
179
- if (pods && pods[0]) {
180
- const { NAME } = pods[0];
181
- if (
182
- shellExec(`sudo kubectl exec -i ${NAME} -- sh -c "${cmd}"`, { stdout: true }).match(
183
- `${deployId}-${env}-running-deployment`,
184
- )
185
- ) {
186
- monitorPodName = NAME;
187
- monitorTrafficName = `${traffic}`;
188
- }
177
+ const { ready, notReadyPods, readyPods } = UnderpostDeploy.API.checkDeploymentReadyStatus(
178
+ deployId,
179
+ env,
180
+ traffic,
181
+ );
182
+ if (ready) {
183
+ monitorPodName = readyPods[0].NAME;
184
+ monitorTrafficName = `${traffic}`;
189
185
  }
190
186
  };
191
187
  if (!monitorPodName) {
package/src/cli/run.js CHANGED
@@ -6,6 +6,7 @@ import UnderpostTest from './test.js';
6
6
  import fs from 'fs-extra';
7
7
  import { range, setPad, timer } from '../client/components/core/CommonJs.js';
8
8
  import UnderpostDeploy from './deploy.js';
9
+ import UnderpostRootEnv from './env.js';
9
10
 
10
11
  const logger = loggerFactory(import.meta);
11
12
 
@@ -40,6 +41,19 @@ class UnderpostRun {
40
41
 
41
42
  shellCd('/home/dd/engine');
42
43
  },
44
+ rmi: (path, options = UnderpostRun.DEFAULT_OPTION) => {
45
+ shellExec(`podman rmi $(podman images -qa) --force`);
46
+ },
47
+ kill: (path, options = UnderpostRun.DEFAULT_OPTION) => {
48
+ shellExec(`sudo kill -9 $(lsof -t -i:${path})`);
49
+ },
50
+ secret: (path, options = UnderpostRun.DEFAULT_OPTION) => {
51
+ shellExec(
52
+ `underpost secret underpost --create-from-file ${
53
+ path ? path : `/home/dd/engine/engine-private/conf/dd-cron/.env.production`
54
+ }`,
55
+ );
56
+ },
43
57
  'gpu-env': (path, options = UnderpostRun.DEFAULT_OPTION) => {
44
58
  shellExec(
45
59
  `node bin cluster --dev --reset && node bin cluster --dev --dedicated-gpu --kubeadm && kubectl get pods --all-namespaces -o wide -w`,
@@ -128,6 +142,65 @@ class UnderpostRun {
128
142
  };
129
143
  _monitor();
130
144
  },
145
+ 'db-client': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
146
+ const { underpostRoot } = options;
147
+ shellExec(`kubectl apply -k ${underpostRoot}/manifests/deployment/adminer/.`);
148
+ },
149
+ cluster: async (path, options = UnderpostRun.DEFAULT_OPTION) => {
150
+ const deployList = fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').split(',');
151
+ const env = 'production';
152
+ shellCd(`/home/dd/engine`);
153
+ shellExec(`underpost cluster --reset`);
154
+ await timer(5000);
155
+ shellExec(`underpost cluster --kubeadm`);
156
+ await timer(5000);
157
+ shellExec(`underpost dockerfile-pull-base-images --path /home/dd/engine/src/runtime/lampp --kubeadm-load`);
158
+ await timer(5000);
159
+ shellExec(`underpost cluster --kubeadm --pull-image --mongodb`);
160
+ await timer(5000);
161
+ shellExec(`underpost cluster --kubeadm --pull-image --mariadb`);
162
+ await timer(5000);
163
+ for (const deployId of deployList) {
164
+ shellExec(`underpost db ${deployId} --import --git`);
165
+ }
166
+ await timer(5000);
167
+ shellExec(`underpost cluster --kubeadm --pull-image --valkey`);
168
+ await timer(5000);
169
+ shellExec(`underpost cluster --kubeadm --contour`);
170
+ await timer(5000);
171
+ shellExec(`underpost cluster --kubeadm --cert-manager`);
172
+ for (const deployId of deployList) {
173
+ shellExec(`underpost deploy ${deployId} ${env} --kubeadm --cert`);
174
+ }
175
+ },
176
+ deploy: async (path, options = UnderpostRun.DEFAULT_OPTION) => {
177
+ const deployId = path;
178
+ const currentTraffic = UnderpostDeploy.API.getCurrentTraffic(deployId);
179
+ const targetTraffic = currentTraffic === 'blue' ? 'green' : 'blue';
180
+ const env = 'production';
181
+ shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${targetTraffic}`);
182
+
183
+ let secondsElapsed = 0;
184
+ logger.info('Deployment init', { deployId, env, targetTraffic });
185
+
186
+ while (!UnderpostDeploy.API.checkDeploymentReadyStatus(deployId, env, targetTraffic).ready) {
187
+ await timer(1000);
188
+ secondsElapsed++;
189
+ logger.info(`Deployment in progress, seconds elapsed: ${secondsElapsed}`);
190
+ }
191
+
192
+ logger.info(`Deployment ready, seconds elapsed: ${secondsElapsed}`);
193
+
194
+ UnderpostRootEnv.API.set(`${deployId}-${env}-traffic`, targetTraffic);
195
+
196
+ shellExec(
197
+ `node bin deploy --info-router --build-manifest --traffic ${targetTraffic} --replicas ${
198
+ options.replicas ? options.replicas : 1
199
+ } ${deployId} ${env}`,
200
+ );
201
+ shellExec(`sudo kubectl apply -f ./engine-private/conf/${deployId}/build/${env}/proxy.yaml`);
202
+ shellExec(`sudo kubectl rollout restart deployment/${deployId}-${env}-${currentTraffic}`);
203
+ },
131
204
  'tf-vae-test': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
132
205
  const { underpostRoot } = options;
133
206
  const podName = 'tf-vae-test';
@@ -174,6 +247,12 @@ class UnderpostRun {
174
247
  const volumeHostPath = options.volumeHostPath || path;
175
248
  const enableVolumeMount = volumeHostPath && volumeMountPath;
176
249
 
250
+ if (options.volumeType === 'dev') options.volumeType = 'FileOrCreate';
251
+ const volumeType =
252
+ options.volumeType || (enableVolumeMount && fs.statSync(volumeHostPath).isDirectory()) ? 'Directory' : 'File';
253
+
254
+ const envs = UnderpostRootEnv.API.list();
255
+
177
256
  const cmd = `kubectl apply -f - <<EOF
178
257
  apiVersion: v1
179
258
  kind: Pod
@@ -197,16 +276,19 @@ ${
197
276
  ${args.map((arg) => ` ${arg}`).join('\n')}`
198
277
  : ''
199
278
  }
200
- ${
279
+ ${`${
201
280
  gpuEnable
202
281
  ? ` resources:
203
282
  limits:
204
283
  nvidia.com/gpu: '1'
205
- env:
206
- - name: NVIDIA_VISIBLE_DEVICES
207
- value: all`
284
+ `
208
285
  : ''
209
- }
286
+ } env:
287
+ ${Object.keys(envs)
288
+ .map((key) => ({ key, value: typeof envs[key] === 'number' ? envs[key] : `"${envs[key]}"` }))
289
+ .concat(gpuEnable ? [{ key: 'NVIDIA_VISIBLE_DEVICES', value: 'all' }] : [])
290
+ .map((env) => ` - name: ${env.key}\n value: ${env.value}`)
291
+ .join('\n')}`}
210
292
  ${
211
293
  enableVolumeMount
212
294
  ? `
@@ -217,7 +299,7 @@ ${
217
299
  - name: ${volumeName}
218
300
  hostPath:
219
301
  path: ${volumeHostPath}
220
- type: ${fs.statSync(volumeHostPath).isDirectory() ? 'Directory' : 'File'}`
302
+ type: ${volumeType}`
221
303
  : ''
222
304
  }
223
305
  EOF`;
package/src/index.js CHANGED
@@ -34,7 +34,7 @@ class Underpost {
34
34
  * @type {String}
35
35
  * @memberof Underpost
36
36
  */
37
- static version = 'v2.8.839';
37
+ static version = 'v2.8.843';
38
38
  /**
39
39
  * Repository cli API
40
40
  * @static
package/src/monitor.js ADDED
@@ -0,0 +1,24 @@
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 { ProcessController } from './server/process.js';
9
+ import { getUnderpostRootPath } from './server/conf.js';
10
+ import fs from 'fs-extra';
11
+ import UnderpostMonitor from './cli/monitor.js';
12
+
13
+ const underpostRootPath = getUnderpostRootPath();
14
+ fs.existsSync(`${underpostRootPath}/.env`)
15
+ ? dotenv.config({ path: `${underpostRootPath}/.env`, override: true })
16
+ : dotenv.config();
17
+
18
+ const logger = loggerFactory(import.meta);
19
+
20
+ await logger.setUpInfo();
21
+
22
+ UnderpostMonitor.API.callback(process.argv[2], process.argv[3], { type: 'blue-green', sync: true });
23
+
24
+ ProcessController.init(logger);
@@ -1,43 +1,35 @@
1
1
  FROM rockylinux:9
2
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
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
23
- RUN chmod +x 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
27
- RUN ln -sf /opt/lampp/lampp /usr/bin/lampp
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
32
- # Enable error display in php
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
36
- RUN echo "IncludeOptional /opt/lampp/apache2/conf.d/*.conf" >>/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
39
- RUN mkdir /www
40
- RUN ln -s /www /opt/lampp/htdocs
3
+ # --- Update and install required packages
4
+ RUN dnf -y update && \
5
+ dnf -y install epel-release && \
6
+ dnf -y install --allowerasing \
7
+ bzip2 \
8
+ sudo \
9
+ curl \
10
+ net-tools \
11
+ openssh-server \
12
+ nano \
13
+ vim-enhanced \
14
+ less \
15
+ openssl-devel \
16
+ wget \
17
+ git \
18
+ gnupg2 \
19
+ libnsl \
20
+ perl && \
21
+ dnf clean all
22
+
23
+ # --- Download and install XAMPP
24
+ RUN curl -L -o /tmp/xampp-linux-installer.run "https://sourceforge.net/projects/xampp/files/XAMPP%20Linux/7.4.33/xampp-linux-x64-7.4.33-0-installer.run" && \
25
+ chmod +x /tmp/xampp-linux-installer.run && \
26
+ bash -c "/tmp/xampp-linux-installer.run --mode unattended" && \
27
+ ln -sf /opt/lampp/lampp /usr/bin/lampp
28
+
29
+ # --- Create /xampp/htdocs (static root) and set permissions
30
+ RUN mkdir -p /opt/lampp/htdocs && \
31
+ chown -R root:root /opt/lampp/htdocs && \
32
+ chmod -R a+rX /opt/lampp/htdocs
41
33
 
42
34
  # Install Node.js
43
35
  RUN curl -fsSL https://rpm.nodesource.com/setup_23.x | bash -
@@ -51,7 +43,6 @@ RUN npm --version
51
43
  # Set working directory
52
44
  WORKDIR /home/dd
53
45
 
54
- # Expose necessary ports
55
46
  EXPOSE 22
56
47
  EXPOSE 80
57
48
  EXPOSE 443
@@ -10,7 +10,16 @@ const Lampp = {
10
10
  initService: async function (options = { daemon: false }) {
11
11
  let cmd;
12
12
  // linux
13
- fs.writeFileSync(`/opt/lampp/apache2/conf/httpd.conf`, this.router || '', 'utf8');
13
+ // /opt/lampp/apache2/conf/httpd.conf
14
+ fs.writeFileSync(`/opt/lampp/etc/extra/httpd-vhosts.conf`, this.router || '', 'utf8');
15
+ fs.writeFileSync(
16
+ `/opt/lampp/etc/httpd.conf`,
17
+ fs
18
+ .readFileSync(`/opt/lampp/etc/httpd.conf`, 'utf8')
19
+ .replace(`#Include etc/extra/httpd-vhosts.conf`, `Include etc/extra/httpd-vhosts.conf`),
20
+ 'utf8',
21
+ );
22
+
14
23
  cmd = `sudo /opt/lampp/lampp stop`;
15
24
  if (!fs.readFileSync(`/opt/lampp/etc/httpd.conf`, 'utf8').match(`# Listen 80`))
16
25
  fs.writeFileSync(
@@ -42,7 +51,7 @@ const Lampp = {
42
51
  if (this.router) fs.writeFileSync(`./tmp/lampp-router.conf`, this.router, 'utf-8');
43
52
  shellExec(cmd);
44
53
  },
45
- enabled: () => fs.existsSync(`/opt/lampp/apache2/conf/httpd.conf`),
54
+ enabled: () => fs.existsSync(`/opt/lampp/etc/httpd.conf`),
46
55
  appendRouter: function (render) {
47
56
  if (!this.router) {
48
57
  if (fs.existsSync(`./tmp/lampp-router.conf`))