underpost 2.8.837 → 2.8.839

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
@@ -24,16 +24,20 @@ template
24
24
 
25
25
 
26
26
 
27
+
28
+
27
29
  <!-- badges -->
28
30
 
29
31
 
30
- [![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.837)](https://socket.dev/npm/package/underpost/overview/2.8.837) [![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)
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)
31
33
 
32
34
 
33
35
  <!-- end-badges -->
34
36
 
35
37
 
36
38
 
39
+
40
+
37
41
  </div>
38
42
 
39
43
  <div align="center">
@@ -78,7 +82,7 @@ Run dev client server
78
82
  npm run dev
79
83
  ```
80
84
  <!-- -->
81
- ## underpost ci/cd cli v2.8.837
85
+ ## underpost ci/cd cli v2.8.839
82
86
 
83
87
  ### Usage: `underpost [options] [command]`
84
88
  ```
package/cli.md CHANGED
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v2.8.837
1
+ ## underpost ci/cd cli v2.8.839
2
2
 
3
3
  ### Usage: `underpost [options] [command]`
4
4
  ```
@@ -554,28 +554,20 @@ Options:
554
554
  Runs a script from the specified path.
555
555
 
556
556
  Arguments:
557
- runner-id The runner ID to run. Options:
558
- spark-template, gpu-env, tf-gpu-test, ide,
559
- tf-vae-test, deploy-job.
560
- path The absolute or relative directory path
561
- where the script is located.
557
+ runner-id The runner ID to run. Options: spark-template, gpu-env, tf-gpu-test, ide, monitor, tf-vae-test, deploy-job.
558
+ path The absolute or relative directory path where the script is located.
562
559
 
563
560
  Options:
564
- --command <command-array> Array of commands to run.
565
- --args <args-array> Array of arguments to pass to the command.
566
- --dev Sets the development context environment
567
- for the script.
568
- --pod-name <pod-name> Optional: Specifies the pod name for test
569
- execution.
570
- --volume-name <volume-name> Optional: Specifies the volume name for
571
- test execution.
572
- --image-name <image-name> Optional: Specifies the image name for
573
- test execution.
574
- --container-name <container-name> Optional: Specifies the container name for
575
- test execution.
576
- --namespace <namespace> Optional: Specifies the namespace for test
577
- execution.
578
- -h, --help display help for command
561
+ --command <command-array> Array of commands to run.
562
+ --args <args-array> Array of arguments to pass to the command.
563
+ --dev Sets the development context environment for the script.
564
+ --pod-name <pod-name> Optional: Specifies the pod name for test execution.
565
+ --volume-host-path <volume-host-path> Optional: Specifies the volume host path for test execution.
566
+ --volume-mount-path <volume-mount-path> Optional: Specifies the volume mount path for test execution.
567
+ --image-name <image-name> Optional: Specifies the image name for test execution.
568
+ --container-name <container-name> Optional: Specifies the container name for test execution.
569
+ --namespace <namespace> Optional: Specifies the namespace for test execution.
570
+ -h, --help display help for command
579
571
 
580
572
  ```
581
573
 
