underpost 2.89.1 → 2.89.2

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/README.md CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  <!-- badges -->
20
20
 
21
- [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.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.89.1)](https://socket.dev/npm/package/underpost/overview/2.89.1) [![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)
21
+ [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.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.89.2)](https://socket.dev/npm/package/underpost/overview/2.89.2) [![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)
22
22
 
23
23
  <!-- end-badges -->
24
24
 
@@ -66,7 +66,7 @@ Run dev client server
66
66
  npm run dev
67
67
  ```
68
68
  <!-- -->
69
- ## underpost ci/cd cli v2.89.1
69
+ ## underpost ci/cd cli v2.89.2
70
70
 
71
71
  ### Usage: `underpost [options] [command]`
72
72
  ```
package/cli.md CHANGED
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v2.89.1
1
+ ## underpost ci/cd cli v2.89.2
2
2
 
3
3
  ### Usage: `underpost [options] [command]`
4
4
  ```
@@ -277,6 +277,8 @@ Options:
277
277
  kubeconfig files.
278
278
  --k3s Initializes the cluster using K3s (Lightweight
279
279
  Kubernetes).
280
+ --hosts <hosts> A comma-separated list of cluster hostnames or IP
281
+ addresses.
280
282
  -h, --help display help for command
281
283
 
282
284
  ```
@@ -289,50 +291,53 @@ Options:
289
291
  Manages application deployments, defaulting to deploying development pods.
290
292
 
291
293
  Arguments:
292
- deploy-list A comma-separated list of deployment IDs
293
- (e.g., "default-a,default-b").
294
- env Optional: The environment for deployment
295
- (e.g., "development", "production").
296
- Defaults to "development".
294
+ deploy-list A comma-separated list of deployment IDs
295
+ (e.g., "default-a,default-b").
296
+ env Optional: The environment for deployment
297
+ (e.g., "development", "production").
298
+ Defaults to "development".
297
299
 
298
300
  Options:
299
- --remove Deletes specified deployments and their
300
- associated services.
301
- --sync Synchronizes deployment environment
302
- variables, ports, and replica counts.
303
- --info-router Displays the current router structure and
304
- configuration.
305
- --expose Exposes services matching the provided
306
- deployment ID list.
307
- --info-util Displays useful `kubectl` utility
308
- management commands.
309
- --cert Resets TLS/SSL certificate secrets for
310
- deployments.
311
- --cert-hosts <hosts> Resets TLS/SSL certificate secrets for
312
- specified hosts.
313
- --node <node> Sets optional node for deployment
314
- operations.
315
- --build-manifest Builds Kubernetes YAML manifests, including
316
- deployments, services, proxies, and
317
- secrets.
318
- --replicas <replicas> Sets a custom number of replicas for
319
- deployments.
320
- --image <image> Sets a custom image for deployments.
321
- --versions <deployment-versions> A comma-separated list of custom deployment
322
- versions.
323
- --traffic <traffic-versions> A comma-separated list of custom deployment
324
- traffic weights.
325
- --disable-update-deployment Disables updates to deployments.
326
- --disable-update-proxy Disables updates to proxies.
327
- --status Retrieves current network traffic data from
328
- resource deployments and the host machine
329
- network configuration.
330
- --kubeadm Enables the kubeadm context for deployment
331
- operations.
332
- --etc-hosts Enables the etc-hosts context for
333
- deployment operations.
334
- --restore-hosts Restores default `/etc/hosts` entries.
335
- -h, --help display help for command
301
+ --remove Deletes specified deployments and their
302
+ associated services.
303
+ --sync Synchronizes deployment environment
304
+ variables, ports, and replica counts.
305
+ --info-router Displays the current router structure and
306
+ configuration.
307
+ --expose Exposes services matching the provided
308
+ deployment ID list.
309
+ --info-util Displays useful `kubectl` utility
310
+ management commands.
311
+ --cert Resets TLS/SSL certificate secrets for
312
+ deployments.
313
+ --cert-hosts <hosts> Resets TLS/SSL certificate secrets for
314
+ specified hosts.
315
+ --node <node> Sets optional node for deployment
316
+ operations.
317
+ --build-manifest Builds Kubernetes YAML manifests,
318
+ including deployments, services, proxies,
319
+ and secrets.
320
+ --replicas <replicas> Sets a custom number of replicas for
321
+ deployments.
322
+ --image <image> Sets a custom image for deployments.
323
+ --versions <deployment-versions> A comma-separated list of custom
324
+ deployment versions.
325
+ --traffic <traffic-versions> A comma-separated list of custom
326
+ deployment traffic weights.
327
+ --disable-update-deployment Disables updates to deployments.
328
+ --disable-update-proxy Disables updates to proxies.
329
+ --disable-deployment-proxy Disables proxies of deployments.
330
+ --status Retrieves current network traffic data
331
+ from resource deployments and the host
332
+ machine network configuration.
333
+ --kubeadm Enables the kubeadm context for deployment
334
+ operations.
335
+ --etc-hosts Enables the etc-hosts context for
336
+ deployment operations.
337
+ --restore-hosts Restores default `/etc/hosts` entries.
338
+ --disable-update-underpost-config Disables updates to Underpost
339
+ configuration during deployment.
340
+ -h, --help display help for command
336
341
 
337
342
  ```
338
343
 
@@ -623,7 +628,7 @@ Options:
623
628
  Runs a script from the specified path.
624
629
 
625
630
  Arguments:
626
- runner-id The runner ID to run. Options: spark-template, rmi, kill, secret, underpost-config, gpu-env, tf-gpu-test, dev-cluster, ssh-cluster-info, dev-hosts-expose, dev-hosts-restore, cluster-build, template-deploy, template-deploy-image, clean, pull, release-deploy, ssh-deploy, ide, sync, tz, cron, ls-deployments, ls-images, host-update, dev-container, monitor, db-client, git-conf, promote, metrics, cluster, deploy, dev, service, sh, log, release-cmt, sync-replica, tf-vae-test, deploy-job.
631
+ runner-id The runner ID to run. Options: spark-template, rmi, kill, secret, underpost-config, gpu-env, tf-gpu-test, dev-cluster, metadata, svc-ls, svc-rm, ssh-cluster-info, dev-hosts-expose, dev-hosts-restore, cluster-build, template-deploy, template-deploy-image, clean, pull, release-deploy, ssh-deploy, ide, sync, tz, cron, ls-deployments, ls-images, host-update, dev-container, monitor, db-client, git-conf, promote, metrics, cluster, deploy, dev, service, sh, log, release-cmt, sync-replica, tf-vae-test, deploy-job.
627
632
  path The absolute or relative directory path where the script is located.
628
633
 
629
634
  Options:
@@ -632,7 +637,10 @@ Options:
632
637
  --dev Sets the development context environment for the script.
633
638
  --build Set builder context runner
634
639
  --replicas <replicas> Sets a custom number of replicas for deployment.
635
- --pod-name <pod-name> Optional: Specifies the pod name for test execution.
640
+ --pod-name <pod-name> Optional: Specifies the pod name for execution.
641
+ --node-name <node-name> Optional: Specifies the node name for execution.
642
+ --port <port> Optional: Specifies the port for execution.
643
+ --etc-hosts Enables etc-hosts context for the runner execution.
636
644
  --volume-host-path <volume-host-path> Optional: Specifies the volume host path for test execution.
637
645
  --volume-mount-path <volume-mount-path> Optional: Specifies the volume mount path for test execution.
638
646
  --volume-type <volume-type> Optional: Specifies the volume type for test execution.
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-default-development-blue
20
- image: localhost/rockylinux9-underpost:v2.89.1
20
+ image: localhost/rockylinux9-underpost:v2.89.2
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-default-development-green
103
- image: localhost/rockylinux9-underpost:v2.89.1
103
+ image: localhost/rockylinux9-underpost:v2.89.2
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-test-development-blue
20
- image: localhost/rockylinux9-underpost:v2.89.1
20
+ image: localhost/rockylinux9-underpost:v2.89.2
21
21
  # resources:
22
22
  # requests:
23
23
  # memory: "96294Ki"
@@ -104,7 +104,7 @@ spec:
104
104
  spec:
105
105
  containers:
106
106
  - name: dd-test-development-green
107
- image: localhost/rockylinux9-underpost:v2.89.1
107
+ image: localhost/rockylinux9-underpost:v2.89.2
108
108
  # resources:
109
109
  # requests:
110
110
  # memory: "96294Ki"
@@ -10,6 +10,7 @@ spec:
10
10
  routes:
11
11
  - conditions:
12
12
  - prefix: /
13
+
13
14
  enableWebsockets: true
14
15
  services:
15
16
  - name: dd-test-development-blue-service
@@ -18,6 +19,7 @@ spec:
18
19
 
19
20
  - conditions:
20
21
  - prefix: /peer
22
+
21
23
  enableWebsockets: true
22
24
  services:
23
25
  - name: dd-test-development-blue-service
@@ -35,6 +37,7 @@ spec:
35
37
  routes:
36
38
  - conditions:
37
39
  - prefix: /
40
+
38
41
  enableWebsockets: true
39
42
  services:
40
43
  - name: dd-test-development-blue-service
@@ -43,6 +46,7 @@ spec:
43
46
 
44
47
  - conditions:
45
48
  - prefix: /peer
49
+
46
50
  enableWebsockets: true
47
51
  services:
48
52
  - name: dd-test-development-blue-service
@@ -21,6 +21,13 @@ spec:
21
21
  containers:
22
22
  - name: grafana
23
23
  image: grafana/grafana:latest
24
+ env:
25
+ # - name: GF_SERVER_ROOT_URL
26
+ # value: '{{GF_SERVER_ROOT_URL}}'
27
+ - name: GF_SERVER_ROOT_URL
28
+ value: '/grafana'
29
+ - name: GF_SERVER_SERVE_FROM_SUB_PATH
30
+ value: 'true'
24
31
  imagePullPolicy: IfNotPresent
25
32
  ports:
26
33
  - containerPort: 3000
@@ -2,6 +2,6 @@
2
2
  apiVersion: kustomize.config.k8s.io/v1beta1
3
3
  kind: Kustomization
4
4
  resources:
5
+ - storage-class.yaml
5
6
  - pvc.yaml
6
- - deployment.yaml
7
7
  - service.yaml
@@ -6,7 +6,7 @@ metadata:
6
6
  spec:
7
7
  accessModes:
8
8
  - ReadWriteOnce
9
- storageClassName: local-path
9
+ storageClassName: grafana-storage-class
10
10
  resources:
11
11
  requests:
12
12
  storage: 5Gi
@@ -0,0 +1,9 @@
1
+ apiVersion: storage.k8s.io/v1
2
+ kind: StorageClass
3
+ metadata:
4
+ name: grafana-storage-class
5
+ annotations:
6
+ storageclass.kubernetes.io/is-default-class: 'false'
7
+ provisioner: rancher.io/local-path
8
+ reclaimPolicy: Retain
9
+ volumeBindingMode: WaitForFirstConsumer
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.89.1",
5
+ "version": "2.89.2",
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",
@@ -58,6 +58,7 @@ class UnderpostCluster {
58
58
  * @param {boolean} [options.config=false] - Apply general host configuration (SELinux, containerd, sysctl, firewalld).
59
59
  * @param {boolean} [options.worker=false] - Configure as a worker node (for Kubeadm or K3s join).
60
60
  * @param {boolean} [options.chown=false] - Set up kubectl configuration for the current user.
61
+ * @param {string} [options.hosts] - Set custom hosts entries.
61
62
  * @memberof UnderpostCluster
62
63
  */
63
64
  async init(
@@ -90,6 +91,7 @@ class UnderpostCluster {
90
91
  config: false,
91
92
  worker: false,
92
93
  chown: false,
94
+ hosts: '',
93
95
  },
94
96
  ) {
95
97
  // Handles initial host setup (installing docker, podman, kind, kubeadm, helm)
@@ -280,6 +282,14 @@ class UnderpostCluster {
280
282
  if (options.grafana === true) {
281
283
  shellExec(`kubectl delete deployment grafana --ignore-not-found`);
282
284
  shellExec(`kubectl apply -k ${underpostRoot}/manifests/grafana`);
285
+ const yaml = `${fs
286
+ .readFileSync(`${underpostRoot}/manifests/grafana/deployment.yaml`, 'utf8')
287
+ .replace('{{GF_SERVER_ROOT_URL}}', options.hosts.split(',')[0])}`;
288
+ console.log(yaml);
289
+ shellExec(`kubectl apply -f - <<EOF
290
+ ${yaml}
291
+ EOF
292
+ `);
283
293
  }
284
294
 
285
295
  if (options.prom && typeof options.prom === 'string') {
package/src/cli/deploy.js CHANGED
@@ -91,12 +91,25 @@ class UnderpostDeploy {
91
91
  * @param {Array<string>} deploymentVersions - List of deployment versions.
92
92
  * @returns {string} - YAML service configuration for the specified deployment.
93
93
  * @param {string} [serviceId] - Custom service name (optional).
94
+ * @param {Array} [pathRewritePolicy] - Path rewrite policy (optional).
94
95
  * @memberof UnderpostDeploy
95
96
  */
96
- deploymentYamlServiceFactory({ deployId, path, env, port, deploymentVersions, serviceId }) {
97
+ deploymentYamlServiceFactory({ deployId, path, env, port, deploymentVersions, serviceId, pathRewritePolicy }) {
97
98
  return `
98
99
  - conditions:
99
100
  - prefix: ${path}
101
+ ${
102
+ pathRewritePolicy
103
+ ? `pathRewritePolicy:
104
+ replacePrefix:
105
+ ${pathRewritePolicy.map(
106
+ (rd) => `- prefix: ${rd.prefix}
107
+ replacement: ${rd.replacement}
108
+ `,
109
+ ).join(`
110
+ `)}`
111
+ : ''
112
+ }
100
113
  enableWebsockets: true
101
114
  services:
102
115
  ${deploymentVersions
@@ -230,7 +243,7 @@ ${UnderpostDeploy.API.deploymentYamlPartsFactory({
230
243
 
231
244
  const pathPortAssignment = pathPortAssignmentData[host];
232
245
  // logger.info('', { host, pathPortAssignment });
233
- proxyYaml += `
246
+ let _proxyYaml = `
234
247
  ---
235
248
  apiVersion: projectcontour.io/v1
236
249
  kind: HTTPProxy
@@ -248,32 +261,31 @@ spec:
248
261
  routes:`;
249
262
  const deploymentVersions =
250
263
  options.traffic && typeof options.traffic === 'string' ? options.traffic.split(',') : ['blue'];
251
- for (const conditionObj of pathPortAssignment) {
252
- const { path, port } = conditionObj;
253
- proxyYaml += UnderpostDeploy.API.deploymentYamlServiceFactory({
254
- path,
255
- deployId,
256
- env,
257
- port,
258
- deploymentVersions,
259
- });
260
- }
264
+ let proxyRoutes = '';
265
+ if (!options.disableDeploymentProxy)
266
+ for (const conditionObj of pathPortAssignment) {
267
+ const { path, port } = conditionObj;
268
+ proxyRoutes += UnderpostDeploy.API.deploymentYamlServiceFactory({
269
+ path,
270
+ deployId,
271
+ env,
272
+ port,
273
+ deploymentVersions,
274
+ });
275
+ }
261
276
  for (const customService of customServices) {
262
- const { path: _path, port, serviceId, host: _host } = customService;
277
+ const { path: _path, port, serviceId, host: _host, pathRewritePolicy } = customService;
263
278
  if (host === _host) {
264
- switch (serviceId) {
265
- case 'mongo-express-service': {
266
- proxyYaml += UnderpostDeploy.API.deploymentYamlServiceFactory({
267
- path: _path,
268
- port,
269
- serviceId,
270
- deploymentVersions,
271
- });
272
- break;
273
- }
274
- }
279
+ proxyRoutes += UnderpostDeploy.API.deploymentYamlServiceFactory({
280
+ path: _path,
281
+ port,
282
+ serviceId,
283
+ deploymentVersions,
284
+ pathRewritePolicy,
285
+ });
275
286
  }
276
287
  }
288
+ if (proxyRoutes) proxyYaml += _proxyYaml + proxyRoutes;
277
289
  }
278
290
  const yamlPath = `./engine-private/conf/${deployId}/build/${env}/proxy.yaml`;
279
291
  fs.writeFileSync(yamlPath, proxyYaml, 'utf8');
@@ -332,28 +344,30 @@ spec:
332
344
 
333
345
  /**
334
346
  * Callback function for handling deployment options.
335
- * @param {string} deployList - List of deployment IDs to include in the manifest.
336
- * @param {string} env - Environment for which the manifest is being built.
337
- * @param {object} options - Options for the manifest build process.
338
- * @param {string} options.remove - Whether to remove the deployment.
339
- * @param {string} options.infoRouter - Whether to display router information.
340
- * @param {string} options.sync - Whether to synchronize the deployment.
341
- * @param {string} options.buildManifest - Whether to build the manifest.
342
- * @param {string} options.infoUtil - Whether to display utility information.
343
- * @param {string} options.expose - Whether to expose the deployment.
344
- * @param {string} options.cert - Whether to create a certificate.
345
- * @param {string} options.certHosts - List of hosts for which certificates are being created.
347
+ * @param {string} deployList - List of deployment IDs to process.
348
+ * @param {string} env - Environment for which the deployment is being processed.
349
+ * @param {object} options - Options for the deployment process.
350
+ * @param {boolean} options.remove - Whether to remove the deployment.
351
+ * @param {boolean} options.infoRouter - Whether to display router information.
352
+ * @param {boolean} options.sync - Whether to synchronize deployment configurations.
353
+ * @param {boolean} options.buildManifest - Whether to build the deployment manifest.
354
+ * @param {boolean} options.infoUtil - Whether to display utility information.
355
+ * @param {boolean} options.expose - Whether to expose the deployment.
356
+ * @param {boolean} options.cert - Whether to create certificates for the deployment.
357
+ * @param {string} options.certHosts - Comma-separated list of hosts for which to create certificates.
346
358
  * @param {string} options.versions - Comma-separated list of versions to deploy.
347
359
  * @param {string} options.image - Docker image for the deployment.
348
- * @param {string} options.traffic - Current traffic status for the deployment.
360
+ * @param {string} options.traffic - Traffic status for the deployment.
349
361
  * @param {string} options.replicas - Number of replicas for the deployment.
350
362
  * @param {string} options.node - Node name for resource allocation.
351
- * @param {string} options.restoreHosts - Whether to restore hosts.
352
- * @param {string} options.disableUpdateDeployment - Whether to disable updating the deployment.
353
- * @param {string} options.disableUpdateProxy - Whether to disable updating the proxy.
354
- * @param {string} options.status - Whether to display status host machine server and traffic information.
355
- * @param {string} options.etcHosts - Whether to update /etc/hosts.
356
- * @returns {Promise<void>} - Promise that resolves when the callback is complete.
363
+ * @param {boolean} options.restoreHosts - Whether to restore the hosts file.
364
+ * @param {boolean} options.disableUpdateDeployment - Whether to disable deployment updates.
365
+ * @param {boolean} options.disableUpdateProxy - Whether to disable proxy updates.
366
+ * @param {boolean} options.disableDeploymentProxy - Whether to disable deployment proxy.
367
+ * @param {boolean} options.status - Whether to display deployment status.
368
+ * @param {boolean} options.etcHosts - Whether to display the /etc/hosts file.
369
+ * @param {boolean} options.disableUpdateUnderpostConfig - Whether to disable Underpost config updates.
370
+ * @returns {Promise<void>} - Promise that resolves when the deployment process is complete.
357
371
  * @memberof UnderpostDeploy
358
372
  */
359
373
  async callback(
@@ -376,8 +390,10 @@ spec:
376
390
  restoreHosts: false,
377
391
  disableUpdateDeployment: false,
378
392
  disableUpdateProxy: false,
393
+ disableDeploymentProxy: false,
379
394
  status: false,
380
395
  etcHosts: false,
396
+ disableUpdateUnderpostConfig: false,
381
397
  },
382
398
  ) {
383
399
  if (options.infoUtil === true)
@@ -473,7 +489,7 @@ EOF`);
473
489
  logger.info('router', await UnderpostDeploy.API.routerFactory(deployList, env));
474
490
  return;
475
491
  }
476
- UnderpostDeploy.API.configMap(env);
492
+ if (!options.disableUpdateUnderpostConfig) UnderpostDeploy.API.configMap(env);
477
493
  let renderHosts = '';
478
494
  let etcHosts = [];
479
495
  if (options.restoreHosts === true) {
@@ -789,37 +805,35 @@ ${renderHosts}`,
789
805
  }))
790
806
  .filter((o) => o.image);
791
807
  }
792
- if (node === 'kind-worker') {
793
- const raw = shellExec(`docker exec -i ${node} crictl images`, {
794
- stdout: true,
795
- silent: true,
796
- });
808
+ const raw = shellExec(node === 'kind-worker' ? `docker exec -i ${node} crictl images` : `crictl images`, {
809
+ stdout: true,
810
+ silent: true,
811
+ });
812
+
813
+ const heads = raw
814
+ .split(`\n`)[0]
815
+ .split(' ')
816
+ .filter((_r) => _r.trim());
817
+
818
+ const pods = raw
819
+ .split(`\n`)
820
+ .filter((r) => !r.match('IMAGE'))
821
+ .map((r) => r.split(' ').filter((_r) => _r.trim()));
797
822
 
798
- const heads = raw
799
- .split(`\n`)[0]
800
- .split(' ')
801
- .filter((_r) => _r.trim());
823
+ const result = [];
802
824
 
803
- const pods = raw
804
- .split(`\n`)
805
- .filter((r) => !r.match('IMAGE'))
806
- .map((r) => r.split(' ').filter((_r) => _r.trim()));
807
-
808
- const result = [];
809
-
810
- for (const row of pods) {
811
- if (row.length === 0) continue;
812
- const pod = {};
813
- let index = -1;
814
- for (const head of heads) {
815
- if (head in pod) continue;
816
- index++;
817
- pod[head] = row[index];
818
- }
819
- result.push(pod);
825
+ for (const row of pods) {
826
+ if (row.length === 0) continue;
827
+ const pod = {};
828
+ let index = -1;
829
+ for (const head of heads) {
830
+ if (head in pod) continue;
831
+ index++;
832
+ pod[head] = row[index];
820
833
  }
821
- return result;
834
+ result.push(pod);
822
835
  }
836
+ return result;
823
837
  },
824
838
  };
825
839
  }
package/src/cli/index.js CHANGED
@@ -162,6 +162,7 @@ program
162
162
  .option('--worker', 'Sets the context for a worker node.')
163
163
  .option('--chown', 'Sets the appropriate ownership for Kubernetes kubeconfig files.')
164
164
  .option('--k3s', 'Initializes the cluster using K3s (Lightweight Kubernetes).')
165
+ .option('--hosts <hosts>', 'A comma-separated list of cluster hostnames or IP addresses.')
165
166
  .action(Underpost.cluster.init)
166
167
  .description('Manages Kubernetes clusters, defaulting to Kind cluster initialization.');
167
168
 
@@ -191,6 +192,7 @@ program
191
192
  .option('--traffic <traffic-versions>', 'A comma-separated list of custom deployment traffic weights.')
192
193
  .option('--disable-update-deployment', 'Disables updates to deployments.')
193
194
  .option('--disable-update-proxy', 'Disables updates to proxies.')
195
+ .option('--disable-deployment-proxy', 'Disables proxies of deployments.')
194
196
  .option(
195
197
  '--status',
196
198
  'Retrieves current network traffic data from resource deployments and the host machine network configuration.',
@@ -198,6 +200,7 @@ program
198
200
  .option('--kubeadm', 'Enables the kubeadm context for deployment operations.')
199
201
  .option('--etc-hosts', 'Enables the etc-hosts context for deployment operations.')
200
202
  .option('--restore-hosts', 'Restores default `/etc/hosts` entries.')
203
+ .option('--disable-update-underpost-config', 'Disables updates to Underpost configuration during deployment.')
201
204
  .description('Manages application deployments, defaulting to deploying development pods.')
202
205
  .action(Underpost.deploy.callback);
203
206
 
@@ -379,7 +382,10 @@ program
379
382
  .option('--dev', 'Sets the development context environment for the script.')
380
383
  .option('--build', 'Set builder context runner')
381
384
  .option('--replicas <replicas>', 'Sets a custom number of replicas for deployment.')
382
- .option('--pod-name <pod-name>', 'Optional: Specifies the pod name for test execution.')
385
+ .option('--pod-name <pod-name>', 'Optional: Specifies the pod name for execution.')
386
+ .option('--node-name <node-name>', 'Optional: Specifies the node name for execution.')
387
+ .option('--port <port>', 'Optional: Specifies the port for execution.')
388
+ .option('--etc-hosts', 'Enables etc-hosts context for the runner execution.')
383
389
  .option('--volume-host-path <volume-host-path>', 'Optional: Specifies the volume host path for test execution.')
384
390
  .option('--volume-mount-path <volume-mount-path>', 'Optional: Specifies the volume mount path for test execution.')
385
391
  .option('--volume-type <volume-type>', 'Optional: Specifies the volume type for test execution.')
package/src/cli/run.js CHANGED
@@ -42,6 +42,9 @@ class UnderpostRun {
42
42
  * @type {Object}
43
43
  * @property {boolean} dev - Whether to run in development mode.
44
44
  * @property {string} podName - The name of the pod to run.
45
+ * @property {string} nodeName - The name of the node to run.
46
+ * @property {number} port - Custom port to use.
47
+ * @property {boolean} etcHosts - Whether to modify /etc/hosts.
45
48
  * @property {string} volumeHostPath - The host path for the volume.
46
49
  * @property {string} volumeMountPath - The mount path for the volume.
47
50
  * @property {string} imageName - The name of the image to run.
@@ -65,6 +68,8 @@ class UnderpostRun {
65
68
  static DEFAULT_OPTION = {
66
69
  dev: false,
67
70
  podName: '',
71
+ nodeName: '',
72
+ port: 0,
68
73
  volumeHostPath: '',
69
74
  volumeMountPath: '',
70
75
  imageName: '',
@@ -216,13 +221,66 @@ class UnderpostRun {
216
221
  );
217
222
  shellExec(`${baseCommand} cluster${options.dev ? ' --dev' : ''} --valkey --pull-image`);
218
223
  }
219
- shellExec(`${baseCommand} deploy --expose mongo`, { async: true });
220
- shellExec(`${baseCommand} deploy --expose valkey`, { async: true });
224
+ shellExec(`${baseCommand} deploy --expose --disable-update-underpost-config mongo`, { async: true });
225
+ shellExec(`${baseCommand} deploy --expose --disable-update-underpost-config valkey`, { async: true });
221
226
  {
222
227
  const hostListenResult = UnderpostDeploy.API.etcHostFactory(mongoHosts);
223
228
  logger.info(hostListenResult.renderHosts);
224
229
  }
225
230
  },
231
+
232
+ /**
233
+ * @method metadata
234
+ * @description Generates metadata for the specified path after exposing the development cluster.
235
+ * @param {string} path - The input value, identifier, or path for the operation.
236
+ * @param {Object} options - The default underpost runner options for customizing workflow
237
+ * @memberof UnderpostRun
238
+ */
239
+ metadata: async (path, options = UnderpostRun.DEFAULT_OPTION) => {
240
+ const ports = '6379,27017';
241
+ shellExec(`node bin run kill '${ports}'`);
242
+ shellExec(`node bin run dev-cluster --dev expose`, { async: true });
243
+ console.log('Loading fordward services...');
244
+ await timer(5000);
245
+ shellExec(`node bin metadata --generate ${path}`);
246
+ shellExec(`node bin run kill '${ports}'`);
247
+ },
248
+
249
+ /**
250
+ * @method svc-ls
251
+ * @description Lists systemd services and installed packages, optionally filtering by the provided path.
252
+ * @param {string} path - The input value, identifier, or path for the operation (used as the optional filter for services and packages).
253
+ * @param {Object} options - The default underpost runner options for customizing workflow
254
+ * @memberof UnderpostRun
255
+ */
256
+ 'svc-ls': (path, options = UnderpostRun.DEFAULT_OPTION) => {
257
+ const log = shellExec(`systemctl list-units --type=service${path ? ` | grep ${path}` : ''}`, {
258
+ silent: true,
259
+ stdout: true,
260
+ });
261
+ console.log(path ? log.replaceAll(path, path.red) : log);
262
+ const log0 = shellExec(`sudo dnf list installed${path ? ` | grep ${path}` : ''}`, {
263
+ silent: true,
264
+ stdout: true,
265
+ });
266
+ console.log(path ? log0.replaceAll(path, path.red) : log0);
267
+ },
268
+
269
+ /**
270
+ * @method svc-rm
271
+ * @description Removes a systemd service by stopping it, disabling it, uninstalling the package, and deleting related files.
272
+ * @param {string} path - The input value, identifier, or path for the operation (used as the service name).
273
+ * @param {Object} options - The default underpost runner options for customizing workflow
274
+ * @memberof UnderpostRun
275
+ */
276
+ 'svc-rm': (path, options = UnderpostRun.DEFAULT_OPTION) => {
277
+ shellExec(`sudo systemctl stop ${path}`);
278
+ shellExec(`sudo systemctl disable --now ${path}`);
279
+ shellExec(`sudo dnf remove -y ${path}*`);
280
+ shellExec(`sudo rm -f /usr/lib/systemd/system/${path}.service`);
281
+ shellExec(`sudo rm -f /etc/yum.repos.d/${path}*.repo`);
282
+ },
283
+
226
284
  /**
227
285
  * @method ssh-cluster-info
228
286
  * @description Executes the `ssh-cluster-info.sh` script to display cluster connection information.
@@ -498,7 +556,12 @@ class UnderpostRun {
498
556
  * @memberof UnderpostRun
499
557
  */
500
558
  'ls-images': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
501
- console.table(UnderpostDeploy.API.getCurrentLoadedImages('kind-worker', false));
559
+ console.table(
560
+ UnderpostDeploy.API.getCurrentLoadedImages(
561
+ options.nodeName ? options.nodeName : 'kind-worker',
562
+ path === 'spec' ? true : false,
563
+ ),
564
+ );
502
565
  },
503
566
 
504
567
  /**
@@ -883,52 +946,84 @@ class UnderpostRun {
883
946
  service: async (path = '', options = UnderpostRun.DEFAULT_OPTION) => {
884
947
  const env = options.dev ? 'development' : 'production';
885
948
  const baseCommand = options.dev ? 'node bin' : 'underpost';
886
- // const baseClusterCommand = options.dev ? ' --dev' : '';
949
+ const baseClusterCommand = options.dev ? ' --dev' : '';
887
950
  shellCd(`/home/dd/engine`);
888
951
  let [deployId, serviceId, host, _path, replicas, image, node] = path.split(',');
952
+ // const confClient = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.client.json`, 'utf8'));
953
+ const confServer = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'));
954
+ // const confSSR = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.ssr.json`, 'utf8'));
955
+ // const packageData = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/package.json`, 'utf8'));
889
956
  const services = fs.existsSync(`./engine-private/deploy/${deployId}/conf.services.json`)
890
957
  ? JSON.parse(fs.readFileSync(`./engine-private/deploy/${deployId}/conf.services.json`, 'utf8'))
891
958
  : [];
959
+ let serviceData = services.findIndex((s) => s.serviceId === serviceId);
960
+ const payload = {
961
+ serviceId,
962
+ path: _path,
963
+ port: options.port,
964
+ host,
965
+ };
966
+ let podToMonitor;
967
+ if (!payload.port)
968
+ switch (serviceId) {
969
+ case 'mongo-express-service': {
970
+ payload.port = 8081;
971
+ break;
972
+ }
973
+ case 'grafana': {
974
+ payload.port = 3000;
975
+ // payload.pathRewritePolicy = [
976
+ // {
977
+ // prefix: '/grafana',
978
+ // replacement: '/',
979
+ // },
980
+ // ];
981
+ break;
982
+ }
983
+ }
984
+ if (serviceData == -1) {
985
+ services.push(payload);
986
+ } else {
987
+ services[serviceData] = payload;
988
+ }
989
+ fs.writeFileSync(
990
+ `./engine-private/conf/${deployId}/conf.services.json`,
991
+ JSON.stringify(services, null, 4),
992
+ 'utf8',
993
+ );
892
994
  switch (serviceId) {
893
995
  case 'mongo-express-service': {
894
- let serviceData = services.findIndex((s) => s.serviceId === serviceId);
895
- const payload = {
896
- serviceId,
897
- path: _path,
898
- port: 8081,
899
- host,
900
- };
901
- if (serviceData == -1) {
902
- services.push(payload);
903
- } else {
904
- services[serviceData] = payload;
905
- }
906
- fs.writeFileSync(
907
- `./engine-private/conf/${deployId}/conf.services.json`,
908
- JSON.stringify(services, null, 4),
909
- 'utf8',
910
- );
911
996
  shellExec(`kubectl delete svc mongo-express-service --ignore-not-found`);
912
997
  shellExec(`kubectl delete deployment mongo-express --ignore-not-found`);
913
998
  shellExec(`kubectl apply -f manifests/deployment/mongo-express/deployment.yaml`);
914
-
915
- const success = await UnderpostTest.API.statusMonitor('mongo-express');
916
-
917
- if (success) {
918
- const versions = UnderpostDeploy.API.getCurrentTraffic(deployId) || 'blue';
919
- if (!node) node = os.hostname();
920
- shellExec(
921
- `${baseCommand} deploy --kubeadm --build-manifest --sync --info-router --replicas ${
922
- replicas ? replicas : 1
923
- } --node ${node}${image ? ` --image ${image}` : ''}${versions ? ` --versions ${versions}` : ''} dd ${env}`,
924
- );
925
- shellExec(
926
- `${baseCommand} deploy --kubeadm --disable-update-deployment ${deployId} ${env} --versions ${versions}`,
927
- );
928
- } else logger.error('Mongo Express deployment failed');
999
+ podToMonitor = 'mongo-express';
1000
+ break;
1001
+ }
1002
+ case 'grafana': {
1003
+ shellExec(
1004
+ `node bin cluster${baseClusterCommand} --grafana --hosts '${host}' --prom '${Object.keys(confServer)}'`,
1005
+ );
1006
+ podToMonitor = 'grafana';
929
1007
  break;
930
1008
  }
931
1009
  }
1010
+ const success = await UnderpostTest.API.statusMonitor(podToMonitor);
1011
+ if (success) {
1012
+ const versions = UnderpostDeploy.API.getCurrentTraffic(deployId) || 'blue';
1013
+ if (!node) node = os.hostname();
1014
+ shellExec(
1015
+ `${baseCommand} deploy${options.dev ? '' : ' --kubeadm'}${options.devProxyPortOffset ? ' --disable-deployment-proxy' : ''} --build-manifest --sync --info-router --replicas ${
1016
+ replicas ? replicas : 1
1017
+ } --node ${node}${image ? ` --image ${image}` : ''}${versions ? ` --versions ${versions}` : ''} dd ${env}`,
1018
+ );
1019
+ shellExec(
1020
+ `${baseCommand} deploy${options.dev ? '' : ' --kubeadm'}${options.devProxyPortOffset ? ' --disable-deployment-proxy' : ''} --disable-update-deployment ${deployId} ${env} --versions ${versions}`,
1021
+ );
1022
+ } else logger.error('Mongo Express deployment failed');
1023
+ if (options.etcHosts === true) {
1024
+ const hostListenResult = UnderpostDeploy.API.etcHostFactory([host]);
1025
+ logger.info(hostListenResult.renderHosts);
1026
+ }
932
1027
  },
933
1028
 
934
1029
  /**
package/src/index.js CHANGED
@@ -35,7 +35,7 @@ class Underpost {
35
35
  * @type {String}
36
36
  * @memberof Underpost
37
37
  */
38
- static version = 'v2.89.1';
38
+ static version = 'v2.89.2';
39
39
  /**
40
40
  * Repository cli API
41
41
  * @static