@@ -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.837'
61
+ engine.version: '2.8.839'
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.837
20
+ image: localhost/rockylinux9-underpost:v2.8.839
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.837
103
+ image: localhost/rockylinux9-underpost:v2.8.839
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
@@ -8,14 +8,14 @@ for iface_path in /sys/class/net/*; do
8
8
  operstate=$(< "$iface_path/operstate")
9
9
  mtu=$(< "$iface_path/mtu")
10
10
 
11
- # Driver: módulo kernel que maneja esta interfaz
11
+ # Driver
12
12
  if [ -L "$iface_path/device/driver" ]; then
13
13
  driver=$(basename "$(readlink -f "$iface_path/device/driver")")
14
14
  else
15
15
  driver="—"
16
16
  fi
17
17
 
18
- # Vendor:Device ID PCI
18
+ # Vendor device ID PCI
19
19
  pci_dev="$iface_path/device"
20
20
  if [ -f "$pci_dev/vendor" ] && [ -f "$pci_dev/device" ]; then
21
21
  vendor_id=$(< "$pci_dev/vendor")
@@ -28,7 +28,7 @@ for iface_path in /sys/class/net/*; do
28
28
  pci="—"
29
29
  fi
30
30
 
31
- # Link Speed: lectura directa de /sys/class/net/<iface>/speed
31
+ # Link Speed
32
32
  speed=$(cat "$iface_path/speed" 2>/dev/null || echo "—")
33
33
 
34
34
  echo "Interface: $name"
@@ -0,0 +1,19 @@
1
+ # GPUs and drivers in use
2
+ sudo lspci -nnk | egrep -i 'vga|3d' -A3
3
+
4
+ # modules loaded relevant
5
+ lsmod | egrep 'nvidia|nouveau|amdgpu' || true
6
+
7
+ # if exists nvidia tool
8
+ nvidia-smi 2>/dev/null || echo "nvidia-smi no disponible / driver no cargado"
9
+
10
+ # kernel related errors
11
+ sudo dmesg | egrep -i 'nvidia|nouveau|amdgpu' --color=auto
12
+
13
+ # recent system errors / gdm / mutter / X
14
+ sudo journalctl -b -p err --no-pager | head -n 200
15
+ journalctl -b _COMM=gdm --no-pager | tail -n 200
16
+ journalctl -b _COMM=Xorg --no-pager | tail -n 200
17
+
18
+ # X log (if exists)
19
+ sudo grep -E "(EE|WW|NVIDIA|nouveau|amdgpu)" /var/log/Xorg.0.log || true
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.837",
5
+ "version": "2.8.839",
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",
@@ -1,5 +1,5 @@
1
1
  import { getNpmRootPath, getUnderpostRootPath } from '../server/conf.js';
2
- import { pbcopy, shellExec } from '../server/process.js';
2
+ import { openTerminal, pbcopy, shellExec } from '../server/process.js';
3
3
  import dotenv from 'dotenv';
4
4
  import { loggerFactory } from '../server/logger.js';
5
5
  import { getLocalIPv4Address } from '../server/dns.js';
@@ -699,18 +699,8 @@ menuentry '${menuentryStr}' {
699
699
  fs.writeFileSync(`${nfsHostPath}/underpost/token-secret`, token_secret, 'utf8');
700
700
 
701
701
  // Open new terminals for live cloud-init logs.
702
- shellExec(
703
- `gnome-terminal -- bash -c "node ${underpostRoot}/bin baremetal --logs cloud; exec bash" & disown`,
704
- {
705
- async: true,
706
- },
707
- );
708
- shellExec(
709
- `gnome-terminal -- bash -c "node ${underpostRoot}/bin baremetal --logs machine; exec bash" & disown`,
710
- {
711
- async: true,
712
- },
713
- );
702
+ openTerminal(`node ${underpostRoot}/bin baremetal --logs cloud`);
703
+ openTerminal(`node ${underpostRoot}/bin baremetal --logs machine`);
714
704
  } catch (error) {
715
705
  logger.error(error, error.stack);
716
706
  } finally {
@@ -519,7 +519,7 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
519
519
 
520
520
  try {
521
521
  // Phase 0: Truncate large logs under /var/log to free up immediate space
522
- logger.info('Phase 0/6: Truncating large log files under /var/log...');
522
+ logger.info('Phase 0/7: Truncating large log files under /var/log...');
523
523
  try {
524
524
  const cleanPath = `/var/log/`;
525
525
  const largeLogsFiles = shellExec(
@@ -540,7 +540,7 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
540
540
 
541
541
  // Phase 1: Clean up Persistent Volumes with hostPath
542
542
  // This targets data created by Kubernetes Persistent Volumes that use hostPath.
543
- logger.info('Phase 1/6: Cleaning Kubernetes hostPath volumes...');
543
+ logger.info('Phase 1/7: Cleaning Kubernetes hostPath volumes...');
544
544
  try {
545
545
  const pvListJson = shellExec(`kubectl get pv -o json || echo '{"items":[]}'`, { stdout: true, silent: true });
546
546
  const pvList = JSON.parse(pvListJson);
@@ -563,7 +563,7 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
563
563
  // Phase 2: Restore SELinux and stop services
564
564
  // This is critical for fixing the 'permission denied' error you experienced.
565
565
  // Enable SELinux permissive mode and restore file contexts.
566
- logger.info('Phase 2/6: Stopping services and fixing SELinux...');
566
+ logger.info('Phase 2/7: Stopping services and fixing SELinux...');
567
567
  logger.info(' -> Ensuring SELinux is in permissive mode...');
568
568
  shellExec(`sudo setenforce 0 || true`);
569
569
  shellExec(`sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config || true`);
@@ -580,7 +580,7 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
580
580
  shellExec('sudo umount -f /var/lib/kubelet/pods/*/* || true');
581
581
 
582
582
  // Phase 3: Execute official uninstallation commands
583
- logger.info('Phase 3/6: Executing official reset and uninstallation commands...');
583
+ logger.info('Phase 3/7: Executing official reset and uninstallation commands...');
584
584
  logger.info(' -> Executing kubeadm reset...');
585
585
  shellExec('sudo kubeadm reset --force || true');
586
586
  logger.info(' -> Executing K3s uninstallation script if it exists...');
@@ -589,7 +589,7 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
589
589
  shellExec('kind get clusters | xargs -r -t -n1 kind delete cluster || true');
590
590
 
591
591
  // Phase 4: File system cleanup
592
- logger.info('Phase 4/6: Cleaning up remaining file system artifacts...');
592
+ logger.info('Phase 4/7: Cleaning up remaining file system artifacts...');
593
593
  // Remove any leftover configurations and data.
594
594
  shellExec('sudo rm -rf /etc/kubernetes/* || true');
595
595
  shellExec('sudo rm -rf /etc/cni/net.d/* || true');
@@ -602,15 +602,21 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
602
602
  shellExec('rm -rf $HOME/.kube || true');
603
603
 
604
604
  // Phase 5: Host network cleanup
605
- logger.info('Phase 5/6: Cleaning up host network configurations...');
605
+ logger.info('Phase 5/7: Cleaning up host network configurations...');
606
606
  // Remove iptables rules and CNI network interfaces.
607
607
  shellExec('sudo iptables -F || true');
608
608
  shellExec('sudo iptables -t nat -F || true');
609
+ // Restore iptables rules
610
+ shellExec(`chmod +x ${options.underpostRoot}/manifests/maas/nat-iptables.sh`);
611
+ shellExec(`${options.underpostRoot}/manifests/maas/nat-iptables.sh`, { silent: true });
609
612
  shellExec('sudo ip link del cni0 || true');
610
613
  shellExec('sudo ip link del flannel.1 || true');
611
614
 
615
+ logger.info('Phase 6/7: Clean up images');
616
+ shellExec(`podman rmi $(podman images -qa) --force`);
617
+
612
618
  // Phase 6: Reload daemon and finalize
613
- logger.info('Phase 6/6: Reloading the system daemon and finalizing...');
619
+ logger.info('Phase 7/7: Reloading the system daemon and finalizing...');
614
620
  // shellExec('sudo systemctl daemon-reload');
615
621
  UnderpostCluster.API.config();
616
622
  logger.info('Safe and complete reset finished. The system is ready for a new cluster initialization.');
@@ -662,7 +668,7 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
662
668
  const archData = UnderpostBaremetal.API.getHostArch();
663
669
  logger.info('Installing essential host-level prerequisites for Kubernetes...', archData);
664
670
  // Install Docker and its dependencies
665
- shellExec(`sudo dnf -y install dnf-plugins-core`);
671
+ shellExec(`sudo dnf -y install dnf-plugins-core dbus-x11`);
666
672
  shellExec(`sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo`);
667
673
  shellExec(`sudo dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin`);
668
674
 
package/src/cli/deploy.js CHANGED
@@ -519,6 +519,15 @@ node bin/deploy build-full-client ${deployId}
519
519
  logger.error(error, error.stack);
520
520
  }
521
521
  },
522
+ existsContainerFile({ podName, path }) {
523
+ return JSON.parse(
524
+ shellExec(`kubectl exec ${podName} -- test -f ${path} && echo "true" || echo "false"`, {
525
+ stdout: true,
526
+ disableLog: true,
527
+ silent: true,
528
+ }).trim(),
529
+ );
530
+ },
522
531
  };
523
532
  }
524
533
 
package/src/cli/index.js CHANGED
@@ -324,7 +324,8 @@ program
324
324
  .option('--args <args-array>', 'Array of arguments to pass to the command.')
325
325
  .option('--dev', 'Sets the development context environment for the script.')
326
326
  .option('--pod-name <pod-name>', 'Optional: Specifies the pod name for test execution.')
327
- .option('--volume-name <volume-name>', 'Optional: Specifies the volume name for test execution.')
327
+ .option('--volume-host-path <volume-host-path>', 'Optional: Specifies the volume host path for test execution.')
328
+ .option('--volume-mount-path <volume-mount-path>', 'Optional: Specifies the volume mount path for test execution.')
328
329
  .option('--image-name <image-name>', 'Optional: Specifies the image name for test execution.')
329
330
  .option('--container-name <container-name>', 'Optional: Specifies the container name for test execution.')
330
331
  .option('--namespace <namespace>', 'Optional: Specifies the namespace for test execution.')
package/src/cli/run.js CHANGED
@@ -1,9 +1,11 @@
1
- import { pbcopy, shellCd, shellExec } from '../server/process.js';
1
+ import { daemonProcess, getTerminalPid, openTerminal, pbcopy, shellCd, shellExec } from '../server/process.js';
2
2
  import read from 'read';
3
3
  import { getNpmRootPath } from '../server/conf.js';
4
4
  import { loggerFactory } from '../server/logger.js';
5
5
  import UnderpostTest from './test.js';
6
6
  import fs from 'fs-extra';
7
+ import { range, setPad, timer } from '../client/components/core/CommonJs.js';
8
+ import UnderpostDeploy from './deploy.js';
7
9
 
8
10
  const logger = loggerFactory(import.meta);
9
11
 
@@ -11,7 +13,8 @@ class UnderpostRun {
11
13
  static DEFAULT_OPTION = {
12
14
  dev: false,
13
15
  podName: '',
14
- volumeName: '',
16
+ volumeHostPath: '',
17
+ volumeMountPath: '',
15
18
  imageName: '',
16
19
  containerName: '',
17
20
  namespace: '',
@@ -52,9 +55,91 @@ class UnderpostRun {
52
55
  const { underpostRoot } = options;
53
56
  shellExec(`node ${underpostRoot}/bin/vs ${path}`);
54
57
  },
58
+ monitor: (path, options = UnderpostRun.DEFAULT_OPTION) => {
59
+ const pid = getTerminalPid();
60
+ logger.info('monitor pid', pid);
61
+ const checkPath = '/await';
62
+ const _monitor = async () => {
63
+ const result = UnderpostDeploy.API.existsContainerFile({ podName: path, path: checkPath });
64
+ logger.info('monitor', result);
65
+ if (result === true) {
66
+ switch (path) {
67
+ case 'tf-vae-test':
68
+ {
69
+ const nameSpace = 'default';
70
+ const podName = path;
71
+ const basePath = '/home/dd';
72
+ const scriptPath = '/site/en/tutorials/generative/cvae.py';
73
+ // shellExec(
74
+ // `sudo kubectl cp ${nameSpace}/${podName}:${basePath}/docs${scriptPath} ${basePath}/lab/src/${scriptPath
75
+ // .split('/')
76
+ // .pop()}`,
77
+ // );
78
+ // const file = fs.readFileSync(`${basePath}/lab/src/${scriptPath.split('/').pop()}`, 'utf8');
79
+ // fs.writeFileSync(
80
+ // `${basePath}/lab/src/${scriptPath.split('/').pop()}`,
81
+ // file.replace(
82
+ // `import time`,
83
+ // `import time
84
+ // print('=== SCRIPT UPDATE TEST ===')`,
85
+ // ),
86
+ // 'utf8',
87
+ // );
88
+ shellExec(
89
+ `sudo kubectl cp ${basePath}/lab/src/${scriptPath
90
+ .split('/')
91
+ .pop()} ${nameSpace}/${podName}:${basePath}/docs${scriptPath}`,
92
+ );
93
+ // shellExec(`sudo kubectl exec -i ${podName} -- sh -c "ipython ${basePath}/docs${scriptPath}"`);
94
+ shellExec(`sudo kubectl exec -i ${podName} -- sh -c "rm -rf ${checkPath}"`);
95
+
96
+ {
97
+ const checkPath = `/latent_space_plot.png`;
98
+ const outsPaths = [];
99
+ logger.info('monitor', checkPath);
100
+ while (!UnderpostDeploy.API.existsContainerFile({ podName, path: `/home/dd/docs${checkPath}` }))
101
+ await timer(1000);
102
+
103
+ {
104
+ const toPath = `${basePath}/lab${checkPath}`;
105
+ outsPaths.push(toPath);
106
+ shellExec(`sudo kubectl cp ${nameSpace}/${podName}:${basePath}/docs${checkPath} ${toPath}`);
107
+ }
108
+
109
+ for (let i of range(1, 10)) {
110
+ i = `/image_at_epoch_${setPad(i, '0', 4)}.png`;
111
+ const toPath = `${basePath}/lab/${i}`;
112
+ outsPaths.push(toPath);
113
+ shellExec(`sudo kubectl cp ${nameSpace}/${podName}:${basePath}/docs${i} ${toPath}`);
114
+ }
115
+ openTerminal(`firefox ${outsPaths.join(' ')}`, { single: true });
116
+ }
117
+ shellExec(`sudo kill -9 ${pid}`);
118
+ }
119
+ break;
120
+
121
+ default:
122
+ break;
123
+ }
124
+ return;
125
+ }
126
+ await timer(1000);
127
+ _monitor();
128
+ };
129
+ _monitor();
130
+ },
55
131
  'tf-vae-test': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
56
132
  const { underpostRoot } = options;
133
+ const podName = 'tf-vae-test';
57
134
  await UnderpostRun.RUNNERS['deploy-job']('', {
135
+ podName,
136
+ // volumeMountPath: '/custom_images',
137
+ // volumeHostPath: '/home/dd/engine/src/client/public/cyberia/assets/skin',
138
+ on: {
139
+ init: async () => {
140
+ openTerminal(`node bin run --dev monitor ${podName}`);
141
+ },
142
+ },
58
143
  args: [
59
144
  `pip install --upgrade \
60
145
  nbconvert \
@@ -68,19 +153,26 @@ class UnderpostRun {
68
153
  'git clone https://github.com/tensorflow/docs.git',
69
154
  'cd docs',
70
155
  'jupyter nbconvert --to python site/en/tutorials/generative/cvae.ipynb',
71
- 'ipython site/en/tutorials/generative/cvae.py',
156
+ `echo '' > /await`,
157
+ `echo '=== WAITING SCRIPT LAUNCH ==='`,
158
+ `while [ -f /await ]; do sleep 1; done`,
159
+ `echo '=== FINISHED ==='`,
160
+ daemonProcess(`ipython site/en/tutorials/generative/cvae.py`),
72
161
  ],
73
162
  });
74
163
  },
75
164
  'deploy-job': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
76
165
  const podName = options.podName || 'deploy-job';
77
- const volumeName = options.volumeName || `${podName}-volume`;
166
+ const volumeName = `${podName}-volume`;
78
167
  const args = (options.args ? options.args : path ? [`python ${path}`] : []).filter((c) => c.trim());
79
168
  const imageName = options.imageName || 'nvcr.io/nvidia/tensorflow:24.04-tf2-py3';
80
169
  const containerName = options.containerName || `${podName}-container`;
81
170
  const gpuEnable = imageName.match('nvidia');
82
171
  const runtimeClassName = gpuEnable ? 'nvidia' : '';
83
172
  const namespace = options.namespace || 'default';
173
+ const volumeMountPath = options.volumeMountPath || path;
174
+ const volumeHostPath = options.volumeHostPath || path;
175
+ const enableVolumeMount = volumeHostPath && volumeMountPath;
84
176
 
85
177
  const cmd = `kubectl apply -f - <<EOF
86
178
  apiVersion: v1
@@ -116,16 +208,16 @@ ${
116
208
  : ''
117
209
  }
118
210
  ${
119
- path
211
+ enableVolumeMount
120
212
  ? `
121
213
  volumeMounts:
122
214
  - name: ${volumeName}
123
- mountPath: ${path}
215
+ mountPath: ${volumeMountPath}
124
216
  volumes:
125
217
  - name: ${volumeName}
126
218
  hostPath:
127
- path: ${path}
128
- type: ${fs.statSync(path).isDirectory() ? 'Directory' : 'File'}`
219
+ path: ${volumeHostPath}
220
+ type: ${fs.statSync(volumeHostPath).isDirectory() ? 'Directory' : 'File'}`
129
221
  : ''
130
222
  }
131
223
  EOF`;
@@ -134,6 +226,7 @@ EOF`;
134
226
  shellExec(cmd, { disableLog: true });
135
227
  const successInstance = await UnderpostTest.API.statusMonitor(podName);
136
228
  if (successInstance) {
229
+ options.on?.init ? await options.on.init() : null;
137
230
  shellExec(`kubectl logs -f ${podName}`);
138
231
  }
139
232
  },
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.837';
37
+ static version = 'v2.8.839';
38
38
  /**
39
39
  * Repository cli API
40
40
  * @static
@@ -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 };